@@ -19,6 +19,7 @@ import path from 'node:path';
1919import Database from 'better-sqlite3' ;
2020import { afterAll , beforeAll , describe , expect , it } from 'vitest' ;
2121import { buildGraph } from '../../src/domain/graph/builder.js' ;
22+ import { isNativeAvailable } from '../../src/infrastructure/native.js' ;
2223
2324const FIXTURE = {
2425 'service.js' : `
@@ -103,7 +104,7 @@ function readNodes(dbPath: string) {
103104 }
104105}
105106
106- describe ( 'computed property name method resolution (#1517)' , ( ) => {
107+ describe ( 'computed property name method resolution (#1517) — WASM ' , ( ) => {
107108 it ( 'stores computed class method under plain name (no brackets)' , ( ) => {
108109 const dbPath = path . join ( tmpDir , '.codegraph' , 'graph.db' ) ;
109110 const nodes = readNodes ( dbPath ) ;
@@ -176,3 +177,54 @@ describe('computed property name method resolution (#1517)', () => {
176177 ) . toBeDefined ( ) ;
177178 } ) ;
178179} ) ;
180+
181+ // ── Native engine parity ────────────────────────────────────────────────────
182+ // Guards that handle_method_def in Rust applies the same bracket-stripping as
183+ // the four WASM paths. Skipped when the native addon is not installed.
184+
185+ describe . skipIf ( ! isNativeAvailable ( ) ) (
186+ 'computed property name method resolution (#1517) — native' ,
187+ ( ) => {
188+ let nativeTmpDir : string ;
189+
190+ beforeAll ( async ( ) => {
191+ nativeTmpDir = fs . mkdtempSync ( path . join ( os . tmpdir ( ) , 'cg-1517-native-' ) ) ;
192+ for ( const [ rel , content ] of Object . entries ( FIXTURE ) ) {
193+ fs . writeFileSync ( path . join ( nativeTmpDir , rel ) , content ) ;
194+ }
195+ await buildGraph ( nativeTmpDir , { engine : 'native' , incremental : false , skipRegistry : true } ) ;
196+ } , 60_000 ) ;
197+
198+ afterAll ( ( ) => {
199+ fs . rmSync ( nativeTmpDir , { recursive : true , force : true } ) ;
200+ } ) ;
201+
202+ it ( 'stores computed class method under plain name (no brackets)' , ( ) => {
203+ const nodes = readNodes ( path . join ( nativeTmpDir , '.codegraph' , 'graph.db' ) ) ;
204+ const node = nodes . find ( ( n ) => n . name === 'ApiClient.fetchData' ) ;
205+ expect (
206+ node ,
207+ 'ApiClient.fetchData missing in native output — handle_method_def may not strip brackets' ,
208+ ) . toBeDefined ( ) ;
209+ expect ( node ! . kind ) . toBe ( 'method' ) ;
210+ } ) ;
211+
212+ it ( 'does not store any node with brackets in its name from computed keys' , ( ) => {
213+ const nodes = readNodes ( path . join ( nativeTmpDir , '.codegraph' , 'graph.db' ) ) ;
214+ const bracketed = nodes . filter ( ( n ) => n . name . includes ( '[' ) ) ;
215+ expect (
216+ bracketed ,
217+ `Native output has bracket-leaked nodes: ${ bracketed . map ( ( n ) => n . name ) . join ( ', ' ) } ` ,
218+ ) . toHaveLength ( 0 ) ;
219+ } ) ;
220+
221+ it ( 'resolves call to computed class method at dot-notation call site' , ( ) => {
222+ const edges = readCallEdges ( path . join ( nativeTmpDir , '.codegraph' , 'graph.db' ) ) ;
223+ const edge = edges . find ( ( e ) => e . tgt === 'ApiClient.fetchData' ) ;
224+ expect (
225+ edge ,
226+ 'No native call edge to ApiClient.fetchData — computed method not resolvable in native engine' ,
227+ ) . toBeDefined ( ) ;
228+ } ) ;
229+ } ,
230+ ) ;
0 commit comments