Files
kjol/tools/tsgo/internal/fourslash/tests/goToSourceDefinitionImports_test.go
2026-07-09 16:50:43 -04:00

279 lines
12 KiB
Go

package fourslash_test
import (
"testing"
"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestGoToSourceAliasedImportExport(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @moduleResolution: bundler
// @Filename: /home/src/workspaces/project/node_modules/pkg/package.json
{ "name": "pkg", "main": "./index.js", "types": "./index.d.ts" }
// @Filename: /home/src/workspaces/project/node_modules/pkg/index.d.ts
export declare const foo: number;
// @Filename: /home/src/workspaces/project/node_modules/pkg/index.js
exports./*target*/foo = 1;
// @Filename: /home/src/workspaces/project/index.ts
import { foo as /*importAlias*/bar } from "pkg";
bar;
// @Filename: /home/src/workspaces/project/reexport.ts
export { foo as /*reExportAlias*/bar } from "pkg";`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.VerifyBaselineGoToSourceDefinition(t, "importAlias", "reExportAlias")
}
func TestGoToSourceAliasedImportSpecifier(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
// import { original as alias } uses the propertyName branch.
const content = `// @moduleResolution: bundler
// @Filename: /home/src/workspaces/project/node_modules/pkg/package.json
{ "name": "pkg", "main": "./index.js", "types": "./index.d.ts" }
// @Filename: /home/src/workspaces/project/node_modules/pkg/index.d.ts
export declare function original(): string;
// @Filename: /home/src/workspaces/project/node_modules/pkg/index.js
export function /*target*/original() { return "ok"; }
// @Filename: /home/src/workspaces/project/index.ts
import { original as /*aliasedImport*/renamed } from "pkg";
renamed();`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.VerifyBaselineGoToSourceDefinition(t, "aliasedImport")
}
func TestGoToSourceCallThroughImport(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
// When calling an imported function, the checker returns both the import specifier
// (in the current file) and the call signature target (from .d.ts → mapped to .js).
const content = `// @moduleResolution: bundler
// @Filename: /home/src/workspaces/project/node_modules/pkg/package.json
{ "name": "pkg", "main": "./index.js", "types": "./index.d.ts" }
// @Filename: /home/src/workspaces/project/node_modules/pkg/index.d.ts
export declare class Widget {
constructor(name: string);
render(): void;
}
// @Filename: /home/src/workspaces/project/node_modules/pkg/index.js
export class /*targetWidget*/Widget {
constructor(name) { this.name = name; }
/*targetRender*/render() {}
}
// @Filename: /home/src/workspaces/project/index.ts
import { Widget } from "pkg";
const w = new /*constructorCall*/Widget("test");
w./*methodCall*/render();`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.VerifyBaselineGoToSourceDefinition(t, "constructorCall", "methodCall")
}
func TestGoToSourceCallbackParam(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @moduleResolution: bundler
// @Filename: /home/src/workspaces/project/node_modules/@types/yargs/package.json
{
"name": "@types/yargs",
"version": "1.0.0",
"types": "./index.d.ts"
}
// @Filename: /home/src/workspaces/project/node_modules/@types/yargs/index.d.ts
export interface Yargs { positional(): Yargs; }
export declare function command(command: string, cb: (yargs: Yargs) => void): void;
// @Filename: /home/src/workspaces/project/node_modules/yargs/package.json
{
"name": "yargs",
"version": "1.0.0",
"main": "index.js"
}
// @Filename: /home/src/workspaces/project/node_modules/yargs/index.js
export function command(cmd, cb) { cb({ /*end*/positional: "This is obviously not even close to realistic" }); }
// @Filename: /home/src/workspaces/project/index.ts
import { command } from "yargs";
command("foo", yargs => {
yargs.[|/*start*/positional|]();
});`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.VerifyBaselineGoToSourceDefinition(t, "start")
}
func TestGoToSourceReExportNames(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @moduleResolution: bundler
// @Filename: /home/src/workspaces/project/node_modules/pkg/package.json
{ "name": "pkg", "main": "./index.js", "types": "./index.d.ts" }
// @Filename: /home/src/workspaces/project/node_modules/pkg/index.d.ts
export declare function foo(): string;
export declare function bar(): number;
// @Filename: /home/src/workspaces/project/node_modules/pkg/index.js
export function /*targetFoo*/foo() { return "ok"; }
export function /*targetBar*/bar() { return 42; }
// @Filename: /home/src/workspaces/project/reexport.ts
export { /*reExportFoo*/foo, /*reExportBar*/bar } from "pkg";
// @Filename: /home/src/workspaces/project/index.ts
import { foo, bar } from [|"pkg"/*moduleSpecifier*/|];`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.VerifyBaselineGoToSourceDefinition(t, "reExportFoo", "reExportBar", "moduleSpecifier")
}
func TestGoToSourceReExportModuleSpecifier(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @moduleResolution: bundler
// @Filename: /home/src/workspaces/project/node_modules/pkg/package.json
{ "name": "pkg", "main": "./index.js", "types": "./index.d.ts" }
// @Filename: /home/src/workspaces/project/node_modules/pkg/index.d.ts
export declare function alpha(): string;
export declare function beta(): number;
// @Filename: /home/src/workspaces/project/node_modules/pkg/index.js
export function /*targetAlpha*/alpha() { return "a"; }
export function /*targetBeta*/beta() { return 2; }
// @Filename: /home/src/workspaces/project/reexport.ts
export { alpha, beta } from [|"pkg"/*reExportSpecifier*/|];`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.VerifyBaselineGoToSourceDefinition(t, "reExportSpecifier")
}
func TestGoToSourceReExportedImplementation(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @moduleResolution: bundler
// @Filename: /home/src/workspaces/project/node_modules/pkg/package.json
{ "name": "pkg", "main": "./index.js", "types": "./index.d.ts", "type": "module" }
// @Filename: /home/src/workspaces/project/node_modules/pkg/index.d.ts
export { foo } from "./foo";
// @Filename: /home/src/workspaces/project/node_modules/pkg/index.js
export { foo } from "./foo.js";
// @Filename: /home/src/workspaces/project/node_modules/pkg/foo.d.ts
export declare function foo(): string;
// @Filename: /home/src/workspaces/project/node_modules/pkg/foo.js
export function /*target*/foo() { return "ok"; }
// @Filename: /home/src/workspaces/project/index.ts
import { /*importName*/foo } from "pkg";
foo/*start*/();`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.VerifyBaselineGoToSourceDefinition(t, "importName", "start")
}
func TestGoToSourceImportFilteredByExternalDeclaration(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @moduleResolution: bundler
// @Filename: /home/src/workspaces/project/node_modules/pkg/package.json
{ "name": "pkg", "main": "./index.js", "types": "./index.d.ts" }
// @Filename: /home/src/workspaces/project/node_modules/pkg/index.d.ts
export declare function helper(): void;
// @Filename: /home/src/workspaces/project/node_modules/pkg/index.js
export function /*target*/helper() {}
// @Filename: /home/src/workspaces/project/index.ts
import { helper } from "pkg";
helper/*usage*/();
export { helper as /*reExport*/myHelper } from "pkg";`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.VerifyBaselineGoToSourceDefinition(t, "usage", "reExport")
}
func TestGoToSourceDtsReExport(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
// The .d.ts declaration itself re-exports from another module,
// so findContainingModuleSpecifier(declaration) finds that specifier.
const content = `// @moduleResolution: bundler
// @Filename: /home/src/workspaces/project/node_modules/pkg/package.json
{ "name": "pkg", "main": "./index.js", "types": "./index.d.ts" }
// @Filename: /home/src/workspaces/project/node_modules/pkg/impl.d.ts
export declare function helper(): void;
// @Filename: /home/src/workspaces/project/node_modules/pkg/impl.js
export function /*target*/helper() {}
// @Filename: /home/src/workspaces/project/node_modules/pkg/index.d.ts
export { helper } from "./impl";
// @Filename: /home/src/workspaces/project/node_modules/pkg/index.js
export { helper } from "./impl.js";
// @Filename: /home/src/workspaces/project/index.ts
import { helper } from "pkg";
helper/*usage*/();`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.VerifyBaselineGoToSourceDefinition(t, "usage")
}
func TestGoToSourceBarrelReExportChain(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
// index.js re-exports from impl.js, causing getForwardedImplementationFiles
// to follow the chain.
const content = `// @moduleResolution: bundler
// @Filename: /home/src/workspaces/project/node_modules/pkg/package.json
{ "name": "pkg", "main": "./index.js", "types": "./index.d.ts" }
// @Filename: /home/src/workspaces/project/node_modules/pkg/impl.js
export function /*target*/doWork() { return 42; }
// @Filename: /home/src/workspaces/project/node_modules/pkg/impl.d.ts
export declare function doWork(): number;
// @Filename: /home/src/workspaces/project/node_modules/pkg/index.d.ts
export { doWork } from "./impl";
// @Filename: /home/src/workspaces/project/node_modules/pkg/index.js
export { doWork } from "./impl.js";
// @Filename: /home/src/workspaces/project/index.ts
import { /*importName*/doWork } from "pkg";
doWork/*callSite*/();`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.VerifyBaselineGoToSourceDefinition(t, "importName", "callSite")
}
func TestGoToSourceCJSReExportViaDefineProperty(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @moduleResolution: bundler
// @Filename: /home/src/workspaces/project/node_modules/pkg/package.json
{ "name": "pkg", "main": "./index.js", "types": "./index.d.ts" }
// @Filename: /home/src/workspaces/project/node_modules/pkg/index.d.ts
export declare function greet(name: string): string;
export declare enum TargetPopulation {
Team = "team",
Public = "public",
}
// @Filename: /home/src/workspaces/project/node_modules/pkg/index.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TargetPopulation = exports.greet = void 0;
var impl_1 = require("./impl");
Object.defineProperty(exports, "greet", { enumerable: true, get: function () { return impl_1.greet; } });
var types_1 = require("./types");
Object.defineProperty(exports, "TargetPopulation", { enumerable: true, get: function () { return types_1.TargetPopulation; } });
// @Filename: /home/src/workspaces/project/node_modules/pkg/impl.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.greet = void 0;
function /*greetImpl*/greet(name) { return "Hello, " + name; }
exports.greet = greet;
// @Filename: /home/src/workspaces/project/node_modules/pkg/types.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TargetPopulation = void 0;
var /*targetPopulationImpl*/TargetPopulation;
(function (TargetPopulation) {
TargetPopulation["Team"] = "team";
TargetPopulation["Public"] = "public";
})(TargetPopulation || (exports.TargetPopulation = TargetPopulation = {}));
// @Filename: /home/src/workspaces/project/index.ts
import { /*namedImport*/greet, /*enumImport*/TargetPopulation } from "pkg";
greet/*call*/("world");
TargetPopulation/*enumAccess*/.Team;`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.VerifyBaselineGoToSourceDefinition(t, "namedImport", "enumImport", "call", "enumAccess")
}