From 8490e99732f7f390e18495db704f8bed982e7674 Mon Sep 17 00:00:00 2001 From: arkh Date: Mon, 13 Apr 2026 11:28:08 +0300 Subject: [PATCH] test(dart): add integration tests for await and widget-tree call patterns --- .../lang-resolution/dart-await-calls/app.dart | 6 ++ .../dart-await-calls/service.dart | 5 ++ .../dart-widget-tree-calls/app.dart | 10 +++ .../dart-widget-tree-calls/builders.dart | 3 + .../test/integration/resolvers/dart.test.ts | 73 +++++++++++++++++++ 5 files changed, 97 insertions(+) create mode 100644 gitnexus/test/fixtures/lang-resolution/dart-await-calls/app.dart create mode 100644 gitnexus/test/fixtures/lang-resolution/dart-await-calls/service.dart create mode 100644 gitnexus/test/fixtures/lang-resolution/dart-widget-tree-calls/app.dart create mode 100644 gitnexus/test/fixtures/lang-resolution/dart-widget-tree-calls/builders.dart diff --git a/gitnexus/test/fixtures/lang-resolution/dart-await-calls/app.dart b/gitnexus/test/fixtures/lang-resolution/dart-await-calls/app.dart new file mode 100644 index 000000000..efa4c00ed --- /dev/null +++ b/gitnexus/test/fixtures/lang-resolution/dart-await-calls/app.dart @@ -0,0 +1,6 @@ +import 'service.dart'; + +Future run() async { + final user = await fetchUser(); + await processData(user); +} diff --git a/gitnexus/test/fixtures/lang-resolution/dart-await-calls/service.dart b/gitnexus/test/fixtures/lang-resolution/dart-await-calls/service.dart new file mode 100644 index 000000000..c0251b632 --- /dev/null +++ b/gitnexus/test/fixtures/lang-resolution/dart-await-calls/service.dart @@ -0,0 +1,5 @@ +Future fetchUser() async { + return 'user'; +} + +Future processData(String data) async {} diff --git a/gitnexus/test/fixtures/lang-resolution/dart-widget-tree-calls/app.dart b/gitnexus/test/fixtures/lang-resolution/dart-widget-tree-calls/app.dart new file mode 100644 index 000000000..844e26abe --- /dev/null +++ b/gitnexus/test/fixtures/lang-resolution/dart-widget-tree-calls/app.dart @@ -0,0 +1,10 @@ +import 'builders.dart'; + +// Named argument call: child: buildHeader() +// List literal calls: children: [buildBody(), buildFooter()] +dynamic buildPage() { + return Column( + child: buildHeader(), + children: [buildBody(), buildFooter()], + ); +} diff --git a/gitnexus/test/fixtures/lang-resolution/dart-widget-tree-calls/builders.dart b/gitnexus/test/fixtures/lang-resolution/dart-widget-tree-calls/builders.dart new file mode 100644 index 000000000..8e1d981d2 --- /dev/null +++ b/gitnexus/test/fixtures/lang-resolution/dart-widget-tree-calls/builders.dart @@ -0,0 +1,3 @@ +dynamic buildHeader() => null; +dynamic buildBody() => null; +dynamic buildFooter() => null; diff --git a/gitnexus/test/integration/resolvers/dart.test.ts b/gitnexus/test/integration/resolvers/dart.test.ts index 82fa77f22..bd3ff708b 100644 --- a/gitnexus/test/integration/resolvers/dart.test.ts +++ b/gitnexus/test/integration/resolvers/dart.test.ts @@ -512,3 +512,76 @@ describe.skipIf(!dartAvailable)( }); }, ); + +// --------------------------------------------------------------------------- +// await call patterns: await fetchUser(), await processData() +// --------------------------------------------------------------------------- + +describe.skipIf(!dartAvailable)('Dart await call resolution', () => { + let result: PipelineResult; + + beforeAll(async () => { + result = await runPipelineFromRepo( + path.join(FIXTURES, 'dart-await-calls'), + () => {}, + ); + }, 60000); + + it('detects fetchUser and processData as functions', () => { + const fns = getNodesByLabel(result, 'Function'); + expect(fns).toContain('fetchUser'); + expect(fns).toContain('processData'); + }); + + it('resolves run → fetchUser via await direct call', () => { + const calls = getRelationships(result, 'CALLS'); + const edge = calls.find((c) => c.source === 'run' && c.target === 'fetchUser'); + expect(edge).toBeDefined(); + }); + + it('resolves run → processData via await direct call', () => { + const calls = getRelationships(result, 'CALLS'); + const edge = calls.find((c) => c.source === 'run' && c.target === 'processData'); + expect(edge).toBeDefined(); + }); +}); + +// --------------------------------------------------------------------------- +// Widget-tree call patterns: named argument and list literal +// --------------------------------------------------------------------------- + +describe.skipIf(!dartAvailable)('Dart widget-tree call resolution', () => { + let result: PipelineResult; + + beforeAll(async () => { + result = await runPipelineFromRepo( + path.join(FIXTURES, 'dart-widget-tree-calls'), + () => {}, + ); + }, 60000); + + it('detects buildHeader, buildBody, buildFooter as functions', () => { + const fns = getNodesByLabel(result, 'Function'); + expect(fns).toContain('buildHeader'); + expect(fns).toContain('buildBody'); + expect(fns).toContain('buildFooter'); + }); + + it('resolves buildPage → buildHeader via named argument call', () => { + const calls = getRelationships(result, 'CALLS'); + const edge = calls.find((c) => c.source === 'buildPage' && c.target === 'buildHeader'); + expect(edge).toBeDefined(); + }); + + it('resolves buildPage → buildBody via list literal call', () => { + const calls = getRelationships(result, 'CALLS'); + const edge = calls.find((c) => c.source === 'buildPage' && c.target === 'buildBody'); + expect(edge).toBeDefined(); + }); + + it('resolves buildPage → buildFooter via list literal call', () => { + const calls = getRelationships(result, 'CALLS'); + const edge = calls.find((c) => c.source === 'buildPage' && c.target === 'buildFooter'); + expect(edge).toBeDefined(); + }); +});