Skip to content

Commit e379a65

Browse files
weirdwaterclaude
andcommitted
Implement tests for import generation
Co-authored-by: Claude <noreply@anthropic.com>
1 parent 9d9ff5c commit e379a65

1 file changed

Lines changed: 125 additions & 14 deletions

File tree

Lines changed: 125 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,134 @@
1-
import { ImportableModule, generateImports } from "../generateImports";
1+
import { ImportableModule, generateImports, ImportStatement } from "../generateImports";
22

33
describe("generateImports", () => {
4-
let myModules: ImportableModule[];
54

6-
beforeEach(() => {
7-
myModules = [new ImportableModule("my-module", ["foo", "bar", "baz"])];
5+
describe("with no modules", () => {
6+
it("returns no import statements for empty code", () => {
7+
const result = generateImports([], "");
8+
expect(result).toEqual([]);
9+
});
10+
11+
it("returns no import statements", () => {
12+
const result = generateImports([], "const x = 5; const y = 10;");
13+
expect(result).toEqual([]);
14+
});
15+
});
16+
17+
describe("with modules", () => {
18+
const foobarModule = new ImportableModule("foobar", ["foo", "bar", "baz"]);
19+
const numbersModule = new ImportableModule("numbers", ["pi", "e", "infinity"]);
20+
const animalsModule = new ImportableModule("animals", ["cat", "dog", "capibara"]);
21+
22+
describe("with no matching members in code", () => {
23+
24+
it("returns no import statements", () => {
25+
const code = "x y z";
26+
const result = generateImports([foobarModule, numbersModule, animalsModule], code);
27+
28+
expect(result).toEqual([]);
29+
});
30+
31+
});
32+
33+
describe("with matching members in code", () => {
34+
35+
it("returns import statements for each module with matching members", () => {
36+
const code = " foo cat ";
37+
const result = generateImports([foobarModule, animalsModule], code);
38+
39+
expect(result).toHaveLength(2);
40+
expect(result[0].from).toBe("animals");
41+
expect(result[1].from).toBe("foobar");
42+
});
43+
44+
it("orders import statements alphabetically by module name", () => {
45+
const code = " foo pi cat ";
46+
const result = generateImports([foobarModule, numbersModule, animalsModule], code);
47+
48+
expect(result.map(s => s.from)).toEqual(["animals", "foobar", "numbers"]);
49+
});
50+
51+
describe("with mixed import types", () => {
52+
const code = " foo bar pi e cat ";
53+
const result = generateImports([numbersModule, animalsModule, foobarModule], code);
54+
55+
it("groups import statements by type (multiple, single)", () => {
56+
// Multiple-member imports should come first
57+
expect(result[0].members).toHaveLength(2);
58+
expect(result[1].members).toHaveLength(2);
59+
60+
// Single-member imports should come last
61+
expect(result[2].members).toHaveLength(1);
62+
});
63+
64+
it("sorts grouped imports alphabetically", () => {
65+
expect(result[0].from).toBe("foobar")
66+
expect(result[1].from).toBe("numbers")
67+
});
68+
})
69+
70+
});
71+
872
});
973

10-
describe("given code without names in importable modules", () => {
11-
const code = `
12-
function add(x, y) {
13-
return x + y + magicNumber
14-
}
15-
`;
74+
});
75+
76+
describe("ImportableModule", () => {
77+
78+
describe("generateImportStatement()", () => {
79+
const module = new ImportableModule("test-module", ["TypeA", "TypeB", "helper"]);
80+
81+
it("finds no members for empty code", () => {
82+
const statement = module.generateImportStatement("");
83+
expect(statement.members).toEqual([]);
84+
expect(statement.from).toBe("test-module");
85+
});
86+
87+
it("finds no members for code with names containing members", () => {
88+
// Should NOT match partial names like "TypeAbc" or "myhelper"
89+
const code = "TypeAbc myhelper";
90+
const statement = module.generateImportStatement(code);
91+
expect(statement.members).toEqual([]);
92+
});
93+
94+
it.each([" TypeA ", "(TypeA)", "{TypeA}", "<TypeA>", "'TypeA'", '"TypeA"', " TypeA.foo", " TypeA:"])(
95+
"matches member TypeA in code `%s`", (code) => {
96+
const statement = module.generateImportStatement(code);
97+
expect(statement.members).toContain("TypeA");
98+
});
99+
});
100+
});
101+
102+
describe("ImportStatement", () => {
16103

17-
it("produces no import statements", () => {
18-
const imports = generateImports(myModules, code);
19-
expect(imports).toHaveLength(0);
104+
describe("type property", () => {
105+
106+
it("returns 'none' for statement with no members", () => {
107+
const statement = new ImportStatement("test-module", []);
108+
expect(statement.type).toBe("none");
109+
});
110+
111+
it("returns 'single' for statement with 1 member", () => {
112+
const statement = new ImportStatement("test-module", ["TypeA"]);
113+
expect(statement.type).toBe("single");
20114
});
21-
})
22115

116+
it("returns 'multiple' for statement with multiple members", () => {
117+
const statement = new ImportStatement("test-module", ["TypeA", "TypeB"]);
118+
expect(statement.type).toBe("multiple");
119+
});
120+
});
121+
122+
describe("toString() formats string properly", () => {
123+
124+
it("for statement with 1 member", () => {
125+
const statement = new ImportStatement("test-module", ["TypeA"]);
126+
expect(statement.toString()).toBe('import { TypeA } from "test-module";');
127+
});
128+
129+
it("for statement with multiple members", () => {
130+
const statement = new ImportStatement("test-module", ["TypeA", "TypeB", "helper"]);
131+
expect(statement.toString()).toBe('import { TypeA, TypeB, helper } from "test-module";');
132+
});
133+
});
23134
});

0 commit comments

Comments
 (0)