From a56d1b1425ccb6115601e9b047dfcb111fe80bb8 Mon Sep 17 00:00:00 2001 From: Ihor Chulinda Date: Thu, 1 Mar 2018 12:57:24 +0100 Subject: [PATCH] fix(core): adding context and sandbox object to resolvers this fix provides an ability to execute some resolving code inside test's vm context --- packages/baset-core/src/abstractResolver.ts | 7 ++++-- packages/baset-core/src/testGroup.ts | 28 +++++++++++++-------- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/packages/baset-core/src/abstractResolver.ts b/packages/baset-core/src/abstractResolver.ts index ac3a5804..e4469f4d 100644 --- a/packages/baset-core/src/abstractResolver.ts +++ b/packages/baset-core/src/abstractResolver.ts @@ -1,6 +1,9 @@ +import { NodeVM } from 'baset-vm'; +import { IDictionary } from './utils'; + export abstract class AbstractResolver { - abstract match: (obj: any) => Promise; - abstract resolve: (obj: any) => Promise; + abstract match: (obj: any, context: NodeVM, sandbox: IDictionary) => Promise; + abstract resolve: (obj: any, context: NodeVM, sandbox: IDictionary) => Promise; constructor(public options: any) { } } diff --git a/packages/baset-core/src/testGroup.ts b/packages/baset-core/src/testGroup.ts index e8e036cb..f51f6267 100644 --- a/packages/baset-core/src/testGroup.ts +++ b/packages/baset-core/src/testGroup.ts @@ -26,7 +26,7 @@ export class TestGroup { private readerChain: AbstractReader[]; private resolvers: AbstractResolver[]; private allImports: string[]; - private indexOfResolver: (obj: any) => Promise; + private indexOfResolver: (obj: any, context: NodeVM, sandbox: IDictionary) => Promise; constructor( pattern: string | RegExp, private options: ITestGroupOptions, @@ -50,11 +50,11 @@ export class TestGroup { const resolveMatchers = this.resolvers .map((resolver, index) => - async (toMatch: any) => resolver.match(toMatch)); - this.indexOfResolver = async (obj: any) => + async (toMatch: any, context: NodeVM, sandbox: IDictionary) => resolver.match(toMatch, context, sandbox)); + this.indexOfResolver = async (obj: any, context: NodeVM, sandbox: IDictionary) => (await Promise.all( resolveMatchers - .map(matcher => matcher(obj)))) + .map(matcher => matcher(obj, context, sandbox)))) .indexOf(true); this.allImports = [ @@ -69,6 +69,7 @@ export class TestGroup { read = async (filePath: string) => { const resolvedPath = path.resolve(filePath); const compiler = this.getCompiler(); + const sandbox: IDictionary = {}; const context = new NodeVM({ require: { builtin: ['*'], @@ -76,6 +77,7 @@ export class TestGroup { external: true, import: this.allImports, }, + sandbox: { basetSandbox: sandbox }, compiler: compiler.compile, sourceExtensions: compiler.extensions, resolveFilename: compiler.resolveFilename, @@ -87,23 +89,27 @@ export class TestGroup { ? compiledSrc : [compiledSrc]; const testsExports = tests.map((test, index) => context.run(test, `${resolvedPath}.${index}.js`)); - const testsResults = testsExports.map((value, index) => this.calculateValues(value, `exports[${index}]`)); + const testsResults = testsExports.map((value, index) => this.calculateValues(value, context, sandbox, `exports[${index}]`)); return this.baseliner.create(testsResults); } // tslint:disable-next-line:no-any - private calculateValues = async (obj: any, name = 'exports'): Promise => { - const resolverIndex = await this.indexOfResolver(obj); - if (resolverIndex !== -1) return this.resolvers[resolverIndex].resolve(obj); + private calculateValues = async (obj: any, context: NodeVM, sandbox: IDictionary, name = 'exports'): Promise => { + const resolverIndex = await this.indexOfResolver(obj, context, sandbox); + if (resolverIndex !== -1) return this.resolvers[resolverIndex].resolve(obj, context, sandbox); if (isPrimitive(obj)) return obj; if (this.references.has(obj)) return this.createSelfReference(obj); this.references.set(obj, name); - if (obj instanceof Promise) return this.calculateValues(await obj, name); + if (obj instanceof Promise) return this.calculateValues(await obj, context, sandbox, name); if (obj instanceof Function) return obj.toString().split('\n')[0]; - if (Array.isArray(obj)) return await Promise.all(obj.map((value, key) => this.calculateValues(value, `${name}[${key}]`))); + if (Array.isArray(obj)) { + return await Promise.all( + obj.map((value, key) => + this.calculateValues(value, context, sandbox, `${name}[${key}]`))); + } return (await Promise.all(Object.keys(obj) - .map(async key => ({ [key]: await this.calculateValues(obj[key], `${name}.${key}`) })))) + .map(async key => ({ [key]: await this.calculateValues(obj[key], context, sandbox, `${name}.${key}`) })))) .reduce((result, prop) => ({ ...result, ...prop }), {}); }