Tests: Introduce LightClassComputationControl to track when stubs for light classes are built

Use it to track when light classes are built in KotlinSourceInJavaCompletionTest
This commit is contained in:
Pavel V. Talanov
2015-11-05 18:14:17 +03:00
parent ec48b54032
commit 085d95a5b8
23 changed files with 109 additions and 17 deletions
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.asJava
import com.google.common.collect.Lists
import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.progress.ProcessCanceledException
import com.intellij.openapi.project.Project
@@ -107,6 +108,8 @@ abstract class LightClassDataProvider<T : WithFileStubAndExtraDiagnostics>(
if (pop !== javaFileStub) {
LOG.error("Unbalanced stack operations: " + pop)
}
ServiceManager.getService(project, StubComputationTracker::class.java)?.onStubComputed(javaFileStub)
}
catch (e: ProcessCanceledException) {
throw e
@@ -354,3 +357,8 @@ class LightClassDataProviderForFileFacade(
return this.javaClass.name + " for $facadeFqName"
}
}
interface StubComputationTracker {
fun onStubComputed(javaFileStub: PsiJavaFileStub)
}
@@ -4,3 +4,4 @@ public class Testing {
// EXIST: c
// EXIST: d
// LIGHT_CLASS: mockLib.foo.Anno
@@ -5,3 +5,4 @@ public class Testing {
}
// EXIST: foo
// LIGHT_CLASS: mockLib.foo.LibClass
+2 -1
View File
@@ -4,4 +4,5 @@ public class Testing {
}
}
// EXIST: classObjectFun
// EXIST: classObjectFun
// LIGHT_CLASS: mockLib.foo.LibClass
@@ -5,3 +5,4 @@ public class Testing {
}
// EXIST: Companion
// LIGHT_CLASS: mockLib.foo.LibClass
@@ -5,3 +5,4 @@ public class Testing {
}
// EXIST: RED, GREEN, BLUE
// LIGHT_CLASS: mockLib.foo.LibEnum
@@ -5,3 +5,4 @@ public class Testing {
}
// EXIST: DefaultImpls
// LIGHT_CLASS: mockLib.foo.MyInterface
@@ -6,3 +6,4 @@ public class Testing {
}
// EXIST: foo
// LIGHT_CLASS: mockLib.foo.MyInterface
@@ -5,3 +5,4 @@ public class Testing {
}
// EXIST: foo
// LIGHT_CLASS: mockLib.foo.MyInterface
@@ -6,3 +6,4 @@ public class Testing {
}
// EXIST: foo
// LIGHT_CLASS: mockLib.foo.MyInterface
@@ -6,4 +6,4 @@ public class Testing {
// EXIST: funInFacade
// EXIST: funInFacade2
// LIGHT_CLASS: facades.MultiFileFacadeClass
+1
View File
@@ -7,3 +7,4 @@ public class Testing {
}
// EXIST: LibClass.Nested
// LIGHT_CLASS: mockLib.foo.LibClass
@@ -6,3 +6,4 @@ public class Testing {
// EXIST: getValInNested
// EXIST: funInNested
// LIGHT_CLASS: mockLib.foo.LibClass
@@ -6,3 +6,4 @@ public class Testing {
// EXIST: getValInNested
// EXIST: funInNested
// LIGHT_CLASS: mockLib.foo.LibClass
@@ -5,3 +5,4 @@ public class Testing {
}
// EXIST: INSTANCE
// LIGHT_CLASS: mockLib.foo.LibClass
@@ -4,3 +4,4 @@ public class Testing {
}
// EXIST: F
// LIGHT_CLASS: mockLib.foo.F
@@ -5,3 +5,4 @@ public class Testing {
}
// EXIST: INSTANCE
// LIGHT_CLASS: mockLib.foo.LibObject
@@ -8,4 +8,4 @@ public class Testing {
// EXIST: topLevelExtFunction
// EXIST: getTopLevelVar
// EXIST: setTopLevelVar
// LIGHT_CLASS: mockLib.foo.MainKt
@@ -7,3 +7,4 @@ public class Testing {
// EXIST: topLevelFunction
// EXIST: topLevelExtFunction
// EXIST: getTopLevelVar, setTopLevelVar
// LIGHT_CLASS: mockLib.foo.MainKt
+1 -1
View File
@@ -5,4 +5,4 @@ public class Testing {
}
// EXIST: foo
// LIGHT_CLASS: mockLib.foo.LibTrait
@@ -19,10 +19,6 @@ package org.jetbrains.kotlin.idea.completion.test
import com.intellij.codeInsight.completion.CompletionType
import com.intellij.openapi.util.io.FileUtil
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
import com.intellij.util.ArrayUtil
import com.intellij.util.Function
import com.intellij.util.containers.ContainerUtil
import junit.framework.TestCase
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
import java.io.File
@@ -31,17 +27,16 @@ public abstract class AbstractKotlinSourceInJavaCompletionTest : KotlinFixtureCo
override fun doTest(testPath: String) {
val mockLibDir = File(COMPLETION_TEST_DATA_BASE_PATH + "/injava/mockLib")
val listFiles = mockLibDir.listFiles()
TestCase.assertNotNull(listFiles)
val paths = ArrayUtil.toStringArray(ContainerUtil.map<File, String>(listFiles, object : Function<File, String> {
override fun `fun`(file: File): String {
return FileUtil.toSystemIndependentName(file.getAbsolutePath())
}
}))
val paths = mockLibDir.listFiles()!!.map {
FileUtil.toSystemIndependentName(it.absolutePath)
}.toTypedArray()
myFixture.configureByFiles(*paths)
super.doTest(testPath)
LightClassComputationControl.testWithControl(project, FileUtil.loadFile(File(testPath))) {
super.doTest(testPath)
}
}
override fun getProjectDescriptor() = LightCodeInsightFixtureTestCase.JAVA_LATEST
override fun defaultCompletionType() = CompletionType.BASIC
}
}
@@ -133,6 +133,7 @@ public object ExpectedCompletionUtils {
NOTHING_ELSE_PREFIX,
RUNTIME_TYPE,
COMPLETION_TYPE_PREFIX,
LightClassComputationControl.LIGHT_CLASS_DIRECTIVE,
AstAccessControl.ALLOW_AST_ACCESS_DIRECTIVE)
public fun itemsShouldExist(fileText: String, platform: TargetPlatform?): Array<CompletionProposal> {
@@ -0,0 +1,72 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* 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 org.jetbrains.kotlin.idea.completion.test
import com.intellij.openapi.components.ComponentManager
import com.intellij.openapi.project.Project
import com.intellij.psi.impl.java.stubs.PsiClassStub
import com.intellij.psi.impl.java.stubs.PsiJavaFileStub
import org.jetbrains.kotlin.asJava.StubComputationTracker
import org.jetbrains.kotlin.test.InTextDirectivesUtils
import org.junit.Assert
import org.picocontainer.MutablePicoContainer
import java.util.*
object LightClassComputationControl {
fun testWithControl(project: Project, testText: String, testBody: () -> Unit) {
val expectedLightClassFqNames = InTextDirectivesUtils.findLinesWithPrefixesRemoved(
testText, "// $LIGHT_CLASS_DIRECTIVE"
).map { it.trim() }
val actualFqNames = ArrayList<String>()
val stubComputationTracker = object : StubComputationTracker {
override fun onStubComputed(javaFileStub: PsiJavaFileStub) {
val qualifiedName = (javaFileStub.childrenStubs.single() as PsiClassStub<*>).qualifiedName!!
actualFqNames.add(qualifiedName)
}
}
project.withServiceRegistered<StubComputationTracker>(stubComputationTracker) {
testBody()
}
if (expectedLightClassFqNames.toSortedSet() != actualFqNames.toSortedSet()) {
Assert.fail(
"Expected to compute: ${expectedLightClassFqNames.prettyToString()}\n" +
"Actually computed: ${actualFqNames.prettyToString()}\n" +
"Use $LIGHT_CLASS_DIRECTIVE to specify expected light class computations"
)
}
}
val LIGHT_CLASS_DIRECTIVE = "LIGHT_CLASS:"
private fun List<String>.prettyToString() = if (isEmpty()) "<empty>" else joinToString()
}
private inline fun <reified T : Any> ComponentManager.withServiceRegistered(instance: T, body: () -> Unit) {
val picoContainer = picoContainer as MutablePicoContainer
val key = T::class.java.name
try {
picoContainer.unregisterComponent(key)
picoContainer.registerComponentInstance(key, instance)
body()
}
finally {
picoContainer.unregisterComponent(key)
}
}