@t09tanaka/test-gates 0.5.0 → 0.5.1
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/CHANGELOG.md +6 -0
- package/dist/cli.js +65 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.5.1
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- `selfcheck --jobs` no longer keeps every other control apart because the word `require` appears inside a string, a template, a comment or a regular expression (`'sslmode=require'`, `// pass it to require`). Only code is looked at now. Handing `require` on under another name (`const r = require`) still counts as loading a module whose name is computed.
|
|
8
|
+
|
|
3
9
|
## 0.5.0
|
|
4
10
|
|
|
5
11
|
This release makes the gates quicker to check in CI: `test-gates mutation --shard <index>/<total>` splits the mutation run over parallel jobs, and `selfcheck --jobs` runs more controls side by side. Nothing changes for a run without the new option:
|
package/dist/cli.js
CHANGED
|
@@ -5458,6 +5458,70 @@ function withoutStrings(source) {
|
|
|
5458
5458
|
)
|
|
5459
5459
|
);
|
|
5460
5460
|
}
|
|
5461
|
+
var BEFORE_REGEX = /(?:^|[(,=:[!&|?{};+\-*%<>~^]|\b(?:return|typeof|case|in|of|void|delete|throw|new|yield|await))\s*$/;
|
|
5462
|
+
var COMMENT_OR_STRING = /\/\/[^\n]*|\/\*[\s\S]*?(?:\*\/|$)|(['"])(?:\\.|(?!\1)[^\\\n])*\1?/y;
|
|
5463
|
+
var REGEX = /\/(?:\\.|\[(?:\\.|[^\]\\\n])*\]?|[^/\\\n[])*\/?/y;
|
|
5464
|
+
var TEMPLATE_TEXT = /(?:\\[\s\S]|[^`\\$]|\$(?!\{))*/y;
|
|
5465
|
+
function withoutLiterals(source) {
|
|
5466
|
+
let out = "";
|
|
5467
|
+
let i = 0;
|
|
5468
|
+
const blank = (text) => text.replace(/[^\n]/g, " ");
|
|
5469
|
+
const enclosed = (literal) => {
|
|
5470
|
+
const closed = literal.length > 1 && literal.endsWith(literal.charAt(0));
|
|
5471
|
+
return literal.charAt(0) + blank(literal.slice(1, closed ? -1 : void 0)) + (closed ? literal.charAt(0) : "");
|
|
5472
|
+
};
|
|
5473
|
+
const take = (pattern) => {
|
|
5474
|
+
pattern.lastIndex = i;
|
|
5475
|
+
const found = pattern.exec(source)?.[0] ?? null;
|
|
5476
|
+
if (found !== null) {
|
|
5477
|
+
i += found.length;
|
|
5478
|
+
}
|
|
5479
|
+
return found;
|
|
5480
|
+
};
|
|
5481
|
+
const code = (inBraces) => {
|
|
5482
|
+
while (i < source.length) {
|
|
5483
|
+
const c = source[i];
|
|
5484
|
+
const literal = take(COMMENT_OR_STRING);
|
|
5485
|
+
if (literal !== null) {
|
|
5486
|
+
out += literal.startsWith("/") ? blank(literal) : enclosed(literal);
|
|
5487
|
+
} else if (c === "/" && BEFORE_REGEX.test(out)) {
|
|
5488
|
+
out += enclosed(take(REGEX));
|
|
5489
|
+
} else if (c === "`") {
|
|
5490
|
+
i += 1;
|
|
5491
|
+
out += "`";
|
|
5492
|
+
template();
|
|
5493
|
+
} else if (c === "}" && inBraces) {
|
|
5494
|
+
return;
|
|
5495
|
+
} else if (c === "{" && inBraces) {
|
|
5496
|
+
braces("{");
|
|
5497
|
+
} else {
|
|
5498
|
+
out += c;
|
|
5499
|
+
i += 1;
|
|
5500
|
+
}
|
|
5501
|
+
}
|
|
5502
|
+
};
|
|
5503
|
+
const braces = (open) => {
|
|
5504
|
+
i += open.length;
|
|
5505
|
+
out += open;
|
|
5506
|
+
code(true);
|
|
5507
|
+
if (i < source.length) {
|
|
5508
|
+
i += 1;
|
|
5509
|
+
out += "}";
|
|
5510
|
+
}
|
|
5511
|
+
};
|
|
5512
|
+
const template = () => {
|
|
5513
|
+
out += blank(take(TEMPLATE_TEXT));
|
|
5514
|
+
if (source.startsWith("${", i)) {
|
|
5515
|
+
braces("${");
|
|
5516
|
+
template();
|
|
5517
|
+
} else if (i < source.length) {
|
|
5518
|
+
i += 1;
|
|
5519
|
+
out += "`";
|
|
5520
|
+
}
|
|
5521
|
+
};
|
|
5522
|
+
code(false);
|
|
5523
|
+
return out;
|
|
5524
|
+
}
|
|
5461
5525
|
var PURE_BUILTINS = [
|
|
5462
5526
|
"assert",
|
|
5463
5527
|
"assert/strict",
|
|
@@ -5473,7 +5537,7 @@ var PURE_BUILTINS = [
|
|
|
5473
5537
|
];
|
|
5474
5538
|
var RUNNER_PACKAGES = ["vitest", "@jest/globals"];
|
|
5475
5539
|
function reachesOutside(file, trusted) {
|
|
5476
|
-
const dense = file.source.replace(/\s/g, "");
|
|
5540
|
+
const dense = withoutLiterals(file.source).replace(/\s/g, "");
|
|
5477
5541
|
const code = withoutStrings(file.source).replace(/\s/g, "");
|
|
5478
5542
|
const mark = REACHES.find((text) => code.includes(text));
|
|
5479
5543
|
if (mark !== void 0) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@t09tanaka/test-gates",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "Test gates for the code that must not be wrong: per-file 100% coverage as the floor, mutation testing with a per-mutant allow list as the real check.",
|
|
5
5
|
"author": "t09tanaka",
|
|
6
6
|
"license": "MIT",
|