readme-assert 6.0.3 → 7.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +20 -40
- package/readme.md +90 -75
- package/src/cli.js +87 -0
- package/src/comment-to-assert.js +139 -0
- package/src/extract.js +66 -0
- package/src/generate.js +94 -0
- package/src/index.js +4 -0
- package/src/run.js +268 -0
- package/cli.js +0 -9
- package/lib/cli.js +0 -62
- package/lib/extract.js +0 -74
- package/lib/global-assert.js +0 -144
- package/lib/index.js +0 -111
- package/lib/runInThisContext.js +0 -45
- package/license +0 -21
package/src/run.js
ADDED
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { spawn } from "node:child_process";
|
|
4
|
+
import { randomUUID } from "node:crypto";
|
|
5
|
+
import { extractBlocks } from "./extract.js";
|
|
6
|
+
import { generate } from "./generate.js";
|
|
7
|
+
import { commentToAssert } from "./comment-to-assert.js";
|
|
8
|
+
|
|
9
|
+
const tmpFiles = new Set();
|
|
10
|
+
|
|
11
|
+
function cleanupTmpFiles() {
|
|
12
|
+
for (const f of tmpFiles) {
|
|
13
|
+
try { fs.unlinkSync(f); } catch {}
|
|
14
|
+
}
|
|
15
|
+
tmpFiles.clear();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
process.on("exit", cleanupTmpFiles);
|
|
19
|
+
|
|
20
|
+
for (const signal of ["SIGINT", "SIGTERM"]) {
|
|
21
|
+
process.once(signal, () => {
|
|
22
|
+
cleanupTmpFiles();
|
|
23
|
+
process.kill(process.pid, signal);
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Process a markdown file into executable code units.
|
|
29
|
+
*
|
|
30
|
+
* @param {string} filePath
|
|
31
|
+
* @param {{ auto?: boolean, all?: boolean, main?: string }} options
|
|
32
|
+
* @returns {Promise<Array<{ code: string, name: string }>>}
|
|
33
|
+
*/
|
|
34
|
+
export async function processMarkdown(filePath, options = {}) {
|
|
35
|
+
const markdown = fs.readFileSync(filePath, "utf-8");
|
|
36
|
+
const extracted = extractBlocks(markdown, {
|
|
37
|
+
auto: options.auto,
|
|
38
|
+
all: options.all,
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
if (extracted.blocks.length === 0) {
|
|
42
|
+
throw new Error("README has no test code blocks");
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const { units } = generate(extracted);
|
|
46
|
+
|
|
47
|
+
// Resolve package info for import renaming
|
|
48
|
+
let packageName, localPath;
|
|
49
|
+
const pkgPath = findPackageJson(path.dirname(filePath));
|
|
50
|
+
if (pkgPath) {
|
|
51
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
|
|
52
|
+
if (pkg.name) {
|
|
53
|
+
const mainEntry = options.main || pkg.main || pkg.exports?.["."] || "./index.js";
|
|
54
|
+
packageName = pkg.name;
|
|
55
|
+
localPath = path.resolve(path.dirname(pkgPath), mainEntry);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const results = [];
|
|
60
|
+
for (const unit of units) {
|
|
61
|
+
let code = unit.code;
|
|
62
|
+
|
|
63
|
+
if (packageName) {
|
|
64
|
+
code = renameImports(code, packageName, localPath);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const transformed = commentToAssert(code, {
|
|
68
|
+
filename: filePath,
|
|
69
|
+
typescript: unit.hasTypescript,
|
|
70
|
+
});
|
|
71
|
+
code = transformed.code;
|
|
72
|
+
|
|
73
|
+
if (unit.hasTypescript) {
|
|
74
|
+
const esbuild = await import("esbuild");
|
|
75
|
+
const result = await esbuild.transform(code, {
|
|
76
|
+
loader: "ts",
|
|
77
|
+
sourcemap: false,
|
|
78
|
+
});
|
|
79
|
+
code = result.code;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
results.push({ code, name: unit.name });
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return results;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Run a markdown file as a test.
|
|
90
|
+
*
|
|
91
|
+
* Each code block (or group) is written to a temp file and executed
|
|
92
|
+
* sequentially. Stops on first failure.
|
|
93
|
+
*
|
|
94
|
+
* @param {string} filePath
|
|
95
|
+
* @param {{ auto?: boolean, all?: boolean, main?: string }} options
|
|
96
|
+
* @returns {Promise<{ exitCode: number, stdout: string, stderr: string, results: Array }>}
|
|
97
|
+
*/
|
|
98
|
+
export async function run(filePath, options = {}) {
|
|
99
|
+
const units = await processMarkdown(filePath, options);
|
|
100
|
+
const dir = path.dirname(filePath);
|
|
101
|
+
let allStdout = "";
|
|
102
|
+
let allStderr = "";
|
|
103
|
+
const results = [];
|
|
104
|
+
|
|
105
|
+
const useRequire = options.require?.length > 0;
|
|
106
|
+
|
|
107
|
+
for (const unit of units) {
|
|
108
|
+
let code = unit.code;
|
|
109
|
+
|
|
110
|
+
// --require hooks only work with CJS, so downgrade dynamic import to require
|
|
111
|
+
if (useRequire && code.includes("await import(")) {
|
|
112
|
+
code = code.replace(
|
|
113
|
+
'const { default: assert } = await import("node:assert/strict");',
|
|
114
|
+
'const assert = require("node:assert/strict");',
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const isESM = /^import\s/m.test(code) || /^export\s/m.test(code) || code.includes("await import(");
|
|
119
|
+
const ext = isESM ? ".mjs" : ".cjs";
|
|
120
|
+
const tmpFile = path.join(dir, `.readme-assert-${randomUUID().slice(0, 8)}${ext}`);
|
|
121
|
+
tmpFiles.add(tmpFile);
|
|
122
|
+
fs.writeFileSync(tmpFile, code);
|
|
123
|
+
|
|
124
|
+
try {
|
|
125
|
+
const nodeArgs = [];
|
|
126
|
+
for (const r of options.require || []) nodeArgs.push("--require", r);
|
|
127
|
+
for (const i of options.import || []) nodeArgs.push("--import", i);
|
|
128
|
+
nodeArgs.push(tmpFile);
|
|
129
|
+
const result = await exec("node", nodeArgs, dir, filePath);
|
|
130
|
+
allStdout += result.stdout;
|
|
131
|
+
allStderr += result.stderr;
|
|
132
|
+
results.push({ name: unit.name, ...result });
|
|
133
|
+
|
|
134
|
+
if (result.exitCode !== 0) {
|
|
135
|
+
return { exitCode: result.exitCode, stdout: allStdout, stderr: allStderr, results };
|
|
136
|
+
}
|
|
137
|
+
} finally {
|
|
138
|
+
try { fs.unlinkSync(tmpFile); } catch {}
|
|
139
|
+
tmpFiles.delete(tmpFile);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return { exitCode: 0, stdout: allStdout, stderr: allStderr, results };
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function exec(cmd, args, cwd, mdPath) {
|
|
147
|
+
return new Promise((resolve) => {
|
|
148
|
+
const child = spawn(cmd, args, { cwd, stdio: ["ignore", "pipe", "pipe"] });
|
|
149
|
+
let stdout = "";
|
|
150
|
+
let stderr = "";
|
|
151
|
+
|
|
152
|
+
child.stdout.on("data", (d) => (stdout += d));
|
|
153
|
+
child.stderr.on("data", (d) => (stderr += d));
|
|
154
|
+
|
|
155
|
+
child.on("close", (exitCode) => {
|
|
156
|
+
// Rewrite temp file paths to the markdown file path
|
|
157
|
+
const tmpFile = args[args.length - 1];
|
|
158
|
+
stderr = stderr.replaceAll(tmpFile, mdPath);
|
|
159
|
+
stdout = stdout.replaceAll(tmpFile, mdPath);
|
|
160
|
+
|
|
161
|
+
if (exitCode !== 0) {
|
|
162
|
+
stderr = formatError(stderr, mdPath);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
resolve({ exitCode, stdout, stderr });
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function formatError(stderr, mdPath) {
|
|
171
|
+
// Extract location from stack trace
|
|
172
|
+
const locMatch = stderr.match(new RegExp(`${escapeRegExp(mdPath)}:(\\d+):(\\d+)`));
|
|
173
|
+
const line = locMatch ? parseInt(locMatch[1]) : null;
|
|
174
|
+
|
|
175
|
+
// Extract actual/expected from the error object dump
|
|
176
|
+
const actualMatch = stderr.match(/actual: (.+)/);
|
|
177
|
+
const expectedMatch = stderr.match(/expected: (.+)/);
|
|
178
|
+
const operatorMatch = stderr.match(/operator: '(.+)'/);
|
|
179
|
+
|
|
180
|
+
// Extract the error message line
|
|
181
|
+
const msgMatch = stderr.match(/AssertionError.*?:\s*(.+)/);
|
|
182
|
+
// Also catch non-assertion errors (ReferenceError, TypeError, etc.)
|
|
183
|
+
const genericMatch = !msgMatch && stderr.match(/(\w*Error.*)/);
|
|
184
|
+
|
|
185
|
+
const parts = [];
|
|
186
|
+
|
|
187
|
+
// Location header
|
|
188
|
+
const relPath = path.relative(process.cwd(), mdPath);
|
|
189
|
+
if (line) {
|
|
190
|
+
parts.push(`\n FAIL ${relPath}:${line}\n`);
|
|
191
|
+
} else {
|
|
192
|
+
parts.push(`\n FAIL ${relPath}\n`);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Source context from the markdown
|
|
196
|
+
if (line) {
|
|
197
|
+
try {
|
|
198
|
+
const mdLines = fs.readFileSync(mdPath, "utf-8").split("\n");
|
|
199
|
+
const start = Math.max(0, line - 3);
|
|
200
|
+
const end = Math.min(mdLines.length, line + 2);
|
|
201
|
+
for (let i = start; i < end; i++) {
|
|
202
|
+
const lineNum = String(i + 1).padStart(4);
|
|
203
|
+
const marker = i + 1 === line ? " > " : " ";
|
|
204
|
+
parts.push(`${marker}${lineNum} | ${mdLines[i]}`);
|
|
205
|
+
}
|
|
206
|
+
parts.push("");
|
|
207
|
+
} catch {
|
|
208
|
+
// ignore read errors
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// Actual vs expected
|
|
213
|
+
if (actualMatch && expectedMatch) {
|
|
214
|
+
parts.push(` expected: ${expectedMatch[1].replace(/,\s*$/, "")}`);
|
|
215
|
+
parts.push(` received: ${actualMatch[1].replace(/,\s*$/, "")}`);
|
|
216
|
+
parts.push("");
|
|
217
|
+
} else if (msgMatch) {
|
|
218
|
+
parts.push(` ${msgMatch[0]}`);
|
|
219
|
+
parts.push("");
|
|
220
|
+
} else if (genericMatch) {
|
|
221
|
+
parts.push(` ${genericMatch[1]}`);
|
|
222
|
+
parts.push("");
|
|
223
|
+
} else {
|
|
224
|
+
// Fallback: strip Node internals and return cleaned stderr
|
|
225
|
+
parts.push(
|
|
226
|
+
stderr
|
|
227
|
+
.split("\n")
|
|
228
|
+
.filter((l) => !l.match(/^\s*(at [a-z].*\(node:|node:internal|Node\.js v|triggerUncaught|\^$)/i))
|
|
229
|
+
.join("\n")
|
|
230
|
+
.trim(),
|
|
231
|
+
);
|
|
232
|
+
parts.push("");
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
return parts.join("\n");
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
function escapeRegExp(s) {
|
|
239
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
function renameImports(code, packageName, localPath) {
|
|
243
|
+
const escaped = packageName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
244
|
+
return code
|
|
245
|
+
.replace(
|
|
246
|
+
new RegExp(`(from\\s+['"])${escaped}(['"])`, "g"),
|
|
247
|
+
`$1${localPath}$2`,
|
|
248
|
+
)
|
|
249
|
+
.replace(
|
|
250
|
+
new RegExp(`(from\\s+['"])${escaped}/`, "g"),
|
|
251
|
+
`$1${path.dirname(localPath)}/`,
|
|
252
|
+
)
|
|
253
|
+
.replace(
|
|
254
|
+
new RegExp(`(require\\s*\\(\\s*['"])${escaped}(['"]\\s*\\))`, "g"),
|
|
255
|
+
`$1${localPath}$2`,
|
|
256
|
+
);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
function findPackageJson(dir) {
|
|
260
|
+
let current = path.resolve(dir);
|
|
261
|
+
while (true) {
|
|
262
|
+
const candidate = path.join(current, "package.json");
|
|
263
|
+
if (fs.existsSync(candidate)) return candidate;
|
|
264
|
+
const parent = path.dirname(current);
|
|
265
|
+
if (parent === current) return null;
|
|
266
|
+
current = parent;
|
|
267
|
+
}
|
|
268
|
+
}
|
package/cli.js
DELETED
package/lib/cli.js
DELETED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
var _yargs = _interopRequireDefault(require("yargs"));
|
|
4
|
-
|
|
5
|
-
var _ = _interopRequireDefault(require("."));
|
|
6
|
-
|
|
7
|
-
var _package = require("../package.json");
|
|
8
|
-
|
|
9
|
-
var _fs = _interopRequireDefault(require("fs"));
|
|
10
|
-
|
|
11
|
-
var _path = _interopRequireDefault(require("path"));
|
|
12
|
-
|
|
13
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
|
14
|
-
|
|
15
|
-
var argv = _yargs["default"].usage("\nRun readme as test\n\nUsage: $0 [options]").option("auto", {
|
|
16
|
-
alias: "a",
|
|
17
|
-
description: "Auto discover test code block",
|
|
18
|
-
type: "boolean"
|
|
19
|
-
}).option("all", {
|
|
20
|
-
alias: "l",
|
|
21
|
-
description: "Run all supported code blocks",
|
|
22
|
-
type: "boolean"
|
|
23
|
-
}).option("babel", {
|
|
24
|
-
description: "Use babelrc when transpiling",
|
|
25
|
-
"default": false,
|
|
26
|
-
type: "boolean"
|
|
27
|
-
}).option("file", {
|
|
28
|
-
alias: "f",
|
|
29
|
-
description: "readme.md file to read"
|
|
30
|
-
}).option("main", {
|
|
31
|
-
alias: "m",
|
|
32
|
-
description: "Points to the entry point of the module",
|
|
33
|
-
type: "string"
|
|
34
|
-
}).option("print-code", {
|
|
35
|
-
alias: "p",
|
|
36
|
-
description: "Print the transformed code",
|
|
37
|
-
type: "boolean"
|
|
38
|
-
}).option("require", {
|
|
39
|
-
alias: "r",
|
|
40
|
-
description: "Require a given module",
|
|
41
|
-
type: "array"
|
|
42
|
-
}).alias("h", "help").version(_package.version).help().argv;
|
|
43
|
-
|
|
44
|
-
function resolve(file) {
|
|
45
|
-
try {
|
|
46
|
-
_fs["default"].statSync(_path["default"].join(process.cwd(), file));
|
|
47
|
-
|
|
48
|
-
return _path["default"].resolve(file);
|
|
49
|
-
} catch (err) {
|
|
50
|
-
return undefined;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
var filename = argv.file ? _path["default"].resolve(argv.file) : resolve("README.md") || resolve("readme.md");
|
|
55
|
-
|
|
56
|
-
if (filename == null) {
|
|
57
|
-
console.log(_fs["default"].statSync(_path["default"].join(process.cwd(), "README.md")));
|
|
58
|
-
console.error("could not locate readme.md");
|
|
59
|
-
process.exit(1);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
(0, _["default"])(argv.main, argv.require || [], argv["print-code"], argv.babel, argv.file ? _path["default"].resolve(argv.file) : resolve("README.md") || resolve("readme.md"), argv.auto, argv.all);
|
package/lib/extract.js
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports["default"] = extractCode;
|
|
7
|
-
|
|
8
|
-
var _gfmCodeBlocks = _interopRequireDefault(require("gfm-code-blocks"));
|
|
9
|
-
|
|
10
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
|
11
|
-
|
|
12
|
-
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }
|
|
13
|
-
|
|
14
|
-
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); }
|
|
15
|
-
|
|
16
|
-
function _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); }
|
|
17
|
-
|
|
18
|
-
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }
|
|
19
|
-
|
|
20
|
-
function isSupportedLang(block) {
|
|
21
|
-
var lang = block.lang.split(" ")[0];
|
|
22
|
-
return lang === "javascript" || lang === "js" || lang === "typescript" || lang === "ts";
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function isTypescript(block) {
|
|
26
|
-
var lang = block.lang.split(" ")[0];
|
|
27
|
-
return lang === "typescript" || lang === "ts";
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function isTest(block) {
|
|
31
|
-
var tag = block.lang.split(" ")[1];
|
|
32
|
-
return tag === "test" || tag === "should";
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
var arrowRegex = /\/(\/|\*)\s?(=>|→|throws)/;
|
|
36
|
-
|
|
37
|
-
function isAutomaticTest(block) {
|
|
38
|
-
return block.code.match(arrowRegex);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function extractCode(markdown) {
|
|
42
|
-
var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
|
|
43
|
-
_ref$auto = _ref.auto,
|
|
44
|
-
auto = _ref$auto === void 0 ? false : _ref$auto,
|
|
45
|
-
_ref$all = _ref.all,
|
|
46
|
-
all = _ref$all === void 0 ? false : _ref$all;
|
|
47
|
-
|
|
48
|
-
var hasTypescript = false;
|
|
49
|
-
var code = new Array(markdown.length).fill(" ");
|
|
50
|
-
var newline = /\n/gm;
|
|
51
|
-
var result;
|
|
52
|
-
|
|
53
|
-
while (result = newline.exec(markdown)) {
|
|
54
|
-
code[result.index] = "\n";
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
var blocks = (0, _gfmCodeBlocks["default"])(markdown).filter(all ? function () {
|
|
58
|
-
return true;
|
|
59
|
-
} : auto ? isAutomaticTest : isTest).filter(isSupportedLang);
|
|
60
|
-
|
|
61
|
-
if (blocks.length === 0) {
|
|
62
|
-
console.error("\nREADME has no test code blocks\n");
|
|
63
|
-
process.exit(1);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
blocks.forEach(function (block) {
|
|
67
|
-
hasTypescript = hasTypescript || isTypescript(block);
|
|
68
|
-
code.splice.apply(code, [block.start, block.end - block.start].concat(_toConsumableArray(block.code.padStart(block.end - block.start, " ").split(""))));
|
|
69
|
-
});
|
|
70
|
-
return {
|
|
71
|
-
code: code.join(""),
|
|
72
|
-
hasTypescript: hasTypescript
|
|
73
|
-
};
|
|
74
|
-
}
|
package/lib/global-assert.js
DELETED
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
var _assert = _interopRequireWildcard(require("assert"));
|
|
4
|
-
|
|
5
|
-
var _tapYaml = require("tap-yaml");
|
|
6
|
-
|
|
7
|
-
var _stackUtils = _interopRequireWildcard(require("stack-utils"));
|
|
8
|
-
|
|
9
|
-
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj["default"] = obj; return newObj; } }
|
|
10
|
-
|
|
11
|
-
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }
|
|
12
|
-
|
|
13
|
-
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); }
|
|
14
|
-
|
|
15
|
-
function _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); }
|
|
16
|
-
|
|
17
|
-
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }
|
|
18
|
-
|
|
19
|
-
console.log("TAP version 13");
|
|
20
|
-
var tests = 0;
|
|
21
|
-
var passes = 0;
|
|
22
|
-
var failures = 0;
|
|
23
|
-
var stackUtils = new _stackUtils["default"]({
|
|
24
|
-
internals: [].concat(_toConsumableArray((0, _stackUtils.nodeInternals)()), [/\/readme-assert\/lib\//])
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
function printObject(obj) {
|
|
28
|
-
console.log(" ---");
|
|
29
|
-
console.log((0, _tapYaml.stringify)(obj, 4).replace(/^/gm, " "));
|
|
30
|
-
console.log(" ...");
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function test(message, fn) {
|
|
34
|
-
var _arguments = arguments;
|
|
35
|
-
return function () {
|
|
36
|
-
var args = Array.prototype.slice.call(_arguments);
|
|
37
|
-
tests++;
|
|
38
|
-
|
|
39
|
-
try {
|
|
40
|
-
fn.apply(_assert["default"], [args]);
|
|
41
|
-
console.log("ok ".concat(tests, " ").concat(message || ""));
|
|
42
|
-
passes++;
|
|
43
|
-
} catch (err) {
|
|
44
|
-
console.log("not ok ".concat(tests, " ").concat(message || ""));
|
|
45
|
-
failures++;
|
|
46
|
-
|
|
47
|
-
if ("actual" in err && "expected" in err && "operator" in err) {
|
|
48
|
-
printObject({
|
|
49
|
-
operator: err.operator,
|
|
50
|
-
actual: err.actual,
|
|
51
|
-
expected: err.expected,
|
|
52
|
-
stack: stackUtils.clean(err.stack).split("\n").slice(1).join("\n")
|
|
53
|
-
});
|
|
54
|
-
} else {
|
|
55
|
-
printObject(err);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}();
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
var assert = function assert(value, message) {
|
|
62
|
-
return test(message, function () {
|
|
63
|
-
return (0, _assert["default"])(value, message);
|
|
64
|
-
});
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
assert.deepEqual = function (actual, expected, message) {
|
|
68
|
-
test(message, function () {
|
|
69
|
-
return (0, _assert.deepEqual)(actual, expected, message);
|
|
70
|
-
});
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
assert.deepStrictEqual = function (actual, expected, message) {
|
|
74
|
-
test(message, function () {
|
|
75
|
-
return (0, _assert.deepStrictEqual)(actual, expected, message);
|
|
76
|
-
});
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
assert.doesNotThrow = function (block, error, message) {
|
|
80
|
-
test(message, function () {
|
|
81
|
-
return (0, _assert.doesNotThrow)(block, error, message);
|
|
82
|
-
});
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
assert.equal = function (actual, expected, message) {
|
|
86
|
-
test(message, function () {
|
|
87
|
-
return (0, _assert.equal)(actual, expected, message);
|
|
88
|
-
});
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
assert.fail = function (actual, expected, message, operator) {
|
|
92
|
-
test(message, function () {
|
|
93
|
-
return (0, _assert.fail)(actual, expected, message, operator);
|
|
94
|
-
});
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
assert.ifError = function (value) {
|
|
98
|
-
test("", function () {
|
|
99
|
-
return (0, _assert.ifError)(value);
|
|
100
|
-
});
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
assert.notDeepEqual = function (actual, expected, message) {
|
|
104
|
-
test(message, function () {
|
|
105
|
-
return (0, _assert.notDeepEqual)(actual, expected, message);
|
|
106
|
-
});
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
assert.notDeepStrictEqual = function (actual, expected, message) {
|
|
110
|
-
test(message, function () {
|
|
111
|
-
return (0, _assert.notDeepStrictEqual)(actual, expected, message);
|
|
112
|
-
});
|
|
113
|
-
};
|
|
114
|
-
|
|
115
|
-
assert.ok = function (value, message) {
|
|
116
|
-
test(message, function () {
|
|
117
|
-
return (0, _assert.ok)(value, message);
|
|
118
|
-
});
|
|
119
|
-
};
|
|
120
|
-
|
|
121
|
-
assert["throws"] = function (block, error, message) {
|
|
122
|
-
test(message, function () {
|
|
123
|
-
return (0, _assert["throws"])(block, error, message);
|
|
124
|
-
});
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
process.on("uncaughtException", function (err) {
|
|
128
|
-
console.log("Bail out! Uncaught exception ".concat(err.name));
|
|
129
|
-
printObject(err);
|
|
130
|
-
process.exit(1);
|
|
131
|
-
});
|
|
132
|
-
process.on("exit", function (code) {
|
|
133
|
-
if (code === 0) {
|
|
134
|
-
console.log("1..".concat(tests));
|
|
135
|
-
console.log("# tests ".concat(tests));
|
|
136
|
-
console.log("# pass ".concat(passes));
|
|
137
|
-
console.log("# fail ".concat(failures));
|
|
138
|
-
|
|
139
|
-
if (failures > 0) {
|
|
140
|
-
process.reallyExit(1);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
});
|
|
144
|
-
global.assert = assert;
|
package/lib/index.js
DELETED
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports["default"] = run;
|
|
7
|
-
|
|
8
|
-
var babel = _interopRequireWildcard(require("@babel/core"));
|
|
9
|
-
|
|
10
|
-
var _pluginTransformTypescript = _interopRequireDefault(require("@babel/plugin-transform-typescript"));
|
|
11
|
-
|
|
12
|
-
var _presetEnv = _interopRequireDefault(require("@babel/preset-env"));
|
|
13
|
-
|
|
14
|
-
var _babelPluginTransformCommentToAssert = _interopRequireDefault(require("babel-plugin-transform-comment-to-assert"));
|
|
15
|
-
|
|
16
|
-
var _babelPluginTransformRenameImport = _interopRequireDefault(require("babel-plugin-transform-rename-import"));
|
|
17
|
-
|
|
18
|
-
var _sourceMapSupport = _interopRequireDefault(require("source-map-support"));
|
|
19
|
-
|
|
20
|
-
var _fs = _interopRequireDefault(require("fs"));
|
|
21
|
-
|
|
22
|
-
var _path = _interopRequireDefault(require("path"));
|
|
23
|
-
|
|
24
|
-
var _pkgUp = _interopRequireDefault(require("pkg-up"));
|
|
25
|
-
|
|
26
|
-
var _extract2 = _interopRequireDefault(require("./extract"));
|
|
27
|
-
|
|
28
|
-
var _runInThisContext = require("./runInThisContext");
|
|
29
|
-
|
|
30
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
|
31
|
-
|
|
32
|
-
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj["default"] = obj; return newObj; } }
|
|
33
|
-
|
|
34
|
-
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }
|
|
35
|
-
|
|
36
|
-
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); }
|
|
37
|
-
|
|
38
|
-
function _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); }
|
|
39
|
-
|
|
40
|
-
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }
|
|
41
|
-
|
|
42
|
-
function run(main, req, shouldPrintCode, babelrc, filePath, auto, all) {
|
|
43
|
-
var sourceMaps = !shouldPrintCode;
|
|
44
|
-
var sourceMapsFile = shouldPrintCode ? _path["default"].join(_path["default"].dirname(filePath), "readme.md.js") : filePath;
|
|
45
|
-
req.forEach(function (f) {
|
|
46
|
-
require(require.resolve(f, {
|
|
47
|
-
paths: [process.cwd()]
|
|
48
|
-
}));
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
var mdDirname = _path["default"].dirname(filePath);
|
|
52
|
-
|
|
53
|
-
process.chdir(mdDirname);
|
|
54
|
-
var mdText = read(filePath);
|
|
55
|
-
|
|
56
|
-
var rootPkg = _pkgUp["default"].sync();
|
|
57
|
-
|
|
58
|
-
var pkg = JSON.parse(read(rootPkg));
|
|
59
|
-
|
|
60
|
-
var _extract = (0, _extract2["default"])(mdText, {
|
|
61
|
-
auto: auto,
|
|
62
|
-
all: all
|
|
63
|
-
}),
|
|
64
|
-
code = _extract.code,
|
|
65
|
-
hasTypescript = _extract.hasTypescript;
|
|
66
|
-
|
|
67
|
-
var transformed = babel.transform(code, {
|
|
68
|
-
babelrc: babelrc,
|
|
69
|
-
sourceMaps: sourceMaps,
|
|
70
|
-
plugins: [].concat(_toConsumableArray(hasTypescript ? [_pluginTransformTypescript["default"]] : []), [_babelPluginTransformCommentToAssert["default"], rootPkg ? [_babelPluginTransformRenameImport["default"], {
|
|
71
|
-
replacement: main || process.cwd(),
|
|
72
|
-
original: pkg.name
|
|
73
|
-
}] : undefined]),
|
|
74
|
-
presets: [_presetEnv["default"]],
|
|
75
|
-
filename: sourceMapsFile
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
if (sourceMaps) {
|
|
79
|
-
_sourceMapSupport["default"].install({
|
|
80
|
-
retrieveSourceMap: function retrieveSourceMap(request) {
|
|
81
|
-
if (request === filePath) {
|
|
82
|
-
return {
|
|
83
|
-
url: sourceMapsFile,
|
|
84
|
-
map: transformed.map
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
return null;
|
|
89
|
-
}
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
if (shouldPrintCode) {
|
|
94
|
-
printCode(transformed.code, sourceMapsFile);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
require("./global-assert");
|
|
98
|
-
|
|
99
|
-
(0, _runInThisContext.runInThisContext)(transformed.code, sourceMapsFile);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
function read(file) {
|
|
103
|
-
return _fs["default"].readFileSync(_path["default"].join(file), "utf-8");
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
function printCode(code, sourceMapsFile) {
|
|
107
|
-
console.log("\n# ", sourceMapsFile);
|
|
108
|
-
code.split("\n").forEach(function (l, i) {
|
|
109
|
-
return console.log("# ".concat(String(i + 1).padEnd(3, " "), " ").concat(l));
|
|
110
|
-
});
|
|
111
|
-
}
|