Skip to content

Commit

Permalink
feat: implement jslib with modules
Browse files Browse the repository at this point in the history
  • Loading branch information
sigoden committed Jun 6, 2021
1 parent 1be3492 commit b94f1c9
Show file tree
Hide file tree
Showing 11 changed files with 52 additions and 41 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ Write functions `lib.js`

```js
// Make random color e.g. #34FFFF
function randColor() {
exports.makeColor = function () {
const letters = '0123456789ABCDEF';
let color = '#';
for (let i = 0; i < 6; i++) {
Expand All @@ -340,7 +340,7 @@ function randColor() {
}

// Detect date in ISO8601(e.g. 2021-06-02:00:00.000Z) format
function isDate(date) {
exports.isDate = function (date) {
return /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/.test(date)
}
```
Expand All @@ -354,7 +354,7 @@ Use functions
test1: {
req: {
body: {
// call the `randColor` function to generate random colors
// call the `makeColor` function to generate random colors
color:'makeColor()', @eval
}
},
Expand Down
10 changes: 5 additions & 5 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -327,17 +327,17 @@ Apitest 使用JSONA格式描述测试用例。 JSON描述数据,注解描述
```js

// 创建随机颜色
function randColor() {
const letters = '0123456789ABCDEF';
let color = '#';
exports.makeColor = function () {
const letters = "0123456789ABCDEF";
let color = "#";
for (let i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}

// 判断是否是ISO8601(2021-06-02:00:00.000Z)风格的时间字符串
function isDate(date) {
exports.isDate = function (date) {
return /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/.test(date)
}
```
Expand All @@ -350,7 +350,7 @@ function isDate(date) {
test1: {
req: {
body: {
color: 'makeColor()', @eval // 调用 `randColor` 函数生成随机颜色
color: 'makeColor()', @eval // 调用 `makeColor` 函数生成随机颜色
}
},
res: {
Expand Down
18 changes: 7 additions & 11 deletions src/Loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,13 @@ export interface Module {
describe: string;
}

export interface JSLib {
}

export default class Loader {
private workDir: string;
private cases: Cases;
private jslibs: string[] = [];
private jslib: JSLib = {};
private clients: Clients = new Clients();
private modules: Module[] = [];
private mixin: JsonaObject;
Expand Down Expand Up @@ -58,7 +61,7 @@ export default class Loader {
mainFile,
cases: this.cases,
clients: this.clients,
jslibs: this.jslibs,
jslibs: this.jslib,
};
}

Expand Down Expand Up @@ -128,18 +131,11 @@ export default class Loader {
const libFile = path.resolve(this.workDir, libFileName);
let jslib;
try {
jslib = await fs.readFile(libFile, "utf8");
} catch (err) {
throw new Error(`main@jslib(${libName}): load ${libFileName} failed`);
}
try {
const context = {};
const script = new vm.Script(jslib);
script.runInNewContext(context);
jslib = require(libFile);
} catch (err) {
throw new Error(`main@jslib(${libName}): load ${libFileName} throw ${err.message}${toPosString(anno.position)}`);
}
this.jslibs.push(jslib);
_.merge(this.jslib, jslib);
} else {
throw new Error(`[main@jslib] should have string value${toPosString(anno.position)}`);
}
Expand Down
13 changes: 7 additions & 6 deletions src/Session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,24 @@ import * as fs from "fs/promises";
import * as crypto from "crypto";
import * as _ from "lodash";
import { Case, Unit } from "./Cases";
import { JSLib } from "./Loader";

export const EMPTY_CACHE = { cursor: "", tests: {} };

export default class Session {
private cacheFile: string;
private cache: Cache;
private unitIds: string[];
private jslibs: string[] = [];
private jslib: JSLib;

public constructor(cacheFile: string, unitIds: string[], cache: Cache, jslibs: string[]) {
public constructor(cacheFile: string, unitIds: string[], cache: Cache, jslib: JSLib) {
this.cacheFile = cacheFile;
this.unitIds = unitIds;
this.cache = cache;
this.jslibs = jslibs;
this.jslib = jslib;
}

public static async create(mainFile: string, unitIds: string[], jslibs: string[]) {
public static async create(mainFile: string, unitIds: string[], jslibs: any) {
const cacheFileName = "apitest" + md5(mainFile) + ".json";
const cacheFile = path.resolve(os.tmpdir(), cacheFileName);
const cache = await loadCache(cacheFile);
Expand Down Expand Up @@ -59,7 +60,7 @@ export default class Session {
_.set(state, ["req"], req);
_.set(this.cache.tests, testcase.paths.concat(["req"]), req);
}
return { state, jslibs: this.jslibs };
return { state, jslib: this.jslib };
}

public async saveValue(testcase: Case, key: string, value: any, persist = true) {
Expand Down Expand Up @@ -89,7 +90,7 @@ export default class Session {
}

export interface VmContext {
jslibs: string[],
jslib: JSLib,
state: any;
}

Expand Down
3 changes: 2 additions & 1 deletion src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,13 @@ export function evalValue(paths: string[], ctx: VmContext, code: string, anno =
if (!expressions[lastIdx].trim().startsWith("return")) {
expressions[lastIdx] = "return " + expressions[lastIdx];
}
const patchedCode = ctx.jslibs.join("\n") + expressions.join(";");
const patchedCode = expressions.join(";");
const EXPORT_KEY = "__exports__";
ctx.state[EXPORT_KEY] = null;
try {
const wrapCode = `${EXPORT_KEY} = (function(){${patchedCode};}())`;
const script = new vm.Script(wrapCode);
_.merge(ctx.state, ctx.jslib);
script.runInNewContext(ctx.state);
return ctx.state[EXPORT_KEY];
} catch (err) {
Expand Down
5 changes: 0 additions & 5 deletions tests/__snapshots__/loader.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,6 @@ exports[`loader invalid jslib 1`] = `
`;

exports[`loader invalid jslib js 1`] = `
"main@jslib(invalid-jslib-404): load invalid-jslib-404.js failed
"
`;

exports[`loader invalid jslib js2 1`] = `
"main@jslib(invalid-jslib): load invalid-jslib.js throw Unexpected end of input at line 2 col 4
"
`;
Expand Down
2 changes: 1 addition & 1 deletion tests/fixtures/loader/invalid-jslib-js.jsona
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
@jslib("invalid-jslib-404")
@jslib("invalid-jslib")
}
3 changes: 0 additions & 3 deletions tests/fixtures/loader/invalid-jslib-js2.jsona

This file was deleted.

12 changes: 12 additions & 0 deletions tests/fixtures/loader/jslib.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
exports.makeColor = function () {
const letters = "0123456789ABCDEF";
let color = "#";
for (let i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
};

exports.isDate = function (date) {
return /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/.test(date);
};
11 changes: 11 additions & 0 deletions tests/fixtures/loader/jslib.jsona
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
@jslib("jslib")
test1: { @client("echo")
req: {
color: 'makeColor()', @eval
},
res: {
color: `/#[0-9A-F]{6}/.test($)`, @eval
}
}
}
10 changes: 4 additions & 6 deletions tests/loader.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,6 @@ describe("loader", () => {
expect(code).toEqual(1);
expect(stdout).toMatchSnapshot();
});
test("invalid jslib js2", async () => {
const { stdout, code } = await spwanTest("loader/invalid-jslib-js2.jsona", ["--ci"]);
expect(code).toEqual(1);
expect(stdout).toMatchSnapshot();
});
test("invalid jslib", async () => {
const { stdout, code } = await spwanTest("loader/invalid-jslib.jsona", ["--ci"]);
expect(code).toEqual(1);
Expand Down Expand Up @@ -66,7 +61,10 @@ describe("loader", () => {
expect(code).toEqual(1);
expect(stdout).toMatchSnapshot();
});

test("jslib", async () => {
const { code } = await spwanTest("loader/jslib.jsona", ["--ci"]);
expect(code).toEqual(0);
});
test("target file not found", async () => {
const { stdout, code } = await spwanTest("loader/notfound.jsona", ["--ci"]);
expect(code).toEqual(1);
Expand Down

0 comments on commit b94f1c9

Please sign in to comment.