Skip to content

Commit

Permalink
fix(core): adding context and sandbox object to resolvers
Browse files Browse the repository at this point in the history
this fix provides an ability to execute some resolving code inside test's vm context
  • Loading branch information
Igmat committed Mar 1, 2018
1 parent bd465a2 commit a56d1b1
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 13 deletions.
7 changes: 5 additions & 2 deletions packages/baset-core/src/abstractResolver.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { NodeVM } from 'baset-vm';
import { IDictionary } from './utils';

export abstract class AbstractResolver {
abstract match: (obj: any) => Promise<boolean>;
abstract resolve: (obj: any) => Promise<any>;
abstract match: (obj: any, context: NodeVM, sandbox: IDictionary<any>) => Promise<boolean>;
abstract resolve: (obj: any, context: NodeVM, sandbox: IDictionary<any>) => Promise<any>;
constructor(public options: any) { }
}

Expand Down
28 changes: 17 additions & 11 deletions packages/baset-core/src/testGroup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export class TestGroup {
private readerChain: AbstractReader[];
private resolvers: AbstractResolver[];
private allImports: string[];
private indexOfResolver: (obj: any) => Promise<number>;
private indexOfResolver: (obj: any, context: NodeVM, sandbox: IDictionary<any>) => Promise<number>;
constructor(
pattern: string | RegExp,
private options: ITestGroupOptions,
Expand All @@ -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<any>) => resolver.match(toMatch, context, sandbox));
this.indexOfResolver = async (obj: any, context: NodeVM, sandbox: IDictionary<any>) =>
(await Promise.all(
resolveMatchers
.map(matcher => matcher(obj))))
.map(matcher => matcher(obj, context, sandbox))))
.indexOf(true);

this.allImports = [
Expand All @@ -69,13 +69,15 @@ export class TestGroup {
read = async (filePath: string) => {
const resolvedPath = path.resolve(filePath);
const compiler = this.getCompiler();
const sandbox: IDictionary<any> = {};
const context = new NodeVM({
require: {
builtin: ['*'],
context: 'sandbox',
external: true,
import: this.allImports,
},
sandbox: { basetSandbox: sandbox },
compiler: compiler.compile,
sourceExtensions: compiler.extensions,
resolveFilename: compiler.resolveFilename,
Expand All @@ -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<any> => {
const resolverIndex = await this.indexOfResolver(obj);
if (resolverIndex !== -1) return this.resolvers[resolverIndex].resolve(obj);
private calculateValues = async (obj: any, context: NodeVM, sandbox: IDictionary<any>, name = 'exports'): Promise<any> => {
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 }), {});
}

Expand Down

0 comments on commit a56d1b1

Please sign in to comment.