mirror of
https://github.com/samiyev/puaros.git
synced 2025-12-27 23:06:54 +05:00
Extract enum declarations with member names and values from TypeScript AST and display them in the initial LLM context. This allows the LLM to know valid enum values without making tool calls. Features: - Numeric values (Active=1) - String values (Admin="admin") - Implicit values (Up, Down) - Negative numbers (Cold=-10) - const enum modifier - export enum modifier - Long enum truncation (>100 chars) Adds EnumInfo and EnumMemberInfo interfaces, extractEnum() method in ASTParser, formatEnumSignature() in prompts.ts, and 17 new unit tests.
1777 lines
62 KiB
TypeScript
1777 lines
62 KiB
TypeScript
import { describe, it, expect } from "vitest"
|
|
import {
|
|
SYSTEM_PROMPT,
|
|
buildInitialContext,
|
|
buildFileContext,
|
|
truncateContext,
|
|
type ProjectStructure,
|
|
} from "../../../../src/infrastructure/llm/prompts.js"
|
|
import type { FileAST } from "../../../../src/domain/value-objects/FileAST.js"
|
|
import type { FileMeta } from "../../../../src/domain/value-objects/FileMeta.js"
|
|
|
|
describe("prompts", () => {
|
|
describe("SYSTEM_PROMPT", () => {
|
|
it("should be a non-empty string", () => {
|
|
expect(typeof SYSTEM_PROMPT).toBe("string")
|
|
expect(SYSTEM_PROMPT.length).toBeGreaterThan(100)
|
|
})
|
|
|
|
it("should contain core principles", () => {
|
|
expect(SYSTEM_PROMPT).toContain("Lazy Loading")
|
|
expect(SYSTEM_PROMPT).toContain("Precision")
|
|
expect(SYSTEM_PROMPT).toContain("Safety")
|
|
})
|
|
|
|
it("should list available tools", () => {
|
|
expect(SYSTEM_PROMPT).toContain("get_lines")
|
|
expect(SYSTEM_PROMPT).toContain("edit_lines")
|
|
expect(SYSTEM_PROMPT).toContain("find_references")
|
|
expect(SYSTEM_PROMPT).toContain("git_status")
|
|
expect(SYSTEM_PROMPT).toContain("run_command")
|
|
})
|
|
|
|
it("should include safety rules", () => {
|
|
expect(SYSTEM_PROMPT).toContain("Safety Rules")
|
|
expect(SYSTEM_PROMPT).toContain("Never execute commands that could harm")
|
|
})
|
|
})
|
|
|
|
describe("buildInitialContext", () => {
|
|
const structure: ProjectStructure = {
|
|
name: "my-project",
|
|
rootPath: "/home/user/my-project",
|
|
files: ["src/index.ts", "src/utils.ts", "package.json"],
|
|
directories: ["src", "tests"],
|
|
}
|
|
|
|
const asts = new Map<string, FileAST>([
|
|
[
|
|
"src/index.ts",
|
|
{
|
|
imports: [],
|
|
exports: [],
|
|
functions: [
|
|
{
|
|
name: "main",
|
|
lineStart: 1,
|
|
lineEnd: 10,
|
|
params: [],
|
|
isAsync: false,
|
|
isExported: true,
|
|
},
|
|
],
|
|
classes: [],
|
|
interfaces: [],
|
|
typeAliases: [],
|
|
parseError: false,
|
|
},
|
|
],
|
|
[
|
|
"src/utils.ts",
|
|
{
|
|
imports: [],
|
|
exports: [],
|
|
functions: [],
|
|
classes: [
|
|
{
|
|
name: "Helper",
|
|
lineStart: 1,
|
|
lineEnd: 20,
|
|
methods: [],
|
|
properties: [],
|
|
implements: [],
|
|
isExported: true,
|
|
isAbstract: false,
|
|
},
|
|
],
|
|
interfaces: [],
|
|
typeAliases: [],
|
|
parseError: false,
|
|
},
|
|
],
|
|
])
|
|
|
|
it("should include project header", () => {
|
|
const context = buildInitialContext(structure, asts)
|
|
|
|
expect(context).toContain("# Project: my-project")
|
|
expect(context).toContain("Root: /home/user/my-project")
|
|
expect(context).toContain("Files: 3")
|
|
expect(context).toContain("Directories: 2")
|
|
})
|
|
|
|
it("should include directory structure", () => {
|
|
const context = buildInitialContext(structure, asts)
|
|
|
|
expect(context).toContain("## Structure")
|
|
expect(context).toContain("src/")
|
|
expect(context).toContain("tests/")
|
|
})
|
|
|
|
it("should include file overview with AST summaries (signatures format)", () => {
|
|
const context = buildInitialContext(structure, asts)
|
|
|
|
expect(context).toContain("## Files")
|
|
expect(context).toContain("### src/index.ts")
|
|
expect(context).toContain("- main()")
|
|
expect(context).toContain("### src/utils.ts")
|
|
expect(context).toContain("- class Helper")
|
|
})
|
|
|
|
it("should use compact format when includeSignatures is false", () => {
|
|
const context = buildInitialContext(structure, asts, undefined, {
|
|
includeSignatures: false,
|
|
})
|
|
|
|
expect(context).toContain("## Files")
|
|
expect(context).toContain("fn: main")
|
|
expect(context).toContain("class: Helper")
|
|
})
|
|
|
|
it("should include file flags from metadata", () => {
|
|
const metas = new Map<string, FileMeta>([
|
|
[
|
|
"src/index.ts",
|
|
{
|
|
complexity: { loc: 100, nesting: 3, cyclomaticComplexity: 10, score: 75 },
|
|
dependencies: [],
|
|
dependents: ["a.ts", "b.ts", "c.ts", "d.ts", "e.ts", "f.ts"],
|
|
isHub: true,
|
|
isEntryPoint: true,
|
|
fileType: "source",
|
|
},
|
|
],
|
|
])
|
|
|
|
const context = buildInitialContext(structure, asts, metas)
|
|
|
|
expect(context).toContain("(hub, entry, complex)")
|
|
})
|
|
})
|
|
|
|
describe("buildFileContext", () => {
|
|
const ast: FileAST = {
|
|
imports: [
|
|
{ name: "fs", from: "node:fs", line: 1, type: "builtin", isDefault: false },
|
|
{ name: "helper", from: "./helper", line: 2, type: "internal", isDefault: true },
|
|
],
|
|
exports: [
|
|
{ name: "main", line: 10, isDefault: false, kind: "function" },
|
|
{ name: "Config", line: 20, isDefault: true, kind: "class" },
|
|
],
|
|
functions: [
|
|
{
|
|
name: "main",
|
|
lineStart: 10,
|
|
lineEnd: 30,
|
|
params: [
|
|
{ name: "args", optional: false, hasDefault: false },
|
|
{ name: "options", optional: true, hasDefault: false },
|
|
],
|
|
isAsync: true,
|
|
isExported: true,
|
|
},
|
|
],
|
|
classes: [
|
|
{
|
|
name: "Config",
|
|
lineStart: 40,
|
|
lineEnd: 80,
|
|
methods: [
|
|
{
|
|
name: "load",
|
|
lineStart: 50,
|
|
lineEnd: 60,
|
|
params: [],
|
|
isAsync: false,
|
|
visibility: "public",
|
|
isStatic: false,
|
|
},
|
|
],
|
|
properties: [],
|
|
extends: "BaseConfig",
|
|
implements: ["IConfig"],
|
|
isExported: true,
|
|
isAbstract: false,
|
|
},
|
|
],
|
|
interfaces: [],
|
|
typeAliases: [],
|
|
parseError: false,
|
|
}
|
|
|
|
it("should include file path header", () => {
|
|
const context = buildFileContext("src/index.ts", ast)
|
|
|
|
expect(context).toContain("## src/index.ts")
|
|
})
|
|
|
|
it("should include imports section", () => {
|
|
const context = buildFileContext("src/index.ts", ast)
|
|
|
|
expect(context).toContain("### Imports")
|
|
expect(context).toContain('fs from "node:fs" (builtin)')
|
|
expect(context).toContain('helper from "./helper" (internal)')
|
|
})
|
|
|
|
it("should include exports section", () => {
|
|
const context = buildFileContext("src/index.ts", ast)
|
|
|
|
expect(context).toContain("### Exports")
|
|
expect(context).toContain("function main")
|
|
expect(context).toContain("class Config (default)")
|
|
})
|
|
|
|
it("should include functions section", () => {
|
|
const context = buildFileContext("src/index.ts", ast)
|
|
|
|
expect(context).toContain("### Functions")
|
|
expect(context).toContain("async main(args, options)")
|
|
expect(context).toContain("[10-30]")
|
|
})
|
|
|
|
it("should include classes section with methods", () => {
|
|
const context = buildFileContext("src/index.ts", ast)
|
|
|
|
expect(context).toContain("### Classes")
|
|
expect(context).toContain("Config extends BaseConfig implements IConfig")
|
|
expect(context).toContain("[40-80]")
|
|
expect(context).toContain("load()")
|
|
})
|
|
|
|
it("should include metadata section when provided", () => {
|
|
const meta: FileMeta = {
|
|
complexity: { loc: 100, nesting: 3, cyclomaticComplexity: 10, score: 65 },
|
|
dependencies: ["a.ts", "b.ts"],
|
|
dependents: ["c.ts"],
|
|
isHub: false,
|
|
isEntryPoint: true,
|
|
fileType: "source",
|
|
}
|
|
|
|
const context = buildFileContext("src/index.ts", ast, meta)
|
|
|
|
expect(context).toContain("### Metadata")
|
|
expect(context).toContain("LOC: 100")
|
|
expect(context).toContain("Complexity: 65/100")
|
|
expect(context).toContain("Dependencies: 2")
|
|
expect(context).toContain("Dependents: 1")
|
|
})
|
|
})
|
|
|
|
describe("buildFileContext - edge cases", () => {
|
|
it("should handle empty imports", () => {
|
|
const ast: FileAST = {
|
|
imports: [],
|
|
exports: [],
|
|
functions: [],
|
|
classes: [],
|
|
interfaces: [],
|
|
typeAliases: [],
|
|
parseError: false,
|
|
}
|
|
|
|
const context = buildFileContext("empty.ts", ast)
|
|
|
|
expect(context).toContain("## empty.ts")
|
|
expect(context).not.toContain("### Imports")
|
|
})
|
|
|
|
it("should handle empty exports", () => {
|
|
const ast: FileAST = {
|
|
imports: [{ name: "x", from: "./x", line: 1, type: "internal", isDefault: false }],
|
|
exports: [],
|
|
functions: [],
|
|
classes: [],
|
|
interfaces: [],
|
|
typeAliases: [],
|
|
parseError: false,
|
|
}
|
|
|
|
const context = buildFileContext("no-exports.ts", ast)
|
|
|
|
expect(context).toContain("### Imports")
|
|
expect(context).not.toContain("### Exports")
|
|
})
|
|
|
|
it("should handle empty functions", () => {
|
|
const ast: FileAST = {
|
|
imports: [],
|
|
exports: [],
|
|
functions: [],
|
|
classes: [
|
|
{
|
|
name: "MyClass",
|
|
lineStart: 1,
|
|
lineEnd: 10,
|
|
methods: [],
|
|
properties: [],
|
|
implements: [],
|
|
isExported: false,
|
|
isAbstract: false,
|
|
},
|
|
],
|
|
interfaces: [],
|
|
typeAliases: [],
|
|
parseError: false,
|
|
}
|
|
|
|
const context = buildFileContext("no-functions.ts", ast)
|
|
|
|
expect(context).not.toContain("### Functions")
|
|
expect(context).toContain("### Classes")
|
|
})
|
|
|
|
it("should handle empty classes", () => {
|
|
const ast: FileAST = {
|
|
imports: [],
|
|
exports: [],
|
|
functions: [
|
|
{
|
|
name: "test",
|
|
lineStart: 1,
|
|
lineEnd: 5,
|
|
params: [],
|
|
isAsync: false,
|
|
isExported: false,
|
|
},
|
|
],
|
|
classes: [],
|
|
interfaces: [],
|
|
typeAliases: [],
|
|
parseError: false,
|
|
}
|
|
|
|
const context = buildFileContext("no-classes.ts", ast)
|
|
|
|
expect(context).toContain("### Functions")
|
|
expect(context).not.toContain("### Classes")
|
|
})
|
|
|
|
it("should handle class without extends", () => {
|
|
const ast: FileAST = {
|
|
imports: [],
|
|
exports: [],
|
|
functions: [],
|
|
classes: [
|
|
{
|
|
name: "Standalone",
|
|
lineStart: 1,
|
|
lineEnd: 10,
|
|
methods: [],
|
|
properties: [],
|
|
implements: ["IFoo"],
|
|
isExported: false,
|
|
isAbstract: false,
|
|
},
|
|
],
|
|
interfaces: [],
|
|
typeAliases: [],
|
|
parseError: false,
|
|
}
|
|
|
|
const context = buildFileContext("standalone.ts", ast)
|
|
|
|
expect(context).toContain("Standalone implements IFoo")
|
|
expect(context).not.toContain("extends")
|
|
})
|
|
|
|
it("should handle class without implements", () => {
|
|
const ast: FileAST = {
|
|
imports: [],
|
|
exports: [],
|
|
functions: [],
|
|
classes: [
|
|
{
|
|
name: "Child",
|
|
lineStart: 1,
|
|
lineEnd: 10,
|
|
methods: [],
|
|
properties: [],
|
|
extends: "Parent",
|
|
implements: [],
|
|
isExported: false,
|
|
isAbstract: false,
|
|
},
|
|
],
|
|
interfaces: [],
|
|
typeAliases: [],
|
|
parseError: false,
|
|
}
|
|
|
|
const context = buildFileContext("child.ts", ast)
|
|
|
|
expect(context).toContain("Child extends Parent")
|
|
expect(context).not.toContain("implements")
|
|
})
|
|
|
|
it("should handle method with private visibility", () => {
|
|
const ast: FileAST = {
|
|
imports: [],
|
|
exports: [],
|
|
functions: [],
|
|
classes: [
|
|
{
|
|
name: "WithPrivate",
|
|
lineStart: 1,
|
|
lineEnd: 20,
|
|
methods: [
|
|
{
|
|
name: "secretMethod",
|
|
lineStart: 5,
|
|
lineEnd: 10,
|
|
params: [],
|
|
isAsync: false,
|
|
visibility: "private",
|
|
isStatic: false,
|
|
},
|
|
],
|
|
properties: [],
|
|
implements: [],
|
|
isExported: false,
|
|
isAbstract: false,
|
|
},
|
|
],
|
|
interfaces: [],
|
|
typeAliases: [],
|
|
parseError: false,
|
|
}
|
|
|
|
const context = buildFileContext("private.ts", ast)
|
|
|
|
expect(context).toContain("private secretMethod()")
|
|
})
|
|
|
|
it("should handle non-async function", () => {
|
|
const ast: FileAST = {
|
|
imports: [],
|
|
exports: [],
|
|
functions: [
|
|
{
|
|
name: "syncFn",
|
|
lineStart: 1,
|
|
lineEnd: 5,
|
|
params: [{ name: "x", optional: false, hasDefault: false }],
|
|
isAsync: false,
|
|
isExported: false,
|
|
},
|
|
],
|
|
classes: [],
|
|
interfaces: [],
|
|
typeAliases: [],
|
|
parseError: false,
|
|
}
|
|
|
|
const context = buildFileContext("sync.ts", ast)
|
|
|
|
expect(context).toContain("syncFn(x)")
|
|
expect(context).not.toContain("async syncFn")
|
|
})
|
|
|
|
it("should handle export without default", () => {
|
|
const ast: FileAST = {
|
|
imports: [],
|
|
exports: [{ name: "foo", line: 1, isDefault: false, kind: "variable" }],
|
|
functions: [],
|
|
classes: [],
|
|
interfaces: [],
|
|
typeAliases: [],
|
|
parseError: false,
|
|
}
|
|
|
|
const context = buildFileContext("named-export.ts", ast)
|
|
|
|
expect(context).toContain("variable foo")
|
|
expect(context).not.toContain("(default)")
|
|
})
|
|
})
|
|
|
|
describe("buildInitialContext - edge cases", () => {
|
|
it("should handle nested directory names", () => {
|
|
const structure: ProjectStructure = {
|
|
name: "test",
|
|
rootPath: "/test",
|
|
files: [],
|
|
directories: ["src/components/ui"],
|
|
}
|
|
const asts = new Map<string, FileAST>()
|
|
|
|
const context = buildInitialContext(structure, asts)
|
|
|
|
expect(context).toContain("ui/")
|
|
})
|
|
|
|
it("should handle file with only interfaces", () => {
|
|
const structure: ProjectStructure = {
|
|
name: "test",
|
|
rootPath: "/test",
|
|
files: ["types.ts"],
|
|
directories: [],
|
|
}
|
|
const asts = new Map<string, FileAST>([
|
|
[
|
|
"types.ts",
|
|
{
|
|
imports: [],
|
|
exports: [],
|
|
functions: [],
|
|
classes: [],
|
|
interfaces: [
|
|
{
|
|
name: "IFoo",
|
|
lineStart: 1,
|
|
lineEnd: 5,
|
|
properties: [],
|
|
extends: [],
|
|
isExported: true,
|
|
},
|
|
],
|
|
typeAliases: [],
|
|
parseError: false,
|
|
},
|
|
],
|
|
])
|
|
|
|
const context = buildInitialContext(structure, asts)
|
|
|
|
expect(context).toContain("- interface IFoo")
|
|
})
|
|
|
|
it("should handle file with only interfaces (compact format)", () => {
|
|
const structure: ProjectStructure = {
|
|
name: "test",
|
|
rootPath: "/test",
|
|
files: ["types.ts"],
|
|
directories: [],
|
|
}
|
|
const asts = new Map<string, FileAST>([
|
|
[
|
|
"types.ts",
|
|
{
|
|
imports: [],
|
|
exports: [],
|
|
functions: [],
|
|
classes: [],
|
|
interfaces: [
|
|
{
|
|
name: "IFoo",
|
|
lineStart: 1,
|
|
lineEnd: 5,
|
|
properties: [],
|
|
extends: [],
|
|
isExported: true,
|
|
},
|
|
],
|
|
typeAliases: [],
|
|
parseError: false,
|
|
},
|
|
],
|
|
])
|
|
|
|
const context = buildInitialContext(structure, asts, undefined, {
|
|
includeSignatures: false,
|
|
})
|
|
|
|
expect(context).toContain("interface: IFoo")
|
|
})
|
|
|
|
it("should handle file with only type aliases", () => {
|
|
const structure: ProjectStructure = {
|
|
name: "test",
|
|
rootPath: "/test",
|
|
files: ["types.ts"],
|
|
directories: [],
|
|
}
|
|
const asts = new Map<string, FileAST>([
|
|
[
|
|
"types.ts",
|
|
{
|
|
imports: [],
|
|
exports: [],
|
|
functions: [],
|
|
classes: [],
|
|
interfaces: [],
|
|
typeAliases: [{ name: "MyType", line: 1, isExported: true }],
|
|
parseError: false,
|
|
},
|
|
],
|
|
])
|
|
|
|
const context = buildInitialContext(structure, asts)
|
|
|
|
expect(context).toContain("- type MyType")
|
|
})
|
|
|
|
it("should handle file with only type aliases (compact format)", () => {
|
|
const structure: ProjectStructure = {
|
|
name: "test",
|
|
rootPath: "/test",
|
|
files: ["types.ts"],
|
|
directories: [],
|
|
}
|
|
const asts = new Map<string, FileAST>([
|
|
[
|
|
"types.ts",
|
|
{
|
|
imports: [],
|
|
exports: [],
|
|
functions: [],
|
|
classes: [],
|
|
interfaces: [],
|
|
typeAliases: [{ name: "MyType", line: 1, isExported: true }],
|
|
parseError: false,
|
|
},
|
|
],
|
|
])
|
|
|
|
const context = buildInitialContext(structure, asts, undefined, {
|
|
includeSignatures: false,
|
|
})
|
|
|
|
expect(context).toContain("type: MyType")
|
|
})
|
|
|
|
it("should handle file with no AST content", () => {
|
|
const structure: ProjectStructure = {
|
|
name: "test",
|
|
rootPath: "/test",
|
|
files: ["empty.ts"],
|
|
directories: [],
|
|
}
|
|
const asts = new Map<string, FileAST>([
|
|
[
|
|
"empty.ts",
|
|
{
|
|
imports: [],
|
|
exports: [],
|
|
functions: [],
|
|
classes: [],
|
|
interfaces: [],
|
|
typeAliases: [],
|
|
parseError: false,
|
|
},
|
|
],
|
|
])
|
|
|
|
const context = buildInitialContext(structure, asts)
|
|
|
|
expect(context).toContain("- empty.ts")
|
|
})
|
|
|
|
it("should handle meta with only hub flag", () => {
|
|
const structure: ProjectStructure = {
|
|
name: "test",
|
|
rootPath: "/test",
|
|
files: ["hub.ts"],
|
|
directories: [],
|
|
}
|
|
const asts = new Map<string, FileAST>([
|
|
[
|
|
"hub.ts",
|
|
{
|
|
imports: [],
|
|
exports: [],
|
|
functions: [],
|
|
classes: [],
|
|
interfaces: [],
|
|
typeAliases: [],
|
|
parseError: false,
|
|
},
|
|
],
|
|
])
|
|
const metas = new Map<string, FileMeta>([
|
|
[
|
|
"hub.ts",
|
|
{
|
|
complexity: { loc: 10, nesting: 1, cyclomaticComplexity: 1, score: 10 },
|
|
dependencies: [],
|
|
dependents: [],
|
|
isHub: true,
|
|
isEntryPoint: false,
|
|
fileType: "source",
|
|
},
|
|
],
|
|
])
|
|
|
|
const context = buildInitialContext(structure, asts, metas)
|
|
|
|
expect(context).toContain("(hub)")
|
|
expect(context).not.toContain("entry")
|
|
expect(context).not.toContain("complex")
|
|
})
|
|
|
|
it("should handle meta with no flags", () => {
|
|
const structure: ProjectStructure = {
|
|
name: "test",
|
|
rootPath: "/test",
|
|
files: ["normal.ts"],
|
|
directories: [],
|
|
}
|
|
const asts = new Map<string, FileAST>([
|
|
[
|
|
"normal.ts",
|
|
{
|
|
imports: [],
|
|
exports: [],
|
|
functions: [],
|
|
classes: [],
|
|
interfaces: [],
|
|
typeAliases: [],
|
|
parseError: false,
|
|
},
|
|
],
|
|
])
|
|
const metas = new Map<string, FileMeta>([
|
|
[
|
|
"normal.ts",
|
|
{
|
|
complexity: { loc: 10, nesting: 1, cyclomaticComplexity: 1, score: 10 },
|
|
dependencies: [],
|
|
dependents: [],
|
|
isHub: false,
|
|
isEntryPoint: false,
|
|
fileType: "source",
|
|
},
|
|
],
|
|
])
|
|
|
|
const context = buildInitialContext(structure, asts, metas)
|
|
|
|
expect(context).toContain("- normal.ts")
|
|
expect(context).not.toContain("(hub")
|
|
expect(context).not.toContain("entry")
|
|
expect(context).not.toContain("complex")
|
|
})
|
|
|
|
it("should skip files not in AST map", () => {
|
|
const structure: ProjectStructure = {
|
|
name: "test",
|
|
rootPath: "/test",
|
|
files: ["exists.ts", "missing.ts"],
|
|
directories: [],
|
|
}
|
|
const asts = new Map<string, FileAST>([
|
|
[
|
|
"exists.ts",
|
|
{
|
|
imports: [],
|
|
exports: [],
|
|
functions: [],
|
|
classes: [],
|
|
interfaces: [],
|
|
typeAliases: [],
|
|
parseError: false,
|
|
},
|
|
],
|
|
])
|
|
|
|
const context = buildInitialContext(structure, asts)
|
|
|
|
expect(context).toContain("exists.ts")
|
|
expect(context).not.toContain("missing.ts")
|
|
})
|
|
|
|
it("should skip undefined AST entries", () => {
|
|
const structure: ProjectStructure = {
|
|
name: "test",
|
|
rootPath: "/test",
|
|
files: ["file.ts"],
|
|
directories: [],
|
|
}
|
|
const asts = new Map<string, FileAST>()
|
|
asts.set("file.ts", undefined as unknown as FileAST)
|
|
|
|
const context = buildInitialContext(structure, asts)
|
|
|
|
expect(context).toContain("## Files")
|
|
expect(context).not.toContain("file.ts")
|
|
})
|
|
})
|
|
|
|
describe("truncateContext", () => {
|
|
it("should return original context if within limit", () => {
|
|
const context = "Short context"
|
|
|
|
const result = truncateContext(context, 1000)
|
|
|
|
expect(result).toBe(context)
|
|
})
|
|
|
|
it("should truncate long context", () => {
|
|
const context = "a".repeat(1000)
|
|
|
|
const result = truncateContext(context, 100)
|
|
|
|
expect(result.length).toBeLessThan(500)
|
|
expect(result).toContain("truncated")
|
|
})
|
|
|
|
it("should break at newline boundary", () => {
|
|
const context = "Line 1\nLine 2\nLine 3\n" + "a".repeat(1000)
|
|
|
|
const result = truncateContext(context, 50)
|
|
|
|
expect(result).toContain("truncated")
|
|
})
|
|
})
|
|
|
|
describe("function signatures with types", () => {
|
|
it("should format function with typed parameters", () => {
|
|
const structure: ProjectStructure = {
|
|
name: "test",
|
|
rootPath: "/test",
|
|
files: ["user.ts"],
|
|
directories: [],
|
|
}
|
|
const asts = new Map<string, FileAST>([
|
|
[
|
|
"user.ts",
|
|
{
|
|
imports: [],
|
|
exports: [],
|
|
functions: [
|
|
{
|
|
name: "getUser",
|
|
lineStart: 1,
|
|
lineEnd: 5,
|
|
params: [
|
|
{
|
|
name: "id",
|
|
type: "string",
|
|
optional: false,
|
|
hasDefault: false,
|
|
},
|
|
],
|
|
isAsync: false,
|
|
isExported: true,
|
|
},
|
|
],
|
|
classes: [],
|
|
interfaces: [],
|
|
typeAliases: [],
|
|
parseError: false,
|
|
},
|
|
],
|
|
])
|
|
|
|
const context = buildInitialContext(structure, asts)
|
|
|
|
expect(context).toContain("- getUser(id: string)")
|
|
})
|
|
|
|
it("should format async function with return type", () => {
|
|
const structure: ProjectStructure = {
|
|
name: "test",
|
|
rootPath: "/test",
|
|
files: ["user.ts"],
|
|
directories: [],
|
|
}
|
|
const asts = new Map<string, FileAST>([
|
|
[
|
|
"user.ts",
|
|
{
|
|
imports: [],
|
|
exports: [],
|
|
functions: [
|
|
{
|
|
name: "getUser",
|
|
lineStart: 1,
|
|
lineEnd: 5,
|
|
params: [
|
|
{
|
|
name: "id",
|
|
type: "string",
|
|
optional: false,
|
|
hasDefault: false,
|
|
},
|
|
],
|
|
isAsync: true,
|
|
isExported: true,
|
|
returnType: "Promise<User>",
|
|
},
|
|
],
|
|
classes: [],
|
|
interfaces: [],
|
|
typeAliases: [],
|
|
parseError: false,
|
|
},
|
|
],
|
|
])
|
|
|
|
const context = buildInitialContext(structure, asts)
|
|
|
|
expect(context).toContain("- async getUser(id: string): Promise<User>")
|
|
})
|
|
|
|
it("should format function with optional parameters", () => {
|
|
const structure: ProjectStructure = {
|
|
name: "test",
|
|
rootPath: "/test",
|
|
files: ["utils.ts"],
|
|
directories: [],
|
|
}
|
|
const asts = new Map<string, FileAST>([
|
|
[
|
|
"utils.ts",
|
|
{
|
|
imports: [],
|
|
exports: [],
|
|
functions: [
|
|
{
|
|
name: "format",
|
|
lineStart: 1,
|
|
lineEnd: 5,
|
|
params: [
|
|
{
|
|
name: "value",
|
|
type: "string",
|
|
optional: false,
|
|
hasDefault: false,
|
|
},
|
|
{
|
|
name: "options",
|
|
type: "FormatOptions",
|
|
optional: true,
|
|
hasDefault: false,
|
|
},
|
|
],
|
|
isAsync: false,
|
|
isExported: true,
|
|
returnType: "string",
|
|
},
|
|
],
|
|
classes: [],
|
|
interfaces: [],
|
|
typeAliases: [],
|
|
parseError: false,
|
|
},
|
|
],
|
|
])
|
|
|
|
const context = buildInitialContext(structure, asts)
|
|
|
|
expect(context).toContain("- format(value: string, options?: FormatOptions): string")
|
|
})
|
|
|
|
it("should format function with multiple typed parameters", () => {
|
|
const structure: ProjectStructure = {
|
|
name: "test",
|
|
rootPath: "/test",
|
|
files: ["api.ts"],
|
|
directories: [],
|
|
}
|
|
const asts = new Map<string, FileAST>([
|
|
[
|
|
"api.ts",
|
|
{
|
|
imports: [],
|
|
exports: [],
|
|
functions: [
|
|
{
|
|
name: "createUser",
|
|
lineStart: 1,
|
|
lineEnd: 10,
|
|
params: [
|
|
{
|
|
name: "name",
|
|
type: "string",
|
|
optional: false,
|
|
hasDefault: false,
|
|
},
|
|
{
|
|
name: "email",
|
|
type: "string",
|
|
optional: false,
|
|
hasDefault: false,
|
|
},
|
|
{
|
|
name: "age",
|
|
type: "number",
|
|
optional: true,
|
|
hasDefault: false,
|
|
},
|
|
],
|
|
isAsync: true,
|
|
isExported: true,
|
|
returnType: "Promise<User>",
|
|
},
|
|
],
|
|
classes: [],
|
|
interfaces: [],
|
|
typeAliases: [],
|
|
parseError: false,
|
|
},
|
|
],
|
|
])
|
|
|
|
const context = buildInitialContext(structure, asts)
|
|
|
|
expect(context).toContain(
|
|
"- async createUser(name: string, email: string, age?: number): Promise<User>",
|
|
)
|
|
})
|
|
|
|
it("should format function without types (JavaScript style)", () => {
|
|
const structure: ProjectStructure = {
|
|
name: "test",
|
|
rootPath: "/test",
|
|
files: ["legacy.js"],
|
|
directories: [],
|
|
}
|
|
const asts = new Map<string, FileAST>([
|
|
[
|
|
"legacy.js",
|
|
{
|
|
imports: [],
|
|
exports: [],
|
|
functions: [
|
|
{
|
|
name: "doSomething",
|
|
lineStart: 1,
|
|
lineEnd: 5,
|
|
params: [
|
|
{ name: "x", optional: false, hasDefault: false },
|
|
{ name: "y", optional: false, hasDefault: false },
|
|
],
|
|
isAsync: false,
|
|
isExported: true,
|
|
},
|
|
],
|
|
classes: [],
|
|
interfaces: [],
|
|
typeAliases: [],
|
|
parseError: false,
|
|
},
|
|
],
|
|
])
|
|
|
|
const context = buildInitialContext(structure, asts)
|
|
|
|
expect(context).toContain("- doSomething(x, y)")
|
|
})
|
|
|
|
it("should format interface with extends", () => {
|
|
const structure: ProjectStructure = {
|
|
name: "test",
|
|
rootPath: "/test",
|
|
files: ["types.ts"],
|
|
directories: [],
|
|
}
|
|
const asts = new Map<string, FileAST>([
|
|
[
|
|
"types.ts",
|
|
{
|
|
imports: [],
|
|
exports: [],
|
|
functions: [],
|
|
classes: [],
|
|
interfaces: [
|
|
{
|
|
name: "AdminUser",
|
|
lineStart: 1,
|
|
lineEnd: 5,
|
|
properties: [],
|
|
extends: ["User", "Admin"],
|
|
isExported: true,
|
|
},
|
|
],
|
|
typeAliases: [],
|
|
parseError: false,
|
|
},
|
|
],
|
|
])
|
|
|
|
const context = buildInitialContext(structure, asts)
|
|
|
|
expect(context).toContain("- interface AdminUser extends User, Admin")
|
|
})
|
|
})
|
|
|
|
describe("interface fields (0.24.2)", () => {
|
|
it("should format interface with fields", () => {
|
|
const structure: ProjectStructure = {
|
|
name: "test",
|
|
rootPath: "/test",
|
|
files: ["user.ts"],
|
|
directories: [],
|
|
}
|
|
const asts = new Map<string, FileAST>([
|
|
[
|
|
"user.ts",
|
|
{
|
|
imports: [],
|
|
exports: [],
|
|
functions: [],
|
|
classes: [],
|
|
interfaces: [
|
|
{
|
|
name: "User",
|
|
lineStart: 1,
|
|
lineEnd: 5,
|
|
properties: [
|
|
{
|
|
name: "id",
|
|
line: 2,
|
|
type: "string",
|
|
visibility: "public",
|
|
isStatic: false,
|
|
isReadonly: false,
|
|
},
|
|
{
|
|
name: "name",
|
|
line: 3,
|
|
type: "string",
|
|
visibility: "public",
|
|
isStatic: false,
|
|
isReadonly: false,
|
|
},
|
|
{
|
|
name: "email",
|
|
line: 4,
|
|
type: "string",
|
|
visibility: "public",
|
|
isStatic: false,
|
|
isReadonly: false,
|
|
},
|
|
],
|
|
extends: [],
|
|
isExported: true,
|
|
},
|
|
],
|
|
typeAliases: [],
|
|
parseError: false,
|
|
},
|
|
],
|
|
])
|
|
|
|
const context = buildInitialContext(structure, asts)
|
|
|
|
expect(context).toContain("interface User { id: string, name: string, email: string }")
|
|
})
|
|
|
|
it("should format interface with extends and fields", () => {
|
|
const structure: ProjectStructure = {
|
|
name: "test",
|
|
rootPath: "/test",
|
|
files: ["types.ts"],
|
|
directories: [],
|
|
}
|
|
const asts = new Map<string, FileAST>([
|
|
[
|
|
"types.ts",
|
|
{
|
|
imports: [],
|
|
exports: [],
|
|
functions: [],
|
|
classes: [],
|
|
interfaces: [
|
|
{
|
|
name: "AdminUser",
|
|
lineStart: 1,
|
|
lineEnd: 5,
|
|
properties: [
|
|
{
|
|
name: "role",
|
|
line: 2,
|
|
type: "string",
|
|
visibility: "public",
|
|
isStatic: false,
|
|
isReadonly: false,
|
|
},
|
|
],
|
|
extends: ["User"],
|
|
isExported: true,
|
|
},
|
|
],
|
|
typeAliases: [],
|
|
parseError: false,
|
|
},
|
|
],
|
|
])
|
|
|
|
const context = buildInitialContext(structure, asts)
|
|
|
|
expect(context).toContain("interface AdminUser extends User { role: string }")
|
|
})
|
|
|
|
it("should format interface with readonly fields", () => {
|
|
const structure: ProjectStructure = {
|
|
name: "test",
|
|
rootPath: "/test",
|
|
files: ["types.ts"],
|
|
directories: [],
|
|
}
|
|
const asts = new Map<string, FileAST>([
|
|
[
|
|
"types.ts",
|
|
{
|
|
imports: [],
|
|
exports: [],
|
|
functions: [],
|
|
classes: [],
|
|
interfaces: [
|
|
{
|
|
name: "Config",
|
|
lineStart: 1,
|
|
lineEnd: 3,
|
|
properties: [
|
|
{
|
|
name: "version",
|
|
line: 2,
|
|
type: "string",
|
|
visibility: "public",
|
|
isStatic: false,
|
|
isReadonly: true,
|
|
},
|
|
],
|
|
extends: [],
|
|
isExported: true,
|
|
},
|
|
],
|
|
typeAliases: [],
|
|
parseError: false,
|
|
},
|
|
],
|
|
])
|
|
|
|
const context = buildInitialContext(structure, asts)
|
|
|
|
expect(context).toContain("interface Config { readonly version: string }")
|
|
})
|
|
|
|
it("should format interface with no type annotation", () => {
|
|
const structure: ProjectStructure = {
|
|
name: "test",
|
|
rootPath: "/test",
|
|
files: ["types.ts"],
|
|
directories: [],
|
|
}
|
|
const asts = new Map<string, FileAST>([
|
|
[
|
|
"types.ts",
|
|
{
|
|
imports: [],
|
|
exports: [],
|
|
functions: [],
|
|
classes: [],
|
|
interfaces: [
|
|
{
|
|
name: "Loose",
|
|
lineStart: 1,
|
|
lineEnd: 3,
|
|
properties: [
|
|
{
|
|
name: "data",
|
|
line: 2,
|
|
visibility: "public",
|
|
isStatic: false,
|
|
isReadonly: false,
|
|
},
|
|
],
|
|
extends: [],
|
|
isExported: true,
|
|
},
|
|
],
|
|
typeAliases: [],
|
|
parseError: false,
|
|
},
|
|
],
|
|
])
|
|
|
|
const context = buildInitialContext(structure, asts)
|
|
|
|
expect(context).toContain("interface Loose { data }")
|
|
})
|
|
})
|
|
|
|
describe("type alias definitions (0.24.2)", () => {
|
|
it("should format type alias with definition", () => {
|
|
const structure: ProjectStructure = {
|
|
name: "test",
|
|
rootPath: "/test",
|
|
files: ["types.ts"],
|
|
directories: [],
|
|
}
|
|
const asts = new Map<string, FileAST>([
|
|
[
|
|
"types.ts",
|
|
{
|
|
imports: [],
|
|
exports: [],
|
|
functions: [],
|
|
classes: [],
|
|
interfaces: [],
|
|
typeAliases: [
|
|
{
|
|
name: "UserId",
|
|
line: 1,
|
|
isExported: true,
|
|
definition: "string",
|
|
},
|
|
],
|
|
parseError: false,
|
|
},
|
|
],
|
|
])
|
|
|
|
const context = buildInitialContext(structure, asts)
|
|
|
|
expect(context).toContain("- type UserId = string")
|
|
})
|
|
|
|
it("should format union type alias", () => {
|
|
const structure: ProjectStructure = {
|
|
name: "test",
|
|
rootPath: "/test",
|
|
files: ["types.ts"],
|
|
directories: [],
|
|
}
|
|
const asts = new Map<string, FileAST>([
|
|
[
|
|
"types.ts",
|
|
{
|
|
imports: [],
|
|
exports: [],
|
|
functions: [],
|
|
classes: [],
|
|
interfaces: [],
|
|
typeAliases: [
|
|
{
|
|
name: "Status",
|
|
line: 1,
|
|
isExported: true,
|
|
definition: '"pending" | "active" | "done"',
|
|
},
|
|
],
|
|
parseError: false,
|
|
},
|
|
],
|
|
])
|
|
|
|
const context = buildInitialContext(structure, asts)
|
|
|
|
expect(context).toContain('- type Status = "pending" | "active" | "done"')
|
|
})
|
|
|
|
it("should format intersection type alias", () => {
|
|
const structure: ProjectStructure = {
|
|
name: "test",
|
|
rootPath: "/test",
|
|
files: ["types.ts"],
|
|
directories: [],
|
|
}
|
|
const asts = new Map<string, FileAST>([
|
|
[
|
|
"types.ts",
|
|
{
|
|
imports: [],
|
|
exports: [],
|
|
functions: [],
|
|
classes: [],
|
|
interfaces: [],
|
|
typeAliases: [
|
|
{
|
|
name: "AdminUser",
|
|
line: 1,
|
|
isExported: true,
|
|
definition: "User & Admin",
|
|
},
|
|
],
|
|
parseError: false,
|
|
},
|
|
],
|
|
])
|
|
|
|
const context = buildInitialContext(structure, asts)
|
|
|
|
expect(context).toContain("- type AdminUser = User & Admin")
|
|
})
|
|
|
|
it("should truncate long type definitions", () => {
|
|
const structure: ProjectStructure = {
|
|
name: "test",
|
|
rootPath: "/test",
|
|
files: ["types.ts"],
|
|
directories: [],
|
|
}
|
|
const longDefinition =
|
|
"{ id: string, name: string, email: string, phone: string, address: string, city: string, country: string, zip: string }"
|
|
const asts = new Map<string, FileAST>([
|
|
[
|
|
"types.ts",
|
|
{
|
|
imports: [],
|
|
exports: [],
|
|
functions: [],
|
|
classes: [],
|
|
interfaces: [],
|
|
typeAliases: [
|
|
{
|
|
name: "BigType",
|
|
line: 1,
|
|
isExported: true,
|
|
definition: longDefinition,
|
|
},
|
|
],
|
|
parseError: false,
|
|
},
|
|
],
|
|
])
|
|
|
|
const context = buildInitialContext(structure, asts)
|
|
|
|
expect(context).toContain("- type BigType = { id: string")
|
|
expect(context).toContain("...")
|
|
})
|
|
|
|
it("should format type alias without definition (fallback)", () => {
|
|
const structure: ProjectStructure = {
|
|
name: "test",
|
|
rootPath: "/test",
|
|
files: ["types.ts"],
|
|
directories: [],
|
|
}
|
|
const asts = new Map<string, FileAST>([
|
|
[
|
|
"types.ts",
|
|
{
|
|
imports: [],
|
|
exports: [],
|
|
functions: [],
|
|
classes: [],
|
|
interfaces: [],
|
|
typeAliases: [
|
|
{
|
|
name: "Unknown",
|
|
line: 1,
|
|
isExported: true,
|
|
},
|
|
],
|
|
parseError: false,
|
|
},
|
|
],
|
|
])
|
|
|
|
const context = buildInitialContext(structure, asts)
|
|
|
|
expect(context).toContain("- type Unknown")
|
|
expect(context).not.toContain("- type Unknown =")
|
|
})
|
|
|
|
it("should format function type alias", () => {
|
|
const structure: ProjectStructure = {
|
|
name: "test",
|
|
rootPath: "/test",
|
|
files: ["types.ts"],
|
|
directories: [],
|
|
}
|
|
const asts = new Map<string, FileAST>([
|
|
[
|
|
"types.ts",
|
|
{
|
|
imports: [],
|
|
exports: [],
|
|
functions: [],
|
|
classes: [],
|
|
interfaces: [],
|
|
typeAliases: [
|
|
{
|
|
name: "Handler",
|
|
line: 1,
|
|
isExported: true,
|
|
definition: "(event: Event) => void",
|
|
},
|
|
],
|
|
parseError: false,
|
|
},
|
|
],
|
|
])
|
|
|
|
const context = buildInitialContext(structure, asts)
|
|
|
|
expect(context).toContain("- type Handler = (event: Event) => void")
|
|
})
|
|
})
|
|
|
|
describe("enum definitions (0.24.3)", () => {
|
|
it("should format enum with numeric values", () => {
|
|
const structure: ProjectStructure = {
|
|
name: "test",
|
|
rootPath: "/test",
|
|
files: ["enums.ts"],
|
|
directories: [],
|
|
}
|
|
const asts = new Map<string, FileAST>([
|
|
[
|
|
"enums.ts",
|
|
{
|
|
imports: [],
|
|
exports: [],
|
|
functions: [],
|
|
classes: [],
|
|
interfaces: [],
|
|
typeAliases: [],
|
|
enums: [
|
|
{
|
|
name: "Status",
|
|
lineStart: 1,
|
|
lineEnd: 5,
|
|
members: [
|
|
{ name: "Active", value: 1 },
|
|
{ name: "Inactive", value: 0 },
|
|
{ name: "Pending", value: 2 },
|
|
],
|
|
isExported: true,
|
|
isConst: false,
|
|
},
|
|
],
|
|
parseError: false,
|
|
},
|
|
],
|
|
])
|
|
|
|
const context = buildInitialContext(structure, asts)
|
|
|
|
expect(context).toContain("- enum Status { Active=1, Inactive=0, Pending=2 }")
|
|
})
|
|
|
|
it("should format enum with string values", () => {
|
|
const structure: ProjectStructure = {
|
|
name: "test",
|
|
rootPath: "/test",
|
|
files: ["enums.ts"],
|
|
directories: [],
|
|
}
|
|
const asts = new Map<string, FileAST>([
|
|
[
|
|
"enums.ts",
|
|
{
|
|
imports: [],
|
|
exports: [],
|
|
functions: [],
|
|
classes: [],
|
|
interfaces: [],
|
|
typeAliases: [],
|
|
enums: [
|
|
{
|
|
name: "Role",
|
|
lineStart: 1,
|
|
lineEnd: 5,
|
|
members: [
|
|
{ name: "Admin", value: "admin" },
|
|
{ name: "User", value: "user" },
|
|
],
|
|
isExported: true,
|
|
isConst: false,
|
|
},
|
|
],
|
|
parseError: false,
|
|
},
|
|
],
|
|
])
|
|
|
|
const context = buildInitialContext(structure, asts)
|
|
|
|
expect(context).toContain('- enum Role { Admin="admin", User="user" }')
|
|
})
|
|
|
|
it("should format const enum", () => {
|
|
const structure: ProjectStructure = {
|
|
name: "test",
|
|
rootPath: "/test",
|
|
files: ["enums.ts"],
|
|
directories: [],
|
|
}
|
|
const asts = new Map<string, FileAST>([
|
|
[
|
|
"enums.ts",
|
|
{
|
|
imports: [],
|
|
exports: [],
|
|
functions: [],
|
|
classes: [],
|
|
interfaces: [],
|
|
typeAliases: [],
|
|
enums: [
|
|
{
|
|
name: "HttpStatus",
|
|
lineStart: 1,
|
|
lineEnd: 5,
|
|
members: [
|
|
{ name: "OK", value: 200 },
|
|
{ name: "NotFound", value: 404 },
|
|
],
|
|
isExported: true,
|
|
isConst: true,
|
|
},
|
|
],
|
|
parseError: false,
|
|
},
|
|
],
|
|
])
|
|
|
|
const context = buildInitialContext(structure, asts)
|
|
|
|
expect(context).toContain("- const enum HttpStatus { OK=200, NotFound=404 }")
|
|
})
|
|
|
|
it("should format enum without explicit values", () => {
|
|
const structure: ProjectStructure = {
|
|
name: "test",
|
|
rootPath: "/test",
|
|
files: ["enums.ts"],
|
|
directories: [],
|
|
}
|
|
const asts = new Map<string, FileAST>([
|
|
[
|
|
"enums.ts",
|
|
{
|
|
imports: [],
|
|
exports: [],
|
|
functions: [],
|
|
classes: [],
|
|
interfaces: [],
|
|
typeAliases: [],
|
|
enums: [
|
|
{
|
|
name: "Direction",
|
|
lineStart: 1,
|
|
lineEnd: 5,
|
|
members: [
|
|
{ name: "Up", value: undefined },
|
|
{ name: "Down", value: undefined },
|
|
],
|
|
isExported: true,
|
|
isConst: false,
|
|
},
|
|
],
|
|
parseError: false,
|
|
},
|
|
],
|
|
])
|
|
|
|
const context = buildInitialContext(structure, asts)
|
|
|
|
expect(context).toContain("- enum Direction { Up, Down }")
|
|
})
|
|
|
|
it("should format empty enum", () => {
|
|
const structure: ProjectStructure = {
|
|
name: "test",
|
|
rootPath: "/test",
|
|
files: ["enums.ts"],
|
|
directories: [],
|
|
}
|
|
const asts = new Map<string, FileAST>([
|
|
[
|
|
"enums.ts",
|
|
{
|
|
imports: [],
|
|
exports: [],
|
|
functions: [],
|
|
classes: [],
|
|
interfaces: [],
|
|
typeAliases: [],
|
|
enums: [
|
|
{
|
|
name: "Empty",
|
|
lineStart: 1,
|
|
lineEnd: 1,
|
|
members: [],
|
|
isExported: true,
|
|
isConst: false,
|
|
},
|
|
],
|
|
parseError: false,
|
|
},
|
|
],
|
|
])
|
|
|
|
const context = buildInitialContext(structure, asts)
|
|
|
|
expect(context).toContain("- enum Empty")
|
|
})
|
|
|
|
it("should include enum in compact format", () => {
|
|
const structure: ProjectStructure = {
|
|
name: "test",
|
|
rootPath: "/test",
|
|
files: ["enums.ts"],
|
|
directories: [],
|
|
}
|
|
const asts = new Map<string, FileAST>([
|
|
[
|
|
"enums.ts",
|
|
{
|
|
imports: [],
|
|
exports: [],
|
|
functions: [],
|
|
classes: [],
|
|
interfaces: [],
|
|
typeAliases: [],
|
|
enums: [
|
|
{
|
|
name: "Status",
|
|
lineStart: 1,
|
|
lineEnd: 5,
|
|
members: [{ name: "Active", value: 1 }],
|
|
isExported: true,
|
|
isConst: false,
|
|
},
|
|
],
|
|
parseError: false,
|
|
},
|
|
],
|
|
])
|
|
|
|
const context = buildInitialContext(structure, asts, undefined, {
|
|
includeSignatures: false,
|
|
})
|
|
|
|
expect(context).toContain("enum: Status")
|
|
})
|
|
|
|
it("should truncate long enum definitions", () => {
|
|
const structure: ProjectStructure = {
|
|
name: "test",
|
|
rootPath: "/test",
|
|
files: ["enums.ts"],
|
|
directories: [],
|
|
}
|
|
const asts = new Map<string, FileAST>([
|
|
[
|
|
"enums.ts",
|
|
{
|
|
imports: [],
|
|
exports: [],
|
|
functions: [],
|
|
classes: [],
|
|
interfaces: [],
|
|
typeAliases: [],
|
|
enums: [
|
|
{
|
|
name: "VeryLongEnumName",
|
|
lineStart: 1,
|
|
lineEnd: 20,
|
|
members: [
|
|
{ name: "FirstVeryLongMemberName", value: "first_value" },
|
|
{ name: "SecondVeryLongMemberName", value: "second_value" },
|
|
{ name: "ThirdVeryLongMemberName", value: "third_value" },
|
|
],
|
|
isExported: true,
|
|
isConst: false,
|
|
},
|
|
],
|
|
parseError: false,
|
|
},
|
|
],
|
|
])
|
|
|
|
const context = buildInitialContext(structure, asts)
|
|
|
|
expect(context).toContain("...")
|
|
expect(context).toContain("- enum VeryLongEnumName")
|
|
})
|
|
})
|
|
})
|