diff --git a/jps/jps-plugin/jps-tests/jps-tests.iml b/jps/jps-plugin/jps-tests/jps-tests.iml
index 3363179a26b..b4cb296a6a6 100644
--- a/jps/jps-plugin/jps-tests/jps-tests.iml
+++ b/jps/jps-plugin/jps-tests/jps-tests.iml
@@ -20,6 +20,9 @@
+
+
+
\ No newline at end of file
diff --git a/jps/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/incremental/AbstractJsProtoComparisonTest.kt b/jps/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/incremental/AbstractJsProtoComparisonTest.kt
new file mode 100644
index 00000000000..ec8f4f73c5f
--- /dev/null
+++ b/jps/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/incremental/AbstractJsProtoComparisonTest.kt
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2010-2017 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.jps.incremental
+
+import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments
+import org.jetbrains.kotlin.cli.common.arguments.K2JsArgumentConstants
+import org.jetbrains.kotlin.cli.js.K2JSCompiler
+import org.jetbrains.kotlin.config.Services
+import org.jetbrains.kotlin.incremental.ClassProtoData
+import org.jetbrains.kotlin.incremental.Difference
+import org.jetbrains.kotlin.incremental.difference as differenceImpl
+import org.jetbrains.kotlin.incremental.PackagePartProtoData
+import org.jetbrains.kotlin.incremental.ProtoData
+import org.jetbrains.kotlin.incremental.utils.TestMessageCollector
+import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumer
+import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumerImpl
+import org.jetbrains.kotlin.name.ClassId
+import org.jetbrains.kotlin.name.FqName
+import org.jetbrains.kotlin.name.Name
+import org.jetbrains.kotlin.serialization.ProtoBuf
+import org.jetbrains.kotlin.serialization.deserialization.NameResolverImpl
+import org.jetbrains.kotlin.serialization.js.JsProtoBuf
+import org.jetbrains.kotlin.serialization.js.JsSerializerProtocol
+import org.junit.Assert
+import java.io.File
+
+abstract class AbstractJsProtoComparisonTest : AbstractProtoComparisonTest() {
+ override fun expectedOutputFile(testDir: File): File =
+ File(testDir, "js.result.out")
+ .takeIf { it.exists() }
+ ?: super.expectedOutputFile(testDir)
+
+ override fun compileAndGetClasses(sourceDir: File, outputDir: File): Map {
+ val incrementalResults = IncrementalResultsConsumerImpl()
+ // todo: find out if it is safe to call directly
+ val services = Services.Builder().run {
+ register(IncrementalResultsConsumer::class.java, incrementalResults)
+ build()
+ }
+
+ val ktFiles = sourceDir.walkMatching { it.name.endsWith(".kt") }.map { it.canonicalPath }.toList()
+ val messageCollector = TestMessageCollector()
+ val args = K2JSCompilerArguments().apply {
+ outputFile = File(outputDir, "out.js").canonicalPath
+ metaInfo = true
+ main = K2JsArgumentConstants.NO_CALL
+ freeArgs.addAll(ktFiles)
+ }
+
+ K2JSCompiler().exec(messageCollector, services, args).let { exitCode ->
+ val expectedOutput = "OK"
+ val actualOutput = (listOf(exitCode.name) + messageCollector.errors).joinToString("\n")
+ Assert.assertEquals(expectedOutput, actualOutput)
+ }
+
+ val classes = hashMapOf()
+
+ for ((sourceFile, protoBytes, _) in incrementalResults.packageParts) {
+ val proto = ProtoBuf.PackageFragment.parseFrom(protoBytes, JsSerializerProtocol.extensionRegistry)
+ val nameResolver = NameResolverImpl(proto.strings, proto.qualifiedNames)
+
+ proto.class_List.forEach {
+ val classId = nameResolver.getClassId(it.fqName)
+ classes[classId] = ClassProtoData(it, nameResolver)
+ }
+
+ proto.`package`.apply {
+ val packageFqName = if (hasExtension(JsProtoBuf.packageFqName)) {
+ nameResolver.getPackageFqName(getExtension(JsProtoBuf.packageFqName))
+ }
+ else FqName.ROOT
+
+ val packagePartClassId = ClassId(packageFqName, Name.identifier(sourceFile.nameWithoutExtension.capitalize() + "Kt"))
+ classes[packagePartClassId] = PackagePartProtoData(this, nameResolver)
+ }
+ }
+
+ return classes
+ }
+
+ override fun difference(oldData: ProtoData, newData: ProtoData): Difference? =
+ differenceImpl(oldData, newData)
+}
diff --git a/jps/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/incremental/AbstractJvmProtoComparisonTest.kt b/jps/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/incremental/AbstractJvmProtoComparisonTest.kt
index 36ce3fc2eba..f14ea22eab1 100644
--- a/jps/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/incremental/AbstractJvmProtoComparisonTest.kt
+++ b/jps/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/incremental/AbstractJvmProtoComparisonTest.kt
@@ -20,7 +20,6 @@ import org.jetbrains.kotlin.incremental.Difference
import org.jetbrains.kotlin.incremental.LocalFileKotlinClass
import org.jetbrains.kotlin.incremental.difference
import org.jetbrains.kotlin.incremental.storage.ProtoMapValue
-import org.jetbrains.kotlin.incremental.testingUtils.copyTestSources
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
import org.jetbrains.kotlin.name.ClassId
@@ -40,7 +39,7 @@ abstract class AbstractJvmProtoComparisonTest : AbstractProtoComparisonTest : UsefulTestCase() {
+abstract class AbstractProtoComparisonTest : TestWithWorkingDir() {
protected abstract fun compileAndGetClasses(sourceDir: File, outputDir: File): Map
protected abstract fun difference(oldData: PROTO_DATA, newData: PROTO_DATA): Difference?
+ protected open fun expectedOutputFile(testDir: File): File =
+ File(testDir, "result.out")
+
fun doTest(testDataPath: String) {
val testDir = File(testDataPath)
- val workingDir = KotlinTestUtils.tmpDir("testDirectory")
val oldClassMap = classesForPrefixedSources(testDir, workingDir, "old")
val newClassMap = classesForPrefixedSources(testDir, workingDir, "new")
@@ -69,7 +72,7 @@ abstract class AbstractProtoComparisonTest : UsefulTestCase() {
p.println("CHANGES in $classId: ${changes.joinToString()}")
}
- KotlinTestUtils.assertEqualsToFile(File(testDataPath + File.separator + "result.out"), sb.toString())
+ KotlinTestUtils.assertEqualsToFile(expectedOutputFile(testDir), sb.toString())
}
private fun classesForPrefixedSources(testDir: File, workingDir: File, prefix: String): Map {
diff --git a/jps/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/incremental/JsProtoComparisonTestGenerated.java b/jps/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/incremental/JsProtoComparisonTestGenerated.java
new file mode 100644
index 00000000000..57af389c73c
--- /dev/null
+++ b/jps/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/incremental/JsProtoComparisonTestGenerated.java
@@ -0,0 +1,221 @@
+/*
+ * Copyright 2010-2017 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.jps.incremental;
+
+import com.intellij.testFramework.TestDataPath;
+import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
+import org.jetbrains.kotlin.test.KotlinTestUtils;
+import org.jetbrains.kotlin.test.TargetBackend;
+import org.jetbrains.kotlin.test.TestMetadata;
+import org.junit.runner.RunWith;
+
+import java.io.File;
+import java.util.regex.Pattern;
+
+/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
+@SuppressWarnings("all")
+@RunWith(JUnit3RunnerWithInners.class)
+public class JsProtoComparisonTestGenerated extends AbstractJsProtoComparisonTest {
+ @TestMetadata("jps-plugin/testData/comparison/classSignatureChange")
+ @TestDataPath("$PROJECT_ROOT")
+ @RunWith(JUnit3RunnerWithInners.class)
+ public static class ClassSignatureChange extends AbstractJsProtoComparisonTest {
+ public void testAllFilesPresentInClassSignatureChange() throws Exception {
+ KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/comparison/classSignatureChange"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
+ }
+
+ @TestMetadata("classAnnotationListChanged")
+ public void testClassAnnotationListChanged() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/comparison/classSignatureChange/classAnnotationListChanged/");
+ doTest(fileName);
+ }
+
+ @TestMetadata("classFlagsAndMembersChanged")
+ public void testClassFlagsAndMembersChanged() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/comparison/classSignatureChange/classFlagsAndMembersChanged/");
+ doTest(fileName);
+ }
+
+ @TestMetadata("classFlagsChanged")
+ public void testClassFlagsChanged() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/comparison/classSignatureChange/classFlagsChanged/");
+ doTest(fileName);
+ }
+
+ @TestMetadata("classTypeParameterListChanged")
+ public void testClassTypeParameterListChanged() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/comparison/classSignatureChange/classTypeParameterListChanged/");
+ doTest(fileName);
+ }
+
+ @TestMetadata("classWithSuperTypeListChanged")
+ public void testClassWithSuperTypeListChanged() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/comparison/classSignatureChange/classWithSuperTypeListChanged/");
+ doTest(fileName);
+ }
+ }
+
+ @TestMetadata("jps-plugin/testData/comparison/classPrivateOnlyChange")
+ @TestDataPath("$PROJECT_ROOT")
+ @RunWith(JUnit3RunnerWithInners.class)
+ public static class ClassPrivateOnlyChange extends AbstractJsProtoComparisonTest {
+ public void testAllFilesPresentInClassPrivateOnlyChange() throws Exception {
+ KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/comparison/classPrivateOnlyChange"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
+ }
+
+ @TestMetadata("classWithPrivateFunChanged")
+ public void testClassWithPrivateFunChanged() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/comparison/classPrivateOnlyChange/classWithPrivateFunChanged/");
+ doTest(fileName);
+ }
+
+ @TestMetadata("classWithPrivatePrimaryConstructorChanged")
+ public void testClassWithPrivatePrimaryConstructorChanged() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/comparison/classPrivateOnlyChange/classWithPrivatePrimaryConstructorChanged/");
+ doTest(fileName);
+ }
+
+ @TestMetadata("classWithPrivateSecondaryConstructorChanged")
+ public void testClassWithPrivateSecondaryConstructorChanged() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/comparison/classPrivateOnlyChange/classWithPrivateSecondaryConstructorChanged/");
+ doTest(fileName);
+ }
+
+ @TestMetadata("classWithPrivateValChanged")
+ public void testClassWithPrivateValChanged() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/comparison/classPrivateOnlyChange/classWithPrivateValChanged/");
+ doTest(fileName);
+ }
+
+ @TestMetadata("classWithPrivateVarChanged")
+ public void testClassWithPrivateVarChanged() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/comparison/classPrivateOnlyChange/classWithPrivateVarChanged/");
+ doTest(fileName);
+ }
+ }
+
+ @TestMetadata("jps-plugin/testData/comparison/classMembersOnlyChanged")
+ @TestDataPath("$PROJECT_ROOT")
+ @RunWith(JUnit3RunnerWithInners.class)
+ public static class ClassMembersOnlyChanged extends AbstractJsProtoComparisonTest {
+ public void testAllFilesPresentInClassMembersOnlyChanged() throws Exception {
+ KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/comparison/classMembersOnlyChanged"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
+ }
+
+ @TestMetadata("classWithCompanionObjectChanged")
+ public void testClassWithCompanionObjectChanged() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/comparison/classMembersOnlyChanged/classWithCompanionObjectChanged/");
+ doTest(fileName);
+ }
+
+ @TestMetadata("classWithConstructorChanged")
+ public void testClassWithConstructorChanged() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/comparison/classMembersOnlyChanged/classWithConstructorChanged/");
+ doTest(fileName);
+ }
+
+ @TestMetadata("classWithFunAndValChanged")
+ public void testClassWithFunAndValChanged() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/comparison/classMembersOnlyChanged/classWithFunAndValChanged/");
+ doTest(fileName);
+ }
+
+ @TestMetadata("classWithNestedClassesChanged")
+ public void testClassWithNestedClassesChanged() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/comparison/classMembersOnlyChanged/classWithNestedClassesChanged/");
+ doTest(fileName);
+ }
+
+ @TestMetadata("classWitnEnumChanged")
+ public void testClassWitnEnumChanged() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/comparison/classMembersOnlyChanged/classWitnEnumChanged/");
+ doTest(fileName);
+ }
+
+ @TestMetadata("defaultValues")
+ public void testDefaultValues() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/comparison/classMembersOnlyChanged/defaultValues/");
+ doTest(fileName);
+ }
+
+ @TestMetadata("membersFlagsChanged")
+ public void testMembersFlagsChanged() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/comparison/classMembersOnlyChanged/membersFlagsChanged/");
+ doTest(fileName);
+ }
+
+ @TestMetadata("sealedClassImplAdded")
+ public void testSealedClassImplAdded() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/comparison/classMembersOnlyChanged/sealedClassImplAdded/");
+ doTest(fileName);
+ }
+ }
+
+ @TestMetadata("jps-plugin/testData/comparison/packageMembers")
+ @TestDataPath("$PROJECT_ROOT")
+ @RunWith(JUnit3RunnerWithInners.class)
+ public static class PackageMembers extends AbstractJsProtoComparisonTest {
+ public void testAllFilesPresentInPackageMembers() throws Exception {
+ KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/comparison/packageMembers"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
+ }
+
+ @TestMetadata("defaultValues")
+ public void testDefaultValues() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/comparison/packageMembers/defaultValues/");
+ doTest(fileName);
+ }
+
+ @TestMetadata("membersFlagsChanged")
+ public void testMembersFlagsChanged() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/comparison/packageMembers/membersFlagsChanged/");
+ doTest(fileName);
+ }
+
+ @TestMetadata("packageFacadePrivateOnlyChanges")
+ public void testPackageFacadePrivateOnlyChanges() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/comparison/packageMembers/packageFacadePrivateOnlyChanges/");
+ doTest(fileName);
+ }
+
+ @TestMetadata("packageFacadePublicChanges")
+ public void testPackageFacadePublicChanges() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/comparison/packageMembers/packageFacadePublicChanges/");
+ doTest(fileName);
+ }
+ }
+
+ @TestMetadata("jps-plugin/testData/comparison/unchanged")
+ @TestDataPath("$PROJECT_ROOT")
+ @RunWith(JUnit3RunnerWithInners.class)
+ public static class Unchanged extends AbstractJsProtoComparisonTest {
+ public void testAllFilesPresentInUnchanged() throws Exception {
+ KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/comparison/unchanged"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
+ }
+
+ @TestMetadata("unchangedClass")
+ public void testUnchangedClass() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/comparison/unchanged/unchangedClass/");
+ doTest(fileName);
+ }
+
+ @TestMetadata("unchangedPackageFacade")
+ public void testUnchangedPackageFacade() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/comparison/unchanged/unchangedPackageFacade/");
+ doTest(fileName);
+ }
+ }
+}
diff --git a/jps/jps-plugin/testData/comparison/classMembersOnlyChanged/classWitnEnumChanged/js.result.out b/jps/jps-plugin/testData/comparison/classMembersOnlyChanged/classWitnEnumChanged/js.result.out
new file mode 100644
index 00000000000..add71453244
--- /dev/null
+++ b/jps/jps-plugin/testData/comparison/classMembersOnlyChanged/classWitnEnumChanged/js.result.out
@@ -0,0 +1,4 @@
+REMOVED test/EnumClassWithChanges.CONST_2
+ADDED test/EnumClassWithChanges.CONST_3
+ADDED test/EnumClassWithChanges.CONST_4
+CHANGES in test/EnumClassWithChanges: CLASS_SIGNATURE