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

org.scalatest.OptionValues.scala Maven / Gradle / Ivy

/*
 * 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.scalatest

import org.scalactic._
import java.util.NoSuchElementException
import org.scalatest.exceptions.StackDepthException
import org.scalatest.exceptions.TestFailedException

/**
 * Trait that provides an implicit conversion that adds a value method
 * to Option, which will return the value of the option if it is defined,
 * or throw TestFailedException if not.
 *
 * 

* This construct allows you to express in one statement that an option should be defined * and that its value should meet some expectation. Here's an example: *

* *
 * opt.value should be > 9
 * 
* *

* Or, using an assertion instead of a matcher expression: *

* *
 * assert(opt.value > 9)
 * 
* *

* Were you to simply invoke get on the Option, * if the option wasn't defined, it would throw a NoSuchElementException: *

* *
 * val opt: Option[Int] = None
 *
 * opt.get should be > 9 // opt.get throws NoSuchElementException
 * 
* *

* The NoSuchElementException would cause the test to fail, but without providing a stack depth pointing * to the failing line of test code. This stack depth, provided by TestFailedException (and a * few other ScalaTest exceptions), makes it quicker for * users to navigate to the cause of the failure. Without OptionValues, to get * a stack depth exception you would need to make two statements, like this: *

* *
 * val opt: Option[Int] = None
 *
 * opt should be ('defined) // throws TestFailedException
 * opt.get should be > 9
 * 
* *

* The OptionValues trait allows you to state that more concisely: *

* *
 * val opt: Option[Int] = None
 *
 * opt.value should be > 9 // opt.value throws TestFailedException
 * 
*/ trait OptionValues { import scala.language.implicitConversions /** * Implicit conversion that adds a value method to Option. * * @param opt the Option on which to add the value method */ // SKIP-DOTTY-START implicit def convertOptionToValuable[T](opt: Option[T])(implicit pos: source.Position): Valuable[T] = new Valuable(opt, pos) // SKIP-DOTTY-END //DOTTY-ONLY implicit def convertOptionToValuable[T](opt: Option[T])(implicit pos: source.Position): OptionValuable[T] = new OptionValuable(opt, pos) // SKIP-DOTTY-START /** * Wrapper class that adds a value method to Option, allowing * you to make statements like: * *
   * opt.value should be > 9
   * 
* * @param opt An option to convert to Valuable, which provides the value method. */ class Valuable[T](opt: Option[T], pos: source.Position) { // SKIP-DOTTY-END //DOTTY-ONLY /** //DOTTY-ONLY * Wrapper class that adds a value method to Option, allowing //DOTTY-ONLY * you to make statements like: //DOTTY-ONLY * //DOTTY-ONLY *
  //DOTTY-ONLY  * opt.value should be > 9
  //DOTTY-ONLY  * 
//DOTTY-ONLY * //DOTTY-ONLY * @param opt An option to convert to OptionValuable, which provides the value method. //DOTTY-ONLY */ //DOTTY-ONLY class OptionValuable[T](opt: Option[T], pos: source.Position) { /** * Returns the value contained in the wrapped Option, if defined, else throws TestFailedException with * a detail message indicating the option was not defined. */ def value: T = { try { opt.get } catch { case cause: NoSuchElementException => throw new TestFailedException((_: StackDepthException) => Some(Resources.optionValueNotDefined), Some(cause), pos) } } } } /** * Companion object that facilitates the importing of OptionValues members as * an alternative to mixing it in. One use case is to import OptionValues's members so you can use * value on option in the Scala interpreter: * *
 * $ scala -cp scalatest-1.7.jar
 * Welcome to Scala version 2.9.1.final (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_29).
 * Type in expressions to have them evaluated.
 * Type :help for more information.
 *
 * scala> import org.scalatest._
 * import org.scalatest._
 *
 * scala> import matchers.Matchers._
 * import matchers.Matchers._
 *
 * scala> import OptionValues._
 * import OptionValues._
 *
 * scala> val opt1: Option[Int] = Some(1)
 * opt1: Option[Int] = Some(1)
 * 
 * scala> val opt2: Option[Int] = None
 * opt2: Option[Int] = None
 * 
 * scala> opt1.value should be < 10
 * 
 * scala> opt2.value should be < 10
 * org.scalatest.TestFailedException: The Option on which value was invoked was not defined.
 *   at org.scalatest.OptionValues$Valuable.value(OptionValues.scala:68)
 *   at .<init>(<console>:18)
 *   ...
 * 
* */ object OptionValues extends OptionValues




© 2015 - 2024 Weber Informatics LLC | Privacy Policy