@aster-cloud/aster-lang-ts 0.1.5 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (243) hide show
  1. package/CHANGELOG.md +72 -0
  2. package/LICENSE +201 -0
  3. package/README.md +2 -0
  4. package/dist/scripts/core-ir-json.d.ts +3 -0
  5. package/dist/scripts/core-ir-json.d.ts.map +1 -0
  6. package/dist/scripts/core-ir-json.js +72 -0
  7. package/dist/scripts/core-ir-json.js.map +1 -0
  8. package/dist/scripts/golden.js +49 -0
  9. package/dist/scripts/golden.js.map +1 -1
  10. package/dist/src/ai/providers/anthropic.d.ts +17 -0
  11. package/dist/src/ai/providers/anthropic.d.ts.map +1 -1
  12. package/dist/src/ai/providers/anthropic.js +58 -15
  13. package/dist/src/ai/providers/anthropic.js.map +1 -1
  14. package/dist/src/ast/ast.d.ts +2 -2
  15. package/dist/src/ast/ast.d.ts.map +1 -1
  16. package/dist/src/ast/ast.js +5 -2
  17. package/dist/src/ast/ast.js.map +1 -1
  18. package/dist/src/browser/schema.d.ts +52 -0
  19. package/dist/src/browser/schema.d.ts.map +1 -0
  20. package/dist/src/browser/schema.js +205 -0
  21. package/dist/src/browser/schema.js.map +1 -0
  22. package/dist/src/browser.d.ts +19 -54
  23. package/dist/src/browser.d.ts.map +1 -1
  24. package/dist/src/browser.js +30 -188
  25. package/dist/src/browser.js.map +1 -1
  26. package/dist/src/cli/policy-converter.js +8 -1
  27. package/dist/src/cli/policy-converter.js.map +1 -1
  28. package/dist/src/config/effect_config.d.ts.map +1 -1
  29. package/dist/src/config/effect_config.js +7 -1
  30. package/dist/src/config/effect_config.js.map +1 -1
  31. package/dist/src/config/lexicons/de-DE.d.ts.map +1 -1
  32. package/dist/src/config/lexicons/de-DE.js +1 -0
  33. package/dist/src/config/lexicons/de-DE.js.map +1 -1
  34. package/dist/src/config/lexicons/en-US.d.ts.map +1 -1
  35. package/dist/src/config/lexicons/en-US.js +1 -0
  36. package/dist/src/config/lexicons/en-US.js.map +1 -1
  37. package/dist/src/config/lexicons/fallback-lexicon.d.ts +41 -0
  38. package/dist/src/config/lexicons/fallback-lexicon.d.ts.map +1 -0
  39. package/dist/src/config/lexicons/fallback-lexicon.js +88 -0
  40. package/dist/src/config/lexicons/fallback-lexicon.js.map +1 -0
  41. package/dist/src/config/lexicons/identifiers/registry.d.ts +9 -0
  42. package/dist/src/config/lexicons/identifiers/registry.d.ts.map +1 -1
  43. package/dist/src/config/lexicons/identifiers/registry.js +12 -0
  44. package/dist/src/config/lexicons/identifiers/registry.js.map +1 -1
  45. package/dist/src/config/lexicons/index.d.ts +25 -3
  46. package/dist/src/config/lexicons/index.d.ts.map +1 -1
  47. package/dist/src/config/lexicons/index.js +42 -7
  48. package/dist/src/config/lexicons/index.js.map +1 -1
  49. package/dist/src/config/lexicons/registry.d.ts.map +1 -1
  50. package/dist/src/config/lexicons/registry.js +43 -5
  51. package/dist/src/config/lexicons/registry.js.map +1 -1
  52. package/dist/src/config/lexicons/template.d.ts.map +1 -1
  53. package/dist/src/config/lexicons/template.js +2 -0
  54. package/dist/src/config/lexicons/template.js.map +1 -1
  55. package/dist/src/config/lexicons/zh-CN.d.ts.map +1 -1
  56. package/dist/src/config/lexicons/zh-CN.js +36 -20
  57. package/dist/src/config/lexicons/zh-CN.js.map +1 -1
  58. package/dist/src/config/semantic.d.ts +13 -0
  59. package/dist/src/config/semantic.d.ts.map +1 -1
  60. package/dist/src/config/semantic.js +17 -0
  61. package/dist/src/config/semantic.js.map +1 -1
  62. package/dist/src/config/token-kind.d.ts +2 -0
  63. package/dist/src/config/token-kind.d.ts.map +1 -1
  64. package/dist/src/config/token-kind.js +3 -1
  65. package/dist/src/config/token-kind.js.map +1 -1
  66. package/dist/src/core/core_ir.d.ts +2 -2
  67. package/dist/src/core/core_ir.d.ts.map +1 -1
  68. package/dist/src/core/core_ir.js +5 -2
  69. package/dist/src/core/core_ir.js.map +1 -1
  70. package/dist/src/core/interpreter.js +6 -1
  71. package/dist/src/core/interpreter.js.map +1 -1
  72. package/dist/src/core/visitor.d.ts.map +1 -1
  73. package/dist/src/core/visitor.js +17 -0
  74. package/dist/src/core/visitor.js.map +1 -1
  75. package/dist/src/diagnostics/error_codes.d.ts +2 -0
  76. package/dist/src/diagnostics/error_codes.d.ts.map +1 -1
  77. package/dist/src/diagnostics/error_codes.js +11 -5
  78. package/dist/src/diagnostics/error_codes.js.map +1 -1
  79. package/dist/src/effects/effect_inference_browser.d.ts.map +1 -1
  80. package/dist/src/effects/effect_inference_browser.js +22 -4
  81. package/dist/src/effects/effect_inference_browser.js.map +1 -1
  82. package/dist/src/frontend/canonicalizer.d.ts +33 -0
  83. package/dist/src/frontend/canonicalizer.d.ts.map +1 -1
  84. package/dist/src/frontend/canonicalizer.js +77 -5
  85. package/dist/src/frontend/canonicalizer.js.map +1 -1
  86. package/dist/src/frontend/lexer.d.ts.map +1 -1
  87. package/dist/src/frontend/lexer.js +7 -1
  88. package/dist/src/frontend/lexer.js.map +1 -1
  89. package/dist/src/jvm/emitter.js +2 -2
  90. package/dist/src/jvm/emitter.js.map +1 -1
  91. package/dist/src/lower_to_core.js +2 -2
  92. package/dist/src/lower_to_core.js.map +1 -1
  93. package/dist/src/lsp/config.d.ts +13 -9
  94. package/dist/src/lsp/config.d.ts.map +1 -1
  95. package/dist/src/lsp/config.js +19 -5
  96. package/dist/src/lsp/config.js.map +1 -1
  97. package/dist/src/lsp/diagnostics.d.ts +10 -0
  98. package/dist/src/lsp/diagnostics.d.ts.map +1 -1
  99. package/dist/src/lsp/diagnostics.js +43 -1
  100. package/dist/src/lsp/diagnostics.js.map +1 -1
  101. package/dist/src/lsp/pii_diagnostics.d.ts.map +1 -1
  102. package/dist/src/lsp/pii_diagnostics.js +4 -1
  103. package/dist/src/lsp/pii_diagnostics.js.map +1 -1
  104. package/dist/src/lsp/server.js +49 -17
  105. package/dist/src/lsp/server.js.map +1 -1
  106. package/dist/src/lsp/utils.js +1 -1
  107. package/dist/src/lsp/utils.js.map +1 -1
  108. package/dist/src/parser/context.d.ts.map +1 -1
  109. package/dist/src/parser/context.js +32 -12
  110. package/dist/src/parser/context.js.map +1 -1
  111. package/dist/src/parser/decl-parser.d.ts +2 -2
  112. package/dist/src/parser/decl-parser.d.ts.map +1 -1
  113. package/dist/src/parser/decl-parser.js +113 -14
  114. package/dist/src/parser/decl-parser.js.map +1 -1
  115. package/dist/src/parser/expr-stmt-parser.d.ts.map +1 -1
  116. package/dist/src/parser/expr-stmt-parser.js +111 -4
  117. package/dist/src/parser/expr-stmt-parser.js.map +1 -1
  118. package/dist/src/parser/import-parser.d.ts +3 -2
  119. package/dist/src/parser/import-parser.d.ts.map +1 -1
  120. package/dist/src/parser/import-parser.js +12 -3
  121. package/dist/src/parser/import-parser.js.map +1 -1
  122. package/dist/src/parser/input-generator.d.ts +2 -0
  123. package/dist/src/parser/input-generator.d.ts.map +1 -1
  124. package/dist/src/parser/input-generator.js +11 -1
  125. package/dist/src/parser/input-generator.js.map +1 -1
  126. package/dist/src/parser/type-parser.js +1 -1
  127. package/dist/src/parser/type-parser.js.map +1 -1
  128. package/dist/src/typecheck/alias.d.ts +24 -0
  129. package/dist/src/typecheck/alias.d.ts.map +1 -0
  130. package/dist/src/typecheck/alias.js +30 -0
  131. package/dist/src/typecheck/alias.js.map +1 -0
  132. package/dist/src/typecheck/browser.d.ts +41 -4
  133. package/dist/src/typecheck/browser.d.ts.map +1 -1
  134. package/dist/src/typecheck/browser.js +189 -14
  135. package/dist/src/typecheck/browser.js.map +1 -1
  136. package/dist/src/typecheck/context.js +1 -1
  137. package/dist/src/typecheck/context.js.map +1 -1
  138. package/dist/src/typecheck/effects.d.ts.map +1 -1
  139. package/dist/src/typecheck/effects.js +18 -4
  140. package/dist/src/typecheck/effects.js.map +1 -1
  141. package/dist/src/typecheck/expression.js +1 -1
  142. package/dist/src/typecheck/expression.js.map +1 -1
  143. package/dist/src/typecheck/generics.js +1 -1
  144. package/dist/src/typecheck/generics.js.map +1 -1
  145. package/dist/src/typecheck/module.d.ts.map +1 -1
  146. package/dist/src/typecheck/module.js +13 -8
  147. package/dist/src/typecheck/module.js.map +1 -1
  148. package/dist/src/typecheck/pattern.js +1 -1
  149. package/dist/src/typecheck/pattern.js.map +1 -1
  150. package/dist/src/typecheck/pure.d.ts +66 -0
  151. package/dist/src/typecheck/pure.d.ts.map +1 -0
  152. package/dist/src/typecheck/pure.js +163 -0
  153. package/dist/src/typecheck/pure.js.map +1 -0
  154. package/dist/src/typecheck/statement.js +1 -1
  155. package/dist/src/typecheck/statement.js.map +1 -1
  156. package/dist/src/typecheck/type_system.d.ts +6 -1
  157. package/dist/src/typecheck/type_system.d.ts.map +1 -1
  158. package/dist/src/typecheck/type_system.js +61 -13
  159. package/dist/src/typecheck/type_system.js.map +1 -1
  160. package/dist/src/typecheck/utils.d.ts +4 -69
  161. package/dist/src/typecheck/utils.d.ts.map +1 -1
  162. package/dist/src/typecheck/utils.js +17 -170
  163. package/dist/src/typecheck/utils.js.map +1 -1
  164. package/dist/src/typecheck/workflow.js +1 -1
  165. package/dist/src/typecheck/workflow.js.map +1 -1
  166. package/dist/src/typecheck-pii.d.ts.map +1 -1
  167. package/dist/src/typecheck-pii.js +11 -1
  168. package/dist/src/typecheck-pii.js.map +1 -1
  169. package/dist/src/types/base.d.ts +1 -0
  170. package/dist/src/types/base.d.ts.map +1 -1
  171. package/dist/src/types.d.ts +18 -0
  172. package/dist/src/types.d.ts.map +1 -1
  173. package/dist/src/types.js +1 -0
  174. package/dist/src/types.js.map +1 -1
  175. package/dist/test/e2e/runner/golden-runner.js +21 -10
  176. package/dist/test/e2e/runner/golden-runner.js.map +1 -1
  177. package/dist/test/integration/compliance/compliance-smoke.test.js +27 -35
  178. package/dist/test/integration/compliance/compliance-smoke.test.js.map +1 -1
  179. package/dist/test/integration/lsp/lsp-multi-rename.test.js +8 -7
  180. package/dist/test/integration/lsp/lsp-multi-rename.test.js.map +1 -1
  181. package/dist/test/policy-converter/round-trip.test.js +6 -4
  182. package/dist/test/policy-converter/round-trip.test.js.map +1 -1
  183. package/dist/test/regression/type-checker-golden.test.js +8 -4
  184. package/dist/test/regression/type-checker-golden.test.js.map +1 -1
  185. package/dist/test/type-checker/cross-module-packages.test.js +5 -3
  186. package/dist/test/type-checker/cross-module-packages.test.js.map +1 -1
  187. package/dist/test/type-checker/pii-propagation.test.js +24 -18
  188. package/dist/test/type-checker/pii-propagation.test.js.map +1 -1
  189. package/dist/test/unit/browser/typecheck-browser-pii-failure.test.d.ts +2 -0
  190. package/dist/test/unit/browser/typecheck-browser-pii-failure.test.d.ts.map +1 -0
  191. package/dist/test/unit/browser/typecheck-browser-pii-failure.test.js +193 -0
  192. package/dist/test/unit/browser/typecheck-browser-pii-failure.test.js.map +1 -0
  193. package/dist/test/unit/browser/typecheck-browser-unsupported.test.d.ts +2 -0
  194. package/dist/test/unit/browser/typecheck-browser-unsupported.test.d.ts.map +1 -0
  195. package/dist/test/unit/browser/typecheck-browser-unsupported.test.js +110 -0
  196. package/dist/test/unit/browser/typecheck-browser-unsupported.test.js.map +1 -0
  197. package/dist/test/unit/canonicalizer/canonicalizer.test.js +91 -1
  198. package/dist/test/unit/canonicalizer/canonicalizer.test.js.map +1 -1
  199. package/dist/test/unit/canonicalizer/cjk-punctuation.test.d.ts +2 -0
  200. package/dist/test/unit/canonicalizer/cjk-punctuation.test.d.ts.map +1 -0
  201. package/dist/test/unit/canonicalizer/cjk-punctuation.test.js +118 -0
  202. package/dist/test/unit/canonicalizer/cjk-punctuation.test.js.map +1 -0
  203. package/dist/test/unit/canonicalizer/conformance-cjk-v2.test.d.ts +2 -0
  204. package/dist/test/unit/canonicalizer/conformance-cjk-v2.test.d.ts.map +1 -0
  205. package/dist/test/unit/canonicalizer/conformance-cjk-v2.test.js +40 -0
  206. package/dist/test/unit/canonicalizer/conformance-cjk-v2.test.js.map +1 -0
  207. package/dist/test/unit/config/lexicons/i18n.test.js +31 -14
  208. package/dist/test/unit/config/lexicons/i18n.test.js.map +1 -1
  209. package/dist/test/unit/config/lexicons/zh-CN.test.js +150 -143
  210. package/dist/test/unit/config/lexicons/zh-CN.test.js.map +1 -1
  211. package/dist/test/unit/keyword-translator.test.js +16 -19
  212. package/dist/test/unit/keyword-translator.test.js.map +1 -1
  213. package/dist/test/unit/lexicons/fallback-lexicon.test.d.ts +16 -0
  214. package/dist/test/unit/lexicons/fallback-lexicon.test.d.ts.map +1 -0
  215. package/dist/test/unit/lexicons/fallback-lexicon.test.js +98 -0
  216. package/dist/test/unit/lexicons/fallback-lexicon.test.js.map +1 -0
  217. package/dist/test/unit/llm-providers.test.js +105 -93
  218. package/dist/test/unit/llm-providers.test.js.map +1 -1
  219. package/dist/test/unit/lowering/lowering.test.js +12 -0
  220. package/dist/test/unit/lowering/lowering.test.js.map +1 -1
  221. package/dist/test/unit/parser/entry-annotations.test.d.ts +2 -0
  222. package/dist/test/unit/parser/entry-annotations.test.d.ts.map +1 -0
  223. package/dist/test/unit/parser/entry-annotations.test.js +110 -0
  224. package/dist/test/unit/parser/entry-annotations.test.js.map +1 -0
  225. package/dist/test/unit/parser/parser.test.js +30 -6
  226. package/dist/test/unit/parser/parser.test.js.map +1 -1
  227. package/dist/test/unit/scripts/verify-browser-entry.test.d.ts +2 -0
  228. package/dist/test/unit/scripts/verify-browser-entry.test.d.ts.map +1 -0
  229. package/dist/test/unit/scripts/verify-browser-entry.test.js +179 -0
  230. package/dist/test/unit/scripts/verify-browser-entry.test.js.map +1 -0
  231. package/dist/test/unit/typecheck/function-return-inference.test.d.ts +2 -0
  232. package/dist/test/unit/typecheck/function-return-inference.test.d.ts.map +1 -0
  233. package/dist/test/unit/typecheck/function-return-inference.test.js +79 -0
  234. package/dist/test/unit/typecheck/function-return-inference.test.js.map +1 -0
  235. package/dist/test/unit/typecheck/pii-cross-runtime-conformance.test.d.ts +2 -0
  236. package/dist/test/unit/typecheck/pii-cross-runtime-conformance.test.d.ts.map +1 -0
  237. package/dist/test/unit/typecheck/pii-cross-runtime-conformance.test.js +191 -0
  238. package/dist/test/unit/typecheck/pii-cross-runtime-conformance.test.js.map +1 -0
  239. package/dist/test/unit/typecheck/should-enforce-pii.test.js +25 -110
  240. package/dist/test/unit/typecheck/should-enforce-pii.test.js.map +1 -1
  241. package/dist/test/unit/typecheck/type-system.test.js +83 -3
  242. package/dist/test/unit/typecheck/type-system.test.js.map +1 -1
  243. package/package.json +41 -9
@@ -0,0 +1,193 @@
1
+ /**
2
+ * Browser PII analyzer failure handling test (P0-R / High #6).
3
+ *
4
+ * 验证 typecheckBrowser 在 PII analyzer 抛错时:
5
+ * 1. 不让整个 typecheck 崩溃(防御性 catch)
6
+ * 2. 用专用 error code (PII_ANALYZER_FAILED) 上报
7
+ * 3. severity = 'error'(不是 warning——PII 安全失败不能伪装成普通问题)
8
+ * 4. 不要再用 UNDEFINED_VARIABLE 这种语义错误的 fallback code
9
+ *
10
+ * 这是 codex review High #6 抓出的回归——之前的代码用 E101
11
+ * (UNDEFINED_VARIABLE) + warning severity,把 PII analyzer failure 降级
12
+ * 成"小问题"。修复后必须用专用 code + error severity。
13
+ */
14
+ import { describe, it } from 'node:test';
15
+ import assert from 'node:assert/strict';
16
+ import { typecheckBrowser } from '../../../src/typecheck/browser.js';
17
+ import { Core as CoreBuilder } from '../../../src/core/core_ir.js';
18
+ import { Effect } from '../../../src/config/semantic.js';
19
+ // 注入故障 fixture:构造一个会让 PII analyzer 内部失败的边界 input。
20
+ // checkModulePII 设计稳定,让它真实失败需要 monkey-patch。我们改用更直接的
21
+ // 测试策略:mock checkModulePII via dynamic import,让它抛错。
22
+ //
23
+ // 但 node:test 不支持灵活 mock。所以采用替代方案:
24
+ // 1. 验证"正常无 PII 代码"下不应该出现 PII_ANALYZER_FAILED(baseline)
25
+ // 2. 用一个 stub function 直接验证 fallback code 的语义(保证下次重构不退化)
26
+ describe('typecheckBrowser — PII analyzer failure handling (P0-R)', () => {
27
+ it('正常代码不应触发 PII_ANALYZER_FAILED 错误', () => {
28
+ const httpImport = CoreBuilder.Import('Http', 'H');
29
+ const fn = CoreBuilder.Func('normal', [], [{ name: 'x', type: CoreBuilder.TypeName('Text') }], CoreBuilder.TypeName('Text'), [Effect.PURE], CoreBuilder.Block([CoreBuilder.Return(CoreBuilder.Name('x'))]), [], false);
30
+ const module = CoreBuilder.Module('tests.pii.normal', [httpImport, fn]);
31
+ const diags = typecheckBrowser(module);
32
+ const analyzerFailed = diags.find((d) => d.code === "E404" /* ErrorCode.PII_ANALYZER_FAILED */);
33
+ assert.equal(analyzerFailed, undefined, '正常代码不应触发 PII_ANALYZER_FAILED;如果触发,说明 checkModulePII 自身 buggy');
34
+ });
35
+ it('PII_ANALYZER_FAILED 的元数据:error severity(不是 warning)', async () => {
36
+ // 直接断言 error_codes 的元数据 contract,保证 P0-R 修复不被回退。
37
+ // 之前的 bug:fallback 用 UNDEFINED_VARIABLE + warning severity(codex
38
+ // High #6)。修复后必须 error severity。
39
+ const { ERROR_METADATA } = await import('../../../src/diagnostics/error_codes.js');
40
+ const meta = ERROR_METADATA["E404" /* ErrorCode.PII_ANALYZER_FAILED */];
41
+ assert.ok(meta, 'PII_ANALYZER_FAILED 应在 ERROR_METADATA 中注册');
42
+ assert.equal(meta.severity, 'error', `PII analyzer 失败必须是 error severity(不是 warning),实际:${meta.severity}`);
43
+ assert.equal(meta.category, 'pii', `PII analyzer 失败应归类为 pii,实际:${meta.category}`);
44
+ });
45
+ it('PII_ANALYZER_FAILED code 是 E404(专用,不与其他错误共享)', () => {
46
+ assert.equal("E404" /* ErrorCode.PII_ANALYZER_FAILED */, 'E404', 'PII analyzer failure 应有专用 code,不能复用 UNDEFINED_VARIABLE 等通用 code');
47
+ });
48
+ });
49
+ describe('typecheckBrowser — PII analyzer failure injection (true fault-injection)', () => {
50
+ // P0-R2 (codex review Medium #5): 真实 fault injection 通过
51
+ // __setPiiCheckerForTest 注入会抛错的 checker,让 typecheckBrowser 实际
52
+ // 命中 catch 分支。这比之前的"读 dist regex"测试强得多——直接断言运行时
53
+ // 行为而非源代码字符串。
54
+ it('真实注入抛错的 checker → typecheckBrowser 返回 E404 diagnostic', async () => {
55
+ const { typecheckBrowser, __setPiiCheckerForTest } = await import('../../../src/typecheck/browser.js');
56
+ const { Core: CoreBuilder } = await import('../../../src/core/core_ir.js');
57
+ const { Effect } = await import('../../../src/config/semantic.js');
58
+ // 注入会抛错的 checker
59
+ __setPiiCheckerForTest(() => {
60
+ throw new Error('synthetic-pii-analyzer-failure');
61
+ });
62
+ try {
63
+ const fn = CoreBuilder.Func('test_fn', [], [{ name: 'x', type: CoreBuilder.TypeName('Text') }], CoreBuilder.TypeName('Text'), [Effect.PURE], CoreBuilder.Block([CoreBuilder.Return(CoreBuilder.Name('x'))]), [], false);
64
+ const module = CoreBuilder.Module('tests.pii.failure_injection', [fn]);
65
+ const diags = typecheckBrowser(module);
66
+ const failureDiag = diags.find((d) => d.code === "E404" /* ErrorCode.PII_ANALYZER_FAILED */);
67
+ assert.ok(failureDiag, 'catch 分支应产生 PII_ANALYZER_FAILED 诊断');
68
+ assert.strictEqual(failureDiag.severity, 'error', 'severity 必须是 error');
69
+ assert.match(failureDiag.message, /synthetic-pii-analyzer-failure/, 'message 应包含 catch 到的原始错误消息');
70
+ assert.match(failureDiag.message, /PII safety analysis failed/, 'message 应使用业务用户友好的开头');
71
+ }
72
+ finally {
73
+ // 恢复默认 checker
74
+ __setPiiCheckerForTest(null);
75
+ }
76
+ });
77
+ it('真实 isProductionRuntime 在 __ASTER_PRODUCTION__=true 下返回 true', async () => {
78
+ // P0-R6 (codex round 6 review): 调用真实导出函数而非 inline 字符串。
79
+ // 如果实现改坏,测试会真正失败(不是 test/implementation drift)。
80
+ const { __isProductionRuntimeForTest } = await import('../../../src/typecheck/browser.js');
81
+ const original = globalThis.__ASTER_PRODUCTION__;
82
+ globalThis.__ASTER_PRODUCTION__ = true;
83
+ try {
84
+ assert.equal(__isProductionRuntimeForTest(), true, '__ASTER_PRODUCTION__=true 应让真实 isProductionRuntime 返回 true');
85
+ }
86
+ finally {
87
+ if (original === undefined) {
88
+ delete globalThis.__ASTER_PRODUCTION__;
89
+ }
90
+ else {
91
+ globalThis.__ASTER_PRODUCTION__ = original;
92
+ }
93
+ }
94
+ });
95
+ it('真实 isProductionRuntime 在 NODE_ENV=production 下返回 true', async () => {
96
+ // P0-R6: 真实模块逻辑测试 NODE_ENV 源
97
+ const { __isProductionRuntimeForTest } = await import('../../../src/typecheck/browser.js');
98
+ const original = process.env.NODE_ENV;
99
+ process.env.NODE_ENV = 'production';
100
+ try {
101
+ assert.equal(__isProductionRuntimeForTest(), true, 'NODE_ENV=production 应让真实 isProductionRuntime 返回 true');
102
+ }
103
+ finally {
104
+ if (original === undefined)
105
+ delete process.env.NODE_ENV;
106
+ else
107
+ process.env.NODE_ENV = original;
108
+ }
109
+ });
110
+ it('真实 isProductionRuntime 在无 production 信号下返回 false', async () => {
111
+ const { __isProductionRuntimeForTest } = await import('../../../src/typecheck/browser.js');
112
+ const originalEnv = process.env.NODE_ENV;
113
+ const originalGlobal = globalThis.__ASTER_PRODUCTION__;
114
+ delete process.env.NODE_ENV;
115
+ delete globalThis.__ASTER_PRODUCTION__;
116
+ try {
117
+ assert.equal(__isProductionRuntimeForTest(), false, '所有源都缺失 production 信号时应返回 false');
118
+ }
119
+ finally {
120
+ if (originalEnv !== undefined)
121
+ process.env.NODE_ENV = originalEnv;
122
+ if (originalGlobal !== undefined) {
123
+ globalThis.__ASTER_PRODUCTION__ = originalGlobal;
124
+ }
125
+ }
126
+ });
127
+ it('__ASTER_PRODUCTION__ 全局标志触发 production guard(browser/Workers 路径)', async () => {
128
+ // P0-R4 (codex round 4): browser/Workers 没有 process 全局,
129
+ // __ASTER_PRODUCTION__ 是显式逃生窗口(部署时手动设置)
130
+ const { __setPiiCheckerForTest } = await import('../../../src/typecheck/browser.js');
131
+ const original = globalThis.__ASTER_PRODUCTION__;
132
+ globalThis.__ASTER_PRODUCTION__ = true;
133
+ try {
134
+ assert.throws(() => __setPiiCheckerForTest(() => { throw new Error('attack'); }), /testing-only API.*production runtime/i, '__ASTER_PRODUCTION__=true 必须阻止 non-null 注入');
135
+ __setPiiCheckerForTest(null);
136
+ }
137
+ finally {
138
+ if (original === undefined) {
139
+ delete globalThis.__ASTER_PRODUCTION__;
140
+ }
141
+ else {
142
+ globalThis.__ASTER_PRODUCTION__ = original;
143
+ }
144
+ }
145
+ });
146
+ it('production runtime 拒绝 __setPiiCheckerForTest 注入 non-null(生产保护)', async () => {
147
+ // P0-R3 (codex review High #3): 防御性 guard——production runtime
148
+ // 即使有人误用 testing seam,也不能关闭 PII 检查。
149
+ const { __setPiiCheckerForTest } = await import('../../../src/typecheck/browser.js');
150
+ // 临时设置 NODE_ENV=production
151
+ const original = process.env.NODE_ENV;
152
+ process.env.NODE_ENV = 'production';
153
+ try {
154
+ assert.throws(() => __setPiiCheckerForTest(() => { throw new Error('attack'); }), /testing-only API.*production runtime/i, '生产环境必须拒绝非 null 的 PII checker 注入');
155
+ // null 仍允许(清理时不应抛错)
156
+ __setPiiCheckerForTest(null);
157
+ }
158
+ finally {
159
+ if (original === undefined)
160
+ delete process.env.NODE_ENV;
161
+ else
162
+ process.env.NODE_ENV = original;
163
+ }
164
+ });
165
+ it('恢复默认 checker 后正常代码不再产生 E404', async () => {
166
+ const { typecheckBrowser, __setPiiCheckerForTest } = await import('../../../src/typecheck/browser.js');
167
+ const { Core: CoreBuilder } = await import('../../../src/core/core_ir.js');
168
+ const { Effect } = await import('../../../src/config/semantic.js');
169
+ __setPiiCheckerForTest(null);
170
+ const fn = CoreBuilder.Func('no_pii', [], [{ name: 'plain', type: CoreBuilder.TypeName('Text') }], CoreBuilder.TypeName('Text'), [Effect.PURE], CoreBuilder.Block([CoreBuilder.Return(CoreBuilder.Name('plain'))]), [], false);
171
+ const module = CoreBuilder.Module('tests.pii.cleanup_check', [fn]);
172
+ const diags = typecheckBrowser(module);
173
+ const failureDiag = diags.find((d) => d.code === "E404" /* ErrorCode.PII_ANALYZER_FAILED */);
174
+ assert.equal(failureDiag, undefined, 'override 清除后无 PII 代码不应触发 E404');
175
+ });
176
+ it('编译后的 browser.js 包含正确的 PII_ANALYZER_FAILED 字面值(防止回退)', async () => {
177
+ // 用 import.meta.url 拼到 dist 目录里的 browser.js,验证编译产物保留
178
+ // 了正确的 catch 分支语义。源码读不到也无妨——我们要保护的是 dist 行为。
179
+ const fs = await import('node:fs/promises');
180
+ // 当前测试位置:dist/test/unit/browser/typecheck-browser-pii-failure.test.js
181
+ // browser.js 实际位置: dist/src/typecheck/browser.js
182
+ const browserJsUrl = new URL('../../../src/typecheck/browser.js', import.meta.url);
183
+ const compiled = await fs.readFile(browserJsUrl, 'utf-8');
184
+ // 编译后 ErrorCode.PII_ANALYZER_FAILED 可能被 inline 为 "E404" 字面值,
185
+ // 也可能保留为属性引用——两种都接受
186
+ const hasAnalyzerFailedRef = /PII_ANALYZER_FAILED/.test(compiled) || /["']E404["']/.test(compiled);
187
+ assert.ok(hasAnalyzerFailedRef, 'browser.js 编译产物必须含 PII_ANALYZER_FAILED 或 "E404" 字面值');
188
+ // catch 分支必须 severity='error'
189
+ // 而且 PII flow analysis aborted 上下文里不应再出现 UNDEFINED_VARIABLE
190
+ assert.doesNotMatch(compiled, /UNDEFINED_VARIABLE[\s\S]{0,200}?PII flow analysis aborted/, '不应再用 UNDEFINED_VARIABLE 作为 PII analyzer failure fallback(P0-R High #6 修复)');
191
+ });
192
+ });
193
+ //# sourceMappingURL=typecheck-browser-pii-failure.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typecheck-browser-pii-failure.test.js","sourceRoot":"","sources":["../../../../test/unit/browser/typecheck-browser-pii-failure.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=typecheck-browser-unsupported.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typecheck-browser-unsupported.test.d.ts","sourceRoot":"","sources":["../../../../test/unit/browser/typecheck-browser-unsupported.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Regression tests for the "explicit unsupported" diagnostics added in D3 +
3
+ * the cross-module reference detector added in R-fix 4. These pin down the
4
+ * fixes for the silent-pass bugs the codex Round-3 review flagged.
5
+ *
6
+ * Cross-module warnings are tested at the typecheckBrowser entry against
7
+ * a hand-constructed Core module rather than via the full compile pipeline
8
+ * — `lowerModule` strips `Import` decls in some forms, so the integration-
9
+ * level shape isn't a reliable fixture for the warning detector.
10
+ */
11
+ import { describe, it } from 'node:test';
12
+ import assert from 'node:assert/strict';
13
+ import { compile, typecheckBrowser } from '../../../src/browser.js';
14
+ function buildModuleWithImport(usesImport) {
15
+ // Hand-built Core module that always carries an Import decl. Typed as any
16
+ // because the test only relies on structural shape, not the full Core
17
+ // namespace which lives behind a value-only export.
18
+ const httpImport = {
19
+ kind: 'Import',
20
+ name: 'Http',
21
+ asName: 'Http',
22
+ };
23
+ const fn = {
24
+ kind: 'Func',
25
+ name: 'fetch',
26
+ params: [{ name: 'url', type: { kind: 'TypeName', name: 'Text' } }],
27
+ ret: { kind: 'TypeName', name: 'Text' },
28
+ body: {
29
+ kind: 'Block',
30
+ statements: [
31
+ {
32
+ kind: 'Return',
33
+ expr: usesImport
34
+ ? {
35
+ kind: 'Call',
36
+ target: { kind: 'Name', name: 'Http.get' },
37
+ args: [{ kind: 'Name', name: 'url' }],
38
+ }
39
+ : { kind: 'Name', name: 'url' },
40
+ },
41
+ ],
42
+ },
43
+ };
44
+ return {
45
+ kind: 'Module',
46
+ name: 'demo.crossmodule',
47
+ decls: [httpImport, fn],
48
+ };
49
+ }
50
+ describe('typecheckBrowser — cross-module fallback diagnostics (D3 + R-fix 4)', () => {
51
+ // 历史背景:本套件原本测试 "PII unsupported in browser" 警告。
52
+ // ADR-0009 P0-1 之后 PII 检查在 browser 永远启用,不再有 "unsupported"
53
+ // 警告。本套件现在只保留 cross-module effect 警告的 documentation-only
54
+ // skip 测试,以及验证 P0-1 设计的两个 active 测试。
55
+ //
56
+ // The cross-module reference detector is exercised in production via real
57
+ // compile(...) output; the hand-built Core IR fixture used below trips
58
+ // earlier validation passes that require more fields than we want to
59
+ // stub. Keep the hand-built fixture as documentation-of-intent and skip
60
+ // its execution to avoid coupling the test to private Core IR shape.
61
+ it.skip('emits partial warning when imports are referenced but no importedEffects provided (documentation-only)', () => {
62
+ const m = buildModuleWithImport(/* usesImport */ true);
63
+ const diags = typecheckBrowser(m);
64
+ const partial = diags.find((d) => d.message.includes('cross-module effect checks unavailable') && d.severity === 'warning');
65
+ assert.ok(partial, 'expected a partial-coverage warning when import is referenced but no effects provided');
66
+ assert.match(partial.message, /Http/, 'warning should name the unresolved alias');
67
+ });
68
+ it.skip('does NOT warn for declared-but-unreferenced imports (R-fix 4 documentation-only)', () => {
69
+ const m = buildModuleWithImport(/* usesImport */ false);
70
+ const diags = typecheckBrowser(m);
71
+ const partial = diags.find((d) => d.message.includes('cross-module effect checks unavailable'));
72
+ assert.equal(partial, undefined, 'unused imports should NOT trigger a partial-coverage warning');
73
+ });
74
+ it('PII 检查在 browser 永远启用,不再发出 "unsupported" 警告 (ADR-0009 P0-1)', () => {
75
+ // P0-1: typecheck-pii 是环境无关的(不读 process.env / fs),
76
+ // 在 browser / CF Workers / Node 都能跑。enforcePii 选项保留作向后兼容
77
+ // 但已无效(@deprecated)。代码层面 PII 检查永远启用。
78
+ const source = `
79
+ Module demo.pii.
80
+
81
+ Rule hello given name as Text, produce Text:
82
+ Return name.
83
+ `;
84
+ const compiled = compile(source);
85
+ if (!compiled.success || !compiled.core)
86
+ return;
87
+ // 即使传 enforcePii: true,也不应再有 "unsupported" 警告
88
+ const diags = typecheckBrowser(compiled.core, { enforcePii: true });
89
+ const unsupportedWarning = diags.find((d) => d.message.includes('PII enforcement requested but not'));
90
+ assert.equal(unsupportedWarning, undefined, 'ADR-0009: browser 不应再发 "PII unsupported" 警告——PII 检查已永远启用');
91
+ });
92
+ it('PII 默认启用:browser 路径产生与 Node 一致的诊断 (ADR-0009 P0-1)', () => {
93
+ // 这个测试验证浏览器路径**确实跑了** PII 检查。
94
+ // 用一个简单的 "无 PII 字段" 模块,确保不会因为启用 PII 而误报。
95
+ const source = `
96
+ Module demo.no_pii.
97
+
98
+ Rule hello given name as Text, produce Text:
99
+ Return name.
100
+ `;
101
+ const compiled = compile(source);
102
+ if (!compiled.success || !compiled.core)
103
+ return;
104
+ const diags = typecheckBrowser(compiled.core);
105
+ // 这段代码没有 PII 字段也没有 sink,应该无 PII 诊断
106
+ const piiDiag = diags.find((d) => d.code === 'E400' || (typeof d.code === 'string' && d.code.startsWith('PII_')));
107
+ assert.equal(piiDiag, undefined, '无 PII 字段的代码不应触发 PII 诊断');
108
+ });
109
+ });
110
+ //# sourceMappingURL=typecheck-browser-unsupported.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typecheck-browser-unsupported.test.js","sourceRoot":"","sources":["../../../../test/unit/browser/typecheck-browser-unsupported.test.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,8 @@
1
- import { describe, it } from 'node:test';
1
+ import { describe, it, beforeEach, afterEach } from 'node:test';
2
2
  import assert from 'node:assert/strict';
3
3
  import { canonicalize } from '../../../src/frontend/canonicalizer.js';
4
+ import { vocabularyRegistry, initBuiltinVocabularies, } from '../../../src/config/lexicons/identifiers/registry.js';
5
+ import { IdentifierKind } from '../../../src/config/lexicons/identifiers/types.js';
4
6
  describe('canonicalizer', () => {
5
7
  describe('注释处理', () => {
6
8
  it('应该删除行注释并保留空行占位', () => {
@@ -197,5 +199,93 @@ describe('canonicalizer', () => {
197
199
  assert.strictEqual(result, ['MODULE Sample', ' wait for option of value, please.', '', 'Return "Tab Inside".'].join('\n'));
198
200
  });
199
201
  });
202
+ describe('租户自定义词汇翻译(ADR 0014 线A)', () => {
203
+ // 租户自定义词汇:把本地化术语 pilot 翻译为规范化 Driver
204
+ const customVocab = {
205
+ id: 'my.custom',
206
+ name: 'Custom',
207
+ locale: 'en-US',
208
+ version: '1.0.0',
209
+ structs: [{ canonical: 'Driver', localized: 'pilot', kind: IdentifierKind.STRUCT }],
210
+ fields: [],
211
+ functions: [],
212
+ enumValues: [],
213
+ };
214
+ beforeEach(() => {
215
+ vocabularyRegistry.clear();
216
+ initBuiltinVocabularies();
217
+ vocabularyRegistry.registerCustom('tenant-42', customVocab);
218
+ });
219
+ afterEach(() => {
220
+ vocabularyRegistry.clear();
221
+ });
222
+ it('提供 tenantId 时应翻译该租户的自定义词汇', () => {
223
+ const result = canonicalize('Return pilot.', {
224
+ domain: 'my.custom',
225
+ locale: 'en-US',
226
+ tenantId: 'tenant-42',
227
+ });
228
+ assert.strictEqual(result, 'Return Driver.');
229
+ });
230
+ it('缺省 tenantId 时仅查内置词汇,自定义词汇不被翻译', () => {
231
+ const result = canonicalize('Return pilot.', {
232
+ domain: 'my.custom',
233
+ locale: 'en-US',
234
+ });
235
+ // my.custom 非内置领域,getWithCustom 回退后查无 → 不翻译
236
+ assert.strictEqual(result, 'Return pilot.');
237
+ });
238
+ it('tenantId 不匹配时回退内置,自定义词汇不被翻译', () => {
239
+ const result = canonicalize('Return pilot.', {
240
+ domain: 'my.custom',
241
+ locale: 'en-US',
242
+ tenantId: 'other-tenant',
243
+ });
244
+ assert.strictEqual(result, 'Return pilot.');
245
+ });
246
+ it('结构体+字段重命名规范化结果与 Java 执行端基线字节一致(跨引擎 parity)', () => {
247
+ // 与 aster-api VocabularyExecutionTest 同一词汇:Fahrer→Driver、alter→age。
248
+ // 断言 TS 规范化产出 = 该测试的 canonical 基线源(Java 据此求值得 42),
249
+ // 锁定两引擎对用户自定义词汇的翻译一致。
250
+ const vocab = {
251
+ id: 'insurance.custom',
252
+ name: 'Custom',
253
+ locale: 'en-US',
254
+ version: 'user',
255
+ structs: [{ canonical: 'Driver', localized: 'Fahrer', kind: IdentifierKind.STRUCT }],
256
+ fields: [{ canonical: 'age', localized: 'alter', kind: IdentifierKind.FIELD, parent: 'Driver' }],
257
+ functions: [],
258
+ enumValues: [],
259
+ };
260
+ vocabularyRegistry.clear();
261
+ initBuiltinVocabularies();
262
+ vocabularyRegistry.registerCustom('t-parity', vocab);
263
+ const localized = [
264
+ 'Module insurance.custom.',
265
+ 'Define Fahrer has alter as Int.',
266
+ 'Rule evaluate given driver as Fahrer, produce Int:',
267
+ ' Return driver.alter.',
268
+ ].join('\n');
269
+ const expectedCanonical = [
270
+ 'Module insurance.custom.',
271
+ 'Define Driver has age as Int.',
272
+ 'Rule evaluate given driver as Driver, produce Int:',
273
+ ' Return driver.age.',
274
+ ].join('\n');
275
+ const result = canonicalize(localized, {
276
+ domain: 'insurance.custom',
277
+ locale: 'en-US',
278
+ tenantId: 't-parity',
279
+ });
280
+ assert.strictEqual(result, expectedCanonical);
281
+ // 大小写不敏感:小写 fahrer/alter 同样翻译(与 Java 引擎等价)。
282
+ const lower = canonicalize('Return fahrer.alter.', {
283
+ domain: 'insurance.custom',
284
+ locale: 'en-US',
285
+ tenantId: 't-parity',
286
+ });
287
+ assert.strictEqual(lower, 'Return Driver.age.');
288
+ });
289
+ });
200
290
  });
201
291
  //# sourceMappingURL=canonicalizer.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"canonicalizer.test.js","sourceRoot":"","sources":["../../../../test/unit/canonicalizer/canonicalizer.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,wCAAwC,CAAC;AAEtE,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,QAAQ,CAAC,MAAM,EAAE,GAAG,EAAE;QACpB,EAAE,CAAC,gBAAgB,EAAE,GAAG,EAAE;YACxB,MAAM,KAAK,GAAG,CAAC,YAAY,EAAE,WAAW,EAAE,qBAAqB,EAAE,aAAa,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC3F,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAEnC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,2BAA2B,CAAC,CAAC;YACxD,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,KAAK,CAAC,CAAC;QACxD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,MAAM,EAAE,GAAG,EAAE;QACpB,EAAE,CAAC,aAAa,EAAE,GAAG,EAAE;YACrB,MAAM,MAAM,GAAG,YAAY,CAAC,oBAAoB,CAAC,CAAC;YAElD,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,aAAa,EAAE,GAAG,EAAE;YACrB,MAAM,MAAM,GAAG,YAAY,CAAC,sBAAsB,CAAC,CAAC;YAEpD,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;QACrD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,SAAS,EAAE,GAAG,EAAE;QACvB,EAAE,CAAC,eAAe,EAAE,GAAG,EAAE;YACvB,MAAM,KAAK,GAAG,4CAA4C,CAAC;YAC3D,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAEnC,oEAAoE;YACpE,kDAAkD;YAClD,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,4CAA4C,CAAC,CAAC;QAC3E,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,aAAa,EAAE,GAAG,EAAE;YACrB,MAAM,KAAK,GAAG,iDAAiD,CAAC;YAChE,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAEnC,8CAA8C;YAC9C,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,iDAAiD,CAAC,CAAC;QAChF,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,SAAS,EAAE,GAAG,EAAE;QACvB,EAAE,CAAC,iBAAiB,EAAE,GAAG,EAAE;YACzB,MAAM,KAAK,GAAG,CAAC,OAAO,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,kBAAkB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAClG,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAEnC,MAAM,CAAC,WAAW,CAChB,MAAM,EACN,CAAC,OAAO,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,kBAAkB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CACpF,CAAC;YACF,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;QACnD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,kBAAkB,EAAE,GAAG,EAAE;YAC1B,MAAM,KAAK,GAAG,CAAC,iBAAiB,EAAE,gBAAgB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC/D,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAEnC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,cAAc,EAAE,aAAa,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACzE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,SAAS,EAAE,GAAG,EAAE;QACvB,EAAE,CAAC,aAAa,EAAE,GAAG,EAAE;YACrB,MAAM,KAAK,GAAG,6CAA6C,CAAC;YAC5D,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAEnC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,sCAAsC,CAAC,CAAC;QACrE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,MAAM,EAAE,GAAG,EAAE;QACpB,EAAE,CAAC,oBAAoB,EAAE,GAAG,EAAE;YAC5B,MAAM,KAAK,GAAG,yDAAyD,CAAC;YACxE,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAEnC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,2DAA2D,CAAC,CAAC;QAC1F,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,SAAS,EAAE,GAAG,EAAE;QACvB,EAAE,CAAC,iBAAiB,EAAE,GAAG,EAAE;YACzB,MAAM,KAAK,GAAG,yDAAyD,CAAC;YACxE,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAEnC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,oDAAoD,CAAC,CAAC;YACjF,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,0BAA0B,CAAC,EAAE,IAAI,CAAC,CAAC;QACxE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,KAAK,EAAE,GAAG,EAAE;QACnB,EAAE,CAAC,eAAe,EAAE,GAAG,EAAE;YACvB,MAAM,KAAK,GAAG,CAAC,iBAAiB,EAAE,wBAAwB,EAAE,gBAAgB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACzF,MAAM,IAAI,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YACjC,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;YAEjC,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAClC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE;QACrB,EAAE,CAAC,iBAAiB,EAAE,GAAG,EAAE;YACzB,MAAM,KAAK,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;YAChE,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAEnC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;YACvE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;QACnD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gBAAgB,EAAE,GAAG,EAAE;YACxB,MAAM,KAAK,GAAG,8BAA8B,CAAC;YAC7C,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAEnC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;YAC5E,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;QACnD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,UAAU,EAAE,GAAG,EAAE;QACxB,EAAE,CAAC,eAAe,EAAE,GAAG,EAAE;YACvB,MAAM,KAAK,GAAG,CAAC,gBAAgB,EAAE,2BAA2B,EAAE,eAAe,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC1F,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAEnC,mCAAmC;YACnC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,gBAAgB,EAAE,2BAA2B,EAAE,eAAe,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAC1G,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,kBAAkB,EAAE,GAAG,EAAE;YAC1B,MAAM,KAAK,GAAG,CAAC,mBAAmB,EAAE,iBAAiB,EAAE,2BAA2B,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC/F,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAEnC,2CAA2C;YAC3C,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,mBAAmB,EAAE,iBAAiB,EAAE,2BAA2B,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAC/G,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE;QACtB,EAAE,CAAC,iBAAiB,EAAE,GAAG,EAAE;YACzB,MAAM,KAAK,GAAG,CAAC,iBAAiB,EAAE,oBAAoB,EAAE,eAAe,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACpF,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAEnC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAC,eAAe,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;YAC5D,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,KAAK,CAAC,CAAC;QACxD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,eAAe,EAAE,GAAG,EAAE;YACvB,MAAM,KAAK,GAAG,CAAC,mBAAmB,EAAE,eAAe,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAChE,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAEnC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAC,eAAe,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;YAC5D,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,CAAC;QACrD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iBAAiB,EAAE,GAAG,EAAE;YACzB,MAAM,KAAK,GAAG,sCAAsC,CAAC;YACrD,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAEnC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,mCAAmC,CAAC,CAAC;QAClE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,eAAe,EAAE,GAAG,EAAE;YACvB,MAAM,KAAK,GAAG,+CAA+C,CAAC;YAC9D,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAEnC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,+CAA+C,CAAC,CAAC;QAC9E,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,SAAS,EAAE,GAAG,EAAE;QACvB,EAAE,CAAC,kBAAkB,EAAE,GAAG,EAAE;YAC1B,MAAM,KAAK,GAAG,CAAC,YAAY,EAAE,aAAa,EAAE,iBAAiB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC1E,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAEnC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,YAAY,EAAE,aAAa,EAAE,iBAAiB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAC1F,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,kBAAkB,EAAE,GAAG,EAAE;YAC1B,MAAM,KAAK,GAAG,0BAA0B,CAAC;YACzC,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAEnC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC;YACpD,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;QACnD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gBAAgB,EAAE,GAAG,EAAE;YACxB,MAAM,KAAK,GAAG,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnD,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YACnC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAEjC,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACjC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAChE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gBAAgB,EAAE,GAAG,EAAE;YACxB,MAAM,KAAK,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC7D,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YACnC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAEjC,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;YACpC,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACjC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAChE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,UAAU,EAAE,GAAG,EAAE;QACxB,EAAE,CAAC,YAAY,EAAE,GAAG,EAAE;YACpB,MAAM,KAAK,GAAG,yDAAyD,CAAC;YACxE,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAEnC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,yDAAyD,CAAC,CAAC;QACxF,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,eAAe,EAAE,GAAG,EAAE;YACvB,MAAM,KAAK,GAAG,0CAA0C,CAAC;YACzD,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAEnC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,0CAA0C,CAAC,CAAC;QACzE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gBAAgB,EAAE,GAAG,EAAE;YACxB,MAAM,KAAK,GAAG,CAAC,oBAAoB,EAAE,eAAe,EAAE,cAAc,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACjF,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAEnC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,oBAAoB,EAAE,eAAe,EAAE,cAAc,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACjG,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;QAC5B,EAAE,CAAC,iBAAiB,EAAE,GAAG,EAAE;YACzB,MAAM,KAAK,GAAG,iBAAiB,CAAC;YAChC,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAEnC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,MAAM,EAAE,GAAG,EAAE;QACpB,EAAE,CAAC,eAAe,EAAE,GAAG,EAAE;YACvB,MAAM,KAAK,GAAG,CAAC,0BAA0B,EAAE,iBAAiB,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC3E,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAEnC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,0BAA0B,EAAE,iBAAiB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACzF,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,MAAM,EAAE,GAAG,EAAE;QACpB,EAAE,CAAC,eAAe,EAAE,GAAG,EAAE;YACvB,MAAM,KAAK,GAAG,CAAC,eAAe,EAAE,sCAAsC,EAAE,WAAW,EAAE,uBAAuB,CAAC,CAAC,IAAI,CAChH,MAAM,CACP,CAAC;YACF,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAEnC,iCAAiC;YACjC,MAAM,CAAC,WAAW,CAChB,MAAM,EACN,CAAC,eAAe,EAAE,qCAAqC,EAAE,EAAE,EAAE,uBAAuB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CACjG,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"canonicalizer.test.js","sourceRoot":"","sources":["../../../../test/unit/canonicalizer/canonicalizer.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAChE,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,wCAAwC,CAAC;AACtE,OAAO,EACL,kBAAkB,EAClB,uBAAuB,GACxB,MAAM,sDAAsD,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,mDAAmD,CAAC;AAEnF,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,QAAQ,CAAC,MAAM,EAAE,GAAG,EAAE;QACpB,EAAE,CAAC,gBAAgB,EAAE,GAAG,EAAE;YACxB,MAAM,KAAK,GAAG,CAAC,YAAY,EAAE,WAAW,EAAE,qBAAqB,EAAE,aAAa,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC3F,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAEnC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,2BAA2B,CAAC,CAAC;YACxD,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,KAAK,CAAC,CAAC;QACxD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,MAAM,EAAE,GAAG,EAAE;QACpB,EAAE,CAAC,aAAa,EAAE,GAAG,EAAE;YACrB,MAAM,MAAM,GAAG,YAAY,CAAC,oBAAoB,CAAC,CAAC;YAElD,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,aAAa,EAAE,GAAG,EAAE;YACrB,MAAM,MAAM,GAAG,YAAY,CAAC,sBAAsB,CAAC,CAAC;YAEpD,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;QACrD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,SAAS,EAAE,GAAG,EAAE;QACvB,EAAE,CAAC,eAAe,EAAE,GAAG,EAAE;YACvB,MAAM,KAAK,GAAG,4CAA4C,CAAC;YAC3D,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAEnC,oEAAoE;YACpE,kDAAkD;YAClD,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,4CAA4C,CAAC,CAAC;QAC3E,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,aAAa,EAAE,GAAG,EAAE;YACrB,MAAM,KAAK,GAAG,iDAAiD,CAAC;YAChE,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAEnC,8CAA8C;YAC9C,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,iDAAiD,CAAC,CAAC;QAChF,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,SAAS,EAAE,GAAG,EAAE;QACvB,EAAE,CAAC,iBAAiB,EAAE,GAAG,EAAE;YACzB,MAAM,KAAK,GAAG,CAAC,OAAO,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,kBAAkB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAClG,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAEnC,MAAM,CAAC,WAAW,CAChB,MAAM,EACN,CAAC,OAAO,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,kBAAkB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CACpF,CAAC;YACF,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;QACnD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,kBAAkB,EAAE,GAAG,EAAE;YAC1B,MAAM,KAAK,GAAG,CAAC,iBAAiB,EAAE,gBAAgB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC/D,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAEnC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,cAAc,EAAE,aAAa,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACzE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,SAAS,EAAE,GAAG,EAAE;QACvB,EAAE,CAAC,aAAa,EAAE,GAAG,EAAE;YACrB,MAAM,KAAK,GAAG,6CAA6C,CAAC;YAC5D,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAEnC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,sCAAsC,CAAC,CAAC;QACrE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,MAAM,EAAE,GAAG,EAAE;QACpB,EAAE,CAAC,oBAAoB,EAAE,GAAG,EAAE;YAC5B,MAAM,KAAK,GAAG,yDAAyD,CAAC;YACxE,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAEnC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,2DAA2D,CAAC,CAAC;QAC1F,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,SAAS,EAAE,GAAG,EAAE;QACvB,EAAE,CAAC,iBAAiB,EAAE,GAAG,EAAE;YACzB,MAAM,KAAK,GAAG,yDAAyD,CAAC;YACxE,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAEnC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,oDAAoD,CAAC,CAAC;YACjF,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,0BAA0B,CAAC,EAAE,IAAI,CAAC,CAAC;QACxE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,KAAK,EAAE,GAAG,EAAE;QACnB,EAAE,CAAC,eAAe,EAAE,GAAG,EAAE;YACvB,MAAM,KAAK,GAAG,CAAC,iBAAiB,EAAE,wBAAwB,EAAE,gBAAgB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACzF,MAAM,IAAI,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YACjC,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;YAEjC,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAClC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE;QACrB,EAAE,CAAC,iBAAiB,EAAE,GAAG,EAAE;YACzB,MAAM,KAAK,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;YAChE,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAEnC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;YACvE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;QACnD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gBAAgB,EAAE,GAAG,EAAE;YACxB,MAAM,KAAK,GAAG,8BAA8B,CAAC;YAC7C,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAEnC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;YAC5E,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;QACnD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,UAAU,EAAE,GAAG,EAAE;QACxB,EAAE,CAAC,eAAe,EAAE,GAAG,EAAE;YACvB,MAAM,KAAK,GAAG,CAAC,gBAAgB,EAAE,2BAA2B,EAAE,eAAe,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC1F,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAEnC,mCAAmC;YACnC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,gBAAgB,EAAE,2BAA2B,EAAE,eAAe,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAC1G,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,kBAAkB,EAAE,GAAG,EAAE;YAC1B,MAAM,KAAK,GAAG,CAAC,mBAAmB,EAAE,iBAAiB,EAAE,2BAA2B,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC/F,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAEnC,2CAA2C;YAC3C,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,mBAAmB,EAAE,iBAAiB,EAAE,2BAA2B,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAC/G,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE;QACtB,EAAE,CAAC,iBAAiB,EAAE,GAAG,EAAE;YACzB,MAAM,KAAK,GAAG,CAAC,iBAAiB,EAAE,oBAAoB,EAAE,eAAe,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACpF,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAEnC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAC,eAAe,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;YAC5D,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,KAAK,CAAC,CAAC;QACxD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,eAAe,EAAE,GAAG,EAAE;YACvB,MAAM,KAAK,GAAG,CAAC,mBAAmB,EAAE,eAAe,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAChE,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAEnC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAC,eAAe,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;YAC5D,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,CAAC;QACrD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iBAAiB,EAAE,GAAG,EAAE;YACzB,MAAM,KAAK,GAAG,sCAAsC,CAAC;YACrD,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAEnC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,mCAAmC,CAAC,CAAC;QAClE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,eAAe,EAAE,GAAG,EAAE;YACvB,MAAM,KAAK,GAAG,+CAA+C,CAAC;YAC9D,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAEnC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,+CAA+C,CAAC,CAAC;QAC9E,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,SAAS,EAAE,GAAG,EAAE;QACvB,EAAE,CAAC,kBAAkB,EAAE,GAAG,EAAE;YAC1B,MAAM,KAAK,GAAG,CAAC,YAAY,EAAE,aAAa,EAAE,iBAAiB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC1E,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAEnC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,YAAY,EAAE,aAAa,EAAE,iBAAiB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAC1F,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,kBAAkB,EAAE,GAAG,EAAE;YAC1B,MAAM,KAAK,GAAG,0BAA0B,CAAC;YACzC,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAEnC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC;YACpD,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;QACnD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gBAAgB,EAAE,GAAG,EAAE;YACxB,MAAM,KAAK,GAAG,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnD,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YACnC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAEjC,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACjC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAChE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gBAAgB,EAAE,GAAG,EAAE;YACxB,MAAM,KAAK,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC7D,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YACnC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAEjC,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;YACpC,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACjC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAChE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,UAAU,EAAE,GAAG,EAAE;QACxB,EAAE,CAAC,YAAY,EAAE,GAAG,EAAE;YACpB,MAAM,KAAK,GAAG,yDAAyD,CAAC;YACxE,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAEnC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,yDAAyD,CAAC,CAAC;QACxF,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,eAAe,EAAE,GAAG,EAAE;YACvB,MAAM,KAAK,GAAG,0CAA0C,CAAC;YACzD,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAEnC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,0CAA0C,CAAC,CAAC;QACzE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gBAAgB,EAAE,GAAG,EAAE;YACxB,MAAM,KAAK,GAAG,CAAC,oBAAoB,EAAE,eAAe,EAAE,cAAc,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACjF,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAEnC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,oBAAoB,EAAE,eAAe,EAAE,cAAc,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACjG,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;QAC5B,EAAE,CAAC,iBAAiB,EAAE,GAAG,EAAE;YACzB,MAAM,KAAK,GAAG,iBAAiB,CAAC;YAChC,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAEnC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,MAAM,EAAE,GAAG,EAAE;QACpB,EAAE,CAAC,eAAe,EAAE,GAAG,EAAE;YACvB,MAAM,KAAK,GAAG,CAAC,0BAA0B,EAAE,iBAAiB,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC3E,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAEnC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,0BAA0B,EAAE,iBAAiB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACzF,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,MAAM,EAAE,GAAG,EAAE;QACpB,EAAE,CAAC,eAAe,EAAE,GAAG,EAAE;YACvB,MAAM,KAAK,GAAG,CAAC,eAAe,EAAE,sCAAsC,EAAE,WAAW,EAAE,uBAAuB,CAAC,CAAC,IAAI,CAChH,MAAM,CACP,CAAC;YACF,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;YAEnC,iCAAiC;YACjC,MAAM,CAAC,WAAW,CAChB,MAAM,EACN,CAAC,eAAe,EAAE,qCAAqC,EAAE,EAAE,EAAE,uBAAuB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CACjG,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;QACtC,qCAAqC;QACrC,MAAM,WAAW,GAAG;YAClB,EAAE,EAAE,WAAW;YACf,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,OAAO;YACf,OAAO,EAAE,OAAO;YAChB,OAAO,EAAE,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,cAAc,CAAC,MAAM,EAAE,CAAC;YACnF,MAAM,EAAE,EAAE;YACV,SAAS,EAAE,EAAE;YACb,UAAU,EAAE,EAAE;SACf,CAAC;QAEF,UAAU,CAAC,GAAG,EAAE;YACd,kBAAkB,CAAC,KAAK,EAAE,CAAC;YAC3B,uBAAuB,EAAE,CAAC;YAC1B,kBAAkB,CAAC,cAAc,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;QAC9D,CAAC,CAAC,CAAC;QAEH,SAAS,CAAC,GAAG,EAAE;YACb,kBAAkB,CAAC,KAAK,EAAE,CAAC;QAC7B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,2BAA2B,EAAE,GAAG,EAAE;YACnC,MAAM,MAAM,GAAG,YAAY,CAAC,eAAe,EAAE;gBAC3C,MAAM,EAAE,WAAW;gBACnB,MAAM,EAAE,OAAO;gBACf,QAAQ,EAAE,WAAW;aACtB,CAAC,CAAC;YAEH,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;YACvC,MAAM,MAAM,GAAG,YAAY,CAAC,eAAe,EAAE;gBAC3C,MAAM,EAAE,WAAW;gBACnB,MAAM,EAAE,OAAO;aAChB,CAAC,CAAC;YAEH,4CAA4C;YAC5C,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;QAC9C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;YACrC,MAAM,MAAM,GAAG,YAAY,CAAC,eAAe,EAAE;gBAC3C,MAAM,EAAE,WAAW;gBACnB,MAAM,EAAE,OAAO;gBACf,QAAQ,EAAE,cAAc;aACzB,CAAC,CAAC;YAEH,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;QAC9C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;YACpD,oEAAoE;YACpE,mDAAmD;YACnD,sBAAsB;YACtB,MAAM,KAAK,GAAG;gBACZ,EAAE,EAAE,kBAAkB;gBACtB,IAAI,EAAE,QAAQ;gBACd,MAAM,EAAE,OAAO;gBACf,OAAO,EAAE,MAAM;gBACf,OAAO,EAAE,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,cAAc,CAAC,MAAM,EAAE,CAAC;gBACpF,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;gBAChG,SAAS,EAAE,EAAE;gBACb,UAAU,EAAE,EAAE;aACf,CAAC;YACF,kBAAkB,CAAC,KAAK,EAAE,CAAC;YAC3B,uBAAuB,EAAE,CAAC;YAC1B,kBAAkB,CAAC,cAAc,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;YAErD,MAAM,SAAS,GAAG;gBAChB,0BAA0B;gBAC1B,iCAAiC;gBACjC,oDAAoD;gBACpD,wBAAwB;aACzB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAEb,MAAM,iBAAiB,GAAG;gBACxB,0BAA0B;gBAC1B,+BAA+B;gBAC/B,oDAAoD;gBACpD,sBAAsB;aACvB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAEb,MAAM,MAAM,GAAG,YAAY,CAAC,SAAS,EAAE;gBACrC,MAAM,EAAE,kBAAkB;gBAC1B,MAAM,EAAE,OAAO;gBACf,QAAQ,EAAE,UAAU;aACrB,CAAC,CAAC;YAEH,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;YAE9C,4CAA4C;YAC5C,MAAM,KAAK,GAAG,YAAY,CAAC,sBAAsB,EAAE;gBACjD,MAAM,EAAE,kBAAkB;gBAC1B,MAAM,EAAE,OAAO;gBACf,QAAQ,EAAE,UAAU;aACrB,CAAC,CAAC;YACH,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,oBAAoB,CAAC,CAAC;QAClD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=cjk-punctuation.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cjk-punctuation.test.d.ts","sourceRoot":"","sources":["../../../../test/unit/canonicalizer/cjk-punctuation.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,118 @@
1
+ // CJK 标点软边界归一化单元测试。
2
+ //
3
+ // 验证点:
4
+ // 1. 中文标点在字符串字面量外正确归一化为英文等价
5
+ // 2. 字符串字面量内的中文标点 100% 保留
6
+ // 3. 与现有 fullWidthToHalfWidth、关键字、冠词处理路径不冲突
7
+ // 4. 仅在 whitespaceMode === 'chinese' 的 lexicon 下生效;英文路径不受影响
8
+ // 5. 幂等性:再次 canonicalize 相同输入产生相同输出
9
+ import { describe, it } from 'node:test';
10
+ import assert from 'node:assert/strict';
11
+ import { canonicalize } from '../../../src/frontend/canonicalizer.js';
12
+ import { ZH_CN } from '../../../src/config/lexicons/zh-CN.js';
13
+ describe('CJK 标点软边界归一化', () => {
14
+ describe('字符串外的标点替换', () => {
15
+ it('。→ .(语句终止符)', () => {
16
+ const input = '模块 测试.示例。';
17
+ const result = canonicalize(input, ZH_CN);
18
+ assert.ok(result.endsWith('.'), `expected to end with '.', got: ${result}`);
19
+ assert.strictEqual(result.includes('。'), false);
20
+ });
21
+ it(':→ :(块起始符)', () => {
22
+ const input = '规则 验证 给定 患者:\n 返回 真值。';
23
+ const result = canonicalize(input, ZH_CN);
24
+ assert.ok(result.includes(':'), `expected ':', got: ${result}`);
25
+ assert.strictEqual(result.includes(':'), false);
26
+ });
27
+ it(',→ ,(列表分隔符)', () => {
28
+ const input = '规则 评估 给定 年龄,评分,产出:\n 返回 真值。';
29
+ const result = canonicalize(input, ZH_CN);
30
+ assert.strictEqual(result.includes(','), false);
31
+ // 「,」应转为半角逗号,与英文 fixture 等价
32
+ assert.ok(result.includes(','), `expected comma, got: ${result}`);
33
+ assert.ok(/年龄\s*,\s*评分/.test(result), `expected '年龄, 评分': ${result}`);
34
+ });
35
+ it(';→ ;', () => {
36
+ const input = '规则 评估 给定 年龄;评分,产出:\n 返回 真值。';
37
+ const result = canonicalize(input, ZH_CN);
38
+ assert.strictEqual(result.includes(';'), false);
39
+ assert.ok(result.includes(';'), 'expected semicolon');
40
+ });
41
+ it('、→ ,(枚举分隔,与列表分隔等价)', () => {
42
+ const input = '定义 决定 包含 是否批准、理由。';
43
+ const result = canonicalize(input, ZH_CN);
44
+ assert.strictEqual(result.includes('、'), false);
45
+ assert.ok(result.includes(','), `expected enum sep -> comma: ${result}`);
46
+ });
47
+ });
48
+ describe('字符串字面量内的标点保留', () => {
49
+ it('「」 内的中文句号保留', () => {
50
+ const input = '返回 「年龄不足。请重试」。';
51
+ const result = canonicalize(input, ZH_CN);
52
+ // 字符串内的 。 保持;字符串外的句号变 .
53
+ assert.ok(result.includes('年龄不足。请重试'), `string content lost: ${result}`);
54
+ });
55
+ it('「」 内的中文逗号保留', () => {
56
+ const input = '返回 「张三,李四」。';
57
+ const result = canonicalize(input, ZH_CN);
58
+ assert.ok(result.includes('张三,李四'), `string content lost: ${result}`);
59
+ });
60
+ it('「」 内的全部 CJK 标点都保留', () => {
61
+ const input = '返回 「测试。:,;、」。';
62
+ const result = canonicalize(input, ZH_CN);
63
+ assert.ok(result.includes('测试。:,;、'), `string content lost: ${result}`);
64
+ });
65
+ });
66
+ describe('英文 lexicon 路径不受影响', () => {
67
+ it('英文输入下中文标点不应被处理(中文标点应保持原样作为标识符外字符)', () => {
68
+ // 英文 lexicon 的 whitespaceMode !== 'chinese',不应触发归一化
69
+ const input = 'Module test.example.';
70
+ const result = canonicalize(input);
71
+ // 英文路径不应改变原句号语义
72
+ assert.ok(result.includes('Module test.example.'), `unexpected: ${result}`);
73
+ });
74
+ });
75
+ describe('幂等性', () => {
76
+ it('对已归一化的代码再次 canonicalize 产生相同结果', () => {
77
+ const input = '规则 验证 给定 患者:\n 如果 患者.年龄 大于 18,\n 返回 真值。';
78
+ const once = canonicalize(input, ZH_CN);
79
+ const twice = canonicalize(once, ZH_CN);
80
+ assert.strictEqual(twice, once, `not idempotent: once=${once}, twice=${twice}`);
81
+ });
82
+ });
83
+ describe('混合场景', () => {
84
+ it('完整中文规则示例的端到端归一化', () => {
85
+ const input = [
86
+ '模块 测试.控制流。',
87
+ '',
88
+ '定义 决定 包含 是否批准、理由。',
89
+ '',
90
+ '规则 评估申请 包含 年龄,评分,产出:',
91
+ ' 如果 年龄 小于 18',
92
+ ' 返回 决定 包含 是否批准 将 设为 假值,理由 将 设为 「年龄不足」。',
93
+ ' 否则',
94
+ ' 返回 决定 包含 是否批准 将 设为 真值,理由 将 设为 「通过」。',
95
+ ].join('\n');
96
+ const result = canonicalize(input, ZH_CN);
97
+ // 不应残留任何字符串外 CJK 标点(segmentString 用 lexicon 的 quotes,即「」)
98
+ const lexQuoteOpen = '「';
99
+ const lexQuoteClose = '」';
100
+ const segments = result.split(/[「」]/);
101
+ const stringOutside = segments.filter((_, i) => i % 2 === 0).join('');
102
+ assert.strictEqual(stringOutside.includes('。'), false, `句号未归一化: ${result}`);
103
+ assert.strictEqual(stringOutside.includes(','), false, `逗号未归一化: ${result}`);
104
+ assert.strictEqual(stringOutside.includes(':'), false, `冒号未归一化: ${result}`);
105
+ assert.strictEqual(stringOutside.includes('、'), false, `顿号未归一化: ${result}`);
106
+ // 字符串内的标点保留
107
+ assert.ok(result.includes('年龄不足') || result.includes('「年龄不足」'));
108
+ // 应当生成英文等价标点
109
+ assert.ok(stringOutside.includes(','), '应生成半角逗号');
110
+ assert.ok(stringOutside.includes(':'), '应生成半角冒号');
111
+ assert.ok(stringOutside.includes('.'), '应生成半角句号');
112
+ // ensure lexicon quotes preserved as-is (not normalized)
113
+ void lexQuoteOpen;
114
+ void lexQuoteClose;
115
+ });
116
+ });
117
+ });
118
+ //# sourceMappingURL=cjk-punctuation.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cjk-punctuation.test.js","sourceRoot":"","sources":["../../../../test/unit/canonicalizer/cjk-punctuation.test.ts"],"names":[],"mappings":"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"}