Skip to content

Commit a6ae8ba

Browse files
committed
migrate to junit 5
1 parent 036a67a commit a6ae8ba

11 files changed

Lines changed: 259 additions & 46 deletions

File tree

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Copyright 2025 https://github.com/openapi-processor/openapi-processor-intellij
3+
* PDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.openapiprocessor.intellij
7+
8+
import com.intellij.openapi.project.DumbService
9+
import com.intellij.psi.JavaPsiFacade
10+
import com.intellij.psi.PsiAnnotation
11+
import com.intellij.psi.PsiElement
12+
import com.intellij.testFramework.junit5.TestApplication
13+
import com.intellij.testFramework.junit5.fixture.projectFixture
14+
import org.junit.jupiter.api.Assertions.assertTrue
15+
import org.junit.jupiter.api.Test
16+
17+
18+
@TestApplication
19+
class AnnotationsSpec {
20+
21+
companion object {
22+
val springPostAnnotation = SpringAnnotation("PostMapping", "post")
23+
val micronautPostAnnotation = MicronautAnnotation("Post", "post")
24+
25+
val project by projectFixture()
26+
}
27+
28+
@Test
29+
fun `post psi annotation matches fully qualified spring @PostMapping`() {
30+
DumbService.getInstance(project).runWhenSmart {
31+
val psiAnnotation = create("""@${springPostAnnotation.qualifiedName}(path = "/bar")""")
32+
assertTrue(springPostAnnotation.matches(psiAnnotation))
33+
}
34+
}
35+
36+
@Test
37+
fun `post psi annotation matches fully qualified micronaut @Post`() {
38+
DumbService.getInstance(project).runWhenSmart {
39+
val psiAnnotation = create("""@${micronautPostAnnotation.qualifiedName}(path = "/bar")""")
40+
assertTrue(micronautPostAnnotation.matches(psiAnnotation))
41+
}
42+
}
43+
44+
fun create(annotation: String, context: PsiElement? = null): PsiAnnotation {
45+
val elementFactory = JavaPsiFacade.getElementFactory(project)
46+
return elementFactory.createAnnotationFromText(annotation, context)
47+
}
48+
}
49+

src/test/kotlin/io/openapiprocessor/intellij/FileTypeSpec.kt

Lines changed: 38 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -20,50 +20,51 @@ import org.junit.jupiter.api.Test
2020

2121
@TestApplication
2222
class FileTypeSpec {
23-
val project = projectFixture()
24-
val module = project.moduleFixture("src")
25-
val sourceRoot = module.sourceRootFixture()
26-
27-
val emptyYaml = sourceRoot.virtualFileFixture("empty.yaml", "")
28-
val otherYaml = sourceRoot.virtualFileFixture("other.yaml", "something: some value")
29-
30-
val mappingYaml = sourceRoot.virtualFileFixture(
31-
"mapping.yaml", """
32-
openapi-processor-mapping: v0
33-
options:
34-
package-name: io.openapiprocessor
35-
""".trimIndent())
36-
37-
val mappingYml = sourceRoot.virtualFileFixture(
38-
"mapping.yml", """
39-
openapi-processor-mapping: v0
40-
options:
41-
package-name: io.openapiprocessor
42-
""".trimIndent())
43-
44-
val directory = sourceRoot.virtualDirFixture("folder")
45-
46-
val jar = testFixture {
47-
val parent = sourceRoot.init()
48-
49-
val tmpDir = directoryContent {
50-
zip("yaml.jar") {
51-
dir("resources") {
52-
file("a.yaml", "openapi-processor-mapping: v0\n")
23+
companion object {
24+
val project = projectFixture()
25+
val module = project.moduleFixture("main")
26+
val sourceRoot = module.sourceRootFixture()
27+
28+
val emptyYaml = sourceRoot.virtualFileFixture("empty.yaml", "")
29+
val otherYaml = sourceRoot.virtualFileFixture("other.yaml", "something: some value")
30+
31+
val mappingYaml = sourceRoot.virtualFileFixture(
32+
"mapping.yaml", """
33+
openapi-processor-mapping: v0
34+
options:
35+
package-name: io.openapiprocessor
36+
""".trimIndent())
37+
38+
val mappingYml = sourceRoot.virtualFileFixture(
39+
"mapping.yml", """
40+
openapi-processor-mapping: v0
41+
options:
42+
package-name: io.openapiprocessor
43+
""".trimIndent())
44+
45+
val directory = sourceRoot.virtualDirFixture("folder")
46+
47+
val jar = testFixture {
48+
val parent = sourceRoot.init()
49+
50+
val tmpDir = directoryContent {
51+
zip("yaml.jar") {
52+
dir("resources") {
53+
file("a.yaml", "openapi-processor-mapping: v0\n")
54+
}
5355
}
54-
}
55-
}.generateInVirtualTempDir()
56+
}.generateInVirtualTempDir()
5657

57-
addProjectLibrary(module.get(), "yaml.jar", tmpDir)
58+
addProjectLibrary(module.get(), "yaml.jar", tmpDir)
5859

59-
initialized(tmpDir) {
60-
edtWriteAction {
61-
tmpDir.delete(parent)
60+
initialized(tmpDir) {
61+
edtWriteAction {
62+
tmpDir.delete(parent)
63+
}
6264
}
6365
}
6466
}
6567

66-
6768
@Test
6869
fun `ignores empty file`() {
6970
assertNotEquals(TypeMappingFileType.NAME, emptyYaml.get().fileType.name)
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Copyright 2025 https://github.com/openapi-processor/openapi-processor-intellij
3+
* PDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.openapiprocessor.intellij
7+
8+
import com.intellij.openapi.application.ApplicationManager
9+
import com.intellij.openapi.application.runReadAction
10+
import com.intellij.openapi.vfs.VfsUtil
11+
import com.intellij.testFramework.TestDataPath
12+
import com.intellij.testFramework.junit5.TestApplication
13+
import com.intellij.testFramework.junit5.fixture.*
14+
import com.intellij.testFramework.replaceService
15+
import io.openapiprocessor.intellij.support.ModuleServiceStub
16+
import io.openapiprocessor.intellij.support.codeInsightFixture
17+
import io.openapiprocessor.intellij.support.psiTargets
18+
import org.junit.jupiter.api.Assertions.assertEquals
19+
import org.junit.jupiter.api.BeforeEach
20+
import org.junit.jupiter.api.Test
21+
import java.nio.file.Path
22+
23+
@TestApplication
24+
@TestDataPath($$"$PROJECT_ROOT/src/test/testdata/interface-to-openapi/paths")
25+
class MappingAnnotationLineMarkerSpec {
26+
27+
val tempPathFixture = tempPathFixture()
28+
val projectFixture = projectFixture(tempPathFixture, openAfterCreation = true)
29+
val moduleFixture = projectFixture.moduleFixture("main")
30+
31+
val sourceRootFixture = moduleFixture.sourceRootFixture(
32+
pathFixture = tempPathFixture,
33+
blueprintResourcePath = Path.of("src/test/testdata/interface-to-openapi/paths")
34+
)
35+
36+
val codeInsightFixture = codeInsightFixture(projectFixture, tempPathFixture)
37+
val disposableFixture = disposableFixture()
38+
39+
40+
@BeforeEach
41+
fun stubModuleService() {
42+
ApplicationManager.getApplication().replaceService(
43+
ModuleService::class.java,
44+
ModuleServiceStub(),
45+
disposableFixture.get()
46+
)
47+
}
48+
49+
@Test
50+
fun `adds navigation gutter icon to mapping annotation`() {
51+
val fixture = codeInsightFixture.get()
52+
53+
val file = VfsUtil.findRelativeFile(sourceRootFixture.get().virtualFile, "api", "Api.java")!!
54+
fixture.configureFromExistingVirtualFile(file)
55+
56+
val gutters = fixture.findAllGutters("api/Api.java")
57+
assertEquals(2, gutters.size)
58+
59+
runReadAction {
60+
val bar = gutters[0]
61+
assertEquals(MappingAnnotationLineMarker.Icon.openapi, bar.icon)
62+
assertEquals(MappingAnnotationLineMarker.I18n.TOOLTIP_TEXT, bar.tooltipText)
63+
assertEquals(bar.psiTargets.first().text, "/bar")
64+
65+
val foo = gutters[1]
66+
assertEquals(MappingAnnotationLineMarker.Icon.openapi, foo.icon)
67+
assertEquals(MappingAnnotationLineMarker.I18n.TOOLTIP_TEXT, foo.tooltipText)
68+
assertEquals(foo.psiTargets.first().text, "/foo")
69+
}
70+
}
71+
}

src/test/kotlin/io/openapiprocessor/intellij/support/Fixtures.kt

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,25 @@
66
package io.openapiprocessor.intellij.support
77

88
import com.intellij.openapi.application.edtWriteAction
9+
import com.intellij.openapi.module.Module
10+
import com.intellij.openapi.project.Project
11+
import com.intellij.openapi.project.modules
912
import com.intellij.openapi.vfs.VfsUtil
1013
import com.intellij.openapi.vfs.VirtualFile
1114
import com.intellij.psi.PsiDirectory
15+
import com.intellij.testFramework.TestApplicationManager
16+
import com.intellij.testFramework.TestDataPath
17+
import com.intellij.testFramework.TestDataProvider
18+
import com.intellij.testFramework.fixtures.CodeInsightTestFixture
19+
import com.intellij.testFramework.fixtures.IdeaProjectTestFixture
20+
import com.intellij.testFramework.fixtures.TempDirTestFixture
21+
import com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl
22+
import com.intellij.testFramework.fixtures.impl.TempDirTestFixtureImpl
23+
import com.intellij.testFramework.junit5.fixture.TestContext
1224
import com.intellij.testFramework.junit5.fixture.TestFixture
1325
import com.intellij.testFramework.junit5.fixture.testFixture
26+
import org.jetbrains.annotations.TestOnly
27+
import java.nio.file.Path
1428

1529
fun TestFixture<PsiDirectory>.virtualDirFixture(path: String): TestFixture<VirtualFile> {
1630
return testFixture {
@@ -27,3 +41,88 @@ fun TestFixture<PsiDirectory>.virtualDirFixture(path: String): TestFixture<Virtu
2741
}
2842
}
2943
}
44+
45+
// based on com.intellij.platform.testFramework.junit5.codeInsight.fixture.codeInsightFixture
46+
47+
48+
@Target(AnnotationTarget.FUNCTION)
49+
annotation class TestSubPath(val value: String)
50+
51+
@TestOnly
52+
fun codeInsightFixture(
53+
projectFixture: TestFixture<Project>,
54+
tempDirFixture: TestFixture<Path>,
55+
): TestFixture<CodeInsightTestFixture> = codeInsightFixture(
56+
projectFixture,
57+
tempDirFixture
58+
) { project, tempDir -> CodeInsightTestFixtureImpl(project, tempDir) }
59+
60+
61+
fun <T: CodeInsightTestFixture> codeInsightFixture(
62+
projectFixture: TestFixture<Project>,
63+
tempDirFixture: TestFixture<Path>,
64+
createFixture: (IdeaProjectTestFixture, TempDirTestFixture) -> T,
65+
): TestFixture<T> = testFixture { context ->
66+
val project = projectFixture.init()
67+
val tempDir = tempDirFixture.init()
68+
69+
val projectFixture = object : IdeaProjectTestFixture {
70+
override fun getProject(): Project = project
71+
72+
override fun getModule(): Module {
73+
check(project.modules.isNotEmpty()) {
74+
"At least one module is required for the project. Use TestFixture<Project>.moduleFixture() to register one in your test class."
75+
}
76+
return project.modules[0]
77+
}
78+
79+
override fun setUp() {
80+
TestApplicationManager.getInstance().setDataProvider(TestDataProvider(project))
81+
}
82+
83+
override fun tearDown() {
84+
TestApplicationManager.getInstance().setDataProvider(null)
85+
}
86+
}
87+
val tempDirFixture = object : TempDirTestFixtureImpl() {
88+
// This method affects the internal temp dir used by the fixture, so we need to override it and not #getTempDir().
89+
override fun doCreateTempDirectory(): Path = tempDir
90+
91+
// As the temporary directory is created by the external fixture, we don't need to handle it here.
92+
override fun deleteOnTearDown(): Boolean = false
93+
}
94+
95+
val codeInsightFixture = createFixture(projectFixture, tempDirFixture)
96+
97+
codeInsightFixture.testDataPath = getTestDataPath(context)
98+
99+
codeInsightFixture.setUp()
100+
initialized(codeInsightFixture) {
101+
codeInsightFixture.tearDown()
102+
}
103+
}
104+
105+
private fun getTestDataPath(context: TestContext): String {
106+
val rootPath = context.findAnnotation(TestDataPath::class.java)?.value?.removePrefix($$"$PROJECT_ROOT/")
107+
check(rootPath != null) {
108+
"the test class should have a @TestDataPath annotation"
109+
}
110+
111+
// val subPath = context.findAnnotation(TestSubPath::class.java)?.value ?: ""
112+
return rootPath
113+
114+
// val homeDir = IdeaTestExecutionPolicy.getHomePathWithPolicy().toNioPathOrNull()
115+
// check(homeDir != null) {
116+
// "Couldn't create nio.Path from ${IdeaTestExecutionPolicy.getHomePathWithPolicy()}"
117+
// }
118+
// val resolvedPath = homeDir.resolve(rootPath).resolve(subPath)
119+
// if (resolvedPath.exists()) {
120+
// return resolvedPath.pathString
121+
// }
122+
// If the project opened as IJ community, then the test path for community will be duplicated, e.g. it is $HOME/community/community/...
123+
// To handle this scenario, we are trying to resolve the path $HOME/community/../community/...
124+
// check(rootPath.startsWith(COMMUNITY_PATH_PREFIX)) {
125+
// "The test data path is not located in community folder, but it doesn't exist in the ultimate."
126+
// }
127+
// return homeDir.resolve("../").resolve(rootPath).resolve(subPath).pathString
128+
}

src/test/kotlin-old/io/openapiprocessor/intellij/support/GutterMark.kt renamed to src/test/kotlin/io/openapiprocessor/intellij/support/GutterMark.kt

File renamed without changes.

src/test/kotlin-old/io/openapiprocessor/intellij/support/ModuleServiceStub.kt renamed to src/test/kotlin/io/openapiprocessor/intellij/support/ModuleServiceStub.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ import io.openapiprocessor.intellij.ModuleService
1515
class ModuleServiceStub: ModuleService {
1616

1717
override fun findModules(element: PsiElement): List<Module> {
18-
val module = ProjectRootManager.getInstance(element.project)
18+
val module = ProjectRootManager
19+
.getInstance(element.project)
1920
.fileIndex
2021
.getModuleForFile(element.containingFile.virtualFile)
2122

src/test/testdata/filetype/empty.yaml

Whitespace-only changes.

src/test/testdata/filetype/mapping.yaml

Lines changed: 0 additions & 4 deletions
This file was deleted.

src/test/testdata/filetype/mapping.yml

Lines changed: 0 additions & 4 deletions
This file was deleted.

src/test/testdata/interface-to-openapi/paths/org/springframework/web/bin/annotation/PostMapping.java renamed to src/test/testdata/interface-to-openapi/paths/org/springframework/web/bind/annotation/PostMapping.java

File renamed without changes.

0 commit comments

Comments
 (0)