diff --git a/angular.json b/angular.json index 693cc07..c524533 100644 --- a/angular.json +++ b/angular.json @@ -26,10 +26,7 @@ "test": { "builder": "@angular-devkit/build-angular:karma", "options": { - "include": [ - "src/**/*.spec.ts", - "testing/**/*.spec.ts" - ], + "include": ["src/**/*.spec.ts", "testing/src/**/*.spec.ts"], "polyfills": ["zone.js", "zone.js/testing"], "tsConfig": "tsconfig.spec.json", "karmaConfig": "karma.conf.js" @@ -38,7 +35,7 @@ "lint": { "builder": "@angular-eslint/builder:lint", "options": { - "lintFilePatterns": ["src/**/*.ts", "src/**/*.html"] + "lintFilePatterns": ["src/**/*.ts", "src/**/*.html", "testing/src/**/*.ts", "testing/src/**/*.html"] } } } diff --git a/testing/src/TestingModuleConfig.ts b/testing/src/TestingModuleConfig.ts deleted file mode 100644 index 7a6a54f..0000000 --- a/testing/src/TestingModuleConfig.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { InjectionToken } from "@angular/core" - -/** - * The configuration options that can be passed to the FontAwesomeTestingModule. - */ -// This interface is user-facing and will be converted to the -// _FontAwesomeTestingModuleInternalConfig for internal use by the module. -export interface FontAwesomeTestingModuleConfig extends Partial<_FontAwesomeTestingModuleInternalConfig> { } - -/** - * The internal configuration for the FontAwesomeTestingModule. - * This interface is private. Conforming objects should be constructed by the - * _getFontAwesomeTestingModuleInternalConfig() function. - */ -export interface _FontAwesomeTestingModuleInternalConfig { - /** - * What to do when `addIcons()` is invoked on an IconLibrary provided by the FontAwesomeTestingModule. - * - * Possible values are: - * - `'logWarning'`: Writes a warning to the console. - * - `'throwError'`: Throws an error - * - `'noop'`: Does nothing - * - * Note that in any case the icon will not be added to the library. - */ - whenAddingIcons: 'logWarning' | 'throwError' | 'noop' -} - -export const FontAwesomeTestingModuleConfigInjectionToken = new InjectionToken<_FontAwesomeTestingModuleInternalConfig>('FontAwesomeTestingModuleInternalConfig') - -/** - * The default values used for configuration if the user passes no configuration, - * or an incomplete one. - */ -const DEFAULT_CONFIG = Object.freeze({ - // The default value maintains compatibility with versions <= 0.14.1 - whenAddingIcons: 'throwError' -}) - -export function _getFontAwesomeTestingModuleInternalConfig(publicConfig: FontAwesomeTestingModuleConfig = {}): _FontAwesomeTestingModuleInternalConfig { - return { - whenAddingIcons: publicConfig.whenAddingIcons ?? DEFAULT_CONFIG.whenAddingIcons - } -} \ No newline at end of file diff --git a/testing/src/config.ts b/testing/src/config.ts new file mode 100644 index 0000000..8ec69d6 --- /dev/null +++ b/testing/src/config.ts @@ -0,0 +1,21 @@ +import { Injectable } from '@angular/core'; + +@Injectable({ + providedIn: 'root', +}) +export class FaTestingConfig { + /** + * What to do when `addIcons()` or `addIconPacks()` is invoked on + * the FaIconLibrary provided by the FontAwesomeTestingModule. + * + * Possible values are: + * - `'throwError'` - Throw an error. + * - `'logWarning'` - Write a warning to the console. + * - `'noop'` - Do nothing. + * + * Note that in any case the icon will not be added to the library. + * + * @default 'throwError' + */ + whenAddingIcons: 'throwError' | 'logWarning' | 'noop' = 'throwError'; +} diff --git a/testing/src/icon/mock-icon-library.service.ts b/testing/src/icon/mock-icon-library.service.ts index 3da51f4..9c11dbf 100644 --- a/testing/src/icon/mock-icon-library.service.ts +++ b/testing/src/icon/mock-icon-library.service.ts @@ -1,10 +1,6 @@ -import { Inject, Injectable, Optional } from '@angular/core'; +import { Injectable } from '@angular/core'; import { FaIconLibraryInterface, IconDefinition, IconName, IconPrefix } from '@fortawesome/angular-fontawesome'; -import { - FontAwesomeTestingModuleConfigInjectionToken, - _FontAwesomeTestingModuleInternalConfig, - _getFontAwesomeTestingModuleInternalConfig -} from '../TestingModuleConfig'; +import { FaTestingConfig } from '../config'; export const dummyIcon: IconDefinition = { prefix: 'fad', @@ -18,27 +14,14 @@ export const ADD_ICON_MESSAGE = 'Attempt to add an icon to the MockFaIconLibrary providedIn: 'root', }) export class MockFaIconLibrary implements FaIconLibraryInterface { + constructor(private config: FaTestingConfig) {} - private config: _FontAwesomeTestingModuleInternalConfig - - // The configuration object is optional in order to maintain backwards compatibility with versions <= 0.14.1. - // If the module is unconfigured (that is, FontAwesomeTestingModule.forRoot() has never been called), - // then the dependency injection will provide `null`. - // - // We could alternatively provide a default configuration in the `providers` array of the `NgModule` decorator, - // but that would break the use case of injecting a service directly without providing a configuration, - // as is done in testing/src/icon/mock-icon-library.service.spec.ts - constructor( - @Inject(FontAwesomeTestingModuleConfigInjectionToken) @Optional() config: _FontAwesomeTestingModuleInternalConfig - ) { - this.config = config ?? _getFontAwesomeTestingModuleInternalConfig() - } addIcons() { if (this.config.whenAddingIcons === 'throwError') { throw new Error(ADD_ICON_MESSAGE); } if (this.config.whenAddingIcons === 'logWarning') { - console.warn(ADD_ICON_MESSAGE) + console.warn(ADD_ICON_MESSAGE); } } @@ -47,7 +30,7 @@ export class MockFaIconLibrary implements FaIconLibraryInterface { throw new Error(ADD_ICON_MESSAGE); } if (this.config.whenAddingIcons === 'logWarning') { - console.warn(ADD_ICON_MESSAGE) + console.warn(ADD_ICON_MESSAGE); } } diff --git a/testing/src/public_api.ts b/testing/src/public_api.ts index 62a5fbc..95eb00f 100644 --- a/testing/src/public_api.ts +++ b/testing/src/public_api.ts @@ -1,3 +1,3 @@ export { FontAwesomeTestingModule } from './testing.module'; -export { MockFaIconLibrary } from './icon/mock-icon-library.service' -export { FontAwesomeTestingModuleConfig } from './TestingModuleConfig' \ No newline at end of file +export { MockFaIconLibrary } from './icon/mock-icon-library.service'; +export { FaTestingConfig } from './config'; diff --git a/testing/test/integration/module-test.spec.ts b/testing/src/testing.module.spec.ts similarity index 89% rename from testing/test/integration/module-test.spec.ts rename to testing/src/testing.module.spec.ts index db5e18c..205be53 100644 --- a/testing/test/integration/module-test.spec.ts +++ b/testing/src/testing.module.spec.ts @@ -2,8 +2,8 @@ import { Component } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { FaIconLibrary } from '@fortawesome/angular-fontawesome'; import { faUser } from '@fortawesome/free-solid-svg-icons'; -import { ADD_ICON_MESSAGE } from 'testing/src/icon/mock-icon-library.service'; -import { FontAwesomeTestingModule } from 'testing/src/public_api'; +import { ADD_ICON_MESSAGE } from './icon/mock-icon-library.service'; +import { FontAwesomeTestingModule } from './testing.module'; @Component({ selector: 'fa-host', @@ -12,75 +12,73 @@ import { FontAwesomeTestingModule } from 'testing/src/public_api'; class HostComponent {} describe('Using the `FontAwesomeTestingModule', () => { - describe('Providing no configuration', () => { // This describe block asserts that the behaviour of versions <= 0.14.1 is maintained let component: HostComponent; let fixture: ComponentFixture; - + beforeEach(() => { TestBed.configureTestingModule({ imports: [FontAwesomeTestingModule], declarations: [HostComponent], }); - + fixture = TestBed.createComponent(HostComponent); component = fixture.componentInstance; fixture.detectChanges(); }); - + it('should allow you to import the module without errors', () => { expect(component).toBeTruthy(); }); - + it('should throw on attempt to add an icon to the mocked icon library', () => { const service = TestBed.inject(FaIconLibrary); expect(() => service.addIcons(faUser)).toThrow(new Error(ADD_ICON_MESSAGE)); }); - + it('should throw on attempt to add an icon pack to the mocked icon library', () => { const service = TestBed.inject(FaIconLibrary); expect(() => service.addIcons(faUser)).toThrow(new Error(ADD_ICON_MESSAGE)); }); - }) + }); describe('Providing an empty configuration object', () => { // This describe block asserts that a partial configuration object // is correctly filled up to the ‘full’ internal object. - // The used configuration should mimick the default values for ‘no configuration’. + // The used configuration should mimic the default values for ‘no configuration’. let component: HostComponent; let fixture: ComponentFixture; - + beforeEach(() => { TestBed.configureTestingModule({ imports: [FontAwesomeTestingModule.forRoot({})], declarations: [HostComponent], }); }); - + beforeEach(() => { fixture = TestBed.createComponent(HostComponent); component = fixture.componentInstance; fixture.detectChanges(); }); - + it('should allow you to import the module without errors', () => { expect(component).toBeTruthy(); }); - + it('should throw on attempt to add an icon to the mocked icon library', () => { const service = TestBed.inject(FaIconLibrary); expect(() => service.addIcons(faUser)).toThrow(new Error(ADD_ICON_MESSAGE)); }); - + it('should throw on attempt to add an icon pack to the mocked icon library', () => { const service = TestBed.inject(FaIconLibrary); expect(() => service.addIcons(faUser)).toThrow(new Error(ADD_ICON_MESSAGE)); }); - }) - + }); describe('Providing {addIcons: "throwError"}', () => { // This describe block asserts that feature request @@ -89,35 +87,34 @@ describe('Using the `FontAwesomeTestingModule', () => { let component: HostComponent; let fixture: ComponentFixture; - + beforeEach(() => { TestBed.configureTestingModule({ - imports: [FontAwesomeTestingModule.forRoot({whenAddingIcons: 'throwError'})], + imports: [FontAwesomeTestingModule.forRoot({ whenAddingIcons: 'throwError' })], declarations: [HostComponent], }); }); - + beforeEach(() => { fixture = TestBed.createComponent(HostComponent); component = fixture.componentInstance; fixture.detectChanges(); }); - + it('should allow you to import the module without errors', () => { expect(component).toBeTruthy(); }); - + it('should throw on attempt to add an icon to the mocked icon library', () => { const service = TestBed.inject(FaIconLibrary); expect(() => service.addIcons(faUser)).toThrow(new Error('Attempt to add an icon to the MockFaIconLibrary.')); }); - + it('should throw on attempt to add an icon pack to the mocked icon library', () => { const service = TestBed.inject(FaIconLibrary); expect(() => service.addIcons(faUser)).toThrow(new Error('Attempt to add an icon to the MockFaIconLibrary.')); }); - }) - + }); describe('Providing {addIcons: "logWarning"}', () => { // This describe block asserts that feature request @@ -126,40 +123,38 @@ describe('Using the `FontAwesomeTestingModule', () => { let component: HostComponent; let fixture: ComponentFixture; - + beforeEach(() => { TestBed.configureTestingModule({ - imports: [FontAwesomeTestingModule.forRoot({whenAddingIcons: 'logWarning'})], + imports: [FontAwesomeTestingModule.forRoot({ whenAddingIcons: 'logWarning' })], declarations: [HostComponent], }); }); - + beforeEach(() => { fixture = TestBed.createComponent(HostComponent); component = fixture.componentInstance; fixture.detectChanges(); }); - + it('should allow you to import the module without errors', () => { expect(component).toBeTruthy(); }); - + it('should call console.warn on attempt to add an icon to the mocked icon library', () => { const service = TestBed.inject(FaIconLibrary); - spyOn(console, 'warn') + spyOn(console, 'warn'); expect(() => service.addIcons(faUser)).not.toThrow(); - expect(console.warn).toHaveBeenCalledOnceWith(ADD_ICON_MESSAGE) + expect(console.warn).toHaveBeenCalledOnceWith(ADD_ICON_MESSAGE); }); - + it('should call console.warn on attempt to add an icon pack to the mocked icon library', () => { const service = TestBed.inject(FaIconLibrary); - spyOn(console, 'warn') + spyOn(console, 'warn'); expect(() => service.addIcons(faUser)).not.toThrow(); - expect(console.warn).toHaveBeenCalledOnceWith(ADD_ICON_MESSAGE) + expect(console.warn).toHaveBeenCalledOnceWith(ADD_ICON_MESSAGE); }); - }) - - + }); describe('Providing {addIcons: "noop"}', () => { // This describe block asserts that feature request @@ -168,36 +163,36 @@ describe('Using the `FontAwesomeTestingModule', () => { let component: HostComponent; let fixture: ComponentFixture; - + beforeEach(() => { TestBed.configureTestingModule({ - imports: [FontAwesomeTestingModule.forRoot({whenAddingIcons: 'noop'})], + imports: [FontAwesomeTestingModule.forRoot({ whenAddingIcons: 'noop' })], declarations: [HostComponent], }); }); - + beforeEach(() => { fixture = TestBed.createComponent(HostComponent); component = fixture.componentInstance; fixture.detectChanges(); }); - + it('should allow you to import the module without errors', () => { expect(component).toBeTruthy(); }); - + it('should ignore attempts to add an icon to the mocked icon library', () => { const service = TestBed.inject(FaIconLibrary); - spyOn(console, 'warn') + spyOn(console, 'warn'); expect(() => service.addIcons(faUser)).not.toThrow(); - expect(console.warn).not.toHaveBeenCalledOnceWith(ADD_ICON_MESSAGE) + expect(console.warn).not.toHaveBeenCalledOnceWith(ADD_ICON_MESSAGE); }); - + it('should ignore attempts to add an icon pack to the mocked icon library', () => { const service = TestBed.inject(FaIconLibrary); - spyOn(console, 'warn') + spyOn(console, 'warn'); expect(() => service.addIcons(faUser)).not.toThrow(); - expect(console.warn).not.toHaveBeenCalledOnceWith(ADD_ICON_MESSAGE) + expect(console.warn).not.toHaveBeenCalledOnceWith(ADD_ICON_MESSAGE); }); - }) + }); }); diff --git a/testing/src/testing.module.ts b/testing/src/testing.module.ts index c82ebb1..dcab461 100644 --- a/testing/src/testing.module.ts +++ b/testing/src/testing.module.ts @@ -1,11 +1,7 @@ import { ModuleWithProviders, NgModule } from '@angular/core'; import { FaIconLibrary, FontAwesomeModule } from '@fortawesome/angular-fontawesome'; +import { FaTestingConfig } from './config'; import { MockFaIconLibrary } from './icon/mock-icon-library.service'; -import { - FontAwesomeTestingModuleConfig, - FontAwesomeTestingModuleConfigInjectionToken, - _getFontAwesomeTestingModuleInternalConfig, -} from './TestingModuleConfig'; @NgModule({ exports: [FontAwesomeModule], @@ -16,7 +12,7 @@ export class FontAwesomeTestingModule { * Use this method to configure the module’s behaviour when trying to add icons * and icon packs to the mock icon library. */ - public static forRoot(config: FontAwesomeTestingModuleConfig = {}): ModuleWithProviders { + static forRoot(config: Partial = {}): ModuleWithProviders { return { ngModule: FontAwesomeTestingModule, providers: [ @@ -25,10 +21,10 @@ export class FontAwesomeTestingModule { useExisting: MockFaIconLibrary, }, { - provide: FontAwesomeTestingModuleConfigInjectionToken, - useValue: _getFontAwesomeTestingModuleInternalConfig(config), - } - ] - } + provide: FaTestingConfig, + useFactory: () => Object.assign(new FaTestingConfig(), config), + }, + ], + }; } }