Skip to content

TypeScript: a call to a function nested in one describe() links to a same-named function in another describe() by line distance #2944

Open

Description

@inth3shadows

A call to a function declared inside a describe() callback can link to a same-named function declared in a different describe() block. The nearer one by line number wins, whichever block it is in, and the function actually in scope gets no callers.

// a.test.ts
describe('first', () => {
  function setup(): number { return 1; }
  // ... 20 lines ...
  it('uses first', () => { setup(); });     // line 23
});
describe('second', () => {
  function setup(): number { return 2; }    // line 26
  it('uses second', () => { setup(); });    // line 27
});

(Plus declare function describe/it in a .d.ts so the file stands alone.)

call expected actual
line 23 setup at line 2 setup at line 26 (resolvedBy: exact-match)
line 27 setup at line 26 setup at line 26

The setup at line 2 ends up with zero callers. With the two blocks closer together than the padding, both calls link correctly, so the outcome comes down to line distance.

Arrow-function helpers too. Writing both helpers as const setup = (): number => 1; / const setup = (): number => 2; gives the same result: line 23 links to the setup at line 26. In the TypeScript-checker comparison this is the bigger group: 162 edges (143 on this repo's tests, 19 on excalidraw), e.g. __tests__/exclude-config.test.ts:72 writeConfig(…) → the writeConfig at line 97, and excalidraw's renderOverrides.test.tsx:791 setup(…) → the setup at line 51 instead of its own.

Reproduced on main at 31ec908 with CODEGRAPH_KERNEL=0, and on 69af19a with the native kernel too (Linux/WSL2, Node 22.23.2).

How I found it. I checked every TS calls edge against the TypeScript checker on three repos. This repo's own tests have 73 such edges (counted on a build of 69af19a), for example __tests__/explore-long-query.test.ts: the setup() calls at lines 147 and 162 link to the setup at line 190 (next describe), not the one at line 103 (their own). Line 147 is 44 lines from its own setup and 43 from the other.

What the index holds (observed). Both nodes are function setup with qualifiedName setup, and the edges' source is the file node, because the calls sit in arrow callbacks. So neither side carries the describe scope, and the tie between the two candidates falls to line distance. I haven't traced where the lexical-reachability check that matchByExactName does for nested functions should come in.

Not fixed by #1952 (the caller's own class member before same-file namesakes): I ran this fixture on its head 3016687, and line 23 still links to line 26.

Searched open issues and PRs for nested same-name functions, describe/setup and same-file namesakes: nothing else covers this.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions