mirror of
https://github.com/colbymchenry/codegraph.git
synced 2026-10-29 14:49:36 +08:00
test(js,ts): require().default and abstract classes read the declared default
Carries two cases from the default-export validation of this branch
(490ef21e): React Native's AnimatedColor shape loaded with
`require('./x').default` and `const { default: X } = require('./x')`,
and an `export default abstract class` below an exported helper that a
class extends. Both fail with main's resolver.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
89d6fc2a7d
commit
0988f787b8
@@ -10,7 +10,8 @@
|
||||
* styled or memo component lost its default function or binding to that
|
||||
* component, and an anonymous default (`export default function () {…}`,
|
||||
* `export default () => …`) took whatever exported function came first — even
|
||||
* one nested inside the default itself.
|
||||
* one nested inside the default itself. `require('./x').default` of an ES
|
||||
* module reads the same default, through the same lookup.
|
||||
*/
|
||||
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
|
||||
import * as fs from 'fs';
|
||||
@@ -173,6 +174,37 @@ export default () => {
|
||||
}
|
||||
|
||||
export default new Service()
|
||||
`,
|
||||
// An abstract class the statement declares, below an exported helper.
|
||||
'src/repository.ts': `export function connect(): string {
|
||||
return "db"
|
||||
}
|
||||
|
||||
export default abstract class Repository {
|
||||
abstract find(id: string): unknown
|
||||
|
||||
describe(): string {
|
||||
return connect()
|
||||
}
|
||||
}
|
||||
`,
|
||||
// React Native's AnimatedColor shape, loaded with `require(…).default`
|
||||
// (read the way a default import reads it) instead of imported.
|
||||
'src/animated/AnimatedColor.ts': `export function getRgbaValueAndNativeColor(value: string): string {
|
||||
return value
|
||||
}
|
||||
|
||||
export default class AnimatedColor {
|
||||
constructor(value: string) {
|
||||
getRgbaValueAndNativeColor(value)
|
||||
}
|
||||
}
|
||||
`,
|
||||
'src/animated/load.ts': `export function makeColors(): unknown[] {
|
||||
const AnimatedColor = require("./AnimatedColor").default
|
||||
const { default: Color } = require("./AnimatedColor")
|
||||
return [new AnimatedColor("red"), new Color("blue")]
|
||||
}
|
||||
`,
|
||||
'src/use.tsx': `import handler from "./api/vans"
|
||||
import Store from "./store"
|
||||
@@ -183,6 +215,7 @@ import Banner from "./components/Banner"
|
||||
import runAnonymous from "./anonymous"
|
||||
import Arrow from "./arrow"
|
||||
import service from "./service"
|
||||
import Repository from "./repository"
|
||||
|
||||
export function consume() {
|
||||
handler({}, { json() {} })
|
||||
@@ -195,6 +228,12 @@ export function consume() {
|
||||
Arrow()
|
||||
service.run()
|
||||
}
|
||||
|
||||
export class Users extends Repository {
|
||||
find(id: string) {
|
||||
return id
|
||||
}
|
||||
}
|
||||
`,
|
||||
};
|
||||
|
||||
@@ -253,6 +292,28 @@ describe('a default import of a module that exports something above its default'
|
||||
expect(targets).not.toContain('src/stream.js:emit');
|
||||
});
|
||||
|
||||
it('extends the abstract class the statement declares', () => {
|
||||
const users = cg.getNodesInFile('src/use.tsx').find((n) => n.name === 'Users' && n.kind === 'class')!;
|
||||
const bases = cg
|
||||
.getOutgoingEdges(users.id)
|
||||
.filter((e) => e.kind === 'extends')
|
||||
.map((e) => `${cg.getNode(e.target)!.filePath}:${cg.getNode(e.target)!.name}`);
|
||||
expect(bases).toEqual(['src/repository.ts:Repository']);
|
||||
});
|
||||
|
||||
it('reads `require(…).default` and `{ default: X } = require(…)` the same way', () => {
|
||||
const make = cg.getNodesInFile('src/animated/load.ts').find((n) => n.name === 'makeColors')!;
|
||||
const created = cg
|
||||
.getOutgoingEdges(make.id)
|
||||
.filter((e) => e.kind === 'calls' || e.kind === 'instantiates')
|
||||
.map((e) => `${e.kind} ${cg.getNode(e.target)!.filePath}:${cg.getNode(e.target)!.name}`)
|
||||
.sort();
|
||||
expect(created).toEqual([
|
||||
'instantiates src/animated/AnimatedColor.ts:AnimatedColor',
|
||||
'instantiates src/animated/AnimatedColor.ts:AnimatedColor',
|
||||
]);
|
||||
});
|
||||
|
||||
it('prefers what the statement exports to an exported component above it', () => {
|
||||
const targets = consumed();
|
||||
expect(targets).toContain('src/components/Title.tsx:Title');
|
||||
|
||||
Reference in New Issue
Block a user