@intentius/chant 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +365 -0
- package/package.json +22 -0
- package/src/attrref.test.ts +148 -0
- package/src/attrref.ts +50 -0
- package/src/barrel.test.ts +157 -0
- package/src/barrel.ts +101 -0
- package/src/bench.test.ts +227 -0
- package/src/build.test.ts +437 -0
- package/src/build.ts +425 -0
- package/src/builder.test.ts +312 -0
- package/src/builder.ts +56 -0
- package/src/child-project.ts +44 -0
- package/src/cli/commands/__fixtures__/init-lexicon-output/README.md +26 -0
- package/src/cli/commands/__fixtures__/init-lexicon-output/docs/astro.config.mjs +14 -0
- package/src/cli/commands/__fixtures__/init-lexicon-output/docs/package.json +16 -0
- package/src/cli/commands/__fixtures__/init-lexicon-output/docs/src/content/docs/index.mdx +8 -0
- package/src/cli/commands/__fixtures__/init-lexicon-output/docs/src/content.config.ts +7 -0
- package/src/cli/commands/__fixtures__/init-lexicon-output/docs/tsconfig.json +10 -0
- package/src/cli/commands/__fixtures__/init-lexicon-output/examples/getting-started/.gitkeep +0 -0
- package/src/cli/commands/__fixtures__/init-lexicon-output/justfile +26 -0
- package/src/cli/commands/__fixtures__/init-lexicon-output/package.json +29 -0
- package/src/cli/commands/__fixtures__/init-lexicon-output/src/codegen/docs.ts +25 -0
- package/src/cli/commands/__fixtures__/init-lexicon-output/src/codegen/generate-cli.ts +8 -0
- package/src/cli/commands/__fixtures__/init-lexicon-output/src/codegen/generate.ts +74 -0
- package/src/cli/commands/__fixtures__/init-lexicon-output/src/codegen/naming.ts +33 -0
- package/src/cli/commands/__fixtures__/init-lexicon-output/src/codegen/package.ts +25 -0
- package/src/cli/commands/__fixtures__/init-lexicon-output/src/codegen/rollback.ts +45 -0
- package/src/cli/commands/__fixtures__/init-lexicon-output/src/coverage.ts +11 -0
- package/src/cli/commands/__fixtures__/init-lexicon-output/src/generated/.gitkeep +0 -0
- package/src/cli/commands/__fixtures__/init-lexicon-output/src/import/generator.ts +10 -0
- package/src/cli/commands/__fixtures__/init-lexicon-output/src/import/parser.ts +10 -0
- package/src/cli/commands/__fixtures__/init-lexicon-output/src/index.ts +9 -0
- package/src/cli/commands/__fixtures__/init-lexicon-output/src/lint/rules/index.ts +1 -0
- package/src/cli/commands/__fixtures__/init-lexicon-output/src/lint/rules/sample.ts +18 -0
- package/src/cli/commands/__fixtures__/init-lexicon-output/src/lsp/completions.ts +14 -0
- package/src/cli/commands/__fixtures__/init-lexicon-output/src/lsp/hover.ts +14 -0
- package/src/cli/commands/__fixtures__/init-lexicon-output/src/plugin.ts +110 -0
- package/src/cli/commands/__fixtures__/init-lexicon-output/src/serializer.ts +24 -0
- package/src/cli/commands/__fixtures__/init-lexicon-output/src/spec/fetch.ts +21 -0
- package/src/cli/commands/__fixtures__/init-lexicon-output/src/spec/parse.ts +25 -0
- package/src/cli/commands/__fixtures__/init-lexicon-output/src/validate-cli.ts +4 -0
- package/src/cli/commands/__fixtures__/init-lexicon-output/src/validate.ts +24 -0
- package/src/cli/commands/__fixtures__/init-lexicon-output/tsconfig.json +10 -0
- package/src/cli/commands/__fixtures__/sample-rule.ts +11 -0
- package/src/cli/commands/__snapshots__/init-lexicon.test.ts.snap +222 -0
- package/src/cli/commands/build.test.ts +149 -0
- package/src/cli/commands/build.ts +344 -0
- package/src/cli/commands/diff.test.ts +148 -0
- package/src/cli/commands/diff.ts +221 -0
- package/src/cli/commands/doctor.test.ts +239 -0
- package/src/cli/commands/doctor.ts +224 -0
- package/src/cli/commands/import.test.ts +379 -0
- package/src/cli/commands/import.ts +335 -0
- package/src/cli/commands/init-lexicon.test.ts +297 -0
- package/src/cli/commands/init-lexicon.ts +993 -0
- package/src/cli/commands/init.test.ts +317 -0
- package/src/cli/commands/init.ts +505 -0
- package/src/cli/commands/licenses.ts +165 -0
- package/src/cli/commands/lint.test.ts +332 -0
- package/src/cli/commands/lint.ts +408 -0
- package/src/cli/commands/list.test.ts +100 -0
- package/src/cli/commands/list.ts +108 -0
- package/src/cli/commands/update.test.ts +38 -0
- package/src/cli/commands/update.ts +207 -0
- package/src/cli/conflict-check.test.ts +255 -0
- package/src/cli/conflict-check.ts +89 -0
- package/src/cli/debug.ts +8 -0
- package/src/cli/format.test.ts +140 -0
- package/src/cli/format.ts +133 -0
- package/src/cli/handlers/build.ts +58 -0
- package/src/cli/handlers/dev.ts +38 -0
- package/src/cli/handlers/init.ts +46 -0
- package/src/cli/handlers/lint.ts +36 -0
- package/src/cli/handlers/misc.ts +57 -0
- package/src/cli/handlers/serve.ts +26 -0
- package/src/cli/index.ts +3 -0
- package/src/cli/lsp/capabilities.ts +46 -0
- package/src/cli/lsp/diagnostics.ts +52 -0
- package/src/cli/lsp/server.test.ts +618 -0
- package/src/cli/lsp/server.ts +393 -0
- package/src/cli/main.test.ts +257 -0
- package/src/cli/main.ts +224 -0
- package/src/cli/mcp/resources/context.ts +59 -0
- package/src/cli/mcp/server.test.ts +747 -0
- package/src/cli/mcp/server.ts +402 -0
- package/src/cli/mcp/tools/build.ts +117 -0
- package/src/cli/mcp/tools/import.ts +48 -0
- package/src/cli/mcp/tools/lint.ts +45 -0
- package/src/cli/plugins.test.ts +31 -0
- package/src/cli/plugins.ts +94 -0
- package/src/cli/registry.ts +73 -0
- package/src/cli/reporters/stylish.test.ts +282 -0
- package/src/cli/reporters/stylish.ts +186 -0
- package/src/cli/watch.test.ts +81 -0
- package/src/cli/watch.ts +101 -0
- package/src/codegen/case.test.ts +30 -0
- package/src/codegen/case.ts +11 -0
- package/src/codegen/coverage.ts +167 -0
- package/src/codegen/docs.ts +634 -0
- package/src/codegen/fetch.test.ts +119 -0
- package/src/codegen/fetch.ts +261 -0
- package/src/codegen/generate-registry.test.ts +118 -0
- package/src/codegen/generate-registry.ts +107 -0
- package/src/codegen/generate-runtime-index.test.ts +81 -0
- package/src/codegen/generate-runtime-index.ts +99 -0
- package/src/codegen/generate-typescript.test.ts +146 -0
- package/src/codegen/generate-typescript.ts +161 -0
- package/src/codegen/generate.ts +206 -0
- package/src/codegen/json-patch.test.ts +113 -0
- package/src/codegen/json-patch.ts +151 -0
- package/src/codegen/json-schema.test.ts +196 -0
- package/src/codegen/json-schema.ts +209 -0
- package/src/codegen/naming.ts +201 -0
- package/src/codegen/package.ts +161 -0
- package/src/codegen/rollback.test.ts +92 -0
- package/src/codegen/rollback.ts +115 -0
- package/src/codegen/topo-sort.test.ts +69 -0
- package/src/codegen/topo-sort.ts +46 -0
- package/src/codegen/typecheck.test.ts +37 -0
- package/src/codegen/typecheck.ts +74 -0
- package/src/codegen/validate.test.ts +86 -0
- package/src/codegen/validate.ts +143 -0
- package/src/composite.test.ts +426 -0
- package/src/composite.ts +243 -0
- package/src/config.test.ts +91 -0
- package/src/config.ts +87 -0
- package/src/declarable.test.ts +160 -0
- package/src/declarable.ts +47 -0
- package/src/detectLexicon.test.ts +236 -0
- package/src/detectLexicon.ts +37 -0
- package/src/discovery/cache.test.ts +78 -0
- package/src/discovery/cache.ts +86 -0
- package/src/discovery/collect.test.ts +269 -0
- package/src/discovery/collect.ts +51 -0
- package/src/discovery/cycles.test.ts +238 -0
- package/src/discovery/cycles.ts +107 -0
- package/src/discovery/files.test.ts +154 -0
- package/src/discovery/files.ts +61 -0
- package/src/discovery/graph.test.ts +476 -0
- package/src/discovery/graph.ts +150 -0
- package/src/discovery/import.test.ts +199 -0
- package/src/discovery/import.ts +20 -0
- package/src/discovery/index.test.ts +272 -0
- package/src/discovery/index.ts +132 -0
- package/src/discovery/resolve.test.ts +267 -0
- package/src/discovery/resolve.ts +54 -0
- package/src/errors.test.ts +138 -0
- package/src/errors.ts +86 -0
- package/src/import/base-parser.test.ts +67 -0
- package/src/import/base-parser.ts +48 -0
- package/src/import/generator.ts +21 -0
- package/src/import/ir-utils.test.ts +103 -0
- package/src/import/ir-utils.ts +87 -0
- package/src/import/parser.ts +41 -0
- package/src/index.ts +60 -0
- package/src/intrinsic-interpolation.test.ts +91 -0
- package/src/intrinsic-interpolation.ts +89 -0
- package/src/intrinsic.test.ts +69 -0
- package/src/intrinsic.ts +43 -0
- package/src/lexicon-integrity.test.ts +94 -0
- package/src/lexicon-integrity.ts +69 -0
- package/src/lexicon-manifest.test.ts +101 -0
- package/src/lexicon-manifest.ts +71 -0
- package/src/lexicon-output.test.ts +182 -0
- package/src/lexicon-output.ts +82 -0
- package/src/lexicon-schema.test.ts +239 -0
- package/src/lexicon-schema.ts +144 -0
- package/src/lexicon.ts +212 -0
- package/src/lint/config-overrides.test.ts +254 -0
- package/src/lint/config.test.ts +644 -0
- package/src/lint/config.ts +375 -0
- package/src/lint/declarative.test.ts +256 -0
- package/src/lint/declarative.ts +187 -0
- package/src/lint/engine.test.ts +465 -0
- package/src/lint/engine.ts +172 -0
- package/src/lint/named-checks.test.ts +37 -0
- package/src/lint/named-checks.ts +33 -0
- package/src/lint/parser.test.ts +129 -0
- package/src/lint/parser.ts +42 -0
- package/src/lint/post-synth.test.ts +113 -0
- package/src/lint/post-synth.ts +76 -0
- package/src/lint/presets/relaxed.json +19 -0
- package/src/lint/presets/strict.json +19 -0
- package/src/lint/rule-loader.test.ts +67 -0
- package/src/lint/rule-loader.ts +67 -0
- package/src/lint/rule-options.test.ts +141 -0
- package/src/lint/rule.test.ts +196 -0
- package/src/lint/rule.ts +98 -0
- package/src/lint/rules/barrel-import-style.test.ts +80 -0
- package/src/lint/rules/barrel-import-style.ts +59 -0
- package/src/lint/rules/composite-scope.ts +55 -0
- package/src/lint/rules/cor017-composite-name-match.test.ts +107 -0
- package/src/lint/rules/cor017-composite-name-match.ts +108 -0
- package/src/lint/rules/cor018-composite-prefer-lexicon-type.test.ts +172 -0
- package/src/lint/rules/cor018-composite-prefer-lexicon-type.ts +167 -0
- package/src/lint/rules/declarable-naming-convention.test.ts +69 -0
- package/src/lint/rules/declarable-naming-convention.ts +70 -0
- package/src/lint/rules/enforce-barrel-import.test.ts +169 -0
- package/src/lint/rules/enforce-barrel-import.ts +81 -0
- package/src/lint/rules/enforce-barrel-ref.test.ts +114 -0
- package/src/lint/rules/enforce-barrel-ref.ts +75 -0
- package/src/lint/rules/evl001-non-literal-expression.test.ts +158 -0
- package/src/lint/rules/evl001-non-literal-expression.ts +149 -0
- package/src/lint/rules/evl002-control-flow-resource.test.ts +110 -0
- package/src/lint/rules/evl002-control-flow-resource.ts +61 -0
- package/src/lint/rules/evl003-dynamic-property-access.test.ts +63 -0
- package/src/lint/rules/evl003-dynamic-property-access.ts +41 -0
- package/src/lint/rules/evl004-spread-non-const.test.ts +130 -0
- package/src/lint/rules/evl004-spread-non-const.ts +111 -0
- package/src/lint/rules/evl005-resource-block-body.test.ts +59 -0
- package/src/lint/rules/evl005-resource-block-body.ts +49 -0
- package/src/lint/rules/evl006-barrel-usage.test.ts +63 -0
- package/src/lint/rules/evl006-barrel-usage.ts +95 -0
- package/src/lint/rules/evl007-invalid-siblings.test.ts +87 -0
- package/src/lint/rules/evl007-invalid-siblings.ts +139 -0
- package/src/lint/rules/evl008-unresolvable-barrel-ref.test.ts +118 -0
- package/src/lint/rules/evl008-unresolvable-barrel-ref.ts +140 -0
- package/src/lint/rules/evl009-composite-no-constant.test.ts +162 -0
- package/src/lint/rules/evl009-composite-no-constant.ts +171 -0
- package/src/lint/rules/evl010-composite-no-transform.test.ts +121 -0
- package/src/lint/rules/evl010-composite-no-transform.ts +69 -0
- package/src/lint/rules/export-required.test.ts +213 -0
- package/src/lint/rules/export-required.ts +158 -0
- package/src/lint/rules/file-declarable-limit.test.ts +148 -0
- package/src/lint/rules/file-declarable-limit.ts +96 -0
- package/src/lint/rules/flat-declarations.test.ts +210 -0
- package/src/lint/rules/flat-declarations.ts +70 -0
- package/src/lint/rules/index.ts +99 -0
- package/src/lint/rules/no-cyclic-declarable-ref.test.ts +135 -0
- package/src/lint/rules/no-cyclic-declarable-ref.ts +178 -0
- package/src/lint/rules/no-redundant-type-import.test.ts +129 -0
- package/src/lint/rules/no-redundant-type-import.ts +85 -0
- package/src/lint/rules/no-redundant-value-cast.test.ts +51 -0
- package/src/lint/rules/no-redundant-value-cast.ts +46 -0
- package/src/lint/rules/no-string-ref.test.ts +100 -0
- package/src/lint/rules/no-string-ref.ts +66 -0
- package/src/lint/rules/no-unused-declarable-import.test.ts +74 -0
- package/src/lint/rules/no-unused-declarable-import.ts +103 -0
- package/src/lint/rules/no-unused-declarable.test.ts +134 -0
- package/src/lint/rules/no-unused-declarable.ts +118 -0
- package/src/lint/rules/prefer-namespace-import.test.ts +102 -0
- package/src/lint/rules/prefer-namespace-import.ts +63 -0
- package/src/lint/rules/single-concern-file.test.ts +156 -0
- package/src/lint/rules/single-concern-file.ts +98 -0
- package/src/lint/rules/stale-barrel-types.ts +60 -0
- package/src/lint/selectors.test.ts +113 -0
- package/src/lint/selectors.ts +188 -0
- package/src/lsp/lexicon-providers.ts +191 -0
- package/src/lsp/types.ts +79 -0
- package/src/mcp/types.ts +22 -0
- package/src/project/scan.test.ts +178 -0
- package/src/project/scan.ts +182 -0
- package/src/project/sync.test.ts +87 -0
- package/src/project/sync.ts +46 -0
- package/src/project-validation.test.ts +64 -0
- package/src/project-validation.ts +79 -0
- package/src/pseudo-parameter.test.ts +39 -0
- package/src/pseudo-parameter.ts +47 -0
- package/src/runtime.ts +68 -0
- package/src/serializer-walker.test.ts +124 -0
- package/src/serializer-walker.ts +83 -0
- package/src/serializer.ts +42 -0
- package/src/sort.test.ts +290 -0
- package/src/sort.ts +58 -0
- package/src/stack-output.ts +82 -0
- package/src/types.test.ts +307 -0
- package/src/types.ts +46 -0
- package/src/utils.test.ts +195 -0
- package/src/utils.ts +46 -0
- package/src/validation.test.ts +308 -0
- package/src/validation.ts +50 -0
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
import { describe, test, expect, beforeEach, afterEach } from "bun:test";
|
|
2
|
+
import { existsSync, readFileSync, mkdirSync, writeFileSync, rmSync, readdirSync } from "fs";
|
|
3
|
+
import { join, dirname } from "path";
|
|
4
|
+
import { tmpdir } from "os";
|
|
5
|
+
import { fileURLToPath } from "url";
|
|
6
|
+
import { initLexiconCommand } from "./init-lexicon";
|
|
7
|
+
|
|
8
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
const FIXTURE_DIR = join(__dirname, "__fixtures__", "init-lexicon-output");
|
|
10
|
+
|
|
11
|
+
function makeTmpDir(): string {
|
|
12
|
+
const dir = join(tmpdir(), `chant-init-lexicon-test-${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
|
13
|
+
mkdirSync(dir, { recursive: true });
|
|
14
|
+
return dir;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
describe("initLexiconCommand", () => {
|
|
18
|
+
let tmpDir: string;
|
|
19
|
+
|
|
20
|
+
beforeEach(() => {
|
|
21
|
+
tmpDir = makeTmpDir();
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
afterEach(() => {
|
|
25
|
+
rmSync(tmpDir, { recursive: true, force: true });
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test("creates all expected files", async () => {
|
|
29
|
+
const targetDir = join(tmpDir, "test-lex");
|
|
30
|
+
const result = await initLexiconCommand({ name: "test-lex", path: targetDir });
|
|
31
|
+
|
|
32
|
+
expect(result.success).toBe(true);
|
|
33
|
+
expect(result.error).toBeUndefined();
|
|
34
|
+
|
|
35
|
+
const expectedFiles = [
|
|
36
|
+
"src/plugin.ts",
|
|
37
|
+
"src/index.ts",
|
|
38
|
+
"src/serializer.ts",
|
|
39
|
+
"src/codegen/generate.ts",
|
|
40
|
+
"src/codegen/generate-cli.ts",
|
|
41
|
+
"src/codegen/naming.ts",
|
|
42
|
+
"src/codegen/package.ts",
|
|
43
|
+
"src/codegen/rollback.ts",
|
|
44
|
+
"src/codegen/docs.ts",
|
|
45
|
+
"src/spec/fetch.ts",
|
|
46
|
+
"src/spec/parse.ts",
|
|
47
|
+
"src/lint/rules/sample.ts",
|
|
48
|
+
"src/lint/rules/index.ts",
|
|
49
|
+
"src/lsp/completions.ts",
|
|
50
|
+
"src/lsp/hover.ts",
|
|
51
|
+
"src/import/parser.ts",
|
|
52
|
+
"src/import/generator.ts",
|
|
53
|
+
"src/coverage.ts",
|
|
54
|
+
"src/validate.ts",
|
|
55
|
+
"src/validate-cli.ts",
|
|
56
|
+
"package.json",
|
|
57
|
+
"tsconfig.json",
|
|
58
|
+
"justfile",
|
|
59
|
+
".gitignore",
|
|
60
|
+
"README.md",
|
|
61
|
+
"docs/package.json",
|
|
62
|
+
"docs/tsconfig.json",
|
|
63
|
+
"docs/astro.config.mjs",
|
|
64
|
+
"docs/src/content.config.ts",
|
|
65
|
+
"docs/src/content/docs/index.mdx",
|
|
66
|
+
"src/generated/.gitkeep",
|
|
67
|
+
"examples/getting-started/.gitkeep",
|
|
68
|
+
".snapshots/.gitkeep",
|
|
69
|
+
];
|
|
70
|
+
|
|
71
|
+
for (const file of expectedFiles) {
|
|
72
|
+
expect(existsSync(join(targetDir, file))).toBe(true);
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
test("plugin.ts contains all 5 required lifecycle methods", async () => {
|
|
77
|
+
const targetDir = join(tmpDir, "lifecycle");
|
|
78
|
+
await initLexiconCommand({ name: "k8s", path: targetDir });
|
|
79
|
+
|
|
80
|
+
const pluginContent = readFileSync(join(targetDir, "src/plugin.ts"), "utf-8");
|
|
81
|
+
|
|
82
|
+
expect(pluginContent).toContain("async generate(");
|
|
83
|
+
expect(pluginContent).toContain("async validate(");
|
|
84
|
+
expect(pluginContent).toContain("async coverage(");
|
|
85
|
+
expect(pluginContent).toContain("async package(");
|
|
86
|
+
expect(pluginContent).toContain("async rollback(");
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
test("package name uses the provided lexicon name", async () => {
|
|
90
|
+
const targetDir = join(tmpDir, "pkg-name");
|
|
91
|
+
await initLexiconCommand({ name: "gcp", path: targetDir });
|
|
92
|
+
|
|
93
|
+
const pkgJson = JSON.parse(readFileSync(join(targetDir, "package.json"), "utf-8"));
|
|
94
|
+
expect(pkgJson.name).toBe("@intentius/chant-lexicon-gcp");
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
test("rule prefix derived correctly", async () => {
|
|
98
|
+
const targetDir = join(tmpDir, "rule-prefix");
|
|
99
|
+
await initLexiconCommand({ name: "k8s", path: targetDir });
|
|
100
|
+
|
|
101
|
+
const ruleContent = readFileSync(join(targetDir, "src/lint/rules/sample.ts"), "utf-8");
|
|
102
|
+
expect(ruleContent).toContain('"K8S001"');
|
|
103
|
+
|
|
104
|
+
const serializerContent = readFileSync(join(targetDir, "src/serializer.ts"), "utf-8");
|
|
105
|
+
expect(serializerContent).toContain('rulePrefix: "K8S"');
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
test("rule prefix handles hyphens", async () => {
|
|
109
|
+
const targetDir = join(tmpDir, "rule-prefix-hyphen");
|
|
110
|
+
await initLexiconCommand({ name: "my-cloud", path: targetDir });
|
|
111
|
+
|
|
112
|
+
const ruleContent = readFileSync(join(targetDir, "src/lint/rules/sample.ts"), "utf-8");
|
|
113
|
+
// "my-cloud" -> "MYCLOUD" -> "MYC"
|
|
114
|
+
expect(ruleContent).toContain('"MYC001"');
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
test("refuses non-empty dir without --force", async () => {
|
|
118
|
+
const targetDir = join(tmpDir, "non-empty");
|
|
119
|
+
mkdirSync(targetDir, { recursive: true });
|
|
120
|
+
writeFileSync(join(targetDir, "existing.txt"), "hello");
|
|
121
|
+
|
|
122
|
+
const result = await initLexiconCommand({ name: "test", path: targetDir });
|
|
123
|
+
|
|
124
|
+
expect(result.success).toBe(false);
|
|
125
|
+
expect(result.error).toContain("not empty");
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
test("allows --force in non-empty dir", async () => {
|
|
129
|
+
const targetDir = join(tmpDir, "force");
|
|
130
|
+
mkdirSync(targetDir, { recursive: true });
|
|
131
|
+
writeFileSync(join(targetDir, "existing.txt"), "hello");
|
|
132
|
+
|
|
133
|
+
const result = await initLexiconCommand({ name: "test", path: targetDir, force: true });
|
|
134
|
+
|
|
135
|
+
expect(result.success).toBe(true);
|
|
136
|
+
expect(result.warnings).toContain("Initializing in non-empty directory");
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
test("warns on second run (skip existing files)", async () => {
|
|
140
|
+
const targetDir = join(tmpDir, "second-run");
|
|
141
|
+
|
|
142
|
+
const first = await initLexiconCommand({ name: "test", path: targetDir });
|
|
143
|
+
expect(first.success).toBe(true);
|
|
144
|
+
expect(first.warnings.length).toBe(0);
|
|
145
|
+
|
|
146
|
+
const second = await initLexiconCommand({ name: "test", path: targetDir, force: true });
|
|
147
|
+
expect(second.success).toBe(true);
|
|
148
|
+
expect(second.warnings.length).toBeGreaterThan(0);
|
|
149
|
+
expect(second.warnings.some((w) => w.includes("already exists"))).toBe(true);
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
test("uses camelCase for plugin variable names", async () => {
|
|
153
|
+
const targetDir = join(tmpDir, "camel");
|
|
154
|
+
await initLexiconCommand({ name: "my-cloud", path: targetDir });
|
|
155
|
+
|
|
156
|
+
const pluginContent = readFileSync(join(targetDir, "src/plugin.ts"), "utf-8");
|
|
157
|
+
expect(pluginContent).toContain("export const myCloudPlugin");
|
|
158
|
+
|
|
159
|
+
const serializerContent = readFileSync(join(targetDir, "src/serializer.ts"), "utf-8");
|
|
160
|
+
expect(serializerContent).toContain("export const myCloudSerializer");
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
test("defaults path to lexicons/<name>", async () => {
|
|
164
|
+
// We can't test the actual default easily without cd'ing,
|
|
165
|
+
// but we can verify the interface accepts no path
|
|
166
|
+
const targetDir = join(tmpDir, "default-path", "lexicons", "test");
|
|
167
|
+
mkdirSync(targetDir, { recursive: true });
|
|
168
|
+
|
|
169
|
+
const result = await initLexiconCommand({
|
|
170
|
+
name: "test",
|
|
171
|
+
path: targetDir,
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
expect(result.success).toBe(true);
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
// ── Scaffold content validation (bug fix regression tests) ──────────
|
|
179
|
+
|
|
180
|
+
describe("scaffold content validation", () => {
|
|
181
|
+
let tmpDir: string;
|
|
182
|
+
let targetDir: string;
|
|
183
|
+
|
|
184
|
+
beforeEach(async () => {
|
|
185
|
+
tmpDir = makeTmpDir();
|
|
186
|
+
targetDir = join(tmpDir, "fixture-lex");
|
|
187
|
+
await initLexiconCommand({ name: "fixture", path: targetDir });
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
afterEach(() => {
|
|
191
|
+
rmSync(tmpDir, { recursive: true, force: true });
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
test("writeGeneratedArtifacts uses WriteConfig object, not positional args", () => {
|
|
195
|
+
const content = readFileSync(join(targetDir, "src/codegen/generate.ts"), "utf-8");
|
|
196
|
+
|
|
197
|
+
// Must call writeGeneratedArtifacts with a config object
|
|
198
|
+
expect(content).toContain("writeGeneratedArtifacts({");
|
|
199
|
+
expect(content).toContain("baseDir:");
|
|
200
|
+
expect(content).toContain("files:");
|
|
201
|
+
expect(content).toContain('"lexicon.json": result.lexiconJSON');
|
|
202
|
+
expect(content).toContain('"index.d.ts": result.typesDTS');
|
|
203
|
+
expect(content).toContain('"index.ts": result.indexTS');
|
|
204
|
+
|
|
205
|
+
// Must NOT have the old positional-arg call
|
|
206
|
+
expect(content).not.toContain("writeGeneratedArtifacts(result, dir)");
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
test("packagePipeline config includes collectSkills", () => {
|
|
210
|
+
const content = readFileSync(join(targetDir, "src/codegen/package.ts"), "utf-8");
|
|
211
|
+
|
|
212
|
+
expect(content).toContain("collectSkills:");
|
|
213
|
+
expect(content).toContain("collectSkills: () => new Map()");
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
test("packagePipeline forwards force flag", () => {
|
|
217
|
+
const content = readFileSync(join(targetDir, "src/codegen/package.ts"), "utf-8");
|
|
218
|
+
|
|
219
|
+
expect(content).toContain("force: opts?.force");
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
test("generate.ts TODO stubs include return type hints", () => {
|
|
223
|
+
const content = readFileSync(join(targetDir, "src/codegen/generate.ts"), "utf-8");
|
|
224
|
+
|
|
225
|
+
// fetchSchemas hint
|
|
226
|
+
expect(content).toContain("Must return Map<typeName, Buffer>");
|
|
227
|
+
// parseSchema hint
|
|
228
|
+
expect(content).toContain("Must return a ParsedResult");
|
|
229
|
+
// generateRegistry hint
|
|
230
|
+
expect(content).toContain("Must return a string of JSON");
|
|
231
|
+
// generateRuntimeIndex hint
|
|
232
|
+
expect(content).toContain("Must return a string of TypeScript");
|
|
233
|
+
// AWS references
|
|
234
|
+
expect(content).toContain("lexicons/aws/");
|
|
235
|
+
});
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
// ── Fixture snapshot tests ──────────────────────────────────────────
|
|
239
|
+
|
|
240
|
+
describe("init-lexicon fixture snapshot", () => {
|
|
241
|
+
const FIXTURE_LEXICON_NAME = "fixture";
|
|
242
|
+
|
|
243
|
+
test("generate and snapshot fixture files", async () => {
|
|
244
|
+
// Generate scaffold into the fixture directory
|
|
245
|
+
// Use force to overwrite any stale fixtures
|
|
246
|
+
rmSync(FIXTURE_DIR, { recursive: true, force: true });
|
|
247
|
+
mkdirSync(FIXTURE_DIR, { recursive: true });
|
|
248
|
+
|
|
249
|
+
const result = await initLexiconCommand({
|
|
250
|
+
name: FIXTURE_LEXICON_NAME,
|
|
251
|
+
path: FIXTURE_DIR,
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
expect(result.success).toBe(true);
|
|
255
|
+
|
|
256
|
+
// Key files that must exist
|
|
257
|
+
const criticalFiles = [
|
|
258
|
+
"src/codegen/generate.ts",
|
|
259
|
+
"src/codegen/package.ts",
|
|
260
|
+
"src/plugin.ts",
|
|
261
|
+
"src/serializer.ts",
|
|
262
|
+
"package.json",
|
|
263
|
+
];
|
|
264
|
+
|
|
265
|
+
for (const file of criticalFiles) {
|
|
266
|
+
expect(existsSync(join(FIXTURE_DIR, file))).toBe(true);
|
|
267
|
+
}
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
test("fixture generate.ts matches snapshot", async () => {
|
|
271
|
+
// Ensure fixture exists
|
|
272
|
+
if (!existsSync(join(FIXTURE_DIR, "src/codegen/generate.ts"))) {
|
|
273
|
+
await initLexiconCommand({ name: FIXTURE_LEXICON_NAME, path: FIXTURE_DIR });
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
const content = readFileSync(join(FIXTURE_DIR, "src/codegen/generate.ts"), "utf-8");
|
|
277
|
+
expect(content).toMatchSnapshot();
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
test("fixture package.ts matches snapshot", async () => {
|
|
281
|
+
if (!existsSync(join(FIXTURE_DIR, "src/codegen/package.ts"))) {
|
|
282
|
+
await initLexiconCommand({ name: FIXTURE_LEXICON_NAME, path: FIXTURE_DIR });
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
const content = readFileSync(join(FIXTURE_DIR, "src/codegen/package.ts"), "utf-8");
|
|
286
|
+
expect(content).toMatchSnapshot();
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
test("fixture plugin.ts matches snapshot", async () => {
|
|
290
|
+
if (!existsSync(join(FIXTURE_DIR, "src/plugin.ts"))) {
|
|
291
|
+
await initLexiconCommand({ name: FIXTURE_LEXICON_NAME, path: FIXTURE_DIR });
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
const content = readFileSync(join(FIXTURE_DIR, "src/plugin.ts"), "utf-8");
|
|
295
|
+
expect(content).toMatchSnapshot();
|
|
296
|
+
});
|
|
297
|
+
});
|