-
-
Notifications
You must be signed in to change notification settings - Fork 4.8k
fix(ruby): scope-resolution namespaced class/module definitions — F62 (#1933) #1972
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
242174b
6314437
58cda04
7cbd723
bb289ab
26d8a31
e1edbd8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| class Foo::Bar | ||
| def bar_method; end | ||
| end | ||
|
|
||
| module Baz::Qux | ||
| def qux_method; end | ||
| end | ||
|
|
||
| class Outer::Middle::Inner | ||
| def inner_method; end | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,82 @@ | ||
| /** | ||
| * Regression tests for Ruby namespaced class/module definitions (issue #1933 F62). | ||
| * | ||
| * The existing query captures (class) and (module) with name: (constant) only — | ||
| * missing namespaced forms like class Foo::Bar and module Baz::Qux where the | ||
| * name field is a scope_resolution node. | ||
| */ | ||
| // NOTE: Tests are capture-level only. Graph-node modeling for namespaced | ||
| // class/module definitions is a tracked follow-up — the scope-extractor | ||
| // doesn't yet handle scope_resolution names end-to-end. | ||
| import { describe, it, expect } from 'vitest'; | ||
| import { emitRubyScopeCaptures } from '../../../src/core/ingestion/languages/ruby/index.js'; | ||
| import type { CaptureMatch } from 'gitnexus-shared'; | ||
|
|
||
| describe('Ruby namespaced class/module definitions (F62) — capture-level', () => { | ||
| it('class Foo::Bar captures @declaration.class with tail constant (Bar)', () => { | ||
| const src = `class Foo::Bar | ||
| def bar_method; end | ||
| end | ||
| `; | ||
| const matches = emitRubyScopeCaptures(src, 'test.rb') as CaptureMatch[]; | ||
| const classDecls = matches.filter((m) => m['@declaration.class']); | ||
| expect(classDecls.length).toBe(1); | ||
| expect(classDecls[0]['@declaration.name'].text).toBe('Bar'); | ||
| }); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [P2 · incomplete fix] These assertions verify capture output only — the graph node is never created. All 5 tests assert This is pre-existing (byte-identical at BASE), so not a regression — but the tests pass while the F62 goal isn't met end-to-end. Consider a |
||
|
|
||
| it('module Baz::Qux captures @declaration.trait with tail constant (Qux)', () => { | ||
| const src = `module Baz::Qux | ||
| def qux_method; end | ||
| end | ||
| `; | ||
| const matches = emitRubyScopeCaptures(src, 'test.rb') as CaptureMatch[]; | ||
| const moduleDecls = matches.filter((m) => m['@declaration.trait']); | ||
| expect(moduleDecls.length).toBe(1); | ||
| expect(moduleDecls[0]['@declaration.name'].text).toBe('Qux'); | ||
| }); | ||
|
|
||
| it('nested chain Outer::Middle::Inner resolves to tail constant (Inner)', () => { | ||
| const src = `class Outer::Middle::Inner | ||
| def inner_method; end | ||
| end | ||
| `; | ||
| const matches = emitRubyScopeCaptures(src, 'test.rb') as CaptureMatch[]; | ||
| const classDecls = matches.filter((m) => m['@declaration.class']); | ||
| expect(classDecls.length).toBe(1); | ||
| expect(classDecls[0]['@declaration.name'].text).toBe('Inner'); | ||
| }); | ||
|
|
||
| it('bare class Foo still works alongside namespaced class', () => { | ||
| const src = ` | ||
| class Foo | ||
| def foo_method; end | ||
| end | ||
|
|
||
| class Foo::Bar | ||
| def bar_method; end | ||
| end | ||
| `; | ||
| const matches = emitRubyScopeCaptures(src, 'test.rb') as CaptureMatch[]; | ||
| const classDecls = matches.filter((m) => m['@declaration.class']); | ||
| expect(classDecls.length).toBe(2); | ||
| const names = classDecls.map((m) => m['@declaration.name'].text).sort(); | ||
| expect(names).toEqual(['Bar', 'Foo']); | ||
| }); | ||
|
|
||
| it('bare module Baz still works alongside namespaced module', () => { | ||
| const src = ` | ||
| module Baz | ||
| def baz_method; end | ||
| end | ||
|
|
||
| module Baz::Qux | ||
| def qux_method; end | ||
| end | ||
| `; | ||
| const matches = emitRubyScopeCaptures(src, 'test.rb') as CaptureMatch[]; | ||
| const moduleDecls = matches.filter((m) => m['@declaration.trait']); | ||
| expect(moduleDecls.length).toBe(2); | ||
| const names = moduleDecls.map((m) => m['@declaration.name'].text).sort(); | ||
| expect(names).toEqual(['Baz', 'Qux']); | ||
| }); | ||
| }); | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[P1 · CI blocker] The captures golden wasn't regenerated — a separate artifact from the bench baseline.
[reproduced]This
_notecorrectly flags bench-fingerprint drift, but the scope-captures golden —test/fixtures/ruby-captures-golden/expected-captures.json(not in this diff) — is a different file and was not regenerated.ruby-captures-golden.test.tsglobs everyruby-*fixture, so it now collectsruby-namespaced/namespaced.rband fails:expected {…(81)} to deeply equal {…(80)}(exit 1). Confirmed failing in CI (tests / ubuntu / coverage→ fail;CI Gatefails downstream).Fix:
UPDATE_GOLDEN=1 npx vitest run test/unit/scope-resolution/ruby/ruby-captures-golden.test.tsand commit the updatedexpected-captures.json.