From b4db6e8f232d2a02f2b624eefb6e427babd13bb1 Mon Sep 17 00:00:00 2001 From: Colum Ferry Date: Mon, 5 Dec 2022 12:00:49 +0000 Subject: [PATCH] fix(angular): standalone angular projects with karma should function (#13626) --- .../__snapshots__/karma-project.spec.ts.snap | 115 ++++++++++++++++++ .../karma.conf.js__tmpl__ | 17 ++- .../karma-project/karma-project.spec.ts | 20 +++ .../lib/generate-karma-project-files.ts | 16 +++ 4 files changed, 166 insertions(+), 2 deletions(-) diff --git a/packages/angular/src/generators/karma-project/__snapshots__/karma-project.spec.ts.snap b/packages/angular/src/generators/karma-project/__snapshots__/karma-project.spec.ts.snap index 946578a2c0b52..98b6cd2e1a252 100644 --- a/packages/angular/src/generators/karma-project/__snapshots__/karma-project.spec.ts.snap +++ b/packages/angular/src/generators/karma-project/__snapshots__/karma-project.spec.ts.snap @@ -15,6 +15,53 @@ module.exports = function (config) { dir: join(__dirname, '../../coverage/libs/nested-lib') } }); +};" +`; + +exports[`karmaProject --root-project should generate the right karma.conf.js file for a nested project in a workspace with a project at the root 2`] = ` +"// Karma configuration file, see link for more information +// https://karma-runner.github.io/6.4/config/configuration-file.html + +const { constants } = require('karma'); +const { join } = require('path'); + +module.exports = (config) => { + config.set({ + basePath: '', + frameworks: ['jasmine', '@angular-devkit/build-angular'], + plugins: [ + require('karma-jasmine'), + require('karma-chrome-launcher'), + require('karma-jasmine-html-reporter'), + require('karma-coverage'), + require('@angular-devkit/build-angular/plugins/karma'), + ], + client: { + jasmine: { + // you can add configuration options for Jasmine here + // the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html + // for example, you can disable the random execution with \`random: false\` + // or set a specific seed with \`seed: 4321\` + }, + clearContext: false, // leave Jasmine Spec Runner output visible in browser + }, + jasmineHtmlReporter: { + suppressAll: true, // removes the duplicated traces + }, + coverageReporter: { + dir: join(__dirname, 'coverage/root-app'), + subdir: '.', + reporters: [{ type: 'html' }, { type: 'text-summary' }], + }, + reporters: ['progress', 'kjhtml'], + port: 9876, + colors: true, + logLevel: constants.LOG_INFO, + autoWatch: true, + browsers: ['Chrome'], + singleRun: true, + restartOnFileChange: true, + }); }; " `; @@ -67,6 +114,74 @@ module.exports = (config) => { " `; +exports[`karmaProject --root-project should use get syntax when root project does not have karma conf with set syntax 1`] = ` +"// Karma configuration file, see link for more information +// https://karma-runner.github.io/6.4/config/configuration-file.html + +const { join } = require('path'); +const getBaseKarmaConfig = require('../../karma.conf'); + +module.exports = function (config) { + const baseConfig = getBaseKarmaConfig(config); + + config.set({ + ...baseConfig, + coverageReporter: { + ...baseConfig.coverageReporter, + dir: join(__dirname, '../../coverage/libs/nested-lib') + } + }); +};" +`; + +exports[`karmaProject --root-project should use get syntax when root project does not have karma conf with set syntax 2`] = ` +"// Karma configuration file, see link for more information +// https://karma-runner.github.io/1.0/config/configuration-file.html + +const { join } = require('path'); +const { constants } = require('karma'); + +module.exports = () => { + return { + basePath: '', + frameworks: ['jasmine', '@angular-devkit/build-angular'], + plugins: [ + require('karma-jasmine'), + require('karma-chrome-launcher'), + require('karma-jasmine-html-reporter'), + require('karma-coverage'), + require('@angular-devkit/build-angular/plugins/karma'), + ], + client: { + jasmine: { + // you can add configuration options for Jasmine here + // the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html + // for example, you can disable the random execution with \`random: false\` + // or set a specific seed with \`seed: 4321\` + }, + clearContext: false, // leave Jasmine Spec Runner output visible in browser + }, + jasmineHtmlReporter: { + suppressAll: true, // removes the duplicated traces + }, + coverageReporter: { + dir: join(__dirname, './coverage'), + subdir: '.', + reporters: [{ type: 'html' }, { type: 'text-summary' }], + }, + reporters: ['progress', 'kjhtml'], + port: 9876, + colors: true, + logLevel: constants.LOG_INFO, + autoWatch: true, + browsers: ['Chrome'], + singleRun: true, + restartOnFileChange: true + }; +}; +" +`; + exports[`karmaProject should create a karma.conf.js 1`] = ` "// Karma configuration file, see link for more information // https://karma-runner.github.io/6.4/config/configuration-file.html diff --git a/packages/angular/src/generators/karma-project/files/workspace-with-root-project/karma.conf.js__tmpl__ b/packages/angular/src/generators/karma-project/files/workspace-with-root-project/karma.conf.js__tmpl__ index dbbdf05ed972a..32d54474c154c 100644 --- a/packages/angular/src/generators/karma-project/files/workspace-with-root-project/karma.conf.js__tmpl__ +++ b/packages/angular/src/generators/karma-project/files/workspace-with-root-project/karma.conf.js__tmpl__ @@ -1,7 +1,7 @@ // Karma configuration file, see link for more information // https://karma-runner.github.io/6.4/config/configuration-file.html -const { join } = require('path'); +const { join } = require('path');<% if (rootProjectWithConfigSet) { %> const setBaseKarmaConfig = require('<%= offsetFromRoot %>karma.conf'); module.exports = function (config) { @@ -12,4 +12,17 @@ module.exports = function (config) { dir: join(__dirname, '<%= offsetFromRoot %>coverage/<%= projectRoot %>') } }); -}; +};<% } else { %> +const getBaseKarmaConfig = require('<%= offsetFromRoot %>karma.conf'); + +module.exports = function (config) { + const baseConfig = getBaseKarmaConfig(config); + + config.set({ + ...baseConfig, + coverageReporter: { + ...baseConfig.coverageReporter, + dir: join(__dirname, '<%= offsetFromRoot %>coverage/<%= projectRoot %>') + } + }); +};<% } %> \ No newline at end of file diff --git a/packages/angular/src/generators/karma-project/karma-project.spec.ts b/packages/angular/src/generators/karma-project/karma-project.spec.ts index 22432dbf05828..3ddb922354bac 100644 --- a/packages/angular/src/generators/karma-project/karma-project.spec.ts +++ b/packages/angular/src/generators/karma-project/karma-project.spec.ts @@ -253,6 +253,26 @@ describe('karmaProject', () => { expect( tree.read('libs/nested-lib/karma.conf.js', 'utf-8') ).toMatchSnapshot(); + expect(tree.read('karma.conf.js', 'utf-8')).toMatchSnapshot(); + }); + + it('should use get syntax when root project does not have karma conf with set syntax', async () => { + await applicationGenerator(tree, { + name: 'root-app', + unitTestRunner: UnitTestRunner.Jest, + rootProject: true, + }); + await libraryGenerator(tree, { + name: 'nested-lib', + unitTestRunner: UnitTestRunner.None, + }); + await karmaProjectGenerator(tree, { project: 'nested-lib' }); + + expect(tree.exists('libs/nested-lib/karma.conf.js')).toBe(true); + expect( + tree.read('libs/nested-lib/karma.conf.js', 'utf-8') + ).toMatchSnapshot(); + expect(tree.read('karma.conf.js', 'utf-8')).toMatchSnapshot(); }); }); }); diff --git a/packages/angular/src/generators/karma-project/lib/generate-karma-project-files.ts b/packages/angular/src/generators/karma-project/lib/generate-karma-project-files.ts index f446583bfcb40..55912fe9b15bb 100644 --- a/packages/angular/src/generators/karma-project/lib/generate-karma-project-files.ts +++ b/packages/angular/src/generators/karma-project/lib/generate-karma-project-files.ts @@ -6,6 +6,7 @@ import { offsetFromRoot, readProjectConfiguration, } from '@nrwl/devkit'; +import { tsquery } from '@phenomnomnominal/tsquery'; export function generateKarmaProjectFiles(tree: Tree, project: string): void { const projectConfig = readProjectConfiguration(tree, project); @@ -44,6 +45,7 @@ export function generateKarmaProjectFiles(tree: Tree, project: string): void { tmpl: '', projectRoot: projectConfig.root, offsetFromRoot: offsetFromRoot(projectConfig.root), + rootProjectWithConfigSet: isUsingConfigSetInBaseKarmaConfig(tree), } ); } @@ -59,3 +61,17 @@ function isWorkspaceWithProjectAtRoot(tree: Tree): boolean { return false; } + +function isUsingConfigSetInBaseKarmaConfig(tree: Tree) { + if (!tree.exists('karma.conf.js')) { + return false; + } + + const CONFIG_SET_SELECTOR = + 'PropertyAccessExpression:has(Identifier[name=config], Identifier[name=set])'; + + const ast = tsquery.ast(tree.read('karma.conf.js', 'utf-8')); + const nodes = tsquery(ast, CONFIG_SET_SELECTOR, { visitAllChildren: true }); + + return nodes.length > 0; +}