From 79c564a2aa69ee62abe734dd2ea0e02b16be4615 Mon Sep 17 00:00:00 2001 From: soywiz Date: Tue, 17 Dec 2019 10:10:36 +0100 Subject: [PATCH] Start using korge-templates.xml for project generation (except gradle wrapper for now) --- .gitignore | 1 + .../intellij/config/KorgeGlobalSettings.kt | 48 +- .../korge/intellij/module/KorgeFeatures.kt | 63 --- .../intellij/module/KorgeModuleBuilder.kt | 2 +- .../intellij/module/KorgeModuleConfig.kt | 143 +----- .../intellij/module/KorgeProjectTemplate.kt | 27 +- .../module/wizard/KorgeModuleWizardStep.kt | 50 +- .../soywiz/korge/intellij/util/TemplateExt.kt | 13 + .../soywiz/korge/intellij/korge-templates.xml | 481 +++++++++++++++--- .../config/KorgeGlobalSettingsTest.kt | 14 + .../korge/intellij/util/TemplateExtTest.kt | 10 + 11 files changed, 571 insertions(+), 281 deletions(-) delete mode 100644 src/main/kotlin/com/soywiz/korge/intellij/module/KorgeFeatures.kt create mode 100644 src/main/kotlin/com/soywiz/korge/intellij/util/TemplateExt.kt create mode 100644 src/test/kotlin/com/soywiz/korge/intellij/config/KorgeGlobalSettingsTest.kt create mode 100644 src/test/kotlin/com/soywiz/korge/intellij/util/TemplateExtTest.kt diff --git a/.gitignore b/.gitignore index 2d2dac3..3739c08 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ /.gradle /.idea /out +/velocity.log *.iml .DS_Store diff --git a/src/main/kotlin/com/soywiz/korge/intellij/config/KorgeGlobalSettings.kt b/src/main/kotlin/com/soywiz/korge/intellij/config/KorgeGlobalSettings.kt index 679f301..4072913 100644 --- a/src/main/kotlin/com/soywiz/korge/intellij/config/KorgeGlobalSettings.kt +++ b/src/main/kotlin/com/soywiz/korge/intellij/config/KorgeGlobalSettings.kt @@ -19,16 +19,46 @@ open class KorgeGlobalSettings : PersistentStateComponent { println("KorgeGlobalSettings.init") } - fun getCachedTemplate(): String { - val now = System.currentTimeMillis() - if (cachedTemplateString == null || (now - cachedTemplateLastRefreshTime).milliseconds >= 1.days) { - cachedTemplateLastRefreshTime = now - cachedTemplateString = - runCatching { URL("https://raw.githubusercontent.com/korlibs/korge-intellij-plugin/master/src/main/resources/com/soywiz/korge/intellij/korge-templates.xml").readText() }.getOrNull() - ?: runCatching { KorgeProjectTemplate::class.java.getResource("/com/soywiz/korge/intellij/korge-templates.xml")?.readText() }.getOrNull() - ?: error("Can't get a valid 'korge-templates.xml' file from any source") + companion object { + fun compareKorgeTemplateVersion(xml1: String, xml2: String): Int { + val versionRegex = Regex("") + val result1 = versionRegex.find(xml1) + val result2 = versionRegex.find(xml2) + val v1 = result1?.groupValues?.get(1)?.toIntOrNull() ?: 0 + val v2 = result2?.groupValues?.get(1)?.toIntOrNull() ?: 0 + return v2.compareTo(v1) } - return cachedTemplateString!! + } + + fun getCachedTemplate(): String { + //cachedTemplateLastRefreshTime = 0L // Force cache invalidation + val now = System.currentTimeMillis() + val elapsedTimeSinceLastCheck = (now - cachedTemplateLastRefreshTime).milliseconds + + val resource = runCatching { KorgeProjectTemplate::class.java.getResource("/com/soywiz/korge/intellij/korge-templates.xml")?.readText() }.getOrNull() + + if (cachedTemplateString == null || elapsedTimeSinceLastCheck >= 1.days) { + cachedTemplateLastRefreshTime = now + + println("Refreshing cached korge-templates.xml :: elapsedTimeSinceLastCheck=${elapsedTimeSinceLastCheck.hours}h") + + val online = runCatching { URL("https://raw.githubusercontent.com/korlibs/korge-intellij-plugin/master/src/main/resources/com/soywiz/korge/intellij/korge-templates.xml").readText() }.getOrNull() + + cachedTemplateString = when { + online != null && resource != null -> if (compareKorgeTemplateVersion(online, resource) <= 0) { + println(" - korge-templates.xml: Using online version") + online + } else { + println(" - korge-templates.xml: Using resources version") + "" + } + else -> online ?: resource ?: error("Can't get a valid 'korge-templates.xml' file from any source") + } + } else { + println("Using cached korge-templates.xml :: elapsedTimeSinceLastCheck=${elapsedTimeSinceLastCheck.hours}h :: cachedTemplateString.isNullOrEmpty()=${cachedTemplateString.isNullOrEmpty()}") + } + + return if (cachedTemplateString.isNullOrEmpty()) resource ?: "" else cachedTemplateString!! } override fun getState() = this diff --git a/src/main/kotlin/com/soywiz/korge/intellij/module/KorgeFeatures.kt b/src/main/kotlin/com/soywiz/korge/intellij/module/KorgeFeatures.kt deleted file mode 100644 index 243d213..0000000 --- a/src/main/kotlin/com/soywiz/korge/intellij/module/KorgeFeatures.kt +++ /dev/null @@ -1,63 +0,0 @@ -package com.soywiz.korge.intellij.module - -@Suppress("unused") -object Features { - val core = Feature( - title = "Korge", - description = "Korge support", - artifacts = listOf(), - documentation = "https://korlibs.soywiz.com/korge/", - dependencies = setOf(), - group = "Features" - ) - val f3d = Feature( - title = "3D Support", - description = "Adds experimental 3d support", - artifacts = listOf(), - documentation = "https://korlibs.soywiz.com/korge/3d/", - dependencies = setOf(core), - group = "Features" - ) - val box2d = Feature( - title = "Box-2D Support", - description = "Adds support for Box-2D", - artifacts = listOf(), - documentation = "https://korlibs.soywiz.com/korge/physics/box2d/", - dependencies = setOf(core), - group = "Features" - ) - val dragonbones = Feature( - title = "DragonBones Support", - description = "Adds support for DragonBones", - artifacts = listOf(), - documentation = "https://korlibs.soywiz.com/korge/skeleton/dragonbones/", - dependencies = setOf(core), - group = "Features" - ) - val swf = Feature( - title = "SWF Support", - description = "Adds support for Adobe Flash/Animate SWF files", - artifacts = listOf(), - documentation = "https://korlibs.soywiz.com/korge/animation/swf/", - dependencies = setOf(core), - group = "Features" - ) - - val ALL by lazy { listOf(core, f3d, box2d, dragonbones, swf) } -} - -class Feature( - val title: String, - val description: String, - val artifacts: List, - val documentation: String, - val dependencies: Set, - val group: String = "Features" -) { -} - -class FeatureSet(features: Iterable) { - val direct = features.toSet() - val all = direct.flatMap { it.dependencies }.toSet() - val transitive = all - direct -} diff --git a/src/main/kotlin/com/soywiz/korge/intellij/module/KorgeModuleBuilder.kt b/src/main/kotlin/com/soywiz/korge/intellij/module/KorgeModuleBuilder.kt index 263b7c3..f05554c 100644 --- a/src/main/kotlin/com/soywiz/korge/intellij/module/KorgeModuleBuilder.kt +++ b/src/main/kotlin/com/soywiz/korge/intellij/module/KorgeModuleBuilder.kt @@ -43,7 +43,7 @@ class KorgeModuleBuilder() : JavaModuleBuilder() { val info = config runBlocking { - for ((fileName, fileContent) in config.generate()) { + for ((fileName, fileContent) in config.generate(korgeProjectTemplateProvider.template)) { root.createFile(fileName, fileContent, FileMode("0777")) } } diff --git a/src/main/kotlin/com/soywiz/korge/intellij/module/KorgeModuleConfig.kt b/src/main/kotlin/com/soywiz/korge/intellij/module/KorgeModuleConfig.kt index 4509557..8bd1536 100644 --- a/src/main/kotlin/com/soywiz/korge/intellij/module/KorgeModuleConfig.kt +++ b/src/main/kotlin/com/soywiz/korge/intellij/module/KorgeModuleConfig.kt @@ -1,64 +1,37 @@ package com.soywiz.korge.intellij.module import com.soywiz.korge.intellij.* +import com.soywiz.korge.intellij.util.* import com.soywiz.korio.util.* +import com.soywiz.korio.util.encoding.* class KorgeModuleConfig { var artifactGroup = "com.example" var artifactId = "example" var artifactVersion = "0.0.1" var projectType = ProjectType.Gradle - var featuresToInstall = listOf(Features.core) + var featuresToInstall: List = listOf() var korgeVersion = KorgeProjectTemplate.Versions.Version("1.5.0d") - fun generate(): Map = LinkedHashMap().apply { + fun generate(template: KorgeProjectTemplate): Map = LinkedHashMap().apply { + fun putTextFile(name: String, text: String) { + put(name, text.toByteArray(Charsets.UTF_8)) + } + fun putTextFile(name: String, file: Indenter.() -> Unit) { - put(name, Indenter().also { file(it) }.toString().toByteArray(Charsets.UTF_8)) + putTextFile(name, Indenter().also { file(it) }.toString()) } - val features = featuresToInstall.toSet() - putTextFile("build.gradle") { - line("buildscript") { - line("repositories") { - +"mavenLocal()" - +"""maven { url = uri("https://dl.bintray.com/korlibs/korlibs") }""" - +"""maven { url = uri("https://plugins.gradle.org/m2/") }""" - +"""mavenCentral()""" - } - line("dependencies") { - +"""classpath("com.soywiz.korlibs.korge.plugins:korge-gradle-plugin:$korgeVersion")""" - } - } + val templateContext = mapOf( + "korgeVersion" to korgeVersion, + "artifactGroup" to artifactGroup, + "artifactId" to artifactId, + "features" to featuresToInstall.toSet() + ) + featuresToInstall.associate { "feature_${it.id}" to true } - +"""apply plugin: "korge"""" + fun getFileFromGenerator(path: String): ByteArray = KorgeResources.getBytes("/com/soywiz/korge/intellij/generator/$path") - line("korge") { - +"""id = "$artifactGroup.$artifactId"""" - if (features.contains(Features.f3d)) { - +"supportExperimental3d()" - } - if (features.contains(Features.box2d)) { - +"supportExperimental3d()" - } - if (features.contains(Features.dragonbones)) { - +"supportDragonbones()" - } - if (features.contains(Features.swf)) { - +"supportSwf()" - } - } - - } - - putTextFile("settings.gradle") { - +"""enableFeaturePreview("GRADLE_METADATA")""" - } - - putTextFile("gradle.properties") { - +"org.gradle.jvmargs=-Xmx1536m" - } - - fun getFileFromGenerator(path: String) = KorgeResources.getBytes("/com/soywiz/korge/intellij/generator/$path") + println(templateContext) put("gradlew", getFileFromGenerator("gradlew")) put("gradlew_linux", getFileFromGenerator("gradlew_linux")) @@ -68,75 +41,13 @@ class KorgeModuleConfig { put("gradle/wrapper/gradle-wrapper.jar", getFileFromGenerator("gradle/wrapper/gradle-wrapper.jar")) put("gradle/wrapper/gradle-wrapper.properties", getFileFromGenerator("gradle/wrapper/gradle-wrapper.properties")) - putTextFile("src/commonMain/kotlin/main.kt") { - +"import com.soywiz.klock.seconds" - +"import com.soywiz.korge.*" - +"import com.soywiz.korge.tween.*" - +"import com.soywiz.korge.view.*" - +"import com.soywiz.korim.color.Colors" - +"import com.soywiz.korim.format.*" - +"import com.soywiz.korio.async.launchImmediately" - +"import com.soywiz.korio.file.std.*" - +"import com.soywiz.korma.geom.degrees" - +"import com.soywiz.korma.interpolation.Easing" - - SEPARATOR { - line("""suspend fun main() = Korge(width = 512, height = 512, bgcolor = Colors["#2b2b2b"])""") { - SEPARATOR { - +"val minDegrees = (-16).degrees" - +"val maxDegrees = (+16).degrees" - } - SEPARATOR { - line("""val image = image(resourcesVfs["korge.png"].readBitmap())""") { - +"rotation = maxDegrees" - +"anchor(.5, .5)" - +"scale(.8)" - +"position(256, 256)" - } - } - SEPARATOR { - line("launchImmediately") { - line("while (true)") { - +"image.tween(image::rotation[minDegrees], time = 1.seconds, easing = Easing.EASE_IN_OUT)" - +"image.tween(image::rotation[maxDegrees], time = 1.seconds, easing = Easing.EASE_IN_OUT)" - } - } - } + for (file in template.files.files) { + when (file.encoding) { + "base64" -> { + put(file.path, file.content.fromBase64IgnoreSpaces()) } - } - } - - - put("src/commonMain/resources/korge.png", KorgeResources.KORGE_IMAGE) - - putTextFile("src/commonTest/kotlin/test.kt") { - SEPARATOR { - +"import com.soywiz.klock.*" - +"import com.soywiz.korge.input.*" - +"import com.soywiz.korge.tests.*" - +"import com.soywiz.korge.tween.*" - +"import com.soywiz.korge.view.*" - +"import com.soywiz.korim.color.*" - +"import com.soywiz.korma.geom.*" - +"import kotlin.test.*" - } - SEPARATOR { - line("class MyTest : ViewsForTesting()") { - +"@Test" - line("fun test() = viewsTest") { - +"val log = arrayListOf()" - +"val rect = solidRect(100, 100, Colors.RED)" - line("rect.onClick") { - +"""log += "clicked"""" - } - +"assertEquals(1, views.stage.children.size)" - +"rect.simulateClick()" - +"assertEquals(true, rect.isVisibleToUser())" - +"tween(rect::x[-102], time = 10.seconds)" - +"assertEquals(Rectangle(x=-102, y=0, width=100, height=100), rect.globalBounds)" - +"assertEquals(false, rect.isVisibleToUser())" - +"""assertEquals(listOf("clicked"), log)""" - } + "", "text" -> { + putTextFile(file.path, renderTemplate(file.content.trimIndent().trim(), templateContext)) } } } @@ -144,8 +55,9 @@ class KorgeModuleConfig { } enum class ProjectType(val id: String) { - Gradle("gradle"), - GradleKotlinDsl("gradle-kotlin-dsl"); + Gradle("gradle") + //, GradleKotlinDsl("gradle-kotlin-dsl") + ; companion object { val BY_ID = values().associateBy { it.id } @@ -156,6 +68,7 @@ enum class ProjectType(val id: String) { } } +/* data class KorgeVersion( val version: String, val kotlinVersion: String, @@ -187,4 +100,4 @@ class SemVer(val version: String) : Comparable { override fun toString(): String = version } - +*/ diff --git a/src/main/kotlin/com/soywiz/korge/intellij/module/KorgeProjectTemplate.kt b/src/main/kotlin/com/soywiz/korge/intellij/module/KorgeProjectTemplate.kt index b9669c7..4e0ef6b 100644 --- a/src/main/kotlin/com/soywiz/korge/intellij/module/KorgeProjectTemplate.kt +++ b/src/main/kotlin/com/soywiz/korge/intellij/module/KorgeProjectTemplate.kt @@ -33,12 +33,14 @@ open class KorgeProjectTemplate { @set:XmlElement(name = "feature") var features = arrayListOf() + val allFeatures by lazy { AllFeatures(features) } + class Feature { @set:XmlAttribute(name = "id") var id: String = "" @set:XmlAttribute(name = "dependencies") - var dependencies: String = "" + var dependenciesString: String = "" @set:XmlAttribute(name = "name") var name: String = "" @@ -48,6 +50,26 @@ open class KorgeProjectTemplate { @set:XmlAttribute(name = "documentation") var documentation: String = "" + + @set:XmlAttribute(name = "group") + var group: String = "Features" + + val dependenciesList: List get() = dependenciesString.split(" ").filter { it.isNotBlank() } + } + + interface FeatureResolver { + fun resolve(id: String): Feature? + } + + class FeatureSet(features: Iterable, val resolver: FeatureResolver) { + val direct: Set = features.toSet() + val all: Set = direct.flatMap { it.dependenciesList.map { resolver.resolve(it) } }.filterNotNull().toSet() + val transitive: Set = (all - direct) + } + + class AllFeatures(val features: Iterable) : FeatureResolver { + val byId = features.associateBy { it.id } + override fun resolve(id: String): Feature? = byId[id] ?: features.firstOrNull { it.id == id } } } @@ -59,6 +81,9 @@ open class KorgeProjectTemplate { @set:XmlAttribute(name = "path") var path: String = "" + @set:XmlAttribute(name = "encoding") + var encoding: String = "text" + @set:XmlValue var content: String = "" } diff --git a/src/main/kotlin/com/soywiz/korge/intellij/module/wizard/KorgeModuleWizardStep.kt b/src/main/kotlin/com/soywiz/korge/intellij/module/wizard/KorgeModuleWizardStep.kt index dddc3d7..173ee4f 100644 --- a/src/main/kotlin/com/soywiz/korge/intellij/module/wizard/KorgeModuleWizardStep.kt +++ b/src/main/kotlin/com/soywiz/korge/intellij/module/wizard/KorgeModuleWizardStep.kt @@ -12,6 +12,9 @@ import java.net.* import javax.swing.* import javax.swing.tree.* +typealias Feature = KorgeProjectTemplate.Features.Feature +typealias FeatureSet = KorgeProjectTemplate.Features.FeatureSet + class KorgeModuleWizardStep(val korgeProjectTemplateProvider: KorgeProjectTemplate.Provider, val config: KorgeModuleConfig) : ModuleWizardStep() { override fun updateDataModel() { config.projectType = projectTypeCB.selectedItem as ProjectType @@ -45,21 +48,19 @@ class KorgeModuleWizardStep(val korgeProjectTemplateProvider: KorgeProjectTempla description.removeAll() if (feature != null) { description.add(JLabel(feature.description, SwingConstants.LEFT)) - for (artifact in feature.artifacts) { - description.add(JLabel(artifact)) - } + //for (artifact in feature.artifacts) description.add(JLabel(artifact)) val doc = feature.documentation - if (doc != null) { - description.add(Link(doc, URL(doc))) - } + description.add(Link(doc, URL(doc))) } description.doLayout() description.repaint() } - featureList = object : FeatureCheckboxList(Features.ALL) { + featureList = object : FeatureCheckboxList(listOf()) { override fun onSelected(feature: Feature?, node: ThreeStateCheckedTreeNode) = showFeatureDocumentation(feature) override fun onChanged(feature: Feature, node: ThreeStateCheckedTreeNode) = updateTransitive() + }.also { + it.isEnabled = false } featuresToCheckbox += featureList.featuresToCheckbox @@ -109,6 +110,8 @@ class KorgeModuleWizardStep(val korgeProjectTemplateProvider: KorgeProjectTempla runInUiThread { versionCB.model = DefaultComboBoxModel(korgeProjectTemplate.versions.versions.toTypedArray()) versionCB.isEnabled = true + featureList.features = korgeProjectTemplateProvider.template.features.features.toList() + featureList.isEnabled = true } } } @@ -129,9 +132,11 @@ class KorgeModuleWizardStep(val korgeProjectTemplateProvider: KorgeProjectTempla // } fun updateTransitive() { - val featureSet = FeatureSet(Features.ALL.filter { it.selected }) + val features = korgeProjectTemplateProvider.template.features + val allFeatures = features.features.toList() + val featureSet = FeatureSet(allFeatures.filter { it.selected }, features.allFeatures) - for (feature in Features.ALL) { + for (feature in allFeatures) { feature.indeterminate = (feature in featureSet.transitive) } @@ -148,7 +153,7 @@ open class ThreeStateCheckedTreeNode : CheckedTreeNode { var indeterminate = false } -abstract class FeatureCheckboxList(val features: List) : CheckboxTree( +abstract class FeatureCheckboxList(private val initialFeatures: List) : CheckboxTree( object : CheckboxTree.CheckboxTreeCellRenderer() { override fun customizeRenderer( tree: JTree?, @@ -167,7 +172,7 @@ abstract class FeatureCheckboxList(val features: List) : CheckboxTree( value.indeterminate -> SimpleTextAttributes.REGULAR_ITALIC_ATTRIBUTES else -> SimpleTextAttributes.REGULAR_ATTRIBUTES } - textRenderer.append(feature.title, style) + textRenderer.append(feature.name, style) textRenderer.isEnabled = true tscheckbox.isVisible = true tscheckbox.state = when { @@ -205,14 +210,25 @@ abstract class FeatureCheckboxList(val features: List) : CheckboxTree( } } - init { - for ((group, gfeatures) in features.groupBy { it.group }) { - root.add(ThreeStateCheckedTreeNode(group).apply { isChecked = false }) - for (feature in gfeatures) { - root.add(ThreeStateCheckedTreeNode(feature).apply { isChecked = false; featuresToCheckbox[feature] = this }) + private var _features: List = initialFeatures + var features: List + get() = _features + set(value) { + _features = value + root.removeAllChildren() + for ((group, gfeatures) in _features.groupBy { it.group }) { + root.add(ThreeStateCheckedTreeNode(group).apply { isChecked = false }) + for (feature in gfeatures) { + root.add(ThreeStateCheckedTreeNode(feature).apply { isChecked = false; featuresToCheckbox[feature] = this }) + } } + (this.model as DefaultTreeModel).reload(root) } - (this.model as DefaultTreeModel).reload(root) + + + + init { + features = initialFeatures addTreeSelectionListener { e -> val node = (e.newLeadSelectionPath.lastPathComponent as? ThreeStateCheckedTreeNode) diff --git a/src/main/kotlin/com/soywiz/korge/intellij/util/TemplateExt.kt b/src/main/kotlin/com/soywiz/korge/intellij/util/TemplateExt.kt new file mode 100644 index 0000000..e6392ac --- /dev/null +++ b/src/main/kotlin/com/soywiz/korge/intellij/util/TemplateExt.kt @@ -0,0 +1,13 @@ +package com.soywiz.korge.intellij.util + +import org.apache.velocity.* +import org.apache.velocity.app.* +import java.io.* + +fun renderTemplate(template: String, info: Map): String { + val writer = StringWriter() + val velocityEngine = VelocityEngine() + velocityEngine.init() + velocityEngine.evaluate(VelocityContext(info), writer, "", template) + return writer.toString() +} diff --git a/src/main/resources/com/soywiz/korge/intellij/korge-templates.xml b/src/main/resources/com/soywiz/korge/intellij/korge-templates.xml index c7748b5..be3240d 100644 --- a/src/main/resources/com/soywiz/korge/intellij/korge-templates.xml +++ b/src/main/resources/com/soywiz/korge/intellij/korge-templates.xml @@ -1,81 +1,412 @@ - - - 1.5.0d - 1.4.3 - - - - - - - - - - + + 1.5.0d + 1.4.3 + + + + + + + + + - apply plugin: "korge" + - - - - val image = image(resourcesVfs["korge.png"].readBitmap()) { - rotation = maxDegrees - anchor(.5, .5) - scale(.8) - position(256, 256) - } + - launchImmediately { - image.tween(image::rotation[minDegrees], time = 1.seconds, easing = Easing.EASE_IN_OUT) - image.tween(image::rotation[maxDegrees], time = 1.seconds, easing = Easing.EASE_IN_OUT) - } - } - ]]> - + + + + +() + val rect = solidRect(100, 100, Colors.RED) + rect.onClick { + log += "clicked" + } + assertEquals(1, views.stage.children.size) + rect.simulateClick() + assertEquals(true, rect.isVisibleToUser()) + tween(rect::x[-102], time = 10.seconds) + assertEquals(Rectangle(x=-102, y=0, width=100, height=100), rect.globalBounds) + assertEquals(false, rect.isVisibleToUser()) + assertEquals(listOf("clicked"), log) + } +} +]]> + + + + \ No newline at end of file diff --git a/src/test/kotlin/com/soywiz/korge/intellij/config/KorgeGlobalSettingsTest.kt b/src/test/kotlin/com/soywiz/korge/intellij/config/KorgeGlobalSettingsTest.kt new file mode 100644 index 0000000..19cd510 --- /dev/null +++ b/src/test/kotlin/com/soywiz/korge/intellij/config/KorgeGlobalSettingsTest.kt @@ -0,0 +1,14 @@ +package com.soywiz.korge.intellij.config + +import kotlin.test.* + +class KorgeGlobalSettingsTest { + @Test + fun test() { + assertEquals(+1, KorgeGlobalSettings.compareKorgeTemplateVersion("", "")) + assertEquals(-1, KorgeGlobalSettings.compareKorgeTemplateVersion("", "")) + assertEquals(0, KorgeGlobalSettings.compareKorgeTemplateVersion("", "")) + assertEquals(+1, KorgeGlobalSettings.compareKorgeTemplateVersion("", "")) + assertEquals(-1, KorgeGlobalSettings.compareKorgeTemplateVersion("", "")) + } +} \ No newline at end of file diff --git a/src/test/kotlin/com/soywiz/korge/intellij/util/TemplateExtTest.kt b/src/test/kotlin/com/soywiz/korge/intellij/util/TemplateExtTest.kt new file mode 100644 index 0000000..d4d5e8f --- /dev/null +++ b/src/test/kotlin/com/soywiz/korge/intellij/util/TemplateExtTest.kt @@ -0,0 +1,10 @@ +package com.soywiz.korge.intellij.util + +import kotlin.test.* + +class TemplateExtTest { + @Test + fun test() { + assertEquals("hello world", renderTemplate("hello \$hello", mapOf("hello" to "world"))) + } +} \ No newline at end of file