@rigour-labs/core 6.7.10 → 6.8.1-rc.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.
Files changed (346) hide show
  1. package/dist/brief/briefing.d.ts +59 -0
  2. package/dist/brief/briefing.js +126 -0
  3. package/dist/index.d.ts +2 -0
  4. package/dist/index.js +2 -0
  5. package/dist/inference/cloud-provider.js +12 -2
  6. package/dist/review/backtest-init.d.ts +8 -5
  7. package/dist/review/backtest-init.js +27 -9
  8. package/dist/review/backtest-last.js +3 -1
  9. package/dist/review/reviewer/adapters.d.ts +4 -0
  10. package/dist/review/reviewer/adapters.js +23 -0
  11. package/dist/review/reviewer/inputs.d.ts +4 -1
  12. package/dist/review/reviewer/inputs.js +36 -2
  13. package/dist/review/reviewer/record.d.ts +5 -0
  14. package/dist/review/reviewer/record.js +3 -3
  15. package/dist/review/reviewer/verdict.d.ts +14 -0
  16. package/dist/review/reviewer/verdict.js +46 -6
  17. package/dist/review/reviewer.d.ts +2 -0
  18. package/dist/review/reviewer.js +24 -5
  19. package/dist/review-learning/repo-rules.d.ts +14 -2
  20. package/dist/review-learning/repo-rules.js +59 -9
  21. package/dist/task/thread.d.ts +47 -0
  22. package/dist/task/thread.js +234 -0
  23. package/dist/templates/universal-config.js +4 -0
  24. package/dist/types/index.d.ts +21 -0
  25. package/dist/types/index.js +7 -0
  26. package/package.json +11 -8
  27. package/dist/context/automatic-index-cache.test.d.ts +0 -1
  28. package/dist/context/automatic-index-cache.test.js +0 -30
  29. package/dist/context/automatic-index.test.d.ts +0 -1
  30. package/dist/context/automatic-index.test.js +0 -45
  31. package/dist/context/cache-engine.test.d.ts +0 -1
  32. package/dist/context/cache-engine.test.js +0 -99
  33. package/dist/context/dependency-graph.test.d.ts +0 -1
  34. package/dist/context/dependency-graph.test.js +0 -13
  35. package/dist/context/index-status.test.d.ts +0 -1
  36. package/dist/context/index-status.test.js +0 -26
  37. package/dist/context.test.d.ts +0 -1
  38. package/dist/context.test.js +0 -228
  39. package/dist/deep/agent-review.test.d.ts +0 -1
  40. package/dist/deep/agent-review.test.js +0 -53
  41. package/dist/deep/code-context.test.d.ts +0 -1
  42. package/dist/deep/code-context.test.js +0 -48
  43. package/dist/deep/code-pass.test.d.ts +0 -1
  44. package/dist/deep/code-pass.test.js +0 -112
  45. package/dist/deep/code-review-prompt.test.d.ts +0 -1
  46. package/dist/deep/code-review-prompt.test.js +0 -20
  47. package/dist/deep/code-verifier.test.d.ts +0 -1
  48. package/dist/deep/code-verifier.test.js +0 -54
  49. package/dist/deep/diff-tests/calls.test.d.ts +0 -1
  50. package/dist/deep/diff-tests/calls.test.js +0 -33
  51. package/dist/deep/diff-tests/run.test.d.ts +0 -1
  52. package/dist/deep/diff-tests/run.test.js +0 -58
  53. package/dist/deep/fact-extractor.test.d.ts +0 -1
  54. package/dist/deep/fact-extractor.test.js +0 -581
  55. package/dist/deep/parse-findings.test.d.ts +0 -1
  56. package/dist/deep/parse-findings.test.js +0 -25
  57. package/dist/deep/pr-review.test.d.ts +0 -1
  58. package/dist/deep/pr-review.test.js +0 -80
  59. package/dist/deep/prompts.test.d.ts +0 -1
  60. package/dist/deep/prompts.test.js +0 -235
  61. package/dist/deep/reference-pack.test.d.ts +0 -1
  62. package/dist/deep/reference-pack.test.js +0 -46
  63. package/dist/deep/related-changes.test.d.ts +0 -1
  64. package/dist/deep/related-changes.test.js +0 -33
  65. package/dist/deep/review-context-export.test.d.ts +0 -1
  66. package/dist/deep/review-context-export.test.js +0 -32
  67. package/dist/deep/review-tools.test.d.ts +0 -1
  68. package/dist/deep/review-tools.test.js +0 -39
  69. package/dist/deep/risk.test.d.ts +0 -1
  70. package/dist/deep/risk.test.js +0 -101
  71. package/dist/deep/verifier.test.d.ts +0 -1
  72. package/dist/deep/verifier.test.js +0 -635
  73. package/dist/discovery.test.d.ts +0 -1
  74. package/dist/discovery.test.js +0 -93
  75. package/dist/environment.test.d.ts +0 -1
  76. package/dist/environment.test.js +0 -94
  77. package/dist/firewall/firewall.test.d.ts +0 -1
  78. package/dist/firewall/firewall.test.js +0 -117
  79. package/dist/firewall/trust-boundaries.test.d.ts +0 -1
  80. package/dist/firewall/trust-boundaries.test.js +0 -64
  81. package/dist/firewall/trusted-control.test.d.ts +0 -1
  82. package/dist/firewall/trusted-control.test.js +0 -188
  83. package/dist/gates/agent-team.test.d.ts +0 -1
  84. package/dist/gates/agent-team.test.js +0 -113
  85. package/dist/gates/ast.test.d.ts +0 -1
  86. package/dist/gates/ast.test.js +0 -112
  87. package/dist/gates/checkpoint.test.d.ts +0 -1
  88. package/dist/gates/checkpoint.test.js +0 -105
  89. package/dist/gates/content.test.d.ts +0 -1
  90. package/dist/gates/content.test.js +0 -73
  91. package/dist/gates/coverage.test.d.ts +0 -1
  92. package/dist/gates/coverage.test.js +0 -53
  93. package/dist/gates/dedupe-failures.test.d.ts +0 -1
  94. package/dist/gates/dedupe-failures.test.js +0 -12
  95. package/dist/gates/deep-analysis.test.d.ts +0 -1
  96. package/dist/gates/deep-analysis.test.js +0 -86
  97. package/dist/gates/deep-intent.test.d.ts +0 -1
  98. package/dist/gates/deep-intent.test.js +0 -51
  99. package/dist/gates/deep-timeout.test.d.ts +0 -1
  100. package/dist/gates/deep-timeout.test.js +0 -10
  101. package/dist/gates/deprecated-apis.test.d.ts +0 -1
  102. package/dist/gates/deprecated-apis.test.js +0 -318
  103. package/dist/gates/deprecated-dependencies.test.d.ts +0 -1
  104. package/dist/gates/deprecated-dependencies.test.js +0 -55
  105. package/dist/gates/frontend-secret-exposure.test.d.ts +0 -1
  106. package/dist/gates/frontend-secret-exposure.test.js +0 -148
  107. package/dist/gates/hallucinated-imports/framework-modules-nuxt.test.d.ts +0 -1
  108. package/dist/gates/hallucinated-imports/framework-modules-nuxt.test.js +0 -27
  109. package/dist/gates/hallucinated-imports/js-resolver-types.test.d.ts +0 -1
  110. package/dist/gates/hallucinated-imports/js-resolver-types.test.js +0 -14
  111. package/dist/gates/hallucinated-imports-sveltekit.test.d.ts +0 -1
  112. package/dist/gates/hallucinated-imports-sveltekit.test.js +0 -132
  113. package/dist/gates/hallucinated-imports.test.d.ts +0 -1
  114. package/dist/gates/hallucinated-imports.test.js +0 -1206
  115. package/dist/gates/js-style-context.test.d.ts +0 -1
  116. package/dist/gates/js-style-context.test.js +0 -35
  117. package/dist/gates/logic-drift.test.d.ts +0 -1
  118. package/dist/gates/logic-drift.test.js +0 -52
  119. package/dist/gates/phantom-apis.test.d.ts +0 -1
  120. package/dist/gates/phantom-apis.test.js +0 -396
  121. package/dist/gates/promise-safety.test.d.ts +0 -1
  122. package/dist/gates/promise-safety.test.js +0 -34
  123. package/dist/gates/runner.test.d.ts +0 -1
  124. package/dist/gates/runner.test.js +0 -77
  125. package/dist/gates/scoped-gates.test.d.ts +0 -1
  126. package/dist/gates/scoped-gates.test.js +0 -52
  127. package/dist/gates/security-patterns-owasp.test.d.ts +0 -1
  128. package/dist/gates/security-patterns-owasp.test.js +0 -186
  129. package/dist/gates/security-patterns.test.d.ts +0 -1
  130. package/dist/gates/security-patterns.test.js +0 -194
  131. package/dist/gates/semantic-bugs.test.d.ts +0 -1
  132. package/dist/gates/semantic-bugs.test.js +0 -76
  133. package/dist/gates/side-effect-analysis.test.d.ts +0 -1
  134. package/dist/gates/side-effect-analysis.test.js +0 -162
  135. package/dist/gates/style-drift.test.d.ts +0 -1
  136. package/dist/gates/style-drift.test.js +0 -26
  137. package/dist/gates/test-quality.test.d.ts +0 -1
  138. package/dist/gates/test-quality.test.js +0 -325
  139. package/dist/gates/trusted-reviews.test.d.ts +0 -1
  140. package/dist/gates/trusted-reviews.test.js +0 -16
  141. package/dist/gates/unindexed-reads/queries.test.d.ts +0 -1
  142. package/dist/gates/unindexed-reads/queries.test.js +0 -54
  143. package/dist/gates/unindexed-reads/schema.test.d.ts +0 -1
  144. package/dist/gates/unindexed-reads/schema.test.js +0 -81
  145. package/dist/gates/unindexed-reads/unindexed-reads.test.d.ts +0 -1
  146. package/dist/gates/unindexed-reads/unindexed-reads.test.js +0 -90
  147. package/dist/hooks/checker.test.d.ts +0 -1
  148. package/dist/hooks/checker.test.js +0 -159
  149. package/dist/hooks/dlp-confidence.test.d.ts +0 -1
  150. package/dist/hooks/dlp-confidence.test.js +0 -51
  151. package/dist/hooks/dlp-feedback.test.d.ts +0 -1
  152. package/dist/hooks/dlp-feedback.test.js +0 -131
  153. package/dist/hooks/input-validator.test.d.ts +0 -1
  154. package/dist/hooks/input-validator.test.js +0 -329
  155. package/dist/hooks/templates.test.d.ts +0 -1
  156. package/dist/hooks/templates.test.js +0 -27
  157. package/dist/inference/brain-placeholder.test.d.ts +0 -1
  158. package/dist/inference/brain-placeholder.test.js +0 -28
  159. package/dist/inference/cloud-provider.test.d.ts +0 -1
  160. package/dist/inference/cloud-provider.test.js +0 -139
  161. package/dist/inference/executable.test.d.ts +0 -1
  162. package/dist/inference/executable.test.js +0 -41
  163. package/dist/inference/http-download.test.d.ts +0 -1
  164. package/dist/inference/http-download.test.js +0 -109
  165. package/dist/inference/llama-engine-checksum.test.d.ts +0 -1
  166. package/dist/inference/llama-engine-checksum.test.js +0 -27
  167. package/dist/inference/llama-engine.test.d.ts +0 -1
  168. package/dist/inference/llama-engine.test.js +0 -51
  169. package/dist/inference/llama-process.test.d.ts +0 -1
  170. package/dist/inference/llama-process.test.js +0 -61
  171. package/dist/inference/local-model.test.d.ts +0 -1
  172. package/dist/inference/local-model.test.js +0 -23
  173. package/dist/inference/model-download.test.d.ts +0 -1
  174. package/dist/inference/model-download.test.js +0 -125
  175. package/dist/inference/model-manager.test.d.ts +0 -1
  176. package/dist/inference/model-manager.test.js +0 -24
  177. package/dist/inference/types.test.d.ts +0 -1
  178. package/dist/inference/types.test.js +0 -19
  179. package/dist/memory/recall.test.d.ts +0 -1
  180. package/dist/memory/recall.test.js +0 -36
  181. package/dist/pattern-index/indexer.test.d.ts +0 -6
  182. package/dist/pattern-index/indexer.test.js +0 -197
  183. package/dist/pattern-index/matcher.test.d.ts +0 -6
  184. package/dist/pattern-index/matcher.test.js +0 -238
  185. package/dist/pattern-index/pattern-reuse.test.d.ts +0 -1
  186. package/dist/pattern-index/pattern-reuse.test.js +0 -76
  187. package/dist/pattern-index/semantic-runtime.test.d.ts +0 -1
  188. package/dist/pattern-index/semantic-runtime.test.js +0 -31
  189. package/dist/pattern-index/staleness.test.d.ts +0 -6
  190. package/dist/pattern-index/staleness.test.js +0 -211
  191. package/dist/review/agent-fixes.test.d.ts +0 -1
  192. package/dist/review/agent-fixes.test.js +0 -32
  193. package/dist/review/backtest-init.test.d.ts +0 -1
  194. package/dist/review/backtest-init.test.js +0 -98
  195. package/dist/review/backtest-judges.test.d.ts +0 -1
  196. package/dist/review/backtest-judges.test.js +0 -32
  197. package/dist/review/backtest-last.test.d.ts +0 -1
  198. package/dist/review/backtest-last.test.js +0 -109
  199. package/dist/review/backtest.test.d.ts +0 -1
  200. package/dist/review/backtest.test.js +0 -183
  201. package/dist/review/baseline.test.d.ts +0 -1
  202. package/dist/review/baseline.test.js +0 -22
  203. package/dist/review/branch-checks.test.d.ts +0 -1
  204. package/dist/review/branch-checks.test.js +0 -48
  205. package/dist/review/check-outcomes.test.d.ts +0 -1
  206. package/dist/review/check-outcomes.test.js +0 -56
  207. package/dist/review/code-patterns.test.d.ts +0 -1
  208. package/dist/review/code-patterns.test.js +0 -142
  209. package/dist/review/dead-code.test.d.ts +0 -1
  210. package/dist/review/dead-code.test.js +0 -154
  211. package/dist/review/deep-runs.test.d.ts +0 -1
  212. package/dist/review/deep-runs.test.js +0 -23
  213. package/dist/review/effectiveness.test.d.ts +0 -1
  214. package/dist/review/effectiveness.test.js +0 -42
  215. package/dist/review/fix-scope.test.d.ts +0 -1
  216. package/dist/review/fix-scope.test.js +0 -104
  217. package/dist/review/generated-files.test.d.ts +0 -1
  218. package/dist/review/generated-files.test.js +0 -25
  219. package/dist/review/migration-order.test.d.ts +0 -1
  220. package/dist/review/migration-order.test.js +0 -62
  221. package/dist/review/quiet.test.d.ts +0 -1
  222. package/dist/review/quiet.test.js +0 -38
  223. package/dist/review/receipt.test.d.ts +0 -1
  224. package/dist/review/receipt.test.js +0 -60
  225. package/dist/review/review-task.test.d.ts +0 -1
  226. package/dist/review/review-task.test.js +0 -89
  227. package/dist/review/review.test.d.ts +0 -1
  228. package/dist/review/review.test.js +0 -203
  229. package/dist/review/reviewer/adapters.test.d.ts +0 -1
  230. package/dist/review/reviewer/adapters.test.js +0 -60
  231. package/dist/review/reviewer/api-judge.test.d.ts +0 -1
  232. package/dist/review/reviewer/api-judge.test.js +0 -108
  233. package/dist/review/reviewer/background.test.d.ts +0 -1
  234. package/dist/review/reviewer/background.test.js +0 -118
  235. package/dist/review/reviewer/context.test.d.ts +0 -1
  236. package/dist/review/reviewer/context.test.js +0 -45
  237. package/dist/review/reviewer/exec.test.d.ts +0 -1
  238. package/dist/review/reviewer/exec.test.js +0 -59
  239. package/dist/review/reviewer/inputs.test.d.ts +0 -1
  240. package/dist/review/reviewer/inputs.test.js +0 -26
  241. package/dist/review/reviewer/panel.test.d.ts +0 -1
  242. package/dist/review/reviewer/panel.test.js +0 -110
  243. package/dist/review/reviewer/record.test.d.ts +0 -1
  244. package/dist/review/reviewer/record.test.js +0 -32
  245. package/dist/review/reviewer/rule-writer.test.d.ts +0 -1
  246. package/dist/review/reviewer/rule-writer.test.js +0 -52
  247. package/dist/review/reviewer/settings.test.d.ts +0 -1
  248. package/dist/review/reviewer/settings.test.js +0 -57
  249. package/dist/review/reviewer/usage.test.d.ts +0 -1
  250. package/dist/review/reviewer/usage.test.js +0 -14
  251. package/dist/review/reviewer.test.d.ts +0 -1
  252. package/dist/review/reviewer.test.js +0 -705
  253. package/dist/review/stories.test.d.ts +0 -1
  254. package/dist/review/stories.test.js +0 -58
  255. package/dist/review/toolchain.test.d.ts +0 -1
  256. package/dist/review/toolchain.test.js +0 -108
  257. package/dist/review/typed/redundancy.test.d.ts +0 -1
  258. package/dist/review/typed/redundancy.test.js +0 -315
  259. package/dist/review/typed/schema-nullability.test.d.ts +0 -1
  260. package/dist/review/typed/schema-nullability.test.js +0 -63
  261. package/dist/review-learning/human-edits.test.d.ts +0 -1
  262. package/dist/review-learning/human-edits.test.js +0 -47
  263. package/dist/review-learning/repo-rules.test.d.ts +0 -1
  264. package/dist/review-learning/repo-rules.test.js +0 -55
  265. package/dist/review-learning/review-learning.test.d.ts +0 -1
  266. package/dist/review-learning/review-learning.test.js +0 -249
  267. package/dist/safety.test.d.ts +0 -1
  268. package/dist/safety.test.js +0 -42
  269. package/dist/semantic/benchmark.test.d.ts +0 -1
  270. package/dist/semantic/benchmark.test.js +0 -22
  271. package/dist/semantic/intent/intent.test.d.ts +0 -1
  272. package/dist/semantic/intent/intent.test.js +0 -46
  273. package/dist/semantic/learn/learn.test.d.ts +0 -1
  274. package/dist/semantic/learn/learn.test.js +0 -67
  275. package/dist/semantic/origins.test.d.ts +0 -1
  276. package/dist/semantic/origins.test.js +0 -77
  277. package/dist/semantic/project-facts.test.d.ts +0 -1
  278. package/dist/semantic/project-facts.test.js +0 -45
  279. package/dist/semantic/sites/call-sites.test.d.ts +0 -1
  280. package/dist/semantic/sites/call-sites.test.js +0 -46
  281. package/dist/services/adaptive-thresholds.test.d.ts +0 -1
  282. package/dist/services/adaptive-thresholds.test.js +0 -53
  283. package/dist/services/agent-history.test.d.ts +0 -1
  284. package/dist/services/agent-history.test.js +0 -69
  285. package/dist/services/context-scope-summary.test.d.ts +0 -1
  286. package/dist/services/context-scope-summary.test.js +0 -17
  287. package/dist/services/context-telemetry-service.test.d.ts +0 -1
  288. package/dist/services/context-telemetry-service.test.js +0 -182
  289. package/dist/services/cursor-usage-sync.test.d.ts +0 -1
  290. package/dist/services/cursor-usage-sync.test.js +0 -173
  291. package/dist/services/engineering-knowledge-graph.test.d.ts +0 -1
  292. package/dist/services/engineering-knowledge-graph.test.js +0 -76
  293. package/dist/services/model-pricing.test.d.ts +0 -1
  294. package/dist/services/model-pricing.test.js +0 -44
  295. package/dist/services/observed-savings.test.d.ts +0 -1
  296. package/dist/services/observed-savings.test.js +0 -37
  297. package/dist/services/score-history.test.d.ts +0 -1
  298. package/dist/services/score-history.test.js +0 -61
  299. package/dist/smoke.test.d.ts +0 -1
  300. package/dist/smoke.test.js +0 -17
  301. package/dist/storage/cache-cleanup.test.d.ts +0 -1
  302. package/dist/storage/cache-cleanup.test.js +0 -54
  303. package/dist/storage/context-telemetry.test.d.ts +0 -1
  304. package/dist/storage/context-telemetry.test.js +0 -80
  305. package/dist/storage/db.test.d.ts +0 -1
  306. package/dist/storage/db.test.js +0 -46
  307. package/dist/storage/fix-lessons.test.d.ts +0 -1
  308. package/dist/storage/fix-lessons.test.js +0 -61
  309. package/dist/storage/lessons.test.d.ts +0 -1
  310. package/dist/storage/lessons.test.js +0 -81
  311. package/dist/storage/local-encryption.test.d.ts +0 -1
  312. package/dist/storage/local-encryption.test.js +0 -34
  313. package/dist/storage/local-memory.test.d.ts +0 -1
  314. package/dist/storage/local-memory.test.js +0 -55
  315. package/dist/storage/share-memory.test.d.ts +0 -1
  316. package/dist/storage/share-memory.test.js +0 -34
  317. package/dist/storage/team-diagnostics.test.d.ts +0 -1
  318. package/dist/storage/team-diagnostics.test.js +0 -51
  319. package/dist/storage/team-scope.test.d.ts +0 -1
  320. package/dist/storage/team-scope.test.js +0 -22
  321. package/dist/storage/team-store.test.d.ts +0 -1
  322. package/dist/storage/team-store.test.js +0 -11
  323. package/dist/storage/team-sync-scope.test.d.ts +0 -1
  324. package/dist/storage/team-sync-scope.test.js +0 -100
  325. package/dist/storage/team-vector-store.test.d.ts +0 -1
  326. package/dist/storage/team-vector-store.test.js +0 -56
  327. package/dist/storage/telemetry-scope.test.d.ts +0 -1
  328. package/dist/storage/telemetry-scope.test.js +0 -38
  329. package/dist/telemetry/telemetry.test.d.ts +0 -1
  330. package/dist/telemetry/telemetry.test.js +0 -64
  331. package/dist/types/index.test.d.ts +0 -1
  332. package/dist/types/index.test.js +0 -33
  333. package/dist/utils/command-line.test.d.ts +0 -1
  334. package/dist/utils/command-line.test.js +0 -8
  335. package/dist/utils/diff-removed.test.d.ts +0 -1
  336. package/dist/utils/diff-removed.test.js +0 -29
  337. package/dist/utils/diff.test.d.ts +0 -1
  338. package/dist/utils/diff.test.js +0 -38
  339. package/dist/utils/glob-paths.test.d.ts +0 -1
  340. package/dist/utils/glob-paths.test.js +0 -40
  341. package/dist/utils/profile.test.d.ts +0 -1
  342. package/dist/utils/profile.test.js +0 -68
  343. package/dist/utils/scanner.test.d.ts +0 -1
  344. package/dist/utils/scanner.test.js +0 -48
  345. package/dist/utils/scope.test.d.ts +0 -1
  346. package/dist/utils/scope.test.js +0 -38
@@ -1 +0,0 @@
1
- export {};
@@ -1,235 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
- import { buildAnalysisPrompt, buildCrossFilePrompt, chunkFacts, DEEP_SYSTEM_PROMPT } from './prompts.js';
3
- import { factsToPromptString } from './fact-extractor.js';
4
- // ── Test helpers ──
5
- function makeGoFacts(overrides = {}) {
6
- return {
7
- path: 'pkg/server.go',
8
- language: 'go',
9
- lineCount: 200,
10
- classes: [],
11
- functions: [{
12
- name: 'Server.Start',
13
- lineStart: 10,
14
- lineEnd: 50,
15
- lineCount: 40,
16
- paramCount: 1,
17
- params: ['ctx context.Context'],
18
- maxNesting: 3,
19
- hasReturn: true,
20
- isAsync: false,
21
- isExported: true,
22
- }],
23
- imports: ['net/http', 'context', 'sync'],
24
- exports: [],
25
- errorHandling: [],
26
- testAssertions: 0,
27
- hasTests: false,
28
- structs: [{
29
- name: 'Server',
30
- lineStart: 5,
31
- lineEnd: 15,
32
- fieldCount: 5,
33
- methodCount: 4,
34
- methods: ['Start', 'Stop', 'Handle', 'Route'],
35
- lineCount: 10,
36
- embeds: ['BaseServer'],
37
- }],
38
- interfaces: [{
39
- name: 'Handler',
40
- lineStart: 20,
41
- methodCount: 2,
42
- methods: ['ServeHTTP', 'Health'],
43
- }],
44
- goroutines: 3,
45
- channels: 1,
46
- mutexes: 1,
47
- defers: 2,
48
- ...overrides,
49
- };
50
- }
51
- function makeTsFacts(overrides = {}) {
52
- return {
53
- path: 'src/service.ts',
54
- language: 'typescript',
55
- lineCount: 150,
56
- classes: [{
57
- name: 'UserService',
58
- lineStart: 5,
59
- lineEnd: 140,
60
- methodCount: 6,
61
- methods: ['find', 'create', 'update', 'delete', 'validate', 'notify'],
62
- publicMethods: ['find', 'create', 'update', 'delete'],
63
- lineCount: 135,
64
- dependencies: ['Database', 'Logger'],
65
- }],
66
- functions: [],
67
- imports: ['express', 'lodash', './types'],
68
- exports: ['UserService'],
69
- errorHandling: [
70
- { type: 'try-catch', lineStart: 10, isEmpty: false, strategy: 'throw' },
71
- ],
72
- testAssertions: 0,
73
- hasTests: false,
74
- ...overrides,
75
- };
76
- }
77
- describe('Deep Analysis Prompts', () => {
78
- // ── DEEP_SYSTEM_PROMPT ──
79
- describe('DEEP_SYSTEM_PROMPT', () => {
80
- it('should contain all category groups', () => {
81
- expect(DEEP_SYSTEM_PROMPT).toContain('SOLID Principles');
82
- expect(DEEP_SYSTEM_PROMPT).toContain('Design Patterns');
83
- expect(DEEP_SYSTEM_PROMPT).toContain('DRY');
84
- expect(DEEP_SYSTEM_PROMPT).toContain('Error Handling');
85
- expect(DEEP_SYSTEM_PROMPT).toContain('Concurrency');
86
- expect(DEEP_SYSTEM_PROMPT).toContain('Testing');
87
- });
88
- it('should contain key category IDs', () => {
89
- expect(DEEP_SYSTEM_PROMPT).toContain('god_class');
90
- expect(DEEP_SYSTEM_PROMPT).toContain('god_function');
91
- expect(DEEP_SYSTEM_PROMPT).toContain('srp_violation');
92
- expect(DEEP_SYSTEM_PROMPT).toContain('race_condition');
93
- expect(DEEP_SYSTEM_PROMPT).toContain('empty_catch');
94
- expect(DEEP_SYSTEM_PROMPT).toContain('missing_test');
95
- });
96
- it('should include output schema', () => {
97
- expect(DEEP_SYSTEM_PROMPT).toContain('"findings"');
98
- expect(DEEP_SYSTEM_PROMPT).toContain('"category"');
99
- expect(DEEP_SYSTEM_PROMPT).toContain('"severity"');
100
- expect(DEEP_SYSTEM_PROMPT).toContain('"confidence"');
101
- });
102
- it('should contain Go-specific guidance', () => {
103
- expect(DEEP_SYSTEM_PROMPT).toContain('Go code');
104
- expect(DEEP_SYSTEM_PROMPT).toContain('struct');
105
- expect(DEEP_SYSTEM_PROMPT).toContain('receiver method');
106
- });
107
- });
108
- // ── buildAnalysisPrompt ──
109
- describe('buildAnalysisPrompt', () => {
110
- it('should build prompt with default checks', () => {
111
- const factsStr = 'FILE: src/service.ts (typescript, 150 lines)';
112
- const prompt = buildAnalysisPrompt(factsStr);
113
- // Default checks include descriptions for SOLID, DRY, design patterns
114
- expect(prompt).toContain('SOLID');
115
- expect(prompt).toContain('DRY');
116
- expect(prompt).toContain('god class');
117
- expect(prompt).toContain(factsStr);
118
- });
119
- it('should include language-specific guidance for Go', () => {
120
- const factsStr = 'FILE: pkg/server.go (go, 200 lines)\n STRUCT Server (10 lines, 5 fields)';
121
- const prompt = buildAnalysisPrompt(factsStr);
122
- // Should detect Go as dominant language and add Go guidance
123
- expect(prompt.toLowerCase()).toContain('go');
124
- });
125
- it('should include language-specific guidance for TypeScript', () => {
126
- const factsStr = 'FILE: src/service.ts (typescript, 150 lines)\n CLASS UserService';
127
- const prompt = buildAnalysisPrompt(factsStr);
128
- expect(prompt.toLowerCase()).toContain('typescript');
129
- });
130
- it('should respect custom check selection', () => {
131
- const factsStr = 'FILE: src/service.ts (typescript, 150 lines)';
132
- const checks = {
133
- solid: true,
134
- dry: false,
135
- design_patterns: false,
136
- concurrency: true,
137
- };
138
- const prompt = buildAnalysisPrompt(factsStr, checks);
139
- expect(prompt).toContain('SOLID');
140
- expect(prompt).toContain('Concurrency');
141
- });
142
- });
143
- // ── buildCrossFilePrompt ──
144
- describe('buildCrossFilePrompt', () => {
145
- it('should analyze patterns across multiple files', () => {
146
- const allFacts = [
147
- makeTsFacts({ path: 'src/user.service.ts' }),
148
- makeTsFacts({
149
- path: 'src/order.service.ts',
150
- classes: [{
151
- name: 'OrderService',
152
- lineStart: 1,
153
- lineEnd: 100,
154
- methodCount: 5,
155
- methods: ['find', 'create', 'update', 'delete', 'process'],
156
- publicMethods: ['find', 'create'],
157
- lineCount: 100,
158
- dependencies: ['Database', 'Logger'],
159
- }],
160
- }),
161
- makeTsFacts({
162
- path: 'src/product.service.ts',
163
- errorHandling: [
164
- { type: 'try-catch', lineStart: 5, isEmpty: false, strategy: 'log' },
165
- { type: 'try-catch', lineStart: 15, isEmpty: false, strategy: 'throw' },
166
- ],
167
- }),
168
- ];
169
- const prompt = buildCrossFilePrompt(allFacts);
170
- expect(prompt).toBeDefined();
171
- expect(prompt.length).toBeGreaterThan(0);
172
- // Should reference file count
173
- expect(prompt).toContain('3');
174
- });
175
- it('should include Go-specific cross-file info', () => {
176
- const allFacts = [
177
- makeGoFacts({ path: 'pkg/server.go' }),
178
- makeGoFacts({
179
- path: 'pkg/handler.go',
180
- structs: [{
181
- name: 'Handler',
182
- lineStart: 1,
183
- lineEnd: 50,
184
- fieldCount: 3,
185
- methodCount: 5,
186
- methods: ['Get', 'Post', 'Put', 'Delete', 'Options'],
187
- lineCount: 50,
188
- embeds: [],
189
- }],
190
- }),
191
- ];
192
- const prompt = buildCrossFilePrompt(allFacts);
193
- expect(prompt).toBeDefined();
194
- expect(prompt.length).toBeGreaterThan(0);
195
- });
196
- });
197
- // ── chunkFacts ──
198
- describe('chunkFacts', () => {
199
- it('never lets the serialized chunk overrun the prompt budget, so no file is dropped', () => {
200
- const facts = Array.from({ length: 40 }, (_, i) => makeTsFacts({
201
- path: `src/deeply/nested/module-${i}/implementation-file-with-a-long-name-${i}.ts`,
202
- lineCount: 300,
203
- imports: Array.from({ length: 8 }, (_, j) => `@scope/package-with-long-name-${j}/sub/path`),
204
- }));
205
- const chunks = chunkFacts(facts, 6000);
206
- expect(chunks.flat()).toHaveLength(facts.length);
207
- for (const chunk of chunks) {
208
- const text = factsToPromptString(chunk);
209
- for (const f of chunk)
210
- expect(text).toContain(`FILE: ${f.path}`);
211
- }
212
- });
213
- it('should split facts into token-limited chunks', () => {
214
- const manyFacts = Array.from({ length: 50 }, (_, i) => makeTsFacts({
215
- path: `src/file${i}.ts`,
216
- lineCount: 200,
217
- }));
218
- const chunks = chunkFacts(manyFacts, 4000);
219
- expect(chunks.length).toBeGreaterThan(1);
220
- // All facts should be distributed across chunks
221
- const totalFiles = chunks.reduce((sum, chunk) => sum + chunk.length, 0);
222
- expect(totalFiles).toBe(50);
223
- });
224
- it('should handle single file within budget', () => {
225
- const facts = [makeTsFacts()];
226
- const chunks = chunkFacts(facts, 10000);
227
- expect(chunks).toHaveLength(1);
228
- expect(chunks[0]).toHaveLength(1);
229
- });
230
- it('should handle empty input', () => {
231
- const chunks = chunkFacts([], 4000);
232
- expect(chunks).toHaveLength(0);
233
- });
234
- });
235
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,46 +0,0 @@
1
- import { execFileSync } from 'child_process';
2
- import fs from 'fs';
3
- import os from 'os';
4
- import path from 'path';
5
- import { afterEach, describe, expect, it } from 'vitest';
6
- import { buildReferencePack } from './reference-pack.js';
7
- let repo;
8
- afterEach(() => { if (repo)
9
- fs.rmSync(repo, { recursive: true, force: true }); repo = undefined; });
10
- function project() {
11
- repo = fs.mkdtempSync(path.join(os.tmpdir(), 'reference-pack-'));
12
- const files = {
13
- 'src/paths.ts': "export function cleanPath(p: string): string {\n return p.replace(/\\/+/g, '/');\n}\n",
14
- 'src/routes.ts': "import { cleanPath } from './paths';\nexport function routePath(dir: string, route: string): string {\n return cleanPath(`/${dir}${route}`);\n}\n",
15
- 'src/generator.ts': "import { routePath } from './routes';\nexport const home = routePath('.', '/');\n",
16
- };
17
- for (const [name, text] of Object.entries(files)) {
18
- fs.mkdirSync(path.dirname(path.join(repo, name)), { recursive: true });
19
- fs.writeFileSync(path.join(repo, name), text);
20
- }
21
- execFileSync('git', ['init', '-q'], { cwd: repo });
22
- execFileSync('git', ['add', '-A'], { cwd: repo });
23
- return repo;
24
- }
25
- describe('buildReferencePack', () => {
26
- it('carries the intent, removed lines, callee definitions and callers of a changed export', () => {
27
- const cwd = project();
28
- const pack = buildReferencePack({
29
- cwd, file: 'src/routes.ts', focusLines: [3], maxChars: 10_000,
30
- prBody: 'Normalize virtual route paths.',
31
- removed: [{ line: 3, text: [" return `/${dir}${route}`;"] }],
32
- });
33
- expect(pack.text).toContain('PR DESCRIPTION (what the author intends):\nNormalize virtual route paths.');
34
- expect(pack.text).toContain('REMOVED by this change, just before line 3 of src/routes.ts:\n- return `/${dir}${route}`;');
35
- expect(pack.text).toContain('CALLED: src/paths.ts:1\nexport function cleanPath');
36
- expect(pack.text).toContain("CALLER of routePath:\nsrc/generator.ts:2:export const home = routePath('.', '/');");
37
- expect(pack.source).toContain('cleanPath');
38
- });
39
- it('stays within its budget, keeping the highest-priority sections', () => {
40
- const cwd = project();
41
- const pack = buildReferencePack({ cwd, file: 'src/routes.ts', focusLines: [3], maxChars: 80, prBody: 'Normalize virtual route paths.' });
42
- expect(pack.text).toContain('PR DESCRIPTION');
43
- expect(pack.text).not.toContain('CALLED');
44
- expect(pack.text.length).toBeLessThanOrEqual(80);
45
- });
46
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,33 +0,0 @@
1
- import fs from 'fs';
2
- import os from 'os';
3
- import path from 'path';
4
- import { afterEach, beforeEach, describe, expect, it } from 'vitest';
5
- import { importsFrom, relatedChanges } from './related-changes.js';
6
- import { rankChangedFunctions } from './risk.js';
7
- let dir;
8
- const write = (file, body) => {
9
- fs.mkdirSync(path.dirname(path.join(dir, file)), { recursive: true });
10
- fs.writeFileSync(path.join(dir, file), body);
11
- };
12
- beforeEach(() => { dir = fs.mkdtempSync(path.join(os.tmpdir(), 'related-')); });
13
- afterEach(() => { fs.rmSync(dir, { recursive: true, force: true }); });
14
- describe('relatedChanges', () => {
15
- it('links a changed function to another changed file that imports and calls it, never tests or same-named functions', () => {
16
- write('src/billing/price.ts', 'export function priceOf(row) {\n return row.currency;\n}\n');
17
- write('src/billing/invoice.ts', "import { priceOf } from './price';\n\nexport function invoice(row) {\n return { cur: 'USD', price: priceOf(row) };\n}\n");
18
- write('src/billing/price.test.ts', "import { priceOf } from './price';\npriceOf({});\n");
19
- write('src/other/price.ts', 'export function priceOf(x) {\n return 1;\n}\n');
20
- write('src/other/use.ts', "import { priceOf } from './price';\nexport const y = () => priceOf(2);\n");
21
- const focus = { 'src/billing/price.ts': [2], 'src/billing/invoice.ts': [4], 'src/billing/price.test.ts': [2], 'src/other/use.ts': [2] };
22
- const links = relatedChanges(dir, Object.keys(focus), rankChangedFunctions(dir, focus));
23
- expect(links).toEqual([{ callee: 'priceOf', calleeFile: 'src/billing/price.ts', calleeLine: 1, callerFile: 'src/billing/invoice.ts', callerLine: 4 }]);
24
- });
25
- });
26
- describe('importsFrom', () => {
27
- it('resolves relative and aliased module paths', () => {
28
- expect(importsFrom("import { a, b } from '../lib/x';", 'b', 'src/app/y.ts', 'src/lib/x.ts')).toBe(true);
29
- expect(importsFrom('import { b } from "@/lib/x";', 'b', 'src/app/y.ts', 'src/lib/x.ts')).toBe(true);
30
- expect(importsFrom("import { bb } from '../lib/x';", 'b', 'src/app/y.ts', 'src/lib/x.ts')).toBe(false);
31
- expect(importsFrom("import { b } from './x';", 'b', 'src/app/y.ts', 'src/lib/x.ts')).toBe(false);
32
- });
33
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,32 +0,0 @@
1
- import fs from 'fs';
2
- import os from 'os';
3
- import path from 'path';
4
- import { afterEach, describe, expect, it } from 'vitest';
5
- import { buildCodeReviewPrompt } from './code-review-prompt.js';
6
- import { exportReviewContexts } from './review-context-export.js';
7
- let dir;
8
- afterEach(() => { if (dir)
9
- fs.rmSync(dir, { recursive: true, force: true }); dir = undefined; });
10
- const DIFF = `diff --git a/src/total.ts b/src/total.ts
11
- --- a/src/total.ts
12
- +++ b/src/total.ts
13
- @@ -2,2 +2,2 @@
14
- let sum = 0;
15
- - for (let i = 0; i < items.length; i++) sum += items[i];
16
- + for (let i = 0; i <= items.length; i++) sum += items[i];
17
- `;
18
- describe('exportReviewContexts', () => {
19
- it('emits the review prompt for each changed file, with its focus lines and what the change removed', async () => {
20
- dir = fs.mkdtempSync(path.join(os.tmpdir(), 'review-context-'));
21
- fs.mkdirSync(path.join(dir, 'src'));
22
- fs.writeFileSync(path.join(dir, 'src/total.ts'), 'export function total(items: number[]) {\n let sum = 0;\n for (let i = 0; i <= items.length; i++) sum += items[i];\n return sum;\n}\n');
23
- const [context, ...rest] = await exportReviewContexts(dir, DIFF, { prBody: 'Sum the basket.' });
24
- expect(rest).toEqual([]);
25
- expect(context.file).toBe('src/total.ts');
26
- expect(context.focusLines).toEqual([3]);
27
- expect(context.prompt.startsWith(buildCodeReviewPrompt({ file: '', language: '', text: '', ranges: [], source: '' }).slice(0, 60))).toBe(true);
28
- expect(context.prompt).toContain('3| for (let i = 0; i <= items.length; i++) sum += items[i];');
29
- expect(context.prompt).toContain('- for (let i = 0; i < items.length; i++) sum += items[i];');
30
- expect(context.prompt).toContain('Sum the basket.');
31
- });
32
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,39 +0,0 @@
1
- import { execFileSync } from 'child_process';
2
- import fs from 'fs';
3
- import os from 'os';
4
- import path from 'path';
5
- import { afterEach, beforeEach, describe, expect, it } from 'vitest';
6
- import { ReviewToolbox } from './review-tools.js';
7
- let repo;
8
- const call = (name, args) => ({ id: 'c1', name, arguments: args });
9
- beforeEach(() => {
10
- repo = fs.mkdtempSync(path.join(os.tmpdir(), 'review-tools-'));
11
- fs.mkdirSync(path.join(repo, 'src'));
12
- fs.writeFileSync(path.join(repo, 'src/a.ts'), Array.from({ length: 300 }, (_, i) => `const v${i + 1} = ${i + 1};`).join('\n'));
13
- fs.writeFileSync(path.join(repo, '.env'), 'API_KEY=secret');
14
- execFileSync('git', ['init', '-q'], { cwd: repo });
15
- execFileSync('git', ['add', '-A'], { cwd: repo });
16
- });
17
- afterEach(() => { fs.rmSync(repo, { recursive: true, force: true }); });
18
- describe('ReviewToolbox', () => {
19
- it('reads numbered lines, caps a call at 200 lines, and records what was read', () => {
20
- const tools = new ReviewToolbox(repo);
21
- const out = tools.run(call('read_file', { path: 'src/a.ts', start_line: 10, end_line: 900 }));
22
- expect(out).toContain('src/a.ts lines 10-209 of 300');
23
- expect(out).toContain(' 10| const v10 = 10;');
24
- expect(tools.reads.get('src/a.ts')).toEqual([[10, 209]]);
25
- expect(tools.readText).toContain('const v209');
26
- });
27
- it('refuses paths outside the repository and secrets files, without throwing', () => {
28
- const tools = new ReviewToolbox(repo);
29
- expect(tools.run(call('read_file', { path: '../../etc/passwd' }))).toMatch(/^Error:/);
30
- expect(tools.run(call('read_file', { path: '.env' }))).toBe('Error: this file is not readable by the reviewer');
31
- expect(tools.reads.size).toBe(0);
32
- });
33
- it('greps tracked files but never shows a secrets file', () => {
34
- const tools = new ReviewToolbox(repo);
35
- expect(tools.run(call('grep', { pattern: 'v12 =' }))).toBe('src/a.ts:12:const v12 = 12;');
36
- expect(tools.run(call('grep', { pattern: 'API_KEY' }))).toBe('No matches.');
37
- expect(tools.run(call('shell', {}))).toBe('Unknown tool "shell".');
38
- });
39
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,101 +0,0 @@
1
- import fs from 'fs';
2
- import os from 'os';
3
- import path from 'path';
4
- import { afterEach, beforeEach, describe, expect, it } from 'vitest';
5
- import { functionHash, rankChangedFunctions, scoreRisk } from './risk.js';
6
- import { DEFAULT_MIN_SCORE, routeFiles } from './router.js';
7
- let dir;
8
- beforeEach(() => { dir = fs.mkdtempSync(path.join(os.tmpdir(), 'risk-')); });
9
- afterEach(() => { fs.rmSync(dir, { recursive: true, force: true }); });
10
- const SYNC = [
11
- 'export async function syncOrders(db, cursor) {', // 1
12
- ' for (const page of pages(cursor)) {', // 2
13
- ' if (page.rows.length) {', // 3
14
- " await db.from('orders').upsert(page.rows);", // 4
15
- ' }', // 5
16
- ' }', // 6
17
- '}', // 7
18
- 'function label(name) {', // 8
19
- ' return name.trim();', // 9
20
- '}', // 10
21
- ].join('\n');
22
- const plain = { exported: false, async: false, nesting: 0, lines: 3, removedGuard: false, sensitive: [] };
23
- describe('rankChangedFunctions', () => {
24
- it('reads the signals of each changed function', () => {
25
- fs.writeFileSync(path.join(dir, 'sync.ts'), SYNC);
26
- const ranked = rankChangedFunctions(dir, { 'sync.ts': [4, 9] }, { 'sync.ts': [{ line: 4, text: [' if (!page.ok) return;'] }] });
27
- const byName = Object.fromEntries(ranked.map(f => [f.name, f]));
28
- expect(byName.syncOrders.signals).toEqual({
29
- exported: true, async: true, nesting: 2, lines: 7, removedGuard: true, sensitive: ['data-write', 'paging'],
30
- });
31
- expect(byName.label.signals).toMatchObject({ exported: false, async: false, nesting: 0, removedGuard: false, sensitive: [] });
32
- expect([byName.label.start, byName.label.end]).toEqual([8, 10]);
33
- });
34
- });
35
- describe('test files', () => {
36
- it('are never routed, however their fixtures read', () => {
37
- fs.mkdirSync(path.join(dir, '__tests__'));
38
- for (const file of ['sync.test.ts', 'sync.spec.js', '__tests__/sync.ts'])
39
- fs.writeFileSync(path.join(dir, file), SYNC);
40
- expect(rankChangedFunctions(dir, { 'sync.test.ts': [4], 'sync.spec.js': [4], '__tests__/sync.ts': [4] })).toEqual([]);
41
- });
42
- });
43
- describe('team lessons as a risk signal', () => {
44
- const lesson = (over) => ({
45
- id: 'l1', text: 'Trim before comparing names.', file: 'sync.ts', symbols: ['trimStart'], state: 'verified',
46
- evidence: [{ pr: 1, comment: 'c', author: 'r' }], createdAt: '', updatedAt: '', ...over,
47
- });
48
- const LABEL = 'function label(name) {\n return name.trimStart();\n}\n';
49
- it('makes a plain function risky when a lesson for its file names a symbol it uses', () => {
50
- fs.writeFileSync(path.join(dir, 'sync.ts'), LABEL);
51
- const [f] = rankChangedFunctions(dir, { 'sync.ts': [2] }, {}, [lesson({})]);
52
- expect(f.signals.lesson).toBe('Trim before comparing names.');
53
- expect(f.score).toBeGreaterThanOrEqual(DEFAULT_MIN_SCORE);
54
- });
55
- it('ignores lessons for other files and lessons naming only common words', () => {
56
- fs.writeFileSync(path.join(dir, 'sync.ts'), LABEL);
57
- const other = rankChangedFunctions(dir, { 'sync.ts': [2] }, {}, [lesson({ file: 'other.ts' }), lesson({ symbols: ['name'] })]);
58
- expect(other[0].signals.lesson).toBeUndefined();
59
- expect(other[0].score).toBe(0);
60
- });
61
- });
62
- describe('scoreRisk', () => {
63
- it('ranks a data write behind a removed guard above a plain helper', () => {
64
- const risky = { exported: true, async: true, nesting: 2, lines: 30, removedGuard: true, sensitive: ['data-write', 'paging'] };
65
- expect(scoreRisk(risky)).toBeGreaterThan(scoreRisk(plain));
66
- });
67
- it('gives a short, flat, private, non-sensitive function no model review', () => {
68
- expect(scoreRisk(plain)).toBe(0);
69
- });
70
- it('never scores below zero', () => {
71
- expect(scoreRisk({ ...plain, lines: 1 })).toBeGreaterThanOrEqual(0);
72
- });
73
- });
74
- describe('routeFiles', () => {
75
- it('always keeps files it cannot rank, and reports what it left to the gates', () => {
76
- fs.writeFileSync(path.join(dir, 'helper.ts'), 'function label(name) {\n return name.trim();\n}\n');
77
- fs.writeFileSync(path.join(dir, 'query.py'), 'def f():\n return 1\n');
78
- const routed = routeFiles(dir, ['helper.ts', 'query.py'], { 'helper.ts': [2], 'query.py': [2] }, {}, { min_score: 1 });
79
- expect([...routed.files]).toEqual(['query.py']);
80
- expect(routed.stats).toEqual({ functions: 1, routed: 0, files_skipped: 1, already_reviewed: 0 });
81
- });
82
- it('skips a risky function reviewed before at exactly this code, and only that code', () => {
83
- fs.writeFileSync(path.join(dir, 'sync.ts'), SYNC);
84
- const [risky] = rankChangedFunctions(dir, { 'sync.ts': [4] });
85
- const cleared = routeFiles(dir, ['sync.ts'], { 'sync.ts': [4] }, {}, {}, [{ file: 'sync.ts', function: 'syncOrders', hash: risky.hash }]);
86
- expect(cleared.stats).toMatchObject({ routed: 0, already_reviewed: 1, files_skipped: 1 });
87
- const stale = routeFiles(dir, ['sync.ts'], { 'sync.ts': [4] }, {}, {}, [{ file: 'sync.ts', function: 'syncOrders', hash: 'old' }]);
88
- expect(stale.stats).toMatchObject({ routed: 1, already_reviewed: 0 });
89
- });
90
- });
91
- describe('functionHash', () => {
92
- it('changes when anything inside the function changes, strings included', () => {
93
- const a = 'function f() { return "a b"; }';
94
- const b = 'function f() { return "a b"; }';
95
- expect(functionHash(a)).not.toBe(functionHash(b));
96
- expect(functionHash('function f() { return `x ${y}`; }')).not.toBe(functionHash('function f() { return `x ${y}`; }'));
97
- });
98
- it('treats a Windows checkout of the same code as the same code', () => {
99
- expect(functionHash('function f() {\r\n return 1;\r\n}')).toBe(functionHash('function f() {\n return 1;\n}'));
100
- });
101
- });
@@ -1 +0,0 @@
1
- export {};