Skip to content

Commit

Permalink
Add kotest and property-based tests for number formatting.
Browse files Browse the repository at this point in the history
Found some nice corner cases, like handling of e.g. PLUS_INFINITY or -0.0
  • Loading branch information
jedesroches committed Nov 15, 2023
1 parent e39f3a5 commit ef10fc4
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 62 deletions.
4 changes: 2 additions & 2 deletions plugin/.run/Run Tests.run.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
</option>
<option name="taskNames">
<list>
<option value=":plugin:test" />
<option value="test" />
</list>
</option>
<option name="vmOptions" value="" />
Expand All @@ -22,4 +22,4 @@
<RunAsTest>false</RunAsTest>
<method v="2" />
</configuration>
</component>
</component>
16 changes: 15 additions & 1 deletion plugin/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@

import org.gradle.api.tasks.testing.logging.TestLogEvent
import org.jetbrains.changelog.Changelog
import org.jetbrains.changelog.markdownToHTML
import task.GenerateEmissionFactorsTask30
Expand Down Expand Up @@ -59,6 +60,11 @@ dependencies {

testImplementation("io.mockk:mockk:1.13.4")
testImplementation(kotlin("test-junit"))
testRuntimeOnly("org.junit.vintage:junit-vintage-engine")

val kotestVersion = "5.7.2"
testImplementation("io.kotest:kotest-runner-junit5-jvm:$kotestVersion")
testImplementation("io.kotest:kotest-property-jvm:$kotestVersion")
}


Expand Down Expand Up @@ -110,6 +116,13 @@ tasks {
dependsOn("generateEmissionFactors31")
}

test {
useJUnitPlatform()
testLogging {
events = setOf(TestLogEvent.FAILED, TestLogEvent.PASSED, TestLogEvent.SKIPPED)
}
}

patchPluginXml {
version.set(pluginVersion)
sinceBuild.set(properties("pluginSinceBuild"))
Expand Down Expand Up @@ -162,7 +175,8 @@ tasks {
// pluginVersion is based on the SemVer (https://semver.org) and supports pre-release labels, like 2.1.7-alpha.3
// Specify pre-release label to publish the plugin in a custom Release Channel automatically. Read more:
// https://plugins.jetbrains.com/docs/intellij/deployment.html#specifying-a-release-channel
channels.set(listOf(pluginVersion.split('-').getOrElse(1) { "default" }.split('.').first()))
val channel = listOf(pluginVersion.split('-').getOrElse(1) { "default" }.split('.').first())
channels.set(channel)
}

clean {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,66 +1,40 @@
package ch.kleis.lcaac.plugin.ui.toolwindow.shared

import org.junit.Assert
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
import io.kotest.core.names.DuplicateTestNameMode
import io.kotest.core.spec.style.DescribeSpec
import io.kotest.matchers.shouldBe
import io.kotest.matchers.string.shouldMatch
import io.kotest.property.assume
import io.kotest.property.checkAll
import kotlin.math.abs

@RunWith(Parameterized::class)
class QuantityRendererTest(
private val value: Double,
private val expected: String,
) {
companion object {
@Parameterized.Parameters
@JvmStatic
fun getDisplayedStrings(): Collection<Array<Any>> {
return listOf(
arrayOf(0.0, "0"),
arrayOf(0.0001, "1E-4"),
arrayOf(0.001, "1E-3"),
arrayOf(0.01, "1E-2"),
arrayOf(0.1, "1E-1"),
arrayOf(1.0, "1"),
arrayOf(10.0, "1E1"),
arrayOf(100.0, "1E2"),
arrayOf(1000.0, "1E3"),

arrayOf(0.000999, "9.99E-4"),
arrayOf(0.00999, "9.99E-3"),
arrayOf(0.0999, "9.99E-2"),
arrayOf(0.999, "9.99E-1"),
arrayOf(9.99, "9.99"),
arrayOf(99.9, "9.99E1"),
arrayOf(999.0, "9.99E2"),

arrayOf(0.00123, "1.23E-3"),
arrayOf(0.0123, "1.23E-2"),
arrayOf(0.123, "1.23E-1"),
arrayOf(1.2345, "1.23"),
arrayOf(12.345, "1.23E1"),
arrayOf(123.45, "1.23E2"),
arrayOf(1234.5, "1.23E3"),
arrayOf(12345.123, "1.23E4"),

arrayOf(-0.0, "0"),
arrayOf(-0.00123, "-1.23E-3"),
arrayOf(-0.0123, "-1.23E-2"),
arrayOf(-0.123, "-1.23E-1"),
arrayOf(-1.2345, "-1.23"),
arrayOf(-12.345, "-1.23E1"),
arrayOf(-123.45, "-1.23E2"),
arrayOf(-1234.5, "-1.23E3"),
arrayOf(-12345.123, "-1.23E4"),
)
class QuantityRendererTest : DescribeSpec({
duplicateTestNameMode = DuplicateTestNameMode.Silent
describe("QuantityRenderer") {
// Properties
it("should use scientific notation with 3 significant digits for values not in [-10;-1[U]1;10]") {
val notationRegex = Regex("-?([0-9](\\.[0-9]{1,2})?(E-?[1-9][0-9]*)?|∞)")
checkAll<Double> { value ->
assume(abs(value).let { it >= 10 || it > 1})
QuantityRenderer.formatDouble(value) shouldMatch notationRegex
}
}
it("should not display an exponent part for values in [-10;-1[U]1;10]") {
val notationRegex = Regex("-?[0-9](\\.[0-9]{1,2})?")
checkAll<Double> { value ->
assume(abs(value).let { it < 10 && it >= 1})
QuantityRenderer.formatDouble(value) shouldMatch notationRegex
}
}
}

@Test
fun run() {
// when
val actual = QuantityRenderer.formatDouble(value)
// Non-regression of corner cases found by fuzzing
it("should properly encode infinities") {
QuantityRenderer.formatDouble(Double.POSITIVE_INFINITY) shouldBe ""
QuantityRenderer.formatDouble(Double.NEGATIVE_INFINITY) shouldBe "-∞"
}

// then
Assert.assertEquals(expected, actual)
it("should properly deal with -0.0") {
QuantityRenderer.formatDouble(-0.0) shouldBe "0"
}
}
}
})

0 comments on commit ef10fc4

Please sign in to comment.