@quenty/nevermore-cli 4.43.3 → 4.44.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.
Files changed (154) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/build-scripts/{combine-test-places.luau → combine-test-places.lua} +3 -3
  3. package/build-scripts/{transform-inject-deploy-metadata.luau → transform-inject-deploy-metadata.lua} +3 -3
  4. package/dist/commands/batch-command/batch-deploy-command.js +4 -4
  5. package/dist/commands/batch-command/batch-deploy-command.js.map +1 -1
  6. package/dist/commands/batch-command/batch-test-command.d.ts.map +1 -1
  7. package/dist/commands/batch-command/batch-test-command.js +76 -19
  8. package/dist/commands/batch-command/batch-test-command.js.map +1 -1
  9. package/dist/commands/deploy-command/deploy-init-utils.d.ts.map +1 -1
  10. package/dist/commands/deploy-command/deploy-init-utils.js +7 -1
  11. package/dist/commands/deploy-command/deploy-init-utils.js.map +1 -1
  12. package/dist/commands/deploy-command/index.js +1 -1
  13. package/dist/commands/deploy-command/index.js.map +1 -1
  14. package/dist/commands/init-command/init-game-command.js +2 -2
  15. package/dist/commands/init-command/init-game-command.js.map +1 -1
  16. package/dist/commands/install-package-command.d.ts +14 -0
  17. package/dist/commands/install-package-command.d.ts.map +1 -1
  18. package/dist/commands/install-package-command.js +65 -12
  19. package/dist/commands/install-package-command.js.map +1 -1
  20. package/dist/utils/deploy/deploy-github-columns.d.ts +12 -2
  21. package/dist/utils/deploy/deploy-github-columns.d.ts.map +1 -1
  22. package/dist/utils/deploy/deploy-github-columns.js +11 -4
  23. package/dist/utils/deploy/deploy-github-columns.js.map +1 -1
  24. package/dist/utils/deploy/deploy-metadata.js +1 -1
  25. package/dist/utils/deploy/deploy-metadata.js.map +1 -1
  26. package/dist/utils/job-context/base-job-context.d.ts +2 -2
  27. package/dist/utils/job-context/base-job-context.d.ts.map +1 -1
  28. package/dist/utils/job-context/base-job-context.js +1 -1
  29. package/dist/utils/job-context/base-job-context.js.map +1 -1
  30. package/dist/utils/job-context/batch-script-job-context.d.ts +37 -2
  31. package/dist/utils/job-context/batch-script-job-context.d.ts.map +1 -1
  32. package/dist/utils/job-context/batch-script-job-context.js +59 -22
  33. package/dist/utils/job-context/batch-script-job-context.js.map +1 -1
  34. package/dist/utils/job-context/cloud-job-context.d.ts +2 -2
  35. package/dist/utils/job-context/cloud-job-context.d.ts.map +1 -1
  36. package/dist/utils/job-context/cloud-job-context.js +10 -5
  37. package/dist/utils/job-context/cloud-job-context.js.map +1 -1
  38. package/dist/utils/job-context/cloud-job-context.test.d.ts +7 -0
  39. package/dist/utils/job-context/cloud-job-context.test.d.ts.map +1 -0
  40. package/dist/utils/job-context/cloud-job-context.test.js +91 -0
  41. package/dist/utils/job-context/cloud-job-context.test.js.map +1 -0
  42. package/dist/utils/job-context/job-context.d.ts +70 -2
  43. package/dist/utils/job-context/job-context.d.ts.map +1 -1
  44. package/dist/utils/job-context/local-job-context.d.ts +2 -2
  45. package/dist/utils/job-context/local-job-context.d.ts.map +1 -1
  46. package/dist/utils/job-context/local-job-context.js +4 -2
  47. package/dist/utils/job-context/local-job-context.js.map +1 -1
  48. package/dist/utils/job-context/local-job-context.test.d.ts +7 -0
  49. package/dist/utils/job-context/local-job-context.test.d.ts.map +1 -0
  50. package/dist/utils/job-context/local-job-context.test.js +68 -0
  51. package/dist/utils/job-context/local-job-context.test.js.map +1 -0
  52. package/dist/utils/open-cloud/open-cloud-client.d.ts +50 -7
  53. package/dist/utils/open-cloud/open-cloud-client.d.ts.map +1 -1
  54. package/dist/utils/open-cloud/open-cloud-client.js +49 -13
  55. package/dist/utils/open-cloud/open-cloud-client.js.map +1 -1
  56. package/dist/utils/open-cloud/open-cloud-client.test.js +125 -1
  57. package/dist/utils/open-cloud/open-cloud-client.test.js.map +1 -1
  58. package/dist/utils/open-cloud/open-cloud-logs.characterization.test.d.ts +22 -0
  59. package/dist/utils/open-cloud/open-cloud-logs.characterization.test.d.ts.map +1 -0
  60. package/dist/utils/open-cloud/open-cloud-logs.characterization.test.js +202 -0
  61. package/dist/utils/open-cloud/open-cloud-logs.characterization.test.js.map +1 -0
  62. package/dist/utils/package-manager-utils.d.ts +29 -0
  63. package/dist/utils/package-manager-utils.d.ts.map +1 -0
  64. package/dist/utils/package-manager-utils.js +120 -0
  65. package/dist/utils/package-manager-utils.js.map +1 -0
  66. package/dist/utils/package-manager-utils.test.d.ts +2 -0
  67. package/dist/utils/package-manager-utils.test.d.ts.map +1 -0
  68. package/dist/utils/package-manager-utils.test.js +121 -0
  69. package/dist/utils/package-manager-utils.test.js.map +1 -0
  70. package/dist/utils/testing/batch-run.e2e.test.d.ts +17 -0
  71. package/dist/utils/testing/batch-run.e2e.test.d.ts.map +1 -0
  72. package/dist/utils/testing/batch-run.e2e.test.js +343 -0
  73. package/dist/utils/testing/batch-run.e2e.test.js.map +1 -0
  74. package/dist/utils/testing/batch-test-runner-template.test.d.ts +11 -0
  75. package/dist/utils/testing/batch-test-runner-template.test.d.ts.map +1 -0
  76. package/dist/utils/testing/batch-test-runner-template.test.js +38 -0
  77. package/dist/utils/testing/batch-test-runner-template.test.js.map +1 -0
  78. package/dist/utils/testing/log-fetch-stats.d.ts +40 -0
  79. package/dist/utils/testing/log-fetch-stats.d.ts.map +1 -0
  80. package/dist/utils/testing/log-fetch-stats.js +18 -0
  81. package/dist/utils/testing/log-fetch-stats.js.map +1 -0
  82. package/dist/utils/testing/log-fetch-stats.test.d.ts +2 -0
  83. package/dist/utils/testing/log-fetch-stats.test.d.ts.map +1 -0
  84. package/dist/utils/testing/log-fetch-stats.test.js +41 -0
  85. package/dist/utils/testing/log-fetch-stats.test.js.map +1 -0
  86. package/dist/utils/testing/parsers/batch-log-parser.d.ts +126 -1
  87. package/dist/utils/testing/parsers/batch-log-parser.d.ts.map +1 -1
  88. package/dist/utils/testing/parsers/batch-log-parser.js +440 -103
  89. package/dist/utils/testing/parsers/batch-log-parser.js.map +1 -1
  90. package/dist/utils/testing/parsers/batch-log-parser.test.js +494 -1
  91. package/dist/utils/testing/parsers/batch-log-parser.test.js.map +1 -1
  92. package/dist/utils/testing/parsers/batch-log-renderer.d.ts +79 -0
  93. package/dist/utils/testing/parsers/batch-log-renderer.d.ts.map +1 -0
  94. package/dist/utils/testing/parsers/batch-log-renderer.js +241 -0
  95. package/dist/utils/testing/parsers/batch-log-renderer.js.map +1 -0
  96. package/dist/utils/testing/parsers/batch-log-renderer.test.d.ts +2 -0
  97. package/dist/utils/testing/parsers/batch-log-renderer.test.d.ts.map +1 -0
  98. package/dist/utils/testing/parsers/batch-log-renderer.test.js +202 -0
  99. package/dist/utils/testing/parsers/batch-log-renderer.test.js.map +1 -0
  100. package/dist/utils/testing/runner/combined-project-generator.js +1 -1
  101. package/dist/utils/testing/runner/combined-project-generator.js.map +1 -1
  102. package/dist/utils/testing/runner/test-runner.d.ts +24 -0
  103. package/dist/utils/testing/runner/test-runner.d.ts.map +1 -1
  104. package/dist/utils/testing/runner/test-runner.js +166 -6
  105. package/dist/utils/testing/runner/test-runner.js.map +1 -1
  106. package/dist/utils/testing/runner/test-runner.test.js +228 -2
  107. package/dist/utils/testing/runner/test-runner.test.js.map +1 -1
  108. package/dist/utils/testing/structured-test-results.d.ts +77 -0
  109. package/dist/utils/testing/structured-test-results.d.ts.map +1 -0
  110. package/dist/utils/testing/structured-test-results.js +140 -0
  111. package/dist/utils/testing/structured-test-results.js.map +1 -0
  112. package/dist/utils/testing/structured-test-results.test.d.ts +7 -0
  113. package/dist/utils/testing/structured-test-results.test.d.ts.map +1 -0
  114. package/dist/utils/testing/structured-test-results.test.js +179 -0
  115. package/dist/utils/testing/structured-test-results.test.js.map +1 -0
  116. package/package.json +6 -6
  117. package/src/commands/batch-command/batch-deploy-command.ts +4 -4
  118. package/src/commands/batch-command/batch-test-command.ts +94 -19
  119. package/src/commands/deploy-command/deploy-init-utils.ts +7 -1
  120. package/src/commands/deploy-command/index.ts +1 -1
  121. package/src/commands/init-command/init-game-command.ts +2 -2
  122. package/src/commands/install-package-command.ts +107 -14
  123. package/src/utils/deploy/deploy-github-columns.ts +14 -4
  124. package/src/utils/deploy/deploy-metadata.ts +1 -1
  125. package/src/utils/job-context/base-job-context.ts +3 -2
  126. package/src/utils/job-context/batch-script-job-context.ts +98 -17
  127. package/src/utils/job-context/cloud-job-context.test.ts +112 -0
  128. package/src/utils/job-context/cloud-job-context.ts +12 -6
  129. package/src/utils/job-context/job-context.ts +71 -2
  130. package/src/utils/job-context/local-job-context.test.ts +89 -0
  131. package/src/utils/job-context/local-job-context.ts +7 -3
  132. package/src/utils/open-cloud/open-cloud-client.test.ts +155 -1
  133. package/src/utils/open-cloud/open-cloud-client.ts +94 -18
  134. package/src/utils/open-cloud/open-cloud-logs.characterization.test.ts +277 -0
  135. package/src/utils/package-manager-utils.test.ts +174 -0
  136. package/src/utils/package-manager-utils.ts +148 -0
  137. package/src/utils/testing/batch-run.e2e.test.ts +425 -0
  138. package/src/utils/testing/batch-test-runner-template.test.ts +62 -0
  139. package/src/utils/testing/log-fetch-stats.test.ts +48 -0
  140. package/src/utils/testing/log-fetch-stats.ts +55 -0
  141. package/src/utils/testing/parsers/batch-log-parser.test.ts +660 -1
  142. package/src/utils/testing/parsers/batch-log-parser.ts +721 -116
  143. package/src/utils/testing/parsers/batch-log-renderer.test.ts +330 -0
  144. package/src/utils/testing/parsers/batch-log-renderer.ts +329 -0
  145. package/src/utils/testing/runner/combined-project-generator.ts +1 -1
  146. package/src/utils/testing/runner/test-runner.test.ts +332 -2
  147. package/src/utils/testing/runner/test-runner.ts +231 -9
  148. package/src/utils/testing/structured-test-results.test.ts +267 -0
  149. package/src/utils/testing/structured-test-results.ts +199 -0
  150. package/templates/batch-test-runner.lua +242 -0
  151. package/tsconfig.tsbuildinfo +1 -1
  152. package/templates/batch-test-runner.luau +0 -137
  153. /package/build-scripts/{smoke-test-server.luau → smoke-test-server.lua} +0 -0
  154. /package/build-scripts/{transform-rojo-merge-place.luau → transform-rojo-merge-place.lua} +0 -0
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Guards the two names the batch runner template spells out by hand.
3
+ *
4
+ * The template is raw Luau with no loader, so it cannot import anything: it
5
+ * recognizes a results table by a format string and finds the runner's state by
6
+ * a module name, both written as literals. Nothing else connects those literals
7
+ * to the Luau they describe — rename either side and the batch silently loses
8
+ * every package's counts, which looks exactly like a truncated log.
9
+ */
10
+ export {};
11
+ //# sourceMappingURL=batch-test-runner-template.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"batch-test-runner-template.test.d.ts","sourceRoot":"","sources":["../../../src/utils/testing/batch-test-runner-template.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Guards the two names the batch runner template spells out by hand.
3
+ *
4
+ * The template is raw Luau with no loader, so it cannot import anything: it
5
+ * recognizes a results table by a format string and finds the runner's state by
6
+ * a module name, both written as literals. Nothing else connects those literals
7
+ * to the Luau they describe — rename either side and the batch silently loses
8
+ * every package's counts, which looks exactly like a truncated log.
9
+ */
10
+ import { describe, it, expect } from 'vitest';
11
+ import * as fs from 'fs';
12
+ import * as path from 'path';
13
+ import { resolvePackagePath } from '@quenty/nevermore-template-helpers';
14
+ const TEMPLATE = fs.readFileSync(resolvePackagePath(import.meta.url, 'templates', 'batch-test-runner.lua'), 'utf-8');
15
+ /** The nevermore-test-runner package this template is written against. */
16
+ const RUNNER_DIR = path.resolve(resolvePackagePath(import.meta.url, '..', '..'), 'src', 'nevermore-test-runner', 'src', 'Server');
17
+ function literal(name) {
18
+ const match = new RegExp(`local ${name} = "([^"]+)"`).exec(TEMPLATE);
19
+ expect(match, `${name} is not declared in the template`).toBeTruthy();
20
+ return match[1];
21
+ }
22
+ describe('batch-test-runner.lua', () => {
23
+ it('names a state module that exists in the test runner package', () => {
24
+ const moduleName = literal('STATE_MODULE_NAME');
25
+ expect(fs.existsSync(path.join(RUNNER_DIR, 'NevermoreTestRunnerUtils', `${moduleName}.lua`))).toBe(true);
26
+ });
27
+ it('agrees with the test runner about the results format tag', () => {
28
+ const results = fs.readFileSync(path.join(RUNNER_DIR, 'NevermoreTestResults.lua'), 'utf-8');
29
+ expect(results).toContain(`local FORMAT = "${literal('RESULTS_FORMAT')}"`);
30
+ });
31
+ it('returns its summary as well as printing it', () => {
32
+ // The return value is the copy the engine's log buffer cannot truncate.
33
+ // Losing it would leave the printed summary as the only channel, which is
34
+ // the failure the whole path exists to survive.
35
+ expect(TEMPLATE.trimEnd().endsWith('return results')).toBe(true);
36
+ });
37
+ });
38
+ //# sourceMappingURL=batch-test-runner-template.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"batch-test-runner-template.test.js","sourceRoot":"","sources":["../../../src/utils/testing/batch-test-runner-template.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAExE,MAAM,QAAQ,GAAG,EAAE,CAAC,YAAY,CAC9B,kBAAkB,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,EAAE,uBAAuB,CAAC,EACzE,OAAO,CACR,CAAC;AAEF,0EAA0E;AAC1E,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAC7B,kBAAkB,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,EAC/C,KAAK,EACL,uBAAuB,EACvB,KAAK,EACL,QAAQ,CACT,CAAC;AAEF,SAAS,OAAO,CAAC,IAAY;IAC3B,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,SAAS,IAAI,cAAc,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACrE,MAAM,CAAC,KAAK,EAAE,GAAG,IAAI,kCAAkC,CAAC,CAAC,UAAU,EAAE,CAAC;IACtE,OAAO,KAAM,CAAC,CAAC,CAAC,CAAC;AACnB,CAAC;AAED,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;IACrC,EAAE,CAAC,6DAA6D,EAAE,GAAG,EAAE;QACrE,MAAM,UAAU,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;QAEhD,MAAM,CACJ,EAAE,CAAC,UAAU,CACX,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,0BAA0B,EAAE,GAAG,UAAU,MAAM,CAAC,CACvE,CACF,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACf,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;QAClE,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAC7B,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,0BAA0B,CAAC,EACjD,OAAO,CACR,CAAC;QAEF,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,mBAAmB,OAAO,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC;IAC7E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,wEAAwE;QACxE,0EAA0E;QAC1E,gDAAgD;QAChD,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * What it took to pull a run's logs, recorded so a parser that finds nothing in
3
+ * them can say where the shortfall happened.
4
+ *
5
+ * Output goes missing between a task and the parser at several caps that look
6
+ * identical from the parser's side — the engine drops messages past a session
7
+ * buffer it never reports, the API pages them, and a fetch can be retried. A
8
+ * count of chars alone cannot tell a run that printed little from one whose
9
+ * output the engine discarded, so the fetch reports its own shape too.
10
+ */
11
+ export interface LogFetchStats {
12
+ /**
13
+ * HTTP GETs issued to the logs endpoint for this fetch, retries included.
14
+ * Empty logs are retried, so this exceeds `pages` when the first tries came
15
+ * back with nothing.
16
+ */
17
+ requests: number;
18
+ /** Pages walked via `nextPageToken` on the attempt that produced the logs. */
19
+ pages: number;
20
+ /**
21
+ * `luauExecutionSessionTaskLog` objects across those pages. Each one carries
22
+ * many messages, so this stays far below the message count and is not a line
23
+ * count — the API's per-page limit applies to these, not to messages.
24
+ */
25
+ entries: number;
26
+ /** Engine messages inside those entries: one per `print`/`warn` that survived. */
27
+ messages: number;
28
+ /** Length of the joined log text handed to the parser. */
29
+ chars: number;
30
+ }
31
+ /**
32
+ * Describe how much log text arrived and what the fetch had to do to get it,
33
+ * for a diagnostic that has already decided something is missing.
34
+ *
35
+ * `stats` is absent for logs that did not come from Open Cloud — a local run
36
+ * reads them off the Studio bridge, where there is no request to count — so the
37
+ * volume that can always be measured is reported separately from the fetch.
38
+ */
39
+ export declare function describeLogVolume(rawLogs: string, stats: LogFetchStats | undefined): string;
40
+ //# sourceMappingURL=log-fetch-stats.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log-fetch-stats.d.ts","sourceRoot":"","sources":["../../../src/utils/testing/log-fetch-stats.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB,8EAA8E;IAC9E,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB,kFAAkF;IAClF,QAAQ,EAAE,MAAM,CAAC;IACjB,0DAA0D;IAC1D,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,aAAa,GAAG,SAAS,GAC/B,MAAM,CAYR"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Describe how much log text arrived and what the fetch had to do to get it,
3
+ * for a diagnostic that has already decided something is missing.
4
+ *
5
+ * `stats` is absent for logs that did not come from Open Cloud — a local run
6
+ * reads them off the Studio bridge, where there is no request to count — so the
7
+ * volume that can always be measured is reported separately from the fetch.
8
+ */
9
+ export function describeLogVolume(rawLogs, stats) {
10
+ const lines = rawLogs.length === 0 ? 0 : rawLogs.split('\n').length;
11
+ const volume = `${rawLogs.length} chars, ${lines} line(s) received`;
12
+ if (!stats) {
13
+ return `${volume}; no fetch stats (logs did not come from Open Cloud)`;
14
+ }
15
+ return (`${volume}; fetched in ${stats.requests} API call(s) over ${stats.pages} ` +
16
+ `page(s), ${stats.entries} log entry(ies), ${stats.messages} message(s)`);
17
+ }
18
+ //# sourceMappingURL=log-fetch-stats.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log-fetch-stats.js","sourceRoot":"","sources":["../../../src/utils/testing/log-fetch-stats.ts"],"names":[],"mappings":"AA+BA;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB,CAC/B,OAAe,EACf,KAAgC;IAEhC,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;IACpE,MAAM,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,WAAW,KAAK,mBAAmB,CAAC;IAEpE,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,GAAG,MAAM,sDAAsD,CAAC;IACzE,CAAC;IAED,OAAO,CACL,GAAG,MAAM,gBAAgB,KAAK,CAAC,QAAQ,qBAAqB,KAAK,CAAC,KAAK,GAAG;QAC1E,YAAY,KAAK,CAAC,OAAO,oBAAoB,KAAK,CAAC,QAAQ,aAAa,CACzE,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=log-fetch-stats.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log-fetch-stats.test.d.ts","sourceRoot":"","sources":["../../../src/utils/testing/log-fetch-stats.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,41 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { describeLogVolume } from './log-fetch-stats.js';
3
+ const STATS = {
4
+ requests: 1,
5
+ pages: 1,
6
+ entries: 1,
7
+ messages: 7627,
8
+ chars: 276989,
9
+ };
10
+ describe('describeLogVolume', () => {
11
+ it('reports lines and chars alongside the shape of the fetch', () => {
12
+ const description = describeLogVolume('a\nb\nc', STATS);
13
+ expect(description).toContain('5 chars, 3 line(s) received');
14
+ expect(description).toContain('1 API call(s)');
15
+ expect(description).toContain('1 page(s)');
16
+ expect(description).toContain('1 log entry(ies)');
17
+ expect(description).toContain('7627 message(s)');
18
+ });
19
+ it('separates entries from messages', () => {
20
+ // The two are orders of magnitude apart and only one of them is a line
21
+ // count. A reader that takes "1 entry" for "1 line" concludes the run
22
+ // printed nothing, when 7627 messages arrived inside that entry.
23
+ const description = describeLogVolume('', STATS);
24
+ expect(description).toContain('1 log entry(ies), 7627 message(s)');
25
+ });
26
+ it('counts no lines in empty logs', () => {
27
+ // Splitting '' yields one empty line, which would report a run that
28
+ // produced nothing as having produced a line.
29
+ expect(describeLogVolume('', STATS)).toContain('0 chars, 0 line(s)');
30
+ });
31
+ it('says the fetch is unmeasured rather than empty when it is unknown', () => {
32
+ // A local run reads its logs off the Studio bridge, where there is no
33
+ // request to count. Zeroes there would read as a fetch that returned
34
+ // nothing, which is a different fault entirely.
35
+ const description = describeLogVolume('a\nb', undefined);
36
+ expect(description).toContain('3 chars, 2 line(s) received');
37
+ expect(description).toContain('no fetch stats');
38
+ expect(description).not.toContain('0 API call(s)');
39
+ });
40
+ });
41
+ //# sourceMappingURL=log-fetch-stats.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log-fetch-stats.test.js","sourceRoot":"","sources":["../../../src/utils/testing/log-fetch-stats.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAsB,MAAM,sBAAsB,CAAC;AAE7E,MAAM,KAAK,GAAkB;IAC3B,QAAQ,EAAE,CAAC;IACX,KAAK,EAAE,CAAC;IACR,OAAO,EAAE,CAAC;IACV,QAAQ,EAAE,IAAI;IACd,KAAK,EAAE,MAAM;CACd,CAAC;AAEF,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;QAClE,MAAM,WAAW,GAAG,iBAAiB,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QAExD,MAAM,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,6BAA6B,CAAC,CAAC;QAC7D,MAAM,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;QAC/C,MAAM,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QAC3C,MAAM,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;QAClD,MAAM,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,uEAAuE;QACvE,sEAAsE;QACtE,iEAAiE;QACjE,MAAM,WAAW,GAAG,iBAAiB,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QAEjD,MAAM,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,mCAAmC,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,oEAAoE;QACpE,8CAA8C;QAC9C,MAAM,CAAC,iBAAiB,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;IACvE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mEAAmE,EAAE,GAAG,EAAE;QAC3E,sEAAsE;QACtE,qEAAqE;QACrE,gDAAgD;QAChD,MAAM,WAAW,GAAG,iBAAiB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QAEzD,MAAM,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,6BAA6B,CAAC,CAAC;QAC7D,MAAM,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;QAChD,MAAM,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -1,4 +1,6 @@
1
1
  import { type ParsedTestCounts } from '../test-log-parser.js';
2
+ import { type StructuredTestResults } from '../structured-test-results.js';
3
+ import { type LogFetchStats } from '../log-fetch-stats.js';
2
4
  export interface BatchPackageResult {
3
5
  slug: string;
4
6
  success: boolean;
@@ -14,13 +16,124 @@ export interface BatchPackageResult {
14
16
  * test — often after the test that scheduled it already passed.
15
17
  */
16
18
  tracebackCount: number;
19
+ /**
20
+ * Where `testCounts` came from. `returned` means the run handed them over as a
21
+ * value; `scraped` means they were read out of log text, which is the channel
22
+ * truncation destroys. Absent when there are no counts at all.
23
+ *
24
+ * Recorded because the two are otherwise indistinguishable in the output, and
25
+ * a structured channel that quietly stopped flowing looks exactly like one
26
+ * that never existed.
27
+ */
28
+ countsSource?: 'returned' | 'scraped';
29
+ /**
30
+ * True when this package's counts arrived but its log section did not.
31
+ *
32
+ * A narrower verdict than a package with a section gets: the counts say what
33
+ * happened, but with no text there is nothing to check for tracebacks, and
34
+ * nothing to read when something did go wrong. Reported so a pass that came
35
+ * back half-blind cannot be mistaken for an ordinary one.
36
+ */
37
+ logsLost?: boolean;
38
+ /**
39
+ * What this package's own run returned, recovered from the batch summary.
40
+ *
41
+ * One execution covers every package, so its return value belongs to none of
42
+ * them — the batch runner splits the per-package results into the summary
43
+ * instead, and this puts them back in the shape a single run's results have.
44
+ * Lossy by design: the summary carries counts, not failure text, which is
45
+ * per-package and already in that package's log section.
46
+ */
47
+ testResults?: StructuredTestResults;
48
+ }
49
+ export interface ParseBatchTestLogsOptions {
50
+ /**
51
+ * What the fetch that produced `rawLogs` had to do to collect them, when the
52
+ * caller knows. Not used to judge a package — it only tells a failure that
53
+ * has already happened how much of the run's output ever arrived.
54
+ */
55
+ logFetchStats?: LogFetchStats;
56
+ /**
57
+ * Where diagnostics go. When set, the parser reports through this instead of
58
+ * printing, so a caller that renders the run's output can hold them until
59
+ * after it: a remark about a log window reads as nonsense above the log it
60
+ * is describing.
61
+ */
62
+ onDiagnostic?: (level: BatchDiagnosticLevel, message: string) => void;
63
+ /**
64
+ * What the batch script returned, when the transport carries return values.
65
+ *
66
+ * The same summary the script also prints, taken from the one channel the
67
+ * engine's log buffer cannot truncate — an oversize return value fails the
68
+ * task outright rather than arriving short, so a summary that arrives here is
69
+ * whole. Preferred over the printed copy, which is only reached when this is
70
+ * absent (a local bridge run, or a task that ended without an output).
71
+ */
72
+ returnValues?: unknown[];
73
+ }
74
+ /**
75
+ * `group` and `endgroup` bracket a run of diagnostics that belong together, so
76
+ * a finding repeated across many packages can be collapsed into one block
77
+ * instead of one line each.
78
+ */
79
+ export type BatchDiagnosticLevel = 'info' | 'warn' | 'verbose' | 'group' | 'endgroup';
80
+ /**
81
+ * Print one diagnostic, honoring the grouping levels.
82
+ *
83
+ * `useGroups` is passed in rather than looked up, so the whole run agrees about
84
+ * whether it is emitting workflow commands. Asking `isCI()` separately here, in
85
+ * the renderer and in the reporter is three answers to one question.
86
+ */
87
+ export declare function emitDiagnostic(level: BatchDiagnosticLevel, message: string, useGroups: boolean): void;
88
+ /**
89
+ * Counts the batch runner folds in from what a package's test script returned.
90
+ *
91
+ * Present only for a package whose script returns its results. Carried in the
92
+ * summary rather than left to the logs because the summary prints last and
93
+ * survives a truncated log window, which is where scraped counts are lost.
94
+ */
95
+ interface SummaryCounts {
96
+ passed: number;
97
+ failed: number;
98
+ skipped: number;
99
+ total: number;
100
+ suitesPassed: number;
101
+ suitesFailed: number;
102
+ suitesTotal: number;
17
103
  }
18
104
  interface SummaryEntry {
19
105
  slug: string;
20
106
  success: boolean;
21
107
  durationMs?: number;
22
108
  error?: string;
109
+ counts?: SummaryCounts;
110
+ /** False for a smoke test, so zero counts are not read as "no tests found". */
111
+ ranJest?: boolean;
112
+ }
113
+ interface BeginToken {
114
+ kind: 'begin';
115
+ slug: string;
116
+ }
117
+ interface EndToken {
118
+ kind: 'end';
119
+ slug: string;
120
+ durationMs?: number;
23
121
  }
122
+ interface SummaryToken {
123
+ kind: 'summary';
124
+ /** Where the marker sat, so the JSON payload can be looked up around it. */
125
+ lineIndex: number;
126
+ }
127
+ interface SummaryPayloadToken {
128
+ kind: 'summaryPayload';
129
+ }
130
+ interface ContentToken {
131
+ kind: 'content';
132
+ /** The untrimmed line, since section logs are shown to a human verbatim. */
133
+ line: string;
134
+ }
135
+ /** One log line, classified. Every line becomes exactly one token. */
136
+ export type BatchLogToken = BeginToken | EndToken | SummaryToken | SummaryPayloadToken | ContentToken;
24
137
  /**
25
138
  * Parse the single batch execution's logs into per-package results.
26
139
  *
@@ -35,7 +148,19 @@ interface SummaryEntry {
35
148
  * immune to log reordering. The BEGIN/END markers are used only for splitting logs
36
149
  * into per-package sections. Jest failure detection provides a secondary override.
37
150
  */
38
- export declare function parseBatchTestLogs(rawLogs: string, slugMap: Map<string, string>): Map<string, BatchPackageResult>;
151
+ export declare function parseBatchTestLogs(rawLogs: string, slugMap: Map<string, string>, options?: ParseBatchTestLogsOptions): Map<string, BatchPackageResult>;
152
+ /**
153
+ * Classify every log line, so section splitting reads tokens instead of text.
154
+ */
155
+ export declare function tokenizeBatchLog(lines: string[]): BatchLogToken[];
156
+ /**
157
+ * Find the summary array among a task's return values.
158
+ *
159
+ * The batch script returns the same array it prints. Recognized by shape rather
160
+ * than by position: a run is free to return other things, and an array of
161
+ * objects that all carry a string `slug` is the summary and nothing else.
162
+ */
163
+ export declare function findReturnedSummaryEntries(returnValues: unknown[] | undefined): SummaryEntry[] | undefined;
39
164
  /**
40
165
  * Find the summary array in the lines following the summary marker.
41
166
  *
@@ -1 +1 @@
1
- {"version":3,"file":"batch-log-parser.d.ts","sourceRoot":"","sources":["../../../../src/utils/testing/parsers/batch-log-parser.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,gBAAgB,EAGtB,MAAM,uBAAuB,CAAC;AAG/B,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,oEAAoE;IACpE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,6EAA6E;IAC7E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,cAAc,EAAE,MAAM,CAAC;CACxB;AAMD,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAC3B,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAgRjC;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,MAAM,EAAE,EACf,UAAU,EAAE,MAAM,GACjB,YAAY,EAAE,GAAG,SAAS,CA4B5B;AAED,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"batch-log-parser.d.ts","sourceRoot":"","sources":["../../../../src/utils/testing/parsers/batch-log-parser.ts"],"names":[],"mappings":"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"}