@descryy/runtime-test-runner 0.4.12 → 0.4.13

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 (278) hide show
  1. package/dist/bounded-file.d.ts +18 -0
  2. package/dist/bounded-file.d.ts.map +1 -0
  3. package/dist/bounded-file.js +77 -0
  4. package/dist/bounded-file.js.map +1 -0
  5. package/dist/child-environment.d.ts +12 -0
  6. package/dist/child-environment.d.ts.map +1 -0
  7. package/dist/child-environment.js +124 -0
  8. package/dist/child-environment.js.map +1 -0
  9. package/dist/coverage-capture.d.ts +23 -0
  10. package/dist/coverage-capture.d.ts.map +1 -0
  11. package/dist/coverage-capture.js +165 -0
  12. package/dist/coverage-capture.js.map +1 -0
  13. package/dist/executed-coverage.d.ts +45 -0
  14. package/dist/executed-coverage.d.ts.map +1 -0
  15. package/dist/executed-coverage.js +143 -0
  16. package/dist/executed-coverage.js.map +1 -0
  17. package/dist/go-cover-profile.d.ts +29 -0
  18. package/dist/go-cover-profile.d.ts.map +1 -0
  19. package/dist/go-cover-profile.js +162 -0
  20. package/dist/go-cover-profile.js.map +1 -0
  21. package/dist/go-test.d.ts +29 -2
  22. package/dist/go-test.d.ts.map +1 -1
  23. package/dist/go-test.js +149 -30
  24. package/dist/go-test.js.map +1 -1
  25. package/dist/graph-mapping.d.ts +1 -0
  26. package/dist/graph-mapping.d.ts.map +1 -1
  27. package/dist/graph-mapping.js +78 -1
  28. package/dist/graph-mapping.js.map +1 -1
  29. package/dist/index.d.ts +21 -3
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +11 -1
  32. package/dist/index.js.map +1 -1
  33. package/dist/lexers/c-family.d.ts +4 -0
  34. package/dist/lexers/c-family.d.ts.map +1 -0
  35. package/dist/lexers/c-family.js +221 -0
  36. package/dist/lexers/c-family.js.map +1 -0
  37. package/dist/lexers/chars.d.ts +7 -0
  38. package/dist/lexers/chars.d.ts.map +1 -0
  39. package/dist/lexers/chars.js +49 -0
  40. package/dist/lexers/chars.js.map +1 -0
  41. package/dist/lexers/index.d.ts +7 -0
  42. package/dist/lexers/index.d.ts.map +1 -0
  43. package/dist/lexers/index.js +5 -0
  44. package/dist/lexers/index.js.map +1 -0
  45. package/dist/lexers/python.d.ts +3 -0
  46. package/dist/lexers/python.d.ts.map +1 -0
  47. package/dist/lexers/python.js +101 -0
  48. package/dist/lexers/python.js.map +1 -0
  49. package/dist/quality/annotations.d.ts +14 -0
  50. package/dist/quality/annotations.d.ts.map +1 -0
  51. package/dist/quality/annotations.js +147 -0
  52. package/dist/quality/annotations.js.map +1 -0
  53. package/dist/quality/assertion-kinds.d.ts +18 -0
  54. package/dist/quality/assertion-kinds.d.ts.map +1 -0
  55. package/dist/quality/assertion-kinds.js +25 -0
  56. package/dist/quality/assertion-kinds.js.map +1 -0
  57. package/dist/quality/chains.d.ts +25 -0
  58. package/dist/quality/chains.d.ts.map +1 -0
  59. package/dist/quality/chains.js +129 -0
  60. package/dist/quality/chains.js.map +1 -0
  61. package/dist/quality/common.d.ts +31 -0
  62. package/dist/quality/common.d.ts.map +1 -0
  63. package/dist/quality/common.js +211 -0
  64. package/dist/quality/common.js.map +1 -0
  65. package/dist/quality/csharp-family.d.ts +9 -0
  66. package/dist/quality/csharp-family.d.ts.map +1 -0
  67. package/dist/quality/csharp-family.js +560 -0
  68. package/dist/quality/csharp-family.js.map +1 -0
  69. package/dist/quality/detect.d.ts +3 -0
  70. package/dist/quality/detect.d.ts.map +1 -0
  71. package/dist/quality/detect.js +348 -0
  72. package/dist/quality/detect.js.map +1 -0
  73. package/dist/quality/durations.d.ts +4 -0
  74. package/dist/quality/durations.d.ts.map +1 -0
  75. package/dist/quality/durations.js +177 -0
  76. package/dist/quality/durations.js.map +1 -0
  77. package/dist/quality/expressions.d.ts +7 -0
  78. package/dist/quality/expressions.d.ts.map +1 -0
  79. package/dist/quality/expressions.js +123 -0
  80. package/dist/quality/expressions.js.map +1 -0
  81. package/dist/quality/facts.d.ts +5 -0
  82. package/dist/quality/facts.d.ts.map +1 -0
  83. package/dist/quality/facts.js +183 -0
  84. package/dist/quality/facts.js.map +1 -0
  85. package/dist/quality/failure-of.d.ts +4 -0
  86. package/dist/quality/failure-of.d.ts.map +1 -0
  87. package/dist/quality/failure-of.js +233 -0
  88. package/dist/quality/failure-of.js.map +1 -0
  89. package/dist/quality/frameworks.d.ts +5 -0
  90. package/dist/quality/frameworks.d.ts.map +1 -0
  91. package/dist/quality/frameworks.js +20 -0
  92. package/dist/quality/frameworks.js.map +1 -0
  93. package/dist/quality/go-family.d.ts +6 -0
  94. package/dist/quality/go-family.d.ts.map +1 -0
  95. package/dist/quality/go-family.js +393 -0
  96. package/dist/quality/go-family.js.map +1 -0
  97. package/dist/quality/index.d.ts +10 -0
  98. package/dist/quality/index.d.ts.map +1 -0
  99. package/dist/quality/index.js +19 -0
  100. package/dist/quality/index.js.map +1 -0
  101. package/dist/quality/java-family.d.ts +12 -0
  102. package/dist/quality/java-family.d.ts.map +1 -0
  103. package/dist/quality/java-family.js +529 -0
  104. package/dist/quality/java-family.js.map +1 -0
  105. package/dist/quality/js-assertions.d.ts +11 -0
  106. package/dist/quality/js-assertions.d.ts.map +1 -0
  107. package/dist/quality/js-assertions.js +297 -0
  108. package/dist/quality/js-assertions.js.map +1 -0
  109. package/dist/quality/js-family.d.ts +3 -0
  110. package/dist/quality/js-family.d.ts.map +1 -0
  111. package/dist/quality/js-family.js +470 -0
  112. package/dist/quality/js-family.js.map +1 -0
  113. package/dist/quality/python-family.d.ts +6 -0
  114. package/dist/quality/python-family.d.ts.map +1 -0
  115. package/dist/quality/python-family.js +786 -0
  116. package/dist/quality/python-family.js.map +1 -0
  117. package/dist/quality/scope.d.ts +26 -0
  118. package/dist/quality/scope.d.ts.map +1 -0
  119. package/dist/quality/scope.js +33 -0
  120. package/dist/quality/scope.js.map +1 -0
  121. package/dist/quality/selectors.d.ts +14 -0
  122. package/dist/quality/selectors.d.ts.map +1 -0
  123. package/dist/quality/selectors.js +137 -0
  124. package/dist/quality/selectors.js.map +1 -0
  125. package/dist/quality/statuses.d.ts +7 -0
  126. package/dist/quality/statuses.d.ts.map +1 -0
  127. package/dist/quality/statuses.js +143 -0
  128. package/dist/quality/statuses.js.map +1 -0
  129. package/dist/quality/stream.d.ts +23 -0
  130. package/dist/quality/stream.d.ts.map +1 -0
  131. package/dist/quality/stream.js +194 -0
  132. package/dist/quality/stream.js.map +1 -0
  133. package/dist/quality/types.d.ts +88 -0
  134. package/dist/quality/types.d.ts.map +1 -0
  135. package/dist/quality/types.js +2 -0
  136. package/dist/quality/types.js.map +1 -0
  137. package/dist/run-timeout.d.ts +25 -0
  138. package/dist/run-timeout.d.ts.map +1 -0
  139. package/dist/run-timeout.js +52 -0
  140. package/dist/run-timeout.js.map +1 -0
  141. package/dist/runner-wrappers.d.ts +74 -0
  142. package/dist/runner-wrappers.d.ts.map +1 -0
  143. package/dist/runner-wrappers.js +604 -0
  144. package/dist/runner-wrappers.js.map +1 -0
  145. package/dist/swift-xctest.d.ts +15 -2
  146. package/dist/swift-xctest.d.ts.map +1 -1
  147. package/dist/swift-xctest.js +143 -20
  148. package/dist/swift-xctest.js.map +1 -1
  149. package/dist/test-runner-collector.d.ts +56 -6
  150. package/dist/test-runner-collector.d.ts.map +1 -1
  151. package/dist/test-runner-collector.js +265 -113
  152. package/dist/test-runner-collector.js.map +1 -1
  153. package/dist/testgen/csharp-facts.d.ts +3 -0
  154. package/dist/testgen/csharp-facts.d.ts.map +1 -0
  155. package/dist/testgen/csharp-facts.js +306 -0
  156. package/dist/testgen/csharp-facts.js.map +1 -0
  157. package/dist/testgen/csharp-profile.d.ts +14 -0
  158. package/dist/testgen/csharp-profile.d.ts.map +1 -0
  159. package/dist/testgen/csharp-profile.js +233 -0
  160. package/dist/testgen/csharp-profile.js.map +1 -0
  161. package/dist/testgen/declarations.d.ts +10 -0
  162. package/dist/testgen/declarations.d.ts.map +1 -0
  163. package/dist/testgen/declarations.js +110 -0
  164. package/dist/testgen/declarations.js.map +1 -0
  165. package/dist/testgen/facts-common.d.ts +33 -0
  166. package/dist/testgen/facts-common.d.ts.map +1 -0
  167. package/dist/testgen/facts-common.js +76 -0
  168. package/dist/testgen/facts-common.js.map +1 -0
  169. package/dist/testgen/failure.d.ts +4 -0
  170. package/dist/testgen/failure.d.ts.map +1 -0
  171. package/dist/testgen/failure.js +106 -0
  172. package/dist/testgen/failure.js.map +1 -0
  173. package/dist/testgen/frameworks.d.ts +6 -0
  174. package/dist/testgen/frameworks.d.ts.map +1 -0
  175. package/dist/testgen/frameworks.js +516 -0
  176. package/dist/testgen/frameworks.js.map +1 -0
  177. package/dist/testgen/go-facts.d.ts +11 -0
  178. package/dist/testgen/go-facts.d.ts.map +1 -0
  179. package/dist/testgen/go-facts.js +237 -0
  180. package/dist/testgen/go-facts.js.map +1 -0
  181. package/dist/testgen/go-profile.d.ts +6 -0
  182. package/dist/testgen/go-profile.d.ts.map +1 -0
  183. package/dist/testgen/go-profile.js +155 -0
  184. package/dist/testgen/go-profile.js.map +1 -0
  185. package/dist/testgen/index.d.ts +28 -0
  186. package/dist/testgen/index.d.ts.map +1 -0
  187. package/dist/testgen/index.js +21 -0
  188. package/dist/testgen/index.js.map +1 -0
  189. package/dist/testgen/java-build.d.ts +13 -0
  190. package/dist/testgen/java-build.d.ts.map +1 -0
  191. package/dist/testgen/java-build.js +250 -0
  192. package/dist/testgen/java-build.js.map +1 -0
  193. package/dist/testgen/java-facts.d.ts +3 -0
  194. package/dist/testgen/java-facts.d.ts.map +1 -0
  195. package/dist/testgen/java-facts.js +349 -0
  196. package/dist/testgen/java-facts.js.map +1 -0
  197. package/dist/testgen/java-profile.d.ts +13 -0
  198. package/dist/testgen/java-profile.d.ts.map +1 -0
  199. package/dist/testgen/java-profile.js +194 -0
  200. package/dist/testgen/java-profile.js.map +1 -0
  201. package/dist/testgen/languages.d.ts +11 -0
  202. package/dist/testgen/languages.d.ts.map +1 -0
  203. package/dist/testgen/languages.js +63 -0
  204. package/dist/testgen/languages.js.map +1 -0
  205. package/dist/testgen/lexer.d.ts +19 -0
  206. package/dist/testgen/lexer.d.ts.map +1 -0
  207. package/dist/testgen/lexer.js +257 -0
  208. package/dist/testgen/lexer.js.map +1 -0
  209. package/dist/testgen/mutant-core.d.ts +19 -0
  210. package/dist/testgen/mutant-core.d.ts.map +1 -0
  211. package/dist/testgen/mutant-core.js +39 -0
  212. package/dist/testgen/mutant-core.js.map +1 -0
  213. package/dist/testgen/mutants-lang.d.ts +6 -0
  214. package/dist/testgen/mutants-lang.d.ts.map +1 -0
  215. package/dist/testgen/mutants-lang.js +291 -0
  216. package/dist/testgen/mutants-lang.js.map +1 -0
  217. package/dist/testgen/mutants.d.ts +9 -0
  218. package/dist/testgen/mutants.d.ts.map +1 -0
  219. package/dist/testgen/mutants.js +148 -0
  220. package/dist/testgen/mutants.js.map +1 -0
  221. package/dist/testgen/paths.d.ts +32 -0
  222. package/dist/testgen/paths.d.ts.map +1 -0
  223. package/dist/testgen/paths.js +211 -0
  224. package/dist/testgen/paths.js.map +1 -0
  225. package/dist/testgen/process.d.ts +19 -0
  226. package/dist/testgen/process.d.ts.map +1 -0
  227. package/dist/testgen/process.js +89 -0
  228. package/dist/testgen/process.js.map +1 -0
  229. package/dist/testgen/profile-failure.d.ts +7 -0
  230. package/dist/testgen/profile-failure.d.ts.map +1 -0
  231. package/dist/testgen/profile-failure.js +29 -0
  232. package/dist/testgen/profile-failure.js.map +1 -0
  233. package/dist/testgen/python-facts.d.ts +11 -0
  234. package/dist/testgen/python-facts.d.ts.map +1 -0
  235. package/dist/testgen/python-facts.js +380 -0
  236. package/dist/testgen/python-facts.js.map +1 -0
  237. package/dist/testgen/python-profile.d.ts +4 -0
  238. package/dist/testgen/python-profile.d.ts.map +1 -0
  239. package/dist/testgen/python-profile.js +344 -0
  240. package/dist/testgen/python-profile.js.map +1 -0
  241. package/dist/testgen/source-facts.d.ts +30 -0
  242. package/dist/testgen/source-facts.d.ts.map +1 -0
  243. package/dist/testgen/source-facts.js +497 -0
  244. package/dist/testgen/source-facts.js.map +1 -0
  245. package/dist/testgen/stubs.d.ts +4 -0
  246. package/dist/testgen/stubs.d.ts.map +1 -0
  247. package/dist/testgen/stubs.js +66 -0
  248. package/dist/testgen/stubs.js.map +1 -0
  249. package/dist/testgen/toolchain.d.ts +23 -0
  250. package/dist/testgen/toolchain.d.ts.map +1 -0
  251. package/dist/testgen/toolchain.js +201 -0
  252. package/dist/testgen/toolchain.js.map +1 -0
  253. package/dist/testgen/types.d.ts +67 -0
  254. package/dist/testgen/types.d.ts.map +1 -0
  255. package/dist/testgen/types.js +2 -0
  256. package/dist/testgen/types.js.map +1 -0
  257. package/dist/v8-coverage.d.ts +21 -0
  258. package/dist/v8-coverage.d.ts.map +1 -0
  259. package/dist/v8-coverage.js +217 -0
  260. package/dist/v8-coverage.js.map +1 -0
  261. package/dist/vitest-reporter.d.ts +46 -13
  262. package/dist/vitest-reporter.d.ts.map +1 -1
  263. package/dist/vitest-reporter.js +119 -26
  264. package/dist/vitest-reporter.js.map +1 -1
  265. package/dist/vitest-version.d.ts +21 -0
  266. package/dist/vitest-version.d.ts.map +1 -0
  267. package/dist/vitest-version.js +98 -0
  268. package/dist/vitest-version.js.map +1 -0
  269. package/package.json +14 -8
  270. package/reporters/junit/classes/DescryJUnitListener.class +0 -0
  271. package/reporters/junit/classes/META-INF/services/org.junit.platform.launcher.TestExecutionListener +1 -0
  272. package/reporters/minitest/descry_minitest_reporter.rb +150 -0
  273. package/reporters/phpunit/DescryPhpUnitExtension.php +209 -0
  274. package/reporters/pytest/descry_pytest_plugin.py +397 -0
  275. package/reporters/rspec/descry_rspec_formatter.rb +175 -0
  276. package/reporters/xunit/bin/Release/netstandard2.0/Descry.TestLogger.deps.json +203 -0
  277. package/reporters/xunit/bin/Release/netstandard2.0/Descry.TestLogger.dll +0 -0
  278. package/reporters/xunit/bin/Release/netstandard2.0/Descry.TestLogger.pdb +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"vitest-reporter.d.ts","sourceRoot":"","sources":["../src/vitest-reporter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,UAAU,WAAW;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;CAC/B;AAED,UAAU,cAAc;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE;QAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACjD,QAAQ,CAAC,QAAQ,CAAC,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;IACnF,mLAAmL;IACnL,MAAM,IAAI;QAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,OAAO,EAAE,CAAA;KAAE,GAAG,SAAS,CAAC;IACxF,UAAU,IAAI;QAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;CAC1D;AAsBD,MAAM,CAAC,OAAO,OAAO,oBAAoB;IACvC,eAAe,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI;IAU/C,gBAAgB,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI;CA4BjD"}
1
+ {"version":3,"file":"vitest-reporter.d.ts","sourceRoot":"","sources":["../src/vitest-reporter.ts"],"names":[],"mappings":"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"}
@@ -12,13 +12,8 @@
12
12
  * with the graph's separator -- splitting on `" > "` was rejected since a title
13
13
  * containing `" > "` is legal and would split wrong.
14
14
  *
15
- * `--includeTaskLocation` is load-bearing and its absence is silent: without it
16
- * `testCase.location` is `undefined` on every result, no error, just missing
17
- * line/column (same shape as Jest's `--testLocationInResults`, RT-073).
18
- * `withReporterFlags` injects it rather than leaving it to the caller.
19
- *
20
- * `state: "skipped"` covers both `.skip` and `.todo` (measured) -- Jest tells
21
- * them apart. Neither is a pass.
15
+ * `state: "skipped"` covers both `.skip` and `.todo` (measured) on the modern
16
+ * API -- Jest tells them apart. Neither is a pass.
22
17
  */
23
18
  function write(type, data) {
24
19
  process.stdout.write(JSON.stringify({ type, data }) + "\n");
@@ -32,48 +27,146 @@ function qualifiedNameOf(testCase) {
32
27
  let ancestor = testCase.parent;
33
28
  // top-level test's parent is the module, not a suite -- ends the walk here
34
29
  while (ancestor !== undefined && ancestor.type === "suite") {
35
- chain.unshift(ancestor.name);
30
+ chain.unshift(ancestor.name ?? "");
36
31
  ancestor = ancestor.parent;
37
32
  }
38
33
  return [...chain, testCase.name].join(" ");
39
34
  }
35
+ function legacyQualifiedNameOf(task) {
36
+ const chain = [];
37
+ let ancestor = task.suite;
38
+ while (ancestor !== undefined && ancestor.filepath === undefined) {
39
+ if (ancestor.name !== "")
40
+ chain.unshift(ancestor.name);
41
+ ancestor = ancestor.suite;
42
+ }
43
+ return [...chain, task.name].join(" ");
44
+ }
45
+ function majorOf(version) {
46
+ if (typeof version !== "string")
47
+ return null;
48
+ const match = /^(\d+)\./.exec(version);
49
+ return match === null ? null : Number(match[1]);
50
+ }
51
+ function legacyOutcome(task) {
52
+ if (task.mode === "skip" || task.mode === "todo")
53
+ return "skipped";
54
+ const state = task.result?.state;
55
+ if (state === "pass")
56
+ return "passed";
57
+ if (state === "fail")
58
+ return "failed";
59
+ if (state === "skip" || state === "todo")
60
+ return "skipped";
61
+ return null;
62
+ }
40
63
  export default class DescryVitestReporter {
41
- onTestCaseReady(testCase) {
64
+ started = new Set();
65
+ settled = new Set();
66
+ legacyContext = null;
67
+ liveLegacy = false;
68
+ emitStart(test) {
69
+ if (this.started.has(test.key) || this.started.has(test.fallbackKey))
70
+ return;
71
+ this.started.add(test.key);
72
+ this.started.add(test.fallbackKey);
42
73
  write("test:start", {
43
- name: testCase.name,
44
- qualifiedName: qualifiedNameOf(testCase),
45
- file: testCase.module?.moduleId ?? null,
46
- line: testCase.location?.line ?? null,
47
- column: testCase.location?.column ?? null,
74
+ name: test.name,
75
+ qualifiedName: test.qualifiedName,
76
+ file: test.file,
77
+ line: test.location?.line ?? null,
78
+ column: test.location?.column ?? null,
48
79
  });
49
80
  }
50
- onTestCaseResult(testCase) {
51
- const result = testCase.result();
52
- const state = result?.state;
53
- write(state === "failed" ? "test:fail" : "test:pass", {
54
- name: testCase.name,
55
- qualifiedName: qualifiedNameOf(testCase),
56
- file: testCase.module?.moduleId ?? null,
57
- line: testCase.location?.line ?? null,
58
- column: testCase.location?.column ?? null,
81
+ emitResult(test, outcome, durationMs, errors) {
82
+ if (this.settled.has(test.key) || this.settled.has(test.fallbackKey))
83
+ return;
84
+ this.settled.add(test.key);
85
+ this.settled.add(test.fallbackKey);
86
+ write(outcome === "failed" ? "test:fail" : "test:pass", {
87
+ name: test.name,
88
+ qualifiedName: test.qualifiedName,
89
+ file: test.file,
90
+ line: test.location?.line ?? null,
91
+ column: test.location?.column ?? null,
59
92
  // .skip and .todo both arrive as "skipped" (measured); translator turns them
60
93
  // into TEST_SKIPPED (RT-124).
61
- skip: state === "skipped",
94
+ skip: outcome === "skipped",
62
95
  todo: false,
63
96
  // "unspecified" is a real answer, not a fallback: Vitest doesn't distinguish
64
97
  // .skip from .todo, so "disabled" here would be a guess (RT-129).
65
98
  skipReason: "unspecified",
66
99
  details: {
67
- duration_ms: testCase.diagnostic()?.duration ?? null,
100
+ duration_ms: durationMs,
68
101
  // passed through verbatim, not copied field-by-field: by the time a reporter
69
102
  // sees them, Vitest's errors have crossed its worker RPC and are plain objects
70
103
  // (not Error instances), carrying actual/expected/operator/diff alongside
71
104
  // message/name/stack -- a field-by-field copy silently drops the assertion
72
105
  // diff, the most useful part of a failure. Safe because of that measurement;
73
106
  // a runner handing over live Error instances would need the copy.
74
- error: state === "failed" ? { failureType: "test", errors: result?.errors ?? [] } : null,
107
+ error: outcome === "failed" ? { failureType: "test", errors: errors ?? [] } : null,
75
108
  },
76
109
  });
77
110
  }
111
+ observed(testCase) {
112
+ const file = testCase.module?.moduleId ?? null;
113
+ const qualifiedName = qualifiedNameOf(testCase);
114
+ const fallbackKey = `name:${file ?? ""}\u0000${qualifiedName}`;
115
+ return { key: testCase.id === undefined ? fallbackKey : `id:${testCase.id}`, fallbackKey, name: testCase.name, qualifiedName, file, location: testCase.location };
116
+ }
117
+ observedLegacy(task) {
118
+ const file = task.file?.filepath ?? null;
119
+ const qualifiedName = legacyQualifiedNameOf(task);
120
+ return { key: `id:${task.id}`, fallbackKey: `name:${file ?? ""}\u0000${qualifiedName}`, name: task.name, qualifiedName, file, location: task.location };
121
+ }
122
+ reportLegacy(task) {
123
+ const outcome = legacyOutcome(task);
124
+ if (outcome === null)
125
+ return;
126
+ const test = this.observedLegacy(task);
127
+ this.emitStart(test);
128
+ this.emitResult(test, outcome, task.result?.duration ?? null, task.result?.errors);
129
+ }
130
+ onInit(context) {
131
+ this.legacyContext = context;
132
+ const major = majorOf(context.version);
133
+ this.liveLegacy = (major === null || major < 3) && typeof context.state?.idMap?.get === "function";
134
+ }
135
+ onTestCaseReady(testCase) {
136
+ this.emitStart(this.observed(testCase));
137
+ }
138
+ onTestCaseResult(testCase) {
139
+ const result = testCase.result();
140
+ const state = result?.state;
141
+ const outcome = state === "failed" ? "failed" : state === "skipped" ? "skipped" : "passed";
142
+ const test = this.observed(testCase);
143
+ this.emitStart(test);
144
+ this.emitResult(test, outcome, testCase.diagnostic()?.duration ?? null, result?.errors);
145
+ }
146
+ onTaskUpdate(packs) {
147
+ if (!this.liveLegacy)
148
+ return;
149
+ const idMap = this.legacyContext?.state?.idMap;
150
+ if (idMap === undefined)
151
+ return;
152
+ for (const pack of packs) {
153
+ const id = pack[0];
154
+ if (typeof id !== "string")
155
+ continue;
156
+ const task = idMap.get(id);
157
+ if (task !== undefined && task.type === "test")
158
+ this.reportLegacy(task);
159
+ }
160
+ }
161
+ onFinished(files) {
162
+ const visit = (task) => {
163
+ if (task.type === "test")
164
+ this.reportLegacy(task);
165
+ for (const child of task.tasks ?? [])
166
+ visit(child);
167
+ };
168
+ for (const file of files ?? [])
169
+ visit(file);
170
+ }
78
171
  }
79
172
  //# sourceMappingURL=vitest-reporter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"vitest-reporter.js","sourceRoot":"","sources":["../src/vitest-reporter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAkBH,SAAS,KAAK,CAAC,IAAY,EAAE,IAAa;IACxC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;AAC9D,CAAC;AAED,mFAAmF;AACnF,wDAAwD;AACxD,KAAK,CAAC,iBAAiB,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;AAEzC,kJAAkJ;AAClJ,SAAS,eAAe,CAAC,QAAwB;IAC/C,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC;IAC/B,2EAA2E;IAC3E,OAAO,QAAQ,KAAK,SAAS,IAAI,QAAQ,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC3D,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC7B,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC;IAC7B,CAAC;IACD,OAAO,CAAC,GAAG,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,CAAC,OAAO,OAAO,oBAAoB;IACvC,eAAe,CAAC,QAAwB;QACtC,KAAK,CAAC,YAAY,EAAE;YAClB,IAAI,EAAE,QAAQ,CAAC,IAAI;YACnB,aAAa,EAAE,eAAe,CAAC,QAAQ,CAAC;YACxC,IAAI,EAAE,QAAQ,CAAC,MAAM,EAAE,QAAQ,IAAI,IAAI;YACvC,IAAI,EAAE,QAAQ,CAAC,QAAQ,EAAE,IAAI,IAAI,IAAI;YACrC,MAAM,EAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,IAAI;SAC1C,CAAC,CAAC;IACL,CAAC;IAED,gBAAgB,CAAC,QAAwB;QACvC,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC;QACjC,MAAM,KAAK,GAAG,MAAM,EAAE,KAAK,CAAC;QAC5B,KAAK,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,EAAE;YACpD,IAAI,EAAE,QAAQ,CAAC,IAAI;YACnB,aAAa,EAAE,eAAe,CAAC,QAAQ,CAAC;YACxC,IAAI,EAAE,QAAQ,CAAC,MAAM,EAAE,QAAQ,IAAI,IAAI;YACvC,IAAI,EAAE,QAAQ,CAAC,QAAQ,EAAE,IAAI,IAAI,IAAI;YACrC,MAAM,EAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,IAAI;YACzC,6EAA6E;YAC7E,8BAA8B;YAC9B,IAAI,EAAE,KAAK,KAAK,SAAS;YACzB,IAAI,EAAE,KAAK;YACX,6EAA6E;YAC7E,kEAAkE;YAClE,UAAU,EAAE,aAAsB;YAClC,OAAO,EAAE;gBACP,WAAW,EAAE,QAAQ,CAAC,UAAU,EAAE,EAAE,QAAQ,IAAI,IAAI;gBACpD,6EAA6E;gBAC7E,+EAA+E;gBAC/E,0EAA0E;gBAC1E,2EAA2E;gBAC3E,6EAA6E;gBAC7E,kEAAkE;gBAClE,KAAK,EAAE,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI;aACzF;SACF,CAAC,CAAC;IACL,CAAC;CACF"}
1
+ {"version":3,"file":"vitest-reporter.js","sourceRoot":"","sources":["../src/vitest-reporter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ export type VitestDetection = {
2
+ readonly ok: true;
3
+ readonly version: string;
4
+ readonly major: number;
5
+ readonly packageJsonPath: string;
6
+ } | {
7
+ readonly ok: false;
8
+ readonly reason: string;
9
+ };
10
+ export interface VitestRunPlan {
11
+ readonly detection: VitestDetection;
12
+ readonly taskLocationFlag: boolean;
13
+ readonly degradation: string | null;
14
+ }
15
+ export declare function detectInstalledVitest(cwd: string): VitestDetection;
16
+ export declare function vitestLocationDegradations(plan: VitestRunPlan | null, tally: {
17
+ readonly results: number;
18
+ readonly withoutLocation: number;
19
+ }): readonly string[];
20
+ export declare function planVitestRun(cwd: string): VitestRunPlan;
21
+ //# sourceMappingURL=vitest-version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vitest-version.d.ts","sourceRoot":"","sources":["../src/vitest-version.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,eAAe,GACvB;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAA;CAAE,GACzG;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpD,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAC;IACpC,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;IACnC,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC;AA8BD,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,CAelE;AAED,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI,EAAE,KAAK,EAAE;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,MAAM,EAAE,CAW/J;AAID,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,CA4BxD"}
@@ -0,0 +1,98 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { dirname, join, resolve } from "node:path";
3
+ const TASK_LOCATION_FLAG_MAJORS = new Set([3, 4]);
4
+ const REJECTING_MAJORS = new Set([1, 2]);
5
+ const MAX_ANCESTORS = 64;
6
+ function readInstalledPackage(packageJsonPath) {
7
+ let text;
8
+ try {
9
+ text = readFileSync(packageJsonPath, "utf8");
10
+ }
11
+ catch (error) {
12
+ const code = error.code;
13
+ if (code === "ENOENT" || code === "ENOTDIR")
14
+ return { kind: "absent" };
15
+ return { kind: "unusable", reason: `${packageJsonPath} could not be read (${code ?? String(error)})` };
16
+ }
17
+ let parsed;
18
+ try {
19
+ parsed = JSON.parse(text);
20
+ }
21
+ catch {
22
+ return { kind: "unusable", reason: `${packageJsonPath} could not be parsed as JSON` };
23
+ }
24
+ if (typeof parsed !== "object" || parsed === null)
25
+ return { kind: "unusable", reason: `${packageJsonPath} is not a package manifest` };
26
+ const manifest = parsed;
27
+ if (manifest.name !== "vitest")
28
+ return { kind: "unusable", reason: `${packageJsonPath} is not Vitest's manifest (its name is ${JSON.stringify(manifest.name ?? null)})` };
29
+ if (typeof manifest.version !== "string")
30
+ return { kind: "unusable", reason: `${packageJsonPath} declares no version` };
31
+ const match = /^(\d+)\.(\d+)\.(\d+)/.exec(manifest.version);
32
+ if (match === null)
33
+ return { kind: "unusable", reason: `${packageJsonPath} declares ${JSON.stringify(manifest.version)}, which is not a version` };
34
+ return { kind: "found", version: manifest.version, major: Number(match[1]) };
35
+ }
36
+ export function detectInstalledVitest(cwd) {
37
+ let directory = resolve(cwd);
38
+ for (let depth = 0; depth < MAX_ANCESTORS; depth++) {
39
+ const packageJsonPath = join(directory, "node_modules", "vitest", "package.json");
40
+ const read = readInstalledPackage(packageJsonPath);
41
+ if (read.kind === "found")
42
+ return { ok: true, version: read.version, major: read.major, packageJsonPath };
43
+ if (read.kind === "unusable")
44
+ return { ok: false, reason: read.reason };
45
+ const parent = dirname(directory);
46
+ if (parent === directory)
47
+ break;
48
+ directory = parent;
49
+ }
50
+ return {
51
+ ok: false,
52
+ reason: `no Vitest installation was found in node_modules at or above ${resolve(cwd)} (a Yarn Plug'n'Play install keeps no node_modules and cannot be read this way)`,
53
+ };
54
+ }
55
+ export function vitestLocationDegradations(plan, tally) {
56
+ if (plan === null)
57
+ return [];
58
+ const { results, withoutLocation } = tally;
59
+ if (results > 0 && withoutLocation === 0)
60
+ return [];
61
+ if (plan.taskLocationFlag) {
62
+ return withoutLocation === 0
63
+ ? []
64
+ : [`${withoutLocation} of ${results} Vitest results carried no line or column although --includeTaskLocation was passed, so those results are attributed to their file and test name only.`];
65
+ }
66
+ if (plan.degradation === null)
67
+ return [];
68
+ return [results > 0 ? `${plan.degradation} Measured: ${withoutLocation} of ${results} results carried no line.` : plan.degradation];
69
+ }
70
+ const LOSS = "Per-test line and column are unavailable for this run: results are still attributed to their file and test name, but not to a line.";
71
+ export function planVitestRun(cwd) {
72
+ const detection = detectInstalledVitest(cwd);
73
+ if (!detection.ok) {
74
+ return {
75
+ detection,
76
+ taskLocationFlag: false,
77
+ degradation: `Which Vitest will run could not be determined: ${detection.reason}. ` +
78
+ `Descry therefore passed only its reporter and not --includeTaskLocation, which some versions reject outright. ${LOSS}`,
79
+ };
80
+ }
81
+ if (TASK_LOCATION_FLAG_MAJORS.has(detection.major))
82
+ return { detection, taskLocationFlag: true, degradation: null };
83
+ if (REJECTING_MAJORS.has(detection.major)) {
84
+ return {
85
+ detection,
86
+ taskLocationFlag: false,
87
+ degradation: `Vitest ${detection.version} was detected, and that major rejects --includeTaskLocation on the command line (measured on 1.6.1 and 2.1.9), ` +
88
+ `so Descry did not pass it. ${LOSS} A project can enable test.includeTaskLocation in its own Vitest config to restore lines.`,
89
+ };
90
+ }
91
+ return {
92
+ detection,
93
+ taskLocationFlag: false,
94
+ degradation: `Vitest ${detection.version} is a major Descry has not been measured against, so whether it accepts --includeTaskLocation is unverified; ` +
95
+ `Descry passed only its reporter. ${LOSS}`,
96
+ };
97
+ }
98
+ //# sourceMappingURL=vitest-version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vitest-version.js","sourceRoot":"","sources":["../src/vitest-version.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@descryy/runtime-test-runner",
3
- "version": "0.4.12",
3
+ "version": "0.4.13",
4
4
  "type": "module",
5
5
  "description": "Test-runner observation (plan §17): discovery, start, TEST_STARTED/PASSED/FAILED, trace capture, source mapping, not-run disclosure. Three runners -- node:test, Jest, Vitest -- each observed through its own structured reporter API writing one shared envelope; no TAP or text scraping anywhere.",
6
6
  "license": "UNLICENSED",
@@ -19,21 +19,27 @@
19
19
  }
20
20
  },
21
21
  "files": [
22
- "dist"
22
+ "dist",
23
+ "reporters/pytest/*.py",
24
+ "reporters/rspec/*.rb",
25
+ "reporters/minitest/*.rb",
26
+ "reporters/phpunit/*.php",
27
+ "reporters/junit/classes",
28
+ "reporters/xunit/bin/Release/netstandard2.0"
23
29
  ],
24
30
  "publishConfig": {
25
31
  "registry": "https://registry.npmjs.org",
26
32
  "access": "public"
27
33
  },
28
34
  "dependencies": {
29
- "@descryy/runtime-contracts": "0.4.0",
30
- "@descryy/runtime-backend-observation": "0.3.7",
31
- "@descryy/runtime-controller": "0.4.0",
32
- "@descryy/runtime-graph-correlator": "0.5.1",
33
- "@descryy/core": "0.10.1"
35
+ "@descryy/runtime-contracts": "0.4.1",
36
+ "@descryy/runtime-backend-observation": "0.3.8",
37
+ "@descryy/runtime-controller": "0.4.1",
38
+ "@descryy/runtime-graph-correlator": "0.5.2",
39
+ "@descryy/core": "0.11.0"
34
40
  },
35
41
  "devDependencies": {
36
- "@descryy/ir": "0.11.0"
42
+ "@descryy/ir": "0.12.0"
37
43
  },
38
44
  "scripts": {
39
45
  "build": "tsc -b && node reporters/junit/build.mjs && node reporters/xunit/build.mjs"
@@ -0,0 +1,150 @@
1
+ # frozen_string_literal: true
2
+
3
+ # §17's Minitest reporter — an `AbstractReporter` subclass wired in through
4
+ # Minitest's own plugin hook, writing the same NDJSON envelope every other
5
+ # reporter in this package writes (RT-108's siblings: pytest, RSpec, PHPUnit).
6
+ #
7
+ # ## Why a plugin hook and not a flag
8
+ #
9
+ # Minitest ships no JUnit XML and no `--format` flag. Its only structured
10
+ # extension point is `Minitest::AbstractReporter`, added via
11
+ # `Minitest.plugin_<name>_init(options)` — the mechanism a `minitest/*_plugin.rb`
12
+ # gem uses, required directly here instead of packaged as one. Each test
13
+ # reports as it finishes, the same streaming shape as every other reporter in
14
+ # this package and for the same reason: a document written at the end
15
+ # produces nothing at all if the run is killed.
16
+ #
17
+ # ## Minitest has one not-run flavour, not RSpec's four or PHPUnit's two
18
+ #
19
+ # Core Minitest defines no "declared, never started" skip. `skip` is a method
20
+ # called from *inside* a test body (`Minitest::Assertions#skip`, raising
21
+ # `Minitest::Skip`), and `prerecord` fires for every test regardless of
22
+ # outcome — measured against minitest 5.25.4, a skipped test's `prerecord`
23
+ # callback fires exactly like a passing one's, with no earlier event to
24
+ # distinguish it by. There is no attribute-level skip in the gem itself
25
+ # (`Test::Unit`-alikes and Rails' own test helpers add one; this reporter is
26
+ # written against core Minitest, which is what `require "minitest/autorun"`
27
+ # alone gives you). So `skipReason` is always `"precondition-unmet"` — the
28
+ # runtime-skip case every other runner in this package also has — and never
29
+ # `"disabled"`, because the case that word names cannot happen through this
30
+ # API.
31
+ #
32
+ # ## Errored and Failed are different Ruby exception classes, not a flag
33
+ #
34
+ # `result.failure` returns `Minitest::Skip` (skip), `Minitest::UnexpectedError`
35
+ # (an exception the test body raised rather than chose) or any other
36
+ # `Minitest::Assertion` subclass (a failed assertion the test body chose).
37
+ # Told apart by class — the same principle PHPUnit's own runner is the only
38
+ # layer that knows `Errored` from `Failed` by, not by parsing the message
39
+ # text, which is the rule every reporter in this package follows.
40
+ #
41
+ # ## location is the test's own declared line, not the assertion's
42
+ #
43
+ # Resolved through `UnboundMethod#source_location` to the *method
44
+ # definition's* file:line, not the line an assertion failed on — the same
45
+ # coarseness RSpec's `metadata[:line_number]` and PHPUnit's `test.line()`
46
+ # already report at. The precise failure line, where the runner gives one,
47
+ # lives in `result.failure.message` verbatim and is not re-derived here,
48
+ # consistent with every other reporter leaving the failure text exactly as
49
+ # its runner wrote it.
50
+ #
51
+ # It has to be resolved at `prerecord`, not `record`, and snapshotted —
52
+ # **`prerecord`'s `klass` is the real `Class` object, `record`'s
53
+ # `result.klass` is that class's *name as a string*** (`Result#klass`'s own
54
+ # doc comment says "The class name", measured to mean literally that:
55
+ # `String#instance_method` does not exist). The same shape RSpec's
56
+ # `example_started` snapshot exists for, for a different reason — there it
57
+ # is metadata mutated by execution, here it is a type substituted between
58
+ # the two callbacks — and the same fix: read it while it is still real, key
59
+ # it, and look it up later rather than re-deriving from `record`.
60
+ #
61
+ # ## The envelope version
62
+ #
63
+ # Declared before the first event, as a number: `{"version":"1"}` is read as
64
+ # a broken reporter rather than a matching one. Keep in step with
65
+ # `ENVELOPE_VERSION` in `test-runner-collector.ts` — that file is the
66
+ # authority, not this comment.
67
+
68
+ require "json"
69
+ require "minitest"
70
+
71
+ class DescryMinitestReporter < Minitest::AbstractReporter
72
+ # Must equal ENVELOPE_VERSION in test-runner-collector.ts. A mismatch is refused there, loudly.
73
+ ENVELOPE_VERSION = 1
74
+
75
+ def initialize(*)
76
+ super
77
+ # (klass name, method name) -> declared [file, line], captured while
78
+ # `klass` is still a real `Class` — see the header.
79
+ @locations = {}
80
+ end
81
+
82
+ def start(*)
83
+ emit({ type: "descry:envelope", data: { version: ENVELOPE_VERSION } })
84
+ end
85
+
86
+ def prerecord(klass, name)
87
+ @locations[[klass.name, name]] = klass.instance_method(name).source_location
88
+ emit({ type: "test:start", data: common(klass.name, name) })
89
+ end
90
+
91
+ def record(result)
92
+ data = common(result.klass, result.name)
93
+ failure = result.failure
94
+
95
+ if failure.nil?
96
+ data[:details] = { duration_ms: result.time * 1000 }
97
+ emit({ type: "test:pass", data: data })
98
+ elsif failure.is_a?(Minitest::Skip)
99
+ data[:skip] = true
100
+ # Core Minitest has no declared-skip path through this API — see the
101
+ # header. Always the runtime flavour, and there is no other to confuse
102
+ # it with.
103
+ data[:skipReason] = "precondition-unmet"
104
+ data[:message] = failure.message
105
+ emit({ type: "test:pass", data: data })
106
+ else
107
+ error = { message: failure.message }
108
+ # `Minitest::UnexpectedError` wraps an exception the test body raised
109
+ # rather than an assertion it chose to fail; the two send a developer
110
+ # to different places, and only Minitest's own `result.failure` class
111
+ # says which happened.
112
+ error[:failureType] = "error" if failure.is_a?(Minitest::UnexpectedError)
113
+ data[:details] = { error: error }
114
+ emit({ type: "test:fail", data: data })
115
+ end
116
+ end
117
+
118
+ def report(*)
119
+ end
120
+
121
+ private
122
+
123
+ def common(klass_name, name)
124
+ location = @locations[[klass_name, name]]
125
+ {
126
+ name: name,
127
+ qualifiedName: "#{klass_name}##{name}",
128
+ file: location&.first,
129
+ line: location&.last
130
+ }
131
+ end
132
+
133
+ # **The leading newline is not cosmetic**, and the reason is measured on
134
+ # pytest rather than assumed here: a progress reporter writes its dots with
135
+ # no trailing newline, so a report emitted between two of them lands on the
136
+ # same line and stops being JSON. Minitest's default `ProgressReporter`
137
+ # writes `.`, `F`, `E`, `S` the same way, to the same stream.
138
+ def emit(object)
139
+ $stdout.print("\n#{JSON.generate(object)}\n")
140
+ $stdout.flush
141
+ end
142
+ end
143
+
144
+ module Minitest
145
+ def self.plugin_descry_init(options)
146
+ self.reporter << DescryMinitestReporter.new
147
+ end
148
+ end
149
+
150
+ Minitest.extensions << "descry"