vendor tsgo
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestGoToDefinitionDecoratorNoCrashOnFunctionDeclaration1(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `function dec(target: any) { return target; }
|
||||
|
||||
@/*1*/dec
|
||||
function foo() {}`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyBaselineGoToDefinition(t, true, "1")
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
. "github.com/microsoft/typescript-go/internal/fourslash/tests/util"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestArgumentCompletions(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `
|
||||
function foo(a: "a", b: "b") {}
|
||||
foo("a", /*1*/);
|
||||
|
||||
|
||||
const t3 = ['x', 'y', 'z'] as const;
|
||||
const x: [string, string, string, 'a' | 'b'] = [...t3, /*2*/];
|
||||
`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyCompletions(t, "1", &fourslash.CompletionsExpectedList{
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{`"b"`},
|
||||
},
|
||||
})
|
||||
f.VerifyCompletions(t, "2", &fourslash.CompletionsExpectedList{
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{`"b"`},
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
package fourslash
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestAutoCloseTagsWithTriviaAndComplexNames(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
// Using separate files for each example to avoid unclosed JSX tags affecting other tests.
|
||||
const content = `// @noLib: true
|
||||
|
||||
// @Filename: /0.tsx
|
||||
// JSDoc
|
||||
const x = <
|
||||
/** hello world! */
|
||||
div /** hello world! */
|
||||
>/*0*/
|
||||
|
||||
// @Filename: /1.tsx
|
||||
// Single-line comments
|
||||
const x =
|
||||
<
|
||||
// hello world!
|
||||
div // hello world!
|
||||
>/*1*/
|
||||
|
||||
// @Filename: /2.tsx
|
||||
// Namespaced tag
|
||||
const x =
|
||||
<ns:sometag>/*2*/
|
||||
|
||||
// @Filename: /3.tsx
|
||||
// Namespace with single-line comments
|
||||
const x = <
|
||||
// pre-ns
|
||||
ns
|
||||
// pre-colon
|
||||
:
|
||||
// post-colon
|
||||
sometag
|
||||
// post-id
|
||||
>/*3*/
|
||||
|
||||
// @Filename: /4.tsx
|
||||
// UppercaseComponent-named tag
|
||||
const x = <SomeComponent>/*4*/
|
||||
|
||||
// @Filename: /5.tsx
|
||||
// propertyAccess.Component-named tag
|
||||
const x = <
|
||||
someModule
|
||||
.
|
||||
SomeComponent
|
||||
>/*5*/
|
||||
|
||||
// @Filename: /6.tsx
|
||||
// propertyAccess.Component-named tag with single-line comments
|
||||
const x =
|
||||
<
|
||||
// pre-object
|
||||
someModule
|
||||
// pre-dot
|
||||
.
|
||||
// post-dot
|
||||
SomeComponent
|
||||
// post-id
|
||||
>/*6*/;
|
||||
|
||||
// @Filename: /7.tsx
|
||||
// Generic propertyAccess.Component-named tag
|
||||
const x =
|
||||
<
|
||||
someModule.SomeComponent<string>
|
||||
prop="stringValue"
|
||||
>/*7*/;
|
||||
|
||||
// @Filename: /8.tsx
|
||||
// Namespaced tag with hyphens
|
||||
const x =
|
||||
<my-namespace:my-tag>/*8*/
|
||||
|
||||
// @Filename: /9.tsx
|
||||
// Generic tag with no attributes
|
||||
const x = <SomeComponent<number>>/*9*/
|
||||
|
||||
// @Filename: /10.tsx
|
||||
// Tag name containing $ (must be snippet-escaped)
|
||||
const x = <$Foo>/*10*/
|
||||
`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyBaselineClosingTags(t)
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
// TestAutoImportCJSWithNodeModuleKind verifies that auto-imports use require()
|
||||
// syntax in CJS files when using node16/node20/nodenext module kinds with a
|
||||
// package.json that has "type": "commonjs".
|
||||
func TestAutoImportCJSWithNodeModuleKind(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @Filename: /tsconfig.json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"module": "node20",
|
||||
"checkJs": true,
|
||||
"noEmit": true
|
||||
}
|
||||
}
|
||||
// @Filename: /package.json
|
||||
{ "type": "commonjs" }
|
||||
// @Filename: /lib.js
|
||||
module.exports = { LIB_VERSION: 1 };
|
||||
// @Filename: /main.js
|
||||
module.exports.foo = 0;
|
||||
LIB_VERSION/**/`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
|
||||
f.GoToMarker(t, "")
|
||||
f.VerifyImportFixAtPosition(t, []string{
|
||||
`const { LIB_VERSION } = require("./lib");
|
||||
|
||||
module.exports.foo = 0;
|
||||
LIB_VERSION`,
|
||||
}, nil /*preferences*/)
|
||||
}
|
||||
|
||||
// TestAutoImportCJSWithNodeModuleKindEmptyFile verifies that auto-imports use
|
||||
// require() syntax even in empty CJS files when using node module kinds.
|
||||
func TestAutoImportCJSWithNodeModuleKindEmptyFile(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @Filename: /tsconfig.json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"module": "node20",
|
||||
"checkJs": true,
|
||||
"noEmit": true
|
||||
}
|
||||
}
|
||||
// @Filename: /package.json
|
||||
{ "type": "commonjs" }
|
||||
// @Filename: /lib.js
|
||||
module.exports = { LIB_VERSION: 1 };
|
||||
// @Filename: /main.js
|
||||
LIB_VERSION/**/`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
|
||||
f.GoToMarker(t, "")
|
||||
f.VerifyImportFixAtPosition(t, []string{
|
||||
`const { LIB_VERSION } = require("./lib");
|
||||
|
||||
LIB_VERSION`,
|
||||
}, nil /*preferences*/)
|
||||
}
|
||||
|
||||
// TestAutoImportCJSWithModuleDetectionForce verifies that auto-imports use
|
||||
// require() syntax in JS files with CJS syntax when moduleDetection is "force",
|
||||
// even with --module preserve where GetImpliedNodeFormatForEmit won't help.
|
||||
func TestAutoImportCJSWithModuleDetectionForce(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @Filename: /tsconfig.json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"module": "preserve",
|
||||
"moduleDetection": "force",
|
||||
"checkJs": true,
|
||||
"noEmit": true
|
||||
}
|
||||
}
|
||||
// @Filename: /lib.js
|
||||
export const LIB_VERSION = 1;
|
||||
// @Filename: /main.js
|
||||
const path = require("path");
|
||||
LIB_VERSION/**/`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
|
||||
f.GoToMarker(t, "")
|
||||
f.VerifyImportFixAtPosition(t, []string{
|
||||
`const path = require("path");
|
||||
const { LIB_VERSION } = require("./lib");
|
||||
LIB_VERSION`,
|
||||
}, nil /*preferences*/)
|
||||
}
|
||||
122
tools/tsgo/internal/fourslash/tests/autoImportCompletion_test.go
Normal file
122
tools/tsgo/internal/fourslash/tests/autoImportCompletion_test.go
Normal file
@@ -0,0 +1,122 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/core"
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
. "github.com/microsoft/typescript-go/internal/fourslash/tests/util"
|
||||
"github.com/microsoft/typescript-go/internal/ls/lsutil"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestAutoImportCompletion1(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @Filename: a.ts
|
||||
export const someVar = 10;
|
||||
|
||||
// @Filename: b.ts
|
||||
export const anotherVar = 10;
|
||||
|
||||
// @Filename: c.ts
|
||||
import {someVar} from "./a.ts";
|
||||
someVar;
|
||||
a/**/
|
||||
`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyCompletions(t, "", &fourslash.CompletionsExpectedList{
|
||||
UserPreferences: &lsutil.UserPreferences{
|
||||
IncludeCompletionsForModuleExports: core.TSTrue,
|
||||
IncludeCompletionsForImportStatements: core.TSTrue,
|
||||
},
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
EditRange: Ignored,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{"someVar", "anotherVar"},
|
||||
},
|
||||
})
|
||||
f.BaselineAutoImportsCompletions(t, []string{""})
|
||||
f.VerifyCompletions(t, "", &fourslash.CompletionsExpectedList{
|
||||
UserPreferences: &lsutil.UserPreferences{
|
||||
// completion autoimport preferences off; this tests if fourslash server communication correctly registers changes in user preferences
|
||||
IncludeCompletionsForModuleExports: core.TSFalse,
|
||||
IncludeCompletionsForImportStatements: core.TSFalse,
|
||||
},
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
EditRange: Ignored,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Excludes: []string{"anotherVar"},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestAutoImportCompletion2(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @Filename: a.ts
|
||||
export const someVar = 10;
|
||||
export const anotherVar = 10;
|
||||
|
||||
// @Filename: c.ts
|
||||
import {someVar} from "./a.ts";
|
||||
someVar;
|
||||
a/**/
|
||||
`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyCompletions(t, "", &fourslash.CompletionsExpectedList{
|
||||
UserPreferences: &lsutil.UserPreferences{
|
||||
IncludeCompletionsForModuleExports: core.TSTrue,
|
||||
IncludeCompletionsForImportStatements: core.TSTrue,
|
||||
},
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
EditRange: Ignored,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{"someVar", "anotherVar"},
|
||||
},
|
||||
})
|
||||
f.BaselineAutoImportsCompletions(t, []string{""})
|
||||
}
|
||||
|
||||
func TestAutoImportCompletion3(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @Filename: a.ts
|
||||
export const aa = "asdf";
|
||||
export const someVar = 10;
|
||||
export const bb = 10;
|
||||
|
||||
// @Filename: c.ts
|
||||
import { aa, someVar } from "./a.ts";
|
||||
someVar;
|
||||
b/**/
|
||||
`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyCompletions(t, "", &fourslash.CompletionsExpectedList{
|
||||
UserPreferences: &lsutil.UserPreferences{
|
||||
IncludeCompletionsForModuleExports: core.TSTrue,
|
||||
IncludeCompletionsForImportStatements: core.TSTrue,
|
||||
},
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
EditRange: Ignored,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{"bb"},
|
||||
},
|
||||
})
|
||||
f.BaselineAutoImportsCompletions(t, []string{""})
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
util "github.com/microsoft/typescript-go/internal/fourslash/tests/util"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestAutoImportCompletionsForArbitraryNonIdentifierExports(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `
|
||||
// @module: esnext
|
||||
// @Filename: /a.ts
|
||||
const foo = 0;
|
||||
export { foo as "foo-bar" };
|
||||
export const fooBar = 1;
|
||||
|
||||
// @Filename: /b.ts
|
||||
foo/**/
|
||||
`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
|
||||
f.VerifyCompletions(t, "", &fourslash.CompletionsExpectedList{
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Excludes: []string{"foo-bar"},
|
||||
Includes: []fourslash.CompletionsExpectedItem{"fooBar"},
|
||||
},
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &util.DefaultCommitCharacters,
|
||||
EditRange: util.Ignored,
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
// TestAutoImportCrossProjectNodeModules verifies that when multiple projects share
|
||||
// a node_modules directory, auto-imports for a project only show packages that are
|
||||
// either listed in that project's package.json dependencies OR directly imported
|
||||
// by that project's files.
|
||||
//
|
||||
// Scenario:
|
||||
// - Two separate projects (project-a and project-b) share a root node_modules
|
||||
// - pkg-listed is in both package.json dependencies
|
||||
// - pkg-unlisted is NOT in any package.json, but project-a imports it directly
|
||||
// - When requesting completions in project-b, pkg-unlisted should NOT appear
|
||||
// because project-b doesn't list it and doesn't import it directly.
|
||||
func TestAutoImportCrossProjectNodeModules(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @Filename: /node_modules/pkg-listed/package.json
|
||||
{ "name": "pkg-listed", "version": "1.0.0" }
|
||||
// @Filename: /node_modules/pkg-listed/index.d.ts
|
||||
export declare const pkg_listed_value: number;
|
||||
// @Filename: /node_modules/pkg-unlisted/package.json
|
||||
{ "name": "pkg-unlisted", "version": "1.0.0" }
|
||||
// @Filename: /node_modules/pkg-unlisted/index.d.ts
|
||||
export declare const pkg_unlisted_value: string;
|
||||
// @Filename: /project-a/tsconfig.json
|
||||
{ "compilerOptions": { "module": "commonjs", "strict": true } }
|
||||
// @Filename: /project-a/package.json
|
||||
{ "name": "project-a", "dependencies": { "pkg-listed": "*" } }
|
||||
// @Filename: /project-a/index.ts
|
||||
import { pkg_unlisted_value } from "pkg-unlisted";
|
||||
console.log(pkg_unlisted_value);
|
||||
// @Filename: /project-b/tsconfig.json
|
||||
{ "compilerOptions": { "module": "commonjs", "strict": true } }
|
||||
// @Filename: /project-b/package.json
|
||||
{ "name": "project-b", "dependencies": { "pkg-listed": "*" } }
|
||||
// @Filename: /project-b/index.ts
|
||||
pkg_/**/`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
|
||||
// Open project-a's file first - this establishes that project-a imports pkg-unlisted
|
||||
f.GoToFile(t, "/project-a/index.ts")
|
||||
|
||||
// Now go to project-b and baseline auto-imports
|
||||
f.GoToMarker(t, "")
|
||||
f.BaselineAutoImportsCompletions(t, []string{""})
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
. "github.com/microsoft/typescript-go/internal/fourslash/tests/util"
|
||||
"github.com/microsoft/typescript-go/internal/ls"
|
||||
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestAutoImportCssModule(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `
|
||||
// @Filename: /tsconfig.json
|
||||
{ "compilerOptions": { "module": "nodenext", "moduleResolution": "nodenext" } }
|
||||
|
||||
// @Filename: /package.json
|
||||
{ "type": "module" }
|
||||
|
||||
// @Filename: /augmentations.ts
|
||||
export {};
|
||||
declare module "./styles.css" {
|
||||
export const myClass: string;
|
||||
}
|
||||
|
||||
// @Filename: /index.ts
|
||||
myClass/**/
|
||||
`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
// Verify auto-import completions don't panic when importing from .css module augmentation
|
||||
f.VerifyCompletions(t, "", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
EditRange: Ignored,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{
|
||||
&lsproto.CompletionItem{
|
||||
Label: "myClass",
|
||||
Data: &lsproto.CompletionItemData{
|
||||
AutoImport: &lsproto.AutoImportFix{
|
||||
ModuleSpecifier: "./styles.css",
|
||||
},
|
||||
},
|
||||
AdditionalTextEdits: fourslash.AnyTextEdits,
|
||||
SortText: new(string(ls.SortTextAutoImportSuggestions)),
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,235 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/core"
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
. "github.com/microsoft/typescript-go/internal/fourslash/tests/util"
|
||||
"github.com/microsoft/typescript-go/internal/ls/lsutil"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestAutoImportDefaultPascalCase(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @jsx: react
|
||||
// @module: esnext
|
||||
// @moduleResolution: bundler
|
||||
|
||||
// @Filename: /src/components/ChargerHeader.tsx
|
||||
export default function ChargerHeader() {
|
||||
return null;
|
||||
}
|
||||
|
||||
// @Filename: /src/screens/SomeScreen.tsx
|
||||
export function SomeScreen() {
|
||||
return <ChargerHeader/*1*/
|
||||
}
|
||||
`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyCompletions(t, "1", &fourslash.CompletionsExpectedList{
|
||||
UserPreferences: &lsutil.UserPreferences{
|
||||
IncludeCompletionsForModuleExports: core.TSTrue,
|
||||
IncludeCompletionsForImportStatements: core.TSTrue,
|
||||
},
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
EditRange: Ignored,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{"ChargerHeader"},
|
||||
},
|
||||
})
|
||||
f.BaselineAutoImportsCompletions(t, []string{"1"})
|
||||
}
|
||||
|
||||
func TestAutoImportDefaultPascalCaseAnonymous(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @jsx: react
|
||||
// @module: esnext
|
||||
// @moduleResolution: bundler
|
||||
|
||||
// @Filename: /src/components/ChargerHeader.tsx
|
||||
export default function() {
|
||||
return null;
|
||||
}
|
||||
|
||||
// @Filename: /src/screens/SomeScreen.tsx
|
||||
export function SomeScreen() {
|
||||
return <ChargerHeader/*1*/
|
||||
}
|
||||
`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyCompletions(t, "1", &fourslash.CompletionsExpectedList{
|
||||
UserPreferences: &lsutil.UserPreferences{
|
||||
IncludeCompletionsForModuleExports: core.TSTrue,
|
||||
IncludeCompletionsForImportStatements: core.TSTrue,
|
||||
},
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
EditRange: Ignored,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{"ChargerHeader"},
|
||||
},
|
||||
})
|
||||
f.BaselineAutoImportsCompletions(t, []string{"1"})
|
||||
}
|
||||
|
||||
func TestAutoImportDefaultPascalCaseCaseInsensitive(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @jsx: react
|
||||
// @module: esnext
|
||||
// @moduleResolution: bundler
|
||||
// @useCaseSensitiveFileNames: false
|
||||
|
||||
// @Filename: /src/components/ChargerHeader.tsx
|
||||
export default function ChargerHeader() {
|
||||
return null;
|
||||
}
|
||||
|
||||
// @Filename: /src/screens/SomeScreen.tsx
|
||||
export function SomeScreen() {
|
||||
return <ChargerHeader/*1*/
|
||||
}
|
||||
`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyCompletions(t, "1", &fourslash.CompletionsExpectedList{
|
||||
UserPreferences: &lsutil.UserPreferences{
|
||||
IncludeCompletionsForModuleExports: core.TSTrue,
|
||||
IncludeCompletionsForImportStatements: core.TSTrue,
|
||||
},
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
EditRange: Ignored,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{"ChargerHeader"},
|
||||
},
|
||||
})
|
||||
f.BaselineAutoImportsCompletions(t, []string{"1"})
|
||||
}
|
||||
|
||||
func TestAutoImportDefaultPascalCaseAnonymousCaseInsensitive(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @jsx: react
|
||||
// @module: esnext
|
||||
// @moduleResolution: bundler
|
||||
// @useCaseSensitiveFileNames: false
|
||||
|
||||
// @Filename: /src/components/ChargerHeader.tsx
|
||||
export default function() {
|
||||
return null;
|
||||
}
|
||||
|
||||
// @Filename: /src/screens/SomeScreen.tsx
|
||||
export function SomeScreen() {
|
||||
return <ChargerHeader/*1*/
|
||||
}
|
||||
`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyCompletions(t, "1", &fourslash.CompletionsExpectedList{
|
||||
UserPreferences: &lsutil.UserPreferences{
|
||||
IncludeCompletionsForModuleExports: core.TSTrue,
|
||||
IncludeCompletionsForImportStatements: core.TSTrue,
|
||||
},
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
EditRange: Ignored,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{"ChargerHeader"},
|
||||
},
|
||||
})
|
||||
f.BaselineAutoImportsCompletions(t, []string{"1"})
|
||||
}
|
||||
|
||||
func TestAutoImportDefaultPascalCaseReexportCaseInsensitive(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @jsx: react
|
||||
// @module: esnext
|
||||
// @moduleResolution: bundler
|
||||
// @useCaseSensitiveFileNames: false
|
||||
|
||||
// @Filename: /src/components/ChargerHeader.tsx
|
||||
export default function() {
|
||||
return null;
|
||||
}
|
||||
|
||||
// @Filename: /src/components/index.ts
|
||||
export { default } from "./ChargerHeader";
|
||||
|
||||
// @Filename: /src/screens/SomeScreen.tsx
|
||||
export function SomeScreen() {
|
||||
return <ChargerHeader/*1*/
|
||||
}
|
||||
`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyCompletions(t, "1", &fourslash.CompletionsExpectedList{
|
||||
UserPreferences: &lsutil.UserPreferences{
|
||||
IncludeCompletionsForModuleExports: core.TSTrue,
|
||||
IncludeCompletionsForImportStatements: core.TSTrue,
|
||||
},
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
EditRange: Ignored,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{"ChargerHeader"},
|
||||
},
|
||||
})
|
||||
f.BaselineAutoImportsCompletions(t, []string{"1"})
|
||||
}
|
||||
|
||||
func TestAutoImportDefaultPascalCaseAliasCaseInsensitive(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @jsx: react
|
||||
// @module: esnext
|
||||
// @moduleResolution: bundler
|
||||
// @useCaseSensitiveFileNames: false
|
||||
|
||||
// @Filename: /src/components/ChargerHeader.tsx
|
||||
function ChargerHeader() {
|
||||
return null;
|
||||
}
|
||||
export default ChargerHeader;
|
||||
|
||||
// @Filename: /src/screens/SomeScreen.tsx
|
||||
export function SomeScreen() {
|
||||
return <ChargerHeader/*1*/
|
||||
}
|
||||
`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyCompletions(t, "1", &fourslash.CompletionsExpectedList{
|
||||
UserPreferences: &lsutil.UserPreferences{
|
||||
IncludeCompletionsForModuleExports: core.TSTrue,
|
||||
IncludeCompletionsForImportStatements: core.TSTrue,
|
||||
},
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
EditRange: Ignored,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{"ChargerHeader"},
|
||||
},
|
||||
})
|
||||
f.BaselineAutoImportsCompletions(t, []string{"1"})
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestAutoImportErrorMixedExportKinds(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @Filename: a.ts
|
||||
export function foo(): number {
|
||||
return 10
|
||||
}
|
||||
|
||||
const bar = 20;
|
||||
export { bar as foo };
|
||||
|
||||
// @Filename: b.ts
|
||||
foo/**/
|
||||
`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
// Verify we don't crash from the mixed exports
|
||||
f.BaselineAutoImportsCompletions(t, []string{""})
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestAutoImportExportEqualsOfImportStar(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @module: commonjs
|
||||
// @Filename: /node_modules/mdx/package.json
|
||||
{ "name": "mdx", "version": "1.0.0", "types": "index.d.ts" }
|
||||
// @Filename: /node_modules/mdx/index.d.ts
|
||||
import * as mdx from './lib/index.js'
|
||||
|
||||
export = mdx
|
||||
// @Filename: /node_modules/mdx/lib/index.d.ts
|
||||
export * from './core.js'
|
||||
export * from './compile.js'
|
||||
// @Filename: /node_modules/mdx/lib/core.d.ts
|
||||
export declare function core(): void
|
||||
// @Filename: /node_modules/mdx/lib/compile.d.ts
|
||||
export declare function compile(): void
|
||||
// @Filename: /package.json
|
||||
{ "dependencies": { "mdx": "*" } }
|
||||
// @Filename: /index.ts
|
||||
mdx/**/`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.GoToMarker(t, "")
|
||||
f.BaselineAutoImportsCompletions(t, []string{""})
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/core"
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
. "github.com/microsoft/typescript-go/internal/fourslash/tests/util"
|
||||
"github.com/microsoft/typescript-go/internal/ls/lsutil"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestAutoImportFileExcludePatterns(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @Filename: foo.ts
|
||||
export const mySymbol = 1;
|
||||
// @Filename: ignoreme.ts
|
||||
export const ignoredSymbol = 2;
|
||||
// @Filename: bar.ts
|
||||
mySym/*1*/
|
||||
ignoredSym/*2*/`
|
||||
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.Configure(t, lsutil.UserPreferences{
|
||||
AutoImportFileExcludePatterns: []string{"*ignoreme.ts"},
|
||||
IncludeCompletionsForModuleExports: core.TSTrue,
|
||||
IncludeCompletionsForImportStatements: core.TSTrue,
|
||||
})
|
||||
|
||||
// Verify that mySymbol is included, but ignoredSymbol is excluded from completions
|
||||
f.VerifyCompletions(t, "1", &fourslash.CompletionsExpectedList{
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
EditRange: Ignored,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{"mySymbol"},
|
||||
},
|
||||
})
|
||||
f.VerifyCompletions(t, "2", &fourslash.CompletionsExpectedList{
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
EditRange: Ignored,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Excludes: []string{"ignoredSymbol"},
|
||||
},
|
||||
})
|
||||
|
||||
// Baseline the auto-imports
|
||||
f.BaselineAutoImportsCompletions(t, []string{"1", "2"})
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestAutoImportModuleAugmentation(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @Filename: /a.ts
|
||||
export interface Foo {
|
||||
x: number;
|
||||
}
|
||||
|
||||
// @Filename: /b.ts
|
||||
export {};
|
||||
declare module "./a" {
|
||||
export const Foo: any;
|
||||
}
|
||||
|
||||
// @Filename: /c.ts
|
||||
Foo/**/
|
||||
`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.BaselineAutoImportsCompletions(t, []string{""})
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestAutoImportNewLine(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @Filename: /a.ts
|
||||
export function readFileSync() {}
|
||||
|
||||
// @Filename: /b.ts
|
||||
import {} from "./other1";
|
||||
import {} from "./other2";
|
||||
|
||||
|
||||
readFileSync/**/`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.BaselineAutoImportsCompletions(t, []string{""})
|
||||
}
|
||||
|
||||
func TestAutoImportNewLineWithHeaderComment(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @Filename: /a.ts
|
||||
export function readFileSync() {}
|
||||
|
||||
// @Filename: /b.ts
|
||||
/* file header comment */
|
||||
import {} from "./other1";
|
||||
import {} from "./other2";
|
||||
|
||||
|
||||
readFileSync/**/`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.BaselineAutoImportsCompletions(t, []string{""})
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
. "github.com/microsoft/typescript-go/internal/fourslash/tests/util"
|
||||
"github.com/microsoft/typescript-go/internal/ls"
|
||||
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
// TestAutoImportNodeBuiltinNodenext is a regression test for
|
||||
// https://github.com/microsoft/typescript-go/issues/2555, where auto-imports
|
||||
// for Node.js built-in modules (e.g. "fs") were not appearing when using
|
||||
// module: nodenext and types: ["node"].
|
||||
func TestAutoImportNodeBuiltinNodenext(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @Filename: /tsconfig.json
|
||||
{ "compilerOptions": { "module": "nodenext", "types": ["node"] } }
|
||||
// @Filename: /package.json
|
||||
{ "type": "module" }
|
||||
// @Filename: /node_modules/@types/node/package.json
|
||||
{ "name": "@types/node", "version": "22.0.0" }
|
||||
// @Filename: /node_modules/@types/node/index.d.ts
|
||||
declare module "fs" {
|
||||
export function existsSync(path: string): boolean;
|
||||
export function mkdirSync(path: string, options?: { recursive?: boolean }): void;
|
||||
}
|
||||
declare module "node:fs" { export * from "fs"; }
|
||||
// @Filename: /index.ts
|
||||
existsSync/**/`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyCompletions(t, "", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
EditRange: Ignored,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{
|
||||
&lsproto.CompletionItem{
|
||||
Label: "existsSync",
|
||||
Data: &lsproto.CompletionItemData{
|
||||
AutoImport: &lsproto.AutoImportFix{
|
||||
ModuleSpecifier: "node:fs",
|
||||
},
|
||||
},
|
||||
AdditionalTextEdits: fourslash.AnyTextEdits,
|
||||
SortText: new(string(ls.SortTextAutoImportSuggestions)),
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestAutoImportPackageJsonImportsHashSlashNodenext(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @Filename: /tsconfig.json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "nodenext",
|
||||
"rootDir": "./",
|
||||
"outDir": "build"
|
||||
}
|
||||
}
|
||||
// @Filename: /package.json
|
||||
{
|
||||
"imports": {
|
||||
"#/*": {
|
||||
"types": "./src/*",
|
||||
"default": "./src/*"
|
||||
}
|
||||
}
|
||||
}
|
||||
// @Filename: /src/domain/entities/entity.ts
|
||||
export const entity = 1;
|
||||
// @Filename: /src/features/deep/consumer.ts
|
||||
entit/**/`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.BaselineAutoImportsCompletions(t, []string{""})
|
||||
}
|
||||
|
||||
func TestAutoImportPackageJsonImportsHashSlashNode16(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @Filename: /tsconfig.json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "node16"
|
||||
}
|
||||
}
|
||||
// @Filename: /package.json
|
||||
{
|
||||
"imports": {
|
||||
"#/*": "./src/*"
|
||||
}
|
||||
}
|
||||
// @Filename: /src/domain/entities/entity.ts
|
||||
export const entity = 1;
|
||||
// @Filename: /src/consumer.ts
|
||||
entit/**/`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.BaselineAutoImportsCompletions(t, []string{""})
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestAutoImportQuoteDetection(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @module: esnext
|
||||
// @Filename: /a.ts
|
||||
export const foo = 0;
|
||||
// @Filename: /b.ts
|
||||
import {} from 'node:path';
|
||||
|
||||
fo/**/`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.GoToMarker(t, "")
|
||||
f.VerifyApplyCodeActionFromCompletion(t, new(""), &fourslash.ApplyCodeActionFromCompletionOptions{
|
||||
Name: "foo",
|
||||
Source: "./a",
|
||||
Description: "Add import from \"./a\"",
|
||||
NewFileContent: new(`import {} from 'node:path';
|
||||
import { foo } from './a';
|
||||
|
||||
fo`),
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/core"
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/ls/lsutil"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
// TestAutoImportReexportOfCrossPackageAugmentation verifies no crash when auto-importing
|
||||
// from a package that re-exports from another package that is also augmented.
|
||||
func TestAutoImportReexportOfCrossPackageAugmentation(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @Filename: /node_modules/vitest/package.json
|
||||
{ "name": "vitest", "version": "1.0.0", "types": "index.d.ts" }
|
||||
// @Filename: /node_modules/vitest/index.d.ts
|
||||
export { AugmentedInterface, uniqueFunction } from "@vitest/expect";
|
||||
// @Filename: /node_modules/vitest/augmentation.d.ts
|
||||
export {};
|
||||
declare module "@vitest/expect" {
|
||||
interface AugmentedInterface {
|
||||
bar: string;
|
||||
}
|
||||
function uniqueFunction(): void;
|
||||
}
|
||||
// @Filename: /node_modules/@vitest/expect/package.json
|
||||
{ "name": "@vitest/expect", "version": "1.0.0", "types": "index.d.ts" }
|
||||
// @Filename: /node_modules/@vitest/expect/index.d.ts
|
||||
export interface AugmentedInterface {
|
||||
baz: number;
|
||||
}
|
||||
// @Filename: /tsconfig.json
|
||||
{ "compilerOptions": { "module": "commonjs", "strict": true } }
|
||||
// @Filename: /package.json
|
||||
{ "name": "test", "dependencies": { "vitest": "*" } }
|
||||
// @Filename: /index.ts
|
||||
uniqueFunction/**/`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
|
||||
prefs := lsutil.NewDefaultUserPreferences()
|
||||
prefs.AutoImportEntrypointDirectorySearch = core.TSTrue
|
||||
f.Configure(t, prefs)
|
||||
f.GoToMarker(t, "")
|
||||
f.BaselineAutoImportsCompletions(t, []string{""})
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/core"
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
. "github.com/microsoft/typescript-go/internal/fourslash/tests/util"
|
||||
"github.com/microsoft/typescript-go/internal/ls/lsutil"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestAutoImportSpecifierExcludeRegexes(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @Filename: foo.ts
|
||||
export const mySymbol = 1;
|
||||
// @Filename: ignoreme.ts
|
||||
export const ignoredSymbol = 2;
|
||||
// @Filename: bar.ts
|
||||
mySym/*1*/
|
||||
ignoredSym/*2*/`
|
||||
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.Configure(t, lsutil.UserPreferences{
|
||||
AutoImportSpecifierExcludeRegexes: []string{".*ignoreme.*"},
|
||||
IncludeCompletionsForModuleExports: core.TSTrue,
|
||||
IncludeCompletionsForImportStatements: core.TSTrue,
|
||||
})
|
||||
|
||||
// Verify that mySymbol is included, but ignoredSymbol is excluded from completions
|
||||
f.VerifyCompletions(t, "1", &fourslash.CompletionsExpectedList{
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
EditRange: Ignored,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{"mySymbol"},
|
||||
},
|
||||
})
|
||||
f.VerifyCompletions(t, "2", &fourslash.CompletionsExpectedList{
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
EditRange: Ignored,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Excludes: []string{"ignoredSymbol"},
|
||||
},
|
||||
})
|
||||
|
||||
// Baseline the auto-imports
|
||||
f.BaselineAutoImportsCompletions(t, []string{"1", "2"})
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
// TestAutoImportSymlinkedMonorepoGranularUpdate verifies that when a file in a symlinked
|
||||
// project reference is edited, the auto-import index is updated efficiently via granular
|
||||
// updates rather than rebuilding the entire node_modules bucket.
|
||||
//
|
||||
// Scenario:
|
||||
// - project-a references project-b via project references (tsconfig)
|
||||
// - project-b is symlinked into project-a's node_modules
|
||||
// - Initially, project-b exports projectBValue
|
||||
// - We get completions in project-a (builds the initial index)
|
||||
// - We edit project-b to add a new export (newlyAddedFunction)
|
||||
// - We get completions again in project-a
|
||||
// - The new export should be available, proving the granular update worked
|
||||
func TestAutoImportSymlinkedMonorepoGranularUpdate(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @Filename: /packages/project-b/tsconfig.json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src",
|
||||
"declaration": true,
|
||||
"module": "commonjs",
|
||||
"strict": true
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
// @Filename: /packages/project-b/package.json
|
||||
{
|
||||
"name": "project-b",
|
||||
"version": "1.0.0",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"default": "./dist/index.js"
|
||||
}
|
||||
}
|
||||
}
|
||||
// @Filename: /packages/project-b/src/index.ts
|
||||
export const projectBValue: number = 42;
|
||||
/*projectBEdit*/
|
||||
// @Filename: /packages/project-b/dist/index.d.ts
|
||||
export declare const projectBValue: number;
|
||||
// @Filename: /packages/project-a/tsconfig.json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"strict": true,
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src"
|
||||
},
|
||||
"include": ["src"],
|
||||
"references": [{ "path": "../project-b" }]
|
||||
}
|
||||
// @Filename: /packages/project-a/package.json
|
||||
{ "name": "project-a", "dependencies": { "project-b": "*" } }
|
||||
// @Filename: /packages/project-a/src/index.ts
|
||||
import { projectBValue } from "project-b";
|
||||
console.log(projectBValue);
|
||||
newlyAdded/*projectACompletion*/
|
||||
// @link: /packages/project-b -> /packages/project-a/node_modules/project-b`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
|
||||
// Get initial completions in project-a - this builds the initial auto-import index.
|
||||
// At this point, newlyAddedFunction doesn't exist yet in project-b.
|
||||
f.GoToMarker(t, "projectACompletion")
|
||||
f.BaselineAutoImportsCompletions(t, []string{"projectACompletion"})
|
||||
|
||||
// Now edit project-b's source file to add a new export.
|
||||
// This should trigger a granular update when we request completions again.
|
||||
f.GoToMarker(t, "projectBEdit")
|
||||
f.Insert(t, "\nexport function newlyAddedFunction(): void {}")
|
||||
|
||||
// Go back to project-a and request completions again.
|
||||
// The granular update should have picked up the new export from project-b.
|
||||
f.GoToMarker(t, "projectACompletion")
|
||||
f.BaselineAutoImportsCompletions(t, []string{"projectACompletion"})
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
// TestAutoImportSymlinkedMonorepoProjectReferencesNoPkgExports verifies deduplication
|
||||
// when a monorepo package has both src and dist files, uses project references,
|
||||
// but does NOT have package.json "exports" to limit what files are discovered.
|
||||
//
|
||||
// Scenario:
|
||||
// - project-a references project-b via project references (tsconfig)
|
||||
// - project-b is also symlinked into project-a's node_modules
|
||||
// - project-b has both src/index.ts and dist/index.d.ts
|
||||
// - package.json does NOT have "exports", so node_modules search finds BOTH src and dist
|
||||
// - The program resolves imports to src files via project reference mapping
|
||||
// - We should NOT see duplicate auto-imports (one from src, one from dist)
|
||||
func TestAutoImportSymlinkedMonorepoProjectReferencesNoPkgExports(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @Filename: /packages/project-b/tsconfig.json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src",
|
||||
"declaration": true,
|
||||
"module": "commonjs",
|
||||
"strict": true
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
// @Filename: /packages/project-b/package.json
|
||||
{
|
||||
"name": "project-b",
|
||||
"version": "1.0.0",
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.d.ts"
|
||||
}
|
||||
// @Filename: /packages/project-b/src/index.ts
|
||||
export const projectBValue: number = 42;
|
||||
export function projectBFunction(): string { return "hello"; }
|
||||
// @Filename: /packages/project-b/dist/index.d.ts
|
||||
export declare const projectBValue: number;
|
||||
export declare function projectBFunction(): string;
|
||||
// @Filename: /packages/project-a/tsconfig.json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"strict": true,
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src"
|
||||
},
|
||||
"include": ["src"],
|
||||
"references": [{ "path": "../project-b" }]
|
||||
}
|
||||
// @Filename: /packages/project-a/package.json
|
||||
{ "name": "project-a", "dependencies": { "project-b": "*" } }
|
||||
// @Filename: /packages/project-a/src/index.ts
|
||||
import { projectBValue } from "project-b";
|
||||
console.log(projectBValue);
|
||||
projectBFunc/**/
|
||||
// @link: /packages/project-b -> /packages/project-a/node_modules/project-b`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
|
||||
f.GoToMarker(t, "")
|
||||
// This should show projectBFunction once, not twice (not from both src and dist)
|
||||
f.BaselineAutoImportsCompletions(t, []string{""})
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
// TestAutoImportSymlinkedMonorepoProjectReferences verifies that when a monorepo package
|
||||
// is symlinked into node_modules and has both src and dist files with project references,
|
||||
// auto-imports don't show duplicates.
|
||||
//
|
||||
// Scenario:
|
||||
// - project-a references project-b via project references (tsconfig)
|
||||
// - project-b is also symlinked into project-a's node_modules
|
||||
// - project-b has both src/index.ts and dist/index.d.ts
|
||||
// - package.json "exports" points to dist files
|
||||
// - The node_modules bucket finds dist/.d.ts files
|
||||
// - The program resolves to src files via project reference mapping
|
||||
// - We should NOT see duplicate auto-imports (one from src, one from dist)
|
||||
func TestAutoImportSymlinkedMonorepoProjectReferences(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @Filename: /packages/project-b/tsconfig.json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src",
|
||||
"declaration": true,
|
||||
"module": "commonjs",
|
||||
"strict": true
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
// @Filename: /packages/project-b/package.json
|
||||
{
|
||||
"name": "project-b",
|
||||
"version": "1.0.0",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"default": "./dist/index.js"
|
||||
}
|
||||
}
|
||||
}
|
||||
// @Filename: /packages/project-b/src/index.ts
|
||||
export const projectBValue: number = 42;
|
||||
export function projectBFunction(): string { return "hello"; }
|
||||
// @Filename: /packages/project-b/dist/index.d.ts
|
||||
export declare const projectBValue: number;
|
||||
export declare function projectBFunction(): string;
|
||||
// @Filename: /packages/project-a/tsconfig.json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"strict": true,
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src"
|
||||
},
|
||||
"include": ["src"],
|
||||
"references": [{ "path": "../project-b" }]
|
||||
}
|
||||
// @Filename: /packages/project-a/package.json
|
||||
{ "name": "project-a", "dependencies": { "project-b": "*" } }
|
||||
// @Filename: /packages/project-a/src/index.ts
|
||||
import { projectBValue } from "project-b";
|
||||
console.log(projectBValue);
|
||||
projectBFunc/**/
|
||||
// @link: /packages/project-b -> /packages/project-a/node_modules/project-b`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
|
||||
f.GoToMarker(t, "")
|
||||
// This should show projectBFunction once, not twice (not from both src and dist)
|
||||
f.BaselineAutoImportsCompletions(t, []string{""})
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/core"
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/ls/lsutil"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
// TestAutoImportSymlinkedMonorepoReexport verifies deduplication when a monorepo
|
||||
// package re-exports symbols from deeper files via `export *`.
|
||||
//
|
||||
// Scenario:
|
||||
// - project-a references project-b via project references (tsconfig)
|
||||
// - project-b is symlinked into project-a's node_modules
|
||||
// - project-b has src/utils/foo.ts with the actual export
|
||||
// - project-b has src/index.ts with `export * from './utils/foo'`
|
||||
// - The Export's Path field points to src/utils/foo.ts (where symbol is defined)
|
||||
// - This path must also go through realpath normalization for deduplication
|
||||
// - We should NOT see duplicate auto-imports
|
||||
func TestAutoImportSymlinkedMonorepoReexport(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @Filename: /packages/project-b/tsconfig.json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src",
|
||||
"declaration": true,
|
||||
"module": "commonjs",
|
||||
"strict": true
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
// @Filename: /packages/project-b/package.json
|
||||
{
|
||||
"name": "project-b",
|
||||
"version": "1.0.0",
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.d.ts"
|
||||
}
|
||||
// @Filename: /packages/project-b/src/utils/foo.ts
|
||||
export function projectBFunction(): string { return "hello"; }
|
||||
// @Filename: /packages/project-b/src/index.ts
|
||||
export * from './utils/foo';
|
||||
export const projectBValue: number = 42;
|
||||
// @Filename: /packages/project-b/dist/utils/foo.d.ts
|
||||
export declare function projectBFunction(): string;
|
||||
// @Filename: /packages/project-b/dist/index.d.ts
|
||||
export * from './utils/foo';
|
||||
export declare const projectBValue: number;
|
||||
// @Filename: /packages/project-a/tsconfig.json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"strict": true,
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src"
|
||||
},
|
||||
"include": ["src"],
|
||||
"references": [{ "path": "../project-b" }]
|
||||
}
|
||||
// @Filename: /packages/project-a/package.json
|
||||
{ "name": "project-a", "dependencies": { "project-b": "*" } }
|
||||
// @Filename: /packages/project-a/src/index.ts
|
||||
import { projectBValue } from "project-b";
|
||||
console.log(projectBValue);
|
||||
projectBFunction/**/
|
||||
// @link: /packages/project-b -> /packages/project-a/node_modules/project-b`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
|
||||
prefs := lsutil.NewDefaultUserPreferences()
|
||||
prefs.AutoImportEntrypointDirectorySearch = core.TSTrue
|
||||
f.Configure(t, prefs)
|
||||
f.GoToMarker(t, "")
|
||||
// This should show projectBFunction once via re-export and once via direct import, not duplicates
|
||||
f.VerifyImportFixAtPosition(t, []string{
|
||||
`import { projectBFunction, projectBValue } from "project-b";
|
||||
console.log(projectBValue);
|
||||
projectBFunction`,
|
||||
`import { projectBValue } from "project-b";
|
||||
import { projectBFunction } from "project-b/src/utils/foo";
|
||||
console.log(projectBValue);
|
||||
projectBFunction`,
|
||||
}, nil /*preferences*/)
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
const TestAutoImportSymlinkedMonorepoSourceUpdateScenario = `
|
||||
// @Filename: /home/src/workspaces/project/tsconfig.base.json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "nodenext",
|
||||
"moduleResolution": "nodenext",
|
||||
"composite": true
|
||||
}
|
||||
}
|
||||
|
||||
// @Filename: /home/src/workspaces/project/packages/foo/package.json
|
||||
{
|
||||
"name": "@packages/foo",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./src/index.ts",
|
||||
"default": "./dist/index.js"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// @Filename: /home/src/workspaces/project/packages/foo/tsconfig.json
|
||||
{ "extends": "../../tsconfig.base.json" }
|
||||
|
||||
// @Filename: /home/src/workspaces/project/packages/foo/src/index.ts
|
||||
/*fooEdit*/
|
||||
|
||||
// @Filename: /home/src/workspaces/project/packages/bar/package.json
|
||||
{
|
||||
"name": "@packages/bar",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./src/index.ts",
|
||||
"default": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@packages/foo": "*"
|
||||
}
|
||||
}
|
||||
|
||||
// @Filename: /home/src/workspaces/project/packages/bar/tsconfig.json
|
||||
{ "extends": "../../tsconfig.base.json" }
|
||||
|
||||
// @Filename: /home/src/workspaces/project/packages/bar/src/index.ts
|
||||
/*fooCompletion*/
|
||||
|
||||
// @Filename: /home/src/workspaces/project/package.json
|
||||
{ "workspaces": ["packages/*"], "type": "module" }
|
||||
|
||||
// @link: /home/src/workspaces/project/packages/bar -> /home/src/workspaces/project/node_modules/@packages/bar
|
||||
// @link: /home/src/workspaces/project/packages/foo -> /home/src/workspaces/project/node_modules/@packages/foo
|
||||
`
|
||||
|
||||
func TestAutoImportSymlinkedMonorepoSourceUpdate(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, TestAutoImportSymlinkedMonorepoSourceUpdateScenario)
|
||||
|
||||
defer done()
|
||||
|
||||
// Force auto import to build the cache (no exports yet).
|
||||
f.GoToMarker(t, "fooCompletion")
|
||||
f.BaselineAutoImportsCompletions(t, []string{"fooCompletion"})
|
||||
|
||||
// Add a new export to the symlinked source package.
|
||||
f.GoToMarker(t, "fooEdit")
|
||||
f.Insert(t, "\nexport function foo() {}")
|
||||
|
||||
// The new export should appear via granular cache update.
|
||||
f.GoToMarker(t, "fooCompletion")
|
||||
f.BaselineAutoImportsCompletions(t, []string{"fooCompletion"})
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
// TestAutoImportSymlinkedMonorepo verifies that when a monorepo package is symlinked
|
||||
// into node_modules and imported, auto-imports don't show duplicates.
|
||||
//
|
||||
// Scenario:
|
||||
// - project-a imports "project-b" via a symlink in node_modules
|
||||
// - project-b's source files are at /packages/project-b but symlinked to
|
||||
// /packages/project-a/node_modules/project-b
|
||||
// - The program contains project-b files via realpath, AND the symlink exists in node_modules
|
||||
// - We should NOT see duplicate auto-imports for project-b exports
|
||||
func TestAutoImportSymlinkedMonorepo(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @Filename: /packages/project-b/package.json
|
||||
{ "name": "project-b", "version": "1.0.0", "main": "index.js", "types": "index.d.ts" }
|
||||
// @Filename: /packages/project-b/index.d.ts
|
||||
export declare const projectBValue: number;
|
||||
export declare function projectBFunction(): string;
|
||||
// @Filename: /packages/project-a/tsconfig.json
|
||||
{ "compilerOptions": { "module": "commonjs", "strict": true } }
|
||||
// @Filename: /packages/project-a/package.json
|
||||
{ "name": "project-a", "dependencies": { "project-b": "*" } }
|
||||
// @Filename: /packages/project-a/index.ts
|
||||
import { projectBValue } from "project-b";
|
||||
console.log(projectBValue);
|
||||
projectBFunc/**/
|
||||
// @link: /packages/project-b -> /packages/project-a/node_modules/project-b`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
|
||||
f.GoToMarker(t, "")
|
||||
// This should show projectBFunction once, not twice
|
||||
f.BaselineAutoImportsCompletions(t, []string{""})
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
. "github.com/microsoft/typescript-go/internal/fourslash/tests/util"
|
||||
"github.com/microsoft/typescript-go/internal/ls"
|
||||
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
const TestAutoImportTransitiveLeakScenario = `
|
||||
// @Filename: /home/src/workspaces/project/tsconfig.base.json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "nodenext",
|
||||
"moduleResolution": "nodenext",
|
||||
"composite": true
|
||||
}
|
||||
}
|
||||
|
||||
// @Filename: /home/src/workspaces/project/packages/foo/package.json
|
||||
{
|
||||
"name": "@packages/foo",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./src/index.ts",
|
||||
"default": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"imports": {
|
||||
"#*": {
|
||||
"types": "./src/*.ts",
|
||||
"default": "./dist/*.js"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// @Filename: /home/src/workspaces/project/packages/foo/tsconfig.json
|
||||
{ "extends": "../../tsconfig.base.json" }
|
||||
|
||||
// @Filename: /home/src/workspaces/project/packages/foo/src/internal/index.ts
|
||||
export function fooInternal() {
|
||||
console.log("foo");
|
||||
}
|
||||
|
||||
// @Filename: /home/src/workspaces/project/packages/foo/src/index.ts
|
||||
import { fooInternal } from "#internal/index"
|
||||
export function foo() {
|
||||
fooInternal();
|
||||
}
|
||||
|
||||
// @Filename: /home/src/workspaces/project/packages/bar/package.json
|
||||
{
|
||||
"name": "@packages/bar",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./src/index.ts",
|
||||
"default": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"imports": {
|
||||
"#*": {
|
||||
"types": "./src/*.ts",
|
||||
"default": "./dist/*.js"
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@packages/foo": "*"
|
||||
}
|
||||
}
|
||||
|
||||
// @Filename: /home/src/workspaces/project/packages/bar/tsconfig.json
|
||||
{ "extends": "../../tsconfig.base.json" }
|
||||
|
||||
// @Filename: /home/src/workspaces/project/packages/bar/src/index.ts
|
||||
import { foo } from "@packages/foo"
|
||||
|
||||
fo/*fooCompletion*/
|
||||
|
||||
// @Filename: /home/src/workspaces/project/package.json
|
||||
{ "workspaces": ["packages/*"], "type": "module" }
|
||||
|
||||
// @link: /home/src/workspaces/project/packages/bar -> /home/src/workspaces/project/node_modules/@packages/bar
|
||||
// @link: /home/src/workspaces/project/packages/foo -> /home/src/workspaces/project/node_modules/@packages/foo
|
||||
`
|
||||
|
||||
func TestAutoImportTransitiveLeak(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, TestAutoImportTransitiveLeakScenario)
|
||||
|
||||
defer done()
|
||||
|
||||
f.VerifyCompletions(t, "fooCompletion", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
EditRange: Ignored,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{
|
||||
&lsproto.CompletionItem{
|
||||
Label: "foo",
|
||||
AdditionalTextEdits: fourslash.AnyTextEdits,
|
||||
SortText: new(string(ls.SortTextLocationPriority)),
|
||||
},
|
||||
},
|
||||
Excludes: []string{"fooInternal"},
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestAutoImportTypedefMissingName(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @allowJs: true
|
||||
// @checkJs: true
|
||||
// @Filename: /utils.js
|
||||
/** @typedef {{ x: number }} */
|
||||
|
||||
export function doSomething() {}
|
||||
// @Filename: /index.ts
|
||||
doSomething/**/`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.GoToMarker(t, "")
|
||||
f.BaselineAutoImportsCompletions(t, []string{""})
|
||||
}
|
||||
43
tools/tsgo/internal/fourslash/tests/basicBackspace_test.go
Normal file
43
tools/tsgo/internal/fourslash/tests/basicBackspace_test.go
Normal file
@@ -0,0 +1,43 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
. "github.com/microsoft/typescript-go/internal/fourslash/tests/util"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestBasicBackspace(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `export {};
|
||||
interface Point {
|
||||
x: number;
|
||||
y: number;/*b*/
|
||||
}
|
||||
declare const p: Point;
|
||||
p./*a*/`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyCompletions(t, "a", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{"y"},
|
||||
},
|
||||
})
|
||||
f.GoToMarker(t, "b")
|
||||
f.Backspace(t, 10) // `y: number;`
|
||||
f.VerifyCompletions(t, "a", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Excludes: []string{"y"},
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
. "github.com/microsoft/typescript-go/internal/fourslash/tests/util"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestBasicClassElementKeywords(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `class C {
|
||||
/*a*/
|
||||
}`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyCompletions(t, "a", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &[]string{},
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Exact: CompletionClassElementKeywords,
|
||||
},
|
||||
})
|
||||
}
|
||||
44
tools/tsgo/internal/fourslash/tests/basicEdit_test.go
Normal file
44
tools/tsgo/internal/fourslash/tests/basicEdit_test.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
. "github.com/microsoft/typescript-go/internal/fourslash/tests/util"
|
||||
"github.com/microsoft/typescript-go/internal/ls"
|
||||
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestBasicEdit(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `export {};
|
||||
interface Point {
|
||||
x: number;
|
||||
y: number;
|
||||
}
|
||||
declare const p: Point;
|
||||
p/*a*/`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.GoToMarker(t, "a")
|
||||
f.Insert(t, ".")
|
||||
f.GoToEOF(t)
|
||||
f.VerifyCompletions(t, nil, &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Exact: []fourslash.CompletionsExpectedItem{
|
||||
&lsproto.CompletionItem{
|
||||
Label: "x",
|
||||
Kind: new(lsproto.CompletionItemKindField),
|
||||
SortText: new(string(ls.SortTextLocationPriority)),
|
||||
},
|
||||
"y",
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
. "github.com/microsoft/typescript-go/internal/fourslash/tests/util"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestBasicGlobalCompletions(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @lib: es5
|
||||
/*1*/`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyCompletions(t, "1", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Exact: CompletionGlobals,
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
. "github.com/microsoft/typescript-go/internal/fourslash/tests/util"
|
||||
"github.com/microsoft/typescript-go/internal/ls"
|
||||
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestBasicInterfaceMembers(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `export {};
|
||||
interface Point {
|
||||
x: number;
|
||||
y: number;
|
||||
}
|
||||
declare const p: Point;
|
||||
p./*a*/`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyCompletions(t, "a", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Exact: []fourslash.CompletionsExpectedItem{
|
||||
&lsproto.CompletionItem{
|
||||
Label: "x",
|
||||
Kind: new(lsproto.CompletionItemKindField),
|
||||
SortText: new(string(ls.SortTextLocationPriority)),
|
||||
},
|
||||
"y",
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
. "github.com/microsoft/typescript-go/internal/fourslash/tests/util"
|
||||
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestBasicJSDocCompletions(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `
|
||||
// @filename: file.js
|
||||
// @allowJs: true
|
||||
/**
|
||||
* @/*1*/
|
||||
*/
|
||||
function foo(x) {
|
||||
return x + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* /*2*/
|
||||
*/
|
||||
function bar(x, { y }) {
|
||||
return x + y;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} x
|
||||
* /*3*/
|
||||
*/
|
||||
function baz(x, { y }) {
|
||||
return x + y;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} x
|
||||
* @param {object} param1
|
||||
* @param {n/*4*/} param1.y
|
||||
*/
|
||||
function baz(x, { y }) {
|
||||
return x + y;
|
||||
}
|
||||
|
||||
/**
|
||||
* @/*5*/
|
||||
*/
|
||||
function baz(x = 0) {
|
||||
return x * 2;
|
||||
}
|
||||
`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyCompletions(t, "1", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{
|
||||
&lsproto.CompletionItem{
|
||||
Label: "link",
|
||||
Kind: new(lsproto.CompletionItemKindKeyword),
|
||||
Detail: new("link"),
|
||||
},
|
||||
"param",
|
||||
"returns",
|
||||
"param {*} x ",
|
||||
},
|
||||
},
|
||||
})
|
||||
f.VerifyCompletions(t, "2", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{
|
||||
"@param",
|
||||
"@param {*} x ",
|
||||
},
|
||||
},
|
||||
})
|
||||
f.VerifyCompletions(t, "3", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{
|
||||
"@param",
|
||||
"@param {object} param1 \n* @param {*} param1.y ",
|
||||
},
|
||||
},
|
||||
})
|
||||
f.VerifyCompletions(t, "4", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
EditRange: Ignored,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{
|
||||
"number",
|
||||
},
|
||||
},
|
||||
})
|
||||
f.VerifyCompletions(t, "5", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
EditRange: Ignored,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{
|
||||
"param {number} [x=0] ",
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
. "github.com/microsoft/typescript-go/internal/fourslash/tests/util"
|
||||
"github.com/microsoft/typescript-go/internal/ls"
|
||||
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestBasicMultifileCompletions(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @Filename: /a.ts
|
||||
export const foo = { bar: 'baz' };
|
||||
|
||||
// @Filename: /b.ts
|
||||
import { foo } from './a';
|
||||
const test = foo./*1*/`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyCompletions(t, "1", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{
|
||||
&lsproto.CompletionItem{
|
||||
Label: "bar",
|
||||
Kind: new(lsproto.CompletionItemKindField),
|
||||
SortText: new(string(ls.SortTextLocationPriority)),
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
33
tools/tsgo/internal/fourslash/tests/basicQuickInfo_test.go
Normal file
33
tools/tsgo/internal/fourslash/tests/basicQuickInfo_test.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestBasicQuickInfo(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `
|
||||
/**
|
||||
* Some var
|
||||
*/
|
||||
var someVar/*1*/ = 123;
|
||||
|
||||
/**
|
||||
* Other var
|
||||
* See {@link someVar}
|
||||
*/
|
||||
var otherVar/*2*/ = someVar;
|
||||
|
||||
class Foo/*3*/ {
|
||||
#bar: string;
|
||||
}
|
||||
`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyQuickInfoAt(t, "1", "var someVar: number", "Some var")
|
||||
f.VerifyQuickInfoAt(t, "2", "var otherVar: number", "Other var\nSee [someVar](file:///basicQuickInfo.ts#5,5-5,12)")
|
||||
}
|
||||
43
tools/tsgo/internal/fourslash/tests/basicReplaceLine_test.go
Normal file
43
tools/tsgo/internal/fourslash/tests/basicReplaceLine_test.go
Normal file
@@ -0,0 +1,43 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
. "github.com/microsoft/typescript-go/internal/fourslash/tests/util"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestBasicReplaceLine(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `export {};
|
||||
interface Point {
|
||||
x: number;
|
||||
y: number;
|
||||
}
|
||||
declare const p: Point;
|
||||
p./*a*/`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyCompletions(t, "a", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{"y"},
|
||||
},
|
||||
})
|
||||
f.ReplaceLine(t, 3, " z: number;") // `y: number;`
|
||||
f.VerifyCompletions(t, "a", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Excludes: []string{"y"},
|
||||
Includes: []fourslash.CompletionsExpectedItem{"z"},
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCallHierarchyAnonymousClassNoCrash1(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @Filename: /main.ts
|
||||
class {
|
||||
con/*1*/structor() {}
|
||||
}`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.GoToMarker(t, "1")
|
||||
f.VerifyBaselineCallHierarchy(t)
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCallHierarchyAnonymousClassNoCrash2(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @Filename: /main.ts
|
||||
(class {
|
||||
con/*1*/structor() {}
|
||||
})`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.GoToMarker(t, "1")
|
||||
f.VerifyBaselineCallHierarchy(t)
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCallHierarchyAnonymousClassNoCrash3(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @Filename: /main.ts
|
||||
import Bar from "./other";
|
||||
|
||||
function foo() {
|
||||
new /*1*/Bar();
|
||||
}
|
||||
// @Filename: /other.ts
|
||||
export default class {
|
||||
constructor() {}
|
||||
}`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.GoToMarker(t, "1")
|
||||
f.VerifyBaselineCallHierarchy(t)
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCallHierarchyAnonymousFunctionNoCrash1(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @Filename: /main.ts
|
||||
func/*1*/tion() {}`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.GoToMarker(t, "1")
|
||||
f.VerifyBaselineCallHierarchy(t)
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCallHierarchyAnonymousFunctionNoCrash2(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @Filename: /main.ts
|
||||
(func/*1*/tion() {})`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.GoToMarker(t, "1")
|
||||
f.VerifyBaselineCallHierarchy(t)
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCallHierarchyAnonymousFunctionNoCrash3(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @Filename: /main.ts
|
||||
import bar from "./other";
|
||||
|
||||
function foo() {
|
||||
/*1*/bar();
|
||||
}
|
||||
// @Filename: /other.ts
|
||||
export default function() {}`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.GoToMarker(t, "1")
|
||||
f.VerifyBaselineCallHierarchy(t)
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCallHierarchyInPropDeclarationOfExportedDefaultClass1(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @Filename: /main.ts
|
||||
export default class {
|
||||
onSave = () => {
|
||||
const values = [];
|
||||
values./*m1*/push(1);
|
||||
};
|
||||
}
|
||||
`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.GoToMarker(t, "m1")
|
||||
f.VerifyBaselineCallHierarchy(t)
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCallHierarchyIncomingCallsNoCrashArrayPush(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `function splitNames(name: string) {
|
||||
return (name || "").split(",").filter(Boolean);
|
||||
}
|
||||
|
||||
async function trim(packageNames: string[]) {
|
||||
const nameOrPkgs = packageNames.filter(Boolean);
|
||||
const names = [];
|
||||
for (const nameOrPkg of nameOrPkgs) {
|
||||
try {
|
||||
names./*push*/push(nameOrPkg);
|
||||
} catch (error) {
|
||||
}
|
||||
}
|
||||
return names;
|
||||
}
|
||||
`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.GoToMarker(t, "push")
|
||||
f.VerifyBaselineCallHierarchy(t)
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCallHierarchyIncomingCallsObjectLiteralMethodInExpressionComputedProperty(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `const obj = {
|
||||
[1 + 2]: {
|
||||
method() {
|
||||
return ""./*split*/split(",");
|
||||
}
|
||||
}
|
||||
};
|
||||
`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.GoToMarker(t, "split")
|
||||
f.VerifyBaselineCallHierarchy(t)
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCallHierarchyIncomingCallsObjectLiteralMethodInIdentifierComputedProperty(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `const key = "x";
|
||||
const obj = {
|
||||
[key]: {
|
||||
method() {
|
||||
return ""./*split*/split(",");
|
||||
}
|
||||
}
|
||||
};
|
||||
`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.GoToMarker(t, "split")
|
||||
f.VerifyBaselineCallHierarchy(t)
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCallHierarchyIncomingCallsObjectLiteralMethodInStringLiteralComputedProperty(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `const obj = {
|
||||
["x"]: {
|
||||
method() {
|
||||
return ""./*split*/split(",");
|
||||
}
|
||||
}
|
||||
};
|
||||
`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.GoToMarker(t, "split")
|
||||
f.VerifyBaselineCallHierarchy(t)
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCallHierarchyUnclosedTemplateExprNoCrash1(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
// Regression test for a crash in prepareCallHierarchy caused by parser error
|
||||
// recovery: when a template expression is truncated mid-call (e.g. `${format`
|
||||
// without closing `)`), the parser misinterprets the `class` keyword in
|
||||
// subsequent HTML template literals as a TypeScript class declaration.
|
||||
// The resulting anonymous ClassDeclaration (no name, no `default` modifier)
|
||||
// previously caused a "Expected call hierarchy declaration to have a reference
|
||||
// node" assertion failure.
|
||||
const content = "// @Filename: /main.ts\n" +
|
||||
"function updateBadge() {\n" +
|
||||
" const header = `<div class=\"sub\">${format`;\n" +
|
||||
" const badge = `<div /*1*/class=\"badge\">`;\n" +
|
||||
"}"
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.GoToMarker(t, "1")
|
||||
f.VerifyBaselineCallHierarchy(t)
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestChineseCharacterDisplayInHover(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `
|
||||
interface 中文界面 {
|
||||
上居中: string;
|
||||
下居中: string;
|
||||
}
|
||||
|
||||
class 中文类 {
|
||||
获取中文属性(): 中文界面 {
|
||||
return {
|
||||
上居中: "上居中",
|
||||
下居中: "下居中"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
let /*instanceHover*/实例 = new 中文类();
|
||||
let 属性对象 = 实例./*methodHover*/获取中文属性();`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyQuickInfoAt(t, "instanceHover", "let 实例: 中文类", "")
|
||||
f.VerifyQuickInfoAt(t, "methodHover", "(method) 中文类.获取中文属性(): 中文界面", "")
|
||||
}
|
||||
|
||||
func TestChineseCharacterDisplayInUnionTypes(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `
|
||||
// Test the original issue: Chinese characters in method parameters should display correctly
|
||||
class TSLine {
|
||||
setLengthTextPositionPreset(/*methodParam*/preset: "上居中" | "下居中" | "右居中" | "左居中"): void {}
|
||||
}
|
||||
|
||||
let lines = new TSLine();
|
||||
lines./*method*/setLengthTextPositionPreset;`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
|
||||
// Verify that the method displays Chinese characters correctly in hover (this was the original problem)
|
||||
f.VerifyQuickInfoAt(t, "method", `(method) TSLine.setLengthTextPositionPreset(preset: "上居中" | "下居中" | "右居中" | "左居中"): void`, "")
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
// https://github.com/microsoft/typescript-go/issues/3944
|
||||
func TestCodeFixImportNonTextualSpecifierText(t *testing.T) {
|
||||
fourslash.SkipIfFailing(t)
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = "// @Filename: /a.ts\n" +
|
||||
"import type { A } from `./${myFolder}/${myFile}`;\n" +
|
||||
"\n" +
|
||||
"new A/**/()"
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.GoToMarker(t, "")
|
||||
f.VerifyImportFixAtPosition(t, []string{
|
||||
"import { A } from `./${myFolder}/${myFile}`;\n" +
|
||||
"\n" +
|
||||
"new A()",
|
||||
}, nil /*preferences*/)
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCodeFixMissingTypeAnnotationOnExports_arrowParensParamOnly(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @isolatedDeclarations: true
|
||||
// @declaration: true
|
||||
export const func = /*a*/x/*b*/ => 0;`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.GoToMarker(t, "a")
|
||||
f.VerifyCodeFix(t, fourslash.VerifyCodeFixOptions{
|
||||
Description: `Add annotation of type 'any'`,
|
||||
NewFileContent: `export const func = (x: any) => 0;`,
|
||||
ApplyChanges: true,
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCodeFixMissingTypeAnnotationOnExports_arrowParens(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @isolatedDeclarations: true
|
||||
// @declaration: true
|
||||
export const func = x => x.substring("foo");`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyCodeFixAll(t, fourslash.VerifyCodeFixAllOptions{
|
||||
FixID: "fixMissingTypeAnnotationOnExports",
|
||||
NewFileContent: `export const func = (x: any): any => x.substring("foo");`,
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCodeFixMissingTypeAnnotationOnExports_expandoNoDuplicates(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @declaration: true
|
||||
// @isolatedDeclarations: true
|
||||
// @Filename: /foo.mts
|
||||
export function foo(): void {
|
||||
}
|
||||
|
||||
foo.blah = 123;`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
|
||||
// Verify that only one code fix action is returned, not three identical ones.
|
||||
f.VerifyCodeFixAvailableExact(t, []string{
|
||||
"Annotate types of properties expando function in a namespace",
|
||||
})
|
||||
|
||||
f.VerifyCodeFix(t, fourslash.VerifyCodeFixOptions{
|
||||
Description: "Annotate types of properties expando function in a namespace",
|
||||
NewFileContent: `export function foo(): void {
|
||||
}
|
||||
export declare namespace foo {
|
||||
export var blah: number;
|
||||
}
|
||||
|
||||
foo.blah = 123;`,
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCodeFixMissingTypeAnnotationOnExports_jsxWhitespaceText(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
|
||||
const content = `// @isolatedDeclarations: true
|
||||
// @declaration: true
|
||||
// @module: preserve
|
||||
// @Filename: /test.tsx
|
||||
export const /**/elem = <div>
|
||||
<span />
|
||||
</div>;`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
|
||||
f.GoToMarker(t, "")
|
||||
f.VerifyCodeFixAvailable(t, nil)
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
// Test that auto-imports for JSX tags don't crash when React is type-imported.
|
||||
// When both the JSX namespace (React) and the component need to be imported,
|
||||
// getSymbolNamesToImport returns multiple names and the type-only promotion
|
||||
// path should handle this gracefully instead of panicking.
|
||||
func TestCodeFixPromoteTypeOnlyImportJsxTag(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @module: preserve
|
||||
// @verbatimModuleSyntax: true
|
||||
// @jsx: react
|
||||
// @Filename: /react.ts
|
||||
const React: any = {};
|
||||
export default React;
|
||||
// @Filename: /bar.tsx
|
||||
import type React from "./react";
|
||||
|
||||
<Foo/**/ />;`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.GoToMarker(t, "")
|
||||
// The fix should promote the type-only import of React to a regular import.
|
||||
// The "Cannot find name 'Foo'" error does not produce an auto-import for
|
||||
// React since it's already imported (as type-only, handled by promotion).
|
||||
f.VerifyImportFixAtPosition(t, []string{
|
||||
`import React from "./react";
|
||||
|
||||
<Foo />;`,
|
||||
}, nil /*preferences*/)
|
||||
}
|
||||
|
||||
// Test edge case where both the component name (Foo) and the JSX namespace (React)
|
||||
// are type-only imported. Each diagnostic is matched to its symbol via the error
|
||||
// message, so each produces only its own promotion fix (no duplicates).
|
||||
func TestCodeFixPromoteTypeOnlyImportJsxTagBothTypeOnly(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @module: preserve
|
||||
// @verbatimModuleSyntax: true
|
||||
// @jsx: react
|
||||
// @Filename: /react.ts
|
||||
const React: any = {};
|
||||
export default React;
|
||||
// @Filename: /foo.ts
|
||||
export function Foo() { return null; }
|
||||
// @Filename: /bar.tsx
|
||||
import type React from "./react";
|
||||
import type { Foo } from "./foo";
|
||||
|
||||
<Foo/**/ />;`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.GoToMarker(t, "")
|
||||
// Both Foo and React are type-only imported. The error message string
|
||||
// matching disambiguates which diagnostic is about which symbol, so each
|
||||
// diagnostic produces only its own promotion fix (no duplicates).
|
||||
f.VerifyImportFixAtPosition(t, []string{
|
||||
`import type React from "./react";
|
||||
import { Foo } from "./foo";
|
||||
|
||||
<Foo />;`,
|
||||
`import React from "./react";
|
||||
import type { Foo } from "./foo";
|
||||
|
||||
<Foo />;`,
|
||||
}, nil /*preferences*/)
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
// Test case for crash when promoting type-only import to value import
|
||||
// when existing type imports precede the new value import
|
||||
// https://github.com/microsoft/typescript-go/issues/2559
|
||||
func TestCodeFixPromoteTypeOnlyOrderingCrash(t *testing.T) {
|
||||
fourslash.SkipIfFailing(t)
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @module: node18
|
||||
// @verbatimModuleSyntax: true
|
||||
// @Filename: /bar.ts
|
||||
export interface AAA {}
|
||||
export class BBB {}
|
||||
// @Filename: /foo.ts
|
||||
import type {
|
||||
AAA,
|
||||
BBB,
|
||||
} from "./bar";
|
||||
|
||||
let x: AAA = new BBB()`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.GoToFile(t, "/foo.ts")
|
||||
|
||||
f.VerifyImportFixAtPosition(t, []string{
|
||||
`import {
|
||||
BBB,
|
||||
type AAA,
|
||||
} from "./bar";
|
||||
|
||||
let x: AAA = new BBB()`,
|
||||
}, nil /*preferences*/)
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/core"
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/ls/lsutil"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCodeLensFunctionExpressions01(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
|
||||
const content = `
|
||||
// @filename: anonymousFunctionExpressions.ts
|
||||
export let anonFn1 = function () {};
|
||||
export const anonFn2 = function () {};
|
||||
|
||||
let anonFn3 = function () {};
|
||||
const anonFn4 = function () {};
|
||||
|
||||
// @filename: arrowFunctions.ts
|
||||
export let arrowFn1 = () => {};
|
||||
export const arrowFn2 = () => {};
|
||||
|
||||
let arrowFn3 = () => {};
|
||||
const arrowFn4 = () => {};
|
||||
|
||||
// @filename: namedFunctions.ts
|
||||
export let namedFn1 = function namedFn1() {
|
||||
namedFn1();
|
||||
}
|
||||
namedFn1();
|
||||
|
||||
export const namedFn2 = function namedFn2() {
|
||||
namedFn2();
|
||||
}
|
||||
namedFn2();
|
||||
|
||||
let namedFn3 = function namedFn3() {};
|
||||
const namedFn4 = function namedFn4() {};
|
||||
`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyBaselineCodeLens(t, &lsutil.UserPreferences{
|
||||
CodeLens: lsutil.CodeLensUserPreferences{
|
||||
ReferencesCodeLensEnabled: core.TSTrue,
|
||||
ReferencesCodeLensShowOnAllFunctions: core.TSTrue,
|
||||
|
||||
ImplementationsCodeLensEnabled: core.TSTrue,
|
||||
ImplementationsCodeLensShowOnInterfaceMethods: core.TSTrue,
|
||||
ImplementationsCodeLensShowOnAllClassMethods: core.TSTrue,
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/core"
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/ls/lsutil"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCodeLensFunctionsAndConstants01(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
|
||||
const content = `
|
||||
// @module: preserve
|
||||
|
||||
// @filename: ./exports.ts
|
||||
|
||||
let callCount = 0;
|
||||
export function foo(n: number): void {
|
||||
callCount++;
|
||||
if (n > 0) {
|
||||
foo(n - 1);
|
||||
}
|
||||
else {
|
||||
console.log("function was called " + callCount + " times");
|
||||
}
|
||||
}
|
||||
|
||||
foo(5);
|
||||
|
||||
export const bar = 123;
|
||||
|
||||
// @filename: ./importer.ts
|
||||
import { foo, bar } from "./exports";
|
||||
|
||||
foo(5);
|
||||
console.log(bar);
|
||||
`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyBaselineCodeLens(t, &lsutil.UserPreferences{
|
||||
CodeLens: lsutil.CodeLensUserPreferences{
|
||||
ReferencesCodeLensEnabled: core.TSTrue,
|
||||
ReferencesCodeLensShowOnAllFunctions: core.TSTrue,
|
||||
|
||||
ImplementationsCodeLensEnabled: core.TSTrue,
|
||||
ImplementationsCodeLensShowOnInterfaceMethods: core.TSTrue,
|
||||
ImplementationsCodeLensShowOnAllClassMethods: core.TSTrue,
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/core"
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/ls/lsutil"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCodeLensInterface01(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
|
||||
const content = `
|
||||
// @module: preserve
|
||||
|
||||
// @filename: ./pointable.ts
|
||||
export interface Pointable {
|
||||
getX(): number;
|
||||
getY(): number;
|
||||
}
|
||||
|
||||
// @filename: ./classPointable.ts
|
||||
import { Pointable } from "./pointable";
|
||||
|
||||
class Point implements Pointable {
|
||||
getX(): number {
|
||||
return 0;
|
||||
}
|
||||
getY(): number {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// @filename: ./objectPointable.ts
|
||||
import { Pointable } from "./pointable";
|
||||
|
||||
let x = 0;
|
||||
let y = 0;
|
||||
const p: Pointable = {
|
||||
getX(): number {
|
||||
return x;
|
||||
},
|
||||
getY(): number {
|
||||
return y;
|
||||
},
|
||||
};
|
||||
`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyBaselineCodeLens(t, &lsutil.UserPreferences{
|
||||
CodeLens: lsutil.CodeLensUserPreferences{
|
||||
ReferencesCodeLensEnabled: core.TSTrue,
|
||||
ReferencesCodeLensShowOnAllFunctions: core.TSTrue,
|
||||
|
||||
ImplementationsCodeLensEnabled: core.TSTrue,
|
||||
ImplementationsCodeLensShowOnInterfaceMethods: core.TSTrue,
|
||||
ImplementationsCodeLensShowOnAllClassMethods: core.TSTrue,
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/core"
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/ls/lsutil"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCodeLensOverloads01(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
|
||||
const content = `
|
||||
export function foo(x: number): number;
|
||||
export function foo(x: string): string;
|
||||
export function foo(x: string | number): string | number {
|
||||
return x;
|
||||
}
|
||||
|
||||
foo(1);
|
||||
|
||||
foo("hello");
|
||||
|
||||
// This one isn't expected to match any overload,
|
||||
// but is really just here to test how it affects how code lens.
|
||||
foo(Math.random() ? 1 : "hello");
|
||||
`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyBaselineCodeLens(t, &lsutil.UserPreferences{
|
||||
CodeLens: lsutil.CodeLensUserPreferences{
|
||||
ReferencesCodeLensEnabled: core.TSTrue,
|
||||
ReferencesCodeLensShowOnAllFunctions: core.TSTrue,
|
||||
|
||||
ImplementationsCodeLensEnabled: core.TSTrue,
|
||||
ImplementationsCodeLensShowOnInterfaceMethods: core.TSTrue,
|
||||
ImplementationsCodeLensShowOnAllClassMethods: core.TSTrue,
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/core"
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/ls/lsutil"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCodeLensReferencesShowOnAllClassMethods(t *testing.T) {
|
||||
t.Parallel()
|
||||
containingTestName := t.Name()
|
||||
for _, value := range []core.Tristate{core.TSTrue, core.TSFalse} {
|
||||
t.Run(fmt.Sprintf("%s=%v", containingTestName, value.IsTrue()), func(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
|
||||
const content = `
|
||||
export abstract class ABC {
|
||||
abstract methodA(): void;
|
||||
methodB(): void {}
|
||||
#methodC(): void {}
|
||||
protected methodD(): void {}
|
||||
private methodE(): void {}
|
||||
protected abstract methodG(): void;
|
||||
public methodH(): void {}
|
||||
|
||||
static methodStaticA(): void {}
|
||||
protected static methodStaticB(): void {}
|
||||
private static methodStaticC(): void {}
|
||||
static #methodStaticD(): void {}
|
||||
}
|
||||
`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyBaselineCodeLens(t, &lsutil.UserPreferences{
|
||||
CodeLens: lsutil.CodeLensUserPreferences{
|
||||
ImplementationsCodeLensEnabled: core.TSTrue,
|
||||
ImplementationsCodeLensShowOnAllClassMethods: value,
|
||||
},
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/core"
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/ls/lsutil"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCodeLensReferencesShowOnAllFunctions(t *testing.T) {
|
||||
t.Parallel()
|
||||
containingTestName := t.Name()
|
||||
for _, value := range []core.Tristate{core.TSTrue, core.TSFalse} {
|
||||
t.Run(fmt.Sprintf("%s=%v", containingTestName, value.IsTrue()), func(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
|
||||
const content = `
|
||||
export function f1(): void {}
|
||||
|
||||
function f2(): void {}
|
||||
|
||||
export const f3 = () => {};
|
||||
|
||||
const f4 = () => {};
|
||||
|
||||
const f5 = function() {};
|
||||
`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyBaselineCodeLens(t, &lsutil.UserPreferences{
|
||||
CodeLens: lsutil.CodeLensUserPreferences{
|
||||
ReferencesCodeLensEnabled: core.TSTrue,
|
||||
ReferencesCodeLensShowOnAllFunctions: value,
|
||||
},
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/core"
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/ls/lsutil"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCodeLensReferencesShowOnInterfaceMethods(t *testing.T) {
|
||||
t.Parallel()
|
||||
containingTestName := t.Name()
|
||||
for _, value := range []core.Tristate{core.TSTrue, core.TSFalse} {
|
||||
t.Run(fmt.Sprintf("%s=%v", containingTestName, value.IsTrue()), func(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
|
||||
const content = `
|
||||
export interface I {
|
||||
methodA(): void;
|
||||
}
|
||||
export interface I {
|
||||
methodB(): void;
|
||||
}
|
||||
|
||||
interface J extends I {
|
||||
methodB(): void;
|
||||
methodC(): void;
|
||||
}
|
||||
|
||||
class C implements J {
|
||||
methodA(): void {}
|
||||
methodB(): void {}
|
||||
methodC(): void {}
|
||||
}
|
||||
|
||||
class AbstractC implements J {
|
||||
abstract methodA(): void;
|
||||
methodB(): void {}
|
||||
abstract methodC(): void;
|
||||
}
|
||||
`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyBaselineCodeLens(t, &lsutil.UserPreferences{
|
||||
CodeLens: lsutil.CodeLensUserPreferences{
|
||||
ImplementationsCodeLensEnabled: core.TSTrue,
|
||||
ImplementationsCodeLensShowOnInterfaceMethods: value,
|
||||
},
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
. "github.com/microsoft/typescript-go/internal/fourslash/tests/util"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCompletionAfterCallExpression(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
|
||||
const content = `let x = someCall() /**/`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyCompletions(t, "", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
EditRange: Ignored,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{
|
||||
"satisfies",
|
||||
"as",
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCompletionAfterExtendsL10nInJs(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `
|
||||
// @allowJs: true
|
||||
// @checkJs: true
|
||||
// @Filename: /interfaces.d.ts
|
||||
export interface IL10n {}
|
||||
|
||||
// @Filename: /genericl10n.js
|
||||
/** @typedef {import("./interfaces").IL10n} IL10n */
|
||||
|
||||
class L10n {
|
||||
constructor(options) {
|
||||
this.options = options;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @implements {IL10n}
|
||||
*/
|
||||
class GenericL10n extends L10n/*1*/ {
|
||||
constructor(lang) {
|
||||
super({ lang });
|
||||
}
|
||||
}
|
||||
|
||||
`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
|
||||
f.GoToMarker(t, "1")
|
||||
f.GetCompletions(t, nil /*userPreferences*/)
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
. "github.com/microsoft/typescript-go/internal/fourslash/tests/util"
|
||||
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCompletionAfterTrailingAtInJSDoc1(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @allowJs: true
|
||||
// @Filename: /atTagPosition.js
|
||||
/**
|
||||
* @/*1*/
|
||||
*/
|
||||
function foo(x) {}
|
||||
|
||||
// @Filename: /atAfterExistingParam.js
|
||||
/**
|
||||
* @param {string} x ok
|
||||
* @/*2*/
|
||||
*/
|
||||
function bar(x, y) {}
|
||||
|
||||
// @Filename: /atMidLine.js
|
||||
/**
|
||||
* some text @/*3*/
|
||||
*/
|
||||
function baz(y) {}
|
||||
`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyCompletions(t, []string{"1", "2", "3"}, &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
EditRange: Ignored,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{
|
||||
&lsproto.CompletionItem{
|
||||
Label: "param",
|
||||
Kind: new(lsproto.CompletionItemKindKeyword),
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
. "github.com/microsoft/typescript-go/internal/fourslash/tests/util"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCompletionClassMemberAfterJSDocWithInvalidJSDocTagInTheComment1(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `export class NeedsPrefix {
|
||||
private _prefixes: {
|
||||
add: Record<string, any>;
|
||||
browsers: {selected: string[]};
|
||||
};
|
||||
|
||||
constructor(browsers: string[]) {
|
||||
}
|
||||
|
||||
/** Checks whether an @-rule needs to be prefixed. */
|
||||
/**/atRule(identifier: string): boolean {
|
||||
return true;
|
||||
}
|
||||
}`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyCompletions(t, "", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &[]string{},
|
||||
EditRange: Ignored,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
. "github.com/microsoft/typescript-go/internal/fourslash/tests/util"
|
||||
"github.com/microsoft/typescript-go/internal/ls"
|
||||
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestClassMembersAfterConstAssertionInitializer(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `
|
||||
interface A {
|
||||
a: number
|
||||
def: string
|
||||
}
|
||||
|
||||
class B implements A {
|
||||
a = 1 as const
|
||||
/**/
|
||||
}
|
||||
`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
|
||||
f.VerifyCompletions(t, "", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &[]string{},
|
||||
EditRange: Ignored,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Exact: append([]fourslash.CompletionsExpectedItem{
|
||||
&lsproto.CompletionItem{
|
||||
Label: "def",
|
||||
Kind: new(lsproto.CompletionItemKindField),
|
||||
SortText: new(string(ls.SortTextLocationPriority)),
|
||||
},
|
||||
}, CompletionClassElementKeywords...),
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
. "github.com/microsoft/typescript-go/internal/fourslash/tests/util"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCompletionColonToken(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
|
||||
const content = `
|
||||
// @filename: /a.ts
|
||||
:/*a*/
|
||||
|
||||
// @filename: /b.ts
|
||||
function b(class: /*b*/) {}
|
||||
|
||||
// @filename: /c.ts
|
||||
function c(enum: /*c*/) {}
|
||||
`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
|
||||
for _, marker := range f.Ranges() {
|
||||
f.VerifyCompletions(t, marker, &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
EditRange: Ignored,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: CompletionGlobals,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
. "github.com/microsoft/typescript-go/internal/fourslash/tests/util"
|
||||
"github.com/microsoft/typescript-go/internal/ls"
|
||||
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCompletionDetailSignature(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `
|
||||
|
||||
/*a*/
|
||||
|
||||
function foo(x: string): string;
|
||||
function foo(x: number): number;
|
||||
function foo(x: any): any {
|
||||
return x;
|
||||
}`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyCompletions(t, "a", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{
|
||||
&lsproto.CompletionItem{
|
||||
Label: "foo",
|
||||
Kind: new(lsproto.CompletionItemKindFunction),
|
||||
SortText: new(string(ls.SortTextLocationPriority)),
|
||||
Detail: new("function foo(x: string): string\nfunction foo(x: number): number"),
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,236 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
. "github.com/microsoft/typescript-go/internal/fourslash/tests/util"
|
||||
"github.com/microsoft/typescript-go/internal/ls"
|
||||
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCompletionFilterText1(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `
|
||||
class Foo1 {
|
||||
#bar: number;
|
||||
constructor(bar: number) {
|
||||
this.[|b|]/*1*/
|
||||
}
|
||||
}
|
||||
|
||||
class Foo5 {
|
||||
#bar: number;
|
||||
constructor(bar: number) {
|
||||
this./*5*/
|
||||
}
|
||||
}
|
||||
|
||||
class Foo2 {
|
||||
#bar: number;
|
||||
constructor(bar: number) {
|
||||
this.[|#b|]/*2*/
|
||||
}
|
||||
}
|
||||
|
||||
class Foo6 {
|
||||
#bar: number;
|
||||
constructor(bar: number) {
|
||||
this.[|#|]/*6*/
|
||||
}
|
||||
}
|
||||
|
||||
class Foo3 {
|
||||
#bar: number;
|
||||
constructor(bar: number) {
|
||||
[|b|]/*3*/
|
||||
}
|
||||
}
|
||||
|
||||
class Foo7 {
|
||||
#bar: number;
|
||||
constructor(bar: number) {
|
||||
/*7*/
|
||||
}
|
||||
}
|
||||
|
||||
class Foo4 {
|
||||
#bar: number;
|
||||
constructor(bar: number) {
|
||||
[|#b|]/*4*/
|
||||
}
|
||||
}
|
||||
|
||||
class Foo8 {
|
||||
#bar: number;
|
||||
constructor(bar: number) {
|
||||
[|#|]/*8*/
|
||||
}
|
||||
}
|
||||
`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyCompletions(t, "1", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
EditRange: &fourslash.EditRange{
|
||||
Insert: f.Ranges()[0],
|
||||
Replace: f.Ranges()[0],
|
||||
},
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{
|
||||
&lsproto.CompletionItem{
|
||||
Label: "#bar",
|
||||
Kind: new(lsproto.CompletionItemKindField),
|
||||
SortText: new(string(ls.SortTextLocationPriority)),
|
||||
FilterText: new("bar"),
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
f.VerifyCompletions(t, "5", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{
|
||||
&lsproto.CompletionItem{
|
||||
Label: "#bar",
|
||||
Kind: new(lsproto.CompletionItemKindField),
|
||||
SortText: new(string(ls.SortTextLocationPriority)),
|
||||
FilterText: new("bar"),
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
f.VerifyCompletions(t, "2", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
EditRange: &fourslash.EditRange{
|
||||
Insert: f.Ranges()[1],
|
||||
Replace: f.Ranges()[1],
|
||||
},
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{
|
||||
&lsproto.CompletionItem{
|
||||
Label: "#bar",
|
||||
Kind: new(lsproto.CompletionItemKindField),
|
||||
SortText: new(string(ls.SortTextLocationPriority)),
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
f.VerifyCompletions(t, "6", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
EditRange: &fourslash.EditRange{
|
||||
Insert: f.Ranges()[2],
|
||||
Replace: f.Ranges()[2],
|
||||
},
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{
|
||||
&lsproto.CompletionItem{
|
||||
Label: "#bar",
|
||||
Kind: new(lsproto.CompletionItemKindField),
|
||||
SortText: new(string(ls.SortTextLocationPriority)),
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
f.VerifyCompletions(t, "3", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
EditRange: Ignored,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{
|
||||
&lsproto.CompletionItem{
|
||||
Label: "#bar",
|
||||
Kind: new(lsproto.CompletionItemKindField),
|
||||
SortText: new(string(ls.SortTextSuggestedClassMembers)),
|
||||
FilterText: new("bar"),
|
||||
TextEdit: &lsproto.TextEditOrInsertReplaceEdit{
|
||||
InsertReplaceEdit: &lsproto.InsertReplaceEdit{
|
||||
NewText: "this.#bar",
|
||||
Insert: f.Ranges()[3].LSRange,
|
||||
Replace: f.Ranges()[3].LSRange,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
f.VerifyCompletions(t, "7", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{
|
||||
&lsproto.CompletionItem{
|
||||
Label: "#bar",
|
||||
Kind: new(lsproto.CompletionItemKindField),
|
||||
SortText: new(string(ls.SortTextSuggestedClassMembers)),
|
||||
FilterText: new("bar"),
|
||||
InsertText: new("this.#bar"),
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
f.VerifyCompletions(t, "4", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
EditRange: Ignored,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{
|
||||
&lsproto.CompletionItem{
|
||||
Label: "#bar",
|
||||
Kind: new(lsproto.CompletionItemKindField),
|
||||
SortText: new(string(ls.SortTextSuggestedClassMembers)),
|
||||
TextEdit: &lsproto.TextEditOrInsertReplaceEdit{
|
||||
InsertReplaceEdit: &lsproto.InsertReplaceEdit{
|
||||
NewText: "this.#bar",
|
||||
Insert: f.Ranges()[4].LSRange,
|
||||
Replace: f.Ranges()[4].LSRange,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
f.VerifyCompletions(t, "8", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
EditRange: Ignored,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{
|
||||
&lsproto.CompletionItem{
|
||||
Label: "#bar",
|
||||
Kind: new(lsproto.CompletionItemKindField),
|
||||
SortText: new(string(ls.SortTextSuggestedClassMembers)),
|
||||
TextEdit: &lsproto.TextEditOrInsertReplaceEdit{
|
||||
InsertReplaceEdit: &lsproto.InsertReplaceEdit{
|
||||
NewText: "this.#bar",
|
||||
Insert: f.Ranges()[5].LSRange,
|
||||
Replace: f.Ranges()[5].LSRange,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
. "github.com/microsoft/typescript-go/internal/fourslash/tests/util"
|
||||
"github.com/microsoft/typescript-go/internal/ls"
|
||||
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCompletionFilterText2(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @strict: true
|
||||
declare const foo1: { bar: string } | undefined;
|
||||
if (true) {
|
||||
foo1[|.|]/*1*/
|
||||
}
|
||||
else {
|
||||
foo1?./*2*/
|
||||
}
|
||||
`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyCompletions(t, "1", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{
|
||||
&lsproto.CompletionItem{
|
||||
Label: "bar",
|
||||
Kind: new(lsproto.CompletionItemKindField),
|
||||
SortText: new(string(ls.SortTextLocationPriority)),
|
||||
InsertText: new("?.bar"),
|
||||
FilterText: new(".bar"),
|
||||
TextEdit: &lsproto.TextEditOrInsertReplaceEdit{
|
||||
TextEdit: &lsproto.TextEdit{
|
||||
NewText: "?.bar",
|
||||
Range: f.Ranges()[0].LSRange,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
f.VerifyCompletions(t, "2", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{
|
||||
&lsproto.CompletionItem{
|
||||
Label: "bar",
|
||||
Kind: new(lsproto.CompletionItemKindField),
|
||||
SortText: new(string(ls.SortTextLocationPriority)),
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
. "github.com/microsoft/typescript-go/internal/fourslash/tests/util"
|
||||
"github.com/microsoft/typescript-go/internal/ls"
|
||||
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCompletionFilterText3(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @strict: true
|
||||
declare const foo1: { b: number; "a bc": string; };
|
||||
if (true) {
|
||||
foo1[|.|]/*1*/
|
||||
}
|
||||
else {
|
||||
foo1[|.a|]/*2*/
|
||||
}
|
||||
|
||||
declare const foo2: { b: number; "a bc": string; } | undefined;
|
||||
if (true) {
|
||||
foo2[|.|]/*3*/
|
||||
} else if (false) {
|
||||
foo2[|.a|]/*4*/
|
||||
} else {
|
||||
foo2[|?.|]/*5*/
|
||||
}
|
||||
`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyCompletions(t, "1", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{
|
||||
&lsproto.CompletionItem{
|
||||
Label: "a bc",
|
||||
Kind: new(lsproto.CompletionItemKindField),
|
||||
SortText: new(string(ls.SortTextLocationPriority)),
|
||||
InsertText: new("[\"a bc\"]"),
|
||||
FilterText: new(".a bc"),
|
||||
TextEdit: &lsproto.TextEditOrInsertReplaceEdit{
|
||||
TextEdit: &lsproto.TextEdit{
|
||||
NewText: "[\"a bc\"]",
|
||||
Range: f.Ranges()[0].LSRange,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
f.VerifyCompletions(t, "2", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
EditRange: Ignored,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{
|
||||
&lsproto.CompletionItem{
|
||||
Label: "a bc",
|
||||
Kind: new(lsproto.CompletionItemKindField),
|
||||
SortText: new(string(ls.SortTextLocationPriority)),
|
||||
InsertText: new("[\"a bc\"]"),
|
||||
FilterText: new(".a bc"),
|
||||
TextEdit: &lsproto.TextEditOrInsertReplaceEdit{
|
||||
TextEdit: &lsproto.TextEdit{
|
||||
NewText: "[\"a bc\"]",
|
||||
Range: f.Ranges()[1].LSRange,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
f.VerifyCompletions(t, "3", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{
|
||||
&lsproto.CompletionItem{
|
||||
Label: "a bc",
|
||||
Kind: new(lsproto.CompletionItemKindField),
|
||||
SortText: new(string(ls.SortTextLocationPriority)),
|
||||
InsertText: new("?.[\"a bc\"]"),
|
||||
FilterText: new(".a bc"),
|
||||
TextEdit: &lsproto.TextEditOrInsertReplaceEdit{
|
||||
TextEdit: &lsproto.TextEdit{
|
||||
NewText: "?.[\"a bc\"]",
|
||||
Range: f.Ranges()[2].LSRange,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
f.VerifyCompletions(t, "4", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
EditRange: Ignored,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{
|
||||
&lsproto.CompletionItem{
|
||||
Label: "a bc",
|
||||
Kind: new(lsproto.CompletionItemKindField),
|
||||
SortText: new(string(ls.SortTextLocationPriority)),
|
||||
InsertText: new("?.[\"a bc\"]"),
|
||||
FilterText: new(".a bc"),
|
||||
TextEdit: &lsproto.TextEditOrInsertReplaceEdit{
|
||||
TextEdit: &lsproto.TextEdit{
|
||||
NewText: "?.[\"a bc\"]",
|
||||
Range: f.Ranges()[3].LSRange,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
f.VerifyCompletions(t, "5", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{
|
||||
&lsproto.CompletionItem{
|
||||
Label: "a bc",
|
||||
Kind: new(lsproto.CompletionItemKindField),
|
||||
SortText: new(string(ls.SortTextLocationPriority)),
|
||||
InsertText: new("?.[\"a bc\"]"),
|
||||
FilterText: new("?.a bc"),
|
||||
TextEdit: &lsproto.TextEditOrInsertReplaceEdit{
|
||||
TextEdit: &lsproto.TextEdit{
|
||||
NewText: "?.[\"a bc\"]",
|
||||
Range: f.Ranges()[4].LSRange,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
. "github.com/microsoft/typescript-go/internal/fourslash/tests/util"
|
||||
"github.com/microsoft/typescript-go/internal/ls"
|
||||
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCompletionFilterText4(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `declare const x: [number, number];
|
||||
x[|.|]/**/;
|
||||
`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyCompletions(t, "", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{
|
||||
&lsproto.CompletionItem{
|
||||
Label: "0",
|
||||
Kind: new(lsproto.CompletionItemKindField),
|
||||
SortText: new(string(ls.SortTextLocationPriority)),
|
||||
InsertText: new("[0]"),
|
||||
FilterText: new(".0"),
|
||||
TextEdit: &lsproto.TextEditOrInsertReplaceEdit{
|
||||
TextEdit: &lsproto.TextEdit{
|
||||
NewText: "[0]",
|
||||
Range: f.Ranges()[0].LSRange,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
// !!! can delete, there are similar tests that haven't been ported yet.
|
||||
func TestCompletionImportAttributes(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `
|
||||
// @target: esnext
|
||||
// @module: esnext
|
||||
// @filename: main.ts
|
||||
import yadda1 from "yadda" with {/*attr*/}
|
||||
import yadda2 from "yadda" with {attr/*attrEnd1*/: true}
|
||||
import yadda3 from "yadda" with {attr: /*attrValue*/}
|
||||
|
||||
// @filename: yadda
|
||||
export default {};
|
||||
`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
|
||||
f.GoToEachMarker(t, nil, func(marker *fourslash.Marker, index int) {
|
||||
f.VerifyCompletions(t, marker, nil)
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
// Test that requesting completions after a keyword in an import statement
|
||||
// doesn't crash with a nil pointer dereference.
|
||||
// Reproduces issue: import super/*cursor*/
|
||||
// Before the fix, this would panic with: runtime error: invalid memory address or nil pointer dereference
|
||||
func TestCompletionImportKeywordNoCrash(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
|
||||
emptyCommitChars := []string{}
|
||||
|
||||
// Test with "super" keyword
|
||||
{
|
||||
const content = `import super/*1*/`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
f.VerifyCompletions(t, "1", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &emptyCommitChars,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{
|
||||
"type",
|
||||
},
|
||||
},
|
||||
})
|
||||
done()
|
||||
}
|
||||
|
||||
// Test with "this" keyword
|
||||
{
|
||||
const content = `import this/*1*/`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
f.VerifyCompletions(t, "1", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &emptyCommitChars,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{
|
||||
"type",
|
||||
},
|
||||
},
|
||||
})
|
||||
done()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
. "github.com/microsoft/typescript-go/internal/fourslash/tests/util"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCompletionInArrayLiteralAfterInvalidToken1(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
|
||||
const content = `const pairs: Record<string, [string, string]> = {
|
||||
a: ["x",:/*m1*/]
|
||||
};
|
||||
`
|
||||
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
|
||||
f.VerifyCompletions(t, "m1", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCompletionInJSDocPropertyWithLinkNoCrash1(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `
|
||||
// @allowJs: true
|
||||
// @filename: /file.js
|
||||
export function foo() {}
|
||||
|
||||
/**
|
||||
* @typedef MyType
|
||||
* @property {number} [timeout] - The /*1*/timeout; defaults to {@linkcode DEFAULT}
|
||||
*/
|
||||
`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
|
||||
f.VerifyCompletions(t, "1", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{CommitCharacters: &[]string{".", ",", ";"}},
|
||||
Items: &fourslash.CompletionsExpectedItems{},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCompletionJSDocNoCrash2(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `
|
||||
// @allowJs: true
|
||||
// @filename: file.js
|
||||
/**
|
||||
* @param {Object} obj
|
||||
* @param {string} obj.first The first property
|
||||
* @param {string} obj.second The second property
|
||||
* @param {string} obj.third The {@link foo} third property
|
||||
*/
|
||||
/*1*/function foo(obj) {}
|
||||
`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
|
||||
// The assertion here is simply "does not crash/panic".
|
||||
f.VerifyCompletions(t, "1", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{CommitCharacters: &[]string{".", ",", ";"}},
|
||||
Items: &fourslash.CompletionsExpectedItems{},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCompletionJSDocNoCrash(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `
|
||||
// @allowJs: true
|
||||
// @filename: file.js
|
||||
class ErrorMap {
|
||||
/**
|
||||
* @type {string}
|
||||
*//*1*/
|
||||
errorMap;
|
||||
}
|
||||
`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
|
||||
// The assertion here is simply "does not crash/panic".
|
||||
f.VerifyCompletions(t, "1", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{CommitCharacters: &[]string{".", ",", ";"}},
|
||||
Items: &fourslash.CompletionsExpectedItems{},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCompletionJsxNoCrash(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `
|
||||
// @filename: file.tsx
|
||||
<Foo/>/*1*/
|
||||
`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
|
||||
// The assertion here is simply "does not crash/panic".
|
||||
f.VerifyCompletions(t, "1", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{CommitCharacters: &[]string{".", ",", ";"}},
|
||||
Items: &fourslash.CompletionsExpectedItems{},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
. "github.com/microsoft/typescript-go/internal/fourslash/tests/util"
|
||||
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCompletionListAlreadyImportedNamespaceExportAlias(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @module: node18
|
||||
// @Filename: /values.ts
|
||||
export const A = 1;
|
||||
export const B = 2;
|
||||
|
||||
// @Filename: /namespace.ts
|
||||
import * as Group from "./values.js";
|
||||
type Group = (typeof Group)[keyof typeof Group];
|
||||
export { Group };
|
||||
|
||||
// @Filename: /index.ts
|
||||
import { Group } from "./namespace.js";
|
||||
|
||||
console.log(Grou/**/);`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
|
||||
result := f.VerifyCompletions(t, "", &fourslash.CompletionsExpectedList{
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
EditRange: Ignored,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{
|
||||
&lsproto.CompletionItem{Label: "Group"},
|
||||
},
|
||||
},
|
||||
})
|
||||
result.AndHasNoCodeAction(t, &fourslash.CompletionsExpectedCodeAction{
|
||||
Name: "Group",
|
||||
Source: "./namespace.js",
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
. "github.com/microsoft/typescript-go/internal/fourslash/tests/util"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCompletionListDefaultTypeArgumentPositionTypeOnly(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @lib: es5
|
||||
const foo = "foo";
|
||||
function test1<T = /*1*/>() {}`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyCompletions(t, "1", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Exact: CompletionGlobalTypes,
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
. "github.com/microsoft/typescript-go/internal/fourslash/tests/util"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCompletionListInUnclosedTypeArguments(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `let x = 10;
|
||||
type Type = void;
|
||||
declare function f<T>(): void;
|
||||
declare function f2<T, U>(): void;
|
||||
f</*1a*/T/*2a*/y/*3a*/
|
||||
f</*1b*/T/*2b*/y/*3b*/;
|
||||
f</*1c*/T/*2c*/y/*3c*/>
|
||||
f</*1d*/T/*2d*/y/*3d*/>
|
||||
f</*1e*/T/*2e*/y/*3e*/>();
|
||||
|
||||
f2</*1k*/T/*2k*/y/*3k*/,
|
||||
f2</*1l*/T/*2l*/y/*3l*/,{| "newId": true |}T{| "newId": true |}y{| "newId": true |}
|
||||
f2</*1m*/T/*2m*/y/*3m*/,{| "newId": true |}T{| "newId": true |}y{| "newId": true |};
|
||||
f2</*1n*/T/*2n*/y/*3n*/,{| "newId": false |}T{| "newId": false |}y{| "newId": false |}>
|
||||
f2</*1o*/T/*2o*/y/*3o*/,{| "newId": false |}T{| "newId": false |}y{| "newId": false |}>
|
||||
f2</*1p*/T/*2p*/y/*3p*/,{| "newId": true, "typeOnly": true |}T{| "newId": true, "typeOnly": true |}y{| "newId": true, "typeOnly": true |}>();
|
||||
|
||||
f2<typeof /*1uValueOnly*/x, {| "newId": true |}T{| "newId": true |}y{| "newId": true |}
|
||||
|
||||
f2</*1x*/T/*2x*/y/*3x*/, () =>/*4x*/T/*5x*/y/*6x*/
|
||||
f2<() =>/*1y*/T/*2y*/y/*3y*/, () =>/*4y*/T/*5y*/y/*6y*/
|
||||
f2<any, () =>/*1z*/T/*2z*/y/*3z*/`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.GoToEachMarker(t, nil, func(marker *fourslash.Marker, index int) {
|
||||
markerName := marker.Name
|
||||
valueOnly := markerName != nil && strings.HasSuffix(*markerName, "ValueOnly")
|
||||
commitCharacters := &DefaultCommitCharacters
|
||||
if marker.Data != nil {
|
||||
newId := marker.Data["newId"]
|
||||
typeOnly := marker.Data["typeOnly"]
|
||||
if newId != nil && newId.(bool) && !(typeOnly != nil && typeOnly.(bool)) {
|
||||
commitCharacters = &[]string{".", ";"}
|
||||
}
|
||||
}
|
||||
var includes []fourslash.CompletionsExpectedItem
|
||||
var excludes []string
|
||||
if valueOnly {
|
||||
includes = []fourslash.CompletionsExpectedItem{
|
||||
"x",
|
||||
}
|
||||
excludes = []string{
|
||||
"Type",
|
||||
}
|
||||
} else {
|
||||
includes = []fourslash.CompletionsExpectedItem{
|
||||
"Type",
|
||||
}
|
||||
excludes = []string{
|
||||
"x",
|
||||
}
|
||||
}
|
||||
f.VerifyCompletions(t, marker, &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: commitCharacters,
|
||||
EditRange: Ignored,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: includes,
|
||||
Excludes: excludes,
|
||||
},
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCompletionResolveAfterEdit(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `
|
||||
// @filename: /index.ts
|
||||
interface Point {
|
||||
x: number;
|
||||
y: number;
|
||||
}
|
||||
declare const p: Point;
|
||||
/*a*/
|
||||
|
||||
// @filename: /foo.ts
|
||||
/*b*/
|
||||
`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
|
||||
// Step 1: Get completions at the marker.
|
||||
f.GoToMarker(t, "a")
|
||||
completions := f.GetCompletions(t, nil /*userPreferences*/)
|
||||
if completions == nil || len(completions.Items) == 0 {
|
||||
t.Fatal("Expected completions but got none")
|
||||
}
|
||||
firstItem := completions.Items[0]
|
||||
|
||||
// Step 2: Make a file change (insert a comment after marker).
|
||||
f.GoToMarker(t, "b")
|
||||
f.Insert(t, "1")
|
||||
|
||||
// Step 3: Resolve the first completion item from the original list.
|
||||
resolved := f.ResolveCompletionItem(t, firstItem)
|
||||
if resolved == nil {
|
||||
t.Fatal("Expected resolved completion item but got nil")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/ls"
|
||||
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCompletionResolveKeyword(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `class C {
|
||||
/*a*/
|
||||
}`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyCompletions(t, "a", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &[]string{},
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{
|
||||
&lsproto.CompletionItem{
|
||||
Label: "abstract",
|
||||
Kind: new(lsproto.CompletionItemKindKeyword),
|
||||
SortText: new(string(ls.SortTextGlobalsOrKeywords)),
|
||||
Detail: new("abstract"),
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
. "github.com/microsoft/typescript-go/internal/fourslash/tests/util"
|
||||
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCompletionWithUnterminatedJSDocEndingWithAt1(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @allowJs: true
|
||||
// @Filename: /atOnNewLineAtEOF.js
|
||||
function foo(x) {}
|
||||
/**
|
||||
* @/*1*/`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyCompletions(t, "1", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
EditRange: Ignored,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{
|
||||
&lsproto.CompletionItem{
|
||||
Label: "param",
|
||||
Kind: new(lsproto.CompletionItemKindKeyword),
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
. "github.com/microsoft/typescript-go/internal/fourslash/tests/util"
|
||||
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCompletionWithUnterminatedJSDocEndingWithAt2(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @allowJs: true
|
||||
// @Filename: /atInTextAtEOF.js
|
||||
function foo(x) {}
|
||||
/** some text @/*1*/`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyCompletions(t, "1", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
EditRange: Ignored,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{
|
||||
&lsproto.CompletionItem{
|
||||
Label: "param",
|
||||
Kind: new(lsproto.CompletionItemKindKeyword),
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCompletionsAtTopLevelImportAssignmentNoCrash1(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
|
||||
const content = `// @filename: /a.ts
|
||||
import x =/*1*/
|
||||
class Foo {}
|
||||
// @filename: /b.ts
|
||||
import x = /*2*/
|
||||
class Foo {}
|
||||
// @filename: /c.ts
|
||||
import x =/*3*/
|
||||
`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
|
||||
f.VerifyCompletions(t, []string{"1", "2", "3"}, &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &[]string{},
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
. "github.com/microsoft/typescript-go/internal/fourslash/tests/util"
|
||||
"github.com/microsoft/typescript-go/internal/ls"
|
||||
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCompletionsDeprecatedTags(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
|
||||
const content = `const o = {
|
||||
/** @deprecated */
|
||||
a: 1,
|
||||
b: 2,
|
||||
c: 3,
|
||||
}
|
||||
o./**/`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyCompletions(t, "", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
EditRange: Ignored,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{
|
||||
&lsproto.CompletionItem{
|
||||
Label: "a",
|
||||
Kind: new(lsproto.CompletionItemKindField),
|
||||
Tags: &[]lsproto.CompletionItemTag{lsproto.CompletionItemTagDeprecated},
|
||||
SortText: new(string(ls.DeprecateSortText(ls.SortTextLocationPriority))),
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCompletionsForContextualConstraintTypeInJsDoc(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
|
||||
const content = `
|
||||
// @allowJs: true
|
||||
// @filename: a.ts
|
||||
export interface Blah<T extends { a: "hello" | "world" }> {
|
||||
}
|
||||
|
||||
// @filename: b.js
|
||||
/** @import * as a from "./a" */
|
||||
|
||||
/** @type {a.Blah<{ a: /*1*/ }>} */
|
||||
let x;
|
||||
|
||||
// @filename: c.js
|
||||
/** @import * as a from "./a" */
|
||||
|
||||
/** @type {a.Blah<{ a: /*2*/ }>} */
|
||||
`
|
||||
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
|
||||
// These examples both would panic in retrieving the symbols
|
||||
// of property signature nodes within JSDoc types.
|
||||
// In both cases, we'd have a JSDoc property signature that has no symbol.
|
||||
//
|
||||
// The two cases differ in whether or not there is a variable declaration
|
||||
// following the `@type` comment. These are important to test differently
|
||||
// because of how JSDoc re-parsing would construct nodes in the tree.
|
||||
//
|
||||
// Getting the symbol of the reparsed node is a sufficient fix for marker 1.
|
||||
// However, that would not fix the case at marker 2 because
|
||||
// there is no variable to attach the `@type` annotation, so the node basically
|
||||
// doesn't exist for subsequent passes like the binder.
|
||||
|
||||
f.VerifyCompletions(t, f.Markers(), &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{CommitCharacters: &[]string{".", ",", ";"}},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{
|
||||
`"hello"`,
|
||||
`"world"`,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
fourslashUtil "github.com/microsoft/typescript-go/internal/fourslash/tests/util"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCompletionsOnImportIdentifierWithFromOnNextLine(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `import something/*1*/
|
||||
from`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyCompletions(t, "1", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &[]string{},
|
||||
EditRange: fourslashUtil.Ignored,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{},
|
||||
})
|
||||
}
|
||||
|
||||
func TestCompletionsOnImportTypeWithFromOnNextLine(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `import type/*1*/
|
||||
from`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyCompletions(t, "1", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &[]string{},
|
||||
EditRange: fourslashUtil.Ignored,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
. "github.com/microsoft/typescript-go/internal/fourslash/tests/util"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCompletionsFromUntitledFile(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
// Test that completions work in untitled files without crashing.
|
||||
// Regression test for https://github.com/microsoft/typescript-go/issues/2550
|
||||
const content = `// @filename: /home/src/project/utils.ts
|
||||
export function helper() {}
|
||||
|
||||
// @filename: ^/untitled/ts-nul-authority/Untitled-1.ts
|
||||
/**/`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
|
||||
// Request completions - this should not crash
|
||||
f.VerifyCompletions(t, "", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
// We don't care about the exact completions, just that it doesn't crash
|
||||
Includes: nil,
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCompletionsInJsxTagDifferentSpreadElementTypes(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `
|
||||
// @Filename: /completionsWithDifferentSpreadTypes.tsx
|
||||
// @strict: true
|
||||
|
||||
// A reasonable type to spread.
|
||||
export function ComponentObjectX(props: { x: string }) {
|
||||
return <SomeComponent {...props} /*objectX*//>;
|
||||
}
|
||||
|
||||
// A questionable but valid type to spread.
|
||||
export function ComponentObjectXOrY(props: { x: string } | { y: string }) {
|
||||
return <SomeComponent {...props} /*objectXOrY*//>;
|
||||
}
|
||||
|
||||
// A very unexpected type to spread (a union containing a primitive).
|
||||
export function ComponentNumberOrObjectX(props: number | { x: string }) {
|
||||
return <SomeComponent {...props} /*numberOrObjectX*//>;
|
||||
}
|
||||
|
||||
// Very unexpected, but still structured (union) types.
|
||||
// 'boolean' is 'true | false' and an optional 'null' is really 'null | undefined'.
|
||||
export function ComponentBoolean(props: boolean) {
|
||||
return <SomeComponent {...props} /*boolean*//>;
|
||||
}
|
||||
export function ComponentOptionalNull(props?: null) {
|
||||
return <SomeComponent {...props} /*optNull*//>;
|
||||
}
|
||||
|
||||
// Primitive types (non-structured).
|
||||
export function ComponentAny(props: any) {
|
||||
return <SomeComponent {...props} /*any*//>;
|
||||
}
|
||||
export function ComponentUnknown(props: unknown) {
|
||||
return <SomeComponent {...props} /*unknown*//>;
|
||||
}
|
||||
export function ComponentNever(props: never) {
|
||||
return <SomeComponent {...props} /*never*//>;
|
||||
}
|
||||
export function ComponentUndefined(props: undefined) {
|
||||
return <SomeComponent {...props} /*undefined*//>;
|
||||
}
|
||||
export function ComponentNumber(props: number) {
|
||||
return <SomeComponent {...props} /*number*//>;
|
||||
}
|
||||
`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.GoToEachMarker(t, nil, func(marker *fourslash.Marker, index int) {
|
||||
f.VerifyCompletions(t, marker, nil)
|
||||
})
|
||||
}
|
||||
124
tools/tsgo/internal/fourslash/tests/completionsInJsxTag_test.go
Normal file
124
tools/tsgo/internal/fourslash/tests/completionsInJsxTag_test.go
Normal file
@@ -0,0 +1,124 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
. "github.com/microsoft/typescript-go/internal/fourslash/tests/util"
|
||||
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCompletionsInJsxTag(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @jsx: preserve
|
||||
// @Filename: /a.tsx
|
||||
declare namespace JSX {
|
||||
interface Element {}
|
||||
interface IntrinsicElements {
|
||||
div: {
|
||||
/** Doc */
|
||||
foo: string
|
||||
/** Label docs */
|
||||
"aria-label": string
|
||||
}
|
||||
}
|
||||
}
|
||||
class Foo {
|
||||
render() {
|
||||
<div /*1*/ ></div>;
|
||||
<div /*2*/ />
|
||||
}
|
||||
}`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyCompletions(t, []string{"1", "2"}, &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Exact: []fourslash.CompletionsExpectedItem{
|
||||
&lsproto.CompletionItem{
|
||||
Label: "aria-label",
|
||||
Kind: new(lsproto.CompletionItemKindField),
|
||||
Detail: new("(property) \"aria-label\": string"),
|
||||
Documentation: &lsproto.StringOrMarkupContent{
|
||||
MarkupContent: &lsproto.MarkupContent{
|
||||
Kind: lsproto.MarkupKindMarkdown,
|
||||
Value: "Label docs",
|
||||
},
|
||||
},
|
||||
},
|
||||
&lsproto.CompletionItem{
|
||||
Label: "foo",
|
||||
Kind: new(lsproto.CompletionItemKindField),
|
||||
Detail: new("(property) foo: string"),
|
||||
Documentation: &lsproto.StringOrMarkupContent{
|
||||
MarkupContent: &lsproto.MarkupContent{
|
||||
Kind: lsproto.MarkupKindMarkdown,
|
||||
Value: "Doc",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestCompletionsInJsxNamespacedIntrinsicTag(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @jsx: react
|
||||
// @Filename: /a.tsx
|
||||
declare const React: any;
|
||||
declare namespace JSX {
|
||||
interface Element {}
|
||||
interface IntrinsicElements {
|
||||
/** Element docs */
|
||||
"foo:bar": {
|
||||
/** Foo docs */
|
||||
foo: boolean
|
||||
/** Bar docs */
|
||||
bar: string
|
||||
}
|
||||
}
|
||||
}
|
||||
<foo:bar /*1*/ />
|
||||
<foo:bar /*2*/></foo:bar>`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyCompletions(t, []string{"1", "2"}, &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Exact: []fourslash.CompletionsExpectedItem{
|
||||
&lsproto.CompletionItem{
|
||||
Label: "bar",
|
||||
Kind: new(lsproto.CompletionItemKindField),
|
||||
Detail: new("(property) bar: string"),
|
||||
Documentation: &lsproto.StringOrMarkupContent{
|
||||
MarkupContent: &lsproto.MarkupContent{
|
||||
Kind: lsproto.MarkupKindMarkdown,
|
||||
Value: "Bar docs",
|
||||
},
|
||||
},
|
||||
},
|
||||
&lsproto.CompletionItem{
|
||||
Label: "foo",
|
||||
Kind: new(lsproto.CompletionItemKindField),
|
||||
Detail: new("(property) foo: boolean"),
|
||||
Documentation: &lsproto.StringOrMarkupContent{
|
||||
MarkupContent: &lsproto.MarkupContent{
|
||||
Kind: lsproto.MarkupKindMarkdown,
|
||||
Value: "Foo docs",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
. "github.com/microsoft/typescript-go/internal/fourslash/tests/util"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCompletionsJSDocSignature(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
|
||||
const content = `// @noLib: true
|
||||
// @checkJs: true
|
||||
// @allowJs: true
|
||||
// @filename: index.js
|
||||
/**
|
||||
* @type {{
|
||||
* (input: string):/*1*/ X|Y/*2*/
|
||||
* }}
|
||||
*/
|
||||
let x;`
|
||||
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyCompletions(t, "1", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &[]string{".", ",", ";"},
|
||||
EditRange: Ignored,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{},
|
||||
})
|
||||
f.VerifyCompletions(t, "2", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &[]string{".", ",", ";"},
|
||||
EditRange: Ignored,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
. "github.com/microsoft/typescript-go/internal/fourslash/tests/util"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCompletionsJSDocTrivia(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
|
||||
const content = `// @noLib: true
|
||||
/**
|
||||
* @type {{
|
||||
* 'string-property': boolean;
|
||||
*/*$*/ identifierProperty: boolean;
|
||||
* }}
|
||||
*/
|
||||
var someVariable;`
|
||||
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.GoToMarker(t, "$")
|
||||
f.VerifyCompletions(t, nil, &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &[]string{".", ",", ";"},
|
||||
EditRange: Ignored,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
. "github.com/microsoft/typescript-go/internal/fourslash/tests/util"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCompletionsPathUnknownExtension(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
|
||||
const content = `// @filename: src/some-file.ruhroh
|
||||
/* This is just a test file that needs to exist. */
|
||||
|
||||
// @filename: package.json
|
||||
{
|
||||
"imports": {
|
||||
"#/*": "./src/*"
|
||||
}
|
||||
}
|
||||
|
||||
// @filename: src/globals.d.ts
|
||||
declare module "*.ruhroh";
|
||||
|
||||
// @filename: src/a.mts
|
||||
import "#//*$*/"
|
||||
|
||||
// @filename: tsconfig.json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "preserve",
|
||||
"moduleResolution": "bundler",
|
||||
"rootDir": "src"
|
||||
},
|
||||
"include": ["src"]
|
||||
}`
|
||||
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyCompletions(t, "$", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &[]string{},
|
||||
EditRange: Ignored,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Includes: []fourslash.CompletionsExpectedItem{
|
||||
"some-file.ruhroh",
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
. "github.com/microsoft/typescript-go/internal/fourslash/tests/util"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCompletionsSelfDeclaring2(t *testing.T) {
|
||||
t.Parallel()
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @lib: es5
|
||||
function f1<T>(x: T) {}
|
||||
f1({ [|abc|]/*1*/ });`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyCompletions(t, "1", &fourslash.CompletionsExpectedList{
|
||||
IsIncomplete: false,
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &[]string{},
|
||||
EditRange: &fourslash.EditRange{
|
||||
Insert: f.Ranges()[0],
|
||||
Replace: f.Ranges()[0],
|
||||
},
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{
|
||||
Exact: CompletionGlobalsPlus([]fourslash.CompletionsExpectedItem{
|
||||
"f1",
|
||||
}, false /*noLib*/),
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package fourslash_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/typescript-go/internal/fourslash"
|
||||
. "github.com/microsoft/typescript-go/internal/fourslash/tests/util"
|
||||
"github.com/microsoft/typescript-go/internal/testutil"
|
||||
)
|
||||
|
||||
func TestCompletionsUnterminatedLiteral(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
|
||||
const content = `// @noLib: true
|
||||
function foo(a"/*1*/`
|
||||
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
|
||||
defer done()
|
||||
f.VerifyCompletions(t, "1", &fourslash.CompletionsExpectedList{
|
||||
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
|
||||
CommitCharacters: &DefaultCommitCharacters,
|
||||
},
|
||||
Items: &fourslash.CompletionsExpectedItems{},
|
||||
})
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user