|
| 1 | +import { dartQuery } from "../queries" |
| 2 | +import { testParseSourceCodeDefinitions } from "./helpers" |
| 3 | +import sampleDartContent from "./fixtures/sample-dart" |
| 4 | + |
| 5 | +const dartOptions = { |
| 6 | + language: "dart", |
| 7 | + wasmFile: "tree-sitter-dart.wasm", |
| 8 | + queryString: dartQuery, |
| 9 | + extKey: "dart", |
| 10 | +} |
| 11 | + |
| 12 | +describe("parseSourceCodeDefinitionsForFile with Dart", () => { |
| 13 | + it("captures a redirecting factory constructor", async () => { |
| 14 | + const content = `class Logger { |
| 15 | + factory Logger() = ConsoleLogger; |
| 16 | + } |
| 17 | +
|
| 18 | + class ConsoleLogger implements Logger {}` |
| 19 | + |
| 20 | + const result = await testParseSourceCodeDefinitions("/test/file.dart", content, dartOptions) |
| 21 | + |
| 22 | + expect(result).toMatch(/\d+--\d+ \|\s*factory Logger\(\) = ConsoleLogger/) |
| 23 | + }) |
| 24 | + |
| 25 | + it("captures a multiline generative constructor once", async () => { |
| 26 | + const content = `class Point { |
| 27 | + Point.fromCoordinates( |
| 28 | + int x, |
| 29 | + int y, |
| 30 | + ); |
| 31 | + }` |
| 32 | + |
| 33 | + const result = await testParseSourceCodeDefinitions("/test/file.dart", content, dartOptions) |
| 34 | + |
| 35 | + expect(result?.match(/\d+--\d+ \|\s*Point\.fromCoordinates\(/g)).toHaveLength(1) |
| 36 | + }) |
| 37 | + |
| 38 | + it("captures a mixin application class", async () => { |
| 39 | + const content = `class Base {} |
| 40 | + mixin Serializable {} |
| 41 | + class SerializableBase = Base with Serializable;` |
| 42 | + |
| 43 | + const result = await testParseSourceCodeDefinitions("/test/file.dart", content, dartOptions) |
| 44 | + |
| 45 | + expect(result).toMatch(/\d+--\d+ \|\s*class SerializableBase = Base with Serializable/) |
| 46 | + }) |
| 47 | + |
| 48 | + it("captures external top-level functions and methods", async () => { |
| 49 | + const content = `external int nativeVersion(); |
| 50 | +
|
| 51 | + class NativeApi { |
| 52 | + external String platformName(); |
| 53 | + }` |
| 54 | + |
| 55 | + const result = await testParseSourceCodeDefinitions("/test/file.dart", content, dartOptions) |
| 56 | + |
| 57 | + expect(result).toMatch(/\d+--\d+ \| external int nativeVersion\(\)/) |
| 58 | + expect(result).toMatch(/\d+--\d+ \|\s*external String platformName\(\)/) |
| 59 | + }) |
| 60 | + |
| 61 | + it("does not report local functions as file-level definitions", async () => { |
| 62 | + const content = `void outer() { |
| 63 | + int inner() => 1; |
| 64 | + print(inner()); |
| 65 | + }` |
| 66 | + |
| 67 | + const result = await testParseSourceCodeDefinitions("/test/file.dart", content, dartOptions) |
| 68 | + |
| 69 | + expect(result).toMatch(/\d+--\d+ \| void outer\(\)/) |
| 70 | + expect(result).not.toMatch(/int inner\(\)/) |
| 71 | + }) |
| 72 | + |
| 73 | + it("includes a multiline top-level function body without duplicating its declaration", async () => { |
| 74 | + const content = `int add(int left, int right) { |
| 75 | + final result = left + right; |
| 76 | + return result; |
| 77 | + }` |
| 78 | + |
| 79 | + const result = await testParseSourceCodeDefinitions("/test/file.dart", content, dartOptions) |
| 80 | + const addDefinitions = result?.split("\n").filter((line) => line.includes("int add(")) ?? [] |
| 81 | + |
| 82 | + expect(addDefinitions).toEqual(["1--4 | int add(int left, int right) {"]) |
| 83 | + }) |
| 84 | + |
| 85 | + it("should capture common Dart declarations", async () => { |
| 86 | + const result = await testParseSourceCodeDefinitions("/test/file.dart", sampleDartContent, dartOptions) |
| 87 | + const definitionLines = result?.split("\n").filter((line) => line.includes(" | ")) ?? [] |
| 88 | + |
| 89 | + expect(result).toMatch(/\d+--\d+ \| abstract class Animal/) |
| 90 | + expect(result).toMatch(/\d+--\d+ \|\s*Future<String> describe/) |
| 91 | + expect(result).toMatch(/\d+--\d+ \| class Point/) |
| 92 | + expect(result).toMatch(/\d+--\d+ \|\s*const Point\(\)/) |
| 93 | + expect(result).toMatch(/\d+--\d+ \|\s*Point\.named\(\)/) |
| 94 | + expect(result).toMatch(/\d+--\d+ \|\s*factory Point\.origin\(\)/) |
| 95 | + expect(result).toMatch(/\d+--\d+ \|\s*Point\.fromCoordinates\(/) |
| 96 | + expect(result).toMatch(/\d+--\d+ \|\s*factory Point\.fromRecord\(/) |
| 97 | + expect(result?.match(/\d+--\d+ \| Point\.fromCoordinates\(/g)).toHaveLength(1) |
| 98 | + expect(result?.match(/\d+--\d+ \| factory Point\.fromRecord\(/g)).toHaveLength(1) |
| 99 | + expect(result).toMatch(/\d+--\d+ \|\s*int get x/) |
| 100 | + expect(result).toMatch(/\d+--\d+ \|\s*set x\(int value\)/) |
| 101 | + expect(result).toMatch(/\d+--\d+ \|\s*Point operator \+/) |
| 102 | + expect(result).toMatch(/\d+--\d+ \|\s*Point operator \[]/) |
| 103 | + expect(result).toMatch(/\d+--\d+ \|\s*static List<T> emptyList/) |
| 104 | + expect(result).toMatch(/\d+--\d+ \| mixin Runner/) |
| 105 | + expect(result).toMatch(/\d+--\d+ \| enum Status/) |
| 106 | + expect(result).toMatch(/\d+--\d+ \|\s*const Status\(\)/) |
| 107 | + expect(result).toMatch(/\d+--\d+ \| class Dog extends Animal with Runner/) |
| 108 | + expect(result).toMatch(/\d+--\d+ \| extension StringTools on String/) |
| 109 | + expect(result).toMatch(/\d+--\d+ \| extension on int/) |
| 110 | + expect(result).toMatch(/\d+--\d+ \| extension type UserId/) |
| 111 | + expect(result).toMatch(/\d+--\d+ \| typedef Operation/) |
| 112 | + expect(result).toMatch(/\d+--\d+ \| typedef AsyncOperation/) |
| 113 | + expect(result).toMatch(/\d+--\d+ \| int get answer/) |
| 114 | + expect(result).toMatch(/\d+--\d+ \| set answer\(int value\)/) |
| 115 | + expect(result).toMatch(/\d+--\d+ \|\s*String speak\(\)/) |
| 116 | + expect(result).toMatch(/\d+--\d+ \| int add\(int left, int right\)/) |
| 117 | + expect(result).toMatch(/\d+--\d+ \| Future<T> retry<T extends Object>/) |
| 118 | + expect(result).toMatch(/\d+--\d+ \| Future<void> initialize\(\) async/) |
| 119 | + expect(result).toMatch(/\d+--\d+ \| Iterable<int> countUpTo\(int maximum\) sync\*/) |
| 120 | + expect(result).toMatch(/\d+--\d+ \| Stream<int> countPeriodically\(int maximum\) async\*/) |
| 121 | + expect(definitionLines).toHaveLength(37) |
| 122 | + }) |
| 123 | +}) |
0 commit comments