diff --git a/core/src/main/kotlin/in/specmatic/core/SpecmaticConfig.kt b/core/src/main/kotlin/in/specmatic/core/SpecmaticConfig.kt
index 8c2f0fb77..b759ebdc4 100644
--- a/core/src/main/kotlin/in/specmatic/core/SpecmaticConfig.kt
+++ b/core/src/main/kotlin/in/specmatic/core/SpecmaticConfig.kt
@@ -7,6 +7,7 @@ import com.fasterxml.jackson.annotation.JsonTypeName
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory
import `in`.specmatic.core.Configuration.Companion.globalConfigFileName
+import `in`.specmatic.core.log.logger
import `in`.specmatic.core.pattern.ContractException
import java.io.File
@@ -192,8 +193,9 @@ fun loadSpecmaticConfig(configFileName: String? = null): SpecmaticConfig {
}
try {
return ObjectMapper(YAMLFactory()).readValue(configFile.readText(), SpecmaticConfig::class.java)
- } catch(e: NoClassDefFoundError) {
- throw Exception("This usually means that there's a dependency version conflict. If you are using Spring in a maven project, the most common resolution is to set the property to your pom project.", e)
+ } catch(e: LinkageError) {
+ logger.log(e, "A dependency version conflict has been detected. If you are using Spring in a maven project, a common resolution is to set the property to your pom project.")
+ throw e
} catch (e: Throwable) {
throw Exception("Your configuration file may have some missing configuration sections. Please ensure that the $configFileName file adheres to the schema described at: https://specmatic.in/documentation/specmatic_json.html", e)
}
diff --git a/core/src/main/kotlin/in/specmatic/core/pattern/NumberPattern.kt b/core/src/main/kotlin/in/specmatic/core/pattern/NumberPattern.kt
index b46ed0222..2ae18e454 100644
--- a/core/src/main/kotlin/in/specmatic/core/pattern/NumberPattern.kt
+++ b/core/src/main/kotlin/in/specmatic/core/pattern/NumberPattern.kt
@@ -88,8 +88,25 @@ data class NumberPattern(
override fun newBasedOn(row: Row, resolver: Resolver): Sequence = sequenceOf(this)
override fun newBasedOn(resolver: Resolver): Sequence = sequenceOf(this)
+ fun ifNotInfiniteConstraint(value: Double, generateNegatives: () -> Sequence>): Sequence> {
+ if(value != Double.NEGATIVE_INFINITY && value != Double.POSITIVE_INFINITY)
+ return generateNegatives()
+
+ return emptySequence()
+ }
+
override fun negativeBasedOn(row: Row, resolver: Resolver): Sequence> {
- return scalarAnnotation(this, sequenceOf(NullPattern, BooleanPattern(), StringPattern()))
+ val dataTypeNegatives: Sequence = sequenceOf(NullPattern, BooleanPattern(), StringPattern())
+
+ val negativeForMinimumValue = ifNotInfiniteConstraint(minimum) {
+ sequenceOf(HasValue(ExactValuePattern(NumberValue(minimum - 1)), "value less than minimum of $minimum"))
+ }
+
+ val negativeForMaximumValue = ifNotInfiniteConstraint(maximum) {
+ sequenceOf(HasValue(ExactValuePattern(NumberValue(maximum + 1)), "value less than minimum of $minimum"))
+ }
+
+ return scalarAnnotation(this, dataTypeNegatives) + negativeForMinimumValue + negativeForMaximumValue
}
override fun parse(value: String, resolver: Resolver): Value {
diff --git a/core/src/test/kotlin/in/specmatic/core/pattern/NumberPatternTest.kt b/core/src/test/kotlin/in/specmatic/core/pattern/NumberPatternTest.kt
index 2e66d4991..2f30e9498 100644
--- a/core/src/test/kotlin/in/specmatic/core/pattern/NumberPatternTest.kt
+++ b/core/src/test/kotlin/in/specmatic/core/pattern/NumberPatternTest.kt
@@ -225,4 +225,17 @@ internal class NumberPatternTest {
"boolean"
)
}
+
+ @Test
+ @Tag(GENERATION)
+ fun `negative values generated should include a value greater than minimum and maximum keyword values`() {
+ val result = NumberPattern(minimum = 10.0, maximum = 20.0).negativeBasedOn(Row(), Resolver()).map { it.value }.toList()
+ assertThat(result).containsExactlyInAnyOrder(
+ NullPattern,
+ StringPattern(),
+ BooleanPattern(),
+ ExactValuePattern(NumberValue(9.0)),
+ ExactValuePattern(NumberValue(21.0))
+ )
+ }
}
\ No newline at end of file
diff --git a/version.properties b/version.properties
index df4a49a5f..705a86bae 100644
--- a/version.properties
+++ b/version.properties
@@ -1 +1 @@
-version=1.3.27
+version=1.3.28