From 44b736e8468dac6602b530ade2236a9751512213 Mon Sep 17 00:00:00 2001 From: "Vitaliy.Bibaev" Date: Thu, 7 Jun 2018 20:26:36 +0300 Subject: [PATCH] Generate tests be test data for sequence traces --- .../kotlin/generators/tests/GenerateTests.kt | 12 + .../exec/AbstractSequenceTraceTestCase.kt | 16 + .../sequence/exec/KotlinTraceTestCase.kt | 199 ++++++++++ .../exec/SequenceTraceTestCaseGenerated.java | 347 ++++++++++++++++++ .../sequence/exec/StreamTraceChecker.kt | 179 +++++++++ .../exec/sequence/AppendOperationsTest.kt | 13 - .../exec/sequence/DistinctOperationsTest.kt | 16 - .../exec/sequence/FilterOperationsTest.kt | 18 - .../exec/sequence/FlatMapOperationsTest.kt | 10 - .../exec/sequence/MappingOperationsTest.kt | 12 - .../exec/sequence/MiscOperationsTest.kt | 30 -- .../exec/sequence/OperationsTestCase.kt | 16 - .../exec/sequence/SortingOperationsTest.kt | 15 - .../exec/sequence/TerminalOperationsTest.kt | 83 ----- 14 files changed, 753 insertions(+), 213 deletions(-) create mode 100644 idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/AbstractSequenceTraceTestCase.kt create mode 100644 idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/KotlinTraceTestCase.kt create mode 100644 idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/SequenceTraceTestCaseGenerated.java create mode 100644 idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/StreamTraceChecker.kt delete mode 100644 idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/sequence/AppendOperationsTest.kt delete mode 100644 idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/sequence/DistinctOperationsTest.kt delete mode 100644 idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/sequence/FilterOperationsTest.kt delete mode 100644 idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/sequence/FlatMapOperationsTest.kt delete mode 100644 idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/sequence/MappingOperationsTest.kt delete mode 100644 idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/sequence/MiscOperationsTest.kt delete mode 100644 idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/sequence/OperationsTestCase.kt delete mode 100644 idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/sequence/SortingOperationsTest.kt delete mode 100644 idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/sequence/TerminalOperationsTest.kt diff --git a/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt b/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt index c5af4ded138..3884fa69107 100755 --- a/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt +++ b/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt @@ -78,6 +78,7 @@ import org.jetbrains.kotlin.idea.conversion.copy.AbstractTextJavaToKotlinCopyPas import org.jetbrains.kotlin.idea.coverage.AbstractKotlinCoverageOutputFilesTest import org.jetbrains.kotlin.idea.debugger.* import org.jetbrains.kotlin.idea.debugger.evaluate.* +import org.jetbrains.kotlin.idea.debugger.sequence.exec.AbstractSequenceTraceTestCase import org.jetbrains.kotlin.idea.decompiler.navigation.AbstractNavigateToDecompiledLibraryTest import org.jetbrains.kotlin.idea.decompiler.navigation.AbstractNavigateToLibrarySourceTest import org.jetbrains.kotlin.idea.decompiler.stubBuilder.AbstractClsStubBuilderTest @@ -645,6 +646,17 @@ fun main(args: Array) { model("debugger/fileRanking") } + testClass { + model("debugger/tinyApp/src/sequence/append", testMethod = "doTest") + model("debugger/tinyApp/src/sequence/distinct", testMethod = "doTest") + model("debugger/tinyApp/src/sequence/filter", testMethod = "doTest") + model("debugger/tinyApp/src/sequence/flatMap", testMethod = "doTest") + model("debugger/tinyApp/src/sequence/map", testMethod = "doTest") + model("debugger/tinyApp/src/sequence/misc", testMethod = "doTest") + model("debugger/tinyApp/src/sequence/sort", testMethod = "doTest") +// model("debugger/tinyApp/src/sequence/terminal", testMethod = "doTest") We need to implement mapping logic + } + testClass { model("stubs", extension = "kt") } diff --git a/idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/AbstractSequenceTraceTestCase.kt b/idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/AbstractSequenceTraceTestCase.kt new file mode 100644 index 00000000000..0d9f9f2e8ab --- /dev/null +++ b/idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/AbstractSequenceTraceTestCase.kt @@ -0,0 +1,16 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.debugger.sequence.exec + +import com.intellij.debugger.streams.lib.LibrarySupportProvider +import org.jetbrains.kotlin.idea.debugger.sequence.lib.sequence.KotlinSequenceSupportProvider + +/** + * @author Vitaliy.Bibaev + */ +abstract class AbstractSequenceTraceTestCase : KotlinTraceTestCase() { + override val librarySupportProvider: LibrarySupportProvider = KotlinSequenceSupportProvider() +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/KotlinTraceTestCase.kt b/idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/KotlinTraceTestCase.kt new file mode 100644 index 00000000000..b8bf9cc0345 --- /dev/null +++ b/idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/KotlinTraceTestCase.kt @@ -0,0 +1,199 @@ +/* + * Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.debugger.sequence.exec + +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl +import com.intellij.debugger.impl.OutputChecker +import com.intellij.debugger.streams.lib.LibrarySupportProvider +import com.intellij.debugger.streams.psi.DebuggerPositionResolver +import com.intellij.debugger.streams.psi.impl.DebuggerPositionResolverImpl +import com.intellij.debugger.streams.trace.* +import com.intellij.debugger.streams.trace.impl.TraceResultInterpreterImpl +import com.intellij.debugger.streams.wrapper.StreamChain +import com.intellij.debugger.streams.wrapper.StreamChainBuilder +import com.intellij.execution.ExecutionException +import com.intellij.execution.process.ProcessOutputTypes +import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.util.Computable +import com.intellij.openapi.vfs.VfsUtil +import com.intellij.util.indexing.FileBasedIndex +import com.intellij.xdebugger.XDebugSessionListener +import com.sun.jdi.Value +import junit.framework.TestCase +import org.jetbrains.kotlin.idea.debugger.KotlinDebuggerTestBase +import java.nio.file.Paths +import java.util.concurrent.atomic.AtomicBoolean + +/** + * @author Vitaliy.Bibaev + */ +abstract class KotlinTraceTestCase : KotlinDebuggerTestBase() { + private companion object { + val DEFAULT_CHAIN_SELECTOR = ChainSelector.byIndex(0) + } + + private lateinit var traceChecker: StreamTraceChecker + + override fun initOutputChecker(): OutputChecker { + traceChecker = StreamTraceChecker(this) + return super.initOutputChecker() + } + + abstract val librarySupportProvider: LibrarySupportProvider + + fun doTest(filePath: String) = doTestImpl(filePath) + + override fun createDebugProcess(path: String) { + val filePath = Paths.get(path); + FileBasedIndex.getInstance().requestReindex(VfsUtil.findFileByIoFile(filePath.toFile(), true)!!) + val fileName = filePath.getName(filePath.nameCount - 1).toString() + val packageName = filePath.getName(filePath.nameCount - 2).toString() + createLocalProcess("$packageName.${fileName.replace(".kt", "Kt")}") + } + + @Throws(ExecutionException::class) + private fun doTestImpl(path: String, chainSelector: ChainSelector = DEFAULT_CHAIN_SELECTOR) { + createDebugProcess(path) + val session = debuggerSession.xDebugSession ?: kotlin.test.fail("XDebugSession is null") + TestCase.assertNotNull(session) + + val completed = AtomicBoolean(false) + val positionResolver = getPositionResolver() + val chainBuilder = getChainBuilder() + val resultInterpreter = getResultInterpreter() + val expressionBuilder = getExpressionBuilder() + + session.addSessionListener(object : XDebugSessionListener { + override fun sessionPaused() { + if (completed.getAndSet(true)) { + resume() + return + } + try { + sessionPausedImpl() + } catch (t: Throwable) { + println("Exception caught: " + t + ", " + t.message, ProcessOutputTypes.SYSTEM) + t.printStackTrace() + + resume() + } + + } + + private fun sessionPausedImpl() { + printContext(debugProcess.debuggerContext) + val chain = ApplicationManager.getApplication().runReadAction( + Computable { + val elementAtBreakpoint = positionResolver.getNearestElementToBreakpoint(session) + val chains = if (elementAtBreakpoint == null) null else chainBuilder.build(elementAtBreakpoint) + if (chains == null || chains.isEmpty()) null else chainSelector.select(chains) + }) + + if (chain == null) { + complete(null, null, null, FailureReason.CHAIN_CONSTRUCTION) + return + } + + EvaluateExpressionTracer(session, expressionBuilder, resultInterpreter).trace(chain, object : TracingCallback { + override fun evaluated(result: TracingResult, context: EvaluationContextImpl) { + complete(chain, result, null, null) + } + + override fun evaluationFailed(traceExpression: String, message: String) { + complete(chain, null, message, FailureReason.EVALUATION) + } + + override fun compilationFailed(traceExpression: String, message: String) { + complete(chain, null, message, FailureReason.COMPILATION) + } + }) + } + + private fun complete( + chain: StreamChain?, + result: TracingResult?, + error: String?, + errorReason: FailureReason? + ) { + try { + if (error != null) { + TestCase.assertNotNull(errorReason) + TestCase.assertNotNull(chain) + handleError(chain!!, error, errorReason!!) + } else { + TestCase.assertNull(errorReason) + handleSuccess(chain, result) + } + } catch (t: Throwable) { + println("Exception caught: " + t + ", " + t.message, ProcessOutputTypes.SYSTEM) + } finally { + resume() + } + } + + private fun resume() { + ApplicationManager.getApplication().invokeLater { session.resume() } + } + }, testRootDisposable) + } + + protected fun getPositionResolver(): DebuggerPositionResolver { + return DebuggerPositionResolverImpl() + } + + protected fun handleError(chain: StreamChain, error: String, reason: FailureReason) { + TestCase.fail(error) + } + + protected fun handleSuccess(chain: StreamChain?, result: TracingResult?) { + TestCase.assertNotNull(chain) + TestCase.assertNotNull(result) + + println(chain!!.text, ProcessOutputTypes.SYSTEM) + + val resultValue = result!!.result + handleResultValue(resultValue.value) + + val trace = result.trace + traceChecker.checkChain(trace) + + val resolvedTrace = result.resolve(librarySupportProvider.librarySupport.resolverFactory) + traceChecker.checkResolvedChain(resolvedTrace) + } + + protected fun handleResultValue(result: Value?) { + } + + private fun getResultInterpreter(): TraceResultInterpreter { + return TraceResultInterpreterImpl(librarySupportProvider.librarySupport.interpreterFactory) + } + + private fun getChainBuilder(): StreamChainBuilder { + return librarySupportProvider.chainBuilder + } + + private fun getExpressionBuilder(): TraceExpressionBuilder { + return librarySupportProvider.getExpressionBuilder(project) + } + + protected enum class FailureReason { + COMPILATION, EVALUATION, CHAIN_CONSTRUCTION + } + + @FunctionalInterface + protected interface ChainSelector { + fun select(chains: List): StreamChain + + companion object { + + fun byIndex(index: Int): ChainSelector { + return object : ChainSelector { + override fun select(chains: List): StreamChain = chains.get(index) + } + } + } + } +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/SequenceTraceTestCaseGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/SequenceTraceTestCaseGenerated.java new file mode 100644 index 00000000000..798d6920839 --- /dev/null +++ b/idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/SequenceTraceTestCaseGenerated.java @@ -0,0 +1,347 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.debugger.sequence.exec; + +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 SequenceTraceTestCaseGenerated extends AbstractSequenceTraceTestCase { + @TestMetadata("idea/testData/debugger/tinyApp/src/sequence/append") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Append extends AbstractSequenceTraceTestCase { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath); + } + + public void testAllFilesPresentInAppend() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/debugger/tinyApp/src/sequence/append"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); + } + + @TestMetadata("PlusArray.kt") + public void testPlusArray() throws Exception { + runTest("idea/testData/debugger/tinyApp/src/sequence/append/PlusArray.kt"); + } + + @TestMetadata("PlusElement.kt") + public void testPlusElement() throws Exception { + runTest("idea/testData/debugger/tinyApp/src/sequence/append/PlusElement.kt"); + } + + @TestMetadata("PlusSequence.kt") + public void testPlusSequence() throws Exception { + runTest("idea/testData/debugger/tinyApp/src/sequence/append/PlusSequence.kt"); + } + + @TestMetadata("PlusSingle.kt") + public void testPlusSingle() throws Exception { + runTest("idea/testData/debugger/tinyApp/src/sequence/append/PlusSingle.kt"); + } + } + + @TestMetadata("idea/testData/debugger/tinyApp/src/sequence/distinct") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Distinct extends AbstractSequenceTraceTestCase { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath); + } + + public void testAllFilesPresentInDistinct() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/debugger/tinyApp/src/sequence/distinct"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); + } + + @TestMetadata("Distinct.kt") + public void testDistinct() throws Exception { + runTest("idea/testData/debugger/tinyApp/src/sequence/distinct/Distinct.kt"); + } + + @TestMetadata("DistinctBy.kt") + public void testDistinctBy() throws Exception { + runTest("idea/testData/debugger/tinyApp/src/sequence/distinct/DistinctBy.kt"); + } + + @TestMetadata("DistinctByBigPrimitives.kt") + public void testDistinctByBigPrimitives() throws Exception { + runTest("idea/testData/debugger/tinyApp/src/sequence/distinct/DistinctByBigPrimitives.kt"); + } + + @TestMetadata("DistinctByNullableElement.kt") + public void testDistinctByNullableElement() throws Exception { + runTest("idea/testData/debugger/tinyApp/src/sequence/distinct/DistinctByNullableElement.kt"); + } + + @TestMetadata("DistinctByNullableKey.kt") + public void testDistinctByNullableKey() throws Exception { + runTest("idea/testData/debugger/tinyApp/src/sequence/distinct/DistinctByNullableKey.kt"); + } + + @TestMetadata("DistinctByNullableKeyAndElement.kt") + public void testDistinctByNullableKeyAndElement() throws Exception { + runTest("idea/testData/debugger/tinyApp/src/sequence/distinct/DistinctByNullableKeyAndElement.kt"); + } + + @TestMetadata("DistinctObjects.kt") + public void testDistinctObjects() throws Exception { + runTest("idea/testData/debugger/tinyApp/src/sequence/distinct/DistinctObjects.kt"); + } + } + + @TestMetadata("idea/testData/debugger/tinyApp/src/sequence/filter") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Filter extends AbstractSequenceTraceTestCase { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath); + } + + public void testAllFilesPresentInFilter() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/debugger/tinyApp/src/sequence/filter"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); + } + + @TestMetadata("Drop.kt") + public void testDrop() throws Exception { + runTest("idea/testData/debugger/tinyApp/src/sequence/filter/Drop.kt"); + } + + @TestMetadata("DropWhile.kt") + public void testDropWhile() throws Exception { + runTest("idea/testData/debugger/tinyApp/src/sequence/filter/DropWhile.kt"); + } + + @TestMetadata("Filter.kt") + public void testFilter() throws Exception { + runTest("idea/testData/debugger/tinyApp/src/sequence/filter/Filter.kt"); + } + + @TestMetadata("FilterIndexed.kt") + public void testFilterIndexed() throws Exception { + runTest("idea/testData/debugger/tinyApp/src/sequence/filter/FilterIndexed.kt"); + } + + @TestMetadata("FilterIsInstance.kt") + public void testFilterIsInstance() throws Exception { + runTest("idea/testData/debugger/tinyApp/src/sequence/filter/FilterIsInstance.kt"); + } + + @TestMetadata("FilterNot.kt") + public void testFilterNot() throws Exception { + runTest("idea/testData/debugger/tinyApp/src/sequence/filter/FilterNot.kt"); + } + + @TestMetadata("Minus.kt") + public void testMinus() throws Exception { + runTest("idea/testData/debugger/tinyApp/src/sequence/filter/Minus.kt"); + } + + @TestMetadata("MinusElement.kt") + public void testMinusElement() throws Exception { + runTest("idea/testData/debugger/tinyApp/src/sequence/filter/MinusElement.kt"); + } + + @TestMetadata("Take.kt") + public void testTake() throws Exception { + runTest("idea/testData/debugger/tinyApp/src/sequence/filter/Take.kt"); + } + + @TestMetadata("TakeWhile.kt") + public void testTakeWhile() throws Exception { + runTest("idea/testData/debugger/tinyApp/src/sequence/filter/TakeWhile.kt"); + } + } + + @TestMetadata("idea/testData/debugger/tinyApp/src/sequence/flatMap") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class FlatMap extends AbstractSequenceTraceTestCase { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath); + } + + public void testAllFilesPresentInFlatMap() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/debugger/tinyApp/src/sequence/flatMap"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); + } + + @TestMetadata("FlatMap.kt") + public void testFlatMap() throws Exception { + runTest("idea/testData/debugger/tinyApp/src/sequence/flatMap/FlatMap.kt"); + } + + @TestMetadata("Flatten.kt") + public void testFlatten() throws Exception { + runTest("idea/testData/debugger/tinyApp/src/sequence/flatMap/Flatten.kt"); + } + } + + @TestMetadata("idea/testData/debugger/tinyApp/src/sequence/map") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Map extends AbstractSequenceTraceTestCase { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath); + } + + public void testAllFilesPresentInMap() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/debugger/tinyApp/src/sequence/map"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); + } + + @TestMetadata("Map.kt") + public void testMap() throws Exception { + runTest("idea/testData/debugger/tinyApp/src/sequence/map/Map.kt"); + } + + @TestMetadata("MapIndexed.kt") + public void testMapIndexed() throws Exception { + runTest("idea/testData/debugger/tinyApp/src/sequence/map/MapIndexed.kt"); + } + + @TestMetadata("MapNotNull.kt") + public void testMapNotNull() throws Exception { + runTest("idea/testData/debugger/tinyApp/src/sequence/map/MapNotNull.kt"); + } + + @TestMetadata("WithIndex.kt") + public void testWithIndex() throws Exception { + runTest("idea/testData/debugger/tinyApp/src/sequence/map/WithIndex.kt"); + } + } + + @TestMetadata("idea/testData/debugger/tinyApp/src/sequence/misc") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Misc extends AbstractSequenceTraceTestCase { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath); + } + + public void testAllFilesPresentInMisc() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/debugger/tinyApp/src/sequence/misc"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); + } + + @TestMetadata("AsSequence.kt") + public void testAsSequence() throws Exception { + runTest("idea/testData/debugger/tinyApp/src/sequence/misc/AsSequence.kt"); + } + + @TestMetadata("Chunked.kt") + public void testChunked() throws Exception { + runTest("idea/testData/debugger/tinyApp/src/sequence/misc/Chunked.kt"); + } + + @TestMetadata("ChunkedWithTransform.kt") + public void testChunkedWithTransform() throws Exception { + runTest("idea/testData/debugger/tinyApp/src/sequence/misc/ChunkedWithTransform.kt"); + } + + @TestMetadata("ConstrainOnce.kt") + public void testConstrainOnce() throws Exception { + runTest("idea/testData/debugger/tinyApp/src/sequence/misc/ConstrainOnce.kt"); + } + + @TestMetadata("OnEach.kt") + public void testOnEach() throws Exception { + runTest("idea/testData/debugger/tinyApp/src/sequence/misc/OnEach.kt"); + } + + @TestMetadata("RequireNoNulls.kt") + public void testRequireNoNulls() throws Exception { + runTest("idea/testData/debugger/tinyApp/src/sequence/misc/RequireNoNulls.kt"); + } + + @TestMetadata("Windowed.kt") + public void testWindowed() throws Exception { + runTest("idea/testData/debugger/tinyApp/src/sequence/misc/Windowed.kt"); + } + + @TestMetadata("WindowedWithBigStep.kt") + public void testWindowedWithBigStep() throws Exception { + runTest("idea/testData/debugger/tinyApp/src/sequence/misc/WindowedWithBigStep.kt"); + } + + @TestMetadata("WindowedWithPartial.kt") + public void testWindowedWithPartial() throws Exception { + runTest("idea/testData/debugger/tinyApp/src/sequence/misc/WindowedWithPartial.kt"); + } + + @TestMetadata("WindowedWithStep.kt") + public void testWindowedWithStep() throws Exception { + runTest("idea/testData/debugger/tinyApp/src/sequence/misc/WindowedWithStep.kt"); + } + + @TestMetadata("ZipWithGreater.kt") + public void testZipWithGreater() throws Exception { + runTest("idea/testData/debugger/tinyApp/src/sequence/misc/ZipWithGreater.kt"); + } + + @TestMetadata("ZipWithLesser.kt") + public void testZipWithLesser() throws Exception { + runTest("idea/testData/debugger/tinyApp/src/sequence/misc/ZipWithLesser.kt"); + } + + @TestMetadata("ZipWithNextMany.kt") + public void testZipWithNextMany() throws Exception { + runTest("idea/testData/debugger/tinyApp/src/sequence/misc/ZipWithNextMany.kt"); + } + + @TestMetadata("ZipWithNextSingle.kt") + public void testZipWithNextSingle() throws Exception { + runTest("idea/testData/debugger/tinyApp/src/sequence/misc/ZipWithNextSingle.kt"); + } + + @TestMetadata("ZipWithSame.kt") + public void testZipWithSame() throws Exception { + runTest("idea/testData/debugger/tinyApp/src/sequence/misc/ZipWithSame.kt"); + } + } + + @TestMetadata("idea/testData/debugger/tinyApp/src/sequence/sort") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Sort extends AbstractSequenceTraceTestCase { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath); + } + + public void testAllFilesPresentInSort() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/debugger/tinyApp/src/sequence/sort"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); + } + + @TestMetadata("Sorted.kt") + public void testSorted() throws Exception { + runTest("idea/testData/debugger/tinyApp/src/sequence/sort/Sorted.kt"); + } + + @TestMetadata("SortedBy.kt") + public void testSortedBy() throws Exception { + runTest("idea/testData/debugger/tinyApp/src/sequence/sort/SortedBy.kt"); + } + + @TestMetadata("SortedByDescending.kt") + public void testSortedByDescending() throws Exception { + runTest("idea/testData/debugger/tinyApp/src/sequence/sort/SortedByDescending.kt"); + } + + @TestMetadata("SortedDescending.kt") + public void testSortedDescending() throws Exception { + runTest("idea/testData/debugger/tinyApp/src/sequence/sort/SortedDescending.kt"); + } + + @TestMetadata("SortedWith.kt") + public void testSortedWith() throws Exception { + runTest("idea/testData/debugger/tinyApp/src/sequence/sort/SortedWith.kt"); + } + } +} diff --git a/idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/StreamTraceChecker.kt b/idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/StreamTraceChecker.kt new file mode 100644 index 00000000000..21646bab4b4 --- /dev/null +++ b/idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/StreamTraceChecker.kt @@ -0,0 +1,179 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.debugger.sequence.exec + +import com.intellij.debugger.streams.resolve.ResolvedStreamCall +import com.intellij.debugger.streams.resolve.ResolvedStreamChain +import com.intellij.debugger.streams.trace.* +import com.intellij.execution.ExecutionTestCase +import com.intellij.execution.process.ProcessOutputTypes +import com.intellij.testFramework.UsefulTestCase +import junit.framework.TestCase +import one.util.streamex.StreamEx +import java.util.* + +/** + * @author Vitaliy.Bibaev + */ +class StreamTraceChecker(private val testCase: ExecutionTestCase) { + fun checkChain(trace: List) { + for (info in trace) { + val name = info.call.name + println(name) + + print(" before: ") + val before = info.valuesOrderBefore + println(traceToString(before.values)) + + print(" after: ") + val after = info.valuesOrderAfter + println(traceToString(after.values)) + } + } + + fun checkResolvedChain(result: ResolvedTracingResult) { + val resolvedChain = result.resolvedChain + + checkChain(resolvedChain) + checkTracesIsCorrectInBothDirections(resolvedChain) + + val terminator = resolvedChain.terminator + resolvedChain.intermediateCalls.forEach { x -> printBeforeAndAfterValues(x.stateBefore, x.stateAfter) } + printBeforeAndAfterValues(terminator.stateBefore, terminator.stateAfter) + } + + private fun printBeforeAndAfterValues(before: NextAwareState?, after: PrevAwareState?) { + TestCase.assertFalse(before == null && after == null) + val call = before?.nextCall ?: after!!.prevCall + TestCase.assertNotNull(call) + println("mappings for " + call!!.name) + println(" direct:") + if (before != null) { + printMapping(before.trace, { before.getNextValues(it) }, Direction.FORWARD) + } else { + println(" no") + } + + println(" reverse:") + if (after != null) { + printMapping(after.trace, { after.getPrevValues(it) }, Direction.BACKWARD) + } else { + println(" not found") + } + } + + private fun printMapping( + values: List, + mapper: (TraceElement) -> List, + direction: Direction + ) { + if (values.isEmpty()) { + println(" empty") + } + for (element in values) { + val mappedValues = mapper(element) + val mapped = traceToString(mappedValues) + val line = if (Direction.FORWARD == direction) element.time.toString() + " -> " + mapped else mapped + " <- " + element.time + println(" $line") + } + } + + private enum class Direction { + FORWARD, BACKWARD + } + + private fun checkChain(chain: ResolvedStreamChain) { + val intermediates = chain.intermediateCalls + val terminator = chain.terminator + if (intermediates.isEmpty()) { + TestCase.assertFalse(terminator.stateBefore is PrevAwareState) + } + + checkIntermediates(chain.intermediateCalls) + + TestCase.assertEquals(terminator.call.name, terminator.stateBefore.nextCall.name) + val after = terminator.stateAfter + if (after != null) { + val terminatorCall = after.prevCall + TestCase.assertNotNull(terminatorCall) + TestCase.assertEquals(terminator.call.name, terminatorCall!!.name) + } + + if (!intermediates.isEmpty()) { + val lastIntermediate = intermediates[intermediates.size - 1] + val stateAfterIntermediates = lastIntermediate.stateAfter + UsefulTestCase.assertInstanceOf(stateAfterIntermediates, NextAwareState::class.java) + TestCase.assertEquals(terminator.call.name, (stateAfterIntermediates as NextAwareState).nextCall.name) + } + } + + private fun checkIntermediates(intermediates: List) { + for (i in 0 until intermediates.size - 1) { + val prev = intermediates[i] + val next = intermediates[i + 1] + TestCase.assertSame(prev.stateAfter, next.stateBefore) + val prevCall = prev.stateAfter.prevCall + TestCase.assertNotNull(prevCall) + TestCase.assertEquals(prev.call.name, prevCall!!.name) + TestCase.assertEquals(next.call.name, next.stateBefore.nextCall.name) + } + } + + private fun checkTracesIsCorrectInBothDirections(resolvedChain: ResolvedStreamChain) { + for (intermediate in resolvedChain.intermediateCalls) { + checkNeighborTraces(intermediate.stateBefore, intermediate.stateAfter) + } + + val terminator = resolvedChain.terminator + val after = terminator.stateAfter + if (after != null) { + checkNeighborTraces(terminator.stateBefore, after) + } + } + + private fun checkNeighborTraces(left: NextAwareState, right: PrevAwareState) { + val leftValues = HashSet(left.trace) + val rightValues = HashSet(right.trace) + + checkThatMappingsIsCorrect( + leftValues, + rightValues, + { left.getNextValues(it) }, + { right.getPrevValues(it) }) + checkThatMappingsIsCorrect( + rightValues, + leftValues, + { right.getPrevValues(it) }, + { left.getNextValues(it) }) + } + + private fun checkThatMappingsIsCorrect( + prev: Set, + next: Set, + toNext: (TraceElement) -> List, + toPrev: (TraceElement) -> List + ) { + for (leftElement in prev) { + val mapToRight = toNext.invoke(leftElement) + for (rightElement in mapToRight) { + TestCase.assertTrue(next.contains(rightElement)) + TestCase.assertTrue(toPrev.invoke(rightElement).contains(leftElement)) + } + } + } + + private fun traceToString(trace: Collection): String { + return replaceIfEmpty(StreamEx.of(trace).map({ it.time }).sorted().joining(",")) + } + + private fun replaceIfEmpty(str: String): String { + return if (str.isEmpty()) "nothing" else str + } + + private fun println(msg: String) = testCase.println(msg, ProcessOutputTypes.SYSTEM) + + private fun print(msg: String) = testCase.print(msg, ProcessOutputTypes.SYSTEM) +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/sequence/AppendOperationsTest.kt b/idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/sequence/AppendOperationsTest.kt deleted file mode 100644 index 8c38b0b1b80..00000000000 --- a/idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/sequence/AppendOperationsTest.kt +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -package org.jetbrains.kotlin.idea.debugger.sequence.exec.sequence - -/** - * @author Vitaliy.Bibaev - */ -class AppendOperationsTest : OperationsTestCase("append") { - fun testPlusSingle() = doTestWithResult() - fun testPlusArray() = doTestWithResult() - fun testPlusSequence() = doTestWithResult() - - fun testPlusElement() = doTestWithResult() -} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/sequence/DistinctOperationsTest.kt b/idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/sequence/DistinctOperationsTest.kt deleted file mode 100644 index 063af30b417..00000000000 --- a/idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/sequence/DistinctOperationsTest.kt +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -package org.jetbrains.kotlin.idea.debugger.sequence.exec.sequence - -/** - * @author Vitaliy.Bibaev - */ -class DistinctOperationsTest : OperationsTestCase("distinct") { - fun testDistinct() = doTestWithResult() - fun testDistinctObjects() = doTestWithResult() - - fun testDistinctBy() = doTestWithResult() - fun testDistinctByNullableElement() = doTestWithResult() - fun testDistinctByNullableKey() = doTestWithResult() - fun testDistinctByNullableKeyAndElement() = doTestWithResult() - fun testDistinctByBigPrimitives() = doTestWithResult() -} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/sequence/FilterOperationsTest.kt b/idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/sequence/FilterOperationsTest.kt deleted file mode 100644 index e66cf07aba8..00000000000 --- a/idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/sequence/FilterOperationsTest.kt +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -package org.jetbrains.kotlin.idea.debugger.sequence.exec.sequence - -class FilterOperationsTest : OperationsTestCase("filter") { - fun testFilter() = doTestWithResult() - fun testFilterNot() = doTestWithResult() - fun testFilterIndexed() = doTestWithResult() - fun testFilterIsInstance() = doTestWithoutResult() - - fun testDrop() = doTestWithResult() - fun testDropWhile() = doTestWithoutResult() - - fun testMinus() = doTestWithResult() - fun testMinusElement() = doTestWithResult() - - fun testTake() = doTestWithResult() - fun testTakeWhile() = doTestWithoutResult() -} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/sequence/FlatMapOperationsTest.kt b/idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/sequence/FlatMapOperationsTest.kt deleted file mode 100644 index 03bf17e7715..00000000000 --- a/idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/sequence/FlatMapOperationsTest.kt +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -package org.jetbrains.kotlin.idea.debugger.sequence.exec.sequence - -/** - * @author Vitaliy.Bibaev - */ -class FlatMapOperationsTest : OperationsTestCase("flatMap") { - fun testFlatMap() = doTestWithResult() - fun testFlatten() = doTestWithResult() -} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/sequence/MappingOperationsTest.kt b/idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/sequence/MappingOperationsTest.kt deleted file mode 100644 index e988c12ba22..00000000000 --- a/idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/sequence/MappingOperationsTest.kt +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -package org.jetbrains.kotlin.idea.debugger.sequence.exec.sequence - -/** - * @author Vitaliy.Bibaev - */ -class MappingOperationsTest : OperationsTestCase("map") { - fun testMap() = doTestWithResult() - fun testMapNotNull() = doTestWithResult() - fun testMapIndexed() = doTestWithResult() - fun testWithIndex() = doTestWithoutResult() -} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/sequence/MiscOperationsTest.kt b/idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/sequence/MiscOperationsTest.kt deleted file mode 100644 index 1d5f8663d61..00000000000 --- a/idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/sequence/MiscOperationsTest.kt +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -package org.jetbrains.kotlin.idea.debugger.sequence.exec.sequence - -/** - * @author Vitaliy.Bibaev - */ -class MiscOperationsTest : OperationsTestCase("misc") { - fun testConstrainOnce() = doTestWithResult() - - fun testRequireNoNulls() = doTestWithResult() - - fun testOnEach() = doTestWithResult() - - fun testZipWithSame() = doTestWithResult() - fun testZipWithGreater() = doTestWithResult() - fun testZipWithLesser() = doTestWithResult() - - fun testZipWithNextSingle() = doTestWithResult() - fun testZipWithNextMany() = doTestWithResult() - - fun testChunked() = doTestWithResult() - fun testChunkedWithTransform() = doTestWithResult() - - fun testWindowed() = doTestWithResult() - fun testWindowedWithPartial() = doTestWithResult() - fun testWindowedWithBigStep() = doTestWithResult() - fun testWindowedWithStep() = doTestWithResult() - - fun testAsSequence() = doTestWithResult() -} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/sequence/OperationsTestCase.kt b/idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/sequence/OperationsTestCase.kt deleted file mode 100644 index e359f3dd6f2..00000000000 --- a/idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/sequence/OperationsTestCase.kt +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -package org.jetbrains.kotlin.idea.debugger.sequence.exec.sequence - -import org.jetbrains.kotlin.idea.debugger.sequence.exec.KotlinTraceEvaluationTestCase -import org.jetbrains.kotlin.idea.debugger.sequence.lib.sequence.KotlinSequenceSupportProvider -import com.intellij.debugger.streams.lib.LibrarySupportProvider - -abstract class OperationsTestCase(private val packageName: String) : KotlinTraceEvaluationTestCase() { - override val appName: String = "sequence" - override val librarySupport: LibrarySupportProvider = KotlinSequenceSupportProvider() - - protected fun doTestWithResult() = doTest(false, fullyQualifiedClassName()) - protected fun doTestWithoutResult() = doTest(true, fullyQualifiedClassName()) - - private fun fullyQualifiedClassName() = "$packageName.${getTestName(false)}" -} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/sequence/SortingOperationsTest.kt b/idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/sequence/SortingOperationsTest.kt deleted file mode 100644 index c8c3099ac29..00000000000 --- a/idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/sequence/SortingOperationsTest.kt +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -package org.jetbrains.kotlin.idea.debugger.sequence.exec.sequence - -import org.jetbrains.kotlin.idea.debugger.sequence.exec.sequence.OperationsTestCase - -/** - * @author Vitaliy.Bibaev - */ -class SortingOperationsTest : OperationsTestCase("sort") { - fun testSorted() = doTestWithResult() - fun testSortedBy() = doTestWithResult() - fun testSortedDescending() = doTestWithResult() - fun testSortedByDescending() = doTestWithResult() - fun testSortedWith() = doTestWithResult() -} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/sequence/TerminalOperationsTest.kt b/idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/sequence/TerminalOperationsTest.kt deleted file mode 100644 index 0d61d169ccf..00000000000 --- a/idea/tests/org/jetbrains/kotlin/idea/debugger/sequence/exec/sequence/TerminalOperationsTest.kt +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -package org.jetbrains.kotlin.idea.debugger.sequence.exec.sequence - -import org.jetbrains.kotlin.idea.debugger.sequence.exec.sequence.OperationsTestCase - -/** - * @author Vitaliy.Bibaev - */ -class TerminalOperationsTest : OperationsTestCase("terminal") { - fun testAllTrue() = doTestWithResult() - fun testAllFalse() = doTestWithResult() - - fun testAnyTrue() = doTestWithResult() - fun testAnyFalse() = doTestWithResult() - - fun testAsIterable() = doTestWithResult() - - fun testAssociate() = doTestWithResult() - fun testAssociateBy() = doTestWithResult() - - fun testAverage() = doTestWithResult() - - fun testCount() = doTestWithResult() - - fun testElementAt() = doTestWithResult() - fun testElementAtOrElsePresent() = doTestWithResult() - fun testElementAtOrElseAbsent() = doTestWithResult() - fun testElementAtOrNull() = doTestWithResult() - - fun testFindPresent() = doTestWithResult() - fun testFindAbsent() = doTestWithResult() - - fun testFindLastPresent() = doTestWithResult() - fun testFindLastAbsent() = doTestWithResult() - - fun testFirst() = doTestWithResult() - - fun testFirstOrNullPresent() = doTestWithResult() - fun testFirstOrNullAbsent() = doTestWithResult() - - fun testGroupingBy() = doTestWithResult() - - fun testIndexOfPresent() = doTestWithResult() - fun testIndexOfAbsent() = doTestWithResult() - - fun testIndexOfFirstPresent() = doTestWithResult() - fun testIndexOfFirstAbsent() = doTestWithResult() - - fun testIndexOfLastPresent() = doTestWithResult() - fun testIndexOfLastAbsent() = doTestWithResult() - - fun testLast() = doTestWithResult() - fun testLastIndexOf() = doTestWithResult() - fun testLastOrNullPresent() = doTestWithResult() - fun testLastOrNullAbsent() = doTestWithResult() - - fun testMaxPresent() = doTestWithResult() - fun testMaxAbsent() = doTestWithResult() - fun testMaxBy() = doTestWithResult() - fun testMaxWith() = doTestWithResult() - - fun testMinPresent() = doTestWithResult() - fun testMinAbsent() = doTestWithResult() - fun testMinBy() = doTestWithResult() - fun testMinWith() = doTestWithResult() - - fun testNonePresent() = doTestWithResult() - fun testNoneAbsent() = doTestWithResult() - - fun testPartition() = doTestWithResult() - - fun testSingle() = doTestWithResult() - fun testSingleOrNullPresent() = doTestWithResult() - fun testSingleOrNullAbsent() = doTestWithResult() - - fun testToCollection() = doTestWithResult() - fun testToHashSet() = doTestWithResult() - fun testToMutableSet() = doTestWithResult() - fun testToList() = doTestWithResult() - fun testToMutableList() = doTestWithResult() - fun testToSet() = doTestWithResult() - fun testToSortedSet() = doTestWithResult() -} \ No newline at end of file