Skip to content

Commit

Permalink
number in range matcher added
Browse files Browse the repository at this point in the history
  • Loading branch information
danseid committed Nov 26, 2012
1 parent 366d99b commit 414ef23
Show file tree
Hide file tree
Showing 8 changed files with 230 additions and 89 deletions.
9 changes: 9 additions & 0 deletions README.md
Expand Up @@ -75,6 +75,15 @@ Matchers to use on number objects like Int, Float, Double ...
1 should !be lte 0 //✔
1 should !be lte 1 //✘
1 should be lte 0 //✘
#### be | !be in range()
1 should be in range(1..2) //✔
1 should be in range(1.0..2.0) //✔
1.1 should be in range(1..2) //✔
1 should !be in range(1.1..2.0) //✔
1.0 should !be in range(1.1..2.0) //✔
1.99 should !be in range(2..3) //✔
1.99 should !be in range(1.991..1.992) //✔
1 should !be in range(0.9..0.99); //✔

###String
Matchers to use on string objects
Expand Down
118 changes: 34 additions & 84 deletions src/main/kotlin/org/katchers/NumberMatcher.kt
Expand Up @@ -22,34 +22,32 @@ package org.katchers


class NumberBeMatcher(target: jet.Number): AnyBeMatcher<Number>(target){

inline fun gt(value: Number) = greaterThan(value)
inline fun gte(value: Number) = greaterOrEqualThan(value)
inline fun lt(value: Number) = lessThan(value)
inline fun lte(value: Number) = lessOrEqualThan(value)

fun greaterThan(value: jet.Number) {

inline fun greaterThan(value: jet.Number) {
when {
target == value -> fail("$target > $value", "$target == $value")
target compare value < 0 -> fail("$target > $value", "$target < $value")
else -> return
}
}

fun greaterOrEqualThan(value: Number) = if(target compare value < 0) fail("$target >= $value", "$target < $value")
inline fun greaterOrEqualThan(value: Number) = if(target compare value < 0) fail("$target >= $value", "$target < $value")

fun lessThan(value: Number) {
inline fun lessThan(value: Number) {
when {
target == value -> fail("$target < $value", "$target == $value")
target compare value > 0 -> fail("$target < $value", "$target > $value")
else -> return
}
}

fun lessOrEqualThan(value: Number) = if(target compare value > 0) fail("$target <= $value", "$target > $value")
inline fun lessOrEqualThan(value: Number) = if(target compare value > 0) fail("$target <= $value", "$target > $value")

fun inRange(val r: IntRange) {
inline fun inRange(val r: IntRange) {
if (target !in r) fail("$target should be in [${r.start},${r.end}]", "$target is not in [${r.start},${r.end}]")
}

Expand All @@ -62,19 +60,21 @@ class NumberNotBeMatcher(target: Number): AnyNotBeMatcher<Number>(target){
inline fun lt(value: Number) = lessThan(value)
inline fun lte(value: Number) = lessOrEqualThan(value)

fun greaterThan(value: Number) = if(target compare value > 0) fail("!($target > $value)", "$target > $value")
inline fun greaterThan(value: Number) = if(target compare value > 0) {
fail("!($target > $value)", "$target > $value")
}

fun greaterOrEqualThan(value: Number) {
inline fun greaterOrEqualThan(value: Number) {
when {
target == value -> fail("!($target >= $value)", "$target == $value")
target compare value > 0 -> fail("!($target >= $value)", "$target > $value")
else -> return
}
}

fun lessThan(value: Number) = if(target compare value < 0) fail("!($target < $value)", "$target < $value")
inline fun lessThan(value: Number) = if(target compare value < 0) fail("!($target < $value)", "$target < $value")

fun lessOrEqualThan(value: Number) {
inline fun lessOrEqualThan(value: Number) {
when {
target == value -> fail("!($target <= $value)", "$target == $value")
target compare value < 0 -> fail("!($target <= $value)", "$target < $value")
Expand All @@ -83,81 +83,31 @@ class NumberNotBeMatcher(target: Number): AnyNotBeMatcher<Number>(target){
}
}

/**
* compares Number with another Number. This function is using Double.compareTo function
*/

fun Number.compare(that: Number): Int {
when(this){
is Int -> {
val it = this as Int
when(that){
is Double -> return (it.compareTo(that as Double))
is Float -> return (it.compareTo(that as Float))
is Long -> return (it.compareTo(that as Long))
is Int -> return (it.compareTo(that as Int))
is Short -> return (it.compareTo(that as Short))
is Byte -> return (it.compareTo(that as Byte))
else -> throw ClassCastException()
}
}
is Double -> {
val it = this as Double
when(that){
is Double -> return (it.compareTo(that as Double))
is Float -> return (it.compareTo(that as Float))
is Long -> return (it.compareTo(that as Long))
is Int -> return (it.compareTo(that as Int))
is Short -> return (it.compareTo(that as Short))
is Byte -> return (it.compareTo(that as Byte))
else -> throw ClassCastException()
}
fun compare(d: Double, n: Number): Int {
return when(n){
is Double -> d.compareTo(n)
is Float -> d.compareTo(n)
is Long -> d.compareTo(n)
is Int -> d.compareTo(n)
is Short -> d.compareTo(n)
is Byte -> d.compareTo(n)
else -> throw ClassCastException()
}
is Long -> {
val it = this as Long
when(that){
is Double -> return (it.compareTo(that as Double))
is Float -> return (it.compareTo(that as Float))
is Long -> return (it.compareTo(that as Long))
is Int -> return (it.compareTo(that as Int))
is Short -> return (it.compareTo(that as Short))
is Byte -> return (it.compareTo(that as Byte))
else -> throw ClassCastException()
}
}
is Float -> {
val it = this as Float
when(that){
is Double -> return (it.compareTo(that as Double))
is Float -> return (it.compareTo(that as Float))
is Long -> return (it.compareTo(that as Long))
is Int -> return (it.compareTo(that as Int))
is Short -> return (it.compareTo(that as Short))
is Byte -> return (it.compareTo(that as Byte))
else -> throw ClassCastException()
}
}
is Short -> {
val it = this as Short
when(that){
is Double -> return (it.compareTo(that as Double))
is Float -> return (it.compareTo(that as Float))
is Long -> return (it.compareTo(that as Long))
is Int -> return (it.compareTo(that as Int))
is Short -> return (it.compareTo(that as Short))
is Byte -> return (it.compareTo(that as Byte))
else -> throw ClassCastException()
}
}
is Byte -> {
val it = this as Byte
when(that){
is Double -> return (it.compareTo(that as Double))
is Float -> return (it.compareTo(that as Float))
is Long -> return (it.compareTo(that as Long))
is Int -> return (it.compareTo(that as Int))
is Short -> return (it.compareTo(that as Short))
is Byte -> return (it.compareTo(that as Byte))
else -> throw ClassCastException()
}
}
else -> throw ClassCastException()
}

return when(this){ // casting toDouble because of http://youtrack.jetbrains.com/issue/KT-3078
is Int -> compare(this.toDouble(), that)
is Double -> compare(this, that)
is Long -> compare(this.toDouble(), that)
is Float -> compare(this.toDouble(), that)
is Short -> compare(this.toDouble(), that)
is Byte -> compare(this.toDouble(), that)
else -> throw ClassCastException()
}
}

Expand Down
67 changes: 67 additions & 0 deletions src/main/kotlin/org/katchers/NumberRangesMatcher.kt
@@ -0,0 +1,67 @@
/*
* Copyright 2012 Daniel Seidler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.katchers

/**
* @author Daniel Seidler
* @since 2012/11/22
* NumberRangesMatcher use the "in" syntax of Kotlin
*/

fun range(r: IntRange) = NumberIntRange(r)
fun range(r: LongRange) = NumberLongRange(r)
fun range(r: FloatRange) = NumberFloatRange(r)
fun range(r: DoubleRange) = NumberDoubleRange(r)

trait NumberRange {
open val start: Number;
open val end: Number;
fun inRange(n: Number): Boolean = n.compare(start) >= 0 && n.compare(end) <= 0
fun contains(n: NumberBeMatcher): Boolean {
if(!inRange(n.target)) {
fail("${n.target} should be in ($start, $end)", "${n.target} is not in ($start, $end)")
return false
}
else return true
}
fun contains(n: NumberNotBeMatcher): Boolean {
if(inRange(n.target)) {
fail("${n.target} should not be in ($start, $end)", "${n.target} is in ($start, $end)")
return false
}
else return true
}
}

class NumberIntRange(val r: IntRange): NumberRange{
override val start = r.start;
override val end = r.end;
}

class NumberLongRange(val r: LongRange): NumberRange{
override val start = r.start;
override val end = r.end;
}

class NumberFloatRange(val r: FloatRange): NumberRange{
override val start = r.start;
override val end = r.end;
}

class NumberDoubleRange(val r: DoubleRange): NumberRange{
override val start = r.start;
override val end = r.end;
}
4 changes: 3 additions & 1 deletion src/test/kotlin/AllTest.kt
Expand Up @@ -27,6 +27,8 @@ Suite.SuiteClasses(
javaClass<ShouldTest>(),
javaClass<MustTest>(),
javaClass<FunctionMatcherTest>(),
javaClass<NumberMatcherTest>()
javaClass<NumberMatcherTest>(),
javaClass<NumbersTest>(),
javaClass<NumberRangesMatcherTest>()
)
public class AllTest {}
4 changes: 0 additions & 4 deletions src/test/kotlin/AnyMatchersTest.kt
Expand Up @@ -22,10 +22,6 @@ import org.katchers.*

public class AnyMatchersTest {
test fun integers() {
for(f in 1..2.0){

}

1 should be equal 1
1 should !be equal 2

Expand Down
13 changes: 13 additions & 0 deletions src/test/kotlin/NumberMatcherTest.kt
Expand Up @@ -33,6 +33,10 @@ public class NumberMatcherTest {
1 should be gt 0.9
0.9 should !be gt 1

{ 0.9 should be gt 1 } should fail with assertionError;
{ 1 should be gt 1.1 } should fail with assertionError;
{ 1.1 should !be gt 1 } should fail with assertionError;
{ 1 should !be gt 0.9 } should fail with assertionError;


}
Expand All @@ -48,6 +52,15 @@ public class NumberMatcherTest {
{ 1 should !be gte 1 } should fail with assertionError;
{ 1 should !be gte 0 } should fail with assertionError;
{ 1 should !be gte 2 } should !fail with assertionError;

1.0 should be gte 1
1.1 should be gte 1
1 should be gte 0.9
1 should be gte 1
1.0 should be gte 1.0
1.0 should be gte 0.9


}

test fun shouldBeLessThan() {
Expand Down
47 changes: 47 additions & 0 deletions src/test/kotlin/NumberRangesMatcherTest.kt
@@ -0,0 +1,47 @@
/*
* Copyright 2012 Daniel Seidler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.junit.Test as test
import org.katchers.*

/**
* @author Daniel Seidler
* @since 2012/11/23
*/
public class NumberRangesMatcherTest {

test fun shouldBeInRange() {
1 should be in range(1..2)
1 should be in range(1.0..2.0)
1.1 should be in range(1..2)
1.1 should be in range(1.0..2.0)
1 should be in range(0.9..1.1);
{1 should be in range(1.1..1.2)} should fail with assertionError;
{1.09 should be in range(1.1..1.2)} should fail with assertionError
{1.201 should be in range(1.1..1.2)} should fail with assertionError
}

test fun shouldNotBeInRange() {
1 should !be in range(1.1..2.0)
1.0 should !be in range(1.1..2.0)
1.99 should !be in range(2..3)
1.99 should !be in range(1.991..1.992)
1 should !be in range(0.9..0.99);
{1.001 should !be in range(1..2)} should fail with assertionError;
{1.11 should !be in range(1.10..1.12)} should fail with assertionError
{1.1999 should !be in range(1.1..1.2)} should fail with assertionError

}
}

0 comments on commit 414ef23

Please sign in to comment.