Add a test for consistency between JavaSyntaxBundle and DefaultJavaSyntaxResources, document the regeneration process

GitOrigin-RevId: 1569c0a8a0a372bbba547273a0076ed389a50164
This commit is contained in:
Max Medvedev
2025-06-29 18:04:41 +00:00
committed by intellij-monorepo-bot
parent 21b47322b4
commit 18bfe5b1ad
6 changed files with 75 additions and 9 deletions
@@ -6,6 +6,7 @@ import org.jetbrains.annotations.ApiStatus
import org.jetbrains.annotations.Nls
import org.jetbrains.annotations.NonNls
import org.jetbrains.annotations.PropertyKey
import org.jetbrains.annotations.VisibleForTesting
import kotlin.jvm.JvmStatic
@ApiStatus.Internal
@@ -32,3 +33,10 @@ object JavaSyntaxBundle {
return resourceBundle.messagePointer(key, *params)
}
}
@VisibleForTesting
@ApiStatus.Internal
object DefaultJavaSyntaxResourcesTestAccessor {
val mappings: Map<String, String> get() = DefaultJavaSyntaxResources.mappings
val defaultJavaSyntaxResourcesName: String get() = DefaultJavaSyntaxResources::class.java.name
}
+1
View File
@@ -153,6 +153,7 @@ jvm_library(
"//java/java-syntax:syntax",
"//platform/lang-impl",
"//xml/impl",
"//platform/syntax/syntax-scripts:scripts",
],
runtime_deps = [
":tests_test_resources",
+1
View File
@@ -127,5 +127,6 @@
<orderEntry type="module" module-name="intellij.java.syntax" scope="TEST" />
<orderEntry type="module" module-name="intellij.platform.lang.impl" scope="TEST" />
<orderEntry type="module" module-name="intellij.xml.impl" scope="TEST" />
<orderEntry type="module" module-name="intellij.platform.syntax.scripts" scope="TEST" />
</component>
</module>
@@ -0,0 +1,19 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.java.tests.syntax
import com.intellij.java.syntax.DefaultJavaSyntaxResourcesTestAccessor
import com.intellij.java.syntax.JavaSyntaxBundle
import com.intellij.platform.syntax.scripts.assertPropertiesMatch
import org.junit.jupiter.api.Test
class DefaultJavaSyntaxResourcesTest {
@Test
fun testJavaSyntaxResourcesMatch() {
assertPropertiesMatch(
propertiesFileName = JavaSyntaxBundle.BUNDLE,
defaultResourcesFileName = DefaultJavaSyntaxResourcesTestAccessor.defaultJavaSyntaxResourcesName,
classLoader = JavaSyntaxBundle.javaClass.classLoader,
actualMapping = DefaultJavaSyntaxResourcesTestAccessor.mappings,
)
}
}
@@ -1,3 +1,4 @@
*f:com.intellij.platform.syntax.scripts.GenerateBundleMappingKt
- sf:assertPropertiesMatch(java.lang.String,java.lang.String,java.lang.ClassLoader,java.util.Map):V
- sf:generateMapping(java.lang.String,java.lang.String,java.lang.String):V
- sf:main(java.lang.String[]):V
@@ -49,7 +49,7 @@ fun generateMapping(
outputPath.createFile()
}
val mappings = loadMappings(propertiesPath)
val mappings = loadMappingsFromFile(propertiesPath)
val fileName = outputPath.nameWithoutExtension
outputPath.writer().buffered().use { writer ->
@@ -59,6 +59,30 @@ fun generateMapping(
println("Done! Result: $outputPath")
}
/**
* Use to ensure the properties file and the default resources file are in sync.
*/
fun assertPropertiesMatch(
propertiesFileName: String,
defaultResourcesFileName: String,
classLoader: ClassLoader,
actualMapping: Map<String, String>,
) {
val propResourceName = propertiesFileName.asResourceName()
val propertiesFileStream = classLoader.getResourceAsStream(propResourceName)!!
val expectedMapping = propertiesFileStream.use { stream ->
loadPropertiesBundleMappings(stream)
}
require(expectedMapping == actualMapping) {
"""
|$propertiesFileName and $defaultResourcesFileName do not match.
|
|Please regenerate $defaultResourcesFileName. See instruction how to do it in the class's doc.
""".trimMargin()
}
}
private fun Writer.printClass(
className: String,
packageName: String,
@@ -67,9 +91,7 @@ private fun Writer.printClass(
) {
appendLine("package $packageName")
appendLine()
appendLine("// Generated by generateBundleMapping.kt")
appendLine("// To regenerate the file, please run `GenerateBundleMapping` run configuration with the following parameters: ")
appendLine("// $parametersString ")
appendLine(getRegenerationInstruction(parametersString).addLinePrefix("// "))
appendLine("internal object $className {")
appendLine(" val mappings: Map<String, String> = mapOf(")
for ((key, value) in mappings.entries.sortedBy { it.key }) {
@@ -84,13 +106,27 @@ private fun Writer.printClass(
appendLine('}')
}
private fun loadMappings(propertiesPath: Path): Map<String, String> {
val properties = Properties()
propertiesPath.inputStream().use { stream ->
properties.load(stream)
}
private fun getRegenerationInstruction(parametersString: String): String {
return """
To regenerate the file, please run `GenerateBundleMapping` run configuration with the following parameters: ")
$parametersString
""".trimIndent()
}
private fun String.addLinePrefix(linePrefix: String): String = split('\n').joinToString("\n") { "$linePrefix$it" }
private fun loadMappingsFromFile(propertiesPath: Path): Map<String, String> {
propertiesPath.inputStream().buffered().use { stream ->
return loadPropertiesBundleMappings(stream)
}
}
private fun loadPropertiesBundleMappings(stream: InputStream): Map<String, String> {
val properties = Properties()
properties.load(stream)
return properties.entries.associate { (key, value) ->
(key as String) to (value as String)
}
}
private fun String.asResourceName(): String = object : ResourceBundle.Control() {}.toResourceName(this, "properties")