forked from continuedev/continue
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
1,182 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
// Generated by continue | ||
|
||
import { findInAst } from "./findInAst"; | ||
import Parser from "web-tree-sitter"; | ||
|
||
describe("findInAst", () => { | ||
it("should find a node matching the criterion", () => { | ||
const mockAst = createMockSyntaxNode("root", [ | ||
createMockSyntaxNode("child1", []), | ||
createMockSyntaxNode("function", [createMockSyntaxNode("child2", [])]), | ||
]); | ||
|
||
const criterion = (node: Parser.SyntaxNode) => node.type === "function"; | ||
|
||
const result = findInAst(mockAst, criterion); | ||
|
||
expect(result).not.toBeNull(); | ||
expect(result!.type).toBe("function"); | ||
}); | ||
|
||
it("should return null if no node matches the criterion", () => { | ||
const mockAst = createMockSyntaxNode("root", [ | ||
createMockSyntaxNode("child1", []), | ||
createMockSyntaxNode("child2", []), | ||
]); | ||
|
||
const criterion = (node: Parser.SyntaxNode) => node.type === "function"; | ||
|
||
const result = findInAst(mockAst, criterion); | ||
|
||
expect(result).toBeNull(); | ||
}); | ||
|
||
it("should find a nested node matching the criterion", () => { | ||
const mockAst = createMockSyntaxNode("root", [ | ||
createMockSyntaxNode("child1", [ | ||
createMockSyntaxNode("child2", [createMockSyntaxNode("function", [])]), | ||
]), | ||
createMockSyntaxNode("child3", []), | ||
]); | ||
|
||
const criterion = (node: Parser.SyntaxNode) => node.type === "function"; | ||
|
||
const result = findInAst(mockAst, criterion); | ||
|
||
expect(result).not.toBeNull(); | ||
expect(result!.type).toBe("function"); | ||
}); | ||
|
||
it("should return the first node matching the criterion in depth-first traversal", () => { | ||
const firstFunctionNode = createMockSyntaxNode("function", []); | ||
const secondFunctionNode = createMockSyntaxNode("function", []); | ||
const mockAst = createMockSyntaxNode("root", [ | ||
firstFunctionNode, // First function node | ||
createMockSyntaxNode("child1", [ | ||
secondFunctionNode, // Second function node | ||
]), | ||
]); | ||
|
||
const criterion = (node: Parser.SyntaxNode) => node.type === "function"; | ||
|
||
const result = findInAst(mockAst, criterion); | ||
|
||
expect(result).not.toBeNull(); | ||
expect(result!.type).toBe("function"); | ||
expect(JSON.stringify(result)).toBe(JSON.stringify(firstFunctionNode)); // Ensure it's the first function node | ||
}); | ||
|
||
it("should return the root node if it matches the criterion", () => { | ||
const mockAst = createMockSyntaxNode("function", [ | ||
createMockSyntaxNode("child1", []), | ||
createMockSyntaxNode("child2", []), | ||
]); | ||
|
||
const criterion = (node: Parser.SyntaxNode) => node.type === "function"; | ||
|
||
const result = findInAst(mockAst, criterion); | ||
|
||
expect(result).not.toBeNull(); | ||
expect(result!.type).toBe("function"); | ||
expect(result).toBe(mockAst); | ||
}); | ||
|
||
it("should return null when searching an empty tree", () => { | ||
const mockAst = createMockSyntaxNode("root", []); | ||
|
||
const criterion = (node: Parser.SyntaxNode) => node.type === "function"; | ||
|
||
const result = findInAst(mockAst, criterion); | ||
|
||
expect(result).toBeNull(); | ||
}); | ||
}); | ||
|
||
function createMockSyntaxNode( | ||
type: string, | ||
children: Parser.SyntaxNode[], | ||
): Parser.SyntaxNode { | ||
// Define minimal properties of SyntaxNode required for the test | ||
const node: Partial<Parser.SyntaxNode> = { | ||
type, | ||
children, | ||
childCount: children.length, | ||
child: (index: number) => { | ||
return children[index] || null; | ||
}, | ||
}; | ||
return node as Parser.SyntaxNode; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
// Generated by continue | ||
// core/indexing/chunk/basic.test.ts | ||
|
||
import { basicChunker } from "./basic.js"; | ||
import { countTokensAsync } from "../../llm/countTokens"; | ||
import { ChunkWithoutID } from "../../index"; | ||
|
||
// jest.mock("../../llm/countTokens", () => ({ | ||
// countTokensAsync: jest.fn(), | ||
// })); | ||
|
||
describe.skip("basicChunker", () => { | ||
beforeEach(() => { | ||
jest.resetAllMocks(); | ||
}); | ||
|
||
it("should yield no chunks for empty content", async () => { | ||
const contents = ""; | ||
const maxChunkSize = 10; | ||
const chunks: ChunkWithoutID[] = []; | ||
|
||
for await (const chunk of basicChunker(contents, maxChunkSize)) { | ||
chunks.push(chunk); | ||
} | ||
|
||
expect(chunks).toHaveLength(0); | ||
}); | ||
|
||
it("should yield a single chunk if whole content fits within the max size", async () => { | ||
(countTokensAsync as jest.Mock).mockResolvedValue(1); | ||
const contents = "line1\nline2\nline3"; | ||
const maxChunkSize = 10; | ||
const expectedChunks: ChunkWithoutID[] = [ | ||
{ content: "line1\nline2\nline3\n", startLine: 0, endLine: 2 }, | ||
]; | ||
|
||
const chunks: ChunkWithoutID[] = []; | ||
for await (const chunk of basicChunker(contents, maxChunkSize)) { | ||
chunks.push(chunk); | ||
} | ||
|
||
expect(chunks).toEqual(expectedChunks); | ||
}); | ||
|
||
it("should yield multiple chunks when content exceeds the max size", async () => { | ||
(countTokensAsync as jest.Mock).mockImplementation(async (line: string) => { | ||
if (line === "line3") return 5; | ||
return 3; // Mock returning 3 tokens per line except for "line3" | ||
}); | ||
|
||
const contents = "line1\nline2\nline3\nline4\nline5"; | ||
const maxChunkSize = 8; | ||
const expectedChunks: ChunkWithoutID[] = [ | ||
{ content: "line1\nline2\n", startLine: 0, endLine: 1 }, | ||
{ content: "line3\n", startLine: 2, endLine: 2 }, | ||
{ content: "line4\nline5\n", startLine: 3, endLine: 4 }, | ||
]; | ||
|
||
const chunks: ChunkWithoutID[] = []; | ||
for await (const chunk of basicChunker(contents, maxChunkSize)) { | ||
chunks.push(chunk); | ||
} | ||
|
||
expect(chunks).toEqual(expectedChunks); | ||
}); | ||
|
||
it("should skip lines that exceed the max chunk size", async () => { | ||
(countTokensAsync as jest.Mock).mockImplementation(async (line: string) => { | ||
if (line === "line3") return 15; // Making it explicitly exceed max size | ||
return 3; | ||
}); | ||
|
||
const contents = "line1\nline2\nline3\nline4\nline5"; | ||
const maxChunkSize = 8; | ||
const expectedChunks: ChunkWithoutID[] = [ | ||
{ content: "line1\nline2\n", startLine: 0, endLine: 1 }, | ||
{ content: "line4\nline5\n", startLine: 3, endLine: 4 }, | ||
]; | ||
|
||
const chunks: ChunkWithoutID[] = []; | ||
for await (const chunk of basicChunker(contents, maxChunkSize)) { | ||
chunks.push(chunk); | ||
} | ||
|
||
expect(chunks).toEqual(expectedChunks); | ||
}); | ||
}); |
Oops, something went wrong.