@aster-cloud/aster-lang-ts 1.0.29 → 1.0.31
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.
- package/dist/scripts/aster.js +11 -26
- package/dist/scripts/aster.js.map +1 -1
- package/dist/scripts/corpus-loader.d.ts +17 -0
- package/dist/scripts/corpus-loader.d.ts.map +1 -0
- package/dist/scripts/corpus-loader.js +60 -0
- package/dist/scripts/corpus-loader.js.map +1 -0
- package/dist/scripts/emit-classfiles-core.js +5 -13
- package/dist/scripts/emit-classfiles-core.js.map +1 -1
- package/dist/scripts/emit-classfiles.js +7 -12
- package/dist/scripts/emit-classfiles.js.map +1 -1
- package/dist/scripts/generate_error_codes.js +2 -0
- package/dist/scripts/generate_error_codes.js.map +1 -1
- package/dist/scripts/golden.js +4 -1
- package/dist/scripts/golden.js.map +1 -1
- package/dist/scripts/test-lossless-golden.js +2 -1
- package/dist/scripts/test-lossless-golden.js.map +1 -1
- package/dist/scripts/validate_error_codes.js +1 -0
- package/dist/scripts/validate_error_codes.js.map +1 -1
- package/dist/scripts/verify-lexicon-sync.js +5 -1
- package/dist/scripts/verify-lexicon-sync.js.map +1 -1
- package/dist/src/ast/ast.d.ts +1 -1
- package/dist/src/ast/ast.d.ts.map +1 -1
- package/dist/src/ast/ast.js +2 -1
- package/dist/src/ast/ast.js.map +1 -1
- package/dist/src/browser.d.ts +7 -0
- package/dist/src/browser.d.ts.map +1 -1
- package/dist/src/browser.js +4 -0
- package/dist/src/browser.js.map +1 -1
- package/dist/src/cli/utils/gradle-env.d.ts +9 -0
- package/dist/src/cli/utils/gradle-env.d.ts.map +1 -0
- package/dist/src/cli/utils/gradle-env.js +18 -0
- package/dist/src/cli/utils/gradle-env.js.map +1 -0
- package/dist/src/cli/utils/out-dir.d.ts +18 -0
- package/dist/src/cli/utils/out-dir.d.ts.map +1 -0
- package/dist/src/cli/utils/out-dir.js +49 -0
- package/dist/src/cli/utils/out-dir.js.map +1 -0
- package/dist/src/cnl-printer.d.ts +10 -0
- package/dist/src/cnl-printer.d.ts.map +1 -0
- package/dist/src/cnl-printer.js +360 -0
- package/dist/src/cnl-printer.js.map +1 -0
- package/dist/src/config/lexicons/de-DE.d.ts.map +1 -1
- package/dist/src/config/lexicons/de-DE.js +8 -2
- package/dist/src/config/lexicons/de-DE.js.map +1 -1
- package/dist/src/config/lexicons/en-US.d.ts.map +1 -1
- package/dist/src/config/lexicons/en-US.js +8 -4
- package/dist/src/config/lexicons/en-US.js.map +1 -1
- package/dist/src/config/lexicons/hi-IN.d.ts.map +1 -1
- package/dist/src/config/lexicons/hi-IN.js +8 -2
- package/dist/src/config/lexicons/hi-IN.js.map +1 -1
- package/dist/src/config/lexicons/template.d.ts.map +1 -1
- package/dist/src/config/lexicons/template.js +12 -0
- package/dist/src/config/lexicons/template.js.map +1 -1
- package/dist/src/config/lexicons/zh-CN.d.ts.map +1 -1
- package/dist/src/config/lexicons/zh-CN.js +9 -3
- package/dist/src/config/lexicons/zh-CN.js.map +1 -1
- package/dist/src/config/semantic.d.ts +6 -0
- package/dist/src/config/semantic.d.ts.map +1 -1
- package/dist/src/config/semantic.js +8 -0
- package/dist/src/config/semantic.js.map +1 -1
- package/dist/src/config/token-kind.d.ts +12 -0
- package/dist/src/config/token-kind.d.ts.map +1 -1
- package/dist/src/config/token-kind.js +18 -0
- package/dist/src/config/token-kind.js.map +1 -1
- package/dist/src/core/core_ir.d.ts +1 -1
- package/dist/src/core/core_ir.d.ts.map +1 -1
- package/dist/src/core/core_ir.js +3 -1
- package/dist/src/core/core_ir.js.map +1 -1
- package/dist/src/core/interpreter.d.ts.map +1 -1
- package/dist/src/core/interpreter.js +222 -18
- package/dist/src/core/interpreter.js.map +1 -1
- package/dist/src/cst/cst_printer.d.ts.map +1 -1
- package/dist/src/cst/cst_printer.js +66 -32
- package/dist/src/cst/cst_printer.js.map +1 -1
- package/dist/src/diagnostics/diagnostics.d.ts +1 -0
- package/dist/src/diagnostics/diagnostics.d.ts.map +1 -1
- package/dist/src/diagnostics/diagnostics.js +1 -0
- package/dist/src/diagnostics/diagnostics.js.map +1 -1
- package/dist/src/diagnostics/error_codes.d.ts +10 -2
- package/dist/src/diagnostics/error_codes.d.ts.map +1 -1
- package/dist/src/diagnostics/error_codes.js +64 -0
- package/dist/src/diagnostics/error_codes.js.map +1 -1
- package/dist/src/effects/effect_inference.js +1 -1
- package/dist/src/effects/effect_inference.js.map +1 -1
- package/dist/src/formatter.d.ts +3 -0
- package/dist/src/formatter.d.ts.map +1 -1
- package/dist/src/formatter.js +8 -261
- package/dist/src/formatter.js.map +1 -1
- package/dist/src/frontend/transformers.d.ts.map +1 -1
- package/dist/src/frontend/transformers.js +10 -2
- package/dist/src/frontend/transformers.js.map +1 -1
- package/dist/src/governance/controls-registry.data.d.ts +40 -0
- package/dist/src/governance/controls-registry.data.d.ts.map +1 -0
- package/dist/src/governance/controls-registry.data.js +35 -0
- package/dist/src/governance/controls-registry.data.js.map +1 -0
- package/dist/src/governance/controls.d.ts +23 -0
- package/dist/src/governance/controls.d.ts.map +1 -0
- package/dist/src/governance/controls.js +77 -0
- package/dist/src/governance/controls.js.map +1 -0
- package/dist/src/index.d.ts +4 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +2 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/lower_to_core.js +1 -1
- package/dist/src/lower_to_core.js.map +1 -1
- package/dist/src/lsp/completion.d.ts +22 -1
- package/dist/src/lsp/completion.d.ts.map +1 -1
- package/dist/src/lsp/completion.js +42 -1
- package/dist/src/lsp/completion.js.map +1 -1
- package/dist/src/lsp/debounce-map.d.ts +16 -0
- package/dist/src/lsp/debounce-map.d.ts.map +1 -0
- package/dist/src/lsp/debounce-map.js +32 -0
- package/dist/src/lsp/debounce-map.js.map +1 -0
- package/dist/src/lsp/server.js +6 -8
- package/dist/src/lsp/server.js.map +1 -1
- package/dist/src/lsp/utils.d.ts.map +1 -1
- package/dist/src/lsp/utils.js +2 -0
- package/dist/src/lsp/utils.js.map +1 -1
- package/dist/src/lsp/workspace/file-watcher.d.ts +1 -0
- package/dist/src/lsp/workspace/file-watcher.d.ts.map +1 -1
- package/dist/src/lsp/workspace/file-watcher.js +24 -14
- package/dist/src/lsp/workspace/file-watcher.js.map +1 -1
- package/dist/src/manifest.d.ts +2 -0
- package/dist/src/manifest.d.ts.map +1 -1
- package/dist/src/manifest.js.map +1 -1
- package/dist/src/package/manifest-parser.d.ts +10 -0
- package/dist/src/package/manifest-parser.d.ts.map +1 -1
- package/dist/src/package/manifest-parser.js +27 -28
- package/dist/src/package/manifest-parser.js.map +1 -1
- package/dist/src/package/manifest-schema.d.ts +15 -0
- package/dist/src/package/manifest-schema.d.ts.map +1 -0
- package/dist/src/package/manifest-schema.js +116 -0
- package/dist/src/package/manifest-schema.js.map +1 -0
- package/dist/src/parser/context.d.ts +2 -0
- package/dist/src/parser/context.d.ts.map +1 -1
- package/dist/src/parser/context.js +1 -0
- package/dist/src/parser/context.js.map +1 -1
- package/dist/src/parser/decl-parser.d.ts.map +1 -1
- package/dist/src/parser/decl-parser.js +26 -10
- package/dist/src/parser/decl-parser.js.map +1 -1
- package/dist/src/parser/expr-stmt-parser.d.ts +4 -1
- package/dist/src/parser/expr-stmt-parser.d.ts.map +1 -1
- package/dist/src/parser/expr-stmt-parser.js +147 -6
- package/dist/src/parser/expr-stmt-parser.js.map +1 -1
- package/dist/src/parser/import-parser.d.ts +12 -0
- package/dist/src/parser/import-parser.d.ts.map +1 -1
- package/dist/src/parser/import-parser.js +28 -0
- package/dist/src/parser/import-parser.js.map +1 -1
- package/dist/src/parser.js +1 -1
- package/dist/src/parser.js.map +1 -1
- package/dist/src/typecheck/browser.d.ts +3 -0
- package/dist/src/typecheck/browser.d.ts.map +1 -1
- package/dist/src/typecheck/browser.js +10 -1
- package/dist/src/typecheck/browser.js.map +1 -1
- package/dist/src/typecheck/context.d.ts +3 -0
- package/dist/src/typecheck/context.d.ts.map +1 -1
- package/dist/src/typecheck/context.js.map +1 -1
- package/dist/src/typecheck/expression.d.ts +6 -0
- package/dist/src/typecheck/expression.d.ts.map +1 -1
- package/dist/src/typecheck/expression.js +54 -2
- package/dist/src/typecheck/expression.js.map +1 -1
- package/dist/src/typecheck/generics.d.ts.map +1 -1
- package/dist/src/typecheck/generics.js +3 -0
- package/dist/src/typecheck/generics.js.map +1 -1
- package/dist/src/typecheck/governance.d.ts +43 -0
- package/dist/src/typecheck/governance.d.ts.map +1 -0
- package/dist/src/typecheck/governance.js +162 -0
- package/dist/src/typecheck/governance.js.map +1 -0
- package/dist/src/typecheck/module.d.ts.map +1 -1
- package/dist/src/typecheck/module.js +10 -1
- package/dist/src/typecheck/module.js.map +1 -1
- package/dist/src/typecheck/statement.d.ts.map +1 -1
- package/dist/src/typecheck/statement.js +2 -2
- package/dist/src/typecheck/statement.js.map +1 -1
- package/dist/src/typecheck/type_system.d.ts.map +1 -1
- package/dist/src/typecheck/type_system.js +4 -0
- package/dist/src/typecheck/type_system.js.map +1 -1
- package/dist/src/typecheck/verdict_signatures.d.ts +19 -0
- package/dist/src/typecheck/verdict_signatures.d.ts.map +1 -0
- package/dist/src/typecheck/verdict_signatures.js +23 -0
- package/dist/src/typecheck/verdict_signatures.js.map +1 -0
- package/dist/src/types/base.d.ts +2 -0
- package/dist/src/types/base.d.ts.map +1 -1
- package/dist/test/helpers/sibling-source.d.ts +10 -0
- package/dist/test/helpers/sibling-source.d.ts.map +1 -0
- package/dist/test/helpers/sibling-source.js +20 -0
- package/dist/test/helpers/sibling-source.js.map +1 -0
- package/dist/test/unit/allocation-budget.test.d.ts +2 -0
- package/dist/test/unit/allocation-budget.test.d.ts.map +1 -0
- package/dist/test/unit/allocation-budget.test.js +160 -0
- package/dist/test/unit/allocation-budget.test.js.map +1 -0
- package/dist/test/unit/apply-call.test.js +5 -0
- package/dist/test/unit/apply-call.test.js.map +1 -1
- package/dist/test/unit/canonicalizer/possessive-anchor.test.js +10 -0
- package/dist/test/unit/canonicalizer/possessive-anchor.test.js.map +1 -1
- package/dist/test/unit/cli/gradle-env-guard.test.d.ts +2 -0
- package/dist/test/unit/cli/gradle-env-guard.test.d.ts.map +1 -0
- package/dist/test/unit/cli/gradle-env-guard.test.js +53 -0
- package/dist/test/unit/cli/gradle-env-guard.test.js.map +1 -0
- package/dist/test/unit/cli/gradle-env.test.d.ts +2 -0
- package/dist/test/unit/cli/gradle-env.test.d.ts.map +1 -0
- package/dist/test/unit/cli/gradle-env.test.js +31 -0
- package/dist/test/unit/cli/gradle-env.test.js.map +1 -0
- package/dist/test/unit/cli/out-dir.test.d.ts +2 -0
- package/dist/test/unit/cli/out-dir.test.d.ts.map +1 -0
- package/dist/test/unit/cli/out-dir.test.js +96 -0
- package/dist/test/unit/cli/out-dir.test.js.map +1 -0
- package/dist/test/unit/formatter-corpus-roundtrip.test.d.ts +2 -0
- package/dist/test/unit/formatter-corpus-roundtrip.test.d.ts.map +1 -0
- package/dist/test/unit/formatter-corpus-roundtrip.test.js +190 -0
- package/dist/test/unit/formatter-corpus-roundtrip.test.js.map +1 -0
- package/dist/test/unit/formatter-roundtrip.test.d.ts +2 -0
- package/dist/test/unit/formatter-roundtrip.test.d.ts.map +1 -0
- package/dist/test/unit/formatter-roundtrip.test.js +125 -0
- package/dist/test/unit/formatter-roundtrip.test.js.map +1 -0
- package/dist/test/unit/governance/controls-registry-parity.test.d.ts +2 -0
- package/dist/test/unit/governance/controls-registry-parity.test.d.ts.map +1 -0
- package/dist/test/unit/governance/controls-registry-parity.test.js +28 -0
- package/dist/test/unit/governance/controls-registry-parity.test.js.map +1 -0
- package/dist/test/unit/governance/controls-registry-profiles.test.d.ts +2 -0
- package/dist/test/unit/governance/controls-registry-profiles.test.d.ts.map +1 -0
- package/dist/test/unit/governance/controls-registry-profiles.test.js +106 -0
- package/dist/test/unit/governance/controls-registry-profiles.test.js.map +1 -0
- package/dist/test/unit/governance/governance-check.test.d.ts +2 -0
- package/dist/test/unit/governance/governance-check.test.d.ts.map +1 -0
- package/dist/test/unit/governance/governance-check.test.js +169 -0
- package/dist/test/unit/governance/governance-check.test.js.map +1 -0
- package/dist/test/unit/governance/profile-check.test.d.ts +2 -0
- package/dist/test/unit/governance/profile-check.test.d.ts.map +1 -0
- package/dist/test/unit/governance/profile-check.test.js +139 -0
- package/dist/test/unit/governance/profile-check.test.js.map +1 -0
- package/dist/test/unit/governance/verdict-typecheck.test.d.ts +2 -0
- package/dist/test/unit/governance/verdict-typecheck.test.d.ts.map +1 -0
- package/dist/test/unit/governance/verdict-typecheck.test.js +80 -0
- package/dist/test/unit/governance/verdict-typecheck.test.js.map +1 -0
- package/dist/test/unit/interpreter/verdict-builtins.test.d.ts +2 -0
- package/dist/test/unit/interpreter/verdict-builtins.test.d.ts.map +1 -0
- package/dist/test/unit/interpreter/verdict-builtins.test.js +72 -0
- package/dist/test/unit/interpreter/verdict-builtins.test.js.map +1 -0
- package/dist/test/unit/list-numeric-fail-loud.test.d.ts +2 -0
- package/dist/test/unit/list-numeric-fail-loud.test.d.ts.map +1 -0
- package/dist/test/unit/list-numeric-fail-loud.test.js +83 -0
- package/dist/test/unit/list-numeric-fail-loud.test.js.map +1 -0
- package/dist/test/unit/lossless-mirror.test.d.ts +2 -0
- package/dist/test/unit/lossless-mirror.test.d.ts.map +1 -0
- package/dist/test/unit/lossless-mirror.test.js +41 -0
- package/dist/test/unit/lossless-mirror.test.js.map +1 -0
- package/dist/test/unit/lossless-reflow.test.d.ts +2 -0
- package/dist/test/unit/lossless-reflow.test.d.ts.map +1 -0
- package/dist/test/unit/lossless-reflow.test.js +84 -0
- package/dist/test/unit/lossless-reflow.test.js.map +1 -0
- package/dist/test/unit/lowering/lowering.test.js +35 -35
- package/dist/test/unit/lowering/lowering.test.js.map +1 -1
- package/dist/test/unit/lsp/control-completion.test.d.ts +2 -0
- package/dist/test/unit/lsp/control-completion.test.d.ts.map +1 -0
- package/dist/test/unit/lsp/control-completion.test.js +46 -0
- package/dist/test/unit/lsp/control-completion.test.js.map +1 -0
- package/dist/test/unit/lsp/debounce-map.test.d.ts +2 -0
- package/dist/test/unit/lsp/debounce-map.test.d.ts.map +1 -0
- package/dist/test/unit/lsp/debounce-map.test.js +47 -0
- package/dist/test/unit/lsp/debounce-map.test.js.map +1 -0
- package/dist/test/unit/lsp/file-watcher-restart.test.d.ts +2 -0
- package/dist/test/unit/lsp/file-watcher-restart.test.d.ts.map +1 -0
- package/dist/test/unit/lsp/file-watcher-restart.test.js +40 -0
- package/dist/test/unit/lsp/file-watcher-restart.test.js.map +1 -0
- package/dist/test/unit/manifest-parser.test.js +8 -0
- package/dist/test/unit/manifest-parser.test.js.map +1 -1
- package/dist/test/unit/manifest-schema.test.d.ts +7 -5
- package/dist/test/unit/manifest-schema.test.d.ts.map +1 -1
- package/dist/test/unit/manifest-schema.test.js +48 -10
- package/dist/test/unit/manifest-schema.test.js.map +1 -1
- package/dist/test/unit/parser/governance-sugar.test.d.ts +2 -0
- package/dist/test/unit/parser/governance-sugar.test.d.ts.map +1 -0
- package/dist/test/unit/parser/governance-sugar.test.js +258 -0
- package/dist/test/unit/parser/governance-sugar.test.js.map +1 -0
- package/dist/test/unit/parser/module-header.test.d.ts +2 -0
- package/dist/test/unit/parser/module-header.test.d.ts.map +1 -0
- package/dist/test/unit/parser/module-header.test.js +25 -0
- package/dist/test/unit/parser/module-header.test.js.map +1 -0
- package/dist/test/unit/parser/positional-annotation-args.test.d.ts +2 -0
- package/dist/test/unit/parser/positional-annotation-args.test.d.ts.map +1 -0
- package/dist/test/unit/parser/positional-annotation-args.test.js +26 -0
- package/dist/test/unit/parser/positional-annotation-args.test.js.map +1 -0
- package/dist/test/unit/parser/prefix-operator-call.test.d.ts +2 -0
- package/dist/test/unit/parser/prefix-operator-call.test.d.ts.map +1 -0
- package/dist/test/unit/parser/prefix-operator-call.test.js +69 -0
- package/dist/test/unit/parser/prefix-operator-call.test.js.map +1 -0
- package/dist/test/unit/scripts/corpus-loader.test.d.ts +2 -0
- package/dist/test/unit/scripts/corpus-loader.test.d.ts.map +1 -0
- package/dist/test/unit/scripts/corpus-loader.test.js +85 -0
- package/dist/test/unit/scripts/corpus-loader.test.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 全语料格式化往返:本仓与兄弟仓 aster-lang-test/corpus 下每个能编译的 .aster,
|
|
3
|
+
* 格式化后重新编译,Core IR 须与原文相同(忽略 origin)。
|
|
4
|
+
*
|
|
5
|
+
* 源文的词法包取 .meta.json 的 lexicon,否则依次尝试 en-US / zh-CN / de-DE,取第一个能编译的;
|
|
6
|
+
* 哪个都编译不了的(错误夹具、旧语法示例)不在往返范围内。格式化器输出英文 CNL,故一律用 en-US 重新编译。
|
|
7
|
+
*
|
|
8
|
+
* 另对同一语料跑 LSP 默认格式化(lossless + reflow):再跑一次结果不变,字符串、注释、缩进与句点不变,
|
|
9
|
+
* 不留行尾空白,CRLF 版本的结果即 LF 结果换成 CRLF;能编译的文件以原词法包重新编译 Core IR 不变
|
|
10
|
+
* (reflow 不翻译,保留源文语言)。
|
|
11
|
+
*/
|
|
12
|
+
import { test } from 'node:test';
|
|
13
|
+
import assert from 'node:assert/strict';
|
|
14
|
+
import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
|
|
15
|
+
import { dirname, join, relative } from 'node:path';
|
|
16
|
+
import { fileURLToPath } from 'node:url';
|
|
17
|
+
import { canonicalize } from '../../src/frontend/canonicalizer.js';
|
|
18
|
+
import { lex } from '../../src/frontend/lexer.js';
|
|
19
|
+
import { parseWithLexicon } from '../../src/parser.js';
|
|
20
|
+
import { lowerModule } from '../../src/lower_to_core.js';
|
|
21
|
+
import { formatCNL } from '../../src/formatter.js';
|
|
22
|
+
import { buildCstLossless } from '../../src/cst/cst_builder.js';
|
|
23
|
+
import { printCNLFromCst } from '../../src/cst/cst_printer.js';
|
|
24
|
+
import { EN_US } from '../../src/config/lexicons/en-US.js';
|
|
25
|
+
import { ZH_CN } from '../../src/config/lexicons/zh-CN.js';
|
|
26
|
+
import { DE_DE } from '../../src/config/lexicons/de-DE.js';
|
|
27
|
+
// 编译后从 dist/test/unit 运行:上溯 3 级到仓库根
|
|
28
|
+
const repoRoot = join(dirname(fileURLToPath(import.meta.url)), '..', '..', '..');
|
|
29
|
+
const SKIP_DIRS = new Set(['node_modules', 'dist', 'coverage', '.git', '.ccg', 'aster-lang-test']);
|
|
30
|
+
const LEXICONS = { 'en-US': EN_US, 'zh-CN': ZH_CN, 'de-DE': DE_DE };
|
|
31
|
+
// 源文用中文标识符:格式化器只输出英文 CNL,而 en-US 词法不接受 CJK 标识符字符(lexer isLetter 英文模式),
|
|
32
|
+
// 英文重写后无法重新词法分析。路径相对兄弟仓 aster-lang-test 根。
|
|
33
|
+
const CJK_IDENTIFIERS = '中文标识符无法以英文 CNL 重写(en-US 词法不接受 CJK 标识符)';
|
|
34
|
+
const ALLOW_LIST = new Map([
|
|
35
|
+
['corpus/conformance/cjk-v2/01-punctuation-basic.aster', CJK_IDENTIFIERS],
|
|
36
|
+
['corpus/conformance/cjk-v2/02-string-preservation.aster', CJK_IDENTIFIERS],
|
|
37
|
+
['corpus/conformance/cjk-v2/04-identifier-no-collision.aster', CJK_IDENTIFIERS],
|
|
38
|
+
['corpus/tier3-fixtures/lexicon-i18n/01-hello__i18n-zh-CN.aster', CJK_IDENTIFIERS],
|
|
39
|
+
['corpus/tier3-fixtures/lexicon-i18n/02-types__i18n-zh-CN.aster', CJK_IDENTIFIERS],
|
|
40
|
+
['corpus/tier3-fixtures/lexicon-i18n/03-functions__i18n-zh-CN.aster', CJK_IDENTIFIERS],
|
|
41
|
+
['corpus/tier3-fixtures/lexicon-i18n/04-control-flow__i18n-zh-CN.aster', CJK_IDENTIFIERS],
|
|
42
|
+
['corpus/tier3-fixtures/lexicon-i18n/05-patterns__i18n-zh-CN.aster', CJK_IDENTIFIERS],
|
|
43
|
+
['corpus/tier3-fixtures/lexicon-i18n/06-operators__i18n-zh-CN.aster', CJK_IDENTIFIERS],
|
|
44
|
+
['corpus/tier3-fixtures/lexicon-i18n/user_greeting.aster', CJK_IDENTIFIERS],
|
|
45
|
+
]);
|
|
46
|
+
function asterFiles(dir, out = []) {
|
|
47
|
+
for (const entry of readdirSync(dir)) {
|
|
48
|
+
if (SKIP_DIRS.has(entry))
|
|
49
|
+
continue;
|
|
50
|
+
const path = join(dir, entry);
|
|
51
|
+
if (statSync(path).isDirectory())
|
|
52
|
+
asterFiles(path, out);
|
|
53
|
+
else if (path.endsWith('.aster'))
|
|
54
|
+
out.push(path);
|
|
55
|
+
}
|
|
56
|
+
return out;
|
|
57
|
+
}
|
|
58
|
+
function siblingTestRepo() {
|
|
59
|
+
return [join(repoRoot, '..', 'aster-lang-test'), join(repoRoot, 'aster-lang-test')]
|
|
60
|
+
.find((c) => existsSync(join(c, 'corpus')));
|
|
61
|
+
}
|
|
62
|
+
function toCore(source, lexicon) {
|
|
63
|
+
const result = parseWithLexicon(lex(canonicalize(source, lexicon), lexicon), lexicon);
|
|
64
|
+
const errors = result.diagnostics.filter((d) => d.severity === 'error');
|
|
65
|
+
if (errors.length > 0)
|
|
66
|
+
throw new Error(errors[0].message);
|
|
67
|
+
return lowerModule(result.ast);
|
|
68
|
+
}
|
|
69
|
+
function stripOrigins(o) {
|
|
70
|
+
if (Array.isArray(o))
|
|
71
|
+
return o.map(stripOrigins);
|
|
72
|
+
if (!o || typeof o !== 'object')
|
|
73
|
+
return o;
|
|
74
|
+
return Object.fromEntries(Object.entries(o).filter(([k]) => k !== 'origin').map(([k, v]) => [k, stripOrigins(v)]));
|
|
75
|
+
}
|
|
76
|
+
function declaredLexicon(file) {
|
|
77
|
+
const meta = file.replace(/\.aster$/, '.meta.json');
|
|
78
|
+
return existsSync(meta) ? JSON.parse(readFileSync(meta, 'utf8')).lexicon : undefined;
|
|
79
|
+
}
|
|
80
|
+
/** 返回能编译源文的词法包及其 Core IR;都不能编译时为 undefined */
|
|
81
|
+
function compileWithAnyLexicon(file, source) {
|
|
82
|
+
const names = [declaredLexicon(file), 'en-US', 'zh-CN', 'de-DE'].filter((n) => !!n && n in LEXICONS);
|
|
83
|
+
for (const name of names) {
|
|
84
|
+
try {
|
|
85
|
+
return { lexicon: LEXICONS[name], core: stripOrigins(toCore(source, LEXICONS[name])) };
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
// 换下一个词法包
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return undefined;
|
|
92
|
+
}
|
|
93
|
+
/** 格式化后重新编译与原文比对;返回失败原因,成功为 undefined */
|
|
94
|
+
function corpusFiles(t) {
|
|
95
|
+
const sibling = siblingTestRepo();
|
|
96
|
+
if (sibling === undefined) {
|
|
97
|
+
assert.ok(!process.env.CI, 'CI 中须 checkout aster-lang-test(见 .github/workflows/ci.yml test job)');
|
|
98
|
+
t.diagnostic('aster-lang-test 未并列 checkout,只检查本仓语料');
|
|
99
|
+
}
|
|
100
|
+
return [
|
|
101
|
+
...asterFiles(repoRoot).map((f) => ({ file: f, key: relative(repoRoot, f) })),
|
|
102
|
+
...(sibling ? asterFiles(join(sibling, 'corpus')).map((f) => ({ file: f, key: relative(sibling, f) })) : []),
|
|
103
|
+
];
|
|
104
|
+
}
|
|
105
|
+
/** 无法建 lossless CST(词法错误)时 LSP 不给出编辑,此处同样返回 undefined */
|
|
106
|
+
function losslessCst(source) {
|
|
107
|
+
try {
|
|
108
|
+
return buildCstLossless(source);
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
return undefined;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* reflow 不得改动的部分:除换行外的记号(字符串字面量、缩进 INDENT/DEDENT、句点等)与注释正文(行尾空白除外)。
|
|
116
|
+
* 唯一允许的记号改动是 `.` 与紧随其后的 `:` 合并,故比较前去掉这种 `.`。
|
|
117
|
+
*/
|
|
118
|
+
function untouchable(cst) {
|
|
119
|
+
const merged = (i) => cst.tokens[i].lexeme === '.' && cst.tokens[i + 1]?.lexeme === ':';
|
|
120
|
+
const kept = cst.tokens
|
|
121
|
+
.filter((tk, i) => tk.kind !== 'NEWLINE' && tk.kind !== 'EOF' && !merged(i))
|
|
122
|
+
.map((tk) => `${tk.kind}:${tk.lexeme}`);
|
|
123
|
+
const comments = (cst.inlineComments ?? []).map((c) => c.text.trimEnd());
|
|
124
|
+
return JSON.stringify([kept, comments]);
|
|
125
|
+
}
|
|
126
|
+
/** lossless reflow 后检查幂等、不可改动部分与 Core IR;返回失败原因,成功或不适用为 undefined */
|
|
127
|
+
function reflowProblem(file) {
|
|
128
|
+
const source = readFileSync(file, 'utf8');
|
|
129
|
+
const cst = losslessCst(source);
|
|
130
|
+
if (cst === undefined)
|
|
131
|
+
return undefined;
|
|
132
|
+
const once = printCNLFromCst(cst, { reflow: true });
|
|
133
|
+
const onceCst = losslessCst(once);
|
|
134
|
+
if (onceCst === undefined)
|
|
135
|
+
return 'reflow 结果无法重新词法分析';
|
|
136
|
+
if (printCNLFromCst(onceCst, { reflow: true }) !== once)
|
|
137
|
+
return '二次 reflow 结果不同';
|
|
138
|
+
if (untouchable(onceCst) !== untouchable(cst))
|
|
139
|
+
return '字符串、注释、缩进或句点被改动';
|
|
140
|
+
if (once.split('\n').some((line) => /[ \t]\r?$/.test(line)))
|
|
141
|
+
return '仍有行尾空白';
|
|
142
|
+
const crlf = losslessCst(source.replace(/\r?\n/g, '\r\n'));
|
|
143
|
+
if (crlf === undefined || printCNLFromCst(crlf, { reflow: true }) !== once.replace(/\r?\n/g, '\r\n')) {
|
|
144
|
+
return 'CRLF 版本的 reflow 结果与 LF 版本不一致';
|
|
145
|
+
}
|
|
146
|
+
const compiled = compileWithAnyLexicon(file, source);
|
|
147
|
+
if (compiled === undefined)
|
|
148
|
+
return undefined;
|
|
149
|
+
try {
|
|
150
|
+
assert.deepEqual(stripOrigins(toCore(once, compiled.lexicon)), compiled.core);
|
|
151
|
+
return undefined;
|
|
152
|
+
}
|
|
153
|
+
catch (e) {
|
|
154
|
+
return e.message.split('\n')[0];
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
function roundTripProblem(file) {
|
|
158
|
+
const source = readFileSync(file, 'utf8');
|
|
159
|
+
const compiled = compileWithAnyLexicon(file, source);
|
|
160
|
+
if (compiled === undefined)
|
|
161
|
+
return undefined;
|
|
162
|
+
const formatted = formatCNL(source, { lexicon: compiled.lexicon });
|
|
163
|
+
try {
|
|
164
|
+
assert.deepEqual(stripOrigins(toCore(formatted, EN_US)), compiled.core);
|
|
165
|
+
return undefined;
|
|
166
|
+
}
|
|
167
|
+
catch (e) {
|
|
168
|
+
return e.message.split('\n')[0];
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
test('全语料格式化往返 Core IR 不变', (t) => {
|
|
172
|
+
const failures = corpusFiles(t)
|
|
173
|
+
.map(({ file, key }) => ({ key, problem: roundTripProblem(file) }))
|
|
174
|
+
.filter(({ key, problem }) => problem !== undefined && !ALLOW_LIST.has(key));
|
|
175
|
+
assert.deepEqual(failures, []);
|
|
176
|
+
});
|
|
177
|
+
test('全语料 lossless reflow:幂等,不改字符串、注释、缩进与句点,Core IR 不变', (t) => {
|
|
178
|
+
const failures = corpusFiles(t)
|
|
179
|
+
.map(({ file, key }) => ({ key, problem: reflowProblem(file) }))
|
|
180
|
+
.filter(({ problem }) => problem !== undefined);
|
|
181
|
+
assert.deepEqual(failures, []);
|
|
182
|
+
});
|
|
183
|
+
test('允许清单中的条目确实仍不能往返(能往返的须移出清单)', (t) => {
|
|
184
|
+
const sibling = siblingTestRepo();
|
|
185
|
+
if (sibling === undefined)
|
|
186
|
+
return t.skip('aster-lang-test 未并列 checkout');
|
|
187
|
+
const stale = [...ALLOW_LIST.keys()].filter((key) => roundTripProblem(join(sibling, key)) === undefined);
|
|
188
|
+
assert.deepEqual(stale, []);
|
|
189
|
+
});
|
|
190
|
+
//# sourceMappingURL=formatter-corpus-roundtrip.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatter-corpus-roundtrip.test.js","sourceRoot":"","sources":["../../../test/unit/formatter-corpus-roundtrip.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatter-roundtrip.test.d.ts","sourceRoot":"","sources":["../../../test/unit/formatter-roundtrip.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 格式化器往返:格式化输出须能重新编译,且 Core IR 与原文相同(去掉 origin 后)。
|
|
3
|
+
*
|
|
4
|
+
* 夹具取自 aster-lang-test 的语法糖/长写法样本与 aster-cloud 的信贷试点 v3(en/zh/de)。
|
|
5
|
+
* 格式化器一律输出英文 CNL,语法糖按长写法输出(ADR 0046 §5),故重新编译统一用 en-US。
|
|
6
|
+
*/
|
|
7
|
+
import { describe, test } from 'node:test';
|
|
8
|
+
import assert from 'node:assert/strict';
|
|
9
|
+
import { readFileSync } from 'node:fs';
|
|
10
|
+
import { dirname, join } from 'node:path';
|
|
11
|
+
import { fileURLToPath } from 'node:url';
|
|
12
|
+
import { canonicalize } from '../../src/frontend/canonicalizer.js';
|
|
13
|
+
import { lex } from '../../src/frontend/lexer.js';
|
|
14
|
+
import { parseWithLexicon } from '../../src/parser.js';
|
|
15
|
+
import { lowerModule } from '../../src/lower_to_core.js';
|
|
16
|
+
import { formatCNL } from '../../src/formatter.js';
|
|
17
|
+
import { EN_US } from '../../src/config/lexicons/en-US.js';
|
|
18
|
+
import { ZH_CN } from '../../src/config/lexicons/zh-CN.js';
|
|
19
|
+
import { DE_DE } from '../../src/config/lexicons/de-DE.js';
|
|
20
|
+
// 编译后从 dist/test/unit 运行:上溯 3 级到仓库根,夹具在 test/fixtures 下
|
|
21
|
+
const repoRoot = join(dirname(fileURLToPath(import.meta.url)), '..', '..', '..');
|
|
22
|
+
const fixtureDir = join(repoRoot, 'test', 'fixtures', 'formatter-roundtrip');
|
|
23
|
+
function toCore(source, lexicon = EN_US) {
|
|
24
|
+
const tokens = lex(canonicalize(source, lexicon), lexicon);
|
|
25
|
+
const result = parseWithLexicon(tokens, lexicon);
|
|
26
|
+
const errors = result.diagnostics.filter((d) => d.severity === 'error');
|
|
27
|
+
if (errors.length > 0)
|
|
28
|
+
throw new Error(errors.map((d) => d.message).join('\n') + '\n---\n' + source);
|
|
29
|
+
return lowerModule(result.ast);
|
|
30
|
+
}
|
|
31
|
+
function stripOrigins(o) {
|
|
32
|
+
if (Array.isArray(o))
|
|
33
|
+
return o.map(stripOrigins);
|
|
34
|
+
if (!o || typeof o !== 'object')
|
|
35
|
+
return o;
|
|
36
|
+
const out = {};
|
|
37
|
+
for (const [k, v] of Object.entries(o)) {
|
|
38
|
+
if (k !== 'origin')
|
|
39
|
+
out[k] = stripOrigins(v);
|
|
40
|
+
}
|
|
41
|
+
return out;
|
|
42
|
+
}
|
|
43
|
+
// 格式化 → 用 en-US 重新编译 → 与原文 IR 比对;返回格式化输出供进一步断言
|
|
44
|
+
function assertRoundTrip(source, lexicon = EN_US) {
|
|
45
|
+
const formatted = formatCNL(source, { lexicon });
|
|
46
|
+
assert.deepEqual(stripOrigins(toCore(formatted)), stripOrigins(toCore(source, lexicon)), formatted);
|
|
47
|
+
return formatted;
|
|
48
|
+
}
|
|
49
|
+
const FIXTURES = [
|
|
50
|
+
['governance-sugar.aster', EN_US],
|
|
51
|
+
['governance-sugar-long.aster', EN_US],
|
|
52
|
+
['credit-pilot-v3.en.aster', EN_US],
|
|
53
|
+
['credit-pilot-v3.zh.aster', ZH_CN],
|
|
54
|
+
['credit-pilot-v3.de.aster', DE_DE],
|
|
55
|
+
];
|
|
56
|
+
describe('格式化器往返(Core IR 不变)', () => {
|
|
57
|
+
for (const [file, lexicon] of FIXTURES) {
|
|
58
|
+
test(file, () => {
|
|
59
|
+
const formatted = assertRoundTrip(readFileSync(join(fixtureDir, file), 'utf8'), lexicon);
|
|
60
|
+
assert.doesNotMatch(formatted, /,:/);
|
|
61
|
+
assert.doesNotMatch(formatted, /(>=|<=|[<>*+]|\band)\(/);
|
|
62
|
+
assert.equal(formatCNL(formatted), formatted, '格式化须幂等');
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
test('If 与 Otherwise 块头不带逗号', () => {
|
|
66
|
+
const src = ['Module m.', '', 'Rule r given n as Int, produce Int:', ' If n at least 1:',
|
|
67
|
+
' Return 1.', ' Otherwise:', ' Return 0.', ''].join('\n');
|
|
68
|
+
const formatted = assertRoundTrip(src);
|
|
69
|
+
assert.match(formatted, /\n {2}If n at least 1:\n/);
|
|
70
|
+
assert.match(formatted, /\n {2}Otherwise:\n/);
|
|
71
|
+
});
|
|
72
|
+
test('数值字面量极值按普通十进制输出并原值往返', () => {
|
|
73
|
+
const literals = [
|
|
74
|
+
// [源文写法, 返回类型, 期望 Core 字面量值]
|
|
75
|
+
['0.0000001', 'Double', 1e-7],
|
|
76
|
+
['123456789012345678901234.5', 'Double', 123456789012345678901234.5],
|
|
77
|
+
['0.5', 'Double', 0.5],
|
|
78
|
+
['3.0', 'Double', 3],
|
|
79
|
+
['2147483647', 'Int', 2147483647],
|
|
80
|
+
['0', 'Int', 0],
|
|
81
|
+
['9223372036854775807L', 'Long', '9223372036854775807'],
|
|
82
|
+
];
|
|
83
|
+
for (const [literal, ret, value] of literals) {
|
|
84
|
+
const src = `Module m.\n\nRule r, produce ${ret}:\n Return ${literal}.\n`;
|
|
85
|
+
const formatted = assertRoundTrip(src);
|
|
86
|
+
assert.doesNotMatch(formatted, /\d[eE][+-]?\d/, formatted);
|
|
87
|
+
const ret0 = toCore(formatted).decls[0].body.statements[0];
|
|
88
|
+
assert.equal(ret0.expr.value, value, literal);
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
test('构造字段以逗号分隔,只在会贪婪吞并后续字段时加括号', () => {
|
|
92
|
+
const src = ['Module m.', '', 'Define Inner has x as Int, y as Int.', '',
|
|
93
|
+
'Define Outer has inner as Inner, wrapped as Option of Inner, n as Int, ok as Bool.', '',
|
|
94
|
+
'Rule r given k as Int, produce Outer:',
|
|
95
|
+
' Return Outer with inner set to (Inner with x set to 1, y set to 2), ' +
|
|
96
|
+
'wrapped set to some of (Inner with x set to k plus 1, y set to 4), n set to k plus 1, ok set to k at least 1 and true.',
|
|
97
|
+
''].join('\n');
|
|
98
|
+
const formatted = assertRoundTrip(src);
|
|
99
|
+
assert.match(formatted, /inner set to \(Inner with x set to 1, y set to 2\), wrapped set to \(some of Inner with x set to k plus 1, y set to 4\), n set to k plus 1, ok set to k at least 1 and true\./);
|
|
100
|
+
});
|
|
101
|
+
test('运算符按中缀输出,括号保持结合与优先级', () => {
|
|
102
|
+
const body = [
|
|
103
|
+
'Return (a plus b) times c.',
|
|
104
|
+
'Return a minus (b minus c).',
|
|
105
|
+
'Return a minus b minus c.',
|
|
106
|
+
'Return a divided by (b times c).',
|
|
107
|
+
'Return a integer divided by b modulo c.',
|
|
108
|
+
'Return (a plus b) at least c.',
|
|
109
|
+
'Return not (p and q).',
|
|
110
|
+
'Return not p and q.',
|
|
111
|
+
'Return p or q and r.',
|
|
112
|
+
'Return (p or q) and r.',
|
|
113
|
+
'Return a less than b or a greater than c.',
|
|
114
|
+
'Return a equals to b and a not equal to c.',
|
|
115
|
+
'Return a at most (if p then b else c).',
|
|
116
|
+
];
|
|
117
|
+
const funcs = body.map((line, i) => `Rule f${i} given a as Int, b as Int, c as Int, p as Bool, q as Bool, r as Bool, produce Int:\n ${line}`);
|
|
118
|
+
const formatted = assertRoundTrip(['Module m.', '', ...funcs, ''].join('\n\n'));
|
|
119
|
+
assert.match(formatted, /Return \(a plus b\) times c\./);
|
|
120
|
+
assert.match(formatted, /Return a minus \(b minus c\)\./);
|
|
121
|
+
assert.match(formatted, /Return a minus b minus c\./);
|
|
122
|
+
assert.match(formatted, /Return not \(p and q\)\./);
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
//# sourceMappingURL=formatter-roundtrip.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatter-roundtrip.test.js","sourceRoot":"","sources":["../../../test/unit/formatter-roundtrip.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"controls-registry-parity.test.d.ts","sourceRoot":"","sources":["../../../../test/unit/governance/controls-registry-parity.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { test } from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { readFileSync } from 'node:fs';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
import { CONTROLS_REGISTRY } from '../../../src/governance/controls-registry.data.js';
|
|
6
|
+
import { locateSiblingSource } from '../../helpers/sibling-source.js';
|
|
7
|
+
// 内置副本与真相源深度相等(ADR 0045 §2.2)。候选依次为:本地兄弟 locales、CI 子目录 locales、
|
|
8
|
+
// CI 已 checkout 的 core classpath 副本(core 侧有自己的 locales 一致性门禁,故传递相等)。
|
|
9
|
+
// CI 中全部缺失即失败;本地未并列 checkout 时跳过。
|
|
10
|
+
test('controls 副本与真相源一致', (t) => {
|
|
11
|
+
const cwd = process.cwd();
|
|
12
|
+
const source = locateSiblingSource([
|
|
13
|
+
join(cwd, '..', 'aster-lang-locales', 'controls', 'registry.json'),
|
|
14
|
+
join(cwd, 'aster-lang-locales', 'controls', 'registry.json'),
|
|
15
|
+
join(cwd, 'aster-lang-core', 'src', 'main', 'resources', 'governance', 'controls-registry.json'),
|
|
16
|
+
], 'aster-lang-locales 或 aster-lang-core 以校验控制项注册表副本一致性');
|
|
17
|
+
if (source === undefined)
|
|
18
|
+
return t.skip('本地未并列 checkout aster-lang-locales');
|
|
19
|
+
assert.deepEqual(CONTROLS_REGISTRY, JSON.parse(readFileSync(source, 'utf8')));
|
|
20
|
+
});
|
|
21
|
+
test('CI 中真相源缺失即失败而非跳过', () => {
|
|
22
|
+
const missing = [join(process.cwd(), 'no-such-dir', 'registry.json')];
|
|
23
|
+
assert.equal(locateSiblingSource(missing, 'x', {}), undefined);
|
|
24
|
+
assert.equal(locateSiblingSource(missing, 'x', { CI: '' }), undefined);
|
|
25
|
+
assert.throws(() => locateSiblingSource(missing, 'x', { CI: 'true' }), /CI 中必须 checkout x/);
|
|
26
|
+
assert.throws(() => locateSiblingSource(missing, 'x', { GITHUB_ACTIONS: 'true' }), /CI 中必须 checkout x/);
|
|
27
|
+
});
|
|
28
|
+
//# sourceMappingURL=controls-registry-parity.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"controls-registry-parity.test.js","sourceRoot":"","sources":["../../../../test/unit/governance/controls-registry-parity.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,iBAAiB,EAAE,MAAM,mDAAmD,CAAC;AACtF,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAEtE,iEAAiE;AACjE,qEAAqE;AACrE,kCAAkC;AAClC,IAAI,CAAC,mBAAmB,EAAE,CAAC,CAAC,EAAE,EAAE;IAC9B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC1B,MAAM,MAAM,GAAG,mBAAmB,CAChC;QACE,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,oBAAoB,EAAE,UAAU,EAAE,eAAe,CAAC;QAClE,IAAI,CAAC,GAAG,EAAE,oBAAoB,EAAE,UAAU,EAAE,eAAe,CAAC;QAC5D,IAAI,CAAC,GAAG,EAAE,iBAAiB,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,wBAAwB,CAAC;KACjG,EACD,qDAAqD,CACtD,CAAC;IACF,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,CAAC,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;IAC7E,MAAM,CAAC,SAAS,CAAC,iBAAiB,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;AAChF,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAC5B,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,eAAe,CAAC,CAAC,CAAC;IACtE,MAAM,CAAC,KAAK,CAAC,mBAAmB,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC;IAC/D,MAAM,CAAC,KAAK,CAAC,mBAAmB,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC;IACvE,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,mBAAmB,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,mBAAmB,CAAC,CAAC;IAC5F,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,mBAAmB,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE,cAAc,EAAE,MAAM,EAAE,CAAC,EAAE,mBAAmB,CAAC,CAAC;AAC1G,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"controls-registry-profiles.test.d.ts","sourceRoot":"","sources":["../../../../test/unit/governance/controls-registry-profiles.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { test } from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { canonicalize } from '../../../src/frontend/canonicalizer.js';
|
|
4
|
+
import { lex } from '../../../src/frontend/lexer.js';
|
|
5
|
+
import { parse } from '../../../src/parser.js';
|
|
6
|
+
import { lowerModule } from '../../../src/lower_to_core.js';
|
|
7
|
+
import { typecheckModule } from '../../../src/typecheck.js';
|
|
8
|
+
import { controlRegistryFrom } from '../../../src/governance/controls.js';
|
|
9
|
+
// 注册表档案读取:与 Java ControlRegistryTest 的档案用例逐条对应(规则同 locales 校验口径)。
|
|
10
|
+
// 注入的注册表可能来自运行时 JSON,故以 unknown 构造畸形输入。
|
|
11
|
+
function registryWithProfiles(profiles) {
|
|
12
|
+
return controlRegistryFrom({
|
|
13
|
+
version: '9',
|
|
14
|
+
frameworks: [{ id: 'EU_AI_ACT', title: { en: 'a', zh: 'a', de: 'a' } }],
|
|
15
|
+
controls: [{ key: 'EU_AI_ACT:ART14', framework: 'EU_AI_ACT', article: '14', title: { en: 'a', zh: 'a', de: 'a' } }],
|
|
16
|
+
clauses: [],
|
|
17
|
+
profiles,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
function profile(id, ruleId, registered, frameworks) {
|
|
21
|
+
const requires = { ruleId, registeredControls: registered, frameworks };
|
|
22
|
+
return id === undefined ? { requires } : { id, requires };
|
|
23
|
+
}
|
|
24
|
+
function profileIds(r, candidates) {
|
|
25
|
+
return candidates.filter((id) => r.profile?.(id) !== undefined);
|
|
26
|
+
}
|
|
27
|
+
test('合法档案照常登记', () => {
|
|
28
|
+
const hr = registryWithProfiles([profile('hr', true, false, ['EU_AI_ACT'])]).profile?.('hr');
|
|
29
|
+
assert.deepEqual(hr, { id: 'hr', ruleId: true, registeredControls: false, frameworks: ['EU_AI_ACT'] });
|
|
30
|
+
});
|
|
31
|
+
test('畸形档案不登记且不影响其它档案', () => {
|
|
32
|
+
const good = profile('ok', true, true, []);
|
|
33
|
+
const bad = [
|
|
34
|
+
profile(undefined, true, true, []),
|
|
35
|
+
profile(42, true, true, []),
|
|
36
|
+
profile('Bad_Id', true, true, []),
|
|
37
|
+
profile('x' + 'a'.repeat(64), true, true, []),
|
|
38
|
+
profile('bad', 'yes', true, []),
|
|
39
|
+
profile('bad', true, 1, []),
|
|
40
|
+
profile('bad', true, true, 'EU_AI_ACT'),
|
|
41
|
+
profile('bad', true, true, ['NOPE']),
|
|
42
|
+
profile('bad', true, true, [7]),
|
|
43
|
+
{ id: 'bad' },
|
|
44
|
+
];
|
|
45
|
+
const candidates = ['ok', 'bad', 'Bad_Id', 'x' + 'a'.repeat(64), '42'];
|
|
46
|
+
for (const b of bad) {
|
|
47
|
+
assert.deepEqual(profileIds(registryWithProfiles([good, b]), candidates), ['ok'], JSON.stringify(b));
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
test('重复档案 id 全部不登记', () => {
|
|
51
|
+
const r = registryWithProfiles([profile('dup', true, true, []), profile('dup', false, false, []), profile('ok', true, true, [])]);
|
|
52
|
+
assert.equal(r.profile?.('dup'), undefined);
|
|
53
|
+
assert.notEqual(r.profile?.('ok'), undefined);
|
|
54
|
+
});
|
|
55
|
+
test('profiles 不是数组抛出', () => {
|
|
56
|
+
assert.throws(() => registryWithProfiles({}), /profiles/);
|
|
57
|
+
});
|
|
58
|
+
test('profiles 为 null 视为无档案', () => {
|
|
59
|
+
assert.equal(registryWithProfiles(null).profile?.('governed'), undefined);
|
|
60
|
+
});
|
|
61
|
+
test('声明畸形档案的模块得到 E705', () => {
|
|
62
|
+
const r = registryWithProfiles([profile('acme', true, true, ['NOPE'])]);
|
|
63
|
+
const src = 'Module m.\nProfile "acme".\n\nRule r produce Int:\n Return 1.\n';
|
|
64
|
+
const diags = typecheckModule(lowerModule(parse(lex(canonicalize(src))).ast), { controls: r });
|
|
65
|
+
assert.equal(diags.filter((d) => d.code === "E705" /* ErrorCode.GOV_PROFILE_UNKNOWN */).length, 1, JSON.stringify(diags));
|
|
66
|
+
});
|
|
67
|
+
// 根 frameworks 形态不可信:非数组、null/非对象条目、空白 id 都不抛出,只是不计入已登记框架
|
|
68
|
+
function registryWithFrameworks(frameworks) {
|
|
69
|
+
return controlRegistryFrom({
|
|
70
|
+
version: '9',
|
|
71
|
+
frameworks,
|
|
72
|
+
controls: [],
|
|
73
|
+
clauses: [],
|
|
74
|
+
profiles: [profile('ok', true, true, []), profile('blank', true, true, ['']), profile('eu', true, true, ['EU_AI_ACT'])],
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
test('根 frameworks 畸形时不抛出,畸形条目与空白 id 不计入', () => {
|
|
78
|
+
const variants = [
|
|
79
|
+
'EU_AI_ACT',
|
|
80
|
+
null,
|
|
81
|
+
[null, 7, 'EU_AI_ACT', { id: '' }, { id: ' ' }, { id: 3 }],
|
|
82
|
+
];
|
|
83
|
+
for (const fws of variants) {
|
|
84
|
+
const r = registryWithFrameworks(fws);
|
|
85
|
+
assert.deepEqual(profileIds(r, ['ok', 'blank', 'eu']), ['ok'], JSON.stringify(fws));
|
|
86
|
+
}
|
|
87
|
+
const good = registryWithFrameworks([null, { id: ' ' }, { id: 'EU_AI_ACT' }]);
|
|
88
|
+
assert.deepEqual(profileIds(good, ['ok', 'blank', 'eu']), ['ok', 'eu']);
|
|
89
|
+
});
|
|
90
|
+
// 空白的确切定义:只由 ASCII 空白(空格 \t \n \v \f \r,即 Java 正则默认的 \s)组成;
|
|
91
|
+
// 其它 Unicode 空白(如 NBSP)不算空白,id 照常登记,以便 Java 用 id.matches("\\s*") 得到同一结果
|
|
92
|
+
test('空白 id 只按 ASCII 空白判定', () => {
|
|
93
|
+
for (const blank of ['', ' ', '\t\n\v\f\r ']) {
|
|
94
|
+
const r = controlRegistryFrom({
|
|
95
|
+
version: '9', frameworks: [{ id: blank }], controls: [], clauses: [],
|
|
96
|
+
profiles: [profile('p', true, true, [blank])],
|
|
97
|
+
});
|
|
98
|
+
assert.equal(r.profile?.('p'), undefined, JSON.stringify(blank));
|
|
99
|
+
}
|
|
100
|
+
const nbsp = controlRegistryFrom({
|
|
101
|
+
version: '9', frameworks: [{ id: ' ' }], controls: [], clauses: [],
|
|
102
|
+
profiles: [profile('p', true, true, [' '])],
|
|
103
|
+
});
|
|
104
|
+
assert.deepEqual(nbsp.profile?.('p')?.frameworks, [' ']);
|
|
105
|
+
});
|
|
106
|
+
//# sourceMappingURL=controls-registry-profiles.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"controls-registry-profiles.test.js","sourceRoot":"","sources":["../../../../test/unit/governance/controls-registry-profiles.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"governance-check.test.d.ts","sourceRoot":"","sources":["../../../../test/unit/governance/governance-check.test.ts"],"names":[],"mappings":""}
|