From a55331085e4c5621832e6b23bc52b00068e8256a Mon Sep 17 00:00:00 2001 From: Ruben Taelman Date: Tue, 8 Feb 2022 15:39:24 +0100 Subject: [PATCH] Allow type-checking to be disabled via typeChecking --- lib/loading/ComponentsManagerBuilder.ts | 11 +++++++- lib/preprocess/ParameterHandler.ts | 3 ++- .../ParameterPropertyHandlerRange.ts | 6 +++-- .../ConfigConstructorPool-test.ts | 2 +- .../loading/ComponentsManagerBuilder-test.ts | 26 +++++++++++++++++++ .../ConfigPreprocessorComponent-test.ts | 2 +- .../ConfigPreprocessorComponentMapped-test.ts | 2 +- test/unit/preprocess/ParameterHandler-test.ts | 2 +- .../ParameterPropertyHandlerRange-test.ts | 13 +++++++++- 9 files changed, 58 insertions(+), 9 deletions(-) diff --git a/lib/loading/ComponentsManagerBuilder.ts b/lib/loading/ComponentsManagerBuilder.ts index 0e515dd..dfbcd7f 100644 --- a/lib/loading/ComponentsManagerBuilder.ts +++ b/lib/loading/ComponentsManagerBuilder.ts @@ -30,6 +30,7 @@ export class ComponentsManagerBuilder { private readonly logger: Logger; private readonly moduleState?: IModuleState; private readonly skipContextValidation: boolean; + private readonly typeChecking: boolean; public constructor(options: IComponentsManagerBuilderOptions) { this.mainModulePath = options.mainModulePath; @@ -44,6 +45,9 @@ export class ComponentsManagerBuilder { this.skipContextValidation = options.skipContextValidation === undefined ? true : Boolean(options.skipContextValidation); + this.typeChecking = options.typeChecking === undefined ? + true : + Boolean(options.typeChecking); } public static createLogger(logLevel: LogLevel = 'warn'): Logger { @@ -117,7 +121,7 @@ export class ComponentsManagerBuilder { // Build constructor pool const runTypeConfigs = {}; - const parameterHandler = new ParameterHandler({ objectLoader }); + const parameterHandler = new ParameterHandler({ objectLoader, typeChecking: this.typeChecking }); const configConstructorPool: IConfigConstructorPool = new ConfigConstructorPool({ objectLoader, configPreprocessors: [ @@ -198,4 +202,9 @@ export interface IComponentsManagerBuilderOptions { * Defaults to `true`. */ skipContextValidation?: boolean; + /** + * If values for parameters should be type-checked. + * Defaults to `true`. + */ + typeChecking?: boolean; } diff --git a/lib/preprocess/ParameterHandler.ts b/lib/preprocess/ParameterHandler.ts index 318ed68..fabcf91 100644 --- a/lib/preprocess/ParameterHandler.ts +++ b/lib/preprocess/ParameterHandler.ts @@ -22,7 +22,7 @@ export class ParameterHandler { new ParameterPropertyHandlerDefaultScoped(this.objectLoader), new ParameterPropertyHandlerDefault(this.objectLoader), new ParameterPropertyHandlerFixed(this.objectLoader), - this.parameterPropertyHandlerRange = new ParameterPropertyHandlerRange(this.objectLoader), + this.parameterPropertyHandlerRange = new ParameterPropertyHandlerRange(this.objectLoader, options.typeChecking), new ParameterPropertyHandlerLazy(), ]; } @@ -70,4 +70,5 @@ export class ParameterHandler { export interface IParameterHandlerOptions { objectLoader: RdfObjectLoader; + typeChecking: boolean; } diff --git a/lib/preprocess/parameterproperty/ParameterPropertyHandlerRange.ts b/lib/preprocess/parameterproperty/ParameterPropertyHandlerRange.ts index c4db44c..d2eda72 100644 --- a/lib/preprocess/parameterproperty/ParameterPropertyHandlerRange.ts +++ b/lib/preprocess/parameterproperty/ParameterPropertyHandlerRange.ts @@ -10,9 +10,11 @@ import type { IParameterPropertyHandler } from './IParameterPropertyHandler'; */ export class ParameterPropertyHandlerRange implements IParameterPropertyHandler { private readonly objectLoader: RdfObjectLoader; + private readonly typeChecking: boolean; - public constructor(objectLoader: RdfObjectLoader) { + public constructor(objectLoader: RdfObjectLoader, typeChecking: boolean) { this.objectLoader = objectLoader; + this.typeChecking = typeChecking; } public canHandle(value: Resource | undefined, configRoot: Resource, parameter: Resource): boolean { @@ -46,7 +48,7 @@ export class ParameterPropertyHandlerRange implements IParameterPropertyHandler ): Resource | undefined { const errorContext: IErrorContext = { param }; const conflict = this.hasValueType(value, param.property.range, errorContext, genericsContext); - if (!conflict) { + if (!conflict || !this.typeChecking) { return value; } ParameterPropertyHandlerRange.throwIncorrectTypeError(value, param, genericsContext, conflict); diff --git a/test/unit/construction/ConfigConstructorPool-test.ts b/test/unit/construction/ConfigConstructorPool-test.ts index b9142fe..d008aa1 100644 --- a/test/unit/construction/ConfigConstructorPool-test.ts +++ b/test/unit/construction/ConfigConstructorPool-test.ts @@ -44,7 +44,7 @@ describe('ConfigConstructorPool', () => { moduleState, }); creationSettings = {}; - parameterHandler = new ParameterHandler({ objectLoader }); + parameterHandler = new ParameterHandler({ objectLoader, typeChecking: true }); }); describe('with no preprocessors', () => { diff --git a/test/unit/loading/ComponentsManagerBuilder-test.ts b/test/unit/loading/ComponentsManagerBuilder-test.ts index ee57781..a5a4139 100644 --- a/test/unit/loading/ComponentsManagerBuilder-test.ts +++ b/test/unit/loading/ComponentsManagerBuilder-test.ts @@ -301,4 +301,30 @@ describe('ComponentsManagerBuilder', () => { transports: expect.anything(), }); }); + + it('should build with false typeChecking', async() => { + const componentsManagerBuilder = new ComponentsManagerBuilder({ + mainModulePath, + typeChecking: false, + }); + const mgr = await componentsManagerBuilder.build(); + + expect(mgr).toBeTruthy(); + expect(mgr.moduleState).toBe(dummyModuleState); + expect(mgr.objectLoader).toBeInstanceOf(RdfObjectLoader); + expect(Object.keys(mgr.componentResources).length).toBe(2); + expect(mgr.configRegistry).toBeInstanceOf(ConfigRegistry); + expect(mgr.dumpErrorState).toBe(true); + expect(mgr.configConstructorPool).toBeInstanceOf(ConfigConstructorPool); + expect(( mgr.configConstructorPool).constructionStrategy).toBeInstanceOf(ConstructionStrategyCommonJs); + expect(( mgr.configConstructorPool).configPreprocessors.length).toBe(2); + expect(( mgr.configConstructorPool).configPreprocessors[0]).toBeInstanceOf(ConfigPreprocessorComponentMapped); + expect(( mgr.configConstructorPool).configPreprocessors[1]).toBeInstanceOf(ConfigPreprocessorComponent); + expect(mgr.logger).toBeTruthy(); + expect(createLogger).toBeCalledTimes(1); + expect(createLogger).toHaveBeenCalledWith({ + level: 'warn', + transports: expect.anything(), + }); + }); }); diff --git a/test/unit/preprocess/ConfigPreprocessorComponent-test.ts b/test/unit/preprocess/ConfigPreprocessorComponent-test.ts index 0725252..d05b5b5 100644 --- a/test/unit/preprocess/ConfigPreprocessorComponent-test.ts +++ b/test/unit/preprocess/ConfigPreprocessorComponent-test.ts @@ -38,7 +38,7 @@ describe('ConfigPreprocessorComponent', () => { objectLoader, componentResources, runTypeConfigs: {}, - parameterHandler: new ParameterHandler({ objectLoader }), + parameterHandler: new ParameterHandler({ objectLoader, typeChecking: true }), logger, }); }); diff --git a/test/unit/preprocess/ConfigPreprocessorComponentMapped-test.ts b/test/unit/preprocess/ConfigPreprocessorComponentMapped-test.ts index de42785..2331e21 100644 --- a/test/unit/preprocess/ConfigPreprocessorComponentMapped-test.ts +++ b/test/unit/preprocess/ConfigPreprocessorComponentMapped-test.ts @@ -35,7 +35,7 @@ describe('ConfigPreprocessorComponentMapped', () => { objectLoader, componentResources, runTypeConfigs: {}, - parameterHandler: new ParameterHandler({ objectLoader }), + parameterHandler: new ParameterHandler({ objectLoader, typeChecking: true }), logger: { warn: jest.fn() }, }); }); diff --git a/test/unit/preprocess/ParameterHandler-test.ts b/test/unit/preprocess/ParameterHandler-test.ts index 823acf2..ecd8c09 100644 --- a/test/unit/preprocess/ParameterHandler-test.ts +++ b/test/unit/preprocess/ParameterHandler-test.ts @@ -18,7 +18,7 @@ describe('ParameterHandler', () => { }); await objectLoader.context; genericsContext = new GenericsContext(objectLoader, []); - handler = new ParameterHandler({ objectLoader }); + handler = new ParameterHandler({ objectLoader, typeChecking: true }); configRoot = objectLoader.createCompactedResource({ types: 'ex:Component1', diff --git a/test/unit/preprocess/parameterproperty/ParameterPropertyHandlerRange-test.ts b/test/unit/preprocess/parameterproperty/ParameterPropertyHandlerRange-test.ts index ab46f39..89f307f 100644 --- a/test/unit/preprocess/parameterproperty/ParameterPropertyHandlerRange-test.ts +++ b/test/unit/preprocess/parameterproperty/ParameterPropertyHandlerRange-test.ts @@ -33,7 +33,7 @@ describe('ParameterPropertyHandlerRange', () => { }); await objectLoader.context; genericsContext = new GenericsContext(objectLoader, []); - handler = new ParameterPropertyHandlerRange(objectLoader); + handler = new ParameterPropertyHandlerRange(objectLoader, true); }); describe('canHandle', () => { @@ -66,6 +66,17 @@ describe('ParameterPropertyHandlerRange', () => { genericsContext, )).toThrow(/The value "aaa" for parameter ".*" is not of required range type ".*integer"/u); }); + + it('does not throw on an invalid value when type-checking is disabled', () => { + handler = new ParameterPropertyHandlerRange(objectLoader, false); + expect(() => handler.handle( + objectLoader.createCompactedResource('"aaa"'), + objectLoader.createCompactedResource({}), + objectLoader.createCompactedResource({ range: IRIS_XSD.integer }), + objectLoader.createCompactedResource({}), + genericsContext, + )).not.toThrow(); + }); }); describe('hasValueType', () => {