/*
* Copyright 2013-2016 Sergey Ignatov, Alexander Zolotov, Florin Patan
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.goide.completion;
import com.goide.SdkAware;
import com.goide.sdk.GoSdkService;
import com.intellij.codeInsight.completion.CompletionType;
import com.intellij.codeInsight.lookup.Lookup;
import com.intellij.psi.PsiFile;
import java.io.IOException;
import java.util.List;
@SdkAware
public class GoCompletionSdkAwareTest extends GoCompletionTestBase {
public void testFormatter() {
doTestInclude("package main; import . \"fmt\"; type alias <caret>", "Formatter");
}
public void testDoNotCompleteBuiltinFunctions() {
doCheckResult("package main; var a = fals<caret>", "package main; var a = false<caret>");
}
public void testCamelHumpTypeCompletion() {
doCheckResult("package main;\n" +
"func test(){io.reWSC<caret>}",
"package main;\n\n" +
"import \"idea_io\"\n\n" +
"func test(){idea_io.ReadWriteSeekerCustom()}", Lookup.NORMAL_SELECT_CHAR);
}
public void testCamelHumpFunctionCompletion() {
doCheckResult("package main;\n" +
"func test(){io.reALC<caret>}",
"package main;\n\n" +
"import \"idea_io\"\n\n" +
"func test(){idea_io.ReadAtLeastCustom()}", Lookup.NORMAL_SELECT_CHAR);
}
public void testTypeAutoImport() {
doCheckResult("package main; \n" +
"func test(){Templat<caret>}",
"package main;\n\n" +
"import \"text/template\"\n\n" +
"func test(){template.Template{<caret>}}", "template.Template");
}
public void testTypeAutoImportOnQualifiedName() {
doCheckResult("package main; \n" +
"func test(){template.Templat<caret>}",
"package main;\n\n" +
"import \"text/template\"\n\n" +
"func test(){template.Template{<caret>}}");
}
public void testFunctionAutoImport() {
doCheckResult("package main; \n" +
"func test(){Fprintl<caret>}",
"package main;\n\n" +
"import \"fmt\"\n\n" +
"func test(){fmt.Fprintln(<caret>)}", "fmt.Fprintln");
}
public void testVariableAutoImport() {
doCheckResult("package main; \n" +
"func test(){ErrNotSuppor<caret>}",
"package main;\n\n" +
"import \"net/http\"\n\n" +
"func test(){http.ErrNotSupported}", "http.ErrNotSupported");
}
public void testConstantAutoImport() {
doCheckResult("package main; \n" +
"func test(){O_RDO<caret>}", "package main;\n\n" +
"import \"os\"\n\n" +
"func test(){os.O_RDONLY}");
}
public void testDuplicateAutoImport() {
doCheckResult("package main; \n" +
"func test(){Fprintl<caret>}",
"package main;\n\n" +
"import \"fmt\"\n\n" +
"func test(){fmt.Fprintln(<caret>)}", "fmt.Fprintln");
myFixture.type(");Fprintl");
myFixture.completeBasic();
selectLookupItem("fmt.Fprintln");
myFixture.checkResult("package main;\n\n" +
"import \"fmt\"\n\n" +
"func test(){fmt.Fprintln();fmt.Fprintln()}");
}
public void testForceAutoImportBlankImports() {
doCheckResult("package main; \n" +
"import _ \"fmt\"\n" +
"func test(){Fprintl<caret>}",
"package main;\n\n" +
"import (\n" +
"\t_ \"fmt\"\n" +
"\t\"fmt\"\n" +
")\n" +
"func test(){fmt.Fprintln()}", "fmt.Fprintln");
}
public void testAutoImportWithAlias() {
doCheckResult("package main; \n" +
"import alias `fmt`\n" +
"func test(){Fprintl<caret>}",
"package main; \n" +
"import alias `fmt`\n" +
"func test(){alias.Fprintln()}",
"alias.Fprintln");
}
public void testAutoImportWithDotAlias() {
doCheckResult("package main; \n" +
"import . `fmt`\n" +
"func test(){Fprintl<caret>}",
"package main; \n" +
"import . `fmt`\n" +
"func test(){Fprintln()}");
}
public void testUseImportPathInsteadOfPackageNameForAutoImport() {
doCheckResult("package main\n" +
"\n" +
"import (\n" +
" \"fmt\"\n" +
")\n" +
"\n" +
"func main() {\n" +
" fmt.Printf(FunctionInPackageThatDoesNotMatchDirectory<caret>);\n" +
"}",
"package main\n" +
"\n" +
"import (\n" +
" \"fmt\"\n" +
"\t\"dirName\"\n" +
")\n" +
"\n" +
"func main() {\n" +
" fmt.Printf(otherPackage.FunctionInPackageThatDoesNotMatchDirectoryName());\n" +
"}", "otherPackage.FunctionInPackageThatDoesNotMatchDirectoryName");
}
public void testUsePackageNameInsteadOfImportPathIfPackageIsImported() {
doCheckResult("package main\n" +
"\n" +
"import (\n" +
" \"fmt\"\n" +
" \"dirName\"\n" +
")\n" +
"\n" +
"func main() {\n" +
" fmt.Printf(FunctionInPackageThatDoesNotMatchDirectory<caret>);\n" +
"}",
"package main\n" +
"\n" +
"import (\n" +
" \"fmt\"\n" +
" \"dirName\"\n" +
")\n" +
"\n" +
"func main() {\n" +
" fmt.Printf(otherPackage.FunctionInPackageThatDoesNotMatchDirectoryName());\n" +
"}", "otherPackage.FunctionInPackageThatDoesNotMatchDirectoryName");
}
public void testDoNotImportLocallyImportedPackage() throws IOException {
myFixture.addFileToProject("imported/imported.go", "package imported\n" +
"func LocallyImported() {}");
doCheckResult("package main; \n" +
"import `./imported`\n" +
"func test(){LocallyImport<caret>}", "package main; \n" +
"import `./imported`\n" +
"func test(){imported.LocallyImported()}",
"imported.LocallyImported");
}
public void testImportedFunctionsPriority() {
myFixture.configureByText("a.go", "package main; \n" +
"import `io`\n" +
"func test(){ReadA<caret>}");
failOnFileLoading();
myFixture.completeBasic();
myFixture.assertPreferredCompletionItems(0, "io.ReadAtLeast", "io.ReaderAt", "idea_io.ReadAtLeastCustom", "idea_io.ReaderAtCustom");
}
public void testImportedTypesPriority() {
myFixture.configureByText("a.go", "package main; \n" +
"import `io`\n" +
"func test(ReadWriteSeeke<caret>){}");
failOnFileLoading();
myFixture.completeBasic();
myFixture.assertPreferredCompletionItems(0, "io.ReadWriteSeeker", "idea_io.ReadWriteSeekerCustom");
}
public void testDoNothingInsideSelector() {
doTestVariants(
"package main\n" +
"import \"fmt\"\n" +
"func test(){fmt.Sprintln().<caret>}", CompletionType.BASIC, 1, CheckType.EQUALS
);
}
public void testDoNotRunAutoImportCompletionAfterDot() {
doTestCompletion();
}
public void testDoNotRunAutoImportFunctionCompletionAfterUnaryAmpersand() {
doCheckResult("package main;\n" +
"func test(){println(&io.reALC<caret>)}",
"package main;\n" +
"func test(){println(&io.reALC\n" +
"\t<caret>)}", Lookup.NORMAL_SELECT_CHAR);
assertNull(myFixture.getLookup());
}
public void testDoNotRunAutoImportCompletionAfterDotAndSpace() {
doTestCompletion();
assertNull(myFixture.getLookup());
}
public void testImports() {
doTestInclude("package main; import \"<caret>", "fmt", "io");
}
public void testCaseInsensitiveTypeConversion() {
doCheckResult("package main; import \"fmt\"; func test(){fmt.form<caret>}",
"package main; import \"fmt\"; func test(){fmt.Formatter(<caret>)}");
}
public void testCaseInsensitiveFunction() {
doCheckResult("package main; import \"fmt\"; func test(){fmt.err<caret>}",
"package main; import \"fmt\"; func test(){fmt.Errorf(<caret>)}");
}
public void testCaseInsensitiveType() {
doCheckResult("package main; import \"fmt\"; func test(fmt.form<caret>}",
"package main; import \"fmt\"; func test(fmt.Formatter<caret>}");
}
public void testPrintlnBuiltin() {
doTestInclude("package main; func test(){pr<caret>}", "print", "println");
}
public void testNothingUnrelatedInsideSelector() {
doTestEquals("package foo; type E struct {}; type B struct {E}; func (e E) foo() {}; func boo() {}" +
"func main() {B{}.E..<caret>foo()}", "foo");
}
public void testCompleteWithUnfinishedPackage() {
doCheckResult("package main\n" +
"func main() {\n" +
" f.fprintl<caret>\n" +
"}",
"package main\n\n" +
"import \"fmt\"\n\n" +
"func main() {\n" +
" fmt.Fprintln()\n" +
"}");
}
public void testDoNotCompleteTestFunctions() throws IOException {
myFixture.addFileToProject("pack/pack_test.go", "package pack; func TestFoo() {}");
myFixture.configureByText("my_test.go", "package a; func main() { _ = TestF<caret>");
myFixture.completeBasic();
assertNull(myFixture.getLookup());
myFixture.checkResult("package a; func main() { _ = TestF<caret>");
}
public void testDoNotCompleteBenchmarkFunctions() throws IOException {
myFixture.addFileToProject("pack/pack_test.go", "package pack; func BenchmarkFoo() {}");
myFixture.configureByText("my_test.go", "package a; func main() { _ = BenchmarkF<caret>");
myFixture.completeBasic();
assertNull(myFixture.getLookup());
myFixture.checkResult("package a; func main() { _ = BenchmarkF<caret>");
}
public void testDoNotCompleteExampleFunctions() throws IOException {
myFixture.addFileToProject("pack/pack_test.go", "package pack; func ExampleFoo() {}");
myFixture.configureByText("my_test.go", "package a; func main() { _ = ExampleF<caret>");
assertNull(myFixture.getLookup());
myFixture.completeBasic();
}
public void testCompleteTestBenchmarkExamplesFromNonTestFiles() throws IOException {
myFixture.addFileToProject("pack/pack.go", "package pack; func TestFoo() {} func BenchmarkFoo() {} func ExampleFoo() {}");
myFixture.configureByText("my_test.go", "package a; func main() { _ = Foo<caret>");
myFixture.completeBasic();
//noinspection ConstantConditions
assertContainsElements(myFixture.getLookupElementStrings(), "pack.TestFoo", "pack.BenchmarkFoo", "pack.ExampleFoo");
}
public void testDoNotAutoImportWithTheSameImportPath() throws IOException {
myFixture.addFileToProject("pack1/file2.go", "package pack1; func MyFunctionFromSamePath() {}");
myFixture.addFileToProject("pack2/file2.go", "package pack1; func MyFunctionFromOtherPath() {}");
PsiFile file = myFixture.addFileToProject("pack1/file1.go", "package pack1; func test() { pack1.MyFunc<caret> }");
myFixture.configureFromExistingVirtualFile(file.getVirtualFile());
myFixture.completeBasic();
myFixture.checkResult("package pack1;\n\nimport \"pack2\"\n\nfunc test() { pack1.MyFunctionFromOtherPath() }");
}
public void testAutoImportOwnImportPathFromTest() throws IOException {
myFixture.addFileToProject("pack/a.go", "package myPack; func Func() {}");
PsiFile testFile = myFixture.addFileToProject("pack/a_test.go", "package myPack_test; func TestFunc() { myPack.Fun<caret> }");
myFixture.configureFromExistingVirtualFile(testFile.getVirtualFile());
myFixture.completeBasic();
myFixture.checkResult("package myPack_test;\n\nimport \"pack\"\n\nfunc TestFunc() { myPack.Func() }");
}
public void testDoNotAutoImportDifferentPackageInSamePathFromTest() throws IOException {
String text = "package foo_test; func TestFunc() { bar.Fun<caret> }";
myFixture.addFileToProject("pack/a.go", "package bar; func Func() {}");
PsiFile file = myFixture.addFileToProject("pack/a_test.go", text);
myFixture.configureFromExistingVirtualFile(file.getVirtualFile());
myFixture.completeBasic();
assertNull(myFixture.getLookup());
myFixture.checkResult(text);
}
public void testImportOwnPathFromTestFile() throws IOException {
PsiFile testFile = myFixture.addFileToProject("fuzz/fuzy_test.go", "package fuzy_test; import \"<caret>\"");
myFixture.configureFromExistingVirtualFile(testFile.getVirtualFile());
myFixture.completeBasic();
//noinspection ConstantConditions
assertContainsElements(myFixture.getLookupElementStrings(), "fuzz");
}
public void testDoNotImportOwnPathFromNonTestPackage() throws IOException {
PsiFile testFile = myFixture.addFileToProject("fuzz/fuzy_test.go", "package fuzy; import \"<caret>\"");
myFixture.configureFromExistingVirtualFile(testFile.getVirtualFile());
myFixture.completeBasic();
List<String> strings = myFixture.getLookupElementStrings();
assertTrue(strings != null && !strings.contains("fuzz"));
}
public void testDoNotCompleteBuiltinImport() {
doCheckResult("package a; import \"built<caret>\"", "package a; import \"built<caret>\"");
assertNull(myFixture.getLookup());
}
public void testCompleteVendoredBuiltinImport() {
myFixture.addFileToProject("vendor/builtin/builtin.go", "package builtin; func Hello() {}");
doCheckResult("package a; import \"built<caret>\"", "package a; import \"builtin<caret>\"");
}
public void testAutoImportVendorPackage() {
myFixture.addFileToProject("vendor/vendorPackage/foo.go", "package vendorPackage; func Bar() {}");
doCheckResult("package src; func _() { ven.Ba<caret> }", "package src;\n" +
"\n" +
"import \"vendorPackage\"\n" +
"\n" +
"func _() { vendorPackage.Bar() }");
}
public void testAutoImportVendorPackageWithDisabledVendoring() {
disableVendoring();
myFixture.addFileToProject("vendor/vendorPackage/foo.go", "package vendorPackage; func Bar() {}");
doCheckResult("package src; func _() { ven.Ba<caret> }", "package src;\n" +
"\n" +
"import \"vendor/vendorPackage\"\n" +
"\n" +
"func _() { vendorPackage.Bar() }");
}
public void testDoNotCompleteSymbolsFromUnreachableVendoredPackages() {
myFixture.addFileToProject("vendor/foo/foo.go", "package foo; func VendoredFunction() {}");
myFixture.addFileToProject("vendor/foo/vendor/bar/bar.go", "package bar; func VendoredFunction() {}");
myFixture.configureByText("a.go", "package src; func _() { VendorF<caret> }");
myFixture.completeBasic();
//noinspection ConstantConditions
assertSameElements(myFixture.getLookupElementStrings(), "foo.VendoredFunction");
}
public void testDoNotCompleteSymbolsFromShadowedPackages() {
myFixture.addFileToProject("foo/foo.go", "package foo; func ShadowedFunction() {}");
myFixture.addFileToProject("vendor/foo/foo.go", "package bar; func ShadowedFunction() {}");
myFixture.configureByText("a.go", "package src; func _() { ShadowF<caret> }");
myFixture.completeBasic();
//noinspection ConstantConditions
assertSameElements(myFixture.getLookupElementStrings(), "bar.ShadowedFunction");
}
public void testDoNotCompleteSymbolsFromShadowedVendoredPackages() {
myFixture.addFileToProject("vendor/foo/foo.go", "package bar; func ShadowedFunction() {}");
myFixture.addFileToProject("vendor/foo/vendor/foo/foo.go", "package bar; func ShadowedFunction() {}");
PsiFile file = myFixture.addFileToProject("vendor/foo/main.go", "package foo; func _() { ShadowF<caret> }");
myFixture.configureFromExistingVirtualFile(file.getVirtualFile());
myFixture.completeBasic();
//noinspection ConstantConditions
assertSameElements(myFixture.getLookupElementStrings(), "bar.ShadowedFunction");
}
public void testDoNotCompletePackagesShadowedBySdkDirectories() {
myFixture.addFileToProject("fmt/subdir/fmt.go", "package subdir; func Println() {}");
myFixture.addFileToProject("fmt/fmt.go", "package shadowed; func Println() {}");
myFixture.configureByText("a.go", "package src; import `fmt<caret>`");
myFixture.completeBasic();
//noinspection ConstantConditions
assertSameElements(myFixture.getLookupElementStrings(), "fmt", "fmt/subdir");
}
public void testDoNotCompleteFunctionsFromPackagesShadowedBySdkDirectories() {
myFixture.addFileToProject("fmt/subdir/fmt.go", "package subdir; func Println() {}");
myFixture.addFileToProject("fmt/fmt.go", "package shadowed; func Println() {}");
myFixture.configureByText("a.go", "package src; func _() { Printl<caret> }");
myFixture.completeBasic();
List<String> elementStrings = myFixture.getLookupElementStrings();
assertNotNull(elementStrings);
assertContainsElements(elementStrings, "subdir.Println");
assertDoesntContain(elementStrings, "shadowed.Println");
}
public void testCompleteInternalPackageOn1_2_SDK() {
myFixture.addFileToProject("internal/internal.go", "package internalPackage; func InternalFunction() {}");
myFixture.addFileToProject("sub/internal/internal.go", "package subInternalPackage; func InternalFunction() {}");
myFixture.configureByText("a.go", "package a; import `inte<caret>`");
myFixture.completeBasic();
List<String> elementStrings = myFixture.getLookupElementStrings();
assertNotNull(elementStrings);
assertContainsElements(elementStrings, "internal", "sub/internal", "net/internal");
}
public void testCompleteInternalPackageOn1_4_SDK() {
GoSdkService.setTestingSdkVersion("1.4", getTestRootDisposable());
myFixture.addFileToProject("internal/internal.go", "package internalPackage; func InternalFunction() {}");
myFixture.addFileToProject("sub/internal/internal.go", "package subInternalPackage; func InternalFunction() {}");
myFixture.configureByText("a.go", "package a; import `inte<caret>`");
myFixture.completeBasic();
List<String> elementStrings = myFixture.getLookupElementStrings();
assertNotNull(elementStrings);
assertContainsElements(elementStrings, "internal", "sub/internal");
assertDoesntContain(elementStrings, "net/internal");
}
public void testCompleteInternalPackageOn1_5_SDK() {
GoSdkService.setTestingSdkVersion("1.5", getTestRootDisposable());
myFixture.addFileToProject("internal/internal.go", "package internalPackage; func InternalFunction() {}");
myFixture.addFileToProject("sub/internal/internal.go", "package subInternalPackage; func InternalFunction() {}");
doCheckResult("package a; import `inte<caret>`", "package a; import `internal`");
}
public void testIntArray() { doTestInclude("package a; var x = []<caret>", "int"); }
public void testMapIntInt() { doTestInclude("package a; var x = map[int]<caret>", "int"); }
public void testStruct() { doTestInclude("package a; var x = <caret>", "struct"); }
}