vendor tsgo

This commit is contained in:
2026-07-09 16:50:43 -04:00
parent c06ea2e5a4
commit 98978e4930
5804 changed files with 1556156 additions and 101 deletions

View File

@@ -0,0 +1,22 @@
package fourslash_test
import (
"testing"
"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestNavigationBarJsDoc(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @allowJs: true
// @Filename: foo.js
/** @typedef {(number|string)} NumberLike */
/** @typedef {(string|number)} */
const x = 0;`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.VerifyBaselineDocumentSymbol(t)
}

View File

@@ -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 TestAugmentedTypesModule2(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `function /*11*/m2f(x: number) { };
namespace m2f { export interface I { foo(): void } }
var x: m2f./*1*/
var /*2*/r = m2f/*3*/;`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.VerifyQuickInfoAt(t, "11", "function m2f(x: number): void", "")
f.VerifyCompletions(t, "1", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &DefaultCommitCharacters,
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Exact: []fourslash.CompletionsExpectedItem{
"I",
},
},
})
f.Insert(t, "I.")
f.VerifyCompletions(t, nil, nil)
f.Backspace(t, 1)
f.VerifyQuickInfoAt(t, "2", "var r: (x: number) => void", "")
f.GoToMarker(t, "3")
f.Insert(t, "(")
f.VerifySignatureHelp(t, fourslash.VerifySignatureHelpOptions{Text: "m2f(x: number): void"})
}

View File

@@ -0,0 +1,72 @@
package fourslash
import (
"testing"
"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestAutoCloseFragment(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
const x = <>/*0*/;
// @Filename: /1.tsx
const x = <> foo/*1*/ </>;
// @Filename: /2.tsx
const x = <></>/*2*/;
// @Filename: /3.tsx
const x = </>/*3*/;
// @Filename: /4.tsx
const x = <div>
<>/*4*/
</div>
</>;
// @Filename: /5.tsx
const x = <> text /*5*/;
// @Filename: /6.tsx
const x = <>
<>/*6*/
</>;
// @Filename: /7.tsx
const x = <div>
<>/*7*/
</div>;
// @Filename: /8.tsx
const x = <div>
<>/*8*/</>
</div>;
// @Filename: /9.tsx
const x = <p>
<>
<>/*9*/
</>
</p>`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.VerifyJsxClosingTag(t, map[string]*string{
"0": new("</>"),
"1": nil,
"2": nil,
"3": nil,
"4": new("</>"),
"5": new("</>"),
"6": new("</>"),
"7": new("</>"),
"8": nil,
"9": new("</>"),
})
}

View File

@@ -0,0 +1,73 @@
package fourslash
import (
"testing"
"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestAutoCloseTag(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
const x = <div>/*0*/;
// @Filename: /1.tsx
const x = <div> foo/*1*/ </div>;
// @Filename: /2.tsx
const x = <div></div>/*2*/;
// @Filename: /3.tsx
const x = <div/>/*3*/;
// @Filename: /4.tsx
const x = <div>
<p>/*4*/
</div>
</p>;
// @Filename: /5.tsx
const x = <div> text /*5*/;
// @Filename: /6.tsx
const x = <div>
<div>/*6*/
</div>;
// @Filename: /7.tsx
const x = <div>
<p>/*7*/
</div>;
// @Filename: /8.tsx
const x = <div>
<div>/*8*/</div>
</div>;
// @Filename: /9.tsx
const x = <p>
<div>
<div>/*9*/
</div>
</p>`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.VerifyJsxClosingTag(t, map[string]*string{
"0": new("</div>"),
"1": nil,
"2": nil,
"3": nil,
"4": new("</p>"),
"5": new("</div>"),
"6": new("</div>"),
"7": new("</p>"),
"8": nil,
"9": new("</div>"),
})
}

View File

@@ -0,0 +1,51 @@
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 TestAutoImportCrossProject_symlinks_toSrc(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @Filename: /home/src/workspaces/project/packages/app/package.json
{ "name": "app", "dependencies": { "dep": "*" } }
// @Filename: /home/src/workspaces/project/packages/app/tsconfig.json
{
"compilerOptions": {
"lib": ["es5"],
"module": "commonjs",
"outDir": "dist",
"rootDir": "src",
"baseUrl": "."
}
"references": [{ "path": "../dep" }]
}
// @Filename: /home/src/workspaces/project/packages/app/src/index.ts
dep/**/
// @Filename: /home/src/workspaces/project/packages/dep/package.json
{ "name": "dep", "main": "dist/index.js", "types": "dist/index.d.ts" }
// @Filename: /home/src/workspaces/project/packages/dep/tsconfig.json
{
"compilerOptions": { "lib": ["es5"], "outDir": "dist", "rootDir": "src", "module": "commonjs" }
}
// @Filename: /home/src/workspaces/project/packages/dep/src/index.ts
import "./sub/folder";
// @Filename: /home/src/workspaces/project/packages/dep/src/sub/folder/index.ts
export const dep = 0;
// @link: /home/src/workspaces/project/packages/dep -> /home/src/workspaces/project/packages/app/node_modules/dep`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.Configure(t, lsutil.UserPreferences{AutoImportEntrypointDirectorySearch: core.TSTrue})
f.MarkTestAsStradaServer()
f.GoToMarker(t, "")
f.VerifyImportFixAtPosition(t, []string{
`import { dep } from "dep/src/sub/folder";
dep`,
}, nil /*preferences*/)
}

View File

@@ -0,0 +1,25 @@
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 TestAutoImportNoPackageJson_commonjs(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @lib: es5
// @module: commonjs
// @Filename: /node_modules/lit/index.d.cts
export declare function customElement(name: string): any;
// @Filename: /a.ts
customElement/**/`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.Configure(t, lsutil.UserPreferences{AutoImportEntrypointDirectorySearch: core.TSTrue})
f.VerifyImportFixModuleSpecifiers(t, "", []string{"lit/index.cjs"}, nil /*preferences*/)
}

View File

@@ -0,0 +1,25 @@
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 TestAutoImportNoPackageJson_nodenext(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @lib: es5
// @module: node18
// @Filename: /node_modules/lit/index.d.cts
export declare function customElement(name: string): any;
// @Filename: /a.ts
customElement/**/`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.Configure(t, lsutil.UserPreferences{AutoImportEntrypointDirectorySearch: core.TSTrue})
f.VerifyImportFixModuleSpecifiers(t, "", []string{"lit/index.cjs"}, nil /*preferences*/)
}

View File

@@ -0,0 +1,36 @@
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 TestAutoImportPackageRootPathExtension(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @allowJs: true
// @Filename: /node_modules/pkg/package.json
{
"name": "pkg",
"version": "1.0.0",
"main": "lib"
}
// @Filename: /node_modules/pkg/lib/index.d.mts
export declare function foo(): any;
// @Filename: /package.json
{
"dependencies": {
"pkg": "*"
}
}
// @Filename: /index.ts
foo/**/`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.Configure(t, lsutil.UserPreferences{AutoImportEntrypointDirectorySearch: core.TSTrue})
f.VerifyImportFixModuleSpecifiers(t, "", []string{"pkg/lib/index.mjs"}, nil /*preferences*/)
}

View File

@@ -0,0 +1,35 @@
package fourslash_test
import (
"testing"
"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestAutoImportPackageRootPathTypeModule(t *testing.T) {
t.Skip()
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @allowJs: true
// @Filename: /node_modules/pkg/package.json
{
"name": "pkg",
"version": "1.0.0",
"main": "lib",
"type": "module"
}
// @Filename: /node_modules/pkg/lib/index.js
export function foo() {};
// @Filename: /package.json
{
"dependencies": {
"pkg": "*"
}
}
// @Filename: /index.ts
foo/**/`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.VerifyImportFixModuleSpecifiers(t, "", []string{"pkg"}, nil /*preferences*/)
}

View File

@@ -0,0 +1,39 @@
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 TestAutoImportProvider5(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @lib: es5
// @Filename: /home/src/workspaces/project/package.json
{ "dependencies": { "react-hook-form": "*" } }
// @Filename: /home/src/workspaces/project/node_modules/react-hook-form/package.json
{ "types": "dist/index.d.ts" }
// @Filename: /home/src/workspaces/project/node_modules/react-hook-form/dist/index.d.ts
export * from "./useForm";
// @Filename: /home/src/workspaces/project/node_modules/react-hook-form/dist/useForm.d.ts
export declare function useForm(): void;
// @Filename: /home/src/workspaces/project/index.ts
useForm/**/`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.Configure(t, lsutil.UserPreferences{AutoImportEntrypointDirectorySearch: core.TSTrue})
f.MarkTestAsStradaServer()
f.GoToMarker(t, "")
f.VerifyImportFixAtPosition(t, []string{
`import { useForm } from "react-hook-form";
useForm`,
`import { useForm } from "react-hook-form/dist/useForm";
useForm`,
}, nil /*preferences*/)
}

View File

@@ -0,0 +1,34 @@
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 TestAutoImportSymlinkCaseSensitive(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @Filename: /tsconfig.json
{ "compilerOptions": { "module": "commonjs" } }
// @Filename: /node_modules/.pnpm/mobx@6.0.4/node_modules/MobX/Foo.d.ts
export declare function autorun(): void;
// @Filename: /index.ts
autorun/**/
// @Filename: /utils.ts
import "MobX/Foo";
// @link: /node_modules/.pnpm/mobx@6.0.4/node_modules/MobX -> /node_modules/MobX
// @link: /node_modules/.pnpm/mobx@6.0.4/node_modules/MobX -> /node_modules/.pnpm/cool-mobx-dependent@1.2.3/node_modules/MobX`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.Configure(t, lsutil.UserPreferences{AutoImportEntrypointDirectorySearch: core.TSTrue})
f.GoToMarker(t, "")
f.VerifyImportFixAtPosition(t, []string{
`import { autorun } from "MobX/Foo";
autorun`,
}, nil /*preferences*/)
}

View File

@@ -0,0 +1,75 @@
package fourslash_test
import (
"testing"
"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestCodeFixMissingTypeAnnotationOnExports45_decorators(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @isolatedDeclarations: true
// @declaration: true
// @Filename: /code.ts
function classDecorator<T extends Function> (value: T, context: ClassDecoratorContext) {}
function methodDecorator<This> (
target: (...args: number[])=> number,
context: ClassMethodDecoratorContext<This, (this: This, ...args: number[]) => number>) {}
function getterDecorator(value: Function, context: ClassGetterDecoratorContext) {}
function setterDecorator(value: Function, context: ClassSetterDecoratorContext) {}
function fieldDecorator(value: undefined, context: ClassFieldDecoratorContext) {}
function foo() { return 42;}
@classDecorator
export class A {
@methodDecorator
sum(...args: number[]) {
return args.reduce((a, b) => a + b, 0);
}
getSelf() {
return this;
}
@getterDecorator
get a() {
return foo();
}
@setterDecorator
set a(value) {}
@fieldDecorator classProp = foo();
}`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.VerifyCodeFixAll(t, fourslash.VerifyCodeFixAllOptions{
FixID: "fixMissingTypeAnnotationOnExports",
NewFileContent: `function classDecorator<T extends Function> (value: T, context: ClassDecoratorContext) {}
function methodDecorator<This> (
target: (...args: number[])=> number,
context: ClassMethodDecoratorContext<This, (this: This, ...args: number[]) => number>) {}
function getterDecorator(value: Function, context: ClassGetterDecoratorContext) {}
function setterDecorator(value: Function, context: ClassSetterDecoratorContext) {}
function fieldDecorator(value: undefined, context: ClassFieldDecoratorContext) {}
function foo() { return 42;}
@classDecorator
export class A {
@methodDecorator
sum(...args: number[]): number {
return args.reduce((a, b) => a + b, 0);
}
getSelf(): this {
return this;
}
@getterDecorator
get a(): number {
return foo();
}
@setterDecorator
set a(value: number) {}
@fieldDecorator classProp: number = foo();
}`,
})
}

View File

@@ -0,0 +1,74 @@
package fourslash_test
import (
"testing"
"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestCodeFixMissingTypeAnnotationOnExports46_decorators_experimental(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @isolatedDeclarations: true
// @declaration: true
// @experimentalDecorators: true
// @Filename: /code.ts
function classDecorator<T extends Function>() { return (target: T) => target; }
function methodDecorator() { return (target: any, key: string, descriptor: PropertyDescriptor) => descriptor;}
function parameterDecorator() { return (target: any, key: string, idx: number) => {};}
function getterDecorator() { return (target: any, key: string) => {}; }
function setterDecorator() { return (target: any, key: string) => {}; }
function fieldDecorator() { return (target: any, key: string) => {}; }
function foo() { return 42; }
@classDecorator()
export class A {
@methodDecorator()
sum(...args: number[]) {
return args.reduce((a, b) => a + b, 0);
}
getSelf() {
return this;
}
passParameter(@parameterDecorator() param = foo()) {}
@getterDecorator()
get a() {
return foo();
}
@setterDecorator()
set a(value) {}
@fieldDecorator() classProp = foo();
}`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.VerifyCodeFixAll(t, fourslash.VerifyCodeFixAllOptions{
FixID: "fixMissingTypeAnnotationOnExports",
NewFileContent: `function classDecorator<T extends Function>() { return (target: T) => target; }
function methodDecorator() { return (target: any, key: string, descriptor: PropertyDescriptor) => descriptor;}
function parameterDecorator() { return (target: any, key: string, idx: number) => {};}
function getterDecorator() { return (target: any, key: string) => {}; }
function setterDecorator() { return (target: any, key: string) => {}; }
function fieldDecorator() { return (target: any, key: string) => {}; }
function foo() { return 42; }
@classDecorator()
export class A {
@methodDecorator()
sum(...args: number[]): number {
return args.reduce((a, b) => a + b, 0);
}
getSelf(): this {
return this;
}
passParameter(@parameterDecorator() param: number = foo()): void {}
@getterDecorator()
get a(): number {
return foo();
}
@setterDecorator()
set a(value: number) {}
@fieldDecorator() classProp: number = foo();
}`,
})
}

View File

@@ -0,0 +1,31 @@
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"
)
// Test for issue: Completions crash after `import` when statement is preceded by JSDoc.
// When requesting completions after an import keyword preceded by JSDoc,
// getSingleLineReplacementSpanForImportCompletionNode panics because it assumes
// the ImportKeyword is on a single line, but node.Pos() includes JSDoc comments.
func TestCompletionAfterImportWithJSDoc(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @Filename: /index.ts
/** hello! */
import /**/`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
// Should not crash when requesting completions after import preceded by JSDoc
f.VerifyCompletions(t, "", &fourslash.CompletionsExpectedList{
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &[]string{},
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{},
})
}

View File

@@ -0,0 +1,88 @@
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 TestCompletionForStringLiteralExport(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @typeRoots: my_typings
// @Filename: fourslash/test.ts
export * from "./some/*0*/
export * from "./sub/some/*1*/";
export * from "[|some-/*2*/|]";
export * from "..//*3*/";
export {} from ".//*4*/";
// @Filename: fourslash/someFile1.ts
/*someFile1*/
// @Filename: fourslash/sub/someFile2.ts
/*someFile2*/
// @Filename: fourslash/my_typings/some-module/index.d.ts
export var x = 9;`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.VerifyCompletions(t, []string{"0", "4"}, &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &[]string{},
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Unsorted: []fourslash.CompletionsExpectedItem{
"someFile1",
"my_typings",
"sub",
},
},
})
f.VerifyCompletions(t, "1", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &[]string{},
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Unsorted: []fourslash.CompletionsExpectedItem{
"someFile2",
},
},
})
f.VerifyCompletions(t, "2", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &[]string{},
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Unsorted: []fourslash.CompletionsExpectedItem{
&lsproto.CompletionItem{
Label: "some-module",
TextEdit: &lsproto.TextEditOrInsertReplaceEdit{
TextEdit: &lsproto.TextEdit{
NewText: "some-module",
Range: f.Ranges()[0].LSRange,
},
},
},
},
},
})
f.VerifyCompletions(t, "3", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &[]string{},
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Unsorted: []fourslash.CompletionsExpectedItem{
"fourslash",
},
},
})
}

View File

@@ -0,0 +1,87 @@
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 TestCompletionForStringLiteralImport1(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @typeRoots: my_typings
// @Filename: fourslash/test.ts
import * as foo0 from "./some/*0*/
import * as foo1 from "./sub/some/*1*/
import * as foo2 from "[|some-|]/*2*/"
import * as foo3 from "..//*3*/";
// @Filename: fourslash/someFile1.ts
/*someFile1*/
// @Filename: fourslash/sub/someFile2.ts
/*someFile2*/
// @Filename: fourslash/my_typings/some-module/index.d.ts
export var x = 9;`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.VerifyCompletions(t, "0", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &[]string{},
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Unsorted: []fourslash.CompletionsExpectedItem{
"someFile1",
"my_typings",
"sub",
},
},
})
f.VerifyCompletions(t, "1", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &[]string{},
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Unsorted: []fourslash.CompletionsExpectedItem{
"someFile2",
},
},
})
f.VerifyCompletions(t, "2", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &[]string{},
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Unsorted: []fourslash.CompletionsExpectedItem{
&lsproto.CompletionItem{
Label: "some-module",
TextEdit: &lsproto.TextEditOrInsertReplaceEdit{
TextEdit: &lsproto.TextEdit{
NewText: "some-module",
Range: f.Ranges()[0].LSRange,
},
},
},
},
},
})
f.VerifyCompletions(t, "3", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &[]string{},
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Unsorted: []fourslash.CompletionsExpectedItem{
"fourslash",
},
},
})
}

View File

@@ -0,0 +1,78 @@
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 TestCompletionForStringLiteralImport2(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @typeRoots: my_typings
// @Filename: test.ts
/// <reference path="./[|some|]/*0*/
/// <reference types="[|some|]/*1*/
/// <reference path="./sub/[|some|]/*2*/" />
/// <reference types="[|some|]/*3*/" />
// @Filename: someFile.ts
/*someFile*/
// @Filename: sub/someOtherFile.ts
/*someOtherFile*/
// @Filename: my_typings/some-module/index.d.ts
export var x = 9;`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.VerifyCompletions(t, "0", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &[]string{},
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Unsorted: []fourslash.CompletionsExpectedItem{
"someFile.ts",
"my_typings",
"sub",
},
},
})
f.VerifyCompletions(t, "1", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &[]string{},
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Exact: []fourslash.CompletionsExpectedItem{
"some-module",
},
},
})
f.VerifyCompletions(t, "2", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &[]string{},
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Exact: []fourslash.CompletionsExpectedItem{
"someOtherFile.ts",
},
},
})
f.VerifyCompletions(t, "3", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &[]string{},
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Exact: []fourslash.CompletionsExpectedItem{
"some-module",
},
},
})
}

View File

@@ -0,0 +1,42 @@
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 TestCompletionForStringLiteralNonrelativeImport12(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @Filename: tests/test0.ts
import * as foo1 from "m/*import_as0*/
import foo2 = require("m/*import_equals0*/
var foo3 = require("m/*require0*/
// @Filename: package.json
{
"dependencies": { "module": "latest" },
"devDependencies": { "dev-module": "latest" },
"optionalDependencies": { "optional-module": "latest" },
"peerDependencies": { "peer-module": "latest" }
}`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.VerifyCompletions(t, f.Markers(), &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &[]string{},
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Unsorted: []fourslash.CompletionsExpectedItem{
"module",
"dev-module",
"peer-module",
"optional-module",
},
},
})
}

View File

@@ -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/testutil"
)
func TestCompletionForStringLiteralNonrelativeImport4(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @Filename: dir1/dir2/dir3/dir4/test0.ts
import * as foo1 from "f/*import_as0*/
import foo4 = require("f/*import_equals0*/
var foo7 = require("f/*require0*/
// @Filename: package.json
{ "dependencies": { "fake-module": "latest" } }
// @Filename: node_modules/fake-module/ts.ts
// @Filename: dir1/package.json
{ "dependencies": { "fake-module2": "latest" } }
// @Filename: dir1/node_modules/fake-module2/index.ts
// @Filename: dir1/dir2/dir3/package.json
{ "dependencies": { "fake-module3": "latest" } }
// @Filename: dir1/dir2/dir3/node_modules/fake-module3/ts.ts
`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.VerifyCompletions(t, f.Markers(), &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &[]string{},
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Unsorted: []fourslash.CompletionsExpectedItem{
"fake-module3",
"fake-module2",
"fake-module",
},
},
})
}

View File

@@ -0,0 +1,75 @@
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 TestCompletionForStringLiteralRelativeImport4(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @rootDirs: /sub/src1,/src2
// @Filename: /src2/test0.ts
import * as foo1 from "./mo/*import_as0*/
import foo2 = require("./mo/*import_equals0*/
var foo3 = require("./mo/*require0*/
// @Filename: /src2/inner/inner0.ts
import * as s from ".//*inner*/";
// @Filename: /src2/inner/inner1.ts
export const x = 0;
// @Filename: /src2/module0.ts
export var w = 0;
// @Filename: /sub/src1/module1.ts
export var x = 0;
// @Filename: /sub/src1/module2.ts
export var y = 0;
// @Filename: /sub/src1/more/module3.ts
export var z = 0;
// @Filename: f1.ts
// @Filename: f2.tsx
// @Filename: folder/f1.ts
// @Filename: f3.js
// @Filename: f4.jsx
// @Filename: e1.ts
// @Filename: e2.js
`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.VerifyCompletions(t, []string{"import_as0", "import_equals0", "require0"}, &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &[]string{},
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Unsorted: []fourslash.CompletionsExpectedItem{
"module1",
"module2",
"more",
"module0",
"inner",
},
},
})
f.VerifyCompletions(t, "inner", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &[]string{},
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Unsorted: []fourslash.CompletionsExpectedItem{
"inner1",
},
},
})
}

View File

@@ -0,0 +1,87 @@
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 TestCompletionForStringLiteralWithDynamicImport(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @typeRoots: my_typings
// @Filename: fourslash/test.ts
const a = import("./some/*0*/
const a = import("./sub/some/*1*/");
const a = import("[|some-/*2*/|]");
const a = import("..//*3*/");
// @Filename: fourslash/someFile1.ts
/*someFile1*/
// @Filename: fourslash/sub/someFile2.ts
/*someFile2*/
// @Filename: fourslash/my_typings/some-module/index.d.ts
export var x = 9;`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.VerifyCompletions(t, "0", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &[]string{},
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Unsorted: []fourslash.CompletionsExpectedItem{
"someFile1",
"my_typings",
"sub",
},
},
})
f.VerifyCompletions(t, "1", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &[]string{},
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Unsorted: []fourslash.CompletionsExpectedItem{
"someFile2",
},
},
})
f.VerifyCompletions(t, "2", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &[]string{},
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Unsorted: []fourslash.CompletionsExpectedItem{
&lsproto.CompletionItem{
Label: "some-module",
TextEdit: &lsproto.TextEditOrInsertReplaceEdit{
TextEdit: &lsproto.TextEdit{
NewText: "some-module",
Range: f.Ranges()[0].LSRange,
},
},
},
},
},
})
f.VerifyCompletions(t, "3", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &[]string{},
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Unsorted: []fourslash.CompletionsExpectedItem{
"fourslash",
},
},
})
}

View File

@@ -0,0 +1,115 @@
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 TestCompletionForStringLiteral_details(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @Filename: /other.ts
export const x = 0;
// @Filename: /a.ts
import {} from ".//*path*/";
const x: "a" = "[|/*type*/|]";
interface I {
/** Prop doc */
x: number;
/** Method doc */
m(): void;
}
declare const o: I;
o["[|/*prop*/|]"];`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.VerifyCompletions(t, "path", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &[]string{},
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Includes: []fourslash.CompletionsExpectedItem{
&lsproto.CompletionItem{
Label: "other",
Detail: new("other.ts"),
Kind: new(lsproto.CompletionItemKindFile),
},
},
},
})
f.VerifyCompletions(t, "type", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &DefaultCommitCharacters,
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Exact: []fourslash.CompletionsExpectedItem{
&lsproto.CompletionItem{
Label: "a",
Detail: new("a"),
Kind: new(lsproto.CompletionItemKindConstant),
TextEdit: &lsproto.TextEditOrInsertReplaceEdit{
TextEdit: &lsproto.TextEdit{
NewText: "a",
Range: f.Ranges()[0].LSRange,
},
},
},
},
},
})
f.VerifyCompletions(t, "prop", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &DefaultCommitCharacters,
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Exact: []fourslash.CompletionsExpectedItem{
&lsproto.CompletionItem{
Label: "m",
Detail: new("(method) I.m(): void"),
Documentation: &lsproto.StringOrMarkupContent{
MarkupContent: &lsproto.MarkupContent{
Kind: lsproto.MarkupKindMarkdown,
Value: "Method doc",
},
},
Kind: new(lsproto.CompletionItemKindMethod),
TextEdit: &lsproto.TextEditOrInsertReplaceEdit{
TextEdit: &lsproto.TextEdit{
NewText: "m",
Range: f.Ranges()[1].LSRange,
},
},
},
&lsproto.CompletionItem{
Label: "x",
Detail: new("(property) I.x: number"),
Documentation: &lsproto.StringOrMarkupContent{
MarkupContent: &lsproto.MarkupContent{
Kind: lsproto.MarkupKindMarkdown,
Value: "Prop doc",
},
},
Kind: new(lsproto.CompletionItemKindField),
TextEdit: &lsproto.TextEditOrInsertReplaceEdit{
TextEdit: &lsproto.TextEdit{
NewText: "x",
Range: f.Ranges()[1].LSRange,
},
},
},
},
},
})
}

View File

@@ -0,0 +1,54 @@
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/lsutil"
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestCompletionImportModuleSpecifierEndingDts(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `//@Filename:test.d.ts
export declare class Test {}
//@Filename:module.ts
import { Test } from ".//**/"`
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{
&lsproto.CompletionItem{
Label: "test.js",
Detail: new("test.js"),
},
},
},
UserPreferences: &lsutil.UserPreferences{ImportModuleSpecifierEnding: "js"},
})
f.VerifyCompletions(t, "", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &[]string{},
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Includes: []fourslash.CompletionsExpectedItem{
&lsproto.CompletionItem{
Label: "test",
Detail: new("test.d.ts"),
},
},
},
UserPreferences: &lsutil.UserPreferences{ImportModuleSpecifierEnding: "index"},
})
}

View File

@@ -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/lsutil"
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestCompletionImportModuleSpecifierEndingJs(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `//@allowJs: true
//@Filename:test.js
export function f(){
return 1
}
//@Filename:module.js
import { f } from ".//**/"`
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{
&lsproto.CompletionItem{
Label: "test.js",
Detail: new("test.js"),
},
},
},
UserPreferences: &lsutil.UserPreferences{ImportModuleSpecifierEnding: "js"},
})
f.VerifyCompletions(t, "", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &[]string{},
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Includes: []fourslash.CompletionsExpectedItem{
&lsproto.CompletionItem{
Label: "test",
Detail: new("test.js"),
},
},
},
UserPreferences: &lsutil.UserPreferences{ImportModuleSpecifierEnding: "index"},
})
}

View File

@@ -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/lsutil"
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestCompletionImportModuleSpecifierEndingJsx(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `//@allowJs: true
//@jsx:preserve
//@Filename:test.jsx
export class Test { }
//@Filename:module.jsx
import { Test } from ".//**/"`
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{
&lsproto.CompletionItem{
Label: "test.jsx",
Detail: new("test.jsx"),
},
},
},
UserPreferences: &lsutil.UserPreferences{ImportModuleSpecifierEnding: "js"},
})
f.VerifyCompletions(t, "", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &[]string{},
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Includes: []fourslash.CompletionsExpectedItem{
&lsproto.CompletionItem{
Label: "test",
Detail: new("test.jsx"),
},
},
},
UserPreferences: &lsutil.UserPreferences{ImportModuleSpecifierEnding: "index"},
})
}

View File

@@ -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/lsutil"
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestCompletionImportModuleSpecifierEndingTs(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `//@Filename:test.ts
export function f(){
return 1
}
//@Filename:module.ts
import { f } from ".//**/"`
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{
&lsproto.CompletionItem{
Label: "test.js",
Detail: new("test.js"),
},
},
},
UserPreferences: &lsutil.UserPreferences{ImportModuleSpecifierEnding: "js"},
})
f.VerifyCompletions(t, "", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &[]string{},
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Includes: []fourslash.CompletionsExpectedItem{
&lsproto.CompletionItem{
Label: "test",
Detail: new("test.ts"),
},
},
},
UserPreferences: &lsutil.UserPreferences{ImportModuleSpecifierEnding: "index"},
})
}

View File

@@ -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/ls/lsutil"
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestCompletionImportModuleSpecifierEndingTsxPreserve(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `//@jsx:preserve
//@Filename:test.tsx
export class Test { }
//@Filename:module.tsx
import { Test } from ".//**/"`
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{
&lsproto.CompletionItem{
Label: "test.jsx",
Detail: new("test.jsx"),
},
},
},
UserPreferences: &lsutil.UserPreferences{ImportModuleSpecifierEnding: "js"},
})
f.VerifyCompletions(t, "", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &[]string{},
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Includes: []fourslash.CompletionsExpectedItem{
&lsproto.CompletionItem{
Label: "test",
Detail: new("test.tsx"),
},
},
},
UserPreferences: &lsutil.UserPreferences{ImportModuleSpecifierEnding: "index"},
})
}

View File

@@ -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/ls/lsutil"
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestCompletionImportModuleSpecifierEndingTsxReact(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `//@jsx:react
//@Filename:test.tsx
export class Test { }
//@Filename:module.tsx
import { Test } from ".//**/"`
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{
&lsproto.CompletionItem{
Label: "test.js",
Detail: new("test.js"),
},
},
},
UserPreferences: &lsutil.UserPreferences{ImportModuleSpecifierEnding: "js"},
})
f.VerifyCompletions(t, "", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &[]string{},
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Includes: []fourslash.CompletionsExpectedItem{
&lsproto.CompletionItem{
Label: "test",
Detail: new("test.tsx"),
},
},
},
UserPreferences: &lsutil.UserPreferences{ImportModuleSpecifierEnding: "index"},
})
}

View File

@@ -0,0 +1,102 @@
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 TestCompletionInTernaryConditional(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `export enum Bar { }
export enum Foo { }
function foo(x: Foo) { return x; }
function bar(z: string, x: Foo) { return x; }
const a = '';
foo(/*1*/);
bar(a, a == '' ? /*2*/);
bar(a, a == '' ? /*3*/ : /*4*/);`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
// Test marker 1 - should have Foo preselected in simple call
f.VerifyCompletions(t, "1", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &DefaultCommitCharacters,
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Includes: []fourslash.CompletionsExpectedItem{
&lsproto.CompletionItem{
Label: "Foo",
Kind: new(lsproto.CompletionItemKindEnum),
Preselect: new(true),
},
},
},
})
// Test marker 2 - should have Foo preselected after ? in incomplete ternary
f.VerifyCompletions(t, "2", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &DefaultCommitCharacters,
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Includes: []fourslash.CompletionsExpectedItem{
&lsproto.CompletionItem{
Label: "Foo",
Kind: new(lsproto.CompletionItemKindEnum),
Preselect: new(true),
},
},
},
})
// Test marker 3 - should have Foo preselected after ? in ternary with colon
f.VerifyCompletions(t, "3", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &DefaultCommitCharacters,
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Includes: []fourslash.CompletionsExpectedItem{
&lsproto.CompletionItem{
Label: "Foo",
Kind: new(lsproto.CompletionItemKindEnum),
Preselect: new(true),
},
},
},
})
// Test marker 4 - should have Foo preselected after : in ternary
f.VerifyCompletions(t, "4", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &DefaultCommitCharacters,
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Includes: []fourslash.CompletionsExpectedItem{
&lsproto.CompletionItem{
Label: "Foo",
Kind: new(lsproto.CompletionItemKindEnum),
Preselect: new(true),
},
},
},
})
}

View File

@@ -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 TestCompletionListInClosedFunction05(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `function foo(x: string, y: number, z: boolean) {
function bar(a: number, b: string = "hello", c: typeof x = "hello") {
var v = /*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{
"foo",
"x",
"y",
"z",
"bar",
"a",
"b",
"c",
},
},
})
}

View File

@@ -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/testutil"
)
func TestCompletionListInImportClause05(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @Filename: app.ts
import * as A from "/*1*/";
// @Filename: /node_modules/@types/a__b/index.d.ts
declare module "@e/f" { function fun(): string; }
// @Filename: /node_modules/@types/c__d/index.d.ts
export declare let x: number;`
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{
Unsorted: []fourslash.CompletionsExpectedItem{
"@e/f",
"@a/b",
"@c/d",
},
},
})
}

View File

@@ -0,0 +1,89 @@
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 TestCompletionListInTypeLiteralInTypeParameter21(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `class Foo<T extends ('one' | 2)[]> {}
function foo<T extends ('one' | 2)[]>() {}
type A = Foo<[/*0*/]>;
new Foo<[/*1*/]>();
foo<[/*2*/]>();
foo<[/*3*/]>;
Foo<[/*4*/]>;`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.VerifyCompletions(t, "0", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &DefaultCommitCharacters,
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Includes: []fourslash.CompletionsExpectedItem{
"\"one\"",
"2",
},
},
})
f.VerifyCompletions(t, "1", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &DefaultCommitCharacters,
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Includes: []fourslash.CompletionsExpectedItem{
"\"one\"",
"2",
},
},
})
f.VerifyCompletions(t, "2", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &DefaultCommitCharacters,
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Includes: []fourslash.CompletionsExpectedItem{
"\"one\"",
"2",
},
},
})
f.VerifyCompletions(t, "3", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &DefaultCommitCharacters,
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Includes: []fourslash.CompletionsExpectedItem{
"\"one\"",
"2",
},
},
})
f.VerifyCompletions(t, "4", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &DefaultCommitCharacters,
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Includes: []fourslash.CompletionsExpectedItem{
"\"one\"",
"2",
},
},
})
}

View File

@@ -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/testutil"
)
func TestCompletionListWithLabel(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = ` label: while (true) {
break /*1*/
continue /*2*/
testlabel: while (true) {
break /*3*/
continue /*4*/
break tes/*5*/
continue tes/*6*/
}
break /*7*/
break; /*8*/
}`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.VerifyCompletions(t, []string{"1", "2", "7"}, &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &DefaultCommitCharacters,
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Exact: []fourslash.CompletionsExpectedItem{
"label",
},
},
})
f.VerifyCompletions(t, []string{"3", "4", "5", "6"}, &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &DefaultCommitCharacters,
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Exact: []fourslash.CompletionsExpectedItem{
"label",
"testlabel",
},
},
})
f.VerifyCompletions(t, "8", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &DefaultCommitCharacters,
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Excludes: []string{
"label",
},
},
})
}

View File

@@ -0,0 +1,49 @@
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 TestCompletionsAtIncompleteObjectLiteralProperty(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @noLib: true
f({
[|a|]/**/
xyz: ` + "`" + `` + "`" + `,
});
declare function f(options: { abc?: number, xyz?: string }): void;`
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{
Exact: []fourslash.CompletionsExpectedItem{
&lsproto.CompletionItem{
Label: "abc?",
FilterText: new("abc"),
Kind: new(lsproto.CompletionItemKindField),
SortText: new(string(ls.SortTextOptionalMember)),
TextEdit: &lsproto.TextEditOrInsertReplaceEdit{
InsertReplaceEdit: &lsproto.InsertReplaceEdit{
NewText: "abc",
Insert: f.Ranges()[0].LSRange,
Replace: f.Ranges()[0].LSRange,
},
},
},
},
},
})
}

View File

@@ -0,0 +1,72 @@
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 TestCompletionsImport_defaultAndNamedConflict(t *testing.T) {
fourslash.SkipIfFailing(t)
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @noLib: true
// @Filename: /someModule.ts
export const someModule = 0;
export default 1;
// @Filename: /index.ts
someMo/**/`
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{
Exact: CompletionGlobalsPlus(
[]fourslash.CompletionsExpectedItem{
&lsproto.CompletionItem{
Label: "someModule",
Data: &lsproto.CompletionItemData{
AutoImport: &lsproto.AutoImportFix{
ModuleSpecifier: "./someModule",
},
},
Detail: new("const someModule: 0"),
Kind: new(lsproto.CompletionItemKindVariable),
AdditionalTextEdits: fourslash.AnyTextEdits,
SortText: new(string(ls.SortTextAutoImportSuggestions)),
},
&lsproto.CompletionItem{
Label: "someModule",
Data: &lsproto.CompletionItemData{
AutoImport: &lsproto.AutoImportFix{
ModuleSpecifier: "./someModule",
},
},
Detail: new("(property) default: 1"),
Kind: new(lsproto.CompletionItemKindField),
AdditionalTextEdits: fourslash.AnyTextEdits,
SortText: new(string(ls.SortTextAutoImportSuggestions)),
},
},
true,
),
},
})
f.VerifyApplyCodeActionFromCompletion(t, new(""), &fourslash.ApplyCodeActionFromCompletionOptions{
Name: "someModule",
Source: "./someModule",
AutoImportFix: &lsproto.AutoImportFix{},
Description: "Add import from \"./someModule\"",
NewFileContent: new(`import { someModule } from "./someModule";
someMo`),
})
}

View File

@@ -0,0 +1,64 @@
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"
"github.com/microsoft/typescript-go/internal/ls/lsutil"
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestCompletionsImport_defaultFalsePositive(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @Filename: /node_modules/foo/index.ts
export default function f(): void;
// @Filename: /node_modules/bar/concat.d.ts
export const concat = 0;
// @Filename: /a.ts
export {};
conca/**/`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
prefs := lsutil.NewDefaultUserPreferences()
prefs.AutoImportEntrypointDirectorySearch = core.TSTrue
f.Configure(t, prefs)
f.GoToFile(t, "/a.ts")
f.VerifyCompletions(t, "", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &DefaultCommitCharacters,
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Includes: []fourslash.CompletionsExpectedItem{
&lsproto.CompletionItem{
Label: "concat",
Data: &lsproto.CompletionItemData{
AutoImport: &lsproto.AutoImportFix{
ModuleSpecifier: "bar/concat",
},
},
Detail: new("const concat: 0"),
Kind: new(lsproto.CompletionItemKindVariable),
AdditionalTextEdits: fourslash.AnyTextEdits,
SortText: new(string(ls.SortTextAutoImportSuggestions)),
},
},
},
})
f.VerifyApplyCodeActionFromCompletion(t, new(""), &fourslash.ApplyCodeActionFromCompletionOptions{
Name: "concat",
Source: "bar/concat",
Description: "Add import from \"bar/concat\"",
UserPreferences: &prefs,
NewFileContent: new(`import { concat } from "bar/concat";
export {};
conca`),
})
}

View File

@@ -0,0 +1,143 @@
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 TestCompletionsImport_filteredByPackageJson_ambient(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @lib: es5
//@noEmit: true
//@Filename: /package.json
{
"dependencies": {
"react-syntax-highlighter": "*",
"declared-by-foo": "*"
}
}
//@Filename: /node_modules/@types/foo/index.d.ts
declare module "foo" {
export const foo: any;
}
declare module "declared-by-foo" {
export const declaredBySomethingNotInPackageJson: any;
}
//@Filename: /node_modules/@types/foo/package.json
{
"name": "@types/node"
}
//@Filename: /node_modules/@types/react-syntax-highlighter/index.d.ts
declare module "react-syntax-highlighter/sub" {
const agate: any;
export default agate;
}
declare module "something-else" {
export const somethingElse: any;
}
//@Filename: /node_modules/@types/react-syntax-highlighter/package.json
{
"name": "@types/react-syntax-highlighter"
}
//@Filename: /src/ambient.ts
declare module "local" {
export const local: any';
}
//@Filename: /src/index.ts
fo/*1*/
aga/*2*/
somethi/*3*/
declaredBy/*4*/
loca/*5*/`
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{
Exact: CompletionGlobals,
},
})
f.VerifyCompletions(t, "2", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &DefaultCommitCharacters,
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Includes: []fourslash.CompletionsExpectedItem{
&lsproto.CompletionItem{
Label: "agate",
Data: &lsproto.CompletionItemData{
AutoImport: &lsproto.AutoImportFix{
ModuleSpecifier: "react-syntax-highlighter/sub",
},
},
AdditionalTextEdits: fourslash.AnyTextEdits,
SortText: new(string(ls.SortTextAutoImportSuggestions)),
},
},
},
})
f.VerifyCompletions(t, "3", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &DefaultCommitCharacters,
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Includes: []fourslash.CompletionsExpectedItem{
&lsproto.CompletionItem{
Label: "somethingElse",
Data: &lsproto.CompletionItemData{
AutoImport: &lsproto.AutoImportFix{
ModuleSpecifier: "something-else",
},
},
AdditionalTextEdits: fourslash.AnyTextEdits,
SortText: new(string(ls.SortTextAutoImportSuggestions)),
},
},
},
})
f.VerifyCompletions(t, "4", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &DefaultCommitCharacters,
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Excludes: []string{"declaredBySomethingNotInPackageJson"},
},
})
f.VerifyCompletions(t, "5", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &DefaultCommitCharacters,
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Includes: []fourslash.CompletionsExpectedItem{
&lsproto.CompletionItem{
Label: "local",
Data: &lsproto.CompletionItemData{
AutoImport: &lsproto.AutoImportFix{
ModuleSpecifier: "local",
},
},
AdditionalTextEdits: fourslash.AnyTextEdits,
SortText: new(string(ls.SortTextAutoImportSuggestions)),
},
},
},
})
}

View File

@@ -0,0 +1,60 @@
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 TestCompletionsImport_reExportDefault(t *testing.T) {
fourslash.SkipIfFailing(t)
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @lib: es5
// @module: esnext
// @Filename: /a/b/impl.ts
export default function foo() {}
// @Filename: /a/index.ts
export { default as foo } from "./b/impl";
// @Filename: /use.ts
fo/**/`
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{
Exact: CompletionGlobalsPlus(
[]fourslash.CompletionsExpectedItem{
&lsproto.CompletionItem{
Label: "foo",
Data: &lsproto.CompletionItemData{
AutoImport: &lsproto.AutoImportFix{
ModuleSpecifier: "./a",
},
},
Detail: new("(alias) function foo(): void\nexport foo"),
Kind: new(lsproto.CompletionItemKindFunction),
AdditionalTextEdits: fourslash.AnyTextEdits,
SortText: new(string(ls.SortTextAutoImportSuggestions)),
},
}, false,
),
},
})
f.VerifyApplyCodeActionFromCompletion(t, new(""), &fourslash.ApplyCodeActionFromCompletionOptions{
Name: "foo",
Source: "./a",
Description: "Add import from \"./a\"",
NewFileContent: new(`import { foo } from "./a";
fo`),
})
}

View File

@@ -0,0 +1,64 @@
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 TestCompletionsImport_reexportTransient(t *testing.T) {
fourslash.SkipIfFailing(t)
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @lib: es5
// @esModuleInterop: true
// @Filename: /transient.d.ts
declare const map: { [K in "one"]: number };
export = map;
// @Filename: /r1.ts
export { one } from "./transient";
// @Filename: /r2.ts
export { one } from "./r1";
// @Filename: /index.ts
one/**/`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.GoToMarker(t, "")
f.VerifyCompletions(t, "", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &DefaultCommitCharacters,
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Exact: CompletionGlobalsPlus(
[]fourslash.CompletionsExpectedItem{
&lsproto.CompletionItem{
Label: "one",
Data: &lsproto.CompletionItemData{
AutoImport: &lsproto.AutoImportFix{
ModuleSpecifier: "./r1",
},
},
AdditionalTextEdits: fourslash.AnyTextEdits,
SortText: new(string(ls.SortTextAutoImportSuggestions)),
},
&lsproto.CompletionItem{
Label: "one",
Data: &lsproto.CompletionItemData{
AutoImport: &lsproto.AutoImportFix{
ModuleSpecifier: "./r2",
},
},
AdditionalTextEdits: fourslash.AnyTextEdits,
SortText: new(string(ls.SortTextAutoImportSuggestions)),
},
}, false,
),
},
})
}

View File

@@ -0,0 +1,84 @@
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"
)
// Test that string literal completions are suggested in tuple contexts
// even without typing a quote character.
func TestCompletionsInArrayLiteralWithContextualType(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
// Test 1: Completions after `[` in a tuple should suggest string literals
const content1 = `let y: ["foo" | "bar", string] = [/*a*/];`
f1, done1 := fourslash.NewFourslash(t, nil /*capabilities*/, content1)
defer done1()
f1.VerifyCompletions(t, "a", &fourslash.CompletionsExpectedList{
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &DefaultCommitCharacters,
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Includes: []fourslash.CompletionsExpectedItem{
"\"foo\"",
"\"bar\"",
},
},
})
// Test 2: Completions after `,` in a tuple should provide contextual type for second element
const content2 = `let z: ["a", "b" | "c"] = ["a", /*b*/];`
f2, done2 := fourslash.NewFourslash(t, nil /*capabilities*/, content2)
defer done2()
f2.VerifyCompletions(t, "b", &fourslash.CompletionsExpectedList{
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &DefaultCommitCharacters,
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Includes: []fourslash.CompletionsExpectedItem{
"\"b\"",
"\"c\"",
},
},
})
// Test 3: Verify that properties named "-1" are NOT suggested in array literals
// This was a bug in the old implementation where passing -1 as an index would
// check for a property named "-1" and suggest its value
const content3 = `let x: { "-1": "hello" } = [/*c*/];`
f3, done3 := fourslash.NewFourslash(t, nil /*capabilities*/, content3)
defer done3()
f3.VerifyCompletions(t, "c", &fourslash.CompletionsExpectedList{
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &DefaultCommitCharacters,
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Excludes: []string{
"\"hello\"",
},
},
})
// Test 4: Completions after `]` in a tuple should not crash (issue #2296)
// When completing after the closing bracket, we're outside the array literal
// so we shouldn't be getting contextual types for array elements
const content4 = `let x: [number] = [123]/*d*/;`
f4, done4 := fourslash.NewFourslash(t, nil /*capabilities*/, content4)
defer done4()
// Just verify that completions don't crash - accept any completion list
f4.VerifyCompletions(t, "d", &fourslash.CompletionsExpectedList{
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &DefaultCommitCharacters,
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{},
})
}

View File

@@ -0,0 +1,49 @@
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"
)
// Test for issue: Completions crash in call to `new Map(...)`.
// When requesting completions inside a Map constructor's array literal,
// IndexOfNode returns -1 causing a panic in getContextualTypeForElementExpression
// when trying to access array elements without a bounds check.
func TestCompletionsInMapConstructorNoCrash(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
// Test completion at position /*a*/ - before the string literal
const content1 = `const m = new Map([
[/*a*/'0', ['0', false]],
]);`
f1, done1 := fourslash.NewFourslash(t, nil /*capabilities*/, content1)
defer done1()
// Just verify that completions don't crash - accept any completion list
f1.VerifyCompletions(t, "a", &fourslash.CompletionsExpectedList{
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &DefaultCommitCharacters,
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{},
})
// Test completion at position /*b*/ - after the array literal
const content2 = `const m = new Map([
['0', ['0', false]]/*b*/,
]);`
f2, done2 := fourslash.NewFourslash(t, nil /*capabilities*/, content2)
defer done2()
// Just verify that completions don't crash - accept any completion list
f2.VerifyCompletions(t, "b", &fourslash.CompletionsExpectedList{
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &DefaultCommitCharacters,
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{},
})
}

View File

@@ -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/lsp/lsproto"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestCompletionsPathsJsonModule(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @moduleResolution: bundler
// @resolveJsonModule: true
// @Filename: /project/node_modules/test.json
not read
// @Filename: /project/index.ts
import { } from "/**/";`
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: []fourslash.CompletionsExpectedItem{
&lsproto.CompletionItem{
Label: "test.json",
Kind: new(lsproto.CompletionItemKindFile),
Detail: new("test.json"),
},
},
},
})
}

View File

@@ -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/lsp/lsproto"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestCompletionsPathsRelativeJsonModule(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @moduleResolution: bundler
// @resolveJsonModule: true
// @Filename: /project/test.json
not read
// @Filename: /project/index.ts
import { } from ".//**/";`
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: []fourslash.CompletionsExpectedItem{
&lsproto.CompletionItem{
Label: "test.json",
Kind: new(lsproto.CompletionItemKindFile),
Detail: new("test.json"),
},
},
},
})
}

View File

@@ -0,0 +1,92 @@
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 TestCompletionsPaths_importType(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @allowJs: true
// @moduleResolution: bundler
// @Filename: /ns.ts
file content not read
// @Filename: /node_modules/package/index.ts
file content not read
// @Filename: /usage.ts
type A = typeof import("[|p|]/*1*/");
type B = import(".//*2*/");
// @Filename: /user.js
/** @type {import("/*3*/")} */`
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{
Exact: []fourslash.CompletionsExpectedItem{
&lsproto.CompletionItem{
Label: "package",
Kind: new(lsproto.CompletionItemKindFolder),
Detail: new("package"),
TextEdit: &lsproto.TextEditOrInsertReplaceEdit{
TextEdit: &lsproto.TextEdit{
NewText: "package",
Range: f.Ranges()[0].LSRange,
},
},
},
},
},
})
f.VerifyCompletions(t, "3", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &[]string{},
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Exact: []fourslash.CompletionsExpectedItem{
&lsproto.CompletionItem{
Label: "package",
Kind: new(lsproto.CompletionItemKindFolder),
Detail: new("package"),
},
},
},
})
f.VerifyCompletions(t, "2", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &[]string{},
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Exact: []fourslash.CompletionsExpectedItem{
&lsproto.CompletionItem{
Label: "node_modules",
Kind: new(lsproto.CompletionItemKindFolder),
Detail: new("node_modules"),
},
&lsproto.CompletionItem{
Label: "ns",
Kind: new(lsproto.CompletionItemKindFile),
Detail: new("ns.ts"),
},
&lsproto.CompletionItem{
Label: "user",
Kind: new(lsproto.CompletionItemKindFile),
Detail: new("user.js"),
},
},
},
})
}

View File

@@ -0,0 +1,54 @@
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 TestCompletionsPaths_kinds(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @Filename: /src/b.ts
not read
// @Filename: /src/dir/x.ts
not read
// @Filename: /src/a.ts
import {} from "./[|/*0*/|]";
import {} from "./[|/*1*/|]";
// @Filename: /tsconfig.json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"foo/*": ["src/*"]
}
}
}`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.VerifyCompletions(t, []string{"0", "1"}, &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &[]string{},
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Exact: []fourslash.CompletionsExpectedItem{
&lsproto.CompletionItem{
Label: "b",
Kind: new(lsproto.CompletionItemKindFile),
Detail: new("b.ts"),
},
&lsproto.CompletionItem{
Label: "dir",
Kind: new(lsproto.CompletionItemKindFolder),
Detail: new("dir"),
},
},
},
})
}

View File

@@ -0,0 +1,121 @@
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 TestCompletionsPaths_pathMapping_nonTrailingWildcard1(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @Filename: /src/b.ts
export const x = 0;
// @Filename: /src/dir/x.ts
/export const x = 0;
// @Filename: /src/a.ts
import {} from "foo//*0*/";
import {} from "foo/dir//*1*/"; // invalid
import {} from "foo/[|_|]/*2*/";
import {} from "foo/_dir//*3*/";
// @Filename: /tsconfig.json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"foo/_*/suffix": ["src/*.ts"]
}
}
}`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.VerifyCompletions(t, "0", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &[]string{},
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Exact: []fourslash.CompletionsExpectedItem{
&lsproto.CompletionItem{
Label: "_a/suffix",
Kind: new(lsproto.CompletionItemKindFile),
Detail: new("_a/suffix.ts"),
},
&lsproto.CompletionItem{
Label: "_b/suffix",
Kind: new(lsproto.CompletionItemKindFile),
Detail: new("_b/suffix.ts"),
},
&lsproto.CompletionItem{
Label: "_dir",
Detail: new("_dir"),
},
},
},
})
f.VerifyCompletions(t, "1", nil)
f.VerifyCompletions(t, "2", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &[]string{},
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Exact: []fourslash.CompletionsExpectedItem{
&lsproto.CompletionItem{
Label: "_a/suffix",
Kind: new(lsproto.CompletionItemKindFile),
Detail: new("_a/suffix.ts"),
TextEdit: &lsproto.TextEditOrInsertReplaceEdit{
TextEdit: &lsproto.TextEdit{
Range: f.Ranges()[0].LSRange,
NewText: "_a/suffix",
},
},
},
&lsproto.CompletionItem{
Label: "_b/suffix",
Kind: new(lsproto.CompletionItemKindFile),
Detail: new("_b/suffix.ts"),
TextEdit: &lsproto.TextEditOrInsertReplaceEdit{
TextEdit: &lsproto.TextEdit{
Range: f.Ranges()[0].LSRange,
NewText: "_b/suffix",
},
},
},
&lsproto.CompletionItem{
Label: "_dir",
Kind: new(lsproto.CompletionItemKindFolder),
Detail: new("_dir"),
TextEdit: &lsproto.TextEditOrInsertReplaceEdit{
TextEdit: &lsproto.TextEdit{
Range: f.Ranges()[0].LSRange,
NewText: "_dir",
},
},
},
},
},
})
f.VerifyCompletions(t, "3", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &[]string{},
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Exact: []fourslash.CompletionsExpectedItem{
&lsproto.CompletionItem{
Label: "x/suffix",
Kind: new(lsproto.CompletionItemKindFile),
Detail: new("x/suffix.ts"),
},
},
},
})
}

View File

@@ -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/lsp/lsproto"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestCompletionsPaths_pathMapping_parentDirectory(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @Filename: /src/a.ts
import { } from "foo//**/";
// @Filename: /oof/x.ts
export const x = 0;
// @Filename: /tsconfig.json
{
"compilerOptions": {
"baseUrl": "src",
"paths": {
"foo/*": ["../oof/*"]
}
}
}`
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: []fourslash.CompletionsExpectedItem{
&lsproto.CompletionItem{
Label: "x",
Kind: new(lsproto.CompletionItemKindFile),
Detail: new("x.ts"),
},
},
},
})
}

View File

@@ -0,0 +1,75 @@
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 TestCompletionsPaths_pathMapping(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @Filename: /src/b.ts
export const x = 0;
// @Filename: /src/dir/x.ts
/export const x = 0;
// @Filename: /src/a.ts
import {} from "foo//*0*/";
import {} from "foo/dir//*1*/";
// @Filename: /tsconfig.json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"foo/*": ["src/*"]
}
}
}`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.VerifyCompletions(t, "0", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &[]string{},
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Exact: []fourslash.CompletionsExpectedItem{
&lsproto.CompletionItem{
Label: "a",
Kind: new(lsproto.CompletionItemKindFile),
Detail: new("a.ts"),
},
&lsproto.CompletionItem{
Label: "b",
Kind: new(lsproto.CompletionItemKindFile),
Detail: new("b.ts"),
},
&lsproto.CompletionItem{
Label: "dir",
Kind: new(lsproto.CompletionItemKindFolder),
Detail: new("dir"),
},
},
},
})
f.VerifyCompletions(t, "1", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &[]string{},
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Exact: []fourslash.CompletionsExpectedItem{
&lsproto.CompletionItem{
Label: "x",
Kind: new(lsproto.CompletionItemKindFile),
Detail: new("x.ts"),
},
},
},
})
}

View File

@@ -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/ls"
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestCompletionsSelfDeclaring1(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `interface Test {
keyPath?: string;
autoIncrement?: boolean;
}
function test<T extends Record<string, Test>>(opt: T) { }
test({
a: {
keyPath: '',
[|a|]/**/
}
})`
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{
Exact: []fourslash.CompletionsExpectedItem{
&lsproto.CompletionItem{
Label: "autoIncrement?",
FilterText: new("autoIncrement"),
SortText: new(string(ls.SortTextOptionalMember)),
TextEdit: &lsproto.TextEditOrInsertReplaceEdit{
InsertReplaceEdit: &lsproto.InsertReplaceEdit{
NewText: "autoIncrement",
Insert: f.Ranges()[0].LSRange,
Replace: f.Ranges()[0].LSRange,
},
},
},
},
},
})
}

View File

@@ -0,0 +1,54 @@
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 TestCompletionsWithDeprecatedTag4(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @noLib: true
f({
[|a|]/**/
xyz: ` + "`" + `` + "`" + `,
});
declare function f(options: {
/** @deprecated abc */
abc?: number,
xyz?: string
}): void;`
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{
Exact: []fourslash.CompletionsExpectedItem{
&lsproto.CompletionItem{
Label: "abc?",
FilterText: new("abc"),
Kind: new(lsproto.CompletionItemKindField),
Tags: &[]lsproto.CompletionItemTag{lsproto.CompletionItemTagDeprecated},
SortText: new(string(ls.DeprecateSortText(ls.SortTextOptionalMember))),
TextEdit: &lsproto.TextEditOrInsertReplaceEdit{
InsertReplaceEdit: &lsproto.InsertReplaceEdit{
NewText: "abc",
Insert: f.Ranges()[0].LSRange,
Replace: f.Ranges()[0].LSRange,
},
},
},
},
},
})
}

View File

@@ -0,0 +1,193 @@
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 TestCompletionsWithStringReplacementMode1(t *testing.T) {
fourslash.SkipIfFailing(t)
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `interface TFunction {
(_: 'login.title', __?: {}): string;
(_: 'login.description', __?: {}): string;
(_: 'login.sendEmailAgree', __?: {}): string;
(_: 'login.termsOfUse', __?: {}): string;
(_: 'login.privacyPolicy', __?: {}): string;
(_: 'login.sendEmailButton', __?: {}): string;
(_: 'login.emailInputPlaceholder', __?: {}): string;
(_: 'login.errorWrongEmailTitle', __?: {}): string;
(_: 'login.errorWrongEmailDescription', __?: {}): string;
(_: 'login.errorGeneralEmailTitle', __?: {}): string;
(_: 'login.errorGeneralEmailDescription', __?: {}): string;
(_: 'login.loginErrorTitle', __?: {}): string;
(_: 'login.loginErrorDescription', __?: {}): string;
(_: 'login.openEmailAppErrorTitle', __?: {}): string;
(_: 'login.openEmailAppErrorDescription', __?: {}): string;
(_: 'login.openEmailAppErrorConfirm', __?: {}): string;
}
const f: TFunction = (() => {}) as any;
f('[|login./**/|]')`
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{
Exact: []fourslash.CompletionsExpectedItem{
&lsproto.CompletionItem{
Label: "login.description",
TextEdit: &lsproto.TextEditOrInsertReplaceEdit{
TextEdit: &lsproto.TextEdit{
NewText: "login.description",
Range: f.Ranges()[0].LSRange,
},
},
},
&lsproto.CompletionItem{
Label: "login.emailInputPlaceholder",
TextEdit: &lsproto.TextEditOrInsertReplaceEdit{
TextEdit: &lsproto.TextEdit{
NewText: "login.emailInputPlaceholder",
Range: f.Ranges()[0].LSRange,
},
},
},
&lsproto.CompletionItem{
Label: "login.errorGeneralEmailDescription",
TextEdit: &lsproto.TextEditOrInsertReplaceEdit{
TextEdit: &lsproto.TextEdit{
NewText: "login.errorGeneralEmailDescription",
Range: f.Ranges()[0].LSRange,
},
},
},
&lsproto.CompletionItem{
Label: "login.errorGeneralEmailTitle",
TextEdit: &lsproto.TextEditOrInsertReplaceEdit{
TextEdit: &lsproto.TextEdit{
NewText: "login.errorGeneralEmailTitle",
Range: f.Ranges()[0].LSRange,
},
},
},
&lsproto.CompletionItem{
Label: "login.errorWrongEmailDescription",
TextEdit: &lsproto.TextEditOrInsertReplaceEdit{
TextEdit: &lsproto.TextEdit{
NewText: "login.errorWrongEmailDescription",
Range: f.Ranges()[0].LSRange,
},
},
},
&lsproto.CompletionItem{
Label: "login.errorWrongEmailTitle",
TextEdit: &lsproto.TextEditOrInsertReplaceEdit{
TextEdit: &lsproto.TextEdit{
NewText: "login.errorWrongEmailTitle",
Range: f.Ranges()[0].LSRange,
},
},
},
&lsproto.CompletionItem{
Label: "login.loginErrorDescription",
TextEdit: &lsproto.TextEditOrInsertReplaceEdit{
TextEdit: &lsproto.TextEdit{
NewText: "login.loginErrorDescription",
Range: f.Ranges()[0].LSRange,
},
},
},
&lsproto.CompletionItem{
Label: "login.loginErrorTitle",
TextEdit: &lsproto.TextEditOrInsertReplaceEdit{
TextEdit: &lsproto.TextEdit{
NewText: "login.loginErrorTitle",
Range: f.Ranges()[0].LSRange,
},
},
},
&lsproto.CompletionItem{
Label: "login.openEmailAppErrorConfirm",
TextEdit: &lsproto.TextEditOrInsertReplaceEdit{
TextEdit: &lsproto.TextEdit{
NewText: "login.openEmailAppErrorConfirm",
Range: f.Ranges()[0].LSRange,
},
},
},
&lsproto.CompletionItem{
Label: "login.openEmailAppErrorDescription",
TextEdit: &lsproto.TextEditOrInsertReplaceEdit{
TextEdit: &lsproto.TextEdit{
NewText: "login.openEmailAppErrorDescription",
Range: f.Ranges()[0].LSRange,
},
},
},
&lsproto.CompletionItem{
Label: "login.openEmailAppErrorTitle",
TextEdit: &lsproto.TextEditOrInsertReplaceEdit{
TextEdit: &lsproto.TextEdit{
NewText: "login.openEmailAppErrorTitle",
Range: f.Ranges()[0].LSRange,
},
},
},
&lsproto.CompletionItem{
Label: "login.privacyPolicy",
TextEdit: &lsproto.TextEditOrInsertReplaceEdit{
TextEdit: &lsproto.TextEdit{
NewText: "login.privacyPolicy",
Range: f.Ranges()[0].LSRange,
},
},
},
&lsproto.CompletionItem{
Label: "login.sendEmailAgree",
TextEdit: &lsproto.TextEditOrInsertReplaceEdit{
TextEdit: &lsproto.TextEdit{
NewText: "login.sendEmailAgree",
Range: f.Ranges()[0].LSRange,
},
},
},
&lsproto.CompletionItem{
Label: "login.sendEmailButton",
TextEdit: &lsproto.TextEditOrInsertReplaceEdit{
TextEdit: &lsproto.TextEdit{
NewText: "login.sendEmailButton",
Range: f.Ranges()[0].LSRange,
},
},
},
&lsproto.CompletionItem{
Label: "login.termsOfUse",
TextEdit: &lsproto.TextEditOrInsertReplaceEdit{
TextEdit: &lsproto.TextEdit{
NewText: "login.termsOfUse",
Range: f.Ranges()[0].LSRange,
},
},
},
&lsproto.CompletionItem{
Label: "login.title",
TextEdit: &lsproto.TextEditOrInsertReplaceEdit{
TextEdit: &lsproto.TextEdit{
NewText: "login.title",
Range: f.Ranges()[0].LSRange,
},
},
},
},
},
})
}

View File

@@ -0,0 +1,31 @@
package fourslash_test
import (
"testing"
"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestDocCommentTemplateNamespacesAndModules01(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `/*namespaceN*/
namespace n {
}
/*namespaceM*/
namespace m {
}
/*ambientModule*/
module "ambientModule" {
}`
capabilities := fourslash.GetDefaultCapabilities()
capabilities.TextDocument.Completion.CompletionItem.SnippetSupport = new(false)
f, done := fourslash.NewFourslash(t, capabilities, content)
defer done()
f.VerifyJSDocCompletion(t, "namespaceN", 3, `/** */`, nil)
f.VerifyJSDocCompletion(t, "namespaceM", 3, `/** */`, nil)
f.VerifyJSDocCompletion(t, "ambientModule", 3, `/** */`, nil)
}

View File

@@ -0,0 +1,68 @@
package fourslash_test
import (
"testing"
"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestDuplicatePackageServices_fileChanges(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @noImplicitReferences: true
// @Filename: /node_modules/a/index.d.ts
import X from "x";
export function a(x: X): void;
// @Filename: /node_modules/a/node_modules/x/index.d.ts
export default class /*defAX*/X {
private x: number;
}
// @Filename: /node_modules/a/node_modules/x/package.json
{ "name": "x", "version": "1.2./*aVersionPatch*/3" }
// @Filename: /node_modules/b/index.d.ts
import X from "x";
export const b: X;
// @Filename: /node_modules/b/node_modules/x/index.d.ts
export default class /*defBX*/X {
private x: number;
}
// @Filename: /node_modules/b/node_modules/x/package.json
{ "name": "x", "version": "1.2./*bVersionPatch*/3" }
// @Filename: /src/a.ts
import { a } from "a";
import { b } from "b";
a(/*error*/b);`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.GoToFile(t, "/src/a.ts")
f.VerifyNumberOfErrorsInCurrentFile(t, 0)
testChangeAndChangeBack := func(versionPatch string, def string) {
// Insert "4" after the version patch marker, changing version from 1.2.3 to 1.2.43
f.GoToMarker(t, versionPatch)
f.Insert(t, "4")
// Insert a space after the definition marker to trigger a recheck
f.GoToMarker(t, def)
f.Insert(t, " ")
// No longer have identical packageId, so we get errors.
f.VerifyErrorExistsAfterMarker(t, "error")
// Undo the changes
f.GoToMarker(t, versionPatch)
f.DeleteAtCaret(t, 1)
f.GoToMarker(t, def)
f.DeleteAtCaret(t, 1)
// Back to being identical.
f.GoToFile(t, "/src/a.ts")
f.VerifyNumberOfErrorsInCurrentFile(t, 0)
}
testChangeAndChangeBack("aVersionPatch", "defAX")
testChangeAndChangeBack("bVersionPatch", "defBX")
}

View File

@@ -0,0 +1,95 @@
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 TestExhaustiveCaseCompletions1(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @newline: LF
enum E {
A = 0,
B = "B",
C = "C",
}
// Mixed union
declare const u: E.A | E.B | 1;
switch (u) {
case/*1*/
}
// Union enum
declare const e: E;
switch (e) {
case/*2*/
}
enum F {
D = 1 << 0,
E = 1 << 1,
F = 1 << 2,
}
declare const f: F;
switch (f) {
case/*3*/
}`
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: "case 1: ...",
InsertText: new("case 1:$1\ncase E.A:$2\ncase E.B:$3"),
SortText: new(string(ls.SortTextGlobalsOrKeywords)),
InsertTextFormat: new(lsproto.InsertTextFormatSnippet),
},
},
},
})
f.VerifyCompletions(t, "2", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &DefaultCommitCharacters,
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Includes: []fourslash.CompletionsExpectedItem{
&lsproto.CompletionItem{
Label: "case E.A: ...",
InsertText: new("case E.A:$1\ncase E.B:$2\ncase E.C:$3"),
SortText: new(string(ls.SortTextGlobalsOrKeywords)),
InsertTextFormat: new(lsproto.InsertTextFormatSnippet),
},
},
},
})
f.VerifyCompletions(t, "3", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &DefaultCommitCharacters,
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Includes: []fourslash.CompletionsExpectedItem{
&lsproto.CompletionItem{
Label: "case F.D: ...",
InsertText: new("case F.D:$1\ncase F.E:$2\ncase F.F:$3"),
SortText: new(string(ls.SortTextGlobalsOrKeywords)),
InsertTextFormat: new(lsproto.InsertTextFormatSnippet),
},
},
},
})
}

View File

@@ -0,0 +1,81 @@
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 TestExhaustiveCaseCompletions2(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @newline: LF
// @Filename: /dep.ts
export enum E {
A = 0,
B = "B",
C = "C",
}
declare const u: E.A | E.B | 1;
export { u };
// @Filename: /main.ts
import { u } from "./dep";
switch (u) {
case/*1*/
}
// @Filename: /other.ts
import * as d from "./dep";
declare const u: d.E;
switch (u) {
case/*2*/
}`
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: "case 1: ...",
InsertText: new("case 1:$1\ncase E.A:$2\ncase E.B:$3"),
InsertTextFormat: new(lsproto.InsertTextFormatSnippet),
SortText: new(string(ls.SortTextGlobalsOrKeywords)),
AdditionalTextEdits: fourslash.AnyTextEdits,
},
},
},
})
f.VerifyCompletions(t, "2", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &DefaultCommitCharacters,
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Includes: []fourslash.CompletionsExpectedItem{
&lsproto.CompletionItem{
Label: "case d.E.A: ...",
InsertText: new("case d.E.A:$1\ncase d.E.B:$2\ncase d.E.C:$3"),
InsertTextFormat: new(lsproto.InsertTextFormatSnippet),
SortText: new(string(ls.SortTextGlobalsOrKeywords)),
},
},
},
})
f.VerifyApplyCodeActionFromCompletion(t, new("1"), &fourslash.ApplyCodeActionFromCompletionOptions{
Name: "case 1: ...",
Source: "SwitchCases/",
NewFileContent: new(`import { E, u } from "./dep";
switch (u) {
case
}`),
})
}

View File

@@ -0,0 +1,162 @@
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"
)
// Where exhaustive case completions are available.
func TestExhaustiveCaseCompletions3(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @newline: LF
// @Filename: /main.ts
enum E {
A = 0,
B = "B",
C = "C",
}
declare const u: E;
switch (u) {
case/*1*/
}
switch (u) {
/*2*/
}
switch (u) {
case 1:
/*3*/
}
switch (u) {
[|c|]/*4*/
}
switch (u) {
case /*5*/
}
/*6*/
switch (u) {
/*7*/
switch (u) {
case E./*8*/
}`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
exhaustiveCaseCompletion := &lsproto.CompletionItem{
Label: "case E.A: ...",
InsertText: new("case E.A:$1\ncase E.B:$2\ncase E.C:$3"),
SortText: new(string(ls.SortTextGlobalsOrKeywords)),
InsertTextFormat: new(lsproto.InsertTextFormatSnippet),
}
f.VerifyCompletions(t, "1", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &DefaultCommitCharacters,
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Includes: []fourslash.CompletionsExpectedItem{exhaustiveCaseCompletion},
},
})
f.VerifyCompletions(t, "2", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &DefaultCommitCharacters,
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Includes: []fourslash.CompletionsExpectedItem{exhaustiveCaseCompletion},
},
})
f.VerifyCompletions(t, "3", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &DefaultCommitCharacters,
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Includes: []fourslash.CompletionsExpectedItem{exhaustiveCaseCompletion},
},
})
f.VerifyCompletions(t, "4", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &DefaultCommitCharacters,
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Includes: []fourslash.CompletionsExpectedItem{
&lsproto.CompletionItem{
Label: "case E.A: ...",
TextEdit: &lsproto.TextEditOrInsertReplaceEdit{
InsertReplaceEdit: &lsproto.InsertReplaceEdit{
NewText: "case E.A:$1\ncase E.B:$2\ncase E.C:$3",
Insert: f.Ranges()[0].LSRange,
Replace: f.Ranges()[0].LSRange,
},
},
SortText: new(string(ls.SortTextGlobalsOrKeywords)),
InsertTextFormat: new(lsproto.InsertTextFormatSnippet),
},
},
},
})
f.VerifyCompletions(t, "5", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &DefaultCommitCharacters,
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Includes: []fourslash.CompletionsExpectedItem{exhaustiveCaseCompletion},
},
})
f.VerifyCompletions(t, "6", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &DefaultCommitCharacters,
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Includes: []fourslash.CompletionsExpectedItem{"E", "u", exhaustiveCaseCompletion},
},
})
f.VerifyCompletions(t, "7", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &DefaultCommitCharacters,
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Includes: []fourslash.CompletionsExpectedItem{exhaustiveCaseCompletion},
},
})
f.VerifyCompletions(t, "8", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &DefaultCommitCharacters,
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Exact: []fourslash.CompletionsExpectedItem{
"A",
"B",
"C",
},
},
})
}

View File

@@ -0,0 +1,192 @@
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"
)
// Filter existing values.
func TestExhaustiveCaseCompletions4(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @lib: es5
// @newline: LF
enum E {
A = 0,
B = "B",
C = "C",
}
// Filtering existing literals
declare const u: E.A | E.B | 1 | 1n | "1";
switch (u) {
case E.A:
case 1:
case 1n:
case 0x1n:
case "1":
case ` + "`1`" + `:
case ` + "`1${u}`" + `:
case/*1*/
}
declare const v: E.A | "1" | "2";
switch (v) {
case 0:
case ` + "`1`" + `:
/*2*/
}
// Filtering repeated enum members
enum F {
A = "A",
B = "B",
C = A,
}
declare const x: F;
switch (x) {
/*3*/
}
// Enum with computed elements
enum G {
C = 0,
D = 1 << 1,
E = 1 << 2,
OtherD = D,
DorE = D | E,
}
declare const y: G;
switch (y) {
/*4*/
}
switch (y) {
case 0: // same as G.C
case 1: // same as G.D, but we don't know it
case 3: // same as G.DorE, but we don't know
/*5*/
}
// Already exhaustive switch
enum H {
A = "A",
B = "B",
C = "C",
}
declare const z: H;
switch (z) {
case H.A:
case H.B:
case H.C:
/*6*/
}`
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: "case E.B: ...",
InsertText: new("case E.B:$1"),
SortText: new(string(ls.SortTextGlobalsOrKeywords)),
InsertTextFormat: new(lsproto.InsertTextFormatSnippet),
},
},
},
})
f.VerifyCompletions(t, "2", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &DefaultCommitCharacters,
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Includes: []fourslash.CompletionsExpectedItem{
&lsproto.CompletionItem{
Label: `case "2": ...`,
InsertText: new(`case "2":$1`),
SortText: new(string(ls.SortTextGlobalsOrKeywords)),
InsertTextFormat: new(lsproto.InsertTextFormatSnippet),
},
},
},
})
// F.A and F.B (no C because C's value is the same as A's)
f.VerifyCompletions(t, "3", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &DefaultCommitCharacters,
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Includes: []fourslash.CompletionsExpectedItem{
&lsproto.CompletionItem{
Label: "case F.A: ...",
InsertText: new("case F.A:$1\ncase F.B:$2"),
SortText: new(string(ls.SortTextGlobalsOrKeywords)),
InsertTextFormat: new(lsproto.InsertTextFormatSnippet),
},
},
},
})
f.VerifyCompletions(t, "4", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &DefaultCommitCharacters,
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Includes: []fourslash.CompletionsExpectedItem{
&lsproto.CompletionItem{
Label: "case G.C: ...",
InsertText: new("case G.C:$1\ncase G.D:$2\ncase G.E:$3\ncase G.DorE:$4"),
SortText: new(string(ls.SortTextGlobalsOrKeywords)),
InsertTextFormat: new(lsproto.InsertTextFormatSnippet),
},
},
},
})
f.VerifyCompletions(t, "5", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &DefaultCommitCharacters,
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Includes: []fourslash.CompletionsExpectedItem{
&lsproto.CompletionItem{
Label: "case G.D: ...",
InsertText: new("case G.D:$1\ncase G.E:$2\ncase G.DorE:$3"),
SortText: new(string(ls.SortTextGlobalsOrKeywords)),
InsertTextFormat: new(lsproto.InsertTextFormatSnippet),
},
},
},
})
// No exhaustive case completion offered here because the switch is already exhaustive
f.VerifyCompletions(t, "6", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &DefaultCommitCharacters,
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Exact: append(
[]fourslash.CompletionsExpectedItem{"E", "F", "G", "H", "u", "v", "x", "y", "z"},
CompletionGlobals...,
),
},
})
}

View File

@@ -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 TestExhaustiveCaseCompletions5(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @newline: LF
enum P {
" Space",
Bar,
}
declare const p: P;
switch (p) {
/*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: "case P[\" Space\"]: ...",
InsertText: new("case P[\" Space\"]:$1\ncase P.Bar:$2"),
SortText: new(string(ls.SortTextGlobalsOrKeywords)),
InsertTextFormat: new(lsproto.InsertTextFormatSnippet),
},
},
},
})
}

View 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/ls"
"github.com/microsoft/typescript-go/internal/ls/lsutil"
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestExhaustiveCaseCompletions6(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @newline: LF
declare const p: 'A' | 'B' | 'C';
switch (p) {
/*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: "case 'A': ...",
InsertText: new("case 'A':$1\ncase 'B':$2\ncase 'C':$3"),
SortText: new(string(ls.SortTextGlobalsOrKeywords)),
InsertTextFormat: new(lsproto.InsertTextFormatSnippet),
},
},
},
UserPreferences: &lsutil.UserPreferences{QuotePreference: lsutil.QuotePreference("single")},
})
}

View File

@@ -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 TestExhaustiveCaseCompletions7(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @newline: LF
export function foo(position: -1 | 0 | 1) {
switch (position) {
/**/
}
}`
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: "case -1: ...",
InsertText: new("case -1:$1\ncase 0:$2\ncase 1:$3"),
SortText: new(string(ls.SortTextGlobalsOrKeywords)),
InsertTextFormat: new(lsproto.InsertTextFormatSnippet),
},
},
},
})
}

View File

@@ -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 TestExhaustiveCaseCompletions8(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @newline: LF
export function foo(position: -1n | 0n) {
switch (position) {
/**/
}
}`
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: "case 0n: ...",
InsertText: new("case 0n:$1\ncase -1n:$2"),
SortText: new(string(ls.SortTextGlobalsOrKeywords)),
InsertTextFormat: new(lsproto.InsertTextFormatSnippet),
},
},
},
})
}

View File

@@ -0,0 +1,26 @@
package fourslash_test
import (
"testing"
"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/testutil"
)
// The formatter should move the closing brace of a multiline import to its own line.
func TestFormatMultilineImportBrace(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `import {
basename,
extname, joinPath } from '../base/resources.js';
import { URI } from '../base/uri.js';`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.FormatDocument(t, "")
f.VerifyCurrentFileContent(t, `import {
basename,
extname, joinPath
} from '../base/resources.js';
import { URI } from '../base/uri.js';`)
}

View File

@@ -0,0 +1,24 @@
package fourslash_test
import (
"testing"
"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestFormatOnEnterInComment(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = ` /**
* /*1*/
*/`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.GoToMarker(t, "1")
f.InsertLine(t, "")
f.VerifyCurrentFileContent(t, ` /**
*
*/`)
}

View File

@@ -0,0 +1,23 @@
package fourslash_test
import (
"testing"
"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestGetEditsForFileRename_caseInsensitive(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @useCaseSensitiveFileNames: false
// @Filename: /a.ts
export const a = 0;
// @Filename: /b.ts
import { a } from "./A";`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.VerifyWillRenameFilesEdits(t, "/a.ts", "/eh.ts", map[string]string{
"/b.ts": `import { a } from "./eh";`,
}, nil /*preferences*/)
}

View File

@@ -0,0 +1,60 @@
package fourslash_test
import (
"testing"
"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestGetEditsForFileRename_directory_down(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @Filename: /a.ts
/// <reference path="./src/old/file.ts" />
import old from "./src/old";
import old2 from "./src/old/file";
export default 0;
// @Filename: /src/b.ts
/// <reference path="./old/file.ts" />
import old from "./old";
import old2 from "./old/file";
export default 0;
// @Filename: /src/foo/c.ts
/// <reference path="../old/file.ts" />
import old from "../old";
import old2 from "../old/file";
export default 0;
// @Filename: /src/old/index.ts
import a from "../../a";
import a2 from "../b";
import a3 from "../foo/c";
import f from "./file";
export default 0;
// @Filename: /src/old/file.ts
export default 0;
// @Filename: /tsconfig.json
{ "files": ["a.ts", "src/b.ts", "src/foo/c.ts", "src/old/index.ts", "src/old/file.ts"] }`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.VerifyWillRenameFilesEdits(t, "/src/old", "/src/newDir/new", map[string]string{
"/a.ts": `/// <reference path="./src/newDir/new/file.ts" />
import old from "./src/newDir/new";
import old2 from "./src/newDir/new/file";
export default 0;`,
"/src/b.ts": `/// <reference path="./newDir/new/file.ts" />
import old from "./newDir/new";
import old2 from "./newDir/new/file";
export default 0;`,
"/src/foo/c.ts": `/// <reference path="../newDir/new/file.ts" />
import old from "../newDir/new";
import old2 from "../newDir/new/file";
export default 0;`,
"/src/newDir/new/index.ts": `import a from "../../../a";
import a2 from "../../b";
import a3 from "../../foo/c";
import f from "./file";
export default 0;`,
"/tsconfig.json": `{ "files": ["a.ts", "src/b.ts", "src/foo/c.ts", "src/newDir/new/index.ts", "src/newDir/new/file.ts"] }`,
}, nil /*preferences*/)
}

View File

@@ -0,0 +1,60 @@
package fourslash_test
import (
"testing"
"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestGetEditsForFileRename_directory_up(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @Filename: /a.ts
/// <reference path="./src/old/file.ts" />
import old from "./src/old";
import old2 from "./src/old/file";
export default 0;
// @Filename: /src/b.ts
/// <reference path="./old/file.ts" />
import old from "./old";
import old2 from "./old/file";
export default 0;
// @Filename: /src/foo/c.ts
/// <reference path="../old/file.ts" />
import old from "../old";
import old2 from "../old/file";
export default 0;
// @Filename: /src/old/index.ts
import a from "../../a";
import a2 from "../b";
import a3 from "../foo/c";
import f from "./file";
export default 0;
// @Filename: /src/old/file.ts
export default 0;
// @Filename: /tsconfig.json
{ "files": ["a.ts", "src/b.ts", "src/foo/c.ts", "src/old/index.ts", "src/old/file.ts"] }`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.VerifyWillRenameFilesEdits(t, "/src/old", "/newDir/new", map[string]string{
"/a.ts": `/// <reference path="./newDir/new/file.ts" />
import old from "./newDir/new";
import old2 from "./newDir/new/file";
export default 0;`,
"/src/b.ts": `/// <reference path="../newDir/new/file.ts" />
import old from "../newDir/new";
import old2 from "../newDir/new/file";
export default 0;`,
"/src/foo/c.ts": `/// <reference path="../../newDir/new/file.ts" />
import old from "../../newDir/new";
import old2 from "../../newDir/new/file";
export default 0;`,
"/newDir/new/index.ts": `import a from "../../a";
import a2 from "../../src/b";
import a3 from "../../src/foo/c";
import f from "./file";
export default 0;`,
"/tsconfig.json": `{ "files": ["a.ts", "src/b.ts", "src/foo/c.ts", "newDir/new/index.ts", "newDir/new/file.ts"] }`,
}, nil /*preferences*/)
}

View File

@@ -0,0 +1,23 @@
package fourslash_test
import (
"testing"
"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestGetEditsForFileRename_jsExtension(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @allowJs: true
// @Filename: /src/a.js
export const a = 0;
// @Filename: /b.js
import { a } from "./src/a.js";`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.VerifyWillRenameFilesEdits(t, "/b.js", "/src/b.js", map[string]string{
"/src/b.js": `import { a } from "./a.js";`,
}, nil /*preferences*/)
}

View File

@@ -0,0 +1,27 @@
package fourslash_test
import (
"testing"
"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/ls/lsutil"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestGetEditsForFileRename_preferences(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @Filename: /dir/a.ts
export const a = 0;
// @Filename: /dir/b.ts
import {} from "dir/a";
import {} from 'dir/a';
// @Filename: /tsconfig.json
{"compilerOptions":{"paths":{"*":["*"]}}}`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.VerifyWillRenameFilesEdits(t, "/dir/a.ts", "/dir/a1.ts", map[string]string{
"/dir/b.ts": `import {} from "dir/a1";
import {} from 'dir/a1';`,
}, &lsutil.UserPreferences{ImportModuleSpecifierPreference: "non-relative", QuotePreference: lsutil.QuotePreference("single")})
}

View File

@@ -0,0 +1,41 @@
package fourslash_test
import (
"testing"
"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestGetEditsForFileRename_preservePathEnding(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @allowJs: true
// @checkJs: true
// @strict: true
// @jsx: preserve
// @resolveJsonModule: true
// @Filename: /index.js
export const x = 0;
// @Filename: /jsx.jsx
export const y = 0;
// @Filename: /j.jonah.json
{ "j": 0 }
// @Filename: /a.js
import { x as x0 } from ".";
import { x as x1 } from "./index";
import { x as x2 } from "./index.js";
import { y } from "./jsx.jsx";
import { j } from "./j.jonah.json";`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.VerifyNoErrors(t)
f.VerifyWillRenameFilesEdits(t, "/a.js", "/b.js", map[string]string{}, nil /*preferences*/)
f.VerifyWillRenameFilesEdits(t, "/b.js", "/src/b.js", map[string]string{
"/src/b.js": `import { x as x0 } from "..";
import { x as x1 } from "../index";
import { x as x2 } from "../index.js";
import { y } from "../jsx.jsx";
import { j } from "../j.jonah.json";`,
}, nil /*preferences*/)
}

View File

@@ -0,0 +1,23 @@
package fourslash_test
import (
"testing"
"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestGetEditsForFileRename_resolveJsonModule(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @resolveJsonModule: true
// @Filename: /a.ts
import text from "./message.json";
// @Filename: /message.json
{}`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.VerifyWillRenameFilesEdits(t, "/a.ts", "/src/a.ts", map[string]string{
"/src/a.ts": `import text from "../message.json";`,
}, nil /*preferences*/)
}

View File

@@ -0,0 +1,22 @@
package fourslash_test
import (
"testing"
"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestGetEditsForFileRename_shortenRelativePaths(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @Filename: /src/foo/x.ts
// @Filename: /src/old.ts
import { x } from "./foo/x";`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.VerifyWillRenameFilesEdits(t, "/src/old.ts", "/src/foo/new.ts", map[string]string{
"/src/foo/new.ts": `import { x } from "./x";`,
}, nil /*preferences*/)
}

View File

@@ -0,0 +1,22 @@
package fourslash_test
import (
"testing"
"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestGetEditsForFileRename_subDir(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @Filename: /src/foo/a.ts
// @Filename: /src/old.ts
import a from "./foo/a";`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.VerifyWillRenameFilesEdits(t, "/src/old.ts", "/src/dir/new.ts", map[string]string{
"/src/dir/new.ts": `import a from "../foo/a";`,
}, nil /*preferences*/)
}

View File

@@ -0,0 +1,22 @@
package fourslash_test
import (
"testing"
"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestGetEditsForFileRename_unaffectedNonRelativePath(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @Filename: /sub/a.ts
export const a = 1;
// @Filename: /sub/b.ts
import { a } from "sub/a";
// @Filename: /tsconfig.json
{"compilerOptions":{"paths":{"*":["*"]}}}`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.VerifyWillRenameFilesEdits(t, "/sub/b.ts", "/sub/c/d.ts", map[string]string{}, nil /*preferences*/)
}

View File

@@ -0,0 +1,141 @@
package fourslash_test
import (
"testing"
"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestGetOutliningSpans(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// interface
interface IFoo[| {
getDist(): number;
}|]
// class members
class Foo[| {
constructor()[| {
}|]
public foo(): number[| {
return 0;
}|]
public get X()[| {
return 1;
}|]
public set X(v: number)[| {
}|]
public member = function f()[| {
}|]
}|]
// class expressions
[|(new class[| {
bla()[| {
}|]
}|])|]
switch(1)[| {
case 1:[| break;|]
}|]
var array =[| [
1,
2
]|]
// modules
module m1[| {
module m2[| { }|]
module m3[| {
function foo()[| {
}|]
interface IFoo2[| {
}|]
class foo2 implements IFoo2[| {
}|]
}|]
}|]
// function declaration
function foo(): number[| {
return 0;
}|]
// function expressions
[|(function f()[| {
}|])|]
// trivia handling
class ClassFooWithTrivia[| /* some comments */
/* more trivia */ {
[|/*some trailing trivia */|]
}|] /* even more */
// object literals
var x =[|{
a:1,
b:2,
get foo()[| {
return 1;
}|]
}|]
//outline with deep nesting
var nest =[| [[|[[|[[|[[|[[|[[|[[|[[|[[|[[|[[|[[|[[|[[|[[|[[|[[|[[|[[|[[|[[|[[|[[|[[|[[|[[|[[|[[|[[|[[|[[|[[|[[|[[|[[|[
[|[
[
[
[
[
1,2,3
]
]
]
]
]|]
]|]]|]]|]]|]]|]]|]]|]]|]]|]]|]]|]]|]]|]]|]]|]]|]]|]]|]]|]]|]]|]]|]]|]]|]]|]]|]]|]]|]]|]]|]]|]]|]]|]]|]]|]]|];
//outline after a deeply nested node
class AfterNestedNodes[| {
}|]
// function arguments
function f(x: number[], y: number[])[| {
return 3;
}|]
f[|(
// single line array literal span won't render in VS
[|[0]|],
[|[
1,
2
]|]
)|];
class C<T>[| {
foo: T;
}|]
class D<T> extends C<T>[| {
constructor(x)[| {
super<T>(x);
}|]
}|]`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.VerifyOutliningSpans(t)
}

View File

@@ -0,0 +1,30 @@
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 TestImportNameCodeFixDefaultExport5(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @moduleResolution: bundler
// @Filename: /node_modules/hooks/useFoo.ts
declare const _default: () => void;
export default _default;
// @Filename: /test.ts
[|useFoo|];`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.Configure(t, lsutil.UserPreferences{AutoImportEntrypointDirectorySearch: core.TSTrue})
f.GoToFile(t, "/test.ts")
f.VerifyImportFixAtPosition(t, []string{
`import useFoo from "hooks/useFoo";
useFoo`,
}, nil /*preferences*/)
}

View File

@@ -0,0 +1,22 @@
package fourslash_test
import (
"testing"
"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestImportNameCodeFixDefaultExport7(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @lib: dom
// @Filename: foo.ts
export default globalThis.localStorage;
// @Filename: index.ts
foo/**/`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.GoToMarker(t, "")
f.VerifyImportFixAtPosition(t, []string{}, nil /*preferences*/)
}

View File

@@ -0,0 +1,28 @@
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 TestImportNameCodeFixJsEnding(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @lib: es5
// @module: commonjs
// @Filename: /node_modules/lit/package.json
{ "name": "lit", "version": "1.0.0" }
// @Filename: /node_modules/lit/index.d.ts
import "./decorators";
// @Filename: /node_modules/lit/decorators.d.ts
export declare function customElement(name: string): any;
// @Filename: /a.ts
customElement/**/`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.VerifyImportFixModuleSpecifiers(t, "", []string{"lit/decorators.js"}, &lsutil.UserPreferences{ImportModuleSpecifierEnding: "js", AutoImportEntrypointDirectorySearch: core.TSTrue})
}

View File

@@ -0,0 +1,29 @@
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 TestImportNameCodeFixNewImportNodeModules1(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `[|f1/*0*/();|]
// @Filename: ../package.json
{ "dependencies": { "fake-module": "latest" } }
// @Filename: ../node_modules/fake-module/nested.ts
export var v1 = 5;
export function f1();`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.Configure(t, lsutil.UserPreferences{AutoImportEntrypointDirectorySearch: core.TSTrue})
f.VerifyImportFixAtPosition(t, []string{
`import { f1 } from "fake-module/nested";
f1();`,
}, nil /*preferences*/)
}

View File

@@ -0,0 +1,32 @@
package fourslash_test
import (
"testing"
"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestImportNameCodeFixOptionalImport0(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @Filename: a/f1.ts
[|import * as ns from "./foo";
foo/*0*/();|]
// @Filename: a/foo/bar.ts
export function foo() {};
// @Filename: a/foo.ts
export { foo } from "./foo/bar";`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.VerifyImportFixAtPosition(t, []string{
`import * as ns from "./foo";
ns.foo();`,
`import * as ns from "./foo";
import { foo } from "./foo";
foo();`,
`import * as ns from "./foo";
import { foo } from "./foo/bar";
foo();`,
}, nil /*preferences*/)
}

View File

@@ -0,0 +1,40 @@
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 TestImportNameCodeFix_typesVersions(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @module: commonjs
// @checkJs: true
// @Filename: /node_modules/unified/package.json
{
"name": "unified",
"types": "types/ts3.444/index.d.ts",
"typesVersions": {
">=4.0": {
"types/ts3.444/*": [
"types/ts4.0/*"
]
}
}
}
// @Filename: /node_modules/unified/types/ts3.444/index.d.ts
export declare const x: number;
// @Filename: /node_modules/unified/types/ts4.0/index.d.ts
export declare const x: number;
// @Filename: /foo.js
import {} from "unified";
// @Filename: /index.js
x/**/`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.VerifyImportFixModuleSpecifiers(t, "", []string{"unified", "unified/types/ts3.444/index.js"}, &lsutil.UserPreferences{ImportModuleSpecifierEnding: "js", AutoImportEntrypointDirectorySearch: core.TSTrue})
}

View File

@@ -0,0 +1,24 @@
package fourslash_test
import (
"testing"
"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestImportNameCodeFix_uriStyleNodeCoreModules1(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @module: commonjs
// @Filename: /node_modules/@types/node/index.d.ts
declare module "fs" { function writeFile(): void }
declare module "fs/promises" { function writeFile(): Promise<void> }
declare module "node:fs" { export * from "fs"; }
declare module "node:fs/promises" { export * from "fs/promises"; }
// @Filename: /index.ts
writeFile/**/`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.VerifyImportFixModuleSpecifiers(t, "", []string{"fs", "node:fs", "fs/promises", "node:fs/promises"}, nil /*preferences*/)
}

View File

@@ -0,0 +1,25 @@
package fourslash_test
import (
"testing"
"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestIncrementalParsingWithJsDoc(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `[|import a from 'a/aaaaaaa/aaaaaaa/aaaaaa/aaaaaaa';
/**/import b from 'b';
import c from 'c';|]
[|/** @internal */|]
export class LanguageIdentifier[| { }|]`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.VerifyOutliningSpans(t)
f.GoToMarker(t, "")
f.Backspace(t, 1)
f.VerifyOutliningSpans(t)
}

View File

@@ -0,0 +1,39 @@
package fourslash_test
import (
"testing"
"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/ls/lsutil"
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestInlayHintsInteractiveParameterNamesInSpan1(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `function foo1 (a: number, b: number) {}
function foo2 (c: number, d: number) {}
function foo3 (e: number, f: number) {}
function foo4 (g: number, h: number) {}
function foo5 (i: number, j: number) {}
function foo6 (k: number, i: number) {}
function c1 () { foo1(/*a*/1, /*b*/2); }
function c2 () { foo2(/*c*/1, /*d*/2); }
function c3 () { foo3(/*e*/1, /*f*/2); }
function c4 () { foo4(/*g*/1, /*h*/2); }
function c5 () { foo5(/*i*/1, /*j*/2); }
function c6 () { foo6(/*k*/1, /*l*/2); }`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
start := f.MarkerByName(t, "c")
end := f.MarkerByName(t, "h")
span := &lsproto.Range{Start: start.LSPosition, End: end.LSPosition}
f.VerifyBaselineInlayHints(t, span, &lsutil.UserPreferences{
InlayHints: lsutil.InlayHintsPreferences{
IncludeInlayParameterNameHints: "literals",
},
})
}

View File

@@ -0,0 +1,39 @@
package fourslash_test
import (
"testing"
"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/ls/lsutil"
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestInlayHintsInteractiveParameterNamesInSpan2(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `function foo1 (a: number, b: number) {}
function foo2 (c: number, d: number) {}
function foo3 (e: number, f: number) {}
function foo4 (g: number, h: number) {}
function foo5 (i: number, j: number) {}
function foo6 (k: number, l: number) {}
foo1(/*a*/1, /*b*/2);
foo2(/*c*/1, /*d*/2);
foo3(/*e*/1, /*f*/2);
foo4(/*g*/1, /*h*/2);
foo5(/*i*/1, /*j*/2);
foo6(/*k*/1, /*l*/2);`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
start := f.MarkerByName(t, "c")
end := f.MarkerByName(t, "h")
span := &lsproto.Range{Start: start.LSPosition, End: end.LSPosition}
f.VerifyBaselineInlayHints(t, span, &lsutil.UserPreferences{
InlayHints: lsutil.InlayHintsPreferences{
IncludeInlayParameterNameHints: "literals",
},
})
}

View File

@@ -0,0 +1,101 @@
package fourslash_test
import (
"testing"
"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestIsDefinitionAcrossGlobalProjects(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @Filename: /home/src/workspaces/project/a/index.ts
/// <reference path="../b/index.ts" />
/// <reference path="../c/index.ts" />
namespace NS {
export function /*1*/FA() {
FB();
}
}
interface /*2*/I {
/*3*/FA();
}
const ia: I = {
FA() { },
FB() { },
FC() { },
};
// @Filename: /home/src/workspaces/project/a/tsconfig.json
{
"extends": "../tsconfig.settings.json",
"references": [
{ "path": "../b" },
{ "path": "../c" },
],
"files": [
"index.ts",
],
}
// @Filename: /home/src/workspaces/project/b/index.ts
namespace NS {
export function /*4*/FB() {}
}
interface /*5*/I {
/*6*/FB();
}
const ib: I = { FB() {} };
// @Filename: /home/src/workspaces/project/b/tsconfig.json
{
"extends": "../tsconfig.settings.json",
"files": [
"index.ts",
],
}
// @Filename: /home/src/workspaces/project/c/index.ts
namespace NS {
export function /*7*/FC() {}
}
interface /*8*/I {
/*9*/FC();
}
const ic: I = { FC() {} };
// @Filename: /home/src/workspaces/project/c/tsconfig.json
{
"extends": "../tsconfig.settings.json",
"files": [
"index.ts",
],
}
// @Filename: /home/src/workspaces/project/tsconfig.json
{
"compilerOptions": {
"composite": true,
"lib": ["es5"],
},
"references": [
{ "path": "a" },
],
"files": []
}
// @Filename: /home/src/workspaces/project/tsconfig.settings.json
{
"compilerOptions": {
"composite": true,
"skipLibCheck": true,
"declarationMap": true,
"emitDeclarationOnly": true,
"lib": ["es5"],
}
}`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.MarkTestAsStradaServer()
f.VerifyBaselineFindAllReferences(t, "1", "2", "3", "4", "5", "6", "7", "8", "9")
}

View File

@@ -0,0 +1,34 @@
package fourslash_test
import (
"testing"
"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestJsDocDontBreakWithNamespacesVS(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @allowJs: true
// @Filename: jsDocDontBreakWithNamespaces.js
/**
* @returns {module:@nodefuel/web~Webserver~wsServer#hello} Websocket server object
*/
function foo() { }
foo(''/*foo*/);
/**
* @type {module:xxxxx} */
*/
function bar() { }
bar(''/*bar*/);
/** @type {function(module:xxxx, module:xxxx): module:xxxxx} */
function zee() { }
zee(''/*zee*/);`
f, done := fourslash.NewFourslash(t, &lsproto.ClientCapabilities{VSSupportsVisualStudioExtensions: new(true)}, content)
defer done()
f.VerifyBaselineSignatureHelp(t)
}

View 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 TestJsDocFunctionSignatures12(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @allowJs: true
// @Filename: jsDocFunctionSignatures.js
/**
* @param {{
* stringProp: string,
* numProp: number,
* boolProp: boolean,
* anyProp: any,
* anotherAnyProp: any,
* functionProp: (arg0: string, arg1: any) => any
* }} o
*/
function f1(o) {
o/**/;
}`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.GoToMarker(t, "")
f.VerifyQuickInfoIs(t, "(parameter) o: {\n stringProp: string;\n numProp: number;\n boolProp: boolean;\n anyProp: any;\n anotherAnyProp: any;\n functionProp: (arg0: string, arg1: any) => any;\n}", "")
}

View File

@@ -0,0 +1,24 @@
package fourslash_test
import (
"testing"
"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestJsDocFunctionSignatures2(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @allowNonTsExtensions: true
// @Filename: Foo.js
/** @type {(arg0: string, arg1?: boolean) => number} */
var f6;
f6('', /**/false)`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.GoToMarker(t, "")
f.VerifySignatureHelp(t, fourslash.VerifySignatureHelpOptions{Text: "f6(arg0: string, arg1?: boolean): number"})
}

View File

@@ -0,0 +1,32 @@
package fourslash_test
import (
"testing"
"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestJsDocFunctionSignatures5VS(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @strict: true
// @allowJs: true
// @Filename: Foo.js
/**
* Filters a path based on a regexp or glob pattern.
* @param {String} basePath The base path where the search will be performed.
* @param {String} pattern A string defining a regexp of a glob pattern.
* @param {String} type The search pattern type, can be a regexp or a glob.
* @param {Object} options A object containing options to the search.
* @return {Array} A list containing the filtered paths.
*/
function pathFilter(basePath, pattern, type, options){
//...
}
pathFilter(/**/'foo', 'bar', 'baz', {});`
f, done := fourslash.NewFourslash(t, &lsproto.ClientCapabilities{VSSupportsVisualStudioExtensions: new(true)}, content)
defer done()
f.VerifyBaselineSignatureHelp(t)
}

View File

@@ -0,0 +1,27 @@
package fourslash_test
import (
"testing"
"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestJsDocFunctionSignatures6VS(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @allowJs: true
// @Filename: Foo.js
/**
* @param {string} p1 - A string param
* @param {string?} p2 - An optional param
* @param {string} [p3] - Another optional param
* @param {string} [p4="test"] - An optional param with a default value
*/
function f1(p1, p2, p3, p4){}
f1(/*1*/'foo', /*2*/'bar', /*3*/'baz', /*4*/'qux');`
f, done := fourslash.NewFourslash(t, &lsproto.ClientCapabilities{VSSupportsVisualStudioExtensions: new(true)}, content)
defer done()
f.VerifyBaselineSignatureHelp(t)
}

View File

@@ -0,0 +1,304 @@
package fourslash_test
import (
"testing"
"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestJsdocDeprecated_suggestion1(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @experimentalDecorators: true
// @Filename: a.ts
export namespace foo {
/** @deprecated */
export function faff () { }
[|faff|]()
}
const [|a|] = foo.[|faff|]()
foo[[|"faff"|]]
const { [|faff|] } = foo
[|faff|]()
/** @deprecated */
export function bar () {
foo?.[|faff|]()
}
foo?.[[|"faff"|]]?.()
[|bar|]();
/** @deprecated */
export interface Foo {
/** @deprecated */
zzz: number
}
/** @deprecated */
export type QW = [|Foo|][[|"zzz"|]]
export type WQ = [|QW|]
class C {
/** @deprecated */
constructor() {
}
/** @deprecated */
m() { }
}
/** @deprecated */
class D {
constructor() {
}
}
var c = new [|C|]()
c.[|m|]()
c.[|m|]
new [|D|]()
C
[|D|]
// @Filename: j.tsx
type Props = { someProp?: any }
declare var props: Props
/** @deprecated */
function Compi(_props: Props) {
return <div></div>
}
[|Compi|];
<[|Compi|] />;
<[|Compi|] {...props}><div></div></[|Compi|]>;
/** @deprecated */
function ttf(_x: unknown) {
}
[|ttf|]` + "`" + `` + "`" + `
[|ttf|]
/** @deprecated */
function dec(_c: unknown) { }
[|dec|]
@[|dec|]
class K { }
// @Filename: b.ts
// imports and aliases
import * as f from './a';
import { [|bar|], [|QW|] } from './a';
f.[|bar|]();
f.foo.[|faff|]();
[|bar|]();
type Z = [|QW|];
type A = f.[|Foo|];
type B = f.[|QW|];
type C = f.WQ;
type [|O|] = Z | A | B | C;`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.GoToFile(t, "a.ts")
f.VerifySuggestionDiagnostics(t, []*lsproto.Diagnostic{
{
Code: &lsproto.IntegerOrString{Integer: new(int32(6387))},
Message: lsproto.StringOrMarkupContent{String: new("The signature '(): void' of 'faff' is deprecated.")},
Tags: &[]lsproto.DiagnosticTag{lsproto.DiagnosticTagDeprecated},
Range: f.Ranges()[0].LSRange,
},
{
Code: &lsproto.IntegerOrString{Integer: new(int32(6133))},
Message: lsproto.StringOrMarkupContent{String: new("'a' is declared but its value is never read.")},
Tags: &[]lsproto.DiagnosticTag{lsproto.DiagnosticTagUnnecessary},
Range: f.Ranges()[1].LSRange,
},
{
Code: &lsproto.IntegerOrString{Integer: new(int32(6387))},
Message: lsproto.StringOrMarkupContent{String: new("The signature '(): void' of 'foo.faff' is deprecated.")},
Tags: &[]lsproto.DiagnosticTag{lsproto.DiagnosticTagDeprecated},
Range: f.Ranges()[2].LSRange,
},
{
Code: &lsproto.IntegerOrString{Integer: new(int32(6385))},
Message: lsproto.StringOrMarkupContent{String: new("'faff' is deprecated.")},
Tags: &[]lsproto.DiagnosticTag{lsproto.DiagnosticTagDeprecated},
Range: f.Ranges()[3].LSRange,
},
{
Code: &lsproto.IntegerOrString{Integer: new(int32(6385))},
Message: lsproto.StringOrMarkupContent{String: new("'faff' is deprecated.")},
Tags: &[]lsproto.DiagnosticTag{lsproto.DiagnosticTagDeprecated},
Range: f.Ranges()[4].LSRange,
},
{
Code: &lsproto.IntegerOrString{Integer: new(int32(6387))},
Message: lsproto.StringOrMarkupContent{String: new("The signature '(): void' of 'faff' is deprecated.")},
Tags: &[]lsproto.DiagnosticTag{lsproto.DiagnosticTagDeprecated},
Range: f.Ranges()[5].LSRange,
},
{
Code: &lsproto.IntegerOrString{Integer: new(int32(6387))},
Message: lsproto.StringOrMarkupContent{String: new("The signature '(): void' of 'foo.faff' is deprecated.")},
Tags: &[]lsproto.DiagnosticTag{lsproto.DiagnosticTagDeprecated},
Range: f.Ranges()[6].LSRange,
},
{
Code: &lsproto.IntegerOrString{Integer: new(int32(6387))},
Message: lsproto.StringOrMarkupContent{String: new("The signature '(): void' of 'foo.faff' is deprecated.")},
Tags: &[]lsproto.DiagnosticTag{lsproto.DiagnosticTagDeprecated},
Range: f.Ranges()[7].LSRange,
},
{
Code: &lsproto.IntegerOrString{Integer: new(int32(6387))},
Message: lsproto.StringOrMarkupContent{String: new("The signature '(): void' of 'bar' is deprecated.")},
Tags: &[]lsproto.DiagnosticTag{lsproto.DiagnosticTagDeprecated},
Range: f.Ranges()[8].LSRange,
},
{
Code: &lsproto.IntegerOrString{Integer: new(int32(6385))},
Message: lsproto.StringOrMarkupContent{String: new("'Foo' is deprecated.")},
Tags: &[]lsproto.DiagnosticTag{lsproto.DiagnosticTagDeprecated},
Range: f.Ranges()[9].LSRange,
},
{
Code: &lsproto.IntegerOrString{Integer: new(int32(6385))},
Message: lsproto.StringOrMarkupContent{String: new("'zzz' is deprecated.")},
Tags: &[]lsproto.DiagnosticTag{lsproto.DiagnosticTagDeprecated},
Range: f.Ranges()[10].LSRange,
},
{
Code: &lsproto.IntegerOrString{Integer: new(int32(6385))},
Message: lsproto.StringOrMarkupContent{String: new("'QW' is deprecated.")},
Tags: &[]lsproto.DiagnosticTag{lsproto.DiagnosticTagDeprecated},
Range: f.Ranges()[11].LSRange,
},
{
Code: &lsproto.IntegerOrString{Integer: new(int32(6387))},
Message: lsproto.StringOrMarkupContent{String: new("The signature 'new (): C' of 'C' is deprecated.")},
Tags: &[]lsproto.DiagnosticTag{lsproto.DiagnosticTagDeprecated},
Range: f.Ranges()[12].LSRange,
},
{
Code: &lsproto.IntegerOrString{Integer: new(int32(6387))},
Message: lsproto.StringOrMarkupContent{String: new("The signature '(): void' of 'c.m' is deprecated.")},
Tags: &[]lsproto.DiagnosticTag{lsproto.DiagnosticTagDeprecated},
Range: f.Ranges()[13].LSRange,
},
{
Code: &lsproto.IntegerOrString{Integer: new(int32(6385))},
Message: lsproto.StringOrMarkupContent{String: new("'m' is deprecated.")},
Tags: &[]lsproto.DiagnosticTag{lsproto.DiagnosticTagDeprecated},
Range: f.Ranges()[14].LSRange,
},
{
Code: &lsproto.IntegerOrString{Integer: new(int32(6385))},
Message: lsproto.StringOrMarkupContent{String: new("'D' is deprecated.")},
Tags: &[]lsproto.DiagnosticTag{lsproto.DiagnosticTagDeprecated},
Range: f.Ranges()[15].LSRange,
},
{
Code: &lsproto.IntegerOrString{Integer: new(int32(6385))},
Message: lsproto.StringOrMarkupContent{String: new("'D' is deprecated.")},
Tags: &[]lsproto.DiagnosticTag{lsproto.DiagnosticTagDeprecated},
Range: f.Ranges()[16].LSRange,
},
})
f.GoToFile(t, "j.tsx")
f.VerifySuggestionDiagnostics(t, []*lsproto.Diagnostic{
{
Code: &lsproto.IntegerOrString{Integer: new(int32(6385))},
Message: lsproto.StringOrMarkupContent{String: new("'Compi' is deprecated.")},
Tags: &[]lsproto.DiagnosticTag{lsproto.DiagnosticTagDeprecated},
Range: f.Ranges()[17].LSRange,
},
{
Code: &lsproto.IntegerOrString{Integer: new(int32(6387))},
Message: lsproto.StringOrMarkupContent{String: new("The signature '(_props: Props): any' of 'Compi' is deprecated.")},
Tags: &[]lsproto.DiagnosticTag{lsproto.DiagnosticTagDeprecated},
Range: f.Ranges()[18].LSRange,
},
{
Code: &lsproto.IntegerOrString{Integer: new(int32(6387))},
Message: lsproto.StringOrMarkupContent{String: new("The signature '(_props: Props): any' of 'Compi' is deprecated.")},
Tags: &[]lsproto.DiagnosticTag{lsproto.DiagnosticTagDeprecated},
Range: f.Ranges()[19].LSRange,
},
{
Code: &lsproto.IntegerOrString{Integer: new(int32(6385))},
Message: lsproto.StringOrMarkupContent{String: new("'Compi' is deprecated.")},
Tags: &[]lsproto.DiagnosticTag{lsproto.DiagnosticTagDeprecated},
Range: f.Ranges()[20].LSRange,
},
{
Code: &lsproto.IntegerOrString{Integer: new(int32(6387))},
Message: lsproto.StringOrMarkupContent{String: new("The signature '(_x: unknown): void' of 'ttf' is deprecated.")},
Tags: &[]lsproto.DiagnosticTag{lsproto.DiagnosticTagDeprecated},
Range: f.Ranges()[21].LSRange,
},
{
Code: &lsproto.IntegerOrString{Integer: new(int32(6385))},
Message: lsproto.StringOrMarkupContent{String: new("'ttf' is deprecated.")},
Tags: &[]lsproto.DiagnosticTag{lsproto.DiagnosticTagDeprecated},
Range: f.Ranges()[22].LSRange,
},
{
Code: &lsproto.IntegerOrString{Integer: new(int32(6385))},
Message: lsproto.StringOrMarkupContent{String: new("'dec' is deprecated.")},
Tags: &[]lsproto.DiagnosticTag{lsproto.DiagnosticTagDeprecated},
Range: f.Ranges()[23].LSRange,
},
{
Code: &lsproto.IntegerOrString{Integer: new(int32(6387))},
Message: lsproto.StringOrMarkupContent{String: new("The signature '(_c: unknown): void' of 'dec' is deprecated.")},
Tags: &[]lsproto.DiagnosticTag{lsproto.DiagnosticTagDeprecated},
Range: f.Ranges()[24].LSRange,
},
})
f.GoToFile(t, "b.ts")
f.VerifySuggestionDiagnostics(t, []*lsproto.Diagnostic{
{
Code: &lsproto.IntegerOrString{Integer: new(int32(6385))},
Message: lsproto.StringOrMarkupContent{String: new("'bar' is deprecated.")},
Tags: &[]lsproto.DiagnosticTag{lsproto.DiagnosticTagDeprecated},
Range: f.Ranges()[25].LSRange,
},
{
Code: &lsproto.IntegerOrString{Integer: new(int32(6385))},
Message: lsproto.StringOrMarkupContent{String: new("'QW' is deprecated.")},
Tags: &[]lsproto.DiagnosticTag{lsproto.DiagnosticTagDeprecated},
Range: f.Ranges()[26].LSRange,
},
{
Code: &lsproto.IntegerOrString{Integer: new(int32(6387))},
Message: lsproto.StringOrMarkupContent{String: new("The signature '(): void' of 'f.bar' is deprecated.")},
Tags: &[]lsproto.DiagnosticTag{lsproto.DiagnosticTagDeprecated},
Range: f.Ranges()[27].LSRange,
},
{
Code: &lsproto.IntegerOrString{Integer: new(int32(6387))},
Message: lsproto.StringOrMarkupContent{String: new("The signature '(): void' of 'f.foo.faff' is deprecated.")},
Tags: &[]lsproto.DiagnosticTag{lsproto.DiagnosticTagDeprecated},
Range: f.Ranges()[28].LSRange,
},
{
Code: &lsproto.IntegerOrString{Integer: new(int32(6387))},
Message: lsproto.StringOrMarkupContent{String: new("The signature '(): void' of 'bar' is deprecated.")},
Tags: &[]lsproto.DiagnosticTag{lsproto.DiagnosticTagDeprecated},
Range: f.Ranges()[29].LSRange,
},
{
Code: &lsproto.IntegerOrString{Integer: new(int32(6385))},
Message: lsproto.StringOrMarkupContent{String: new("'QW' is deprecated.")},
Tags: &[]lsproto.DiagnosticTag{lsproto.DiagnosticTagDeprecated},
Range: f.Ranges()[30].LSRange,
},
{
Code: &lsproto.IntegerOrString{Integer: new(int32(6385))},
Message: lsproto.StringOrMarkupContent{String: new("'Foo' is deprecated.")},
Tags: &[]lsproto.DiagnosticTag{lsproto.DiagnosticTagDeprecated},
Range: f.Ranges()[31].LSRange,
},
{
Code: &lsproto.IntegerOrString{Integer: new(int32(6385))},
Message: lsproto.StringOrMarkupContent{String: new("'QW' is deprecated.")},
Tags: &[]lsproto.DiagnosticTag{lsproto.DiagnosticTagDeprecated},
Range: f.Ranges()[32].LSRange,
},
{
Code: &lsproto.IntegerOrString{Integer: new(int32(6196))},
Message: lsproto.StringOrMarkupContent{String: new("'O' is declared but never used.")},
Tags: &[]lsproto.DiagnosticTag{lsproto.DiagnosticTagUnnecessary},
Range: f.Ranges()[33].LSRange,
},
})
}

View File

@@ -0,0 +1,137 @@
package fourslash_test
import (
"testing"
"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestJsdocDeprecated_suggestion2(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// overloads
declare function foo(a: string): number;
/** @deprecated */
declare function foo(): undefined;
declare function foo (a?: string): number | undefined;
[|foo|]();
foo('');
foo;
/** @deprecated */
declare function bar(): number;
[|bar|]();
[|bar|];
/** @deprecated */
declare function baz(): number;
/** @deprecated */
declare function baz(): number | undefined;
[|baz|]();
[|baz|];
interface Foo {
/** @deprecated */
(): void
(a: number): void
}
declare const f: Foo;
[|f|]();
f(1);
interface T {
createElement(): void
/** @deprecated */
createElement(tag: 'xmp'): void;
}
declare const t: T;
t.createElement();
t.[|createElement|]('xmp');
declare class C {
/** @deprecated */
constructor ();
constructor(v: string)
}
C;
const c = new [|C|]();
interface Ca {
/** @deprecated */
(): void
new (): void
}
interface Cb {
(): void
/** @deprecated */
new (): string
}
declare const ca: Ca;
declare const cb: Cb;
ca;
cb;
[|ca|]();
cb();
new ca();
new [|cb|]();`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.VerifySuggestionDiagnostics(t, []*lsproto.Diagnostic{
{
Message: lsproto.StringOrMarkupContent{String: new("The signature '(): undefined' of 'foo' is deprecated.")},
Code: &lsproto.IntegerOrString{Integer: new(int32(6387))},
Range: f.Ranges()[0].LSRange,
Tags: &[]lsproto.DiagnosticTag{lsproto.DiagnosticTagDeprecated},
},
{
Message: lsproto.StringOrMarkupContent{String: new("The signature '(): number' of 'bar' is deprecated.")},
Code: &lsproto.IntegerOrString{Integer: new(int32(6387))},
Range: f.Ranges()[1].LSRange,
Tags: &[]lsproto.DiagnosticTag{lsproto.DiagnosticTagDeprecated},
},
{
Message: lsproto.StringOrMarkupContent{String: new("'bar' is deprecated.")},
Code: &lsproto.IntegerOrString{Integer: new(int32(6385))},
Range: f.Ranges()[2].LSRange,
Tags: &[]lsproto.DiagnosticTag{lsproto.DiagnosticTagDeprecated},
},
{
Message: lsproto.StringOrMarkupContent{String: new("The signature '(): number' of 'baz' is deprecated.")},
Code: &lsproto.IntegerOrString{Integer: new(int32(6387))},
Range: f.Ranges()[3].LSRange,
Tags: &[]lsproto.DiagnosticTag{lsproto.DiagnosticTagDeprecated},
},
{
Message: lsproto.StringOrMarkupContent{String: new("'baz' is deprecated.")},
Code: &lsproto.IntegerOrString{Integer: new(int32(6385))},
Range: f.Ranges()[4].LSRange,
Tags: &[]lsproto.DiagnosticTag{lsproto.DiagnosticTagDeprecated},
},
{
Message: lsproto.StringOrMarkupContent{String: new("The signature '(): void' of 'f' is deprecated.")},
Code: &lsproto.IntegerOrString{Integer: new(int32(6387))},
Range: f.Ranges()[5].LSRange,
Tags: &[]lsproto.DiagnosticTag{lsproto.DiagnosticTagDeprecated},
},
{
Message: lsproto.StringOrMarkupContent{String: new("The signature '(tag: \"xmp\"): void' of 't.createElement' is deprecated.")},
Code: &lsproto.IntegerOrString{Integer: new(int32(6387))},
Range: f.Ranges()[6].LSRange,
Tags: &[]lsproto.DiagnosticTag{lsproto.DiagnosticTagDeprecated},
},
{
Message: lsproto.StringOrMarkupContent{String: new("The signature 'new (): C' of 'C' is deprecated.")},
Code: &lsproto.IntegerOrString{Integer: new(int32(6387))},
Range: f.Ranges()[7].LSRange,
Tags: &[]lsproto.DiagnosticTag{lsproto.DiagnosticTagDeprecated},
},
{
Message: lsproto.StringOrMarkupContent{String: new("The signature '(): void' of 'ca' is deprecated.")},
Code: &lsproto.IntegerOrString{Integer: new(int32(6387))},
Range: f.Ranges()[8].LSRange,
Tags: &[]lsproto.DiagnosticTag{lsproto.DiagnosticTagDeprecated},
},
{
Message: lsproto.StringOrMarkupContent{String: new("The signature 'new (): string' of 'cb' is deprecated.")},
Code: &lsproto.IntegerOrString{Integer: new(int32(6387))},
Range: f.Ranges()[9].LSRange,
Tags: &[]lsproto.DiagnosticTag{lsproto.DiagnosticTagDeprecated},
},
})
}

View File

@@ -0,0 +1,73 @@
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 TestJsdocParameterNameCompletion(t *testing.T) {
fourslash.SkipIfFailing(t)
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `/**
* @param /*0*/
*/
function f(foo, bar) {}
/**
* @param foo
* @param /*1*/
*/
function g(foo, bar) {}
/**
* @param can/*2*/
* @param cantaloupe
*/
function h(cat, canary, canoodle, cantaloupe, zebra) {}
/**
* @param /*3*/ {string} /*4*/
*/
function i(foo, bar) {}`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.VerifyCompletions(t, []string{"0", "3", "4"}, &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &DefaultCommitCharacters,
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Exact: []fourslash.CompletionsExpectedItem{
"bar",
"foo",
},
},
})
f.VerifyCompletions(t, "1", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &DefaultCommitCharacters,
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Exact: []fourslash.CompletionsExpectedItem{
"bar",
},
},
})
f.VerifyCompletions(t, "2", &fourslash.CompletionsExpectedList{
IsIncomplete: false,
ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{
CommitCharacters: &DefaultCommitCharacters,
EditRange: Ignored,
},
Items: &fourslash.CompletionsExpectedItems{
Exact: []fourslash.CompletionsExpectedItem{
"canary",
"canoodle",
},
},
})
}

View File

@@ -0,0 +1,29 @@
package fourslash_test
import (
"testing"
"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestJsdocReturnsTagVS(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @allowJs: true
// @Filename: dummy.js
/**
* Find an item
* @template T
* @param {T[]} l
* @param {T} x
* @returns {?T} The names of the found item(s).
*/
function find(l, x) {
}
find(''/**/);`
f, done := fourslash.NewFourslash(t, &lsproto.ClientCapabilities{VSSupportsVisualStudioExtensions: new(true)}, content)
defer done()
f.VerifyBaselineSignatureHelp(t)
}

View File

@@ -0,0 +1,66 @@
package fourslash_test
import (
"testing"
"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestLinkedEditingJsxTag12(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @Filename: /incomplete.tsx
function Test() {
return <div>
</*0*/
<div {...{}}>
</div>
</div>
}
// @Filename: /incompleteMismatched.tsx
function Test() {
return <div>
<T
<div {...{}}>
</div>
</div>
}
// @Filename: /incompleteMismatched2.tsx
function Test() {
return <div>
<T
<div {...{}}>
T</div>
</div>
}
// @Filename: /incompleteMismatched3.tsx
function Test() {
return <div>
<div {...{}}>
</div>
<T
</div>
}
// @Filename: /mismatched.tsx
function Test() {
return <div>
<T>
<div {...{}}>
</div>
</div>
}
// @Filename: /matched.tsx
function Test() {
return <div>
<div {...{}}>
</div>
</div>
}`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
f.VerifyLinkedEditing(t, map[string][]lsproto.Range{"0": nil})
f.VerifyBaselineLinkedEditing(t)
}

View File

@@ -0,0 +1,66 @@
package fourslash_test
import (
"testing"
"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestLinkedEditingJsxTag1(t *testing.T) {
fourslash.SkipIfFailing(t)
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @Filename: /basic.tsx
/*a*/const j/*b*/sx = (
/*c*/</*0*/d/*1*/iv/*2*/>/*3*/
</*4*///*5*/di/*6*/v/*7*/>/*8*/
);
const jsx2 = (
</*9start*/d/*9*/iv/*9end*/>
</*10start*/d/*10*/iv/*10end*/>
</*11start*/p/*11*/>
<//*12*/p/*12end*/>
<//*13start*/d/*13*/iv/*13end*/>
<//*14start*/d/*14*/iv/*14end*/>
);/*d*/`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
linkedCursors1 := []lsproto.Range{
{Start: f.MarkerByName(t, "0").LSPosition, End: f.MarkerByName(t, "2").LSPosition}, {Start: f.MarkerByName(t, "5").LSPosition, End: f.MarkerByName(t, "7").LSPosition},
}
linkedCursors2 := []lsproto.Range{
{Start: f.MarkerByName(t, "9start").LSPosition, End: f.MarkerByName(t, "9end").LSPosition},
{Start: f.MarkerByName(t, "14start").LSPosition, End: f.MarkerByName(t, "14end").LSPosition},
}
linkedCursors3 := []lsproto.Range{
{Start: f.MarkerByName(t, "10start").LSPosition, End: f.MarkerByName(t, "10end").LSPosition},
{Start: f.MarkerByName(t, "13start").LSPosition, End: f.MarkerByName(t, "13end").LSPosition},
}
linkedCursors4 := []lsproto.Range{
{Start: f.MarkerByName(t, "11start").LSPosition, End: f.MarkerByName(t, "11").LSPosition},
{Start: f.MarkerByName(t, "12").LSPosition, End: f.MarkerByName(t, "12end").LSPosition},
}
f.VerifyLinkedEditing(t, map[string][]lsproto.Range{
"0": linkedCursors1,
"1": linkedCursors1,
"2": linkedCursors1,
"3": nil,
"4": nil,
"5": linkedCursors1,
"6": linkedCursors1,
"7": linkedCursors1,
"8": nil,
"9": linkedCursors2,
"10": linkedCursors3,
"11": linkedCursors4,
"12": linkedCursors4,
"13": linkedCursors3,
"14": linkedCursors2,
"a": nil,
"b": nil,
"c": nil,
"d": nil,
})
}

View File

@@ -0,0 +1,60 @@
package fourslash_test
import (
"testing"
"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestLinkedEditingJsxTag2(t *testing.T) {
fourslash.SkipIfFailing(t)
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @Filename: /attrs.tsx
const jsx = (
</*0*/div/*1*/ /*2*/styl/*3*/e={{ color: 'red' }}/*4*/>/*5*/
<p>
<img />
</p>
<//*6start*/di/*6*/v/*6end*/>
);
// @Filename: /attrsError.tsx
const jsx = (
</*10*/div/*11*/ /*12*/styl/*13*/e={{ color: 'red' }/*14*/>/*15*/
</*16*/p />
<//*17*/div>
);`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
// Test file content (for readability):
// const jsx = (
// <div style={{ color: 'red' }}>
// <p>
// <img />
// </p>
// </div>
// );
linkedCursors := []lsproto.Range{
{Start: f.MarkerByName(t, "0").LSPosition, End: f.MarkerByName(t, "1").LSPosition},
{Start: f.MarkerByName(t, "6start").LSPosition, End: f.MarkerByName(t, "6end").LSPosition},
}
f.VerifyLinkedEditing(t, map[string][]lsproto.Range{
"0": linkedCursors,
"1": linkedCursors,
"2": nil,
"3": nil,
"4": nil,
"5": nil,
"6": linkedCursors,
"10": nil,
"11": nil,
"12": nil,
"13": nil,
"14": nil,
"15": nil,
"16": nil,
})
}

View File

@@ -0,0 +1,51 @@
package fourslash_test
import (
"testing"
"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestLinkedEditingJsxTag4(t *testing.T) {
fourslash.SkipIfFailing(t)
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @Filename: /typeTag.tsx
const jsx = (
</*0*/div/*1*/</*2*/T/*3*/>/*4*/>/*5*/
<p>
<img />
</p>
<//*6*/div/*7*/>
);
// @Filename: /typeTagError.tsx
const jsx = (
</*10*/div/*11*/</*12*/T/*13*/>/*14*/
</*15*/p />
<//*16*/div>
);`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
linkedCursors := []lsproto.Range{
{Start: f.MarkerByName(t, "0").LSPosition, End: f.MarkerByName(t, "1").LSPosition},
{Start: f.MarkerByName(t, "6").LSPosition, End: f.MarkerByName(t, "7").LSPosition},
}
f.VerifyLinkedEditing(t, map[string][]lsproto.Range{
"0": linkedCursors,
"1": linkedCursors,
"2": nil,
"3": nil,
"4": nil,
"5": nil,
"6": linkedCursors,
"10": nil,
"11": nil,
"12": nil,
"13": nil,
"14": nil,
"15": nil,
"16": nil,
})
}

View File

@@ -0,0 +1,59 @@
package fourslash_test
import (
"testing"
"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestLinkedEditingJsxTag5(t *testing.T) {
fourslash.SkipIfFailing(t)
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @FileName: /unclosedElement.tsx
const jsx = (
<div/*0*/>
</*1start*/div/*1*/>
<//*2start*/div/*2*/>/*3*/
);/*4*/
// @FileName: /mismatchedElement.tsx
const jsx = (
/*5*/</*6start*/div/*6*/>
<//*7start*/div/*7*/>
</*8*//div/*9*/>/*10*/
);
// @Filename: /invalidClosing.tsx
const jsx = (
<di/*11*/v>
</*12*/ //*13*/div>
);`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
linkedCursors1 := []lsproto.Range{
{Start: f.MarkerByName(t, "1start").LSPosition, End: f.MarkerByName(t, "1").LSPosition},
{Start: f.MarkerByName(t, "2start").LSPosition, End: f.MarkerByName(t, "2").LSPosition},
}
linkedCursors2 := []lsproto.Range{
{Start: f.MarkerByName(t, "6start").LSPosition, End: f.MarkerByName(t, "6").LSPosition},
{Start: f.MarkerByName(t, "7start").LSPosition, End: f.MarkerByName(t, "7").LSPosition},
}
f.VerifyLinkedEditing(t, map[string][]lsproto.Range{
"0": nil,
"1": linkedCursors1,
"2": linkedCursors1,
"3": nil,
"4": nil,
"5": nil,
"6": linkedCursors2,
"7": linkedCursors2,
"8": nil,
"9": nil,
"10": nil,
"11": nil, // this tag does not parse as a closing tag
"12": nil,
"13": nil,
})
}

View File

@@ -0,0 +1,76 @@
package fourslash_test
import (
"testing"
"github.com/microsoft/typescript-go/internal/fourslash"
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
"github.com/microsoft/typescript-go/internal/testutil"
)
func TestLinkedEditingJsxTag6(t *testing.T) {
fourslash.SkipIfFailing(t)
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `// @Filename: /namespace.tsx
const jsx = (
</*start*/someNamespa/*3*/ce./*2*/Thing/*startend*/>
<//*end*/someNamespace/*1*/.Thing/*endend*/>
);
const jsx1 = </*4*/foo/*5*/ /*6*/./*7*/ /*8*/ba/*9*/r><//*10*/foo.bar>;
const jsx2 = <foo./*11*/bar><//*12*/ /*13*/f/*14*/oo /*15*/./*16*/b/*17*/ar/*18*/>;
const jsx3 = </*19*/foo/*20*/ //*21*// /*22*/some comment
/*23*/./*24*/bar>
</f/*25*/oo.bar>;
let jsx4 =
</*26*/foo /*27*/ .// hi/*28*/
/*29*/bar/*26end*/>
<//*30*/foo /*31*/ .// hi/*32*/
/*33*/bar/*30end*/>`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()
linkedCursors1 := []lsproto.Range{
{Start: f.MarkerByName(t, "start").LSPosition, End: f.MarkerByName(t, "startend").LSPosition},
{Start: f.MarkerByName(t, "end").LSPosition, End: f.MarkerByName(t, "endend").LSPosition},
}
linkedCursors2 := []lsproto.Range{
{Start: f.MarkerByName(t, "26").LSPosition, End: f.MarkerByName(t, "26end").LSPosition},
{Start: f.MarkerByName(t, "30").LSPosition, End: f.MarkerByName(t, "30end").LSPosition},
}
f.VerifyLinkedEditing(t, map[string][]lsproto.Range{
"1": linkedCursors1,
"2": linkedCursors1,
"3": linkedCursors1,
"4": nil,
"5": nil,
"6": nil,
"7": nil,
"8": nil,
"9": nil,
"10": nil,
"11": nil,
"12": nil,
"13": nil,
"14": nil,
"15": nil,
"16": nil,
"17": nil,
"18": nil,
"19": nil,
"20": nil,
"21": nil,
"22": nil,
"23": nil,
"24": nil,
"25": nil,
"26": linkedCursors2,
"27": linkedCursors2,
"28": linkedCursors2,
"29": linkedCursors2,
"30": linkedCursors2,
"31": linkedCursors2,
"32": linkedCursors2,
"33": linkedCursors2,
})
}

Some files were not shown because too many files have changed in this diff Show More