mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-09-19 00:03:33 +00:00
test: overloaded method disambiguation integration tests for 5 languages
Add comprehensive integration tests verifying that overloaded methods with different arities produce distinct graph nodes and correct METHOD_IMPLEMENTS edges. Each fixture uses different parameter counts (1 vs 2) to exercise the #<paramCount> arity suffix. Languages covered: - Java: 7 tests (distinct nodes, 3 METHOD_IMPLEMENTS edges, 2 CALLS edges) - C#: 5 tests (distinct Find nodes, 3 METHOD_IMPLEMENTS edges) - Kotlin: 4 tests (distinct find nodes, 3 METHOD_IMPLEMENTS edges) - TypeScript: 3 tests (TS overloads collapse to 1 impl — expects 2 edges) - Swift: 4 tests (skipped when parser unavailable) All assertions use strict toBe() — no toBeGreaterThanOrEqual.
This commit is contained in:
parent
3c5079f044
commit
afa4e81a5f
20 changed files with 437 additions and 0 deletions
8
gitnexus/test/fixtures/lang-resolution/csharp-overload-dispatch/App.cs
vendored
Normal file
8
gitnexus/test/fixtures/lang-resolution/csharp-overload-dispatch/App.cs
vendored
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
public class App {
|
||||
public void Run() {
|
||||
var repo = new SqlRepository();
|
||||
repo.Find(42);
|
||||
repo.Find("alice", true);
|
||||
repo.Save("test");
|
||||
}
|
||||
}
|
||||
5
gitnexus/test/fixtures/lang-resolution/csharp-overload-dispatch/IRepository.cs
vendored
Normal file
5
gitnexus/test/fixtures/lang-resolution/csharp-overload-dispatch/IRepository.cs
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
public interface IRepository {
|
||||
string Find(int id);
|
||||
string Find(string name, bool exact);
|
||||
void Save(string data);
|
||||
}
|
||||
11
gitnexus/test/fixtures/lang-resolution/csharp-overload-dispatch/SqlRepository.cs
vendored
Normal file
11
gitnexus/test/fixtures/lang-resolution/csharp-overload-dispatch/SqlRepository.cs
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
public class SqlRepository : IRepository {
|
||||
public string Find(int id) {
|
||||
return "found-by-id";
|
||||
}
|
||||
public string Find(string name, bool exact) {
|
||||
return "found-by-name";
|
||||
}
|
||||
public void Save(string data) {
|
||||
Console.WriteLine(data);
|
||||
}
|
||||
}
|
||||
8
gitnexus/test/fixtures/lang-resolution/java-overload-dispatch/App.java
vendored
Normal file
8
gitnexus/test/fixtures/lang-resolution/java-overload-dispatch/App.java
vendored
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
public class App {
|
||||
public void run() {
|
||||
SqlRepository repo = new SqlRepository();
|
||||
repo.find(42);
|
||||
repo.find("alice", true);
|
||||
repo.save("test");
|
||||
}
|
||||
}
|
||||
5
gitnexus/test/fixtures/lang-resolution/java-overload-dispatch/Repository.java
vendored
Normal file
5
gitnexus/test/fixtures/lang-resolution/java-overload-dispatch/Repository.java
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
public interface Repository {
|
||||
String find(int id);
|
||||
String find(String name, boolean exact);
|
||||
void save(String data);
|
||||
}
|
||||
13
gitnexus/test/fixtures/lang-resolution/java-overload-dispatch/SqlRepository.java
vendored
Normal file
13
gitnexus/test/fixtures/lang-resolution/java-overload-dispatch/SqlRepository.java
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
public class SqlRepository implements Repository {
|
||||
public String find(int id) {
|
||||
return "found-by-id";
|
||||
}
|
||||
|
||||
public String find(String name, boolean exact) {
|
||||
return "found-by-name";
|
||||
}
|
||||
|
||||
public void save(String data) {
|
||||
System.out.println(data);
|
||||
}
|
||||
}
|
||||
6
gitnexus/test/fixtures/lang-resolution/kotlin-overload-dispatch/App.kt
vendored
Normal file
6
gitnexus/test/fixtures/lang-resolution/kotlin-overload-dispatch/App.kt
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
fun main() {
|
||||
val repo = SqlRepository()
|
||||
repo.find(42)
|
||||
repo.find("alice", true)
|
||||
repo.save("test")
|
||||
}
|
||||
5
gitnexus/test/fixtures/lang-resolution/kotlin-overload-dispatch/Repository.kt
vendored
Normal file
5
gitnexus/test/fixtures/lang-resolution/kotlin-overload-dispatch/Repository.kt
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
interface Repository {
|
||||
fun find(id: Int): String
|
||||
fun find(name: String, exact: Boolean): String
|
||||
fun save(data: String)
|
||||
}
|
||||
5
gitnexus/test/fixtures/lang-resolution/kotlin-overload-dispatch/SqlRepository.kt
vendored
Normal file
5
gitnexus/test/fixtures/lang-resolution/kotlin-overload-dispatch/SqlRepository.kt
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
class SqlRepository : Repository {
|
||||
override fun find(id: Int): String = "found-by-id"
|
||||
override fun find(name: String, exact: Boolean): String = "found-by-name"
|
||||
override fun save(data: String) { println(data) }
|
||||
}
|
||||
4
gitnexus/test/fixtures/lang-resolution/swift-overload-dispatch/App.swift
vendored
Normal file
4
gitnexus/test/fixtures/lang-resolution/swift-overload-dispatch/App.swift
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
let repo = SqlRepository()
|
||||
repo.find(id: 42)
|
||||
repo.find(name: "alice", exact: true)
|
||||
repo.save(data: "test")
|
||||
5
gitnexus/test/fixtures/lang-resolution/swift-overload-dispatch/Repository.swift
vendored
Normal file
5
gitnexus/test/fixtures/lang-resolution/swift-overload-dispatch/Repository.swift
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
protocol Repository {
|
||||
func find(id: Int) -> String
|
||||
func find(name: String, exact: Bool) -> String
|
||||
func save(data: String)
|
||||
}
|
||||
5
gitnexus/test/fixtures/lang-resolution/swift-overload-dispatch/SqlRepository.swift
vendored
Normal file
5
gitnexus/test/fixtures/lang-resolution/swift-overload-dispatch/SqlRepository.swift
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
class SqlRepository: Repository {
|
||||
func find(id: Int) -> String { return "found-by-id" }
|
||||
func find(name: String, exact: Bool) -> String { return "found-by-name" }
|
||||
func save(data: String) { print(data) }
|
||||
}
|
||||
6
gitnexus/test/fixtures/lang-resolution/ts-overload-dispatch/app.ts
vendored
Normal file
6
gitnexus/test/fixtures/lang-resolution/ts-overload-dispatch/app.ts
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
import { SqlRepository } from './sql-repository';
|
||||
|
||||
const repo = new SqlRepository();
|
||||
repo.find(42);
|
||||
repo.find('alice');
|
||||
repo.save('test');
|
||||
5
gitnexus/test/fixtures/lang-resolution/ts-overload-dispatch/repository.ts
vendored
Normal file
5
gitnexus/test/fixtures/lang-resolution/ts-overload-dispatch/repository.ts
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
export interface IRepository {
|
||||
find(id: number): string;
|
||||
find(name: string): string;
|
||||
save(data: string): void;
|
||||
}
|
||||
12
gitnexus/test/fixtures/lang-resolution/ts-overload-dispatch/sql-repository.ts
vendored
Normal file
12
gitnexus/test/fixtures/lang-resolution/ts-overload-dispatch/sql-repository.ts
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
import { IRepository } from './repository';
|
||||
|
||||
export class SqlRepository implements IRepository {
|
||||
find(id: number): string;
|
||||
find(name: string): string;
|
||||
find(arg: number | string): string {
|
||||
return typeof arg === 'number' ? 'found-by-id' : 'found-by-name';
|
||||
}
|
||||
save(data: string): void {
|
||||
console.log(data);
|
||||
}
|
||||
}
|
||||
|
|
@ -1767,3 +1767,64 @@ describe('C# interface dispatch (METHOD_IMPLEMENTS)', () => {
|
|||
expect(saveEdge).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Overloaded method disambiguation: METHOD_IMPLEMENTS with overloads
|
||||
// IRepository declares Find(int), Find(string), Save(string).
|
||||
// SqlRepository implements all three.
|
||||
// Overloaded methods (same name, different params) collapse into a single
|
||||
// graph node (generateId drops startLine), so Find appears once per file.
|
||||
// METHOD_IMPLEMENTS still emits one edge per unique (source, target) pair.
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
describe('C# overloaded method disambiguation (METHOD_IMPLEMENTS)', () => {
|
||||
let result: PipelineResult;
|
||||
|
||||
beforeAll(async () => {
|
||||
result = await runPipelineFromRepo(path.join(FIXTURES, 'csharp-overload-dispatch'), () => {});
|
||||
}, 60000);
|
||||
|
||||
it('detects 2 distinct Find Method nodes on SqlRepository (different arities)', () => {
|
||||
const methods = getNodesByLabelFull(result, 'Method');
|
||||
const findOnSql = methods.filter(
|
||||
(m) => m.name === 'Find' && m.properties.filePath?.includes('SqlRepository'),
|
||||
);
|
||||
expect(findOnSql.length).toBe(2);
|
||||
});
|
||||
|
||||
it('emits METHOD_IMPLEMENTS edges for both Find overloads', () => {
|
||||
const mi = getRelationships(result, 'METHOD_IMPLEMENTS');
|
||||
const findEdges = mi.filter(
|
||||
(e) =>
|
||||
e.source === 'Find' &&
|
||||
e.target === 'Find' &&
|
||||
e.sourceFilePath.includes('SqlRepository') &&
|
||||
e.targetFilePath.includes('IRepository'),
|
||||
);
|
||||
expect(findEdges.length).toBe(2);
|
||||
});
|
||||
|
||||
it('emits METHOD_IMPLEMENTS for Save -> IRepository.Save', () => {
|
||||
const mi = getRelationships(result, 'METHOD_IMPLEMENTS');
|
||||
const saveEdge = mi.find(
|
||||
(e) =>
|
||||
e.source === 'Save' &&
|
||||
e.target === 'Save' &&
|
||||
e.sourceFilePath.includes('SqlRepository') &&
|
||||
e.targetFilePath.includes('IRepository'),
|
||||
);
|
||||
expect(saveEdge).toBeDefined();
|
||||
});
|
||||
|
||||
it('emits exactly 3 METHOD_IMPLEMENTS edges', () => {
|
||||
const mi = getRelationships(result, 'METHOD_IMPLEMENTS');
|
||||
expect(mi.length).toBe(3);
|
||||
});
|
||||
|
||||
it('detects SqlRepository class and IRepository interface', () => {
|
||||
const classes = getNodesByLabel(result, 'Class');
|
||||
const ifaces = getNodesByLabel(result, 'Interface');
|
||||
expect(classes).toContain('SqlRepository');
|
||||
expect(ifaces).toContain('IRepository');
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1701,3 +1701,115 @@ describe('Java interface dispatch (METHOD_IMPLEMENTS)', () => {
|
|||
expect(sourceFiles.some((f) => f.includes('SendEmail'))).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Java overloaded method disambiguation (METHOD_IMPLEMENTS with arity)
|
||||
// Repository interface: find(int), find(String, boolean), save(String)
|
||||
// SqlRepository implements Repository with matching overloads
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
describe('Java overloaded method disambiguation (METHOD_IMPLEMENTS)', () => {
|
||||
let result: PipelineResult;
|
||||
|
||||
beforeAll(async () => {
|
||||
result = await runPipelineFromRepo(path.join(FIXTURES, 'java-overload-dispatch'), () => {});
|
||||
}, 60000);
|
||||
|
||||
it('detects distinct Method nodes for overloaded find methods on SqlRepository', () => {
|
||||
const methods = getNodesByLabelFull(result, 'Method');
|
||||
const findMethods = methods.filter(
|
||||
(m) => m.name === 'find' && m.properties.filePath?.includes('SqlRepository'),
|
||||
);
|
||||
expect(findMethods.length).toBe(2);
|
||||
const paramCounts = findMethods.map((m) => m.properties.parameterCount).sort();
|
||||
expect(paramCounts).toEqual([1, 2]);
|
||||
});
|
||||
|
||||
it('detects distinct Method nodes for overloaded find methods on Repository interface', () => {
|
||||
const methods = getNodesByLabelFull(result, 'Method');
|
||||
const findMethods = methods.filter(
|
||||
(m) =>
|
||||
m.name === 'find' &&
|
||||
m.properties.filePath?.includes('Repository') &&
|
||||
!m.properties.filePath?.includes('SqlRepository'),
|
||||
);
|
||||
expect(findMethods.length).toBe(2);
|
||||
const paramCounts = findMethods.map((m) => m.properties.parameterCount).sort();
|
||||
expect(paramCounts).toEqual([1, 2]);
|
||||
});
|
||||
|
||||
it('emits METHOD_IMPLEMENTS for find(int) → Repository.find(int)', () => {
|
||||
const mi = getRelationships(result, 'METHOD_IMPLEMENTS');
|
||||
const edge = mi.find(
|
||||
(e) =>
|
||||
e.source === 'find' &&
|
||||
e.target === 'find' &&
|
||||
e.sourceFilePath.includes('SqlRepository') &&
|
||||
e.targetFilePath.includes('Repository'),
|
||||
);
|
||||
expect(edge).toBeDefined();
|
||||
// Verify at least one find→find edge has arity 1 on source side
|
||||
const findEdges = mi.filter(
|
||||
(e) =>
|
||||
e.source === 'find' &&
|
||||
e.target === 'find' &&
|
||||
e.sourceFilePath.includes('SqlRepository') &&
|
||||
e.targetFilePath.includes('Repository'),
|
||||
);
|
||||
const sourceNodes = findEdges.map((e) => {
|
||||
const methods = getNodesByLabelFull(result, 'Method');
|
||||
return methods.find(
|
||||
(m) =>
|
||||
m.name === 'find' &&
|
||||
m.properties.filePath?.includes('SqlRepository') &&
|
||||
m.properties.parameterCount === 1,
|
||||
);
|
||||
});
|
||||
expect(sourceNodes.some((n) => n !== undefined)).toBe(true);
|
||||
});
|
||||
|
||||
it('emits METHOD_IMPLEMENTS for find(String, boolean) → Repository.find(String, boolean)', () => {
|
||||
const mi = getRelationships(result, 'METHOD_IMPLEMENTS');
|
||||
const findEdges = mi.filter(
|
||||
(e) =>
|
||||
e.source === 'find' &&
|
||||
e.target === 'find' &&
|
||||
e.sourceFilePath.includes('SqlRepository') &&
|
||||
e.targetFilePath.includes('Repository'),
|
||||
);
|
||||
// There should be two find→find edges (one per overload)
|
||||
expect(findEdges.length).toBe(2);
|
||||
});
|
||||
|
||||
it('emits METHOD_IMPLEMENTS for save(String) → Repository.save(String)', () => {
|
||||
const mi = getRelationships(result, 'METHOD_IMPLEMENTS');
|
||||
const edge = mi.find(
|
||||
(e) =>
|
||||
e.source === 'save' &&
|
||||
e.target === 'save' &&
|
||||
e.sourceFilePath.includes('SqlRepository') &&
|
||||
e.targetFilePath.includes('Repository'),
|
||||
);
|
||||
expect(edge).toBeDefined();
|
||||
});
|
||||
|
||||
it('emits exactly 3 METHOD_IMPLEMENTS edges', () => {
|
||||
const mi = getRelationships(result, 'METHOD_IMPLEMENTS');
|
||||
const edges = mi.filter(
|
||||
(e) => e.sourceFilePath.includes('SqlRepository') && e.targetFilePath.includes('Repository'),
|
||||
);
|
||||
expect(edges.length).toBe(3);
|
||||
});
|
||||
|
||||
it('emits CALLS edges from run() to both find overloads', () => {
|
||||
const calls = getRelationships(result, 'CALLS');
|
||||
const findCalls = calls.filter(
|
||||
(c) =>
|
||||
c.source === 'run' &&
|
||||
c.target === 'find' &&
|
||||
c.sourceFilePath.includes('App') &&
|
||||
c.targetFilePath.includes('SqlRepository'),
|
||||
);
|
||||
expect(findCalls.length).toBe(2);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1857,3 +1857,54 @@ describe('Kotlin interface dispatch (METHOD_IMPLEMENTS)', () => {
|
|||
expect(saveEdge).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Overloaded method disambiguation: interface with overloaded find + save,
|
||||
// concrete class implements all three. Verifies METHOD_IMPLEMENTS edges
|
||||
// correctly distinguish between overloaded signatures.
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
describe('Kotlin overloaded method disambiguation', () => {
|
||||
let result: PipelineResult;
|
||||
|
||||
beforeAll(async () => {
|
||||
result = await runPipelineFromRepo(path.join(FIXTURES, 'kotlin-overload-dispatch'), () => {});
|
||||
}, 60000);
|
||||
|
||||
it('detects 2 distinct find Method nodes on SqlRepository', () => {
|
||||
const methods = getNodesByLabelFull(result, 'Method');
|
||||
const sqlRepoFinds = methods.filter(
|
||||
(m) => m.name === 'find' && m.properties.filePath?.includes('SqlRepository'),
|
||||
);
|
||||
expect(sqlRepoFinds.length).toBe(2);
|
||||
});
|
||||
|
||||
it('emits METHOD_IMPLEMENTS edges for both find overloads', () => {
|
||||
const mi = getRelationships(result, 'METHOD_IMPLEMENTS');
|
||||
const findEdges = mi.filter(
|
||||
(e) =>
|
||||
e.source === 'find' &&
|
||||
e.target === 'find' &&
|
||||
e.sourceFilePath.includes('SqlRepository') &&
|
||||
e.targetFilePath.includes('Repository'),
|
||||
);
|
||||
expect(findEdges.length).toBe(2);
|
||||
});
|
||||
|
||||
it('emits METHOD_IMPLEMENTS edge for save', () => {
|
||||
const mi = getRelationships(result, 'METHOD_IMPLEMENTS');
|
||||
const saveEdge = mi.find(
|
||||
(e) =>
|
||||
e.source === 'save' &&
|
||||
e.target === 'save' &&
|
||||
e.sourceFilePath.includes('SqlRepository') &&
|
||||
e.targetFilePath.includes('Repository'),
|
||||
);
|
||||
expect(saveEdge).toBeDefined();
|
||||
});
|
||||
|
||||
it('emits exactly 3 METHOD_IMPLEMENTS edges total', () => {
|
||||
const mi = getRelationships(result, 'METHOD_IMPLEMENTS');
|
||||
expect(mi.length).toBe(3);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -808,3 +808,60 @@ describe.skipIf(!swiftAvailable)('Swift abstract dispatch', () => {
|
|||
expect(names).toEqual(['find', 'save']);
|
||||
});
|
||||
});
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Overloaded method disambiguation: protocol with overloaded find + save,
|
||||
// concrete class implements all three. Verifies METHOD_IMPLEMENTS edges
|
||||
// correctly distinguish between overloaded signatures.
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
describe.skipIf(!swiftAvailable)('Swift overloaded method disambiguation', () => {
|
||||
let result: PipelineResult;
|
||||
|
||||
beforeAll(async () => {
|
||||
result = await runPipelineFromRepo(path.join(FIXTURES, 'swift-overload-dispatch'), () => {});
|
||||
}, 60000);
|
||||
|
||||
it('detects 2 distinct find Method nodes on SqlRepository', () => {
|
||||
const methods = getNodesByLabelFull(result, 'Method');
|
||||
const sqlRepoFinds = methods.filter(
|
||||
(m) => m.name === 'find' && m.properties.filePath?.includes('SqlRepository'),
|
||||
);
|
||||
// Swift class methods may be emitted as Function nodes
|
||||
const functions = getNodesByLabelFull(result, 'Function');
|
||||
const sqlRepoFindFns = functions.filter(
|
||||
(m) => m.name === 'find' && m.properties.filePath?.includes('SqlRepository'),
|
||||
);
|
||||
const totalFinds = sqlRepoFinds.length + sqlRepoFindFns.length;
|
||||
expect(totalFinds).toBe(2);
|
||||
});
|
||||
|
||||
it('emits METHOD_IMPLEMENTS edges for both find overloads', () => {
|
||||
const mi = getRelationships(result, 'METHOD_IMPLEMENTS');
|
||||
const findEdges = mi.filter(
|
||||
(e) =>
|
||||
e.source === 'find' &&
|
||||
e.target === 'find' &&
|
||||
e.sourceFilePath.includes('SqlRepository') &&
|
||||
e.targetFilePath.includes('Repository'),
|
||||
);
|
||||
expect(findEdges.length).toBe(2);
|
||||
});
|
||||
|
||||
it('emits METHOD_IMPLEMENTS edge for save', () => {
|
||||
const mi = getRelationships(result, 'METHOD_IMPLEMENTS');
|
||||
const saveEdge = mi.find(
|
||||
(e) =>
|
||||
e.source === 'save' &&
|
||||
e.target === 'save' &&
|
||||
e.sourceFilePath.includes('SqlRepository') &&
|
||||
e.targetFilePath.includes('Repository'),
|
||||
);
|
||||
expect(saveEdge).toBeDefined();
|
||||
});
|
||||
|
||||
it('emits exactly 3 METHOD_IMPLEMENTS edges total', () => {
|
||||
const mi = getRelationships(result, 'METHOD_IMPLEMENTS');
|
||||
expect(mi.length).toBe(3);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2443,3 +2443,56 @@ describe('TypeScript interface dispatch (METHOD_IMPLEMENTS)', () => {
|
|||
expect(saveEdge).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Overloaded method disambiguation: interface with overloaded find + save,
|
||||
// concrete class implements all three. TypeScript overloads collapse to one
|
||||
// implementation signature — expect the implementation body, not individual
|
||||
// overload signatures.
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
describe('TypeScript overloaded method disambiguation', () => {
|
||||
let result: PipelineResult;
|
||||
|
||||
beforeAll(async () => {
|
||||
result = await runPipelineFromRepo(path.join(FIXTURES, 'ts-overload-dispatch'), () => {});
|
||||
}, 60000);
|
||||
|
||||
it('emits METHOD_IMPLEMENTS edge for find', () => {
|
||||
const mi = getRelationships(result, 'METHOD_IMPLEMENTS');
|
||||
const findEdge = mi.find(
|
||||
(e) =>
|
||||
e.source === 'find' &&
|
||||
e.target === 'find' &&
|
||||
e.sourceFilePath.includes('sql-repository') &&
|
||||
e.targetFilePath.includes('repository'),
|
||||
);
|
||||
expect(findEdge).toBeDefined();
|
||||
});
|
||||
|
||||
it('emits METHOD_IMPLEMENTS edge for save', () => {
|
||||
const mi = getRelationships(result, 'METHOD_IMPLEMENTS');
|
||||
const saveEdge = mi.find(
|
||||
(e) =>
|
||||
e.source === 'save' &&
|
||||
e.target === 'save' &&
|
||||
e.sourceFilePath.includes('sql-repository') &&
|
||||
e.targetFilePath.includes('repository'),
|
||||
);
|
||||
expect(saveEdge).toBeDefined();
|
||||
});
|
||||
|
||||
it('TypeScript overloads collapse — find has one implementation METHOD_IMPLEMENTS edge', () => {
|
||||
const mi = getRelationships(result, 'METHOD_IMPLEMENTS');
|
||||
// TypeScript overloads collapse to one implementation signature,
|
||||
// so we expect a single METHOD_IMPLEMENTS edge for find (not two)
|
||||
const findEdges = mi.filter(
|
||||
(e) =>
|
||||
e.source === 'find' &&
|
||||
e.target === 'find' &&
|
||||
e.sourceFilePath.includes('sql-repository') &&
|
||||
e.targetFilePath.includes('repository'),
|
||||
);
|
||||
expect(findEdges.length).toBe(1);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue