All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.scalautils.LegacyCheckingEqualizer.scala Maven / Gradle / Ivy

Go to download

ScalaTest is a free, open-source testing toolkit for Scala and Java programmers.

There is a newer version: 2.0.M6-SNAP4
Show newest version
/*
 * Copyright 2001-2008 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

/**
 * Class used via an implicit conversion to enable any two objects to be compared with
 * === in assertions in tests. For example:
 *
 * 
 * assert(a === b)
 * 
* *

* The benefit of using assert(a === b) rather than assert(a == b) is * that a TestFailedException produced by the former will include the values of a and b * in its detail message. * The implicit method that performs the conversion from Any to Equalizer is * convertToEqualizer in trait Assertions. *

* *

* In case you're not familiar with how implicit conversions work in Scala, here's a quick explanation. * The convertToEqualizer method in Assertions is defined as an "implicit" method that takes an * Any, which means you can pass in any object, and it will convert it to an Equalizer. * The Equalizer has === defined. Most objects don't have === defined as a method * on them. Take two Strings, for example: *

* *
 * assert("hello" === "world")
 * 
* *

* Given this code, the Scala compiler looks for an === method on class String, because that's the class of * "hello". String doesn't define ===, so the compiler looks for an implicit conversion from * String to something that does have an === method, and it finds the convertToEqualizer method. It * then rewrites the code to this: *

* *
 * assert(convertToEqualizer("hello").===("world"))
 * 
* *

* So inside a Suite (which mixes in Assertions, === will work on anything. The only * situation in which the implicit conversion wouldn't * happen is on types that have an === method already defined. *

* *

* The primary constructor takes one object, left, whose type is being converted to Equalizer. The left * value may be a null reference, because this is allowed by Scala's == operator. *

* * @param left An object to convert to Equalizer, which represents the left value * of an assertion. * * @author Bill Venners */ // final class Equalizer(left: Any) { /** * The === operation compares this Equalizer's left value (passed * to the constructor, usually via an implicit conversion) with the passed right value * for equality as determined by the expression left == right. * If true, === returns None. Else, === returns * a Some whose String value indicates the left and right values. * *

* In its typical usage, the Option[String] returned by === will be passed to one of two * of trait Assertion' overloaded assert methods. If None, * which indicates the assertion succeeded, assert will return normally. But if Some is passed, * which indicates the assertion failed, assert will throw a TestFailedException whose detail * message will include the String contained inside the Some, which in turn includes the * left and right values. This TestFailedException is typically embedded in a * Report and passed to a Reporter, which can present the left and right * values to the user. *

*/ /* def ===(right: Any) = { def diffStrings(s: String, t: String): Tuple2[String, String] = { def findCommonPrefixLength(s: String, t: String): Int = { val max = s.length.min(t.length) // the maximum potential size of the prefix var i = 0 var found = false while (i < max & !found) { found = (s.charAt(i) != t.charAt(i)) if (!found) i = i + 1 } i } def findCommonSuffixLength(s: String, t: String): Int = { val max = s.length.min(t.length) // the maximum potential size of the suffix var i = 0 var found = false while (i < max & !found) { found = (s.charAt(s.length - 1 - i) != t.charAt(t.length - 1 - i)) if (!found) i = i + 1 } i } val commonPrefixLength = findCommonPrefixLength(s, t) val commonSuffixLength = findCommonSuffixLength(s.substring(commonPrefixLength), t.substring(commonPrefixLength)) val prefix = s.substring(0, commonPrefixLength) val suffix = if (s.length - commonSuffixLength < 0) "" else s.substring(s.length - commonSuffixLength) val sMiddleEnd = s.length - commonSuffixLength val tMiddleEnd = t.length - commonSuffixLength val sMiddle = s.substring(commonPrefixLength, sMiddleEnd) val tMiddle = t.substring(commonPrefixLength, tMiddleEnd) val MaxContext = 20 val shortPrefix = if (commonPrefixLength > MaxContext) "..." + prefix.substring(prefix.length - MaxContext) else prefix val shortSuffix = if (commonSuffixLength > MaxContext) suffix.substring(0, MaxContext) + "..." else suffix (shortPrefix + "[" + sMiddle + "]" + shortSuffix, shortPrefix + "[" + tMiddle + "]" + shortSuffix) } // If the objects are two strings, replace them with whatever is returned by diffStrings. // Otherwise, use the same objects. def getObjectsForFailureMessage(a: Any, b: Any) = a match { case aStr: String => { b match { case bStr: String => { diffStrings(aStr, bStr) } case _ => (a, b) } } case _ => (a, b) } def areEqualComparingArraysStructurally(left: Any, right: Any) = { left match { case leftArray: Array[_] => right match { case rightArray: Array[_] => leftArray.deep.equals(rightArray.deep) case _ => left == right } case _ => left == right } } if (areEqualComparingArraysStructurally(left, right)) None else { val (leftee, rightee) = getObjectsForFailureMessage(left, right) Some(FailureMessages("didNotEqual", leftee, rightee)) //Some(leftee + " did not equal " + rightee) } } */ /* def !==(right: Any) = if (left != right) None else { val (leftee, rightee) = Suite.getObjectsForFailureMessage(left, right) Some(FailureMessages("equaled", leftee, rightee)) } */ // } class LegacyCheckingEqualizer[L](left: L) { private def diffStrings(s: String, t: String): Tuple2[String, String] = { def findCommonPrefixLength(s: String, t: String): Int = { val max = s.length.min(t.length) // the maximum potential size of the prefix var i = 0 var found = false while (i < max & !found) { found = (s.charAt(i) != t.charAt(i)) if (!found) i = i + 1 } i } def findCommonSuffixLength(s: String, t: String): Int = { val max = s.length.min(t.length) // the maximum potential size of the suffix var i = 0 var found = false while (i < max & !found) { found = (s.charAt(s.length - 1 - i) != t.charAt(t.length - 1 - i)) if (!found) i = i + 1 } i } val commonPrefixLength = findCommonPrefixLength(s, t) val commonSuffixLength = findCommonSuffixLength(s.substring(commonPrefixLength), t.substring(commonPrefixLength)) val prefix = s.substring(0, commonPrefixLength) val suffix = if (s.length - commonSuffixLength < 0) "" else s.substring(s.length - commonSuffixLength) val sMiddleEnd = s.length - commonSuffixLength val tMiddleEnd = t.length - commonSuffixLength val sMiddle = s.substring(commonPrefixLength, sMiddleEnd) val tMiddle = t.substring(commonPrefixLength, tMiddleEnd) val MaxContext = 20 val shortPrefix = if (commonPrefixLength > MaxContext) "..." + prefix.substring(prefix.length - MaxContext) else prefix val shortSuffix = if (commonSuffixLength > MaxContext) suffix.substring(0, MaxContext) + "..." else suffix (shortPrefix + "[" + sMiddle + "]" + shortSuffix, shortPrefix + "[" + tMiddle + "]" + shortSuffix) } // If the objects are two strings, replace them with whatever is returned by diffStrings. // Otherwise, use the same objects. def getObjectsForFailureMessage(a: Any, b: Any) = a match { case aStr: String => { b match { case bStr: String => { diffStrings(aStr, bStr) } case _ => (a, b) } } case _ => (a, b) } def ===[R](right: R)(implicit constraint: EqualityConstraint[L, R]): Option[String] = if (constraint.areEqual(left, right)) None else { val (leftee, rightee) = getObjectsForFailureMessage(left, right) Some(FailureMessages("didNotEqual", leftee, rightee)) } def !==[R](right: R)(implicit constraint: EqualityConstraint[L, R]): Option[String] = if (!constraint.areEqual(left, right)) None else { val (leftee, rightee) = getObjectsForFailureMessage(left, right) Some(FailureMessages("equaled", leftee, rightee)) } def ===(interval: Interval[L]): Option[String] = if (interval == null) { if (left == null) None else { val (leftee, rightee) = getObjectsForFailureMessage(left, interval) Some(FailureMessages("equaled", leftee, rightee)) } } else { if (interval.isWithin(left)) None else Some(FailureMessages("wasNotPlusOrMinus", left, interval.right, interval.tolerance)) } def !==(interval: Interval[L]): Option[String] = if (interval == null) { if (left != null) None else { val (leftee, rightee) = getObjectsForFailureMessage(left, interval) Some(FailureMessages("equaled", leftee, rightee)) } } else { if (if (interval != null) !interval.isWithin(left) else left != interval) None else Some(FailureMessages("wasPlusOrMinus", left, interval.right, interval.tolerance)) } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy