/casbah-commons/src/test/scala/test/Specs2Helpers.scala

http://github.com/mongodb/casbah · Scala · 169 lines · 106 code · 26 blank · 37 comment · 9 complexity · fa4a304e80d23bfefabd5b438e7f1d32 MD5 · raw file

  1. /**
  2. * Copyright (c) 2010 MongoDB, Inc. <http://mongodb.com>
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. *
  16. */
  17. package com.mongodb.casbah.commons
  18. package test
  19. import com.mongodb.casbah.commons.Logging
  20. import com.mongodb.casbah.commons.Imports._
  21. import org.specs2._
  22. import org.specs2.data.Sized
  23. import org.specs2.matcher.{ Expectable, Matcher }
  24. import org.specs2.matcher.Matchers._
  25. trait CasbahMutableSpecification extends mutable.Specification with CasbahSpecificationBase
  26. trait CasbahSpecification extends Specification with CasbahSpecificationBase {}
  27. trait CasbahSpecificationBase extends SpecsDBObjectMatchers with Logging {
  28. implicit val sizedOptDBObj = new Sized[Option[DBObject]] {
  29. def size(t: Option[DBObject]) = t.getOrElse(MongoDBObject.empty).size
  30. }
  31. implicit val sizedDBObj = new Sized[DBObject] {
  32. def size(t: DBObject) = t.size
  33. }
  34. implicit val sizedOptDBList = new Sized[Option[MongoDBList]] {
  35. def size(t: Option[MongoDBList]) = {
  36. val item: MongoDBList = t.getOrElse(MongoDBList.empty)
  37. item.size
  38. }
  39. }
  40. implicit val sizedDBList = new Sized[MongoDBList] {
  41. def size(t: MongoDBList) = t.size
  42. }
  43. }
  44. trait SpecsDBObjectMatchers extends SpecsDBObjectBaseMatchers
  45. trait SpecsDBObjectBaseMatchers extends Logging {
  46. protected def someField(map: Expectable[Option[DBObject]], k: String) = if (k.indexOf('.') < 0) {
  47. map.value.getOrElse(MongoDBObject.empty).getAs[AnyRef](k)
  48. } else {
  49. map.value.getOrElse(MongoDBObject.empty).expand[AnyRef](k)
  50. }
  51. protected def field(map: Expectable[DBObject], k: String) = if (k.indexOf('.') < 0) {
  52. map.value.getAs[AnyRef](k)
  53. } else {
  54. map.value.expand[AnyRef](k)
  55. }
  56. protected def listField(map: Expectable[DBObject], k: String) = if (k.indexOf('.') < 0) {
  57. map.value.getAs[Seq[Any]](k)
  58. } else {
  59. map.value.expand[Seq[Any]](k)
  60. }
  61. def beDBObject: Matcher[AnyRef] = ((_: AnyRef).isInstanceOf[DBObject], " is a DBObject", " is not a DBObject")
  62. def beMongoDBObject: Matcher[AnyRef] = ((_: AnyRef).isInstanceOf[MongoDBObject], " is a MongoDBObject", " is not a MongoDBObject")
  63. def beMongoDBList: Matcher[AnyRef] = ((_: AnyRef).isInstanceOf[MongoDBList], " is a MongoDBList", " is not a MongoDBList")
  64. def haveSomeField(k: String) = new Matcher[Option[DBObject]] {
  65. def apply[S <: Option[DBObject]](map: Expectable[S]) = {
  66. result(someField(map, k).isDefined, map.description + " has the key " + k, map.description + " doesn't have the key " + k, map)
  67. }
  68. }
  69. /** matches if dbObject.contains(k) */
  70. def haveField(k: String) = new Matcher[DBObject] {
  71. def apply[S <: DBObject](map: Expectable[S]) = {
  72. result(field(map, k).isDefined, map.description + " has the key " + k, map.description + " doesn't have the key " + k, map)
  73. }
  74. }
  75. /**
  76. * matches if a Some(map) contains a pair (key, value) == (k, v)
  77. * Will expand out dot notation for matching.
  78. */
  79. def haveSomeEntry[V](p: (String, V)) = new Matcher[Option[DBObject]] {
  80. def apply[S <: Option[DBObject]](map: Expectable[S]) = {
  81. result(
  82. someField(map, p._1).exists(_ == p._2), // match only the value
  83. map.description + " has the pair " + p, map.description + " doesn't have the pair " + p, map
  84. )
  85. }
  86. }
  87. /**
  88. * Special version of "HaveEntry" that expects a list and then uses
  89. * "hasSameElements" on it.
  90. */
  91. def haveListEntry(k: String, l: => Traversable[Any]) = new Matcher[DBObject] {
  92. def apply[S <: DBObject](map: Expectable[S]) = {
  93. val objL = listField(map, k).getOrElse(Seq.empty[Any]).toSeq
  94. val _l = l.toSeq
  95. result(
  96. objL.sameElements(_l), // match only the value
  97. map.description + " has the pair " + k,
  98. map.description + " doesn't have the pair " + k,
  99. map
  100. )
  101. }
  102. }
  103. /**
  104. * matches if map contains a pair (key, value) == (k, v)
  105. * Will expand out dot notation for matching.
  106. */
  107. def haveEntry[V](p: (String, V)) = new Matcher[DBObject] {
  108. def apply[S <: DBObject](map: Expectable[S]) = {
  109. result(
  110. field(map, p._1).exists(_.equals(p._2)), // match only the value
  111. map.description + " has the pair " + p,
  112. map.description + "[" + field(map, p._1) + "] doesn't have the pair " + p + "[" + p._2 + "]",
  113. map
  114. )
  115. }
  116. }
  117. /**
  118. * matches if Some(map) contains all the specified pairs
  119. * can expand dot notation to match specific sub-keys
  120. */
  121. def haveSomeEntries[V](pairs: (String, V)*) = new Matcher[Option[DBObject]] {
  122. def apply[S <: Option[DBObject]](map: Expectable[S]) = {
  123. result(
  124. pairs.forall(pair => someField(map, pair._1).exists(_ == pair._2) /* match only the value */ ),
  125. map.description + " has the pairs " + pairs.mkString(", "), map.description + " doesn't have the pairs " + pairs.mkString(", "), map
  126. )
  127. }
  128. }
  129. /**
  130. * matches if map contains all the specified pairs
  131. * can expand dot notation to match specific sub-keys
  132. */
  133. def haveEntries[V](pairs: (String, V)*) = new Matcher[DBObject] {
  134. def apply[S <: DBObject](map: Expectable[S]) = {
  135. result(
  136. pairs.forall(pair => field(map, pair._1).exists(_ == pair._2) /* match only the value */ ),
  137. map.description + " has the pairs " + pairs.mkString(", "),
  138. map.description + " doesn't have the pairs " + pairs.mkString(", "),
  139. map
  140. )
  141. }
  142. }
  143. }