From bed2c743dce4fb7bf772fecdd3f5e1863c3d60aa Mon Sep 17 00:00:00 2001 From: Nico Jansen Date: Wed, 28 Dec 2016 14:18:45 +0100 Subject: [PATCH 1/5] feat(read-karma-config): Use karma configuration Use karma configuration if the `karmaConfigFile` is present. * Use karma's `files` to fill files in stryker * Use karma's `exclude` to fill files in stryker prefixed with a `!`. * Fill other karma settings (preprocessors, base path etc) in `karmaConfig` stryker option. This is later used in the test runner. * Set test runner to `karma` if not already set. --- src/KarmaConfigReader.ts | 82 ++++++++++++++++++ src/KarmaConfigWriter.ts | 72 ++++++++++++++++ src/index.ts | 11 ++- test/helpers/LoggerStub.ts | 15 ++++ test/helpers/chaiSetup.ts | 8 +- test/integration/KarmaConfigWriter.it.ts | 72 ++++++++++++++++ test/unit/KarmaConfigReaderSpec.ts | 54 ++++++++++++ test/unit/KarmaConfigWriterSpec.ts | 94 +++++++++++++++++++++ testResources/configs/example-karma.conf.js | 68 +++++++++++++++ testResources/configs/files-karma.conf.js | 12 +++ testResources/sampleProject/sdsd.js | 11 --- 11 files changed, 481 insertions(+), 18 deletions(-) create mode 100644 src/KarmaConfigReader.ts create mode 100644 src/KarmaConfigWriter.ts create mode 100644 test/helpers/LoggerStub.ts create mode 100644 test/integration/KarmaConfigWriter.it.ts create mode 100644 test/unit/KarmaConfigReaderSpec.ts create mode 100644 test/unit/KarmaConfigWriterSpec.ts create mode 100644 testResources/configs/example-karma.conf.js create mode 100644 testResources/configs/files-karma.conf.js delete mode 100644 testResources/sampleProject/sdsd.js diff --git a/src/KarmaConfigReader.ts b/src/KarmaConfigReader.ts new file mode 100644 index 0000000..e16a92a --- /dev/null +++ b/src/KarmaConfigReader.ts @@ -0,0 +1,82 @@ +import * as log4js from 'log4js'; +import * as path from 'path'; +import * as karma from 'karma'; +import { requireModule } from './utils'; + +const karmaConfigReaderLocation = 'karma/lib/config'; + +export default class KarmaConfigReader { + + private readonly log: log4js.Logger; + + constructor(private karmaConfigFile: string) { + if (this.karmaConfigFile) { + this.karmaConfigFile = path.resolve(this.karmaConfigFile); + } + this.log = log4js.getLogger('KarmaConfigReader'); + } + + read(): karma.ConfigOptions | null { + if (this.karmaConfigFile && typeof this.karmaConfigFile === 'string') { + this.log.info('Importing config from "%s"', this.karmaConfigFile); + try { + this.validateConfig(); + return this.readConfig(); + } catch (error) { + this.log.error(`Could not read karma configuration from ${this.karmaConfigFile}.`, error); + } + } + return null; + } + + private validateConfig() { + // Deligate validation of configuration to karma config lib, as it has nice and recognizable error handling + this.parseNativeKarmaConfig(); + } + + private readConfig(): karma.ConfigOptions { + // We cannot deligate config reading to karma's config reader, because we cannot serialize the result to child processes + // It results in: TypeError: Serializing native function: bound configure + const configModule = requireModule(this.karmaConfigFile); + const config = new Config(); + configModule(config); + + // Use native functionality of parsing the files, so we ensure that those are correctly resolved + const karmaOptions = this.parseNativeKarmaConfig(); + if (karmaOptions && karmaOptions.files) { + config['files'] = karmaOptions.files; + config['exclude'] = karmaOptions.exclude; + } + return config; + } + + private parseNativeKarmaConfig(): karma.ConfigOptions | null { + let cfg: any; + try { + cfg = require(karmaConfigReaderLocation); + } catch (e) { + this.log.warn(`Could not find karma config reader at "%s"`, karmaConfigReaderLocation); + } + if (cfg) { + return cfg.parseConfig(this.karmaConfigFile, {}); + } else { + return null; + } + } +} + +class Config implements karma.ConfigOptions { + [key: string]: any + + readonly LOG_DISABLE = 'OFF'; + readonly LOG_ERROR = 'ERROR'; + readonly LOG_WARN = 'WARN'; + readonly LOG_INFO = 'INFO'; + readonly LOG_DEBUG = 'DEBUG'; + + set(obj: any) { + for (let i in obj) { + this[i] = obj[i]; + } + } +} \ No newline at end of file diff --git a/src/KarmaConfigWriter.ts b/src/KarmaConfigWriter.ts new file mode 100644 index 0000000..d4dbf41 --- /dev/null +++ b/src/KarmaConfigWriter.ts @@ -0,0 +1,72 @@ +import * as log4js from 'log4js'; +import * as karma from 'karma'; +import { InputFileDescriptor } from 'stryker-api/core'; +import { ConfigWriter, Config as StrykerConfig } from 'stryker-api/config'; +import KarmaConfigReader from './KarmaConfigReader'; + +const log = log4js.getLogger('KarmaConfigWriter'); + +export default class KarmaConfigWriter implements ConfigWriter { + write(strykerConfig: StrykerConfig) { + const karmaConfig = new KarmaConfigReader(strykerConfig['karmaConfigFile']).read(); + if (karmaConfig) { + KarmaConfigWriter.importFiles(strykerConfig, karmaConfig); + KarmaConfigWriter.importDefaultKarmaConfig(strykerConfig, karmaConfig); + KarmaConfigWriter.overrideRunner(strykerConfig); + } + } + + private static overrideRunner(strykerConfig: StrykerConfig) { + if (!strykerConfig.testRunner) { + strykerConfig.testRunner = 'karma'; + } + } + + private static importFiles(strykerConfig: StrykerConfig, karmaConfig: karma.ConfigOptions) { + if (!strykerConfig.files) { + strykerConfig.files = []; + } + const files: (karma.FilePattern | string)[] = karmaConfig.files; + const exclude: string[] = karmaConfig.exclude; + if (files && Array.isArray(files)) { + const karmaFiles = files.map(KarmaConfigWriter.toInputFileDescriptor); + log.debug(`Importing following files from karma.conf file to stryker: ${JSON.stringify(karmaFiles)}`); + strykerConfig.files = strykerConfig.files + .concat(karmaFiles); + } + if (exclude && Array.isArray(exclude)) { + const ignores = exclude.map(fileToIgnore => `!${fileToIgnore}`); + log.debug(`Importing following "exclude" files from karma configuration: ${JSON.stringify(ignores)}`); + strykerConfig.files = strykerConfig.files.concat(ignores); + } + } + + private static importDefaultKarmaConfig(strykerConfig: StrykerConfig, karmaConfig: karma.ConfigOptions) { + if (strykerConfig['karmaConfig']) { + const target = strykerConfig['karmaConfig']; + for (let i in karmaConfig) { + if (!target[i]) { + target[i] = (karmaConfig)[i]; + } + } + } else { + strykerConfig['karmaConfig'] = karmaConfig; + } + } + + private static toInputFileDescriptor(karmaPattern: karma.FilePattern | string): InputFileDescriptor { + if (typeof karmaPattern === 'string') { + return { + pattern: karmaPattern, + included: true, + mutated: false + }; + } else { + return { + pattern: karmaPattern.pattern, + included: karmaPattern.included || false, + mutated: (karmaPattern as any)['mutated'] || false + }; + } + } +} \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index c09019f..24323c4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,7 @@ -import KarmaTestRunner from './KarmaTestRunner'; -import {TestRunnerFactory} from 'stryker-api/test_runner'; - -TestRunnerFactory.instance().register('karma', KarmaTestRunner); +import { TestRunnerFactory } from 'stryker-api/test_runner'; +import { ConfigWriterFactory } from 'stryker-api/config'; +import KarmaTestRunner from './KarmaTestRunner'; +import KarmaConfigWriter from './KarmaConfigWriter'; + +TestRunnerFactory.instance().register('karma', KarmaTestRunner); +ConfigWriterFactory.instance().register('karma', KarmaConfigWriter); \ No newline at end of file diff --git a/test/helpers/LoggerStub.ts b/test/helpers/LoggerStub.ts new file mode 100644 index 0000000..1fcf3c8 --- /dev/null +++ b/test/helpers/LoggerStub.ts @@ -0,0 +1,15 @@ +import * as sinon from 'sinon'; + +export default class LoggerStub { + error: sinon.SinonStub; + warn: sinon.SinonStub; + info: sinon.SinonStub; + debug: sinon.SinonStub; + + constructor() { + this.error = sinon.stub(); + this.warn = sinon.stub(); + this.info = sinon.stub(); + this.debug = sinon.stub(); + } +} diff --git a/test/helpers/chaiSetup.ts b/test/helpers/chaiSetup.ts index 2901092..2dc7d2d 100644 --- a/test/helpers/chaiSetup.ts +++ b/test/helpers/chaiSetup.ts @@ -1,3 +1,5 @@ -import * as chai from 'chai'; -import * as sinonChai from 'sinon-chai'; -chai.use(sinonChai); \ No newline at end of file +import * as chai from 'chai'; +import * as sinonChai from 'sinon-chai'; +import * as chaiAsPromised from 'chai-as-promised'; +chai.use(sinonChai); +chai.use(chaiAsPromised); diff --git a/test/integration/KarmaConfigWriter.it.ts b/test/integration/KarmaConfigWriter.it.ts new file mode 100644 index 0000000..ade11b8 --- /dev/null +++ b/test/integration/KarmaConfigWriter.it.ts @@ -0,0 +1,72 @@ +import { expect } from 'chai'; +import * as path from 'path'; +import { Config } from 'stryker-api/config'; +import KarmaConfigWriter from '../../src/KarmaConfigWriter'; + +function resolve(filePath: string) { + return path.resolve(`testResources/configs/${filePath}`).replace(/\\/g, '/'); +} + +function strykerConfig(karmaConfigPath: string) { + const config = new Config(); + config['karmaConfigFile'] = karmaConfigPath; + return config; +} + +describe('KarmaConfigWriter', () => { + + it('should override the stryker `files` property when no `files` were present', () => { + const config = strykerConfig('testResources/configs/files-karma.conf.js'); + new KarmaConfigWriter().write(config); + expect(config.files).to.deep.eq([ + { included: true, mutated: false, pattern: resolve('src/**/*.js') }, + { included: false, mutated: false, pattern: resolve('resources/**/*.js') }, + '!' + resolve('**/index.js'), + '!' + resolve('+(Error|InfiniteAdd).js'), + '!' + resolve('files-karma.conf.js')]); + }); + + it('should add to the stryker `files` property when `files` were already present', () => { + const config = strykerConfig('testResources/configs/files-karma.conf.js'); + config.files = ['some file']; + new KarmaConfigWriter().write(config); + expect(config.files).to.have.length(6); + expect(config.files[0]).to.be.eq('some file'); + }); + + it('should fill the "karmaConfig" object if no "karmaConfig" object was present', () => { + const config = strykerConfig(resolve('example-karma.conf.js')); + new KarmaConfigWriter().write(config); + + const expectedConfig: any = { + basePath: '', + frameworks: ['jasmine', 'requirejs'], + files: [ + ], + exclude: [ + resolve('example-karma.conf.js') + ], + preprocessors: { + }, + reporters: ['progress'], + port: 9876, + colors: true, + logLevel: 'INFO', + autoWatch: true, + browsers: ['Chrome'], + singleRun: false, + concurrency: Infinity, + }; + const actualConfig = config['karmaConfig']; + for (let i in expectedConfig) { + expect(actualConfig).to.have.property(i).with.deep.eq(expectedConfig[i], `Expected property ${i} with value ${JSON.stringify(actualConfig[i])} to eq ${JSON.stringify(expectedConfig[i])}`); + } + }); + + it('should not do anything if no "karmaConfigFile" property is present', () => { + const config = new Config(); + new KarmaConfigWriter().write(config); + expect(config.files).to.not.be.ok; + expect(config['karmaConfig']).to.not.be.ok; + }); +}); \ No newline at end of file diff --git a/test/unit/KarmaConfigReaderSpec.ts b/test/unit/KarmaConfigReaderSpec.ts new file mode 100644 index 0000000..aa57810 --- /dev/null +++ b/test/unit/KarmaConfigReaderSpec.ts @@ -0,0 +1,54 @@ +import * as sinon from 'sinon'; +import { expect } from 'chai'; +import * as log4js from 'log4js'; +const cfg: { parseConfig: sinon.SinonStub } = require('karma/lib/config'); +import KarmaConfigReader from '../../src/KarmaConfigReader'; +import LoggerStub from '../helpers/LoggerStub'; +import * as path from 'path'; +import * as utils from '../../src/utils'; + +describe('KarmaConfigReader', () => { + let sandbox: sinon.SinonSandbox; + let sut: KarmaConfigReader; + let log: LoggerStub; + let karmaConfigModule: sinon.SinonStub; + + beforeEach(() => { + log = new LoggerStub(); + sandbox = sinon.sandbox.create(); + karmaConfigModule = sandbox.stub(); + sandbox.stub(utils, 'requireModule').returns(karmaConfigModule); + sandbox.stub(cfg, 'parseConfig'); + sandbox.stub(log4js, 'getLogger').returns(log); + }); + + afterEach(() => sandbox.restore()); + + describe('read', () => { + + beforeEach(() => sut = new KarmaConfigReader('someLocation')); + + it('should log an error when the config has validation errors', () => { + const expectedConfigFileLocation = path.resolve('someLocation'); + cfg.parseConfig.throws(new Error('Config error')); + sut.read(); + expect(log.error).to.have.been.calledWith(sinon.match(`Could not read karma configuration from ${expectedConfigFileLocation}.`), sinon.match.has('message', 'Config error')); + expect(cfg.parseConfig).to.have.been.calledWith(expectedConfigFileLocation); + }); + + it('should load the config', () => { + karmaConfigModule.returns('expectedConfig'); + const acualConfig = sut.read(); + expect(karmaConfigModule).to.have.been.calledWith(sinon.match((obj: any) => typeof obj.set === 'function')); + expect(acualConfig).to.be.ok; + }); + }); + + describe('read without karmaConfigFile', () => { + beforeEach(() => sut = new KarmaConfigReader('')); + + it('should not read anything', () => { + expect(sut.read()).to.be.null; + }); + }); +}); \ No newline at end of file diff --git a/test/unit/KarmaConfigWriterSpec.ts b/test/unit/KarmaConfigWriterSpec.ts new file mode 100644 index 0000000..d287cd9 --- /dev/null +++ b/test/unit/KarmaConfigWriterSpec.ts @@ -0,0 +1,94 @@ +import * as sinon from 'sinon'; +import { expect } from 'chai'; +import * as karmaConfigReaderModule from '../../src/KarmaConfigReader'; +import KarmaConfigWriter from '../../src/KarmaConfigWriter'; +import { Config } from 'stryker-api/config'; + +describe('KarmaConfigWriter', () => { + let sut: KarmaConfigWriter; + let sandbox: sinon.SinonSandbox; + let karmaConfigReader: { read: sinon.SinonStub }; + let config: Config; + + beforeEach(() => { + sut = new KarmaConfigWriter(); + sandbox = sinon.sandbox.create(); + karmaConfigReader = { read: sandbox.stub() }; + sandbox.stub(karmaConfigReaderModule, 'default').returns(karmaConfigReader); + config = new Config(); + config['karmaConfigFile'] = 'expectedFile'; + }); + + afterEach(() => sandbox.restore()); + + describe('write', () => { + + it('should create karmaConfigReader using "karmaConfigFile"', () => { + sut.write(config); + expect(karmaConfigReaderModule.default).to.have.been.calledWith('expectedFile'); + expect(karmaConfigReaderModule.default).to.have.been.calledWithNew; + }); + + describe('without readable config', () => { + + it('should not override the runner', () => { + sut.write(config); + expect(config.testRunner).to.be.undefined; + }); + }); + + describe('with readable config', () => { + let karmaConfig: any; + + beforeEach(() => { + karmaConfig = {}; + karmaConfigReader.read.returns(karmaConfig); + }); + + it('should override the runner if it was not provided already', () => { + sut.write(config); + expect(config.testRunner).to.be.eq('karma'); + }); + + it('should not override the runner if it was provided already', () => { + config.testRunner = 'harry'; + sut.write(config); + expect(config.testRunner).to.be.eq('harry'); + }); + + it('should import files', () => { + karmaConfig.files = [{ pattern: 'somePattern' }]; + sut.write(config); + expect(config.files).to.be.deep.eq([{ pattern: 'somePattern', mutated: false, included: false }]); + }); + + it('should not completely override files', () => { + karmaConfig.files = [{ pattern: 'somePattern' }]; + config.files = ['someFile']; + sut.write(config); + expect(config.files).to.be.deep.eq(['someFile', { pattern: 'somePattern', mutated: false, included: false }]); + }); + + it('should exclude the excluded files', () => { + karmaConfig.exclude = ['someFile']; + sut.write(config); + expect(config.files).to.be.deep.eq(['!someFile']); + }); + + it('should add karmaConfig to the options', () => { + karmaConfig.something = 'blaat'; + sut.write(config); + expect(config['karmaConfig']).to.be.eq(karmaConfig); + }); + + it('should not override existing karmaConfig', () => { + config['karmaConfig'] = { value: 'overriden' }; + karmaConfig.value = 'base'; + karmaConfig.theAnswer = 42; + sut.write(config); + expect(config['karmaConfig'].value).to.be.eq('overriden'); + expect(config['karmaConfig'].theAnswer).to.be.eq(42); + }); + }); + }); +}); diff --git a/testResources/configs/example-karma.conf.js b/testResources/configs/example-karma.conf.js new file mode 100644 index 0000000..27ac8c3 --- /dev/null +++ b/testResources/configs/example-karma.conf.js @@ -0,0 +1,68 @@ +// Karma configuration +// Generated on Thu Dec 15 2016 17:14:16 GMT+0100 (W. Europe Standard Time) + +module.exports = function(config) { + config.set({ + + // base path that will be used to resolve all patterns (eg. files, exclude) + basePath: '', + + + // frameworks to use + // available frameworks: https://npmjs.org/browse/keyword/karma-adapter + frameworks: ['jasmine', 'requirejs'], + + + // list of files / patterns to load in the browser + files: [ + ], + + + // list of files to exclude + exclude: [ + ], + + + // preprocess matching files before serving them to the browser + // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor + preprocessors: { + }, + + + // test results reporter to use + // possible values: 'dots', 'progress' + // available reporters: https://npmjs.org/browse/keyword/karma-reporter + reporters: ['progress'], + + + // web server port + port: 9876, + + + // enable / disable colors in the output (reporters and logs) + colors: true, + + + // level of logging + // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG + logLevel: config.LOG_INFO, + + + // enable / disable watching file and executing tests whenever any file changes + autoWatch: true, + + + // start these browsers + // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher + browsers: ['Chrome'], + + + // Continuous Integration mode + // if true, Karma captures browsers, runs the tests and exits + singleRun: false, + + // Concurrency level + // how many browser should be started simultaneous + concurrency: Infinity, + }); +} diff --git a/testResources/configs/files-karma.conf.js b/testResources/configs/files-karma.conf.js new file mode 100644 index 0000000..e3a5675 --- /dev/null +++ b/testResources/configs/files-karma.conf.js @@ -0,0 +1,12 @@ +module.exports = function (config) { + config.set({ + files: [ + 'src/**/*.js', + { pattern: 'resources/**/*.js', included: false } + ], + exclude: [ + '**/index.js', + '+(Error|InfiniteAdd).js' + ] + }); +}; diff --git a/testResources/sampleProject/sdsd.js b/testResources/sampleProject/sdsd.js deleted file mode 100644 index 0ec7314..0000000 --- a/testResources/sampleProject/sdsd.js +++ /dev/null @@ -1,11 +0,0 @@ -const istanbul = require('istanbul'); -const fs = require('fs'); -var instrumenter = new istanbul.Instrumenter(); - -['Add.js', 'Circle.js'].forEach(f => { - let path = 'src/' + f; - let code = fs.readFileSync(path, {encoding: 'utf8'}); - let instrumentedCode = instrumenter.instrumentSync(code, path); - fs.writeFileSync('src-instrumented-for-coverage-all/' + f, instrumentedCode); -}); - From 9c92851ef955b5d57b21e28111813a262a179332 Mon Sep 17 00:00:00 2001 From: Nico Jansen Date: Wed, 28 Dec 2016 14:26:49 +0100 Subject: [PATCH 2/5] feat(read-karma-config): Use karma configuration Forgot to push utils file --- src/utils.ts | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 src/utils.ts diff --git a/src/utils.ts b/src/utils.ts new file mode 100644 index 0000000..e29f459 --- /dev/null +++ b/src/utils.ts @@ -0,0 +1,3 @@ +export function requireModule(name: string): any { + return require(name); +} \ No newline at end of file From 0de8993753c959ce114df672572c45685ac9f8cb Mon Sep 17 00:00:00 2001 From: Nico Jansen Date: Wed, 28 Dec 2016 14:34:55 +0100 Subject: [PATCH 3/5] feat(read-karma-config): Force typescript version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0596970..1700c0e 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ "sinon-chai": "^2.8.0", "stryker-api": "^0.4.1", "tslint": "^4.0.2", - "typescript": "^2.0.2" + "typescript": "~2.0.2" }, "dependencies": { "lodash": "^4.13.1", From 3ab79bc108e152528413f3844f48dbadb2695e61 Mon Sep 17 00:00:00 2001 From: Nico Jansen Date: Wed, 28 Dec 2016 14:50:37 +0100 Subject: [PATCH 4/5] fix(deps): Update stryker-api version --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 1700c0e..4e547d2 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "license": "Apache-2.0", "peerDependencies": { "karma": "^0.13.0 || ~1.0.0 || ^1.1.1", - "stryker-api": "^0.4.0" + "stryker-api": "^0.4.2-rc0" }, "devDependencies": { "@types/chai": "^3.4.32", @@ -55,7 +55,7 @@ "mocha": "^3.0.2", "sinon": "^1.17.5", "sinon-chai": "^2.8.0", - "stryker-api": "^0.4.1", + "stryker-api": "^0.4.2-rc0", "tslint": "^4.0.2", "typescript": "~2.0.2" }, From ccb353105c450ec3fdb218346f65bef3fc511292 Mon Sep 17 00:00:00 2001 From: Nico Jansen Date: Thu, 29 Dec 2016 13:59:11 +0100 Subject: [PATCH 5/5] feat(config-writer): Never set test runner name Never set the test runner name to 'karma' as it could lead to strange behavior. --- src/KarmaConfigWriter.ts | 10 +--------- test/unit/KarmaConfigWriterSpec.ts | 4 ++-- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/src/KarmaConfigWriter.ts b/src/KarmaConfigWriter.ts index d4dbf41..83c6f19 100644 --- a/src/KarmaConfigWriter.ts +++ b/src/KarmaConfigWriter.ts @@ -12,13 +12,6 @@ export default class KarmaConfigWriter implements ConfigWriter { if (karmaConfig) { KarmaConfigWriter.importFiles(strykerConfig, karmaConfig); KarmaConfigWriter.importDefaultKarmaConfig(strykerConfig, karmaConfig); - KarmaConfigWriter.overrideRunner(strykerConfig); - } - } - - private static overrideRunner(strykerConfig: StrykerConfig) { - if (!strykerConfig.testRunner) { - strykerConfig.testRunner = 'karma'; } } @@ -31,8 +24,7 @@ export default class KarmaConfigWriter implements ConfigWriter { if (files && Array.isArray(files)) { const karmaFiles = files.map(KarmaConfigWriter.toInputFileDescriptor); log.debug(`Importing following files from karma.conf file to stryker: ${JSON.stringify(karmaFiles)}`); - strykerConfig.files = strykerConfig.files - .concat(karmaFiles); + strykerConfig.files = strykerConfig.files.concat(karmaFiles); } if (exclude && Array.isArray(exclude)) { const ignores = exclude.map(fileToIgnore => `!${fileToIgnore}`); diff --git a/test/unit/KarmaConfigWriterSpec.ts b/test/unit/KarmaConfigWriterSpec.ts index d287cd9..548d4e2 100644 --- a/test/unit/KarmaConfigWriterSpec.ts +++ b/test/unit/KarmaConfigWriterSpec.ts @@ -45,9 +45,9 @@ describe('KarmaConfigWriter', () => { karmaConfigReader.read.returns(karmaConfig); }); - it('should override the runner if it was not provided already', () => { + it('should not override the runner if it was not provided already, as it could result in strange behavior', () => { sut.write(config); - expect(config.testRunner).to.be.eq('karma'); + expect(config.testRunner).to.be.undefined; }); it('should not override the runner if it was provided already', () => {