From d78393e0a5c65d9320bda3288da28d364d606c15 Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Wed, 19 Apr 2017 02:18:02 -0700 Subject: [PATCH] Added tests. --- example/kobalt/src/Build.kt | 8 +- kobalt/src/Build.kt | 2 +- .../plugin/propertyfile/PropertyFilePlugin.kt | 140 +---------- .../erik/kobalt/plugin/propertyfile/Utils.kt | 179 ++++++++++++++ .../kobalt/plugin/propertyfile/UtilsTest.kt | 230 ++++++++++++++++++ 5 files changed, 419 insertions(+), 140 deletions(-) create mode 100644 src/main/kotlin/net/thauvin/erik/kobalt/plugin/propertyfile/Utils.kt create mode 100644 src/test/kotlin/net/thauvin/erik/kobalt/plugin/propertyfile/UtilsTest.kt diff --git a/example/kobalt/src/Build.kt b/example/kobalt/src/Build.kt index ce46144..7dd817d 100644 --- a/example/kobalt/src/Build.kt +++ b/example/kobalt/src/Build.kt @@ -8,7 +8,7 @@ import net.thauvin.erik.kobalt.plugin.propertyfile.* val bs = buildScript { plugins(file("../kobaltBuild/libs/kobalt-property-file-0.9.0.jar")) - // plugins("net.thauvin.erik:kobalt-property-file:") + //plugins("net.thauvin.erik:kobalt-property-file:") } val p = project { @@ -37,7 +37,9 @@ val p = project { // parameters file = "version.properties" comment = "##Generated file - do not modify!" - // failOnWarning = true + + //failOnWarning = true + //entry(key = "version.fail", value = "a", type = Types.INT) // Version properties with patch increment entry(key = "version.major", value = "1") @@ -51,7 +53,7 @@ val p = project { entry(key = "date.nextMonth", value = "now", type = Types.DATE) entry(key = "date.nextMonth", value = "0", type = Types.DATE, unit = Units.MONTH, operation = Operations.ADD) - // examples from: https://ant.apache.org/manual/Tasks/propertyfile.html + // Examples from: https://ant.apache.org/manual/Tasks/propertyfile.html entry(key = "akey", value = "avalue") entry(key = "adate", type = Types.DATE, value = "now") entry(key = "anint", type = Types.INT, default = "0", operation = Operations.ADD) diff --git a/kobalt/src/Build.kt b/kobalt/src/Build.kt index e31f98a..de3cd0b 100644 --- a/kobalt/src/Build.kt +++ b/kobalt/src/Build.kt @@ -44,7 +44,7 @@ val p = project { } dependenciesTest { - //compile("org.testng:testng:6.11") + compile("org.testng:testng:6.11") } assemble { diff --git a/src/main/kotlin/net/thauvin/erik/kobalt/plugin/propertyfile/PropertyFilePlugin.kt b/src/main/kotlin/net/thauvin/erik/kobalt/plugin/propertyfile/PropertyFilePlugin.kt index 6dcdc14..69abdb2 100644 --- a/src/main/kotlin/net/thauvin/erik/kobalt/plugin/propertyfile/PropertyFilePlugin.kt +++ b/src/main/kotlin/net/thauvin/erik/kobalt/plugin/propertyfile/PropertyFilePlugin.kt @@ -43,23 +43,12 @@ import com.google.inject.Singleton import java.io.FileOutputStream import java.nio.file.Files import java.nio.file.Paths -import java.text.* import java.util.* @Singleton class PropertyFilePlugin @Inject constructor(val configActor: ConfigActor, val taskContributor: TaskContributor) : BasePlugin(), ITaskContributor, IConfigActor by configActor { - private val calendarFields = mapOf( - Units.MILLISECOND to Calendar.MILLISECOND, - Units.SECOND to Calendar.SECOND, - Units.MINUTE to Calendar.MINUTE, - Units.HOUR to Calendar.HOUR_OF_DAY, - Units.DAY to Calendar.DATE, - Units.WEEK to Calendar.WEEK_OF_YEAR, - Units.MONTH to Calendar.MONTH, - Units.YEAR to Calendar.YEAR - ) // ITaskContributor override fun tasksFor(project: Project, context: KobaltContext): List { @@ -114,9 +103,9 @@ class PropertyFilePlugin @Inject constructor(val configActor: ConfigActor success = processDate(p, entry) - Types.INT -> success = processInt(p, entry) - else -> success = processString(p, entry) + Types.DATE -> success = Utils.processDate(p, entry) + Types.INT -> success = Utils.processInt(p, entry) + else -> success = Utils.processString(p, entry) } } } @@ -136,127 +125,6 @@ class PropertyFilePlugin @Inject constructor(val configActor: ConfigActorUtils class. + * + * @author Erik C. Thauvin + * @created 2017-04-18 + * @since 1.0 + */ +class Utils { + companion object { + private val calendarFields = mapOf( + Units.MILLISECOND to Calendar.MILLISECOND, + Units.SECOND to Calendar.SECOND, + Units.MINUTE to Calendar.MINUTE, + Units.HOUR to Calendar.HOUR_OF_DAY, + Units.DAY to Calendar.DATE, + Units.WEEK to Calendar.WEEK_OF_YEAR, + Units.MONTH to Calendar.MONTH, + Units.YEAR to Calendar.YEAR + ) + + fun processDate(p: Properties, entry: Entry): Boolean { + var success = true + val cal = Calendar.getInstance() + val value = Utils.currentValue(p.getProperty(entry.key), entry.value, entry.default, entry.operation) + + val fmt = SimpleDateFormat(if (entry.pattern.isBlank()) "yyyy-MM-dd HH:mm" else entry.pattern) + + if (value.equals("now", true) || value.isBlank()) { + cal.time = Date() + } else { + try { + cal.time = fmt.parse(value) + } catch (pe: ParseException) { + warn("Date parse exception for: ${entry.key}", pe) + success = false + } + } + + if (entry.operation != Operations.SET) { + var offset = 0 + + try { + offset = entry.value!!.toInt() + if (entry.operation == Operations.SUBTRACT) { + offset *= -1 + } + } catch (nfe: NumberFormatException) { + warn("Non-integer value for: ${entry.key}") + success = false + } + + cal.add(calendarFields.getOrDefault(entry.unit, Calendar.DATE), offset) + } + + p.setProperty(entry.key, fmt.format(cal.time)) + + return success + } + + fun processInt(p: Properties, entry: Entry): Boolean { + var success = true + var intValue: Int + try { + val fmt = DecimalFormat(entry.pattern) + val value = Utils.currentValue(p.getProperty(entry.key), entry.value, entry.default, entry.operation) + + intValue = fmt.parse(if (value.isBlank()) "0" else value).toInt() + + if (entry.operation != Operations.SET) { + var opValue = 1 + if (entry.value != null) { + opValue = fmt.parse(entry.value).toInt() + } + if (entry.operation == Operations.ADD) { + intValue += opValue + } else if (entry.operation == Operations.SUBTRACT) { + intValue -= opValue + } + } + + p.setProperty(entry.key, fmt.format(intValue)) + } catch (nfe: NumberFormatException) { + warn("Number format exception for: ${entry.key}", nfe) + success = false + } catch (pe: ParseException) { + warn("Number parsing exception for: ${entry.key}", pe) + success = false + } + + return success + } + + fun processString(p: Properties, entry: Entry): Boolean { + val value = Utils.currentValue(p.getProperty(entry.key), entry.value, entry.default, entry.operation) + + if (entry.operation == Operations.SET) { + p.setProperty(entry.key, value) + } else if (entry.operation == Operations.ADD) { + if (entry.value != null) { + p.setProperty(entry.key, "$value${entry.value}") + } + } + + return true + } + + fun currentValue(value: String?, newValue: String?, default: String?, operation: Operations): String { + var result: String? = null + + if (operation == Operations.SET) { + if (newValue != null && default == null) { + result = newValue + } + if (default != null) { + if (newValue == null && value != null) { + result = value + } + + if (newValue == null && value == null) { + result = default + } + + if (newValue != null && value != null) { + result = newValue + } + + if (newValue != null && value == null) { + result = default + } + } + } else { + result = value ?: default + } + + if (result == null) { + result = "" + } + + return result + } + } +} \ No newline at end of file diff --git a/src/test/kotlin/net/thauvin/erik/kobalt/plugin/propertyfile/UtilsTest.kt b/src/test/kotlin/net/thauvin/erik/kobalt/plugin/propertyfile/UtilsTest.kt new file mode 100644 index 0000000..8b42bd3 --- /dev/null +++ b/src/test/kotlin/net/thauvin/erik/kobalt/plugin/propertyfile/UtilsTest.kt @@ -0,0 +1,230 @@ +/* + * UtilsTest.kt + * + * Copyright (c) 2017, Erik C. Thauvin (erik@thauvin.net) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of this project nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.thauvin.erik.kobalt.plugin.propertyfile + +import org.testng.Assert +import org.testng.annotations.Test +import java.text.SimpleDateFormat +import java.util.* + +@Test +class UtilsTest { + val p = Properties() + + @Test + fun currentValueTest() { + var prev : String? + var value: String? + var default: String? = null + var operation = Operations.SET + + + // If only value is specified, the property is set to it regardless of its previous value. + prev = "previous" + value = "value" + Assert.assertEquals(Utils.currentValue(prev, value, default, operation), value, + "currentValue($prev,$value,$default,$operation)") + + // If only default is specified and the property previously existed, it is unchanged. + prev = "previous" + value = null + default = "default" + Assert.assertEquals(Utils.currentValue(prev, value, default, operation), prev, + "currentValue($prev,$value,$default,$operation)") + + // If only default is specified and the property did not exist, the property is set to default. + prev = null + value = null + default = "default" + Assert.assertEquals(Utils.currentValue(prev, value, default, operation), default, + "currentValue($prev,$value,$default,$operation)") + + // If value and default are both specified and the property previously existed, the property is set to value. + prev = "previous" + value ="value" + default = "default" + Assert.assertEquals(Utils.currentValue(prev, value, default, operation), value, + "currentValue($prev,$value,$default,$operation)") + + // If value and default are both specified and the property did not exist, the property is set to default. + prev = null + value = "value" + default ="default" + Assert.assertEquals(Utils.currentValue(prev, value, default, operation), default, + "currentValue($prev,$value,$default,$operation)") + + // ADD + operation = Operations.ADD + + prev = null + value = "value" + default = "default" + Assert.assertEquals(Utils.currentValue(prev, value, default, operation), default, + "currentValue($prev,$value,$default,$operation)") + + prev = "prev" + value = "value" + default = null + Assert.assertEquals(Utils.currentValue(prev, value, default, operation), prev, + "currentValue($prev,$value,$default,$operation)") + + prev = null + value = "value" + default = null + Assert.assertEquals(Utils.currentValue(prev, value, default, operation), "", + "currentValue($prev,$value,$default,$operation)") + + prev = null + value = "value" + default = "default" + Assert.assertEquals(Utils.currentValue(prev, value, default, operation), default, + "currentValue($prev,$value,$default,$operation)") + + prev = null + value = null + default = null + Assert.assertEquals(Utils.currentValue(prev, value, default, operation), "", + "currentValue($prev,$value,$default,$operation)") + } + + @Test + fun processStringTest() { + val entry = Entry() + + entry.key = "version.major" + entry.value = "1" + + Utils.processString(p, entry) + Assert.assertEquals(entry.value, p.getProperty(entry.key), "processString(${entry.key}, ${entry.value})") + + entry.key = "version.minor" + entry.value = "0" + + Utils.processString(p, entry) + Assert.assertEquals(entry.value, p.getProperty(entry.key), "processString(${entry.key}, ${entry.value})") + } + + @Test + fun processIntTest() { + val entry = Entry() + entry.type = Types.INT + + entry.key = "version.patch" + + entry.value = "a" + Assert.assertFalse(Utils.processInt(p, entry), "parsetInt(${entry.key}, a)") + + // ADD + entry.operation = Operations.ADD + + entry.value = "1" + entry.default = "-1" + Utils.processInt(p, entry) + Assert.assertEquals("0", p.getProperty(entry.key), "processInt(${entry.key}, 0)") + + entry.key = "anint" + entry.value = null + entry.default = "0" + Utils.processInt(p, entry) + Assert.assertEquals("1", p.getProperty(entry.key), "processInt(${entry.key}, 1)") + Utils.processInt(p, entry) + Assert.assertEquals("2", p.getProperty(entry.key), "processInt(${entry.key}, 2)") + + entry.key = "formated.int" + entry.value = null + entry.default = "0013" + entry.pattern = "0000" + Utils.processInt(p, entry) + Assert.assertEquals("0014", p.getProperty(entry.key), "processInt(${entry.key}, 0014)") + Utils.processInt(p, entry) + Assert.assertEquals("0015", p.getProperty(entry.key), "processInt(${entry.key}, 0015)") + + entry.key = "formated.int" + entry.value = "2" + entry.default = "0013" + entry.pattern = "0000" + Utils.processInt(p, entry) + Assert.assertEquals("0017", p.getProperty(entry.key), "processInt(${entry.key}, 0017)") + + // SUBTRACT + entry.operation = Operations.SUBTRACT + entry.value = null + entry.default = "0013" + entry.pattern = "0000" + Utils.processInt(p, entry) + Assert.assertEquals("0016", p.getProperty(entry.key), "processInt(${entry.key}, 0016)") + + } + + @Test + fun processDateTest() { + val entry = Entry() + entry.type = Types.DATE + entry.pattern = "D" + entry.key = "adate" + + val day = SimpleDateFormat(entry.pattern).format(Date()).toInt() + + entry.value = "a" + Assert.assertFalse(Utils.processDate(p, entry), "processDate(${entry.key}, a)") + + entry.value = "99" + Utils.processDate(p, entry) + Assert.assertEquals("99", p.getProperty(entry.key), "processDate(${entry.key}, 99)") + + entry.value = "now" + Utils.processDate(p, entry) + Assert.assertEquals("$day", p.getProperty(entry.key), "processDate(${entry.key}, now)") + + // ADD + entry.operation = Operations.ADD + + entry.value = "1" + Utils.processDate(p, entry) + Assert.assertEquals("${day+1}", p.getProperty(entry.key), "processDate(${entry.key}, now+1)") + + entry.value = "2" + Utils.processDate(p, entry) + Assert.assertEquals("${day+3}", p.getProperty(entry.key), "processDate(${entry.key}, now+3)") + + // SUBTRACT + entry.operation = Operations.SUBTRACT + entry.value = "3" + Utils.processDate(p, entry) + Assert.assertEquals("$day", p.getProperty(entry.key), "processDate(${entry.key}, now-3)") + + entry.operation = Operations.SUBTRACT + entry.value = "2" + Utils.processDate(p, entry) + Assert.assertEquals("${day-2}", p.getProperty(entry.key), "processDate(${entry.key}, now-2)") + } +} \ No newline at end of file