@devasign/verify 1.3.1 → 1.3.2

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.
Files changed (2) hide show
  1. package/dist/cli.js +81 -7
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -5717,7 +5717,7 @@ import { appendFileSync as appendFileSync2, existsSync as existsSync5, writeFile
5717
5717
  import path7 from "node:path";
5718
5718
 
5719
5719
  // src/types.ts
5720
- var CLI_VERSION = "1.3.1";
5720
+ var CLI_VERSION = "1.3.2";
5721
5721
 
5722
5722
  // src/api.ts
5723
5723
  var ApiError = class extends Error {
@@ -5894,20 +5894,94 @@ import path4 from "node:path";
5894
5894
 
5895
5895
  // src/classify.ts
5896
5896
  var ASSERTION = {
5897
- "node-test": /^not ok\b|AssertionError|# fail [1-9]/m,
5898
- bundled: /^not ok\b|AssertionError|# fail [1-9]/m,
5899
- vitest: /AssertionError|Tests\s+\d+ failed|\bFAIL\b.*\.[jt]sx?|✖|×|expected .* to /m,
5900
- jest: /Tests:\s+\d+ failed|✕|expect\(|toBe|toEqual|toHaveBeenCalled/m,
5897
+ "node-test": /AssertionError|ERR_ASSERTION/,
5898
+ bundled: /AssertionError|ERR_ASSERTION/,
5899
+ vitest: /^AssertionError\b/m,
5900
+ jest: /^\s+(?:expect|assert)[.(]|AssertionError/m,
5901
5901
  pytest: /^FAILED\b|\b\d+ failed\b|AssertionError|assert /m,
5902
5902
  go: /^--- FAIL\b|^FAIL\b/m,
5903
5903
  playwright: /expect\(|Timed out .* expect|toBeVisible|toHaveText|toContainText|toHaveURL|toBeChecked|toHaveValue|toHaveCount|Expected:|Received:/m
5904
- }, INFRA = /Cannot find module|Cannot find package|Failed to load url|Failed to resolve import|ERR_MODULE_NOT_FOUND|MODULE_NOT_FOUND|ERR_PACKAGE_PATH_NOT_EXPORTED|SyntaxError|ImportError|ModuleNotFoundError|command not found|ENOENT|no test files|no tests found|No tests found|collected 0 items|\[build failed\]|Executable doesn't exist|browserType\.launch|net::ERR_|ECONNREFUSED|Process from config\.webServer|Timed out waiting .* from config\.webServer/i;
5904
+ }, INFRA = /Cannot find module|Cannot find package|Failed to load url|Failed to resolve import|ERR_MODULE_NOT_FOUND|MODULE_NOT_FOUND|ERR_PACKAGE_PATH_NOT_EXPORTED|SyntaxError|ImportError|ModuleNotFoundError|command not found|ENOENT|no test files|no tests found|No tests found|collected 0 items|\[build failed\]|Executable doesn't exist|browserType\.launch|net::ERR_|ECONNREFUSED|Process from config\.webServer|Timed out waiting .* from config\.webServer/i, FRAME_SKIP = /node_modules\/|^node:/, shortPath = (p) => p.replace(/^file:\/\//, "").replace(/^.*?\/(?=\.devasign\/)/, "");
5905
+ function firstFrame(lines, from, frame, stop) {
5906
+ for (let k = from; k < lines.length && !stop.test(lines[k]); k++) {
5907
+ let p = frame.exec(lines[k])?.[1];
5908
+ if (p && !FRAME_SKIP.test(p)) return shortPath(p);
5909
+ }
5910
+ }
5911
+ var VITEST_FAIL = /^ FAIL {2}\S/, VITEST_HEADER = new RegExp(`${VITEST_FAIL.source}|\u23AF (?:Uncaught Exception|Unhandled Rejection|Unhandled Error) \u23AF`), VITEST_FRAME = /^\s*❯ (?:\S+ )?(\S+:\d+:\d+)$/, VITEST_ASSERTION = /^(?:AssertionError\b|Error: expected (?:number of assertions|any number of assertion)|Error: Snapshot .* mismatched)/;
5912
+ function vitestFailures(lines) {
5913
+ let out = [];
5914
+ for (let i = 0; i < lines.length; i++) {
5915
+ if (!VITEST_HEADER.test(lines[i])) continue;
5916
+ let j = i + 1;
5917
+ for (; j < lines.length && (VITEST_FAIL.test(lines[j]) || !lines[j].trim()); ) j++;
5918
+ let message = (lines[j] ?? "").trim();
5919
+ !message || message.startsWith("\u23AF") || (out.push({ message, assertion: VITEST_ASSERTION.test(message), frame: firstFrame(lines, j + 1, VITEST_FRAME, /^(?:⎯| FAIL {2})/) }), i = j);
5920
+ }
5921
+ return out;
5922
+ }
5923
+ var JEST_TITLE = /^\s*● /, JEST_HINT = /wrong test environment|Consider using the "jsdom" test environment/, JEST_FRAME = /^\s+at (?:.*? \()?([^()\s]+:\d+:\d+)\)?$/, JEST_ASSERTION = /^(?:expect|assert)[.(]|^(?:Jest)?AssertionError\b/;
5924
+ function jestFailures(lines) {
5925
+ let out = [];
5926
+ for (let i = 0; i < lines.length; i++) {
5927
+ if (!JEST_TITLE.test(lines[i])) continue;
5928
+ let j = i + 1;
5929
+ for (; j < lines.length && (!lines[j].trim() || JEST_HINT.test(lines[j])); ) j++;
5930
+ let message = (lines[j] ?? "").trim();
5931
+ !message || JEST_TITLE.test(lines[j]) || out.push({ message, assertion: JEST_ASSERTION.test(message), frame: firstFrame(lines, j + 1, JEST_FRAME, JEST_TITLE) });
5932
+ }
5933
+ return out;
5934
+ }
5935
+ var TAP_NOT_OK = /^\s*not ok \d+ - /, TAP_END = /^\s*(?:\.\.\.$|#|(?:not )?ok \d+ )/, TAP_FRAME = /\(?((?:file:\/\/)?[^()\s]+:\d+:\d+)\)?$/;
5936
+ function tapFailures(lines) {
5937
+ let out = [];
5938
+ for (let i = 0; i < lines.length; i++) {
5939
+ if (!TAP_NOT_OK.test(lines[i])) continue;
5940
+ let block = [];
5941
+ for (let k = i + 1; k < lines.length && !TAP_END.test(lines[k]); k++) block.push(lines[k]);
5942
+ let yaml = block.join(`
5943
+ `);
5944
+ if (/failureType: 'subtestsFailed'/.test(yaml)) continue;
5945
+ let name = /^\s*name: '([^']+)'/m.exec(yaml)?.[1], error = tapError(block), stack = block.findIndex((l) => /^\s*stack: /.test(l));
5946
+ out.push({
5947
+ message: name && !error.startsWith(name) ? `${name}: ${error}` : error,
5948
+ assertion: /code: 'ERR_ASSERTION'|\bAssertionError\b/.test(yaml),
5949
+ frame: stack < 0 ? void 0 : firstFrame(block, stack + 1, TAP_FRAME, /^\s*\w+: /)
5950
+ });
5951
+ }
5952
+ return out;
5953
+ }
5954
+ function tapError(block) {
5955
+ let at = block.findIndex((l) => /^\s*error: /.test(l));
5956
+ if (at < 0) return block.find((l) => l.trim() && l.trim() !== "---")?.trim() ?? "test failed";
5957
+ let inline = /^\s*error: (?:'(.*)'|"(.*)"|([^|>].*))$/.exec(block[at]);
5958
+ if (inline) return (inline[1]?.replace(/''/g, "'") ?? inline[2] ?? inline[3]).trim();
5959
+ let indent = /^\s*/.exec(block[at])[0].length, body = [];
5960
+ for (let k = at + 1; k < block.length && (!block[k].trim() || /^\s*/.exec(block[k])[0].length > indent); k++)
5961
+ block[k].trim() && body.push(block[k].trim());
5962
+ return body.join(" ");
5963
+ }
5964
+ var PARSERS = {
5965
+ vitest: vitestFailures,
5966
+ jest: jestFailures,
5967
+ "node-test": tapFailures,
5968
+ bundled: tapFailures
5969
+ };
5905
5970
  function classifyAttempt(runner, r) {
5906
- if (r = { ...r, output: (r.output || "").replace(/\u001b\[[0-9;]*m/g, "") }, r.spawnError) return { status: "error", error: `could not start test runner: ${r.spawnError}` };
5971
+ if (r = { ...r, output: (r.output || "").replace(/\u001b\[[0-9;]*m/g, "").replace(/\r\n/g, `
5972
+ `) }, r.spawnError) return { status: "error", error: `could not start test runner: ${r.spawnError}` };
5907
5973
  if (r.timedOut) return { status: "error", error: "test run timed out" };
5908
5974
  let out = r.output || "";
5909
5975
  if (r.code === 0)
5910
5976
  return (runner === "node-test" || runner === "bundled") && /^# tests 0\b/m.test(out) ? { status: "error", error: "no tests ran" } : { status: "pass" };
5977
+ let failures = PARSERS[runner]?.(out.split(`
5978
+ `)) ?? [];
5979
+ if (failures.length) {
5980
+ let asserted = failures.find((f) => f.assertion);
5981
+ if (asserted) return { status: "fail", error: asserted.message.slice(0, 500) };
5982
+ let [crash] = failures;
5983
+ return { status: "error", error: `${crash.message}${crash.frame ? ` (at ${crash.frame})` : ""}`.slice(0, 500) };
5984
+ }
5911
5985
  let assertion = ASSERTION[runner] ?? ASSERTION["node-test"], infra = INFRA.test(out);
5912
5986
  return assertion.test(out) && !(infra && !/^not ok|AssertionError|FAILED|--- FAIL/m.test(out)) ? { status: "fail", error: firstFailureLine(out) } : { status: "error", error: firstErrorLine(out) || `exit code ${r.code}` };
5913
5987
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devasign/verify",
3
- "version": "1.3.1",
3
+ "version": "1.3.2",
4
4
  "description": "Runs DevAsign's generated acceptance tests inside your CI and reports per-criterion evidence.",
5
5
  "license": "GPL-3.0-or-later",
6
6
  "type": "module",