Skip to content

Commit 7307d59

Browse files
committed
test: migrate the minimal project e2e test
1 parent c2ba2b5 commit 7307d59

16 files changed

+326
-71
lines changed

packages/ngx-deploy-npm-e2e/src/ngx-deploy-npm.spec.ts

Lines changed: 0 additions & 65 deletions
This file was deleted.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { setup } from './utils';
2+
3+
describe('ngx-deploy-npm', () => {
4+
it('should be installed', async () => {
5+
const { tearDown, executeCommand } = await setup([]);
6+
7+
expect(() => executeCommand('npm ls ngx-deploy-npm')).not.toThrow();
8+
9+
return tearDown();
10+
}, 120000);
11+
});
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { uniq } from '@nx/plugin/testing';
2+
import { setup } from './utils';
3+
4+
describe('Minimal Project', () => {
5+
it('should publish the lib', async () => {
6+
const { processedLibs, tearDown, executeCommand } = await setup([
7+
{ name: uniq('minimal-lib'), generator: 'minimal' },
8+
]);
9+
const [uniqLibName] = processedLibs;
10+
11+
executeCommand(
12+
`npx nx deploy ${uniqLibName.name} --tag e2e --registry=http://localhost:4873`
13+
);
14+
15+
expect(() => {
16+
executeCommand(`npm view ${uniqLibName.npmPackageName}@e2e`);
17+
}).not.toThrow();
18+
19+
return tearDown();
20+
}, 120000);
21+
});
Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
import * as fs from 'fs';
2+
import { dirname, join } from 'path';
3+
import { execSync } from 'child_process';
4+
5+
import { ProjectConfiguration } from '@nx/devkit';
6+
import { readJson } from '@nx/plugin/testing';
7+
8+
import { currentNxVersion } from './get-nx-current-version';
9+
import { InstallGeneratorOptions } from 'bikecoders/ngx-deploy-npm';
10+
import {
11+
generateLib,
12+
initNgxDeployNPMProject,
13+
installDependencies,
14+
installNgxDeployNPMProject,
15+
} from '.';
16+
17+
const mockDomian = '@mock-domain';
18+
19+
const executeCommandFactory =
20+
(projectDirectory: string) => (command: string) => {
21+
let output: string;
22+
23+
try {
24+
output = execSync(command, {
25+
stdio: 'inherit',
26+
cwd: projectDirectory,
27+
encoding: 'utf-8',
28+
env: process.env,
29+
});
30+
} catch (error) {
31+
console.error(`Error executing command: ${command}`);
32+
if (error instanceof Error && 'stderr' in error) {
33+
console.error(error.stderr);
34+
}
35+
throw error;
36+
}
37+
38+
return output;
39+
};
40+
41+
export const setup = async (
42+
libs: {
43+
name: string;
44+
generator: 'minimal' | string;
45+
installOptions?: Omit<
46+
Partial<InstallGeneratorOptions>,
47+
'distFolderPath' | 'project'
48+
>;
49+
skipInstall?: boolean;
50+
extraOptions?: string;
51+
distFolderPath?: string;
52+
}[]
53+
) => {
54+
const projectDirectory = await createTestProject();
55+
const executeCommand = executeCommandFactory(projectDirectory);
56+
57+
initNgxDeployNPMProject(executeCommand);
58+
59+
// Install dependencies only once
60+
const generators = new Set(
61+
libs
62+
.map(({ generator }) => generator)
63+
.filter(generator => generator !== 'minimal')
64+
);
65+
generators.forEach(dependency => {
66+
installDependencies(executeCommand, dependency);
67+
});
68+
69+
// Init libs
70+
await Promise.all(
71+
libs.map(async ({ name, generator, extraOptions = '' }) => {
72+
if (generator === 'minimal') {
73+
await createMinimalLib(projectDirectory, name);
74+
} else {
75+
generateLib({
76+
nxPlugin: generator,
77+
executeCommand,
78+
libName: name,
79+
extraOptions: `--directory="libs/${name}" ${extraOptions}`,
80+
});
81+
}
82+
})
83+
);
84+
85+
// Install ngx-deploy-npm
86+
libs
87+
.filter(({ skipInstall }) => !!skipInstall === false)
88+
.forEach(({ name, installOptions, generator }) => {
89+
const optionGenerator = <T>(
90+
optionaName: keyof InstallGeneratorOptions,
91+
value?: T
92+
) => (value ? `--${optionaName}="${value}"` : '');
93+
94+
const installOptionsParsed = Object.entries(installOptions ?? {})
95+
.map(([key, value]) =>
96+
optionGenerator(key as keyof InstallGeneratorOptions, value)
97+
)
98+
.join(' ');
99+
100+
const distFolderPath =
101+
generator === 'minimal'
102+
? getMinimalLibRoot(projectDirectory, name).libRoot
103+
: `dist/libs/${name}`;
104+
105+
installNgxDeployNPMProject(
106+
executeCommand,
107+
`--project="${name}" --dist-folder-path="${distFolderPath}" ${installOptionsParsed}`
108+
);
109+
});
110+
111+
const processedLibs: {
112+
name: string;
113+
workspace: ProjectConfiguration;
114+
npmPackageName: string;
115+
}[] = libs.map(({ name }) => ({
116+
name: name,
117+
workspace: readJson(`${projectDirectory}/packages/${name}/project.json`),
118+
npmPackageName: `${mockDomian}/${name}`,
119+
}));
120+
121+
return {
122+
processedLibs,
123+
projectDirectory,
124+
tearDown: async () => {
125+
await fs.promises.rm(projectDirectory, {
126+
recursive: true,
127+
force: true,
128+
});
129+
130+
return Promise.resolve();
131+
},
132+
executeCommand,
133+
};
134+
};
135+
136+
function getMinimalLibRoot(projectDirectory: string, libName: string) {
137+
const libRoot = `packages/${libName}`;
138+
const libRootAbsolutePath = join(projectDirectory, libRoot);
139+
140+
return { libRoot, libRootAbsolutePath };
141+
}
142+
143+
async function createMinimalLib(projectDirectory: string, libName: string) {
144+
// Create Lib
145+
const { libRoot, libRootAbsolutePath } = getMinimalLibRoot(
146+
projectDirectory,
147+
libName
148+
);
149+
150+
// Create the lib folder
151+
await fs.promises.mkdir(libRootAbsolutePath, {
152+
recursive: true,
153+
});
154+
155+
const createProjectJsonPromise = fs.promises.writeFile(
156+
join(libRootAbsolutePath, 'project.json'),
157+
generateProjectJSON(libName, libRoot),
158+
'utf8'
159+
);
160+
const createPackageJsonPromise = fs.promises.writeFile(
161+
join(libRootAbsolutePath, 'package.json'),
162+
generatePackageJSON(libName),
163+
'utf8'
164+
);
165+
const createUniqueFilePromise = fs.promises.writeFile(
166+
join(libRootAbsolutePath, 'hello-world.js'),
167+
"console.log('Hello World!');",
168+
'utf8'
169+
);
170+
await Promise.all([
171+
createProjectJsonPromise,
172+
createPackageJsonPromise,
173+
createUniqueFilePromise,
174+
]);
175+
176+
return { libRoot };
177+
178+
function generateProjectJSON(projectName: string, libRoot: string): string {
179+
const content = {
180+
name: projectName,
181+
$schema: '../../node_modules/nx/schemas/project-schema.json',
182+
projectType: 'library',
183+
sourceRoot: libRoot,
184+
};
185+
186+
return JSON.stringify(content, null, 2);
187+
}
188+
189+
function generatePackageJSON(projectName: string): string {
190+
const content = {
191+
name: `${mockDomian}/${projectName}`,
192+
description: 'Minimal LIb',
193+
version: '1.0.0',
194+
};
195+
196+
return JSON.stringify(content, null, 2);
197+
}
198+
}
199+
200+
/**
201+
* Creates a test project with create-nx-workspace and installs the plugin
202+
* @returns The directory where the test project was created
203+
*/
204+
async function createTestProject() {
205+
const projectName = 'test-project';
206+
const projectDirectory = join(process.cwd(), 'tmp', projectName);
207+
208+
// Ensure projectDirectory is empty
209+
await fs.promises.rm(projectDirectory, {
210+
recursive: true,
211+
force: true,
212+
});
213+
await fs.promises.mkdir(dirname(projectDirectory), {
214+
recursive: true,
215+
});
216+
217+
const command = `npx --yes create-nx-workspace@${currentNxVersion} ${projectName} --preset npm --nxCloud=skip --no-interactive`;
218+
executeCommandFactory(dirname(projectDirectory))(command);
219+
220+
return projectDirectory;
221+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
type Options = {
2+
nxPlugin: string;
3+
libName: string;
4+
executeCommand: (command: string) => void;
5+
extraOptions?: string;
6+
generator?: string;
7+
setPublishableOption?: boolean;
8+
};
9+
10+
export function generateLib({
11+
nxPlugin,
12+
libName,
13+
executeCommand,
14+
extraOptions,
15+
generator = 'lib',
16+
setPublishableOption = true,
17+
}: Options) {
18+
const publishableOption = setPublishableOption ? '--publishable' : '';
19+
const extraOptionsNormalized = extraOptions ? extraOptions : '';
20+
21+
executeCommand(
22+
`npx nx generate ${nxPlugin}:${generator} --name ${libName} ${publishableOption} --importPath ${libName} ${extraOptionsNormalized}`
23+
);
24+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import packageJson from '../../../../package.json'; // This import style requires "esModuleInterop", see "side notes"
2+
3+
export const currentNxVersion = packageJson.devDependencies['@nx/workspace'];
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export * from './generate-lib';
2+
export * from './install-deps';
3+
export * from './utils-ngx-deploy-npm';
4+
export * from './get-nx-current-version';
5+
export * from './basic-setup';
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { currentNxVersion } from './get-nx-current-version';
2+
3+
export function installDependencies(
4+
executeCommand: (command: string) => string,
5+
nxPlugin: string
6+
) {
7+
const packageToInstall = `${nxPlugin}@${currentNxVersion}`;
8+
9+
executeCommand(`npm add -D ${packageToInstall}`);
10+
executeCommand(`npx nx g ${nxPlugin}:init`);
11+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
export function initNgxDeployNPMProject(
2+
executeCommand: (command: string) => void
3+
) {
4+
executeCommand(`npm install ngx-deploy-npm@e2e`);
5+
}
6+
7+
// TODO bring all the complexity generating the options to this function
8+
export function installNgxDeployNPMProject(
9+
executeCommand: (command: string) => void,
10+
options = ''
11+
) {
12+
executeCommand(`npx nx generate ngx-deploy-npm:install ${options}`);
13+
}

0 commit comments

Comments
 (0)