org.scalatest.enablers.Collecting.scala Maven / Gradle / Ivy
Show all versions of scalatest_2.11.0-M5 Show documentation
/*
* 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.enablers
import org.scalautils.Equality
import org.scalatest.words.ArrayWrapper
import scala.collection.GenTraversable
import org.scalatest.FailureMessages
import scala.annotation.tailrec
// import scala.collection.JavaConverters._
/**
* Supertrait for typeclasses that enable loneElement
matcher syntax for collections.
*
*
* An Collecting[E, C]
provides access to the "collecting nature" of type C
in such
* a way that loneElement
syntax can be used with type C
. A C
* can be any type of "collecting", a type that in some way collects or brings together elements of type E
.
* ScalaTest provides implicit implementations for several types. You can enable the contain
matcher syntax
* on your own type U
by defining an Collecting[U, E]
for the type and making it available implicitly.
*
*
* ScalaTest provides implicit Collecting
instances for scala.collection.GenTraversable
,
* Array
, java.util.Collection
and java.util.Map
in the
* Collecting
companion object.
*
*
*/
trait Collecting[E, C] {
/**
* Implements the loneElement
syntax of trait LoneElement
.
*
*
* Returns the lone element contained in a collection, wrapped in a Some
, or None
* if the collection contains either no elements or more than one element.
*
*
* @param collection a collection about which an assertion is being made
* @return Some[E]
if the collection contains one and only one element, None
otherwise.
*/
def loneElementOf(collection: C): Option[E]
/**
* Returns the size of the passed collection
.
*
* @param collection a collection
to check the size of
* @return the size of the passed collection
*/
def sizeOf(collection: C): Int
}
/**
* Companion object for Collecting
that provides implicit implementations for the following types:
*
*
* scala.collection.GenTraversable
* Array
* java.util.Collection
* java.util.Map
*
*/
object Collecting {
/**
* Implicit to support Collecting
nature of GenTraversable
.
*
* @tparam E the type of the element in the GenTraversable
* @tparam TRAV any subtype of GenTraversable
* @return Collecting[TRAV[E]]
that supports GenTraversable
in loneElement
syntax
*/
implicit def collectingNatureOfGenTraversable[E, TRAV[e] <: scala.collection.GenTraversable[e]]: Collecting[E, TRAV[E]] =
new Collecting[E, TRAV[E]] {
def loneElementOf(trav: TRAV[E]): Option[E] = {
if (trav.size == 1) Some(trav.head) else None
}
def sizeOf(trav: TRAV[E]): Int = trav.size
}
/**
* Implicit to support Collecting
nature of Array
.
*
* @tparam E the type of the element in the Array
* @return Collecting[Array[E]]
that supports Array
in loneElement
syntax
*/
implicit def collectingNatureOfArray[E]: Collecting[E, Array[E]] =
new Collecting[E, Array[E]] {
def loneElementOf(array: Array[E]): Option[E] = {
if (array.size == 1) Some(array.head) else None
}
def sizeOf(array: Array[E]): Int = array.length
}
/**
* Implicit to support Collecting
nature of java.util.Collection
.
*
* @tparam E the type of the element in the java.util.Collection
* @tparam JCOL any subtype of java.util.Collection
* @return Collecting[JCOL[E]]
that supports java.util.Collection
in loneElement
syntax
*/
implicit def collectingNatureOfJavaCollection[E, JCOL[e] <: java.util.Collection[e]]: Collecting[E, JCOL[E]] =
new Collecting[E, JCOL[E]] {
def loneElementOf(coll: JCOL[E]): Option[E] = {
if (coll.size == 1) Some(coll.iterator.next) else None
}
def sizeOf(coll: JCOL[E]): Int = coll.size
}
// Wrap the extracted entry in an org.scalatest.Entry so people can call key and value methods instead of getKey and getValue
/**
* Implicit to support Collecting
nature of java.util.Map
.
*
* @tparam K the type of the key in the java.util.Map
* @tparam V the type of the value in the java.util.Map
* @tparam JMAP any subtype of java.util.Map
* @return Collecting[JMAP[K, V]]
that supports java.util.Map
in loneElement
syntax
*/
implicit def collectingNatureOfJavaMap[K, V, JMAP[k, v] <: java.util.Map[k, v]]: Collecting[org.scalatest.Entry[K, V], JMAP[K, V]] =
new Collecting[org.scalatest.Entry[K, V], JMAP[K, V]] {
def loneElementOf(jmap: JMAP[K, V]): Option[org.scalatest.Entry[K, V]] = {
if (jmap.size == 1) {
val loneEntry = jmap.entrySet.iterator.next
Some(org.scalatest.Entry(loneEntry.getKey, loneEntry.getValue))
} else None
}
def sizeOf(jmap: JMAP[K, V]): Int = jmap.size
}
}