Skip to content

Commit 6ab9d13

Browse files
committed
Migrate PSI to JUnit 5, introduce KotlinCodeInsightTest
1 parent 7096027 commit 6ab9d13

File tree

6 files changed

+178
-128
lines changed

6 files changed

+178
-128
lines changed

build.gradle.kts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,7 @@ allprojects {
8383
}
8484
}
8585

86-
val excluded = setOf(":sdk:intellij:psi:iconpack")
87-
88-
if (project.path !in excluded) {
89-
tasks.withType<Test>().configureEach {
90-
useJUnitPlatform()
91-
}
86+
tasks.withType<Test>().configureEach {
87+
useJUnitPlatform()
9288
}
9389
}

sdk/intellij/psi/iconpack/build.gradle.kts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,17 @@ plugins {
77
alias(libs.plugins.valkyrie.kover)
88
}
99

10+
tasks.test {
11+
systemProperty("idea.kotlin.plugin.use.k2", "true")
12+
}
13+
1014
dependencies {
1115
implementation(projects.components.generator.core)
1216

1317
testImplementation(testFixtures(projects.sdk.intellij.testFixtures))
1418
testImplementation(projects.components.test.resourceLoader)
1519
testImplementation(libs.assertk)
20+
testRuntimeOnly(libs.junit.launcher)
1621

1722
intellijPlatform {
1823
testFramework(TestFrameworkType.Platform)

sdk/intellij/psi/iconpack/src/test/kotlin/io/github/composegears/valkyrie/sdk/intellij/psi/iconpack/IconPackPsiParserTest.kt

Lines changed: 104 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -4,123 +4,134 @@ import assertk.assertThat
44
import assertk.assertions.containsExactly
55
import assertk.assertions.isEqualTo
66
import assertk.assertions.isNotNull
7+
import com.intellij.testFramework.junit5.TestApplication
8+
import com.intellij.testFramework.runInEdtAndGet
79
import io.github.composegears.valkyrie.generator.core.IconPack
8-
import io.github.composegears.valkyrie.sdk.intellij.testfixtures.KotlinLightTestCase
9-
import org.junit.Test
10+
import io.github.composegears.valkyrie.sdk.intellij.testfixtures.KotlinCodeInsightTest
11+
import org.junit.jupiter.api.Test
1012

11-
class IconPackPsiParserTest : KotlinLightTestCase() {
13+
@TestApplication
14+
class IconPackPsiParserTest : KotlinCodeInsightTest() {
1215

1316
@Test
1417
fun `simple icon pack parser`() {
15-
val ktFile = loadKtFile("SimpleIconPack.kt")
16-
val iconPackInfo = IconPackPsiParser.parse(ktFile)
17-
18-
assertThat(iconPackInfo).isNotNull().transform { packInfo ->
19-
assertThat(packInfo.packageName).isEqualTo("io.github.composegears.valkyrie.psi")
20-
assertThat(packInfo.iconPack.name).isEqualTo("SimpleIconPack")
21-
assertThat(packInfo.iconPack.nested.size).isEqualTo(0)
18+
runInEdtAndGet {
19+
val ktFile = loadKtFile("SimpleIconPack.kt")
20+
val iconPackInfo = IconPackPsiParser.parse(ktFile)
21+
22+
assertThat(iconPackInfo).isNotNull().transform { packInfo ->
23+
assertThat(packInfo.packageName).isEqualTo("io.github.composegears.valkyrie.psi")
24+
assertThat(packInfo.iconPack.name).isEqualTo("SimpleIconPack")
25+
assertThat(packInfo.iconPack.nested.size).isEqualTo(0)
26+
}
2227
}
2328
}
2429

2530
@Test
2631
fun `nested icon pack parser`() {
27-
val ktFile = loadKtFile("NestedIconPack.kt")
28-
val iconPackInfo = IconPackPsiParser.parse(ktFile)
29-
30-
assertThat(iconPackInfo).isNotNull().transform { packInfo ->
31-
assertThat(packInfo.packageName).isEqualTo("io.github.composegears.valkyrie.psi")
32-
assertThat(packInfo.iconPack.name).isEqualTo("NestedIconPack")
33-
assertThat(packInfo.iconPack.nested.size).isEqualTo(5)
34-
assertThat(packInfo.iconPack.nested.map { it.name }).containsExactly(
35-
"Filled",
36-
"Outlined",
37-
"TwoTone",
38-
"Sharp",
39-
"Round",
40-
)
32+
runInEdtAndGet {
33+
val ktFile = loadKtFile("NestedIconPack.kt")
34+
val iconPackInfo = IconPackPsiParser.parse(ktFile)
35+
36+
assertThat(iconPackInfo).isNotNull().transform { packInfo ->
37+
assertThat(packInfo.packageName).isEqualTo("io.github.composegears.valkyrie.psi")
38+
assertThat(packInfo.iconPack.name).isEqualTo("NestedIconPack")
39+
assertThat(packInfo.iconPack.nested.size).isEqualTo(5)
40+
assertThat(packInfo.iconPack.nested.map { it.name }).containsExactly(
41+
"Filled",
42+
"Outlined",
43+
"TwoTone",
44+
"Sharp",
45+
"Round",
46+
)
47+
}
4148
}
4249
}
4350

4451
@Test
4552
fun `data object icon pack parser`() {
46-
val ktFile = loadKtFile("DataObjectIconPack.kt")
47-
val iconPackInfo = IconPackPsiParser.parse(ktFile)
48-
49-
assertThat(iconPackInfo).isNotNull().transform { packInfo ->
50-
assertThat(packInfo.packageName).isEqualTo("io.github.composegears.valkyrie.psi")
51-
assertThat(packInfo.iconPack.name).isEqualTo("DataObjectIconPack")
52-
assertThat(packInfo.iconPack.nested.size).isEqualTo(0)
53+
runInEdtAndGet {
54+
val ktFile = loadKtFile("DataObjectIconPack.kt")
55+
val iconPackInfo = IconPackPsiParser.parse(ktFile)
56+
57+
assertThat(iconPackInfo).isNotNull().transform { packInfo ->
58+
assertThat(packInfo.packageName).isEqualTo("io.github.composegears.valkyrie.psi")
59+
assertThat(packInfo.iconPack.name).isEqualTo("DataObjectIconPack")
60+
assertThat(packInfo.iconPack.nested.size).isEqualTo(0)
61+
}
5362
}
5463
}
5564

5665
@Test
5766
fun `deep nested icon pack parser`() {
58-
val ktFile = loadKtFile("DeepNestedIconPack.kt")
59-
val iconPackInfo = IconPackPsiParser.parse(ktFile)
60-
61-
assertThat(iconPackInfo).isNotNull().transform { packInfo ->
62-
assertThat(packInfo.packageName).isEqualTo("io.github.composegears.valkyrie.psi")
63-
packInfo.iconPack.assertStructure(
64-
expectedName = "DeepNestedIconPack",
65-
expectedNestedCount = 4,
66-
expectedNestedNames = listOf("Level1", "Branch", "Wide", "Single"),
67-
)
68-
69-
// Verify deep linear chain: Level1 -> Level2 -> Level3 -> Level4 -> Level5
70-
packInfo.iconPack.navigate("Level1").assertStructure("Level1", 1)
71-
packInfo.iconPack.navigate("Level1.Level2").assertStructure("Level2", 1)
72-
packInfo.iconPack.navigate("Level1.Level2.Level3").assertStructure("Level3", 1)
73-
packInfo.iconPack.navigate("Level1.Level2.Level3.Level4").assertStructure("Level4", 1)
74-
packInfo.iconPack.navigate("Level1.Level2.Level3.Level4.Level5").assertStructure("Level5", 0)
75-
76-
// Verify Branch with multiple sub-branches
77-
packInfo.iconPack.navigate("Branch").assertStructure(
78-
expectedName = "Branch",
79-
expectedNestedCount = 3,
80-
expectedNestedNames = listOf("Left", "Middle", "Right"),
81-
)
82-
packInfo.iconPack.navigate("Branch.Left").assertStructure("Left", 1)
83-
packInfo.iconPack.navigate("Branch.Left.LeftDeep1").assertStructure("LeftDeep1", 1)
84-
packInfo.iconPack.navigate("Branch.Left.LeftDeep1.LeftDeep2").assertStructure("LeftDeep2", 0)
85-
packInfo.iconPack.navigate("Branch.Middle").assertStructure("Middle", 0)
86-
packInfo.iconPack.navigate("Branch.Right")
87-
.assertStructure(
88-
expectedName = "Right",
89-
expectedNestedCount = 2,
90-
expectedNestedNames = listOf("RightDeep1", "RightDeep2"),
67+
runInEdtAndGet {
68+
val ktFile = loadKtFile("DeepNestedIconPack.kt")
69+
val iconPackInfo = IconPackPsiParser.parse(ktFile)
70+
71+
assertThat(iconPackInfo).isNotNull().transform { packInfo ->
72+
assertThat(packInfo.packageName).isEqualTo("io.github.composegears.valkyrie.psi")
73+
packInfo.iconPack.assertStructure(
74+
expectedName = "DeepNestedIconPack",
75+
expectedNestedCount = 4,
76+
expectedNestedNames = listOf("Level1", "Branch", "Wide", "Single"),
9177
)
9278

93-
// Verify wide tree with multiple children
94-
packInfo.iconPack.navigate("Wide")
95-
.assertStructure(
96-
expectedName = "Wide",
97-
expectedNestedCount = 5,
98-
expectedNestedNames = listOf("Item1", "Item2", "Item3", "Item4", "Item5"),
79+
// Verify deep linear chain: Level1 -> Level2 -> Level3 -> Level4 -> Level5
80+
packInfo.iconPack.navigate("Level1").assertStructure("Level1", 1)
81+
packInfo.iconPack.navigate("Level1.Level2").assertStructure("Level2", 1)
82+
packInfo.iconPack.navigate("Level1.Level2.Level3").assertStructure("Level3", 1)
83+
packInfo.iconPack.navigate("Level1.Level2.Level3.Level4").assertStructure("Level4", 1)
84+
packInfo.iconPack.navigate("Level1.Level2.Level3.Level4.Level5").assertStructure("Level5", 0)
85+
86+
// Verify Branch with multiple sub-branches
87+
packInfo.iconPack.navigate("Branch").assertStructure(
88+
expectedName = "Branch",
89+
expectedNestedCount = 3,
90+
expectedNestedNames = listOf("Left", "Middle", "Right"),
91+
)
92+
packInfo.iconPack.navigate("Branch.Left").assertStructure("Left", 1)
93+
packInfo.iconPack.navigate("Branch.Left.LeftDeep1").assertStructure("LeftDeep1", 1)
94+
packInfo.iconPack.navigate("Branch.Left.LeftDeep1.LeftDeep2").assertStructure("LeftDeep2", 0)
95+
packInfo.iconPack.navigate("Branch.Middle").assertStructure("Middle", 0)
96+
packInfo.iconPack.navigate("Branch.Right")
97+
.assertStructure(
98+
expectedName = "Right",
99+
expectedNestedCount = 2,
100+
expectedNestedNames = listOf("RightDeep1", "RightDeep2"),
101+
)
102+
103+
// Verify wide tree with multiple children
104+
packInfo.iconPack.navigate("Wide")
105+
.assertStructure(
106+
expectedName = "Wide",
107+
expectedNestedCount = 5,
108+
expectedNestedNames = listOf("Item1", "Item2", "Item3", "Item4", "Item5"),
109+
)
110+
111+
// Verify single leaf node
112+
packInfo.iconPack.navigate("Single").assertStructure("Single", 0)
113+
114+
// Verify toRawString produces correct paths
115+
val rawString = IconPack.toRawString(packInfo.iconPack)
116+
val expectedPaths = listOf(
117+
"DeepNestedIconPack.Level1.Level2.Level3.Level4.Level5",
118+
"DeepNestedIconPack.Branch.Left.LeftDeep1.LeftDeep2",
119+
"DeepNestedIconPack.Branch.Middle",
120+
"DeepNestedIconPack.Branch.Right.RightDeep1",
121+
"DeepNestedIconPack.Branch.Right.RightDeep2",
122+
"DeepNestedIconPack.Wide.Item1",
123+
"DeepNestedIconPack.Wide.Item2",
124+
"DeepNestedIconPack.Wide.Item3",
125+
"DeepNestedIconPack.Wide.Item4",
126+
"DeepNestedIconPack.Wide.Item5",
127+
"DeepNestedIconPack.Single",
99128
)
129+
assertThat(rawString).isEqualTo(expectedPaths.joinToString(","))
100130

101-
// Verify single leaf node
102-
packInfo.iconPack.navigate("Single").assertStructure("Single", 0)
103-
104-
// Verify toRawString produces correct paths
105-
val rawString = IconPack.toRawString(packInfo.iconPack)
106-
val expectedPaths = listOf(
107-
"DeepNestedIconPack.Level1.Level2.Level3.Level4.Level5",
108-
"DeepNestedIconPack.Branch.Left.LeftDeep1.LeftDeep2",
109-
"DeepNestedIconPack.Branch.Middle",
110-
"DeepNestedIconPack.Branch.Right.RightDeep1",
111-
"DeepNestedIconPack.Branch.Right.RightDeep2",
112-
"DeepNestedIconPack.Wide.Item1",
113-
"DeepNestedIconPack.Wide.Item2",
114-
"DeepNestedIconPack.Wide.Item3",
115-
"DeepNestedIconPack.Wide.Item4",
116-
"DeepNestedIconPack.Wide.Item5",
117-
"DeepNestedIconPack.Single",
118-
)
119-
assertThat(rawString).isEqualTo(expectedPaths.joinToString(","))
120-
121-
// Verify round-trip conversion (toRawString -> fromString)
122-
val reconstructed = IconPack.fromString(rawString)
123-
assertThat(reconstructed).isEqualTo(packInfo.iconPack)
131+
// Verify round-trip conversion (toRawString -> fromString)
132+
val reconstructed = IconPack.fromString(rawString)
133+
assertThat(reconstructed).isEqualTo(packInfo.iconPack)
134+
}
124135
}
125136
}
126137

sdk/intellij/test-fixtures/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ plugins {
88
}
99

1010
dependencies {
11+
testFixturesApi(libs.junit5.jupiter)
1112
testFixturesApi(libs.junit4)
1213

1314
intellijPlatform {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package io.github.composegears.valkyrie.sdk.intellij.testfixtures
2+
3+
import com.intellij.openapi.application.runInEdt
4+
import com.intellij.openapi.vfs.LocalFileSystem
5+
import com.intellij.testFramework.LightPlatformTestCase
6+
import com.intellij.testFramework.fixtures.CodeInsightTestFixture
7+
import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory
8+
import com.intellij.testFramework.fixtures.impl.TempDirTestFixtureImpl
9+
import java.nio.file.Path
10+
import kotlin.io.path.absolute
11+
import kotlin.properties.Delegates.notNull
12+
import org.jetbrains.kotlin.psi.KtFile
13+
import org.junit.jupiter.api.AfterEach
14+
import org.junit.jupiter.api.BeforeEach
15+
import org.junit.jupiter.api.TestInfo
16+
17+
/**
18+
* Base test class for IntelliJ IDEA tests that work with Kotlin files.
19+
*
20+
* This class provides a configured [CodeInsightTestFixture] for testing Kotlin PSI operations
21+
* and includes utility methods for loading Kotlin files from the test resources directory.
22+
*
23+
* JUnit 5 compatible
24+
*/
25+
abstract class KotlinCodeInsightTest {
26+
27+
private var fixture: CodeInsightTestFixture by notNull()
28+
29+
private val psiManager
30+
get() = fixture.psiManager
31+
32+
protected open val testDataPath: String = "src/test/resources"
33+
34+
@BeforeEach
35+
internal fun setupFixture(testInfo: TestInfo) {
36+
val factory = IdeaTestFixtureFactory.getFixtureFactory()
37+
val fixtureBuilder = factory.createLightFixtureBuilder(null, testInfo.displayName)
38+
val lightFixture = fixtureBuilder.getFixture()
39+
40+
fixture = IdeaTestFixtureFactory.getFixtureFactory()
41+
.createCodeInsightFixture(lightFixture, TempDirTestFixtureImpl())
42+
fixture.testDataPath = testDataPath
43+
fixture.setUp()
44+
}
45+
46+
@AfterEach
47+
internal fun tearDownEdt() {
48+
runInEdt {
49+
fixture.tearDown()
50+
LightPlatformTestCase.closeAndDeleteProject()
51+
}
52+
}
53+
54+
protected fun loadKtFile(fileName: String): KtFile {
55+
val path = Path.of(testDataPath, fileName).absolute()
56+
57+
val virtualFile = LocalFileSystem.getInstance().findFileByPath(path.toString())
58+
?: error("File not found: $fileName at $path")
59+
60+
val psiFile = psiManager.findFile(virtualFile)
61+
?: error("Could not create PSI file for: $fileName")
62+
63+
return psiFile as? KtFile
64+
?: error("File is not a Kotlin file: $fileName (type: ${psiFile::class.simpleName})")
65+
}
66+
}

sdk/intellij/test-fixtures/src/testFixtures/kotlin/io/github/composegears/valkyrie/sdk/intellij/testfixtures/KotlinLightTestCase.kt

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

0 commit comments

Comments
 (0)