Skip to content

Commit

Permalink
test: add unit test for builders
Browse files Browse the repository at this point in the history
  • Loading branch information
fpaul-1A committed Dec 11, 2023
1 parent e70c893 commit c9a5a07
Show file tree
Hide file tree
Showing 26 changed files with 521 additions and 11 deletions.
1 change: 1 addition & 0 deletions jest.config.ut.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ module.exports.getJestConfig = (rootDir, isAngularSetup) => ({
// workaround for the SDK Core
customExportConditions: ['require', 'node']
},
testTimeout: 10000,
workerIdleMemoryLimit: '700MB',
...isAngularSetup ? {
preset: 'jest-preset-angular',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { Architect } from '@angular-devkit/architect';
import { TestingArchitectHost } from '@angular-devkit/architect/testing';
import { schema } from '@angular-devkit/core';
import { cleanVirtualFileSystem, useVirtualFileSystem } from '@o3r/test-helpers';
import * as fs from 'node:fs';
import * as path from 'node:path';
import { ComponentExtractorBuilderSchema } from './schema';

describe('Component Extractor Builder', () => {
const workspaceRoot = path.join('..', '..', '..', '..', '..');
let architect: Architect;
let architectHost: TestingArchitectHost;
let virtualFileSystem: typeof fs;

beforeEach(async () => {
virtualFileSystem = useVirtualFileSystem();

const registry = new schema.CoreSchemaRegistry();
registry.addPostTransform(schema.transforms.addUndefinedDefaults);
architectHost = new TestingArchitectHost(path.resolve(__dirname, workspaceRoot), __dirname);
architect = new Architect(architectHost, registry);
await architectHost.addBuilderFromPackage(path.resolve(__dirname, '..', '..'));
});
afterEach(() => {
cleanVirtualFileSystem();
});

it('should extract components', async () => {
const options: ComponentExtractorBuilderSchema = {
tsConfig: 'apps/showcase/tsconfig.cms.json',
configOutputFile: path.resolve(__dirname, `${workspaceRoot}/apps/showcase/component.config.metadata.json`),
componentOutputFile: path.resolve(__dirname, `${workspaceRoot}/apps/showcase/component.class.metadata.json`),
name: 'showcase',
libraries: [],
placeholdersMetadataFilePath: path.resolve(__dirname, `${workspaceRoot}/apps/showcase/placeholders.metadata.manual.json`),
exposedComponentSupport: true,
globalConfigCategories: [
{ name: 'globalCategory', label: 'Global category' }
],
filePattern: 'src/**/*.(component|config|module).ts',
inline: false,
strictMode: false,
watch: false
};
const run = await architect.scheduleBuilder('@o3r/components:extractor', options);
const output = await run.result;
expect(output.error).toBe(undefined);
await run.stop();

const componentOutput = JSON.parse(virtualFileSystem.readFileSync(options.componentOutputFile, {encoding: 'utf8'}));
expect(typeof componentOutput).toBe('object');
expect(typeof componentOutput.length).toBe('number');
expect(componentOutput[0].library).toBe('showcase');
expect(componentOutput[0].name).toMatch(/.*Component$/);
expect(componentOutput[0].path).toMatch(/.*component.ts$/);
expect(componentOutput[0].templatePath).toMatch(/.*template.html$/);

const configOutput = JSON.parse(virtualFileSystem.readFileSync(options.configOutputFile, {encoding: 'utf8'}));
expect(typeof configOutput).toBe('object');
expect(typeof configOutput.length).toBe('number');
expect(configOutput[0].library).toBe('showcase');
expect(configOutput[0].name).toMatch(/.*Config$/);
expect(configOutput[0].path).toMatch(/.*config.ts$/);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export default createBuilder<ComponentExtractorBuilderSchema>(async (options, co
const execute = async (): Promise<BuilderOutput> => {
context.reportProgress(0, STEP_NUMBER, 'Checking required options');
const tsConfig = path.resolve(context.workspaceRoot, options.tsConfig);
const tsconfigExists = await new Promise<boolean>((resolve) => fs.exists(tsConfig, resolve));
const tsconfigExists = fs.existsSync(tsConfig);
if (!tsconfigExists) {
context.logger.error(`${tsConfig} not found`);

Expand Down
2 changes: 2 additions & 0 deletions packages/@o3r/components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -122,12 +122,14 @@
"jest-junit": "~16.0.0",
"jest-preset-angular": "~13.1.1",
"jsonc-eslint-parser": "~2.4.0",
"memfs": "~4.6.0",
"nx": "~16.10.0",
"pid-from-port": "^1.1.3",
"rxjs": "^7.8.1",
"ts-jest": "~29.1.1",
"ts-node": "~10.9.1",
"typescript": "~5.1.6",
"unionfs": "~4.5.1",
"zone.js": "~0.13.1"
},
"engines": {
Expand Down
6 changes: 6 additions & 0 deletions packages/@o3r/components/testing/setup-jest.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,8 @@
import 'jest-preset-angular/setup-jest';

global.setImmediate ||= ((fn: any, ...args: any) => {
// eslint-disable-next-line @typescript-eslint/no-implied-eval
const ref = global.setTimeout(fn, 0, ...args);
jest.runAllTimers();
return ref;
}) as any;
1 change: 1 addition & 0 deletions packages/@o3r/components/tsconfig.spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"rootDir": ".",
},
"include": [
"./builders/**/*.spec.ts",
"./src/**/*.spec.ts",
"./schematics/**/*.spec.ts"
],
Expand Down
2 changes: 1 addition & 1 deletion packages/@o3r/extractors/src/utils/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export function getLibraryModulePath(libraryName: string, executionDir: string =
};

const moduleIndexPath = getPackagePath(packageJsonInDist) || getPackagePath(packageJson);
const libraryNameForRegExp = libraryName.replace('/', '[\\\\/]').replace(/-/g, '[\\\\/-]');
const libraryNameForRegExp = libraryName.replace(/\\+|\//g, '[\\\\/]').replace(/-/g, '[\\\\/-]');
const libraryReg = new RegExp('^(.*?)' + libraryNameForRegExp + '[\\\\/]?(dist)?');
const matches = moduleIndexPath?.match(libraryReg);
if (!matches) {
Expand Down
51 changes: 51 additions & 0 deletions packages/@o3r/localization/builders/i18n/index.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { Architect } from '@angular-devkit/architect';
import { TestingArchitectHost } from '@angular-devkit/architect/testing';
import { schema } from '@angular-devkit/core';
import { cleanVirtualFileSystem, useVirtualFileSystem } from '@o3r/test-helpers';
import * as fs from 'node:fs';
import * as path from 'node:path';
import { I18nBuilderSchema } from './schema';

describe('Localization i18n Builder', () => {
const workspaceRoot = path.join('..', '..', '..', '..', '..');
let architect: Architect;
let architectHost: TestingArchitectHost;
let virtualFileSystem: typeof fs;

beforeEach(async () => {
virtualFileSystem = useVirtualFileSystem();

const registry = new schema.CoreSchemaRegistry();
registry.addPostTransform(schema.transforms.addUndefinedDefaults);
architectHost = new TestingArchitectHost(path.resolve(__dirname, workspaceRoot), __dirname);
architect = new Architect(architectHost, registry);
await architectHost.addBuilderFromPackage(path.resolve(__dirname, '..', '..'));
});
afterEach(() => {
cleanVirtualFileSystem();
});

it('should generate the i18n', async () => {
const i18nFolder = path.resolve(__dirname, `${workspaceRoot}/apps/showcase/src/components/showcase/localization/i18n`);
await virtualFileSystem.promises.mkdir(i18nFolder, {recursive: true});
const options: I18nBuilderSchema = {
localizationConfigs: [
{
localizationFiles: [
'apps/showcase/src/!(i18n)/**/*.localization.json'
],
i18nFolderPath: 'i18n'
}
],
defaultLanguageFile: 'en-GB.json'
};
const run = await architect.scheduleBuilder('@o3r/localization:i18n', options);
const output = await run.result;
expect(output.error).toBe(undefined);
await run.stop();

const i18nOutput = JSON.parse(virtualFileSystem.readFileSync(path.join(i18nFolder, 'en-GB.json'), {encoding: 'utf8'}));
expect(typeof i18nOutput).toBe('object');
expect(Object.keys(i18nOutput)[0]).toMatch(/o3r-.*/);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { Architect } from '@angular-devkit/architect';
import { TestingArchitectHost } from '@angular-devkit/architect/testing';
import { schema } from '@angular-devkit/core';
import { cleanVirtualFileSystem, useVirtualFileSystem } from '@o3r/test-helpers';
import * as fs from 'node:fs';
import * as path from 'node:path';
import { LocalizationExtractorBuilderSchema } from './schema';

describe('Localization Extractor Builder', () => {
const workspaceRoot = path.join('..', '..', '..', '..', '..');
let architect: Architect;
let architectHost: TestingArchitectHost;
let virtualFileSystem: typeof fs;

beforeEach(async () => {
virtualFileSystem = useVirtualFileSystem();

const registry = new schema.CoreSchemaRegistry();
registry.addPostTransform(schema.transforms.addUndefinedDefaults);
architectHost = new TestingArchitectHost(path.resolve(__dirname, workspaceRoot), __dirname);
architect = new Architect(architectHost, registry);
await architectHost.addBuilderFromPackage(path.resolve(__dirname, '..', '..'));
});
afterEach(() => {
cleanVirtualFileSystem();
});

it('should extract the localizations', async () => {
const options: LocalizationExtractorBuilderSchema = {
tsConfig: 'apps/showcase/tsconfig.cms.json',
outputFile: path.resolve(__dirname, `${workspaceRoot}/apps/showcase/localisation.metadata.json`),
libraries: [],
extraFilePatterns: [
'src/i18n/*.localization.json'
],
watch: false,
ignoreDuplicateKeys: false,
inline: false,
sortKeys: false
};
const run = await architect.scheduleBuilder('@o3r/localization:extractor', options);
const output = await run.result;
expect(output.error).toBe(undefined);
await run.stop();

const localizationOutput = JSON.parse(virtualFileSystem.readFileSync(options.outputFile, {encoding: 'utf8'}));
expect(typeof localizationOutput).toBe('object');
expect(typeof localizationOutput.length).toBe('number');
expect(localizationOutput[0].key).toMatch(/o3r-.*/);
});
});
72 changes: 72 additions & 0 deletions packages/@o3r/localization/builders/localization/index.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import {Architect, createBuilder} from '@angular-devkit/architect';
import { TestingArchitectHost } from '@angular-devkit/architect/testing';
import { schema } from '@angular-devkit/core';
import { cleanVirtualFileSystem, useVirtualFileSystem } from '@o3r/test-helpers';
import * as fs from 'node:fs';
import * as path from 'node:path';
import { of } from 'rxjs';
import { LocalizationBuilderSchema } from './schema';

describe('Localization Builder', () => {
const workspaceRoot = path.join('..', '..', '..', '..', '..');
let architect: Architect;
let architectHost: TestingArchitectHost;
let virtualFileSystem: typeof fs;

beforeEach(async () => {
virtualFileSystem = useVirtualFileSystem();

const registry = new schema.CoreSchemaRegistry();
registry.addPostTransform(schema.transforms.addUndefinedDefaults);
architectHost = new TestingArchitectHost(path.resolve(__dirname, workspaceRoot), __dirname);
architect = new Architect(architectHost, registry);
await architectHost.addBuilderFromPackage(path.resolve(__dirname, '..', '..'));
architectHost.addBuilder('noop', createBuilder(() => of({success: true})), '', {
type: 'object',
additionalProperties: true
});
architectHost.addTarget({project: 'showcase', target: 'compile'}, 'noop', {
outputPath: path.resolve(__dirname, `${workspaceRoot}/apps/showcase/dist`)
});
architectHost.addTarget({project: 'showcase', target: 'extract-translations'}, 'noop', {
outputFile: path.resolve(__dirname, `${workspaceRoot}/apps/showcase/localisation.metadata.json`)
});
await virtualFileSystem.promises.mkdir(path.resolve(__dirname, `${workspaceRoot}/apps/showcase`), {recursive: true});
await virtualFileSystem.promises.writeFile(path.resolve(__dirname, `${workspaceRoot}/apps/showcase/localisation.metadata.json`), '[]');
});
afterEach(() => {
cleanVirtualFileSystem();
});

it('should genere the localizations', async () => {
const options: LocalizationBuilderSchema = {
browserTarget: 'showcase:compile',
localizationExtracterTarget: 'showcase:extract-translations',
locales: [
'en-GB',
'fr-FR'
],
assets: [
'apps/showcase/src/assets/locales',
'apps/showcase/src/assets/locales/*',
'apps/showcase/src/components/**/i18n'
],
outputPath: path.resolve(__dirname, `${workspaceRoot}/apps/showcase/dev-resources/localizations`),
checkUnusedTranslation: true,
defaultLanguageMapping: {},
failIfMissingMetadata: false,
watch: false,
ignoreReferencesIfNotDefault: false,
useMetadataAsDefault: true
};
await virtualFileSystem.promises.mkdir(options.outputPath, {recursive: true});
const run = await architect.scheduleBuilder('@o3r/localization:localization', options);
const output = await run.result;
expect(output.error).toBe(undefined);
await run.stop();

const localizationOutput = virtualFileSystem.readdirSync(options.outputPath);
expect(localizationOutput).toContain('en-GB.json');
expect(localizationOutput).toContain('fr-FR.json');
});
});
4 changes: 2 additions & 2 deletions packages/@o3r/localization/builders/localization/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ function startMetadataGenerator(localizationExtractorTarget: Target, context: Bu
* @param context Ng Builder context
*/
async function checkMetadata(localizationMetaDataFile: string, localizationExtractorTarget: Target, context: BuilderContext): Promise<BuilderOutput | undefined> {
let metaDataExists = await new Promise<boolean>((resolve) => fs.exists(localizationMetaDataFile, resolve));
let metaDataExists = fs.existsSync(localizationMetaDataFile);
if (!metaDataExists) {
context.logger.warn(`The file ${localizationMetaDataFile} does not exist, the extractor will be run`);
context.reportProgress(2, STEP_NUMBER, 'Generating Localization metadata file');
Expand All @@ -306,7 +306,7 @@ async function checkMetadata(localizationMetaDataFile: string, localizationExtra
if (!extractorBuildResult.success) {
return extractorBuildResult;
} else {
metaDataExists = await new Promise<boolean>((resolve) => fs.exists(localizationMetaDataFile, resolve));
metaDataExists = fs.existsSync(localizationMetaDataFile);
if (!metaDataExists) {
return {
success: false,
Expand Down
2 changes: 2 additions & 0 deletions packages/@o3r/localization/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -123,13 +123,15 @@
"jest-junit": "~16.0.0",
"jest-preset-angular": "~13.1.1",
"jsonc-eslint-parser": "~2.4.0",
"memfs": "~4.6.0",
"nx": "~16.10.0",
"pid-from-port": "^1.1.3",
"rxjs": "^7.8.1",
"semver": "^7.5.2",
"ts-jest": "~29.1.1",
"ts-node": "~10.9.1",
"typescript": "~5.1.6",
"unionfs": "~4.5.1",
"zone.js": "~0.13.1"
},
"engines": {
Expand Down
7 changes: 7 additions & 0 deletions packages/@o3r/localization/testing/setup-jest.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,9 @@
import 'jest-preset-angular/setup-jest';
import 'isomorphic-fetch';

global.setImmediate ||= ((fn: any, ...args: any) => {
// eslint-disable-next-line @typescript-eslint/no-implied-eval
const ref = global.setTimeout(fn, 0, ...args);
jest.runAllTimers();
return ref;
}) as any;
Loading

0 comments on commit c9a5a07

Please sign in to comment.