Skip to content

Commit

Permalink
Extract test library to its own repo
Browse files Browse the repository at this point in the history
  • Loading branch information
flash-freezing-lava committed Feb 17, 2023
0 parents commit 78cb5dd
Show file tree
Hide file tree
Showing 22 changed files with 994 additions and 0 deletions.
45 changes: 45 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
gradlew
gradlew.bat
gradle/wrapper
.gradle
build/
!gradle/wrapper/gradle-wrapper.jar
!**/src/main/**/build/
!**/src/test/**/build/

### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr
out/
!**/src/main/**/out/
!**/src/test/**/out/

### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/

### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/

### VS Code ###
.vscode/

### Mac OS ###
.DS_Store
8 changes: 8 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 18 additions & 0 deletions .idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/kotlinc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Directory-based Test Framework for Intellij Plugins

## Give me code

Add the following to your `build.gradle.kts` and replace dirTestVersion with the current version `TODO add badge` and `org/your/test/packageName` with the path to your top-level package:
```kotlin
dependencies {
testImplementation("me.ffl", "intellijDirectoryTests", dirTestVersion)
}

val unitTestTask = task<Test>("unitTest") {
isScanForTestClasses = false
include("org/your/test/packageName/*Test.class")
useJUnitPlatform()
}
```

Create the following class in `src/main/test/org/your/test/packageName`:
```kotlin
// You can change the executor's behavior by passing something other
// than [DirectoryTestConfig.default] to the [DirectoryTests] constructor.
@Suppress("unused")
class MyPluginTest: DirectoryTests()
```
57 changes: 57 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import org.gradle.api.tasks.wrapper.Wrapper.DistributionType

plugins {
kotlin("jvm") version "1.8.0"
`java-library`
`maven-publish`
}

group = "me.ffl"
version = "0.1.0"

repositories {
mavenCentral()
maven("https://www.jetbrains.com/intellij-repository/releases")
maven("https://cache-redirector.jetbrains.com/intellij-dependencies")
}

dependencies {
val kotestVersion = "5.5.0"
api("io.kotest:kotest-runner-junit5:$kotestVersion")
api("io.kotest:kotest-assertions-core:$kotestVersion")
compileOnlyApi("com.jetbrains.intellij.platform:test-framework:223.8617.56")
}

java {
withJavadocJar()
withSourcesJar()
}

tasks {
javadoc {
if (JavaVersion.current().isJava9Compatible) {
(options as StandardJavadocDocletOptions).addBooleanOption("html5", true)
}
}

wrapper {
gradleVersion = "7.2"
distributionType = DistributionType.ALL
}
}

publishing {
publications {
create<MavenPublication>("maven") {
groupId = "me.ffl"
artifactId = "intellijDirectoryTests"
version = "0.1.0"

from(components["java"])
}
}
}

kotlin {
jvmToolchain(17)
}
1 change: 1 addition & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
kotlin.code.style=official
3 changes: 3 additions & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@

rootProject.name = "intellijDirectoryTests"

32 changes: 32 additions & 0 deletions src/main/kotlin/me/ffl/intellijDirectoryTests/Action.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package me.ffl.intellijDirectoryTests

import com.intellij.refactoring.util.CommonRefactoringUtil.RefactoringErrorHintException
import com.intellij.util.io.exists
import com.intellij.util.io.readText
import io.kotest.matchers.shouldBe
import me.ffl.intellijDirectoryTests.MarkupFile.Companion.findCaret
import kotlin.io.path.div

val actionExecutor: KotestExecutor = {
val beforeDir = testDataPath / "before"
val beforeFiles = beforeDir.loadProject()
val errorFile = testDataPath / "should_fail.txt"
val (caretFile, caretOffset) = beforeFiles.findCaret()
val intention = testDataPath.mapNotNull { config.knownIntentionMap[it.toString().removeSuffix("Action").removeSuffix("Intention")] }.lastOrNull().shouldNotBeNull {
"test data path contains no Intention class name"
}
try {
caretFile.executeIntentionAt(intention, caretOffset)
if (errorFile.exists()) {
fail("Intention did not fail, when it was expected")
}
} catch (e: RefactoringErrorHintException) {
if (!errorFile.exists()) {
fail("unexpected intention error: ${e.message}")
} else {
val expected = errorFile.readText()
e.message shouldBe expected
}
}
checkAfterProject()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package me.ffl.intellijDirectoryTests

import com.intellij.codeInsight.intention.IntentionAction
import com.intellij.psi.PsiElement
import com.intellij.testFramework.LightProjectDescriptor
import com.intellij.testFramework.fixtures.CodeInsightTestFixture
import java.nio.file.Path
import kotlin.io.path.Path

data class DirectoryTestConfig(
val kotestExecutors: Map<String, KotestExecutor>,
val needsHeavyTestRunner: Set<String>,
val needsNoWriteAction: Set<String>,
val testDataPath: Path,
val knownIntentions: List<IntentionAction>,
/**
* If true (by default this is false), the files specifying expected parser output is overridden with the actual output.
* This is useful, if you prefer to use `git diff` or intellij's diff view instead of clicking through all tests.
* Obviously, you should `git restore` the files, if the output did not change in the intended way.
*/
val overrideParserOutput: Boolean,
/**
* This function is used to check, whether a reference to a psi element outside the project,
* corresponds to an entry of `external references.txt`.
* This has cannot be implemented by intellijDirectoryTests, because it is specific to the tested language.
* If the function returns null, the PsiElement cannot correspond to any entry.
* This can be used f.e. if the element has no name or is in a file of unknown language.
*/
val externalReferenceToString: (PsiElement) -> String?,
val projectDescriptor: LightProjectDescriptor?,
/**
* Configure kotest to continue on assertion errors and show all errors at last, instead of stopping at the first error.
*/
val softAssertByDefault: Boolean,
) {
internal val knownIntentionMap = knownIntentions.associateBy { it.javaClass.simpleName }

internal fun createContext(
testName: String,
testDataPath: Path,
myFixture: CodeInsightTestFixture
): KotestExecutorContext {
return KotestExecutorContext(testName, testDataPath, myFixture, this)
}

companion object {
private val defaultKotestExecutors: Map<String, KotestExecutor> = mapOf(
"rename" to renameExecutor,
"parser" to parserExecutor,
"documentation" to documentationExecutor,
"find usages" to findUsagesExecutor,
"actions" to actionExecutor,
"resolve" to resolveExecutor,
"hints" to hintsExecutor,
"inline" to inlineExecutor,
)
private val defaultTestDataPath = Path("src/test/testData")
val denyAllExternalReferences: (PsiElement) -> String? = { null }
val default = DirectoryTestConfig(
defaultKotestExecutors,
emptySet(),
emptySet(),
defaultTestDataPath,
emptyList(),
false,
denyAllExternalReferences,
null,
true,
)
}
}
Loading

0 comments on commit 78cb5dd

Please sign in to comment.