More reliable testing of keyword completion (introduced directive "NOTHING_ELSE" instead of "NUMBER")

This commit is contained in:
Valentin Kipyatkov
2015-05-14 17:46:56 +03:00
parent 5807d03a52
commit db40f1ee5a
75 changed files with 113 additions and 80 deletions
@@ -16,6 +16,6 @@ class Derived: Base<String>() {
// INVOCATION_COUNT: 1
// EXIST: funInBase, funWithOverride, funWithoutOverride
// NUMBER: 3
// NOTHING_ELSE: true
// RUNTIME_TYPE: Derived
@@ -20,6 +20,6 @@ class C: B() {
// INVOCATION_COUNT: 2
// EXIST: funA, funAp, funB, funBp, funC, funCp
// NUMBER: 6
// NOTHING_ELSE: true
// RUNTIME_TYPE: C
@@ -14,7 +14,7 @@ fun Base.funExtBase() { }
// INVOCATION_COUNT: 1
// EXIST: funExtBase, funExtDerived
// NUMBER: 2
// NOTHING_ELSE: true
// RUNTIME_TYPE: Derived
@@ -18,7 +18,7 @@ class Derived: Base() {
// INVOCATION_COUNT: 1
// EXIST: funInBase, funWithOverride, funWithoutOverride, funInDerived
// NUMBER: 4
// NOTHING_ELSE: true
// RUNTIME_TYPE: Derived
@@ -7,4 +7,4 @@ class Test {
}
// EXIST: util
// NUMBER: 1
// NOTHING_ELSE: true
@@ -8,4 +8,4 @@ fun foo() {
// EXIST: ext1
// EXIST: ext2
// NUMBER: 2
// NOTHING_ELSE: true
@@ -9,4 +9,4 @@ fun firstFun() {
// INVOCATION_COUNT: 1
// EXIST: Testing
// NUMBER: 1
// NOTHING_ELSE: true
@@ -15,4 +15,4 @@ fun g(a: A) {
// EXIST: foo
// EXIST: foo1
// NUMBER: 2
// NOTHING_ELSE: true
@@ -8,4 +8,4 @@ fun test() = small(paramFirst = param<caret>)
// EXIST: paramTest
// ABSENT: {"lookupString":"paramFirst","tailText":" Int","itemText":"paramFirst ="}
// ABSENT: paramSecond
// NUMBER: 1
// NOTHING_ELSE: true
@@ -7,4 +7,4 @@ fun test(p: Int) = foo(12, third = "", <caret>)
// ABSENT: first
// ABSENT: third
// EXIST: second
// NUMBER: 1
// NOTHING_ELSE: true
@@ -9,4 +9,4 @@ fun test() = small(param<caret>First = 12)
// EXIST: paramSecond
// EXIST: paramTest
// NUMBER: 3
// NOTHING_ELSE: true
@@ -9,4 +9,4 @@ fun firstFun() {
// INVOCATION_COUNT: 1
// EXIST: { lookupString:"toLinkedList", itemText:"toLinkedList", tailText:"() for Iterable<T> in kotlin" }
// NUMBER: 1
// NOTHING_ELSE: true
@@ -4,4 +4,4 @@ val x = InputStreamReader<caret>
// INVOCATION_COUNT: 2
// EXIST: { lookupString:"InputStreamReader", tailText:" (java.io)" }
// NUMBER: 1
// NOTHING_ELSE: true
@@ -2,4 +2,4 @@ val x = LinesSequence<caret>
// INVOCATION_COUNT: 2
// EXIST: { lookupString:"LinesSequence", tailText:" (kotlin.io)" }
// NUMBER: 1
// NOTHING_ELSE: true
@@ -12,4 +12,4 @@ fun firstFun() {
// EXIST: testingExpectedFunction
// ABSENT: testingUnexpectedFunction
// NUMBER: 2
// NOTHING_ELSE: true
@@ -9,4 +9,4 @@ fun firstFun() {
// EXIST: helloFunPreventAutoInsert
// EXIST: helloWithParams
// ABSENT: helloFake
// NUMBER: 3
// NOTHING_ELSE: true
@@ -4,4 +4,4 @@ class A : NotImported<caret>
// AUTOCOMPLETE_SETTING: true
// EXIST: NotImportedClass
// NUMBER: 1
// NOTHING_ELSE: true
@@ -6,4 +6,4 @@ fun f() {
// EXIST: extFun1
// EXIST: extFun2
// NUMBER: 2
// NOTHING_ELSE: true
@@ -1,9 +1,9 @@
// this test tests correct substitution equality checking for generic functions
import dependency.pair
import java.io.InputStreamReader
fun foo() {
1 pai<caret>
}
// EXIST: pair
// NUMBER: 1
// NOTHING_ELSE: true
@@ -11,4 +11,4 @@ class C {
// EXIST: helloProp
// EXIST: helloForC
// ABSENT: helloFake
// NUMBER: 4
// NOTHING_ELSE: true
@@ -9,4 +9,4 @@ fun firstFun(p: () -> Unit) {
// EXIST: helloAny
// ABSENT: helloFun3
// ABSENT: helloFun4
// NUMBER: 3
// NOTHING_ELSE: true
@@ -10,4 +10,4 @@ fun firstFun(p: String.() -> Unit) {
// ABSENT: helloFun4
// ABSENT: helloFun5
// EXIST: helloAny
// NUMBER: 3
// NOTHING_ELSE: true
@@ -6,4 +6,4 @@ fun firstFun(x: third.Dependency) {
// EXIST: helloFun
// EXIST: helloFunGeneric
// NUMBER: 2
// NOTHING_ELSE: true
@@ -9,4 +9,4 @@ fun firstFun() {
// EXIST: { lookupString: "helloProp2", attributes: "bold" }
// ABSENT: helloProp3
// ABSENT: helloProp4
// NUMBER: 2
// NOTHING_ELSE: true
@@ -34,4 +34,5 @@ class MouseMovedEventArgs
// EXIST: constructor
// EXIST: init
/*why?*/
// NUMBER: 27
// EXIST: companion
// NOTHING_ELSE: true
@@ -37,4 +37,6 @@ class B {
// EXIST: var
// EXIST: vararg
/*why?*/
// NUMBER: 22
// EXIST: companion
/*TODO*/
// NOTHING_ELSE: true
@@ -37,4 +37,5 @@ class A {
// EXIST: constructor
// EXIST: init
/*why?*/
// NUMBER: 24
// EXIST: companion
// NOTHING_ELSE: true
@@ -3,3 +3,4 @@ class A(x: Int) {
}
// EXIST: this, super
// NOTHING_ELSE: true
@@ -14,4 +14,4 @@ fun foo() {
// EXIST: { lookupString: "break@myDo", itemText: "break", tailText: "@myDo", attributes: "bold" }
// EXIST: { lookupString: "break@myWhile", itemText: "break", tailText: "@myWhile", attributes: "bold" }
// EXIST: { lookupString: "break@myFor", itemText: "break", tailText: "@myFor", attributes: "bold" }
// NUMBER: 3
// NOTHING_ELSE: true
@@ -7,4 +7,4 @@ fun foo() {
// EXIST: as
// EXIST: in
// EXIST: is
// NUMBER: 5
// NOTHING_ELSE: true
@@ -14,4 +14,4 @@ fun foo() {
// EXIST: { lookupString: "continue@myDo", itemText: "continue", tailText: "@myDo", attributes: "bold" }
// EXIST: { lookupString: "continue@myWhile", itemText: "continue", tailText: "@myWhile", attributes: "bold" }
// EXIST: { lookupString: "continue@myFor", itemText: "continue", tailText: "@myFor", attributes: "bold" }
// NUMBER: 3
// NOTHING_ELSE: true
@@ -1,4 +1,4 @@
[<caret>]
// EXIST: file
// NUMBER: 1
// NOTHING_ELSE: true
@@ -37,4 +37,6 @@ var a : Int
// EXIST: var
// EXIST: vararg
/*why?*/
// NUMBER: 25
// EXIST: companion
/*TODO*/
// NOTHING_ELSE: true
@@ -20,4 +20,4 @@ fun foo(p: Int) {
// EXIST: try
// EXIST: when
// EXIST: while
// NUMBER: 15
// NOTHING_ELSE: true
@@ -35,4 +35,5 @@ public class Test {
// EXIST: constructor
// EXIST: init
/*why?*/
// NUMBER: 24
// EXIST: companion
// NOTHING_ELSE: true
@@ -29,4 +29,5 @@ class TestClass {
/*why?*/
// EXIST: constructor
// EXIST: init
// NUMBER: 24
// EXIST: companion
// NOTHING_ELSE: true
@@ -2,4 +2,4 @@ class T<<caret>>
// EXIST: in
// EXIST: out
// NUMBER: 2
// NOTHING_ELSE: true
@@ -21,4 +21,4 @@ fun foo() {
// EXIST: var
// EXIST: when
// EXIST: while
// NUMBER: 19
// NOTHING_ELSE: true
@@ -9,4 +9,4 @@ class C(<caret>)
// EXIST: protected
// EXIST: internal
// EXIST: override
// NUMBER: 8
// NOTHING_ELSE: true
@@ -14,4 +14,4 @@ fun foo() = <caret>
// EXIST: try
// EXIST: when
// EXIST: while
// NUMBER: 14
// NOTHING_ELSE: true
@@ -5,4 +5,4 @@ fun foo() {
/*TODO: Is 'package' type qualifier syntax correct?*/
// EXIST: package
// EXIST: dynamic
// NUMBER: 2
// NOTHING_ELSE: true
@@ -15,4 +15,4 @@ val prop: Int
// EXIST: try
// EXIST: when
// EXIST: while
// NUMBER: 14
// NOTHING_ELSE: true
@@ -10,4 +10,4 @@ class TestSample() {
// EXIST: var
// EXIST: in
// EXIST: out
// NUMBER: 4
// NOTHING_ELSE: true
@@ -4,4 +4,4 @@ open class Foo {
}
// EXIST: private, public, protected
// NUMBER: 3
// NOTHING_ELSE: true
@@ -4,4 +4,4 @@ fun testing() {}
// EXIST: in
// EXIST: out
// NUMBER: 2
// NOTHING_ELSE: true
@@ -15,4 +15,4 @@ fun foo(p: Int = <caret>)
// EXIST: try
// EXIST: when
// EXIST: while
// NUMBER: 15
// NOTHING_ELSE: true
@@ -14,4 +14,4 @@ var a : Int = <caret>
// EXIST: try
// EXIST: when
// EXIST: while
// NUMBER: 14
// NOTHING_ELSE: true
@@ -7,4 +7,4 @@ fun test(<caret>) {
// EXIST: var
// EXIST: in
// EXIST: out
// NUMBER: 4
// NOTHING_ELSE: true
@@ -28,4 +28,6 @@ package Test
// EXIST: var
// EXIST: vararg
/*why?*/
// NUMBER: 23
// EXIST: companion
/*TODO*/
// NOTHING_ELSE: true
@@ -6,4 +6,4 @@ p<caret>
// EXIST: private
// EXIST: protected
// EXIST: public
// NUMBER: 4
// NOTHING_ELSE: true
@@ -33,4 +33,5 @@ class Some {
/*why?*/
// EXIST: constructor
// EXIST: init
// NUMBER: 27
// EXIST: companion
// NOTHING_ELSE: true
@@ -33,4 +33,5 @@ class Some {
/*why?*/
// EXIST: constructor
// EXIST: init
// NUMBER: 27
// EXIST: companion
// NOTHING_ELSE: true
@@ -35,4 +35,5 @@ class Some {
/*why?*/
// EXIST: constructor
// EXIST: init
// NUMBER: 27
// EXIST: companion
// NOTHING_ELSE: true
@@ -10,4 +10,4 @@ class Outer {
// EXIST: { lookupString: "this@foo", itemText: "this", tailText: "@foo", typeText: "String", attributes: "bold" }
// EXIST: { lookupString: "this@Inner", itemText: "this", tailText: "@Inner", typeText: "Outer.Inner", attributes: "bold" }
// EXIST: { lookupString: "this@Outer", itemText: "this", tailText: "@Outer", typeText: "Outer", attributes: "bold" }
// NUMBER: 3
// NOTHING_ELSE: true
@@ -2,4 +2,4 @@ val String.foo: Int
get() = this@<caret>.length()
// EXIST: "this@foo"
// NUMBER: 1
// NOTHING_ELSE: true
@@ -11,4 +11,4 @@ inline fun takeHandler2(handler: () -> Unit){}
// EXIST: { lookupString: "return", itemText: "return", tailText: null, attributes: "bold" }
// EXIST: { lookupString: "return@takeHandler1", itemText: "return", tailText: "@takeHandler1", attributes: "bold" }
// EXIST: { lookupString: "return@takeHandler2", itemText: "return", tailText: "@takeHandler2", attributes: "bold" }
// NUMBER: 3
// NOTHING_ELSE: true
@@ -10,4 +10,4 @@ inline fun takeHandler2(handler: () -> Unit){}
// INVOCATION_COUNT: 1
// EXIST: { lookupString: "return@takeHandler1", itemText: "return", tailText: "@takeHandler1", attributes: "bold" }
// EXIST: { lookupString: "return@takeHandler2", itemText: "return", tailText: "@takeHandler2", attributes: "bold" }
// NUMBER: 2
// NOTHING_ELSE: true
@@ -25,4 +25,4 @@ fun takeHandler3(handler: Char.() -> Unit){}
// EXIST: { lookupString: "this@Inner", itemText: "this", tailText: "@Inner", typeText: "Outer.Nested.Inner", attributes: "bold" }
// EXIST: { lookupString: "this@Nested", itemText: "this", tailText: "@Nested", typeText: "Outer.Nested", attributes: "bold" }
// ABSENT: "this@Outer"
// NUMBER: 6
// NOTHING_ELSE: true
@@ -27,4 +27,6 @@
// EXIST: var
// EXIST: vararg
/*why?*/
// NUMBER: 24
// EXIST: companion
/*TODO*/
// NOTHING_ELSE: true
@@ -7,4 +7,4 @@ fun bar(pInt: Int, pString: String) {
// EXIST: { lookupString: "param1", itemText: "param1 =" }
// EXIST: { lookupString: "param3", itemText: "param3 =" }
// ABSENT: param2
// NUMBER: 2
// NOTHING_ELSE: true
@@ -7,4 +7,4 @@ fun bar(pInt: Int, pString: String) {
// EXIST: { lookupString: "param1", itemText: "param1 =" }
// EXIST: { lookupString: "param3", itemText: "param3 =" }
// ABSENT: param2
// NUMBER: 2
// NOTHING_ELSE: true
@@ -9,4 +9,4 @@ fun f(){
// EXIST: { lookupString: "emptyList", typeText: "List<String>" }
// EXIST: { lookupString: "emptyList", typeText: "List<Int>" }
// NUMBER: 2
// NOTHING_ELSE: true
@@ -7,4 +7,4 @@ fun foo(): I = <caret>
// EXIST: { lookupString: "O", itemText: "O", tailText: " (<root>)" }
// EXIST: foo
// EXIST: object
// NUMBER: 3
// NOTHING_ELSE: true
@@ -14,4 +14,4 @@ fun foo(): T {
// EXIST: foo
// EXIST: object
// ABSENT: Other
// NUMBER: 3
// NOTHING_ELSE: true
@@ -6,6 +6,6 @@ fun bar(o: Any) {
foo(o as <caret>)
}
// NUMBER: 2
// EXIST: String
// EXIST: Int
// NOTHING_ELSE: true
@@ -6,6 +6,6 @@ fun bar(o: Any) {
foo(o as <caret>)
}
// NUMBER: 2
// EXIST: { lookupString:"List", itemText:"List<String>" }
// EXIST: { lookupString:"Map", itemText:"Map<String, Int>" }
// NOTHING_ELSE: true
@@ -7,6 +7,6 @@ fun bar(o: Any) {
foo(o as <caret>)
}
// NUMBER: 2
// EXIST: { lookupString:"List", itemText:"List<String>" }
// EXIST: { lookupString:"String", itemText:"String" }
// NOTHING_ELSE: true
@@ -15,4 +15,4 @@ fun foo(c: C): T {
// EXIST: { lookupString: "Inner2", itemText: "Inner2", tailText: "()", typeText: "C.Inner2" }
// ABSENT: Inner3
// ABSENT: Nested
// NUMBER: 2
// NOTHING_ELSE: true
@@ -8,4 +8,4 @@ fun foo() : C.Inner {
// ABSENT: Inner
// EXIST: foo
// NUMBER: 1
// NOTHING_ELSE: true
@@ -10,4 +10,4 @@ class Outer {
// EXIST: { lookupString: "this@foo", itemText: "this", tailText: "@foo", typeText: "String", attributes: "bold" }
// EXIST: { lookupString: "this@Inner", itemText: "this", tailText: "@Inner", typeText: "Outer.Inner", attributes: "bold" }
// EXIST: { lookupString: "this@Outer", itemText: "this", tailText: "@Outer", typeText: "Outer", attributes: "bold" }
// NUMBER: 3
// NOTHING_ELSE: true
@@ -9,4 +9,4 @@ fun bar() {
// EXIST: { lookupString: "C2", itemText: "C2<X>" }
// EXIST: { lookupString: "C2", itemText: "C2<Y>" }
// EXIST: { lookupString: "C3", itemText: "C3" }
// NUMBER: 7
// NOTHING_ELSE: true
@@ -3,4 +3,4 @@ fun foo(): T = <caret>
// EXIST: foo
// EXIST: { lookupString: "object", itemText: "object: T{...}" }
// EXIST: { lookupString: "OO", itemText: "OO", tailText: " (<root>)" }
// NUMBER: 3
// NOTHING_ELSE: true
@@ -26,9 +26,8 @@ public abstract class AbstractKeywordCompletionTest : JetFixtureCompletionBaseTe
override fun getPlatform() = TargetPlatform.JVM
override fun complete(invocationCount: Int): Array<LookupElement>? {
val items = myFixture.complete(CompletionType.BASIC)
if (items == null) return null
return items.filter { it.getObject() is KeywordLookupObject }.copyToArray()
val items = myFixture.complete(CompletionType.BASIC) ?: return null
return items.filter { it.getObject() is KeywordLookupObject }.toTypedArray()
}
override fun getProjectDescriptor() = JetLightProjectDescriptor.INSTANCE
@@ -28,21 +28,22 @@ val COMPLETION_TEST_DATA_BASE_PATH: String
fun testCompletion(fileText: String, platform: TargetPlatform?, complete: (Int) -> Array<LookupElement>?, defaultInvocationCount: Int = 0) {
testWithAutoCompleteSetting(fileText) {
val invocationCount = ExpectedCompletionUtils.getInvocationCount(fileText) ?: defaultInvocationCount
val items = complete(invocationCount) ?: array()
val items = complete(invocationCount) ?: emptyArray()
ExpectedCompletionUtils.assertDirectivesValid(fileText)
val expected = ExpectedCompletionUtils.itemsShouldExist(fileText, platform)
val unexpected = ExpectedCompletionUtils.itemsShouldAbsent(fileText, platform)
val itemsNumber = ExpectedCompletionUtils.getExpectedNumber(fileText, platform)
val nothingElse = ExpectedCompletionUtils.isNothingElseExpected(fileText)
Assert.assertTrue("Should be some assertions about completion", expected.size != 0 || unexpected.size != 0 || itemsNumber != null)
ExpectedCompletionUtils.assertContainsRenderedItems(expected, items, ExpectedCompletionUtils.isWithOrder(fileText))
Assert.assertTrue("Should be some assertions about completion", expected.size() != 0 || unexpected.size() != 0 || itemsNumber != null || nothingElse)
ExpectedCompletionUtils.assertContainsRenderedItems(expected, items, ExpectedCompletionUtils.isWithOrder(fileText), nothingElse)
ExpectedCompletionUtils.assertNotContainsRenderedItems(unexpected, items)
if (itemsNumber != null) {
val expectedItems = ExpectedCompletionUtils.listToString(ExpectedCompletionUtils.getItemsInformation(items))
Assert.assertEquals("Invalid number of completion items: ${expectedItems}", itemsNumber, items.size)
Assert.assertEquals("Invalid number of completion items: ${expectedItems}", itemsNumber, items.size())
}
}
}
@@ -123,6 +123,8 @@ public class ExpectedCompletionUtils {
private static final String NUMBER_JS_LINE_PREFIX = "NUMBER_JS:";
private static final String NUMBER_JAVA_LINE_PREFIX = "NUMBER_JAVA:";
private static final String NOTHING_ELSE_PREFIX = "NOTHING_ELSE:";
private static final String INVOCATION_COUNT_PREFIX = "INVOCATION_COUNT:";
private static final String WITH_ORDER_PREFIX = "WITH_ORDER:";
private static final String AUTOCOMPLETE_SETTING_PREFIX = "AUTOCOMPLETE_SETTING:";
@@ -142,6 +144,7 @@ public class ExpectedCompletionUtils {
INVOCATION_COUNT_PREFIX,
WITH_ORDER_PREFIX,
AUTOCOMPLETE_SETTING_PREFIX,
NOTHING_ELSE_PREFIX,
RUNTIME_TYPE,
AstAccessControl.INSTANCE$.getALLOW_AST_ACCESS_DIRECTIVE());
@@ -214,6 +217,10 @@ public class ExpectedCompletionUtils {
}
}
public static boolean isNothingElseExpected(String fileText) {
return Boolean.TRUE.equals(InTextDirectivesUtils.getPrefixedBoolean(fileText, NOTHING_ELSE_PREFIX));
}
@Nullable
public static Integer getInvocationCount(String fileText) {
return InTextDirectivesUtils.getPrefixedInt(fileText, INVOCATION_COUNT_PREFIX);
@@ -232,10 +239,12 @@ public class ExpectedCompletionUtils {
InTextDirectivesUtils.assertHasUnknownPrefixes(fileText, KNOWN_PREFIXES);
}
public static void assertContainsRenderedItems(CompletionProposal[] expected, LookupElement[] items, boolean checkOrder) {
public static void assertContainsRenderedItems(CompletionProposal[] expected, LookupElement[] items, boolean checkOrder, boolean nothingElse) {
List<CompletionProposal> itemsInformation = getItemsInformation(items);
String allItemsString = listToString(itemsInformation);
Set<CompletionProposal> leftItems = nothingElse ? new LinkedHashSet<CompletionProposal>(itemsInformation) : null;
int indexOfPrevious = Integer.MIN_VALUE;
for (CompletionProposal expectedProposal : expected) {
@@ -251,6 +260,10 @@ public class ExpectedCompletionUtils {
!checkOrder || index > indexOfPrevious);
indexOfPrevious = index;
if (leftItems != null) {
leftItems.remove(proposal);
}
break;
}
}
@@ -264,6 +277,10 @@ public class ExpectedCompletionUtils {
}
}
}
if (leftItems != null && !leftItems.isEmpty()) {
Assert.fail("No items not mentioned in EXIST directives expected but some found:\n" + listToString(leftItems));
}
}
private static Integer getPlatformExpectedNumber(String fileText, String platformNumberPrefix) {