/** * Main method. * Standalone program that executes the real codegen and tests that * ngsummary.json files are used for libraries. */ function main() { console.log(`testing usage of ngsummary.json files in libraries...`); const basePath = path.resolve(__dirname, '..'); const project = path.resolve(basePath, 'tsconfig-build.json'); const readFiles: string[] = []; const writtenFiles: {fileName: string, content: string}[] = []; class AssertingHostContext extends NodeCompilerHostContext { readFile(fileName: string): string { if (/.*\/node_modules\/.*/.test(fileName) && !/.*ngsummary\.json$/.test(fileName)) { // Only allow to read summaries from node_modules return null; } readFiles.push(path.relative(basePath, fileName)); return super.readFile(fileName); } readResource(s: string): Promise<string> { readFiles.push(path.relative(basePath, s)); return super.readResource(s); } } const config = tsc.readConfiguration(project, basePath); config.ngOptions.basePath = basePath; // This flag tells ngc do not recompile libraries. config.ngOptions.generateCodeForLibraries = false; console.log(`>>> running codegen for ${project}`); codegen( config, (host) => { host.writeFile = (fileName: string, content: string) => { fileName = path.relative(basePath, fileName); writtenFiles.push({fileName, content}); }; return new AssertingHostContext(); }) .then((exitCode: any) => { console.log(`>>> codegen done, asserting read files`); assertSomeFileMatch(readFiles, /^node_modules\/.*\.ngsummary\.json$/); assertNoFileMatch(readFiles, /^node_modules\/.*\.metadata.json$/); assertNoFileMatch(readFiles, /^node_modules\/.*\.html$/); assertNoFileMatch(readFiles, /^node_modules\/.*\.css$/); assertNoFileMatch(readFiles, /^src\/.*\.ngsummary\.json$/); assertSomeFileMatch(readFiles, /^src\/.*\.html$/); assertSomeFileMatch(readFiles, /^src\/.*\.css$/); console.log(`>>> asserting written files`); assertWrittenFile(writtenFiles, /^src\/module\.ngfactory\.ts$/, /class MainModuleInjector/); console.log(`done, no errors.`); process.exit(exitCode); }) .catch((e: any) => { console.error(e.stack); console.error('Compilation failed'); process.exit(1); }); }
function lazyRoutesTest() { const basePath = path.join(__dirname, '../ngtools_src'); const project = path.join(basePath, 'tsconfig-build.json'); const config = tsc.readConfiguration(project, basePath); const host = ts.createCompilerHost(config.parsed.options, true); const program = ts.createProgram(config.parsed.fileNames, config.parsed.options, host); config.ngOptions.basePath = basePath; const lazyRoutes = __NGTOOLS_PRIVATE_API_2.listLazyRoutes({ program, host, angularCompilerOptions: config.ngOptions, entryModule: 'app.module#AppModule' }); const expectations: {[route: string]: string} = { './lazy.module#LazyModule': 'lazy.module.ts', './feature/feature.module#FeatureModule': 'feature/feature.module.ts', './feature/lazy-feature.module#LazyFeatureModule': 'feature/lazy-feature.module.ts', './feature.module#FeatureModule': 'feature/feature.module.ts', './lazy-feature-nested.module#LazyFeatureNestedModule': 'feature/lazy-feature-nested.module.ts', 'feature2/feature2.module#Feature2Module': 'feature2/feature2.module.ts', './default.module': 'feature2/default.module.ts', 'feature/feature.module#FeatureModule': 'feature/feature.module.ts' }; Object.keys(lazyRoutes).forEach((route: string) => { assert(route in expectations, `Found a route that was not expected: "${route}".`); assert( lazyRoutes[route] == path.join(basePath, expectations[route]), `Route "${route}" does not point to the expected absolute path ` + `"${path.join(basePath, expectations[route])}". It points to "${lazyRoutes[route]}"`); }); // Verify that all expectations were met. assert.deepEqual( Object.keys(lazyRoutes), Object.keys(expectations), `Expected routes listed to be: \n` + ` ${JSON.stringify(Object.keys(expectations))}\n` + `Actual:\n` + ` ${JSON.stringify(Object.keys(lazyRoutes))}\n`); }
/** * Main method. * Standalone program that executes the real codegen and tests that * ngsummary.json files are used for libraries. */ function main() { console.log(`testing usage of ngsummary.json files in libraries...`); const basePath = path.resolve(__dirname, '..'); const project = path.resolve(basePath, 'tsconfig-build.json'); const readFiles: string[] = []; class AssertingHostContext extends NodeCompilerHostContext { readFile(fileName: string): string { readFiles.push(path.relative(basePath, fileName)); return super.readFile(fileName); } readResource(s: string): Promise<string> { readFiles.push(path.relative(basePath, s)); return super.readResource(s); } } const config = tsc.readConfiguration(project, basePath); config.ngOptions.basePath = basePath; // This flag tells ngc do not recompile libraries. config.ngOptions.generateCodeForLibraries = false; console.log(`>>> running codegen for ${project}`); codegen(config, (host) => new AssertingHostContext()) .then((exitCode: any) => { console.log(`>>> codegen done, asserting read files`); assertSomeFileMatch(readFiles, /^node_modules\/.*\.ngsummary\.json$/); assertNoFileMatch(readFiles, /^node_modules\/.*\.html$/); assertNoFileMatch(readFiles, /^node_modules\/.*\.css$/); assertNoFileMatch(readFiles, /^src\/.*\.ngsummary\.json$/); assertSomeFileMatch(readFiles, /^src\/.*\.html$/); assertSomeFileMatch(readFiles, /^src\/.*\.css$/); console.log(`done, no errors.`); process.exit(exitCode); }) .catch((e: any) => { console.error(e.stack); console.error('Compilation failed'); process.exit(1); }); }
function codeGenTest() { const basePath = path.join(__dirname, '../ngtools_src'); const project = path.join(basePath, 'tsconfig-build.json'); const readResources: string[] = []; const wroteFiles: string[] = []; const config = tsc.readConfiguration(project, basePath); const hostContext = new NodeCompilerHostContext(); const delegateHost = ts.createCompilerHost(config.parsed.options, true); const host: ts.CompilerHost = Object.assign( {}, delegateHost, {writeFile: (fileName: string, ...rest: any[]) => { wroteFiles.push(fileName); }}); const program = ts.createProgram(config.parsed.fileNames, config.parsed.options, host); config.ngOptions.basePath = basePath; console.log(`>>> running codegen for ${project}`); return __NGTOOLS_PRIVATE_API_2 .codeGen({ basePath, compilerOptions: config.parsed.options, program, host, angularCompilerOptions: config.ngOptions, // i18n options. i18nFormat: null, i18nFile: null, locale: null, readResource: (fileName: string) => { readResources.push(fileName); return hostContext.readResource(fileName); } }) .then(() => { console.log(`>>> codegen done, asserting read and wrote files`); // Assert for each file that it has been read and each `ts` has a written file associated. const allFiles = glob.sync(path.join(basePath, '**/*'), {nodir: true}); allFiles.forEach((fileName: string) => { // Skip tsconfig. if (fileName.match(/tsconfig-build.json$/)) { return; } // Assert that file was read. if (fileName.match(/\.module\.ts$/)) { const factory = fileName.replace(/\.module\.ts$/, '.module.ngfactory.ts'); assert(wroteFiles.indexOf(factory) != -1, `Expected file "${factory}" to be written.`); } else if (fileName.match(/\.css$/) || fileName.match(/\.html$/)) { assert( readResources.indexOf(fileName) != -1, `Expected resource "${fileName}" to be read.`); } }); console.log(`done, no errors.`); }) .catch((e: any) => { console.error(e.stack); console.error('Compilation failed'); throw e; }); }
function codeGenTest(forceError = false) { const basePath = path.join(__dirname, '../ngtools_src'); const srcPath = path.join(__dirname, '../src'); const project = path.join(basePath, 'tsconfig-build.json'); const readResources: string[] = []; const wroteFiles: string[] = []; const config = tsc.readConfiguration(project, basePath); const delegateHost = ts.createCompilerHost(config.parsed.options, true); const host: ts.CompilerHost = Object.assign( {}, delegateHost, {writeFile: (fileName: string, ...rest: any[]) => { wroteFiles.push(fileName); }}); const program = ts.createProgram(config.parsed.fileNames, config.parsed.options, host); config.ngOptions.basePath = basePath; console.log(`>>> running codegen for ${project}`); if (forceError) { console.log(`>>> asserting that missingTranslation param with error value throws`); } return __NGTOOLS_PRIVATE_API_2 .codeGen({ basePath, compilerOptions: config.parsed.options, program, host, angularCompilerOptions: config.ngOptions, // i18n options. i18nFormat: 'xlf', i18nFile: path.join(srcPath, 'messages.fi.xlf'), locale: 'fi', missingTranslation: forceError ? 'error' : 'ignore', readResource: (fileName: string) => { readResources.push(fileName); if (!host.fileExists(fileName)) { throw new Error(`Compilation failed. Resource file not found: ${fileName}`); } return Promise.resolve(host.readFile(fileName)); } }) .then(() => { console.log(`>>> codegen done, asserting read and wrote files`); // Assert for each file that it has been read and each `ts` has a written file associated. const allFiles = glob.sync(path.join(basePath, '**/*'), {nodir: true}); allFiles.forEach((fileName: string) => { // Skip tsconfig. if (fileName.match(/tsconfig-build.json$/)) { return; } // Assert that file was read. if (fileName.match(/\.module\.ts$/)) { const factory = fileName.replace(/\.module\.ts$/, '.module.ngfactory.ts'); assert(wroteFiles.indexOf(factory) != -1, `Expected file "${factory}" to be written.`); } else if (fileName.match(/\.css$/) || fileName.match(/\.html$/)) { assert( readResources.indexOf(fileName) != -1, `Expected resource "${fileName}" to be read.`); } }); console.log(`done, no errors.`); }) .catch((e: Error) => { if (forceError) { assert( e.message.match(`Missing translation for message`), `Expected error message for missing translations`); console.log(`done, error catched`); } else { console.error(e.stack); console.error('Compilation failed'); throw e; } }); }
function i18nTest() { const basePath = path.join(__dirname, '../ngtools_src'); const project = path.join(basePath, 'tsconfig-build.json'); const readResources: string[] = []; const wroteFiles: string[] = []; const config = tsc.readConfiguration(project, basePath); const hostContext = new NodeCompilerHostContext(); const delegateHost = ts.createCompilerHost(config.parsed.options, true); const host: ts.CompilerHost = Object.assign( {}, delegateHost, {writeFile: (fileName: string, ...rest: any[]) => { wroteFiles.push(fileName); }}); const program = ts.createProgram(config.parsed.fileNames, config.parsed.options, host); config.ngOptions.basePath = basePath; console.log(`>>> running i18n extraction for ${project}`); return __NGTOOLS_PRIVATE_API_2 .extractI18n({ basePath, compilerOptions: config.parsed.options, program, host, angularCompilerOptions: config.ngOptions, i18nFormat: 'xlf', locale: undefined, outFile: undefined, readResource: (fileName: string) => { readResources.push(fileName); return hostContext.readResource(fileName); }, }) .then(() => { console.log(`>>> i18n extraction done, asserting read and wrote files`); const allFiles = glob.sync(path.join(basePath, '**/*'), {nodir: true}); assert(wroteFiles.length == 1, `Expected a single message bundle file.`); assert( wroteFiles[0].endsWith('/ngtools_src/messages.xlf'), `Expected the bundle file to be "message.xlf".`); allFiles.forEach((fileName: string) => { // Skip tsconfig. if (fileName.match(/tsconfig-build.json$/)) { return; } // Assert that file was read. if (fileName.match(/\.css$/) || fileName.match(/\.html$/)) { assert( readResources.indexOf(fileName) != -1, `Expected resource "${fileName}" to be read.`); } }); console.log(`done, no errors.`); }) .catch((e: Error) => { console.error(e.stack); console.error('Extraction failed'); throw e; }); }