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

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

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

import scala.collection._
import mutable.WrappedArray
import scala.util.Success

/**
 * A function that given any object will produce a “pretty” string representation of that object,
 * where “pretty” is in the eye of the implementer. 
 *
 * 

* Scala's Any type declares a toString that will convert any object to a String * representation. This String representation is primarily intended for programmers, and is usually sufficient. * However, sometimes it can be helpful to provide an alternative implementation of toString for certain types. * For example, the toString implementation on String prints out the value of the String: *

* *
 * scala> "1".toString
 * res0: String = 1
 * 
* *

* If the error message that resulted from comparing Int 1 with String "1" * in a ScalaTest assertion used toString, therefore, the error message would be: *

* *
 * 1 did not equal 1
 * 
* *

* To make it quicker to figure out why the assertion failed, ScalaTest prettifies the objects involved in * the error message. The default Prettifier will place double quotes on either side of a Strings * toString result: *

* *
 * scala> import org.scalautils._
 * import org.scalautils._
 *
 * scala> Prettifier.default("1")
 * res1: String = "1"
 * 
* *

* Thus the error message resulting from comparing Int 1 with String "1", * in a ScalaTest assertion is: *

* *
 * 1 did not equal "1"
 * 
* *

* If you wish to prettify an object in production code, for example, to issue a profoundly clear debug message, you can use * PrettyMethods and invoke pretty. Here's an example: *

* *
 * scala> import PrettyMethods._
 * import PrettyMethods._
 *
 * scala> 1.pretty
 * res2: String = 1
 *
 * scala> "1".pretty
 * res3: String = "1"
 * 
* *

* For example, the default Prettifier, Prettifier.default, transforms: *

* *
    *
  • Null to: null
  • *
  • Unit to: <() the Unit value>
  • *
  • String to: "string" (the toString result surrounded by double quotes)
  • *
  • Char to: 'c' (the toString result surrounded by single quotes)
  • *
  • Array to: Array("1", "2", "3")
  • *
  • scala.Some to: Some("3")
  • *
  • scala.util.Left to: Left("3")
  • *
  • scala.util.Right to: Right("3")
  • *
  • scala.util.Success to: Success("3")
  • *
  • org.scalautils.Good to: Good("3")
  • *
  • org.scalautils.Bad to: Bad("3")
  • *
  • org.scalautils.One to: One("3")
  • *
  • org.scalautils.Many to: Many("1", "2", "3")
  • *
  • scala.collection.GenTraversable to: List("1", "2", "3")
  • *
  • java.util.Collection to: ["1", "2", "3"]
  • *
  • java.util.Map to: {1="one", 2="two", 3="three"}
  • *
* *

* For anything else, the default Prettifier returns the result of invoking toString. *

* *

* Note: Prettifier is not parameterized (i.e., Prettifier[T], where T is the type * to prettify) because assertions (including matcher expressions) in ScalaTest would then need to look up Prettifiers implicitly by type. This would slow * compilation even though most (let's guess 99.9%) of the time in practice assertions do not fail, and thus 99.9% of the time no error messages need to be generated. * If no error messages are needed 99.9% of the time, no prettification is needed 99.9% of the time, so the slow down in compile time for the implicit * look ups is unlikely to be worth the benefit. Only a few types in practice usually need prettification for testing error message purposes, and those will be covered * by the default Prettifier. A future version of ScalaTest will provide a simple mechanism to replace the default Prettifier with a * custom one when a test actually fails. *

*/ trait Prettifier extends (Any => String) /** * Companion object for Prettifier that provides a default Prettifier implementation. */ object Prettifier { /** * A default Prettifier. * *

* This default Prettifier is used in ScalaTest to clarify error messages. *

* *

* It transforms: *

* *
    *
  • Null to: null
  • *
  • Unit to: <() the Unit value>
  • *
  • String to: "string" (the toString result surrounded by double quotes)
  • *
  • Char to: 'c' (the toString result surrounded by single quotes)
  • *
  • Array to: Array("1", "2", "3")
  • *
  • scala.Some to: Some("3")
  • *
  • scala.util.Left to: Left("3")
  • *
  • scala.util.Right to: Right("3")
  • *
  • scala.util.Success to: Success("3")
  • *
  • org.scalautils.Good to: Good("3")
  • *
  • org.scalautils.Bad to: Bad("3")
  • *
  • org.scalautils.One to: One("3")
  • *
  • org.scalautils.Many to: Many("1", "2", "3")
  • *
  • scala.collection.GenTraversable to: List("1", "2", "3")
  • *
  • java.util.Collection to: ["1", "2", "3"]
  • *
  • java.util.Map to: {1="one", 2="two", 3="three"}
  • *
* * *

* For anything else, it returns the result of invoking toString. *

*/ val default: Prettifier = new Prettifier { def apply(o: Any): String = o match { case null => "null" case aUnit: Unit => "<(), the Unit value>" case aString: String => "\"" + aString + "\"" case aChar: Char => "\'" + aChar + "\'" case Some(e) => "Some(" + apply(e) + ")" case Success(e) => "Success(" + apply(e) + ")" case Left(e) => "Left(" + apply(e) + ")" case Right(e) => "Right(" + apply(e) + ")" case Good(e) => "Good(" + apply(e) + ")" case Bad(e) => "Bad(" + apply(e) + ")" case One(e) => "One(" + apply(e) + ")" case many: Many[_] => "Many(" + many.toIterator.map(apply(_)).mkString(", ") + ")" case anArray: Array[_] => "Array(" + (anArray map apply).mkString(", ") + ")" case aWrappedArray: WrappedArray[_] => "Array(" + (aWrappedArray map apply).mkString(", ") + ")" case aGenMap: GenMap[_, _] => val defaultToString = aGenMap.toString val typeName = defaultToString.takeWhile(_ != '(') typeName + "(" + (aGenMap.toIterator.map { case (key, value) => // toIterator is needed for consistent ordering apply(key) + " -> " + apply(value) }).mkString(", ") + ")" case aGenTraversable: GenTraversable[_] => val defaultToString = aGenTraversable.toString val typeName = defaultToString.takeWhile(_ != '(') typeName + "(" + aGenTraversable.toIterator.map(apply(_)).mkString(", ") + ")" // toIterator is needed for consistent ordering case javaCol: java.util.Collection[_] => // By default java collection follows http://download.java.net/jdk7/archive/b123/docs/api/java/util/AbstractCollection.html#toString() // let's do our best to prettify its element when it is not overriden import scala.collection.JavaConverters._ val theToString = javaCol.toString if (theToString.startsWith("[") && theToString.endsWith("]")) "[" + javaCol.iterator().asScala.map(apply(_)).mkString(", ") + "]" else theToString case javaMap: java.util.Map[_, _] => // By default java map follows http://download.java.net/jdk7/archive/b123/docs/api/java/util/AbstractMap.html#toString() // let's do our best to prettify its element when it is not overriden import scala.collection.JavaConverters._ val theToString = javaMap.toString if (theToString.startsWith("{") && theToString.endsWith("}")) "{" + javaMap.entrySet.iterator.asScala.map { entry => apply(entry.getKey) + "=" + apply(entry.getValue) }.mkString(", ") + "}" else theToString case anythingElse => anythingElse.toString } } /** * A basic Prettifier. * *

* This was the default Prettifier used in ScalaTest 2.0 release. *

* *

* It transforms: *

* *
    *
  • Null to: null
  • *
  • Unit to: <() the Unit value>
  • *
  • String to: "string" (the toString result surrounded by double quotes)
  • *
  • Char to: 'c' (the toString result surrounded by single quotes)
  • *
  • Array to: Array("1", "2", "3")
  • *
  • scala.util.Some to: Some("3")
  • *
* *

* For anything else, it returns the result of invoking toString. *

*/ val basic = new BasicPrettifier } private[scalautils] class BasicPrettifier extends Prettifier { def apply(o: Any): String = o match { case null => "null" case aUnit: Unit => "<(), the Unit value>" case aString: String => "\"" + aString + "\"" case aChar: Char => "\'" + aChar + "\'" case anArray: Array[_] => prettifyArrays(anArray) case aWrappedArray: WrappedArray[_] => prettifyArrays(aWrappedArray) case anythingElse => anythingElse.toString } private def prettifyArrays(o: Any): String = o match { case arr: Array[_] => "Array(" + (arr map (a => prettifyArrays(a))).mkString(", ") + ")" case wrappedArr: WrappedArray[_] => "Array(" + (wrappedArr map (a => prettifyArrays(a))).mkString(", ") + ")" case _ => if (o != null) o.toString else "null" } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy