Refactor scratch tests: add ability to set scratch options in test file

This commit is contained in:
Natalia Selezneva
2019-05-29 15:56:18 +03:00
parent b59bd9d6a6
commit a6221cf594
55 changed files with 218 additions and 83 deletions
+3
View File
@@ -0,0 +1,3 @@
// REPL_MODE: ~REPL_MODE~
// INTERACTIVE_MODE: ~INTERACTIVE_MODE~
1
+2
View File
@@ -1,3 +1,5 @@
// REPL_MODE: false
for (i in 0..5) { // OUTPUT: 0; 1; 2; 3; 4; 5 for (i in 0..5) { // OUTPUT: 0; 1; 2; 3; 4; 5
println(i) println(i)
} }
+2
View File
@@ -1,3 +1,5 @@
// REPL_MODE: ~REPL_MODE~
for (i in 0..5) { for (i in 0..5) {
println(i) println(i)
} }
+2
View File
@@ -1,3 +1,5 @@
// REPL_MODE: true
for (i in 0..5) { // OUTPUT: 0; 1; 2; 3; 4; 5 for (i in 0..5) { // OUTPUT: 0; 1; 2; 3; 4; 5
println(i) println(i)
} }
+2
View File
@@ -1,3 +1,5 @@
// REPL_MODE: false
class GClass<T> { // RESULT: class GClass<T> class GClass<T> { // RESULT: class GClass<T>
fun foo(t: T): T { fun foo(t: T): T {
return t return t
+2
View File
@@ -1,3 +1,5 @@
// REPL_MODE: ~REPL_MODE~
class GClass<T> { class GClass<T> {
fun foo(t: T): T { fun foo(t: T): T {
return t return t
+2
View File
@@ -1,3 +1,5 @@
// REPL_MODE: true
class GClass<T> { class GClass<T> {
fun foo(t: T): T { fun foo(t: T): T {
return t return t
+2
View File
@@ -1,3 +1,5 @@
// REPL_MODE: false
class MyClass { // RESULT: class MyClass class MyClass { // RESULT: class MyClass
fun foo() = 1 fun foo() = 1
} }
+2
View File
@@ -1,3 +1,5 @@
// REPL_MODE: ~REPL_MODE~
class MyClass { class MyClass {
fun foo() = 1 fun foo() = 1
} }
+2
View File
@@ -1,3 +1,5 @@
// REPL_MODE: true
class MyClass { class MyClass {
fun foo() = 1 fun foo() = 1
} }
@@ -1,2 +1,4 @@
// REPL_MODE: false
val a: Int? = 1 // RESULT: val a: Int? val a: Int? = 1 // RESULT: val a: Int?
kotlin.test.assertNotNull(1) // RESULT: 1 kotlin.test.assertNotNull(1) // RESULT: 1
+2
View File
@@ -1,2 +1,4 @@
// REPL_MODE: ~REPL_MODE~
val a: Int? = 1 val a: Int? = 1
kotlin.test.assertNotNull(1) kotlin.test.assertNotNull(1)
@@ -1,2 +1,4 @@
// REPL_MODE: true
val a: Int? = 1 val a: Int? = 1
kotlin.test.assertNotNull(1) // RESULT: res1: kotlin.Int = 1 kotlin.test.assertNotNull(1) // RESULT: res1: kotlin.Int = 1
@@ -1,3 +1,5 @@
// REPL_MODE: false
import inlineFun.* import inlineFun.*
foo { 1 + 3 } // RESULT: 4 foo { 1 + 3 } // RESULT: 4
@@ -1,3 +1,5 @@
// REPL_MODE: ~REPL_MODE~
import inlineFun.* import inlineFun.*
foo { 1 + 3 } foo { 1 + 3 }
@@ -1,3 +1,5 @@
// REPL_MODE: true
import inlineFun.* import inlineFun.*
foo { 1 + 3 } // RESULT: res1: kotlin.Int = 4 foo { 1 + 3 } // RESULT: res1: kotlin.Int = 4
@@ -1,3 +1,5 @@
// REPL_MODE: false
import myTest.MyJavaClass import myTest.MyJavaClass
MyJavaClass().test() // RESULT: 1 MyJavaClass().test() // RESULT: 1
+2
View File
@@ -1,3 +1,5 @@
// REPL_MODE: ~REPL_MODE~
import myTest.MyJavaClass import myTest.MyJavaClass
MyJavaClass().test() MyJavaClass().test()
@@ -1,3 +1,5 @@
// REPL_MODE: true
import myTest.MyJavaClass import myTest.MyJavaClass
MyJavaClass().test() // RESULT: res1: kotlin.Int = 1 MyJavaClass().test() // RESULT: res1: kotlin.Int = 1
+2
View File
@@ -1,2 +1,4 @@
// REPL_MODE: false
val a = 1 // RESULT: val a: Int val a = 1 // RESULT: val a: Int
a // RESULT: 1 a // RESULT: 1
+2
View File
@@ -1,2 +1,4 @@
// REPL_MODE: ~REPL_MODE~
val a = 1 val a = 1
a a
+2
View File
@@ -1,2 +1,4 @@
// REPL_MODE: true
val a = 1 val a = 1
a // RESULT: res1: kotlin.Int = 1 a // RESULT: res1: kotlin.Int = 1
+2
View File
@@ -1,3 +1,5 @@
// REPL_MODE: false
fun foo(): Int { // RESULT: fun foo(): Int fun foo(): Int { // RESULT: fun foo(): Int
return 1 return 1
} }
+2
View File
@@ -1,3 +1,5 @@
// REPL_MODE: ~REPL_MODE~
fun foo(): Int { fun foo(): Int {
return 1 return 1
} }
+2
View File
@@ -1,3 +1,5 @@
// REPL_MODE: true
fun foo(): Int { fun foo(): Int {
return 1 return 1
} }
+3 -2
View File
@@ -1,3 +1,4 @@
arrayListOf(1, 2).size // RESULT: 2 // REPL_MODE: false
// NO_MODULE
//NO_MODULE arrayListOf(1, 2).size // RESULT: 2
+3 -2
View File
@@ -1,3 +1,4 @@
arrayListOf(1, 2).size // REPL_MODE: ~REPL_MODE~
// NO_MODULE
//NO_MODULE arrayListOf(1, 2).size
+3 -2
View File
@@ -1,3 +1,4 @@
arrayListOf(1, 2).size // RESULT: res0: kotlin.Int = 2 // REPL_MODE: true
// NO_MODULE
//NO_MODULE arrayListOf(1, 2).size // RESULT: res0: kotlin.Int = 2
+2
View File
@@ -1,3 +1,5 @@
// REPL_MODE: false
val a = 1 // RESULT: val a: Int val a = 1 // RESULT: val a: Int
a // RESULT: 1 a // RESULT: 1
a // RESULT: 1 a // RESULT: 1
+2
View File
@@ -1,3 +1,5 @@
// REPL_MODE: ~REPL_MODE~
val a = 1 val a = 1
a a
a a
+2
View File
@@ -1,3 +1,5 @@
// REPL_MODE: true
val a = 1 val a = 1
a // RESULT: res1: kotlin.Int = 1 a // RESULT: res1: kotlin.Int = 1
a // RESULT: res2: kotlin.Int = 1 a // RESULT: res2: kotlin.Int = 1
+2
View File
@@ -1,3 +1,5 @@
// REPL_MODE: false
arrayListOf(1, 5, 7).map { it * 2 } // RESULT: 2 arrayListOf(1, 5, 7).map { it * 2 } // RESULT: 2
.filter { it < 10 } .filter { it < 10 }
.find { it == 2 } .find { it == 2 }
+2
View File
@@ -1,3 +1,5 @@
// REPL_MODE: ~REPL_MODE~
arrayListOf(1, 5, 7).map { it * 2 } arrayListOf(1, 5, 7).map { it * 2 }
.filter { it < 10 } .filter { it < 10 }
.find { it == 2 } .find { it == 2 }
+2
View File
@@ -1,3 +1,5 @@
// REPL_MODE: true
arrayListOf(1, 5, 7).map { it * 2 } // RESULT: res0: kotlin.Int? = 2 arrayListOf(1, 5, 7).map { it * 2 } // RESULT: res0: kotlin.Int? = 2
.filter { it < 10 } .filter { it < 10 }
.find { it == 2 } .find { it == 2 }
+3 -1
View File
@@ -1,2 +1,4 @@
// REPL_MODE: false
foo() // ERROR: Unresolved reference: foo foo() // ERROR: Unresolved reference: foo
/** unresolved.kts:1 Unresolved reference: foo */ /** unresolved.kts:3 Unresolved reference: foo */
+2
View File
@@ -1 +1,3 @@
// REPL_MODE: ~REPL_MODE~
foo() foo()
+3 -1
View File
@@ -1,4 +1,6 @@
// REPL_MODE: true
foo() // ERROR: error: unresolved reference: foo... foo() // ERROR: error: unresolved reference: foo...
/** unresolved.kts:1 error: unresolved reference: foo /** unresolved.kts:3 error: unresolved reference: foo
foo() foo()
^ */ ^ */
+5 -3
View File
@@ -1,3 +1,5 @@
// REPL_MODE: false
foo.forEach { // ERROR: Unresolved reference: foo; Cannot choose among the following candidates without completing ty... foo.forEach { // ERROR: Unresolved reference: foo; Cannot choose among the following candidates without completing ty...
1 + 1 1 + 1
} }
@@ -5,8 +7,8 @@ foo.forEach { // ERROR: Unresolved reference: foo; Cannot choose among
fun goo(a: String) { // ERROR: Unresolved reference: goo fun goo(a: String) { // ERROR: Unresolved reference: goo
super.goo(a) super.goo(a)
} }
/** unresolvedMultiline.kts:1 Unresolved reference: foo */ /** unresolvedMultiline.kts:3 Unresolved reference: foo */
/** unresolvedMultiline.kts:1 Cannot choose among the following candidates without completing type inference: /** unresolvedMultiline.kts:3 Cannot choose among the following candidates without completing type inference:
@HidesMembers public inline fun <T> Iterable<???>.forEach(action: (???) -> Unit): Unit defined in kotlin.collections @HidesMembers public inline fun <T> Iterable<???>.forEach(action: (???) -> Unit): Unit defined in kotlin.collections
@HidesMembers public inline fun <K, V> Map<out ???, ???>.forEach(action: (Map.Entry<???, ???>) -> Unit): Unit defined in kotlin.collections */ @HidesMembers public inline fun <K, V> Map<out ???, ???>.forEach(action: (Map.Entry<???, ???>) -> Unit): Unit defined in kotlin.collections */
/** unresolvedMultiline.kts:5 Unresolved reference: goo */ /** unresolvedMultiline.kts:7 Unresolved reference: goo */
+2
View File
@@ -1,3 +1,5 @@
// REPL_MODE: ~REPL_MODE~
foo.forEach { foo.forEach {
1 + 1 1 + 1
} }
+4 -2
View File
@@ -1,3 +1,5 @@
// REPL_MODE: true
foo.forEach { // ERROR: error: unresolved reference: foo... foo.forEach { // ERROR: error: unresolved reference: foo...
1 + 1 1 + 1
} }
@@ -5,7 +7,7 @@ foo.forEach { // ERROR: error: unresolved reference: foo...
fun goo(a: String) { // ERROR: error: unresolved reference: goo... fun goo(a: String) { // ERROR: error: unresolved reference: goo...
super.goo(a) super.goo(a)
} }
/** unresolvedMultiline.kts:1 error: unresolved reference: foo /** unresolvedMultiline.kts:3 error: unresolved reference: foo
foo.forEach { foo.forEach {
^ ^
error: cannot choose among the following candidates without completing type inference: error: cannot choose among the following candidates without completing type inference:
@@ -13,6 +15,6 @@ error: cannot choose among the following candidates without completing type infe
@HidesMembers public inline fun <K, V> Map<out ???, ???>.forEach(action: (Map.Entry<???, ???>) -> Unit): Unit defined in kotlin.collections @HidesMembers public inline fun <K, V> Map<out ???, ???>.forEach(action: (Map.Entry<???, ???>) -> Unit): Unit defined in kotlin.collections
foo.forEach { foo.forEach {
^ */ ^ */
/** unresolvedMultiline.kts:5 error: unresolved reference: goo /** unresolvedMultiline.kts:7 error: unresolved reference: goo
super.goo(a) super.goo(a)
^ */ ^ */
+2
View File
@@ -1 +1,3 @@
// REPL_MODE: false
println("hello") // OUTPUT: hello println("hello") // OUTPUT: hello
+2
View File
@@ -1 +1,3 @@
// REPL_MODE: ~REPL_MODE~
println("hello") println("hello")
+2
View File
@@ -1 +1,3 @@
// REPL_MODE: true
println("hello") // OUTPUT: hello println("hello") // OUTPUT: hello
+2
View File
@@ -1,3 +1,5 @@
// REPL_MODE: false
var a = 1 // RESULT: var a: Int var a = 1 // RESULT: var a: Int
a++ // RESULT: 1 a++ // RESULT: 1
a // RESULT: 2 a // RESULT: 2
+2
View File
@@ -1,3 +1,5 @@
// REPL_MODE: ~REPL_MODE~
var a = 1 var a = 1
a++ a++
a a
+2
View File
@@ -1,3 +1,5 @@
// REPL_MODE: true
var a = 1 var a = 1
a++ // RESULT: res1: kotlin.Int = 1 a++ // RESULT: res1: kotlin.Int = 1
a // RESULT: res2: kotlin.Int = 2 a // RESULT: res2: kotlin.Int = 2
+9 -7
View File
@@ -1,12 +1,14 @@
// REPL_MODE: false
val a = "a".repeat(100) // RESULT: val a: String val a = "a".repeat(100) // RESULT: val a: String
a // RESULT: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa... a // RESULT: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...
val b = "0123456789\n".repeat(10) // RESULT: val b: String val b = "0123456789\n".repeat(10) // RESULT: val b: String
b // RESULT: 0123456789; 0123456789; 0123456789; 0123456789; 012345678... b // RESULT: 0123456789; 0123456789; 0123456789; 0123456789; 012345678...
println("0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789") // OUTPUT: 01... println("0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789") // OUTPUT: 01...
/** veryLongOutput.kts:2 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa */ /** veryLongOutput.kts:4 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa */
/** veryLongOutput.kts:4 0123456789 */ /** veryLongOutput.kts:6 0123456789 */
/** veryLongOutput.kts:4 0123456789 */ /** veryLongOutput.kts:6 0123456789 */
/** veryLongOutput.kts:4 0123456789 */ /** veryLongOutput.kts:6 0123456789 */
/** veryLongOutput.kts:4 0123456789 */ /** veryLongOutput.kts:6 0123456789 */
/** veryLongOutput.kts:4 0123456789 */ /** veryLongOutput.kts:6 0123456789 */
/** veryLongOutput.kts:5 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 */ /** veryLongOutput.kts:7 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 */
+2
View File
@@ -1,3 +1,5 @@
// REPL_MODE: ~REPL_MODE~
val a = "a".repeat(100) val a = "a".repeat(100)
a a
val b = "0123456789\n".repeat(10) val b = "0123456789\n".repeat(10)
+5 -3
View File
@@ -1,10 +1,12 @@
// REPL_MODE: true
val a = "a".repeat(100) val a = "a".repeat(100)
a // RESULT: res1: kotlin.String = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa... a // RESULT: res1: kotlin.String = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...
val b = "0123456789\n".repeat(10) val b = "0123456789\n".repeat(10)
b // RESULT: res3: kotlin.String = 0123456789... b // RESULT: res3: kotlin.String = 0123456789...
println("0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789") // OUTPUT: 01... println("0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789") // OUTPUT: 01...
/** veryLongOutput.kts:2 res1: kotlin.String = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa */ /** veryLongOutput.kts:4 res1: kotlin.String = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa */
/** veryLongOutput.kts:4 res3: kotlin.String = 0123456789 /** veryLongOutput.kts:6 res3: kotlin.String = 0123456789
0123456789 0123456789
0123456789 0123456789
0123456789 0123456789
@@ -14,4 +16,4 @@ println("01234567890123456789012345678901234567890123456789012345678901234567890
0123456789 0123456789
0123456789 0123456789
0123456789 */ 0123456789 */
/** veryLongOutput.kts:5 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 */ /** veryLongOutput.kts:7 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 */
+2
View File
@@ -1,3 +1,5 @@
// REPL_MODE: false
val a = 1 // RESULT: val a: Int val a = 1 // RESULT: val a: Int
when(a) { // OUTPUT: 1 when(a) { // OUTPUT: 1
1 -> println("1") 1 -> println("1")
+2
View File
@@ -1,3 +1,5 @@
// REPL_MODE: ~REPL_MODE~
val a = 1 val a = 1
when(a) { when(a) {
1 -> println("1") 1 -> println("1")
+2
View File
@@ -1,3 +1,5 @@
// REPL_MODE: true
val a = 1 val a = 1
when(a) { // OUTPUT: 1 when(a) { // OUTPUT: 1
1 -> println("1") 1 -> println("1")
@@ -15,8 +15,6 @@ import com.intellij.openapi.roots.ModuleRootModificationUtil
import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.VirtualFile
import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess
import com.intellij.psi.PsiDocumentManager
import com.intellij.psi.PsiManager
import com.intellij.testFramework.FileEditorManagerTestCase import com.intellij.testFramework.FileEditorManagerTestCase
import com.intellij.testFramework.MapDataContext import com.intellij.testFramework.MapDataContext
import com.intellij.testFramework.PsiTestUtil import com.intellij.testFramework.PsiTestUtil
@@ -26,9 +24,11 @@ import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime
import org.jetbrains.kotlin.idea.KotlinLanguage import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.idea.core.script.ScriptDependenciesManager import org.jetbrains.kotlin.idea.core.script.ScriptDependenciesManager
import org.jetbrains.kotlin.idea.highlighter.KotlinHighlightingUtil import org.jetbrains.kotlin.idea.highlighter.KotlinHighlightingUtil
import org.jetbrains.kotlin.idea.scratch.actions.ClearScratchAction
import org.jetbrains.kotlin.idea.scratch.actions.RunScratchAction import org.jetbrains.kotlin.idea.scratch.actions.RunScratchAction
import org.jetbrains.kotlin.idea.scratch.actions.ScratchCompilationSupport import org.jetbrains.kotlin.idea.scratch.actions.ScratchCompilationSupport
import org.jetbrains.kotlin.idea.scratch.output.InlayScratchFileRenderer import org.jetbrains.kotlin.idea.scratch.output.InlayScratchFileRenderer
import org.jetbrains.kotlin.idea.scratch.ui.ScratchTopPanel
import org.jetbrains.kotlin.idea.test.KotlinLightProjectDescriptor import org.jetbrains.kotlin.idea.test.KotlinLightProjectDescriptor
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase import org.jetbrains.kotlin.idea.test.PluginTestCaseBase
@@ -78,6 +78,9 @@ abstract class AbstractScratchRunActionTest : FileEditorManagerTestCase() {
val mainFileName = "$dirName/${getTestName(true)}.kts" val mainFileName = "$dirName/${getTestName(true)}.kts"
doCompilingTest(mainFileName) doCompilingTest(mainFileName)
launchAction(ClearScratchAction())
doReplTest(mainFileName) doReplTest(mainFileName)
ModuleRootModificationUtil.updateModel(module) { model -> ModuleRootModificationUtil.updateModel(module) { model ->
@@ -87,44 +90,16 @@ abstract class AbstractScratchRunActionTest : FileEditorManagerTestCase() {
fun doTest(fileName: String, isRepl: Boolean) { fun doTest(fileName: String, isRepl: Boolean) {
val sourceFile = File(testDataPath, fileName) val sourceFile = File(testDataPath, fileName)
val fileText = sourceFile.readText() val fileText = sourceFile.readText().inlinePropertiesValues(isRepl)
val scratchFile = createScratchFile(sourceFile.name, fileText) configureScratchByText(sourceFile.name, fileText)
ScriptDependenciesManager.updateScriptDependenciesSynchronously(scratchFile, project) if (!KotlinHighlightingUtil.shouldHighlight(myFixture.file)) error("Highlighting for scratch file is switched off")
val psiFile = PsiManager.getInstance(project).findFile(scratchFile) ?: error("Couldn't find psi file ${sourceFile.path}") launchScratch()
waitUntilScratchFinishes()
if (!KotlinHighlightingUtil.shouldHighlight(psiFile)) error("Highlighting for scratch file is switched off") val actualOutput = getFileTextWithInlays()
val (editor, scratchPanel) = getEditorWithScratchPanel(myManager, scratchFile) ?: error("Couldn't find scratch panel")
scratchPanel.scratchFile.saveOptions {
copy(isRepl = isRepl, isInteractiveMode = false)
}
if (!InTextDirectivesUtils.isDirectiveDefined(fileText, "// NO_MODULE")) {
scratchPanel.setModule(myFixture.module)
}
launchScratch(scratchFile)
val doc = PsiDocumentManager.getInstance(project).getDocument(psiFile) ?: error("Document for ${psiFile.name} is null")
val actualOutput = StringBuilder(psiFile.text)
for (line in doc.lineCount - 1 downTo 0) {
editor.editor.inlayModel.getInlineElementsInRange(
doc.getLineStartOffset(line),
doc.getLineEndOffset(line)
).map { it.renderer }
.filterIsInstance<InlayScratchFileRenderer>()
.forEach {
val str = it.toString()
val offset = doc.getLineEndOffset(line); actualOutput.insert(
offset,
"${str.takeWhile { it.isWhitespace() }}// ${str.trim()}"
)
}
}
val expectedFileName = if (isRepl) { val expectedFileName = if (isRepl) {
fileName.replace(".kts", ".repl.after") fileName.replace(".kts", ".repl.after")
@@ -135,7 +110,59 @@ abstract class AbstractScratchRunActionTest : FileEditorManagerTestCase() {
KotlinTestUtils.assertEqualsToFile(expectedFile, actualOutput.toString()) KotlinTestUtils.assertEqualsToFile(expectedFile, actualOutput.toString())
} }
protected fun createScratchFile(name: String, text: String): VirtualFile { protected fun String.inlinePropertiesValues(
isRepl: Boolean = false,
isInteractiveMode: Boolean = false
): String {
return replace("~REPL_MODE~", isRepl.toString()).replace("~INTERACTIVE_MODE~", isInteractiveMode.toString())
}
private fun getFileTextWithInlays(): StringBuilder {
val doc = myFixture.getDocument(myFixture.file) ?: error("Document for ${myFixture.file.name} is null")
val actualOutput = StringBuilder(myFixture.file.text)
for (line in doc.lineCount - 1 downTo 0) {
getInlays(doc.getLineStartOffset(line), doc.getLineEndOffset(line))
.forEach { inlay ->
val str = inlay.toString()
val offset = doc.getLineEndOffset(line)
actualOutput.insert(
offset,
"${str.takeWhile { it.isWhitespace() }}// ${str.trim()}"
)
}
}
return actualOutput
}
protected fun getInlays(start: Int = 0, end: Int = myFixture.file.textLength): List<InlayScratchFileRenderer> {
val inlineElementsInRange = myFixture.editor.inlayModel.getInlineElementsInRange(start, end)
return inlineElementsInRange
.map { it.renderer }
.filterIsInstance<InlayScratchFileRenderer>()
}
private fun configureOptions(
scratchPanel: ScratchTopPanel,
fileText: String
) {
if (InTextDirectivesUtils.getPrefixedBoolean(fileText, "// INTERACTIVE_MODE: ") != true) {
scratchPanel.scratchFile.saveOptions {
copy(isInteractiveMode = false)
}
}
if (InTextDirectivesUtils.getPrefixedBoolean(fileText, "// REPL_MODE: ") == true) {
scratchPanel.scratchFile.saveOptions {
copy(isRepl = true)
}
}
if (!InTextDirectivesUtils.isDirectiveDefined(fileText, "// NO_MODULE")) {
scratchPanel.setModule(myFixture.module)
}
}
protected fun configureScratchByText(name: String, text: String): ScratchTopPanel {
val scratchFile = ScratchRootType.getInstance().createScratchFile( val scratchFile = ScratchRootType.getInstance().createScratchFile(
project, project,
name, name,
@@ -145,17 +172,30 @@ abstract class AbstractScratchRunActionTest : FileEditorManagerTestCase() {
) ?: error("Couldn't create scratch file") ) ?: error("Couldn't create scratch file")
myFixture.openFileInEditor(scratchFile) myFixture.openFileInEditor(scratchFile)
return scratchFile
ScriptDependenciesManager.updateScriptDependenciesSynchronously(scratchFile, project)
val (_, scratchPanel) = getEditorWithScratchPanel(myManager, myFixture.file.virtualFile)
?: error("Couldn't find scratch panel")
configureOptions(scratchPanel, text)
return scratchPanel
} }
protected fun launchScratch(scratchFile: VirtualFile) { protected fun launchScratch() {
val action = RunScratchAction() val action = RunScratchAction()
val e = getActionEvent(scratchFile, action) launchAction(action)
}
protected fun launchAction(action: AnAction) {
val e = getActionEvent(myFixture.file.virtualFile, action)
action.beforeActionPerformedUpdate(e) action.beforeActionPerformedUpdate(e)
Assert.assertTrue(e.presentation.isEnabled && e.presentation.isVisible) Assert.assertTrue(e.presentation.isEnabled && e.presentation.isVisible)
action.actionPerformed(e) action.actionPerformed(e)
}
protected fun waitUntilScratchFinishes() {
UIUtil.dispatchAllInvocationEvents() UIUtil.dispatchAllInvocationEvents()
val start = System.currentTimeMillis() val start = System.currentTimeMillis()
@@ -175,6 +215,10 @@ abstract class AbstractScratchRunActionTest : FileEditorManagerTestCase() {
return TestActionEvent(context, action) return TestActionEvent(context, action)
} }
protected fun testScratchText(): String {
return File(testDataPath, "idea/testData/scratch/custom/test_scratch.kts").readText()
}
override fun getTestDataPath() = KotlinTestUtils.getHomeDirectory() override fun getTestDataPath() = KotlinTestUtils.getHomeDirectory()
@@ -9,7 +9,6 @@ import com.intellij.openapi.roots.ModuleRootModificationUtil
import com.intellij.openapi.roots.impl.libraries.ProjectLibraryTable import com.intellij.openapi.roots.impl.libraries.ProjectLibraryTable
import com.intellij.openapi.roots.libraries.Library import com.intellij.openapi.roots.libraries.Library
import org.jetbrains.kotlin.idea.run.createLibraryWithLongPaths import org.jetbrains.kotlin.idea.run.createLibraryWithLongPaths
import org.jetbrains.kotlin.idea.scratch.output.InlayScratchFileRenderer
import org.jetbrains.kotlin.idea.util.application.runWriteAction import org.jetbrains.kotlin.idea.util.application.runWriteAction
import org.jetbrains.kotlin.test.JUnit3WithIdeaConfigurationRunner import org.jetbrains.kotlin.test.JUnit3WithIdeaConfigurationRunner
import org.junit.runner.RunWith import org.junit.runner.RunWith
@@ -26,22 +25,13 @@ class CustomScratchRunActionTest : AbstractScratchRunActionTest() {
} }
private fun getOutput(isRepl: Boolean): String { private fun getOutput(isRepl: Boolean): String {
val fileText = "1" val fileText = testScratchText().inlinePropertiesValues(isRepl)
val scratchFile = createScratchFile("scratch_1.kts", fileText) configureScratchByText("scratch_1.kts", fileText)
val (editor, scratchPanel) = getEditorWithScratchPanel(myManager, scratchFile) ?: error("Couldn't find scratch panel") launchScratch()
scratchPanel.scratchFile.saveOptions { waitUntilScratchFinishes()
copy(isRepl = isRepl, isInteractiveMode = false)
}
scratchPanel.setModule(myFixture.module) return getInlays().joinToString().trim()
launchScratch(scratchFile)
return editor.editor.inlayModel.getInlineElementsInRange(0, fileText.length)
.map { it.renderer }
.filterIsInstance<InlayScratchFileRenderer>()
.joinToString().trim()
} }
private val library: Library by lazy { private val library: Library by lazy {
@@ -17,8 +17,7 @@ import kotlin.reflect.full.declaredMemberProperties
class ScratchOptionsSaveTest : AbstractScratchRunActionTest() { class ScratchOptionsSaveTest : AbstractScratchRunActionTest() {
fun testOptionsSaveOnClosingFile() { fun testOptionsSaveOnClosingFile() {
val scratchFile = createScratchFile("scratch_1.kts", "val a = 1") val scratchPanelBeforeClosingFile = configureScratchByText("scratch_1.kts", testScratchText())
val (_, scratchPanelBeforeClosingFile) = getEditorWithScratchPanel(myManager, scratchFile) ?: error("Couldn't find scratch panel")
Assert.assertEquals( Assert.assertEquals(
"This test checks that checkbox options are restored after file closing. Not all checkboxes are checked in this test", "This test checks that checkbox options are restored after file closing. Not all checkboxes are checked in this test",
@@ -34,10 +33,10 @@ class ScratchOptionsSaveTest : AbstractScratchRunActionTest() {
scratchPanelBeforeClosingFile.setMakeBeforeRun(newIsMakeBeforeRunValue) scratchPanelBeforeClosingFile.setMakeBeforeRun(newIsMakeBeforeRunValue)
scratchPanelBeforeClosingFile.setInteractiveMode(newIsInteractiveModeValue) scratchPanelBeforeClosingFile.setInteractiveMode(newIsInteractiveModeValue)
myManager.closeFile(scratchFile) myManager.closeFile(myFixture.file.virtualFile)
myManager.openFile(scratchFile, true) myManager.openFile(myFixture.file.virtualFile, true)
val (_, scratchPanelAfterClosingFile) = getEditorWithScratchPanel(myManager, scratchFile) ?: error("Couldn't find scratch panel") val (_, scratchPanelAfterClosingFile) = getEditorWithScratchPanel(myManager, myFixture.file.virtualFile) ?: error("Couldn't find scratch panel")
Assert.assertEquals("Wrong value for isRepl checkbox", newIsReplValue, scratchPanelAfterClosingFile.scratchFile.options.isRepl) Assert.assertEquals("Wrong value for isRepl checkbox", newIsReplValue, scratchPanelAfterClosingFile.scratchFile.options.isRepl)
Assert.assertEquals( Assert.assertEquals(