Skip to content

Commit

Permalink
feat(config injection): remove Config from the DI tokens (#1389)
Browse files Browse the repository at this point in the history
BREAKING CHANGE: removed Config object from Dependency Injection (only relevant for plugin creators).
  • Loading branch information
simondel authored and nicojs committed Feb 12, 2019
1 parent cb14e67 commit 857e4a5
Show file tree
Hide file tree
Showing 14 changed files with 48 additions and 76 deletions.
5 changes: 0 additions & 5 deletions packages/stryker-api/src/plugin/Contexts.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { LoggerFactoryMethod, Logger } from '../../logging';
import { StrykerOptions } from '../../core';
import { PluginResolver } from './Plugins';
import { Config } from '../../config';
import { PluginKind } from './PluginKind';
import { commonTokens } from './tokens';

Expand All @@ -20,10 +19,6 @@ export interface BaseContext {
*/
export interface OptionsContext extends BaseContext {
[commonTokens.options]: StrykerOptions;
/**
* @deprecated This is just here to migrate between old and new plugins. Don't use this! Use `options` instead
*/
[commonTokens.config]: Config;
}

/**
Expand Down
4 changes: 0 additions & 4 deletions packages/stryker-api/src/plugin/tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,6 @@ const injector: import('typed-inject').InjectorToken = '$injector';
* Common tokens used for dependency injection (see typed-inject readme for more information)
*/
export const commonTokens = Object.freeze({
/**
* @deprecated Use 'options' instead. This is just hear to support plugin migration
*/
config: stringLiteral('config'),
getLogger: stringLiteral('getLogger'),
injector,
logger: stringLiteral('logger'),
Expand Down
1 change: 0 additions & 1 deletion packages/stryker-api/test/unit/plugin/tokens.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ describe('commonTokens', () => {
expect(commonTokens[token]).eq(token);
});
}
itShouldProvideToken('config');
itShouldProvideToken('options');
itShouldProvideToken('logger');
itShouldProvideToken('pluginResolver');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ paths.appTsTestConfig = require.resolve('../../testResources/reactTsProject/tsco

import JestConfigEditor from '../../src/JestConfigEditor';
import { jestTestRunnerFactory } from '../../src/JestTestRunner';
import { testInjector } from '@stryker-mutator/test-helpers';
import { testInjector, factory } from '@stryker-mutator/test-helpers';
import { commonTokens } from 'stryker-api/plugin';

// Get the actual project root, since we will stub process.cwd later on
Expand Down Expand Up @@ -38,9 +38,12 @@ describe('Integration test for Strykers Jest runner', () => {
processCwdStub = sinon.stub(process, 'cwd');
});

function createSut() {
function createSut(jestConfig?: any) {
const jestConfigEditor = testInjector.injector.injectClass(JestConfigEditor);
const config = testInjector.injector.resolve(commonTokens.config);
const config = factory.config();
if (jestConfig) {
config.jest = jestConfig;
}
jestConfigEditor.edit(config);
return testInjector.injector
.provideValue(commonTokens.options, config)
Expand All @@ -49,9 +52,7 @@ describe('Integration test for Strykers Jest runner', () => {

it('should run tests on the example React + TypeScript project', async () => {
processCwdStub.returns(getProjectRoot('reactTsProject'));
testInjector.options.jest = { projectType: 'react-ts' };

const jestTestRunner = createSut();
const jestTestRunner = createSut({ projectType: 'react-ts' });
const result = await jestTestRunner.run(runOptions);

expect(result.status).to.equal(RunStatus.Complete);
Expand Down
7 changes: 0 additions & 7 deletions packages/stryker-test-helpers/src/TestInjector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { Logger } from 'stryker-api/logging';
import * as factory from './factory';
import * as sinon from 'sinon';
import { rootInjector, Injector, Scope } from 'typed-inject';
import { Config } from 'stryker-api/config';

class TestInjector {

Expand All @@ -14,11 +13,6 @@ class TestInjector {
private readonly provideLogger = (): Logger => {
return this.logger;
}
private readonly provideConfig = () => {
const config = new Config();
config.set(this.options);
return config;
}
private readonly provideOptions = () => {
return this.options;
}
Expand All @@ -30,7 +24,6 @@ class TestInjector {
.provideValue(commonTokens.getLogger, this.provideLogger)
.provideFactory(commonTokens.logger, this.provideLogger, Scope.Transient)
.provideFactory(commonTokens.options, this.provideOptions, Scope.Transient)
.provideFactory(commonTokens.config, this.provideConfig, Scope.Transient)
.provideFactory(commonTokens.pluginResolver, this.providePluginResolver, Scope.Transient);

public reset() {
Expand Down
14 changes: 6 additions & 8 deletions packages/stryker/src/Stryker.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { Config } from 'stryker-api/config';
import { StrykerOptions } from 'stryker-api/core';
import { MutantResult } from 'stryker-api/report';
import { MutantTestMatcher } from './mutants/MutantTestMatcher';
Expand Down Expand Up @@ -28,8 +27,8 @@ export default class Stryker {
return this.injector.resolve(coreTokens.reporter);
}

private get config(): Readonly<Config> {
return this.injector.resolve(commonTokens.config);
private get options(): Readonly<StrykerOptions> {
return this.injector.resolve(commonTokens.options);
}

private get timer() {
Expand All @@ -46,12 +45,11 @@ export default class Stryker {
this.injector = buildMainInjector(cliOptions);
this.log = this.injector.resolve(commonTokens.getLogger)(Stryker.name);
// Log level may have changed
const options = this.config;
LogConfigurator.configureMainProcess(options.logLevel, options.fileLogLevel, options.allowConsoleColors);
LogConfigurator.configureMainProcess(this.options.logLevel, this.options.fileLogLevel, this.options.allowConsoleColors);
}

public async runMutationTest(): Promise<MutantResult[]> {
const loggingContext = await LogConfigurator.configureLoggingServer(this.config.logLevel, this.config.fileLogLevel, this.config.allowConsoleColors);
const loggingContext = await LogConfigurator.configureLoggingServer(this.options.logLevel, this.options.fileLogLevel, this.options.allowConsoleColors);
this.timer.reset();
const inputFiles = await this.injector.injectClass(InputFileResolver).resolve();
if (inputFiles.files.length) {
Expand All @@ -60,7 +58,7 @@ export default class Stryker {
.provideValue(coreTokens.loggingContext, loggingContext)
.provideValue(coreTokens.inputFiles, inputFiles);
const initialTestRunProcess = inputFileInjector
.provideValue(commonTokens.produceSourceMaps, this.config.coverageAnalysis !== 'off')
.provideValue(commonTokens.produceSourceMaps, this.options.coverageAnalysis !== 'off')
.provideFactory(coreTokens.pluginCreatorTranspiler, PluginCreator.createFactory(PluginKind.Transpiler))
.provideClass(coreTokens.transpiler, TranspilerFacade)
.injectClass(InitialTestExecutor);
Expand Down Expand Up @@ -118,6 +116,6 @@ export default class Stryker {
const calculator = this.injector.injectClass(ScoreResultCalculator);
const score = calculator.calculate(mutantResults);
this.reporter.onScoreCalculated(score);
calculator.determineExitCode(score, this.config.thresholds);
calculator.determineExitCode(score, this.options.thresholds);
}
}
17 changes: 0 additions & 17 deletions packages/stryker/src/config/configFactory.ts

This file was deleted.

2 changes: 1 addition & 1 deletion packages/stryker/src/config/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export { ConfigEditorApplier } from './ConfigEditorApplier';
export * from './configFactory';
export * from './readConfig';
9 changes: 9 additions & 0 deletions packages/stryker/src/config/readConfig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import ConfigReader from './ConfigReader';
import { tokens } from 'stryker-api/plugin';
import { coreTokens } from '../di';

export function readConfig(configReader: ConfigReader) {
return configReader.readConfig();
}

readConfig.inject = tokens(coreTokens.configReader);
15 changes: 7 additions & 8 deletions packages/stryker/src/di/buildChildProcessInjector.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
import { Config } from 'stryker-api/config';
import { commonTokens, Scope, Injector, OptionsContext, tokens } from 'stryker-api/plugin';
import { optionsFactory, pluginResolverFactory, loggerFactory } from './factoryMethods';
import { pluginResolverFactory, loggerFactory } from './factoryMethods';
import { coreTokens } from '.';
import { getLogger } from 'log4js';
import { rootInjector } from 'typed-inject';
import { StrykerOptions } from 'stryker-api/core';

export function buildChildProcessInjector(config: Config): Injector<OptionsContext> {
export function buildChildProcessInjector(options: StrykerOptions): Injector<OptionsContext> {
return rootInjector
.provideValue(commonTokens.config, config)
.provideFactory(commonTokens.options, optionsFactory)
.provideValue(commonTokens.options, options)
.provideValue(commonTokens.getLogger, getLogger)
.provideFactory(commonTokens.logger, loggerFactory, Scope.Transient)
.provideFactory(coreTokens.pluginDescriptors, pluginDescriptorsFactory)
.provideFactory(commonTokens.pluginResolver, pluginResolverFactory);
}

function pluginDescriptorsFactory(config: Config): ReadonlyArray<string> {
return config.plugins;
function pluginDescriptorsFactory(options: StrykerOptions): ReadonlyArray<string> {
return options.plugins;
}
pluginDescriptorsFactory.inject = tokens(commonTokens.config);
pluginDescriptorsFactory.inject = tokens(commonTokens.options);
3 changes: 1 addition & 2 deletions packages/stryker/src/di/buildMainInjector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { TestFramework } from 'stryker-api/test_framework';
import { rootInjector } from 'typed-inject';
import { getLogger } from 'log4js';
import { loggerFactory, pluginResolverFactory, optionsFactory, testFrameworkFactory } from './factoryMethods';
import { ConfigEditorApplier, configFactory, readConfig } from '../config';
import { ConfigEditorApplier, readConfig } from '../config';
import BroadcastReporter from '../reporters/BroadcastReporter';
import { Config } from 'stryker-api/config';
import ConfigReader from '../config/ConfigReader';
Expand All @@ -33,7 +33,6 @@ export function buildMainInjector(cliOptions: Partial<StrykerOptions>): Injector
.provideFactory(commonTokens.pluginResolver, pluginResolverFactory)
.provideFactory(coreTokens.pluginCreatorConfigEditor, PluginCreator.createFactory(PluginKind.ConfigEditor))
.provideClass(coreTokens.configEditorApplier, ConfigEditorApplier)
.provideFactory(commonTokens.config, configFactory)
.provideFactory(commonTokens.options, optionsFactory)
.provideFactory(coreTokens.pluginCreatorReporter, PluginCreator.createFactory(PluginKind.Reporter))
.provideFactory(coreTokens.pluginCreatorTestFramework, PluginCreator.createFactory(PluginKind.TestFramework))
Expand Down
10 changes: 7 additions & 3 deletions packages/stryker/src/di/factoryMethods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ import { tokens, commonTokens, OptionsContext, Injector, PluginKind, PluginResol
import TestFrameworkOrchestrator from '../TestFrameworkOrchestrator';
import { coreTokens, PluginCreator, PluginLoader } from '.';
import { LoggerFactoryMethod, Logger } from 'stryker-api/logging';
import { StrykerOptions } from 'stryker-api/core';
import { Config } from 'stryker-api/config';
import { ConfigEditorApplier } from '../config';
import { freezeRecursively } from '../utils/objectUtils';

export function pluginResolverFactory(injector: Injector<{ [commonTokens.logger]: Logger, [coreTokens.pluginDescriptors]: ReadonlyArray<string> }>): PluginResolver {
const pluginLoader = injector.injectClass(PluginLoader);
Expand All @@ -21,7 +24,8 @@ export function loggerFactory(getLogger: LoggerFactoryMethod, target: Function |
}
loggerFactory.inject = tokens(commonTokens.getLogger, commonTokens.target);

export function optionsFactory(config: Config) {
return config;
export function optionsFactory(config: Config, configEditorApplier: ConfigEditorApplier): StrykerOptions {
configEditorApplier.edit(config);
return freezeRecursively(config);
}
optionsFactory.inject = tokens(commonTokens.config);
optionsFactory.inject = tokens(coreTokens.configReadFromConfigFile, coreTokens.configEditorApplier);
2 changes: 1 addition & 1 deletion packages/stryker/test/unit/StrykerSpec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ describe(Stryker.name, () => {
.withArgs(MutationTestExecutor).returns(mutationTestExecutorMock)
.withArgs(ScoreResultCalculator).returns(scoreResultCalculator);
injectorMock.resolve
.withArgs(commonTokens.config).returns(strykerConfig)
.withArgs(commonTokens.options).returns(strykerConfig)
.withArgs(di.coreTokens.timer).returns(timerMock)
.withArgs(di.coreTokens.reporter).returns(reporterMock)
.withArgs(di.coreTokens.testFramework).returns(testFrameworkMock)
Expand Down
22 changes: 9 additions & 13 deletions packages/stryker/test/unit/di/buildMainInjector.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,43 +51,39 @@ describe(buildMainInjector.name, () => {
return stub;
}

describe('resolve config', () => {
describe('resolve options', () => {

it('should supply readonly stryker options', () => {
const injector = buildMainInjector({});
const actualConfig = injector.resolve(commonTokens.config);
const actualOptions = injector.resolve(commonTokens.options);
expect(actualConfig).eq(expectedConfig);
expect(actualConfig).frozen;
expect(actualOptions).eq(expectedConfig);
const actualOptions = buildMainInjector({}).resolve(commonTokens.options);
expect(actualOptions).frozen;
});

it('should load default plugins', () => {
buildMainInjector({}).resolve(commonTokens.config);
buildMainInjector({}).resolve(commonTokens.options);
expect(di.PluginLoader).calledWithNew;
expect(di.PluginLoader).calledWith(currentLogMock(), ['stryker-*', require.resolve('../../../src/reporters')]);
});

it('should load plugins', () => {
buildMainInjector({}).resolve(commonTokens.config);
buildMainInjector({}).resolve(commonTokens.options);
expect(pluginLoaderMock.load).called;
});

it('should apply config editors', () => {
buildMainInjector({}).resolve(commonTokens.config);
buildMainInjector({}).resolve(commonTokens.options);
expect(configEditorApplierMock.edit).called;
});

it('should cache the config', () => {
const injector = buildMainInjector({});
injector.resolve(commonTokens.config);
injector.resolve(commonTokens.config);
injector.resolve(commonTokens.options);
injector.resolve(commonTokens.options);
expect(configReaderMock.readConfig).calledOnce;
});

it('should inject the `cliOptions` in the config reader', () => {
const expectedCliOptions = { foo: 'bar' };
buildMainInjector(expectedCliOptions).resolve(commonTokens.config);
buildMainInjector(expectedCliOptions).resolve(commonTokens.options);
expect(configReaderModule.default).calledWith(expectedCliOptions);
});
});
Expand Down

0 comments on commit 857e4a5

Please sign in to comment.