@aster-cloud/aster-lang-ts 1.0.30 → 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,169 @@
|
|
|
1
|
+
import { test } from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
import { canonicalize } from '../../../src/frontend/canonicalizer.js';
|
|
6
|
+
import { lex } from '../../../src/frontend/lexer.js';
|
|
7
|
+
import { parse } from '../../../src/parser.js';
|
|
8
|
+
import { lowerModule } from '../../../src/lower_to_core.js';
|
|
9
|
+
import { typecheckModule } from '../../../src/typecheck.js';
|
|
10
|
+
import { typecheckBrowser } from '../../../src/typecheck/browser.js';
|
|
11
|
+
import { compileAndTypecheck } from '../../../src/browser.js';
|
|
12
|
+
import { Core } from '../../../src/core/core_ir.js';
|
|
13
|
+
import { checkGovernance, controls, returnsVerdict, ruleId } from '../../../src/typecheck/governance.js';
|
|
14
|
+
function coreOf(body) {
|
|
15
|
+
const src = `Module probe.\n${body}\n`;
|
|
16
|
+
const ast = parse(lex(canonicalize(src))).ast;
|
|
17
|
+
return lowerModule(ast);
|
|
18
|
+
}
|
|
19
|
+
function diagnoseFull(body) {
|
|
20
|
+
return typecheckModule(coreOf(body));
|
|
21
|
+
}
|
|
22
|
+
function diagnose(body) {
|
|
23
|
+
return diagnoseFull(body).map((d) => String(d.code));
|
|
24
|
+
}
|
|
25
|
+
/** 手工构造一个规则函数,用于覆盖 CNL 语法难以产出的 Core 形态。 */
|
|
26
|
+
function handFunc(name, body, annotations = []) {
|
|
27
|
+
return Core.Func(name, [], [], Core.TypeName('Unknown'), [], body, [], false, undefined, undefined, annotations);
|
|
28
|
+
}
|
|
29
|
+
const VERDICT_RULE = 'Rule main produce Verdict:\n Return Verdict.allow().';
|
|
30
|
+
test('返回 Verdict 且无 @id 报 W700', () => {
|
|
31
|
+
assert.ok(diagnose(VERDICT_RULE).includes("W700" /* ErrorCode.GOV_VERDICT_RULE_MISSING_ID */));
|
|
32
|
+
});
|
|
33
|
+
test('未声明返回类型但返回 Verdict 调用也报 W700', () => {
|
|
34
|
+
assert.ok(diagnose('Rule main produce:\n Return Verdict.deny("no").').includes("W700" /* ErrorCode.GOV_VERDICT_RULE_MISSING_ID */));
|
|
35
|
+
});
|
|
36
|
+
test('有 @id 不报 W700', () => {
|
|
37
|
+
assert.ok(!diagnose(`@id("R-1")\n${VERDICT_RULE}`).includes("W700" /* ErrorCode.GOV_VERDICT_RULE_MISSING_ID */));
|
|
38
|
+
});
|
|
39
|
+
test('返回 Bool 不报 W700', () => {
|
|
40
|
+
assert.ok(!diagnose('Rule main produce Bool:\n Return true.').includes("W700" /* ErrorCode.GOV_VERDICT_RULE_MISSING_ID */));
|
|
41
|
+
});
|
|
42
|
+
test('重复 @id 报恰好一个 E701,列出全部规则', () => {
|
|
43
|
+
const diags = diagnoseFull('@id("R-1")\nRule alpha produce Verdict:\n Return Verdict.allow().\n\n@id("R-1")\nRule beta produce Verdict:\n Return Verdict.allow().');
|
|
44
|
+
const dup = diags.filter((d) => d.code === "E701" /* ErrorCode.GOV_DUPLICATE_RULE_ID */);
|
|
45
|
+
assert.equal(dup.length, 1, diags.map((d) => d.code).join(','));
|
|
46
|
+
assert.equal(dup[0].data.rules, 'alpha, beta');
|
|
47
|
+
assert.equal(dup[0].data.id, 'R-1');
|
|
48
|
+
});
|
|
49
|
+
test('@id 非字符串报 E702', () => {
|
|
50
|
+
assert.ok(diagnose(`@id(42)\n${VERDICT_RULE}`).includes("E702" /* ErrorCode.GOV_ANNOTATION_ARG_INVALID */));
|
|
51
|
+
});
|
|
52
|
+
test('@id 命名参数报 E702', () => {
|
|
53
|
+
assert.ok(diagnose(`@id(value: "R-1")\n${VERDICT_RULE}`).includes("E702" /* ErrorCode.GOV_ANNOTATION_ARG_INVALID */));
|
|
54
|
+
});
|
|
55
|
+
test('@control 可重复', () => {
|
|
56
|
+
const codes = diagnose(`@id("R-1")\n@control("EU_AI_ACT:ART14")\n@control("GDPR:ART6")\n${VERDICT_RULE}`);
|
|
57
|
+
assert.equal(codes.filter((c) => c === 'W700' || c === 'E701' || c === 'E702').length, 0, codes.join(','));
|
|
58
|
+
});
|
|
59
|
+
test('用户 Define Verdict 报 DUPLICATE_SYMBOL', () => {
|
|
60
|
+
assert.ok(diagnose('Define Verdict has approved.\n\nRule main produce Bool:\n Return true.').includes("E104" /* ErrorCode.DUPLICATE_SYMBOL */));
|
|
61
|
+
});
|
|
62
|
+
test('空白 @id("") 报 E702 且同时报 W700', () => {
|
|
63
|
+
const codes = diagnose(`@id("")\n${VERDICT_RULE}`);
|
|
64
|
+
assert.ok(codes.includes("E702" /* ErrorCode.GOV_ANNOTATION_ARG_INVALID */), codes.join(','));
|
|
65
|
+
assert.ok(codes.includes("W700" /* ErrorCode.GOV_VERDICT_RULE_MISSING_ID */), codes.join(','));
|
|
66
|
+
});
|
|
67
|
+
test('同一规则多个 @id 报 E702,ruleId 为空', () => {
|
|
68
|
+
const m = coreOf(`@id("A")\n@id("B")\n${VERDICT_RULE}`);
|
|
69
|
+
const diags = typecheckModule(m);
|
|
70
|
+
const e702 = diags.filter((d) => d.code === "E702" /* ErrorCode.GOV_ANNOTATION_ARG_INVALID */);
|
|
71
|
+
assert.equal(e702.length, 1, diags.map((d) => d.code).join(','));
|
|
72
|
+
assert.equal(e702[0].data.annotation, 'id');
|
|
73
|
+
const func = m.decls.find((d) => d.kind === 'Func');
|
|
74
|
+
assert.equal(ruleId(func), undefined);
|
|
75
|
+
});
|
|
76
|
+
test('@reason 非字符串报 E702', () => {
|
|
77
|
+
const diags = diagnoseFull(`@id("R-1")\n@reason(42)\n${VERDICT_RULE}`);
|
|
78
|
+
const e702 = diags.filter((d) => d.code === "E702" /* ErrorCode.GOV_ANNOTATION_ARG_INVALID */);
|
|
79
|
+
assert.equal(e702.length, 1, diags.map((d) => d.code).join(','));
|
|
80
|
+
assert.equal(e702[0].data.annotation, 'reason');
|
|
81
|
+
});
|
|
82
|
+
test('ruleId / controls 读取合法注解值', () => {
|
|
83
|
+
const m = coreOf(`@id("R-1")\n@control("EU_AI_ACT:ART14")\n@control("GDPR:ART6")\n@control("")\n${VERDICT_RULE}`);
|
|
84
|
+
const func = m.decls.find((d) => d.kind === 'Func');
|
|
85
|
+
assert.equal(ruleId(func), 'R-1');
|
|
86
|
+
assert.deepEqual(controls(func), ['EU_AI_ACT:ART14', 'GDPR:ART6']);
|
|
87
|
+
});
|
|
88
|
+
test('returnsVerdict 穿透 Block → Scope → Return(手工构造 Core IR)', () => {
|
|
89
|
+
const ret = Core.Return(Core.Call(Core.Name('Verdict.deny'), [Core.String('no')]));
|
|
90
|
+
const func = handFunc('main', Core.Block([Core.Scope([ret])]));
|
|
91
|
+
assert.equal(returnsVerdict(func), true);
|
|
92
|
+
const codes = checkGovernance({ name: 'probe', decls: [func] }).map((d) => d.code);
|
|
93
|
+
assert.deepEqual(codes, ["W700" /* ErrorCode.GOV_VERDICT_RULE_MISSING_ID */]);
|
|
94
|
+
});
|
|
95
|
+
test('returnsVerdict 不经由变量判定', () => {
|
|
96
|
+
const body = Core.Block([
|
|
97
|
+
Core.Let('v', Core.Call(Core.Name('Verdict.allow'), [])),
|
|
98
|
+
Core.Return(Core.Name('v')),
|
|
99
|
+
]);
|
|
100
|
+
assert.equal(returnsVerdict(handFunc('main', body)), false);
|
|
101
|
+
});
|
|
102
|
+
test('注解 name 为 null/undefined 不抛异常', () => {
|
|
103
|
+
const bogus = [{ name: null }, { name: undefined }];
|
|
104
|
+
const func = handFunc('main', Core.Block([Core.Return(Core.Bool(true))]), bogus);
|
|
105
|
+
assert.doesNotThrow(() => checkGovernance({ name: 'probe', decls: [func] }));
|
|
106
|
+
assert.deepEqual(checkGovernance({ name: 'probe', decls: [func] }), []);
|
|
107
|
+
assert.equal(ruleId(func), undefined);
|
|
108
|
+
assert.deepEqual(controls(func), []);
|
|
109
|
+
});
|
|
110
|
+
test('浏览器路径同样报 W700', () => {
|
|
111
|
+
const codes = typecheckBrowser(coreOf(VERDICT_RULE)).map((d) => String(d.code));
|
|
112
|
+
assert.ok(codes.includes("W700" /* ErrorCode.GOV_VERDICT_RULE_MISSING_ID */), codes.join(','));
|
|
113
|
+
});
|
|
114
|
+
test('已登记控制点无 W704', () => {
|
|
115
|
+
const codes = diagnose(`@id("R-1")\n@control("EU_AI_ACT:ART14")\n${VERDICT_RULE}`);
|
|
116
|
+
assert.equal(codes.filter((c) => c === 'W704').length, 0, codes.join(','));
|
|
117
|
+
});
|
|
118
|
+
test('未登记与形态非法都报 W704,同键只报一次', () => {
|
|
119
|
+
const codes = diagnose(`@id("R-1")\n@control("ACME:ART1")\n@control("ACME:ART1")\n@control("eu_ai_act:art14")\n${VERDICT_RULE}`);
|
|
120
|
+
assert.equal(codes.filter((c) => c === 'W704').length, 2, codes.join(','));
|
|
121
|
+
});
|
|
122
|
+
test('注入空注册表时已登记键也报 W704', () => {
|
|
123
|
+
const empty = { version: '0.0.0', has: () => false };
|
|
124
|
+
const fn = handFunc('main', Core.Block([]), [
|
|
125
|
+
{ name: 'id', args: [{ name: '$0', value: 'R-1' }] },
|
|
126
|
+
{ name: 'control', args: [{ name: '$0', value: 'EU_AI_ACT:ART14' }] },
|
|
127
|
+
]);
|
|
128
|
+
const diags = checkGovernance({ name: 'probe', decls: [fn] }, { controls: empty });
|
|
129
|
+
assert.ok(diags.some((d) => d.code === 'W704'), JSON.stringify(diags));
|
|
130
|
+
});
|
|
131
|
+
test('注入的注册表放行一切时形态非法键仍报 W704', () => {
|
|
132
|
+
const permissive = { version: 'x', has: () => true };
|
|
133
|
+
const body = `@id("R-1")\n@control("eu_ai_act:art14")\n${VERDICT_RULE}`;
|
|
134
|
+
const diags = typecheckModule(coreOf(body), { controls: permissive });
|
|
135
|
+
const w704 = diags.filter((d) => d.code === "W704" /* ErrorCode.GOV_CONTROL_UNREGISTERED */);
|
|
136
|
+
assert.equal(w704.length, 1, JSON.stringify(diags));
|
|
137
|
+
});
|
|
138
|
+
test('注入的注册表沿 Node / 浏览器 / compileAndTypecheck 透传', () => {
|
|
139
|
+
const empty = { version: '0.0.0', has: () => false };
|
|
140
|
+
const body = `@id("R-1")\n@control("EU_AI_ACT:ART14")\n${VERDICT_RULE}`;
|
|
141
|
+
const nodeCodes = typecheckModule(coreOf(body), { controls: empty }).map((d) => String(d.code));
|
|
142
|
+
const browserCodes = typecheckBrowser(coreOf(body), { controls: empty }).map((d) => String(d.code));
|
|
143
|
+
const compiled = compileAndTypecheck(`Module probe.\n${body}\n`, { controls: empty });
|
|
144
|
+
const compiledCodes = compiled.typeErrors.map((d) => String(d.code));
|
|
145
|
+
for (const codes of [nodeCodes, browserCodes, compiledCodes]) {
|
|
146
|
+
assert.ok(codes.includes("W704" /* ErrorCode.GOV_CONTROL_UNREGISTERED */), codes.join(','));
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
// 诊断黄金(ADR 0045 §3):源文在 aster-lang-test tier3 type-checker 桶,期望在本仓 expected/;
|
|
150
|
+
// 既有 golden 回归脚本读 npm 版语料,新源文发布前读不到,故直读兄弟仓(本地 ../ 或 CI 工作区 ./)。
|
|
151
|
+
// CI 的 test job 会 checkout aster-lang-test,因此 CI 中缺失即失败;仅本地未并列 checkout 时跳过。
|
|
152
|
+
test('W704 诊断黄金与期望文件一致', (t) => {
|
|
153
|
+
const name = 'governance_control_unregistered';
|
|
154
|
+
const relative = ['corpus', 'tier3-fixtures', 'type-checker', `${name}.aster`];
|
|
155
|
+
const source = [
|
|
156
|
+
join(process.cwd(), '..', 'aster-lang-test', ...relative),
|
|
157
|
+
join(process.cwd(), 'aster-lang-test', ...relative),
|
|
158
|
+
].find((c) => existsSync(c));
|
|
159
|
+
if (source === undefined) {
|
|
160
|
+
assert.ok(!process.env.CI, 'CI 中须 checkout aster-lang-test(见 .github/workflows/ci.yml test job)');
|
|
161
|
+
return t.skip('aster-lang-test 未并列 checkout');
|
|
162
|
+
}
|
|
163
|
+
const ast = parse(lex(canonicalize(readFileSync(source, 'utf8')))).ast;
|
|
164
|
+
const actual = typecheckModule(lowerModule(ast)).map(({ code, severity, message }) => ({ code, severity, message }));
|
|
165
|
+
const expectedPath = join(process.cwd(), 'test', 'type-checker', 'expected', `${name}.errors.json`);
|
|
166
|
+
const expected = JSON.parse(readFileSync(expectedPath, 'utf8')).diagnostics;
|
|
167
|
+
assert.deepEqual(actual, expected);
|
|
168
|
+
});
|
|
169
|
+
//# sourceMappingURL=governance-check.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"governance-check.test.js","sourceRoot":"","sources":["../../../../test/unit/governance/governance-check.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,wCAAwC,CAAC;AACtE,OAAO,EAAE,GAAG,EAAE,MAAM,gCAAgC,CAAC;AACrD,OAAO,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AACrE,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,IAAI,EAAE,MAAM,8BAA8B,CAAC;AAEpD,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,sCAAsC,CAAC;AAGzG,SAAS,MAAM,CAAC,IAAY;IAC1B,MAAM,GAAG,GAAG,kBAAkB,IAAI,IAAI,CAAC;IACvC,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAgB,CAAC;IAC3D,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,YAAY,CAAC,IAAY;IAChC,OAAO,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;AACvC,CAAC;AAED,SAAS,QAAQ,CAAC,IAAY;IAC5B,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AACvD,CAAC;AAED,2CAA2C;AAC3C,SAAS,QAAQ,CAAC,IAAY,EAAE,IAAqB,EAAE,cAAqC,EAAE;IAC5F,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;AACnH,CAAC;AAED,MAAM,YAAY,GAAG,uDAAuD,CAAC;AAE7E,IAAI,CAAC,0BAA0B,EAAE,GAAG,EAAE;IACpC,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,QAAQ,oDAAuC,CAAC,CAAC;AACpF,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,8BAA8B,EAAE,GAAG,EAAE;IACxC,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,kDAAkD,CAAC,CAAC,QAAQ,oDAAuC,CAAC,CAAC;AAC1H,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,eAAe,EAAE,GAAG,EAAE;IACzB,MAAM,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,eAAe,YAAY,EAAE,CAAC,CAAC,QAAQ,oDAAuC,CAAC,CAAC;AACtG,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC3B,MAAM,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,yCAAyC,CAAC,CAAC,QAAQ,oDAAuC,CAAC,CAAC;AAClH,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,0BAA0B,EAAE,GAAG,EAAE;IACpC,MAAM,KAAK,GAAG,YAAY,CACxB,yIAAyI,CAC1I,CAAC;IACF,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,iDAAoC,CAAC,CAAC;IAC5E,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAChE,MAAM,CAAC,KAAK,CAAE,GAAG,CAAC,CAAC,CAAE,CAAC,IAA0B,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC;IACvE,MAAM,CAAC,KAAK,CAAE,GAAG,CAAC,CAAC,CAAE,CAAC,IAAuB,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;AAC3D,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,gBAAgB,EAAE,GAAG,EAAE;IAC1B,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,YAAY,YAAY,EAAE,CAAC,CAAC,QAAQ,mDAAsC,CAAC,CAAC;AACjG,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,gBAAgB,EAAE,GAAG,EAAE;IAC1B,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,sBAAsB,YAAY,EAAE,CAAC,CAAC,QAAQ,mDAAsC,CAAC,CAAC;AAC3G,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,cAAc,EAAE,GAAG,EAAE;IACxB,MAAM,KAAK,GAAG,QAAQ,CAAC,mEAAmE,YAAY,EAAE,CAAC,CAAC;IAC1G,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,MAAM,IAAI,CAAC,KAAK,MAAM,IAAI,CAAC,KAAK,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC7G,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,sCAAsC,EAAE,GAAG,EAAE;IAChD,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,yEAAyE,CAAC,CAAC,QAAQ,yCAA4B,CAAC,CAAC;AACtI,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,6BAA6B,EAAE,GAAG,EAAE;IACvC,MAAM,KAAK,GAAG,QAAQ,CAAC,YAAY,YAAY,EAAE,CAAC,CAAC;IACnD,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,mDAAsC,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACjF,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,oDAAuC,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AACpF,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,6BAA6B,EAAE,GAAG,EAAE;IACvC,MAAM,CAAC,GAAG,MAAM,CAAC,uBAAuB,YAAY,EAAE,CAAC,CAAC;IACxD,MAAM,KAAK,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC;IACjC,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,sDAAyC,CAAC,CAAC;IAClF,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACjE,MAAM,CAAC,KAAK,CAAE,IAAI,CAAC,CAAC,CAAE,CAAC,IAA+B,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;IACzE,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAuB,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAE,CAAC;IAC1E,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,CAAC;AACxC,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAC9B,MAAM,KAAK,GAAG,YAAY,CAAC,4BAA4B,YAAY,EAAE,CAAC,CAAC;IACvE,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,sDAAyC,CAAC,CAAC;IAClF,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACjE,MAAM,CAAC,KAAK,CAAE,IAAI,CAAC,CAAC,CAAE,CAAC,IAA+B,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;AAC/E,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,2BAA2B,EAAE,GAAG,EAAE;IACrC,MAAM,CAAC,GAAG,MAAM,CAAC,iFAAiF,YAAY,EAAE,CAAC,CAAC;IAClH,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAuB,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAE,CAAC;IAC1E,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;IAClC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,iBAAiB,EAAE,WAAW,CAAC,CAAC,CAAC;AACrE,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,wDAAwD,EAAE,GAAG,EAAE;IAClE,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACnF,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/D,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;IACzC,MAAM,KAAK,GAAG,eAAe,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACnF,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,oDAAuC,CAAC,CAAC;AACnE,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,wBAAwB,EAAE,GAAG,EAAE;IAClC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC;QACtB,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,EAAE,CAAC,CAAC;QACxD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;KAC5B,CAAC,CAAC;IACH,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;AAC9D,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,+BAA+B,EAAE,GAAG,EAAE;IACzC,MAAM,KAAK,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,CAA4B,CAAC;IAC/E,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IACjF,MAAM,CAAC,YAAY,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IAC7E,MAAM,CAAC,SAAS,CAAC,eAAe,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;IACxE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,CAAC;IACtC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;AACvC,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,eAAe,EAAE,GAAG,EAAE;IACzB,MAAM,KAAK,GAAG,gBAAgB,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAChF,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,oDAAuC,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AACpF,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,cAAc,EAAE,GAAG,EAAE;IACxB,MAAM,KAAK,GAAG,QAAQ,CAAC,4CAA4C,YAAY,EAAE,CAAC,CAAC;IACnF,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC7E,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,wBAAwB,EAAE,GAAG,EAAE;IAClC,MAAM,KAAK,GAAG,QAAQ,CAAC,0FAA0F,YAAY,EAAE,CAAC,CAAC;IACjI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC7E,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAC9B,MAAM,KAAK,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,KAAK,EAAE,CAAC;IACrD,MAAM,EAAE,GAAG,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE;QAC1C,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE;QACpD,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC,EAAE;KACtE,CAAC,CAAC;IACH,MAAM,KAAK,GAAG,eAAe,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;IACnF,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;AACzE,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,yBAAyB,EAAE,GAAG,EAAE;IACnC,MAAM,UAAU,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC;IACrD,MAAM,IAAI,GAAG,4CAA4C,YAAY,EAAE,CAAC;IACxE,MAAM,KAAK,GAAG,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,CAAC;IACtE,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,oDAAuC,CAAC,CAAC;IAChF,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;AACtD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,6CAA6C,EAAE,GAAG,EAAE;IACvD,MAAM,KAAK,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,KAAK,EAAE,CAAC;IACrD,MAAM,IAAI,GAAG,4CAA4C,YAAY,EAAE,CAAC;IACxE,MAAM,SAAS,GAAG,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAChG,MAAM,YAAY,GAAG,gBAAgB,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACpG,MAAM,QAAQ,GAAG,mBAAmB,CAAC,kBAAkB,IAAI,IAAI,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;IACtF,MAAM,aAAa,GAAG,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACrE,KAAK,MAAM,KAAK,IAAI,CAAC,SAAS,EAAE,YAAY,EAAE,aAAa,CAAC,EAAE,CAAC;QAC7D,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,iDAAoC,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACjF,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,8EAA8E;AAC9E,gEAAgE;AAChE,6EAA6E;AAC7E,IAAI,CAAC,kBAAkB,EAAE,CAAC,CAAC,EAAE,EAAE;IAC7B,MAAM,IAAI,GAAG,iCAAiC,CAAC;IAC/C,MAAM,QAAQ,GAAG,CAAC,QAAQ,EAAE,gBAAgB,EAAE,cAAc,EAAE,GAAG,IAAI,QAAQ,CAAC,CAAC;IAC/E,MAAM,MAAM,GAAG;QACb,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,iBAAiB,EAAE,GAAG,QAAQ,CAAC;QACzD,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,iBAAiB,EAAE,GAAG,QAAQ,CAAC;KACpD,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7B,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,MAAM,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,qEAAqE,CAAC,CAAC;QAClG,OAAO,CAAC,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;IAChD,CAAC;IACD,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,GAAgB,CAAC;IACpF,MAAM,MAAM,GAAG,eAAe,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;IACrH,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE,UAAU,EAAE,GAAG,IAAI,cAAc,CAAC,CAAC;IACpG,MAAM,QAAQ,GAAI,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CAAgC,CAAC,WAAW,CAAC;IAC5G,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;AACrC,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile-check.test.d.ts","sourceRoot":"","sources":["../../../../test/unit/governance/profile-check.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,139 @@
|
|
|
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 { typecheckBrowser } from '../../../src/typecheck/browser.js';
|
|
9
|
+
import { controlRegistryFrom, defaultControlRegistry } from '../../../src/governance/controls.js';
|
|
10
|
+
// ADR 0046 §4:档案检查。场景与 Java ProfileCheckTest 逐条对应(源码、错误码、数量、消息子串一致)。
|
|
11
|
+
function diagnoseSource(src, controls) {
|
|
12
|
+
const ast = parse(lex(canonicalize(src))).ast;
|
|
13
|
+
return typecheckModule(lowerModule(ast), controls ? { controls } : {});
|
|
14
|
+
}
|
|
15
|
+
/** 声明了档案的探针模块源码。 */
|
|
16
|
+
function profiled(id, body) {
|
|
17
|
+
return `Module probe.\nProfile "${id}".\n\n${body}\n`;
|
|
18
|
+
}
|
|
19
|
+
function count(d, code) {
|
|
20
|
+
return d.filter((x) => x.code === code).length;
|
|
21
|
+
}
|
|
22
|
+
/** 拼接某错误码的全部消息,便于断言包含关系。 */
|
|
23
|
+
function messages(d, code) {
|
|
24
|
+
return d.filter((x) => x.code === code).map((x) => x.message).join('\n');
|
|
25
|
+
}
|
|
26
|
+
const show = (d) => JSON.stringify(d.map(({ code, message }) => ({ code, message })));
|
|
27
|
+
test('未知档案报 E705', () => {
|
|
28
|
+
const diags = diagnoseSource('Module m.\nProfile "nope".\n\nRule r produce Int:\n Return 1.\n');
|
|
29
|
+
assert.equal(count(diags, "E705" /* ErrorCode.GOV_PROFILE_UNKNOWN */), 1, show(diags));
|
|
30
|
+
assert.ok(messages(diags, "E705" /* ErrorCode.GOV_PROFILE_UNKNOWN */).includes("unknown profile 'nope' (controls registry 1.1.0)"));
|
|
31
|
+
const e705 = diags.find((d) => d.code === "E705" /* ErrorCode.GOV_PROFILE_UNKNOWN */);
|
|
32
|
+
assert.equal(e705.span?.start.line, 1, 'E705 应定位到 Module 声明行');
|
|
33
|
+
});
|
|
34
|
+
test('缺 @id 报 E706 且 W700 照常', () => {
|
|
35
|
+
const diags = diagnoseSource(profiled('governed', 'Rule r produce Verdict:\n Return Verdict.allow().'));
|
|
36
|
+
assert.equal(count(diags, "E706" /* ErrorCode.GOV_PROFILE_VIOLATION */), 1, show(diags));
|
|
37
|
+
assert.equal(count(diags, "W700" /* ErrorCode.GOV_VERDICT_RULE_MISSING_ID */), 1);
|
|
38
|
+
assert.ok(messages(diags, "E706" /* ErrorCode.GOV_PROFILE_VIOLATION */).includes("Rule 'r' violates profile 'governed': missing @id"));
|
|
39
|
+
const e706 = diags.find((d) => d.code === "E706" /* ErrorCode.GOV_PROFILE_VIOLATION */);
|
|
40
|
+
assert.ok(e706.span !== undefined, 'E706 应定位到规则');
|
|
41
|
+
});
|
|
42
|
+
test('未登记控制点报 E706', () => {
|
|
43
|
+
const diags = diagnoseSource(profiled('governed', '@id("R-1")\n@control("ACME:ART1")\nRule r produce Verdict:\n Return Verdict.allow().'));
|
|
44
|
+
assert.ok(messages(diags, "E706" /* ErrorCode.GOV_PROFILE_VIOLATION */).includes('unregistered control ACME:ART1'), show(diags));
|
|
45
|
+
assert.equal(count(diags, "W704" /* ErrorCode.GOV_CONTROL_UNREGISTERED */), 1);
|
|
46
|
+
});
|
|
47
|
+
test('重复控制点每条要求只报一次', () => {
|
|
48
|
+
const diags = diagnoseSource(profiled('governed', '@id("R-1")\n@control("ACME:ART1")\n@control("ACME:ART1")\nRule r produce Verdict:\n Return Verdict.allow().'));
|
|
49
|
+
assert.equal(count(diags, "E706" /* ErrorCode.GOV_PROFILE_VIOLATION */), 1, show(diags));
|
|
50
|
+
});
|
|
51
|
+
test('缺所需框架控制点报 E706', () => {
|
|
52
|
+
const diags = diagnoseSource(profiled('eu-ai-act-high-risk', '@id("R-1")\n@control("GDPR:ART6")\nRule r produce Verdict:\n Return Verdict.allow().'));
|
|
53
|
+
assert.ok(messages(diags, "E706" /* ErrorCode.GOV_PROFILE_VIOLATION */).includes('no registered control from framework EU_AI_ACT'), show(diags));
|
|
54
|
+
assert.equal(count(diags, "E706" /* ErrorCode.GOV_PROFILE_VIOLATION */), 1);
|
|
55
|
+
});
|
|
56
|
+
test('合规规则零 E70x', () => {
|
|
57
|
+
const diags = diagnoseSource(profiled('eu-ai-act-high-risk', '@id("R-1")\n@control("EU_AI_ACT:ART14")\nRule r produce Verdict:\n Return Verdict.allow().'));
|
|
58
|
+
assert.equal(count(diags, "E706" /* ErrorCode.GOV_PROFILE_VIOLATION */) + count(diags, "E705" /* ErrorCode.GOV_PROFILE_UNKNOWN */), 0, show(diags));
|
|
59
|
+
});
|
|
60
|
+
test('非 Verdict 规则不受档案约束', () => {
|
|
61
|
+
const diags = diagnoseSource(profiled('governed', 'Rule helper produce Int:\n Return 1.'));
|
|
62
|
+
assert.equal(count(diags, "E706" /* ErrorCode.GOV_PROFILE_VIOLATION */), 0, show(diags));
|
|
63
|
+
});
|
|
64
|
+
test('未声明档案的模块零 E70x', () => {
|
|
65
|
+
const diags = diagnoseSource('Module m.\n\nRule r produce Verdict:\n Return Verdict.allow().\n');
|
|
66
|
+
assert.equal(count(diags, "E706" /* ErrorCode.GOV_PROFILE_VIOLATION */) + count(diags, "E705" /* ErrorCode.GOV_PROFILE_UNKNOWN */), 0, show(diags));
|
|
67
|
+
});
|
|
68
|
+
test('未知档案下缺 @id 的 Verdict 规则只报 E705 与 W700', () => {
|
|
69
|
+
const diags = diagnoseSource('Module m.\nProfile "nope".\n\nRule r produce Verdict:\n Return Verdict.allow().\n');
|
|
70
|
+
assert.equal(count(diags, "E705" /* ErrorCode.GOV_PROFILE_UNKNOWN */), 1, show(diags));
|
|
71
|
+
assert.equal(count(diags, "E706" /* ErrorCode.GOV_PROFILE_VIOLATION */), 0, show(diags));
|
|
72
|
+
assert.equal(count(diags, "W700" /* ErrorCode.GOV_VERDICT_RULE_MISSING_ID */), 1, show(diags));
|
|
73
|
+
});
|
|
74
|
+
test('高风险档案下未登记的同框架键同时违反两条要求', () => {
|
|
75
|
+
const diags = diagnoseSource(profiled('eu-ai-act-high-risk', '@id("R-1")\n@control("EU_AI_ACT:ART99")\nRule r produce Verdict:\n Return Verdict.allow().'));
|
|
76
|
+
const e706 = messages(diags, "E706" /* ErrorCode.GOV_PROFILE_VIOLATION */);
|
|
77
|
+
assert.ok(e706.includes('unregistered control EU_AI_ACT:ART99'), show(diags));
|
|
78
|
+
assert.ok(e706.includes('no registered control from framework EU_AI_ACT'), show(diags));
|
|
79
|
+
assert.equal(count(diags, "W704" /* ErrorCode.GOV_CONTROL_UNREGISTERED */), 1, show(diags));
|
|
80
|
+
});
|
|
81
|
+
test('注入的注册表携带自定义档案与框架', () => {
|
|
82
|
+
const custom = controlRegistryFrom({
|
|
83
|
+
version: '9.9.9',
|
|
84
|
+
// 档案引用的框架须在根 frameworks 中登记,否则档案不登记
|
|
85
|
+
frameworks: [
|
|
86
|
+
{ id: 'ACME', title: { en: 'a', zh: 'a', de: 'a' } },
|
|
87
|
+
{ id: 'SOX', title: { en: 's', zh: 's', de: 's' } },
|
|
88
|
+
],
|
|
89
|
+
controls: [
|
|
90
|
+
{ key: 'ACME:ART1', framework: 'ACME', article: '1', title: { en: 'a', zh: 'a', de: 'a' } },
|
|
91
|
+
{ key: 'acme:bad', framework: 'ACME', article: 'x', title: { en: 'b', zh: 'b', de: 'b' } },
|
|
92
|
+
],
|
|
93
|
+
clauses: [],
|
|
94
|
+
profiles: [
|
|
95
|
+
{ id: 'acme', title: { en: 'a', zh: 'a', de: 'a' }, requires: { ruleId: false, registeredControls: true, frameworks: ['ACME', 'SOX'] } },
|
|
96
|
+
],
|
|
97
|
+
});
|
|
98
|
+
const ok = diagnoseSource(profiled('acme', '@control("ACME:ART1")\nRule r produce Verdict:\n Return Verdict.allow().'), custom);
|
|
99
|
+
assert.equal(count(ok, "E706" /* ErrorCode.GOV_PROFILE_VIOLATION */) + count(ok, "E705" /* ErrorCode.GOV_PROFILE_UNKNOWN */), 0, show(ok));
|
|
100
|
+
// 形态非法键即便在注入数据中登记也不算已登记,亦不覆盖框架
|
|
101
|
+
const bad = diagnoseSource(profiled('acme', '@control("acme:bad")\nRule r produce Verdict:\n Return Verdict.allow().'), custom);
|
|
102
|
+
const e706 = messages(bad, "E706" /* ErrorCode.GOV_PROFILE_VIOLATION */);
|
|
103
|
+
assert.ok(e706.includes('unregistered control acme:bad'), show(bad));
|
|
104
|
+
assert.ok(e706.includes('no registered control from framework ACME, SOX'), show(bad));
|
|
105
|
+
// 默认档案在自定义注册表中不存在
|
|
106
|
+
const unknown = diagnoseSource(profiled('governed', 'Rule h produce Int:\n Return 1.'), custom);
|
|
107
|
+
assert.ok(messages(unknown, "E705" /* ErrorCode.GOV_PROFILE_UNKNOWN */).includes("unknown profile 'governed' (controls registry 9.9.9)"), show(unknown));
|
|
108
|
+
});
|
|
109
|
+
test('只含 version/has 的手写注册表视为无档案', () => {
|
|
110
|
+
const minimal = { version: '0.1.0', has: (k) => defaultControlRegistry.has(k) };
|
|
111
|
+
const diags = diagnoseSource(profiled('governed', '@id("R-1")\nRule r produce Verdict:\n Return Verdict.allow().'), minimal);
|
|
112
|
+
assert.equal(count(diags, "E705" /* ErrorCode.GOV_PROFILE_UNKNOWN */), 1, show(diags));
|
|
113
|
+
assert.equal(count(diags, "E706" /* ErrorCode.GOV_PROFILE_VIOLATION */), 0, show(diags));
|
|
114
|
+
});
|
|
115
|
+
test('默认注册表含档案与框架归属', () => {
|
|
116
|
+
assert.equal(defaultControlRegistry.version, '1.1.0');
|
|
117
|
+
assert.deepEqual(defaultControlRegistry.profile?.('governed'), { id: 'governed', ruleId: true, registeredControls: true, frameworks: [] });
|
|
118
|
+
assert.deepEqual(defaultControlRegistry.profile?.('eu-ai-act-high-risk')?.frameworks, ['EU_AI_ACT']);
|
|
119
|
+
assert.equal(defaultControlRegistry.profile?.('nope'), undefined);
|
|
120
|
+
assert.equal(defaultControlRegistry.frameworkOf?.('EU_AI_ACT:ART14'), 'EU_AI_ACT');
|
|
121
|
+
});
|
|
122
|
+
test('缺 profiles 的输入视为空档案', () => {
|
|
123
|
+
const r = controlRegistryFrom({
|
|
124
|
+
version: '9',
|
|
125
|
+
frameworks: [],
|
|
126
|
+
controls: [{ key: 'A:B', framework: 'A', article: 'B', title: { en: 'a', zh: 'a', de: 'a' } }],
|
|
127
|
+
clauses: [],
|
|
128
|
+
});
|
|
129
|
+
assert.equal(r.profile?.('governed'), undefined);
|
|
130
|
+
assert.equal(r.has('A:B'), true);
|
|
131
|
+
});
|
|
132
|
+
test('浏览器类型检查路径同样报 E705', () => {
|
|
133
|
+
const src = 'Module m.\nProfile "nope".\n\nRule r produce Int:\n Return 1.\n';
|
|
134
|
+
const core = lowerModule(parse(lex(canonicalize(src))).ast);
|
|
135
|
+
const diags = typecheckBrowser(core);
|
|
136
|
+
assert.equal(count(diags, "E705" /* ErrorCode.GOV_PROFILE_UNKNOWN */), 1, show(diags));
|
|
137
|
+
assert.ok(messages(diags, "E705" /* ErrorCode.GOV_PROFILE_UNKNOWN */).includes("unknown profile 'nope' (controls registry 1.1.0)"));
|
|
138
|
+
});
|
|
139
|
+
//# sourceMappingURL=profile-check.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile-check.test.js","sourceRoot":"","sources":["../../../../test/unit/governance/profile-check.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verdict-typecheck.test.d.ts","sourceRoot":"","sources":["../../../../test/unit/governance/verdict-typecheck.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,80 @@
|
|
|
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
|
+
function diagnose(body) {
|
|
9
|
+
const src = `Module probe.\n${body}\n`;
|
|
10
|
+
const ast = parse(lex(canonicalize(src))).ast;
|
|
11
|
+
const core = lowerModule(ast);
|
|
12
|
+
return typecheckModule(core).map((d) => String(d.code));
|
|
13
|
+
}
|
|
14
|
+
test('produce Verdict 不被当成类型参数,allow 通过', () => {
|
|
15
|
+
const codes = diagnose('@id("R-1")\nRule main produce Verdict:\n Return Verdict.allow().');
|
|
16
|
+
assert.ok(!codes.includes("E003" /* ErrorCode.RETURN_TYPE_MISMATCH */), codes.join(','));
|
|
17
|
+
assert.ok(!codes.includes("E212" /* ErrorCode.EFF_INFER_UNKNOWN_BUILTIN */), codes.join(','));
|
|
18
|
+
});
|
|
19
|
+
test('produce Bool 返回 Verdict 报 E003', () => {
|
|
20
|
+
const codes = diagnose('@id("R-1")\nRule main produce Bool:\n Return Verdict.allow().');
|
|
21
|
+
assert.ok(codes.includes("E003" /* ErrorCode.RETURN_TYPE_MISMATCH */), codes.join(','));
|
|
22
|
+
});
|
|
23
|
+
test('两个分支类型不一致报错', () => {
|
|
24
|
+
// 两引擎均在 If 分支汇合处报不一致(与 Java 侧裁定一致),返回 then 分支类型
|
|
25
|
+
const codes = diagnose('@id("R-1")\nRule main given x, produce Verdict:\n If x equals to 1:\n Return Verdict.allow().\n Otherwise:\n Return true.');
|
|
26
|
+
assert.ok(codes.includes("E008" /* ErrorCode.IF_BRANCH_MISMATCH */) || codes.includes("E003" /* ErrorCode.RETURN_TYPE_MISMATCH */), codes.join(','));
|
|
27
|
+
});
|
|
28
|
+
test('deny 缺参数报 E703', () => {
|
|
29
|
+
const codes = diagnose('@id("R-1")\nRule main produce Verdict:\n Return Verdict.deny().');
|
|
30
|
+
assert.ok(codes.includes("E703" /* ErrorCode.GOV_VERDICT_CALL_ARITY */), codes.join(','));
|
|
31
|
+
});
|
|
32
|
+
test('deny 非 Text 参数报类型不匹配', () => {
|
|
33
|
+
const codes = diagnose('@id("R-1")\nRule main produce Verdict:\n Return Verdict.deny(42).');
|
|
34
|
+
assert.ok(codes.includes("E001" /* ErrorCode.TYPE_MISMATCH */), codes.join(','));
|
|
35
|
+
});
|
|
36
|
+
test('require_approval 两个 Text 通过', () => {
|
|
37
|
+
const codes = diagnose('@id("R-1")\nRule main produce Verdict:\n Return Verdict.require_approval("Senior Underwriter", "over cap").');
|
|
38
|
+
assert.equal(codes.filter((c) => c.startsWith('E')).length, 0, codes.join(','));
|
|
39
|
+
});
|
|
40
|
+
// ===== Verdict 不可当布尔用(ADR 0039 §2.2,评审 C1;Java VerdictTypeCheckTest 镜像)=====
|
|
41
|
+
test('If 条件为 Verdict 报类型不匹配', () => {
|
|
42
|
+
const codes = diagnose('@id("R-1")\nRule main produce Text:\n Let v be Verdict.deny("x").\n If v:\n Return "yes".\n Return "no".');
|
|
43
|
+
assert.ok(codes.includes("E001" /* ErrorCode.TYPE_MISMATCH */), codes.join(','));
|
|
44
|
+
});
|
|
45
|
+
test('not 作用于 Verdict 报类型不匹配', () => {
|
|
46
|
+
const codes = diagnose('@id("R-1")\nRule main produce Bool:\n Let v be Verdict.deny("x").\n Return not v.');
|
|
47
|
+
assert.ok(codes.includes("E001" /* ErrorCode.TYPE_MISMATCH */), codes.join(','));
|
|
48
|
+
});
|
|
49
|
+
test('Verdict 与 true 相等比较报类型不匹配', () => {
|
|
50
|
+
const codes = diagnose('@id("R-1")\nRule main produce Bool:\n Let v be Verdict.deny("x").\n Return v equals to true.');
|
|
51
|
+
assert.ok(codes.includes("E001" /* ErrorCode.TYPE_MISMATCH */), codes.join(','));
|
|
52
|
+
});
|
|
53
|
+
// ===== Text 形参可作 reason/role(评审 I1)=====
|
|
54
|
+
test('Text 形参作 reason 通过', () => {
|
|
55
|
+
const codes = diagnose('@id("R-1")\nRule main given reason as Text, produce Verdict:\n Return Verdict.deny(reason).');
|
|
56
|
+
assert.equal(codes.filter((c) => c.startsWith('E')).length, 0, codes.join(','));
|
|
57
|
+
});
|
|
58
|
+
test('Text 形参作 role 与 reason 通过', () => {
|
|
59
|
+
const codes = diagnose('@id("R-1")\nRule main given role as Text, reason as Text, produce Verdict:\n Return Verdict.require_approval(role, reason).');
|
|
60
|
+
assert.equal(codes.filter((c) => c.startsWith('E')).length, 0, codes.join(','));
|
|
61
|
+
});
|
|
62
|
+
test('个数不符时仍检查参数内未定义名', () => {
|
|
63
|
+
const codes = diagnose('@id("R-1")\nRule main produce Verdict:\n Return Verdict.allow(missing_name).');
|
|
64
|
+
assert.ok(codes.includes("E703" /* ErrorCode.GOV_VERDICT_CALL_ARITY */), codes.join(','));
|
|
65
|
+
assert.ok(codes.includes("E101" /* ErrorCode.UNDEFINED_VARIABLE */), codes.join(','));
|
|
66
|
+
});
|
|
67
|
+
// ===== Verdict 字段 outcome/role/reason 为 Text(评审 I2)=====
|
|
68
|
+
test('读取 outcome 得到 Text', () => {
|
|
69
|
+
const codes = diagnose('Rule main produce Text:\n Let d be Verdict.deny("x").\n Return d.outcome.');
|
|
70
|
+
assert.equal(codes.filter((c) => c.startsWith('E')).length, 0, codes.join(','));
|
|
71
|
+
});
|
|
72
|
+
test('Verdict 字段类型为 Text 而非 Unknown', () => {
|
|
73
|
+
const codes = diagnose('Rule main produce Int:\n Let d be Verdict.require_approval("r", "x").\n Return d.role.');
|
|
74
|
+
assert.ok(codes.includes("E003" /* ErrorCode.RETURN_TYPE_MISMATCH */), codes.join(','));
|
|
75
|
+
});
|
|
76
|
+
test('Verdict 未知字段仍报 E011', () => {
|
|
77
|
+
const codes = diagnose('Rule main produce Text:\n Let d be Verdict.deny("x").\n Return d.verdict.');
|
|
78
|
+
assert.ok(codes.includes("E011" /* ErrorCode.UNKNOWN_FIELD */), codes.join(','));
|
|
79
|
+
});
|
|
80
|
+
//# sourceMappingURL=verdict-typecheck.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verdict-typecheck.test.js","sourceRoot":"","sources":["../../../../test/unit/governance/verdict-typecheck.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verdict-builtins.test.d.ts","sourceRoot":"","sources":["../../../../test/unit/interpreter/verdict-builtins.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { test } from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { compile } from '../../../src/browser.js';
|
|
4
|
+
import { evaluate } from '../../../src/core/interpreter.js';
|
|
5
|
+
function run(body, context = {}) {
|
|
6
|
+
const m = compile(`Module probe.\n@id("R-1")\n${body}\n`);
|
|
7
|
+
assert.ok(m.core, JSON.stringify(m));
|
|
8
|
+
return evaluate(m.core, 'main', context, { maxSteps: 10_000 });
|
|
9
|
+
}
|
|
10
|
+
test('allow 形状与键序', () => {
|
|
11
|
+
const ev = run('Rule main produce Verdict:\n Return Verdict.allow().');
|
|
12
|
+
assert.equal(ev.success, true);
|
|
13
|
+
assert.equal(JSON.stringify(ev.value), '{"__type":"Verdict","outcome":"ALLOW"}');
|
|
14
|
+
});
|
|
15
|
+
test('deny 带 reason', () => {
|
|
16
|
+
const ev = run('Rule main produce Verdict:\n Return Verdict.deny("no consent").');
|
|
17
|
+
assert.equal(JSON.stringify(ev.value), '{"__type":"Verdict","outcome":"DENY","reason":"no consent"}');
|
|
18
|
+
});
|
|
19
|
+
test('require_approval 键序 role 在 reason 前', () => {
|
|
20
|
+
const ev = run('Rule main produce Verdict:\n Return Verdict.require_approval("Senior Underwriter", "over cap").');
|
|
21
|
+
assert.equal(JSON.stringify(ev.value), '{"__type":"Verdict","outcome":"REQUIRE_APPROVAL","role":"Senior Underwriter","reason":"over cap"}');
|
|
22
|
+
});
|
|
23
|
+
test('escalate', () => {
|
|
24
|
+
const ev = run('Rule main produce Verdict:\n Return Verdict.escalate("low confidence").');
|
|
25
|
+
assert.equal(JSON.stringify(ev.value), '{"__type":"Verdict","outcome":"ESCALATE","reason":"low confidence"}');
|
|
26
|
+
});
|
|
27
|
+
test('空 reason 运行时失败', () => {
|
|
28
|
+
const ev = run('Rule main produce Verdict:\n Return Verdict.deny("").');
|
|
29
|
+
assert.equal(ev.success, false);
|
|
30
|
+
assert.match(String(ev.error), /Verdict\.deny/);
|
|
31
|
+
});
|
|
32
|
+
test('reason 为非 Text 变量时运行时失败', () => {
|
|
33
|
+
const ev = run('Rule main given n, produce Verdict:\n Return Verdict.deny(n).', { n: 42 });
|
|
34
|
+
assert.equal(ev.success, false);
|
|
35
|
+
assert.match(String(ev.error), /Verdict\.deny/);
|
|
36
|
+
});
|
|
37
|
+
test('空白 reason/role 运行时失败', () => {
|
|
38
|
+
const deny = run('Rule main produce Verdict:\n Return Verdict.deny(" ").');
|
|
39
|
+
assert.equal(deny.success, false);
|
|
40
|
+
assert.match(String(deny.error), /Verdict\.deny: reason must not be empty/);
|
|
41
|
+
const approval = run('Rule main given role as Text, produce Verdict:\n Return Verdict.require_approval(role, "over cap").', { role: ' \t' });
|
|
42
|
+
assert.equal(approval.success, false);
|
|
43
|
+
assert.match(String(approval.error), /Verdict\.require_approval: role must not be empty/);
|
|
44
|
+
});
|
|
45
|
+
// ===== Verdict 在布尔上下文 fail-closed(ADR 0039 §2.2,评审 C1;truffle VerdictBuiltinsTest 镜像)=====
|
|
46
|
+
// 类型检查会拒绝这些程序;此处直接构造 Core IR 绕过检查器,验证运行时这道最后防线。
|
|
47
|
+
function runCore(statements) {
|
|
48
|
+
const core = {
|
|
49
|
+
kind: 'Module', name: 'probe', decls: [{
|
|
50
|
+
kind: 'Func', name: 'main', typeParams: [], params: [], ret: { kind: 'TypeName', name: 'Text' },
|
|
51
|
+
effects: [], effectCaps: [], effectCapsExplicit: false, body: { kind: 'Block', statements },
|
|
52
|
+
}],
|
|
53
|
+
};
|
|
54
|
+
return evaluate(core, 'main', {}, { maxSteps: 10_000 });
|
|
55
|
+
}
|
|
56
|
+
const letDeny = { kind: 'Let', name: 'v', expr: { kind: 'Call', target: { kind: 'Name', name: 'Verdict.deny' }, args: [{ kind: 'String', value: 'no consent' }] } };
|
|
57
|
+
const ret = (value) => ({ kind: 'Return', expr: { kind: 'String', value } });
|
|
58
|
+
test('If 条件为 Verdict 时求值失败而非放行', () => {
|
|
59
|
+
const ev = runCore([
|
|
60
|
+
letDeny,
|
|
61
|
+
{ kind: 'If', cond: { kind: 'Name', name: 'v' }, thenBlock: { kind: 'Block', statements: [ret('approved')] }, elseBlock: null },
|
|
62
|
+
ret('rejected'),
|
|
63
|
+
]);
|
|
64
|
+
assert.equal(ev.success, false);
|
|
65
|
+
assert.match(String(ev.error), /Verdict cannot be used as Bool/);
|
|
66
|
+
});
|
|
67
|
+
test('not 作用于 Verdict 时求值失败', () => {
|
|
68
|
+
const ev = runCore([letDeny, { kind: 'Return', expr: { kind: 'Call', target: { kind: 'Name', name: 'not' }, args: [{ kind: 'Name', name: 'v' }] } }]);
|
|
69
|
+
assert.equal(ev.success, false);
|
|
70
|
+
assert.match(String(ev.error), /Verdict cannot be used as Bool/);
|
|
71
|
+
});
|
|
72
|
+
//# sourceMappingURL=verdict-builtins.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verdict-builtins.test.js","sourceRoot":"","sources":["../../../../test/unit/interpreter/verdict-builtins.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-numeric-fail-loud.test.d.ts","sourceRoot":"","sources":["../../../test/unit/list-numeric-fail-loud.test.ts"],"names":[],"mappings":""}
|