Skip to content

Commit

Permalink
feat: guard against importing ConsoleDriverModule without forRoot (#12)
Browse files Browse the repository at this point in the history
* refactor: simplify LogDriver provider in ConsoleDriverModule

* feat: guard against importing ConsoleDriverModule without forRoot
  • Loading branch information
LayZeeDK authored Sep 28, 2020
1 parent 16ddac8 commit a39c01c
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 30 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { NgModule } from '@angular/core';

import { LogDriverToken } from '../log-driver';

import { ConsoleDriver } from './console.driver';

@NgModule({
providers: [
{
provide: LogDriverToken,
useClass: ConsoleDriver,
multi: true,
},
],
})
export class ConsoleDriverRootModule {}
Original file line number Diff line number Diff line change
Expand Up @@ -29,25 +29,23 @@ const createConsoleDriver = ({
return consoleDriver;
};

const expectNgModuleToBeImported = <TModule>(ngModuleType: Type<TModule>) => {
const expectNgModuleToBeGuarded = <TModule>(ngModuleType: Type<TModule>) => {
let ngModule: TModule | undefined;

TestBed.configureTestingModule({
imports: [ngModuleType],
});

expect(() => {
ngModule = TestBed.inject(ngModuleType);
})
.withContext(`${ngModuleType.name} has not been imported`)
.not.toThrowError(new RegExp(`NullInjectorError.*${ngModuleType.name}`));

expect(ngModule).toBeInstanceOf(ngModuleType);
.withContext(`${ngModuleType.name} must guard against being imported directly`)
.toThrow();
};

describe(ConsoleDriverModule.name, () => {
it(`can be imported without using the ${ConsoleDriverModule.forRoot.name} method`, () => {
TestBed.configureTestingModule({
imports: [ConsoleDriverModule],
});

expectNgModuleToBeImported(ConsoleDriverModule);
it(`cannot be imported without using the ${ConsoleDriverModule.forRoot.name} method`, () => {
expectNgModuleToBeGuarded(ConsoleDriverModule);
});

describe(ConsoleDriverModule.forRoot.name, () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,19 @@
import { ModuleWithProviders, NgModule } from '@angular/core';

import { defaultLogDriverConfig, LogDriverConfig, LogDriverConfigToken } from '../../configs/log-driver.config';
import { LogDriverToken } from '../log-driver';

import { ConsoleDriver } from './console.driver';

export function consoleFactory(config: LogDriverConfig): ConsoleDriver {
return new ConsoleDriver(config);
}
import { ConsoleDriverRootModule } from './console-driver-root.module';

@NgModule()
export class ConsoleDriverModule {
static forRoot(config: LogDriverConfig = defaultLogDriverConfig): ModuleWithProviders<ConsoleDriverModule> {
static forRoot(config: LogDriverConfig = defaultLogDriverConfig): ModuleWithProviders<ConsoleDriverRootModule> {
return {
ngModule: ConsoleDriverModule,
providers: [
{ provide: LogDriverConfigToken, useValue: config },
{
provide: LogDriverToken,
useFactory: consoleFactory,
multi: true,
deps: [LogDriverConfigToken],
},
],
ngModule: ConsoleDriverRootModule,
providers: [{ provide: LogDriverConfigToken, useValue: config }],
};
}

constructor() {
throw new Error('Do not import ConsoleDriverModule directly. Use ConsoleDriverModule.forRoot.');
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { LogDriverConfig } from '../../configs/log-driver.config';
import { Inject, Injectable } from '@angular/core';

import { LogDriverConfig, LogDriverConfigToken } from '../../configs/log-driver.config';
import { LogDriver } from '../log-driver';

@Injectable()
export class ConsoleDriver implements LogDriver {
constructor(public config: LogDriverConfig) {}
constructor(@Inject(LogDriverConfigToken) public config: LogDriverConfig) {}

logInfo(logEntry: string): void {
console.info(logEntry);
Expand Down

0 comments on commit a39c01c

Please sign in to comment.