org.scalautils.TolerantNumerics.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of scalatest_2.11.0-M5 Show documentation
Show all versions of scalatest_2.11.0-M5 Show documentation
ScalaTest is a free, open-source testing toolkit for Scala and Java
programmers.
The newest version!
/*
* Copyright 2001-2013 Artima, Inc.
*
* 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.scalautils
/**
* Defines a custom way to determine equality for a type.
*
*
* For example, here's how you could define equality between Double
s such that
* a tolerance of ± 0.01 is allowed:
*
*
*
* class TolerantDoubleEquality extends Equality[Double] {
*
* private val Tol = 0.01
*
* def areEqual(a: Double, b: Any): Boolean = {
* b match {
* case bDouble: Double => (a <= bDouble + Tol) && (a >= bDouble - Tol)
* case _ => false
* }
* }
* }
*
*
*
* If an implicit instance of TolerantDoubleEquality
is in scope, it will be
* used by ScalaTest's ===
operators and its should equal
and should ===
matcher
* syntax. Here's an example:
*
*
*
* $ scala -cp target/jar_contents/
* Welcome to Scala version 2.10.0 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_33).
* Type in expressions to have them evaluated.
* Type :help for more information.
* scala> import org.scalautils._
* import org.scalautils._
* scala> class TolerantDoubleEquality extends Equality[Double] {
* |
* | private val Tol = 0.01
* |
* | def areEqual(a: Double, b: Any): Boolean = {
* | b match {
* | case bDouble: Double => (a >= bDouble + Tol) && (a >= bDouble - Tol)
* | case _ => false
* | }
* | }
* | }
* defined class TolerantDoubleEquality
*
* scala> import TripleEquals._
* import TripleEquals._
*
* scala> 2.0 === 2.001
* res0: Boolean = false
*
* scala> implicit val tolerantDoubleEquality = new TolerantDoubleEquality
* tolerantDoubleEquality: TolerantDoubleEquality = TolerantDoubleEquality@70c13c17
*
* scala> 2.0 === 2.001
* res1: Boolean = true
*
*
*
* Note: The Equality
type class was inspired in part by the Equal
type class of the
* scalaz
project.
*
*
* @tparam A the type whose equality is being customized
*/
trait TolerantNumerics {
/**
* Indicates whether the objects passed as a
and b
are equal.
*
* @param a a left-hand-side object being compared with another (right-hand-side one) for equality (e.g., a == b
)
* @param b a right-hand-side object being compared with another (left-hand-side one) for equality (e.g., a == b
)
* @return true if the passed objects are "equal," as defined by this Equality
instance
*/
def tolerantDoubleEquality(tolerance: Double): Equality[Double] = {
if (tolerance <= 0.0)
throw new IllegalArgumentException(tolerance.toString + " passed to tolerantDoubleEquality was zero or negative. Must be a positive non-zero number.")
new Equality[Double] {
def areEqual(a: Double, b: Any): Boolean = {
b match {
case bDouble: Double => (a <= bDouble + tolerance) && (a >= bDouble - tolerance)
case _ => false
}
}
}
}
def tolerantFloatEquality(tolerance: Float): Equality[Float] = {
if (tolerance <= 0.0f)
throw new IllegalArgumentException(tolerance.toString + " passed to tolerantFloatEquality was zero or negative. Must be a positive non-zero number.")
new Equality[Float] {
def areEqual(a: Float, b: Any): Boolean = {
b match {
case bFloat: Float => (a <= bFloat + tolerance) && (a >= bFloat - tolerance)
case _ => false
}
}
}
}
def tolerantLongEquality(tolerance: Long): Equality[Long] = {
if (tolerance <= 0L)
throw new IllegalArgumentException(tolerance.toString + " passed to tolerantLongEquality was zero or negative. Must be a positive non-zero number.")
new Equality[Long] {
def areEqual(a: Long, b: Any): Boolean = {
b match {
case bLong: Long => (a <= bLong + tolerance) && (a >= bLong - tolerance)
case _ => false
}
}
}
}
def tolerantIntEquality(tolerance: Int): Equality[Int] = {
if (tolerance <= 0)
throw new IllegalArgumentException(tolerance.toString + " passed to tolerantIntEquality was zero or negative. Must be a positive non-zero number.")
new Equality[Int] {
def areEqual(a: Int, b: Any): Boolean = {
b match {
case bInt: Int => (a <= bInt + tolerance) && (a >= bInt - tolerance)
case _ => false
}
}
}
}
def tolerantShortEquality(tolerance: Short): Equality[Short] = {
if (tolerance <= 0)
throw new IllegalArgumentException(tolerance.toString + " passed to tolerantShortEquality was zero or negative. Must be a positive non-zero number.")
new Equality[Short] {
def areEqual(a: Short, b: Any): Boolean = {
b match {
case bShort: Short => (a <= bShort + tolerance) && (a >= bShort - tolerance)
case _ => false
}
}
}
}
def tolerantByteEquality(tolerance: Byte): Equality[Byte] = {
if (tolerance <= 0)
throw new IllegalArgumentException(tolerance.toString + " passed to tolerantByteEquality was zero or negative. Must be a positive non-zero number.")
new Equality[Byte] {
def areEqual(a: Byte, b: Any): Boolean = {
b match {
case bByte: Byte => (a <= bByte + tolerance) && (a >= bByte - tolerance)
case _ => false
}
}
}
}
def tolerantEquivalence[N : Numeric](tolerance: N): Equivalence[N] = {
val numeric = implicitly[Numeric[N]]
if (numeric.lt(tolerance, numeric.zero))
throw new IllegalArgumentException(tolerance.toString + " passed to tolerantEquivalence was zero or negative. Must be a positive non-zero number.")
new Equivalence[N] {
def areEquivalent(a: N, b: N): Boolean = {
val bPlusTolerance = numeric.plus(b, tolerance)
val bMinusTolerance = numeric.minus(b, tolerance)
(numeric.lteq(a, bPlusTolerance)) && (numeric.gteq(a, bMinusTolerance))
}
}
}
}
object TolerantNumerics extends TolerantNumerics
© 2015 - 2025 Weber Informatics LLC | Privacy Policy