UNPKG

6.43 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.printResults = exports.runTests = void 0;
4var fs_1 = require("fs");
5var vm_1 = require("vm");
6var core_1 = require("@babel/core");
7var preset_env_1 = require("@babel/preset-env");
8var chalk_1 = require("chalk");
9function flatten(arr) {
10 return Array.prototype.concat.apply([], arr);
11}
12var parse_code_snippets_from_markdown_1 = require("./parse-code-snippets-from-markdown");
13function runTests(files, config) {
14 var results = files
15 .map(read)
16 .map(parse_code_snippets_from_markdown_1.default)
17 .map(testFile(config));
18 return flatten(results);
19}
20exports.runTests = runTests;
21function read(fileName) {
22 return { contents: fs_1.readFileSync(fileName, "utf8"), fileName: fileName };
23}
24function makeTestSandbox(config) {
25 function sandboxRequire(moduleName) {
26 for (var regexRequire in config.regexRequire) {
27 var regex = new RegExp(regexRequire);
28 var match = regex.exec(moduleName);
29 var handler = config.regexRequire[regexRequire];
30 if (match) {
31 return handler.apply(void 0, match);
32 }
33 }
34 if (config.require[moduleName] === undefined) {
35 throw moduleNotFoundError(moduleName);
36 }
37 return config.require[moduleName];
38 }
39 var sandboxConsole = {
40 log: function () { return null; },
41 };
42 var sandboxGlobals = { require: sandboxRequire, console: sandboxConsole };
43 var sandbox = Object.assign({}, sandboxGlobals, config.globals);
44 return sandbox;
45}
46function testFile(config) {
47 return function testFileWithConfig(args) {
48 var codeSnippets = args.codeSnippets;
49 var fileName = args.fileName;
50 var shareCodeInFile = args.shareCodeInFile;
51 var results;
52 if (shareCodeInFile) {
53 var sandbox = makeTestSandbox(config);
54 results = codeSnippets.map(test(config, fileName, sandbox));
55 }
56 else {
57 results = codeSnippets.map(test(config, fileName));
58 }
59 return results;
60 };
61}
62function test(config, filename, sandbox) {
63 return function (codeSnippet) {
64 if (codeSnippet.skip) {
65 return { status: "skip", codeSnippet: codeSnippet, stack: "" };
66 }
67 var success = false;
68 var stack = "";
69 var code = codeSnippet.code;
70 if (config.transformCode) {
71 try {
72 code = config.transformCode(code);
73 }
74 catch (e) {
75 return { status: "fail", codeSnippet: codeSnippet, stack: "Encountered an error while transforming snippet: \n" + e.stack };
76 }
77 }
78 var perSnippetSandbox;
79 if (sandbox === undefined) {
80 perSnippetSandbox = makeTestSandbox(config);
81 }
82 if (config.beforeEach) {
83 config.beforeEach();
84 }
85 var options = {
86 presets: [preset_env_1.default],
87 };
88 try {
89 if (config.babel !== false) {
90 code = core_1.transformSync(code, options).code;
91 }
92 vm_1.runInNewContext(code, perSnippetSandbox || sandbox);
93 success = true;
94 }
95 catch (e) {
96 stack = e.stack || "";
97 }
98 var status = success ? "pass" : "fail";
99 process.stdout.write(success ? chalk_1.default.green(".") : chalk_1.default.red("x"));
100 return { status: status, codeSnippet: codeSnippet, stack: stack };
101 };
102}
103function printResults(results) {
104 results.filter(function (result) { return result.status === "fail"; }).forEach(printFailure);
105 var passingCount = results.filter(function (result) { return result.status === "pass"; })
106 .length;
107 var failingCount = results.filter(function (result) { return result.status === "fail"; })
108 .length;
109 var skippingCount = results.filter(function (result) { return result.status === "skip"; })
110 .length;
111 function successfulRun() {
112 return failingCount === 0;
113 }
114 console.log(chalk_1.default.green("Passed: " + passingCount));
115 if (skippingCount > 0) {
116 console.log(chalk_1.default.yellow("Skipped: " + skippingCount));
117 }
118 if (successfulRun()) {
119 console.log(chalk_1.default.green("\nSuccess!"));
120 }
121 else {
122 console.log(chalk_1.default.red("Failed: " + failingCount));
123 }
124}
125exports.printResults = printResults;
126function printFailure(result) {
127 console.log(chalk_1.default.red("Failed - " + markDownErrorLocation(result)));
128 var stackDetails = relevantStackDetails(result.stack);
129 console.log(stackDetails);
130 var variableNotDefined = stackDetails.match(/(\w+) is not defined/);
131 if (variableNotDefined) {
132 var variableName = variableNotDefined[1];
133 console.log("You can declare " + chalk_1.default.blue(variableName) + " in the " + chalk_1.default.blue("globals") + " section in " + chalk_1.default.grey(".markdown-doctest-setup.js"));
134 console.log("\nFor example:\n" + chalk_1.default.grey("// .markdown-doctest-setup.js") + "\nmodule.exports = {\n globals: {\n " + chalk_1.default.blue(variableName) + ": ...\n }\n}\n ");
135 }
136}
137function relevantStackDetails(stack) {
138 var match = stack.match(/([\w\W]*?)at eval/) ||
139 stack.match(/([\w\W]*)at [\w*\/]*?doctest.js/);
140 if (match !== null) {
141 return match[1];
142 }
143 return stack;
144}
145function moduleNotFoundError(moduleName) {
146 return new Error("\nAttempted to require '" + chalk_1.default.blue(moduleName) + "' but was not found in config.\nYou need to include it in the require section of your " + chalk_1.default.grey(".markdown-doctest-setup.js") + " file.\n\nFor example:\n" + chalk_1.default.grey("// .markdown-doctest-setup.js") + "\nmodule.exports = {\n require: {\n " + chalk_1.default.blue("'" + moduleName + "': require('" + moduleName + "')") + "\n }\n}\n ");
147}
148function markDownErrorLocation(result) {
149 var match = result.stack.match(/eval.*<.*>:(\d+):(\d+)/);
150 if (match) {
151 var mdLineNumber = parseInt(match[1], 10);
152 var columnNumber = parseInt(match[2], 10);
153 var lineNumber = result.codeSnippet.lineNumber + mdLineNumber;
154 return result.codeSnippet.fileName + ":" + lineNumber + ":" + columnNumber;
155 }
156 return result.codeSnippet.fileName + ":" + result.codeSnippet.lineNumber;
157}