org.specs2.matcher.StringMatchers.scala Maven / Gradle / Ivy
The newest version!
package org.specs2
package matcher
import java.util.regex._
import control.Exceptions._
import text.Quote._
import util.matching.Regex
/**
* The `StringMatchers` trait provides matchers which are applicable to String objects
*/
trait StringMatchers extends StringBaseMatchers with StringBeHaveMatchers
object StringMatchers extends StringMatchers
/**
* This trait provides base matchers for strings.
*
* IgnoreCase and ignoreSpace matchers are created by adapting the BeEqualTo matcher.
*/
private[specs2]
trait StringBaseMatchers { outer =>
/** adapt the BeEqualTo matcher to provide ignoreCase and ignoreSpace matcher */
implicit def stringMatcher(m: AdaptableMatcher[Any]): StringMatcher = new StringMatcher(m)
class StringMatcher(m: AdaptableMatcher[Any]) {
private val ignoringCase = (_:Any) + ", ignoring case"
private val ignoringSpace = (_:Any) + ", ignoring space"
def ignoreCase: AdaptableMatcher[Any] = m.^^^((s: Any) => s.toString.toLowerCase, ignoringCase, ignoringCase)
def ignoreSpace: AdaptableMatcher[Any] = m.^^^((s: Any) => s.toString.trim, ignoringSpace, ignoringSpace)
}
/** matches if a.toLowerCase.trim = b.toLowerCase.trim */
def ==/(s: String) = be_==/(s)
/** matches if a.toLowerCase.trim = b.toLowerCase.trim */
def be_==/(a: String) = new BeEqualTo(a).ignoreCase.ignoreSpace
/** matches if a.toLowerCase.trim != b.toLowerCase.trim */
def be_!=/(a: String) = new BeEqualTo(a).ignoreCase.ignoreSpace
/** matches if a.toLowerCase.trim != b.toLowerCase.trim */
def !=/(s: String) = be_!=/(s)
/** matches if (b contains a) */
def contain(t: String) = new Matcher[String] {
def apply[S <: String](b: Expectable[S]) = {
val a = t
result(a != null && b.value != null && b.value.contains(a),
b.description + " contains " + q(a),
b.description + " doesn't contain " + q(a), b)
}
}
/** matches if (b contains a) */
def contain(t: Char) = new Matcher[String] {
def apply[S <: String](b: Expectable[S]) = {
val a = t
result(b.value != null && b.value.contains(a),
b.description + " contains " + q(a),
b.description + " doesn't contain " + q(a), b)
}
}
/** matches if b matches the regular expression a */
def beMatching(a: =>String) = new BeMatching(a)
/** matches if b matches the pattern a */
def beMatching(a: Pattern) = new BeMatchingPattern(a)
/** matches if b matches the regex a */
def beMatching(a: Regex) = new BeMatchingRegex(a)
/** alias for beMatching but matching just a fragment of the string*/
def =~(t: =>String) = new BeMatching(".*"+t+".*")
/** alias for beMatching but matching just a fragment of the string*/
def =~(p: Pattern) = new BeMatchingPattern(Pattern.compile(".*"+p.toString+".*"))
/** alias for beMatching but matching just a fragment of the string*/
def =~(r: Regex) = new BeMatchingRegex((".*"+r.toString+".*").r)
/** matches if b.startsWith(a) */
def startWith(t: =>String) = new Matcher[String] {
def apply[S <: String](b: Expectable[S]) = {
val a = t
result(b.value!= null && a!= null && b.value.startsWith(a),
b.description + " starts with " + q(a),
b.description + " doesn't start with " + q(a), b)
}
}
/** matches if b.endsWith(a) */
def endWith(t: =>String) = new Matcher[String] {
def apply[S <: String](b: Expectable[S]) = {
val a = t
result(b.value!= null && a!= null && b.value.endsWith(a),
b.description + " ends with " + q(a),
b.description + " doesn't end with " + q(a), b)
}
}
/** matches if the regexp a is found inside b */
def find(a: =>String) = new FindMatcher(a)
/** matches if the pattern p is found inside b */
def find(p: Pattern) = new FindMatcherPattern(p)
/** matches if the regexp r is found inside b */
def find(r: Regex) = new FindMatcherRegex(r)
/**
* Matcher to find if the regexp a is found inside b.
* This matcher can be specialized to a FindMatcherWithGroups which will also check the found groups
*/
class FindMatcher(t: =>String) extends Matcher[String] {
lazy val pattern = Pattern.compile(t)
def withGroup(group: String) = new FindMatcherWithGroups(t, group)
def withGroups(groups: String*) = new FindMatcherWithGroups(t, groups:_*)
def apply[S <: String](b: Expectable[S]) = {
val a = t
result(a != null && b.value != null && pattern.matcher(b.value).find,
q(a) + " is found in " + b.description,
q(a) + " isn't found in " + b.description, b)
}
}
/**
* Matcher to find if the pattern p is found inside b.
*/
class FindMatcherPattern(p: Pattern) extends FindMatcher(p.toString) {
override lazy val pattern = p
override def withGroup(group: String) = new FindMatcherPatternWithGroups(p, group)
override def withGroups(groups: String*) = new FindMatcherPatternWithGroups(p, groups:_*)
}
/**
* Matcher to find if the Regex r is found inside b.
*/
class FindMatcherRegex(r: Regex) extends FindMatcherPattern(r.pattern)
/**
* Matcher to find if the regexp a is found inside b.
* This matcher checks if the found groups are really the ones expected
*/
class FindMatcherWithGroups(t: =>String, groups: String*) extends Matcher[String] {
lazy val pattern = Pattern.compile(t)
def found(b: String) = {
val matcher = pattern.matcher(b)
val groupsFound = new scala.collection.mutable.ListBuffer[String]()
(1 to matcher.groupCount).foreach { i =>
matcher.reset()
while (matcher.find) { groupsFound += matcher.group(i) }
}
groupsFound.toList
}
def apply[S <: String](b: Expectable[S]) = {
val a = t
val groupsFound = found(b.value)
val withGroups = if (groups.size > 1) " with groups " else " with group "
def foundText = {
if (groupsFound.isEmpty)
". Found nothing"
else
". Found: " + q(groupsFound.mkString(", "))
}
val groupsToFind = if (groups == null) Nil else groups.toList
result(a != null && b.value != null && groupsFound == groupsToFind,
q(a) + " is found in " + b.description + withGroups + q(groupsToFind.mkString(", ")),
q(a) + " isn't found in " + b.description + withGroups + q(groupsToFind.mkString(", ")) + foundText, b)
}
}
/**
* Matcher to find if the pattern p is found inside b.
*/
class FindMatcherPatternWithGroups(p: Pattern, groups: String*) extends FindMatcherWithGroups(p.toString, groups:_*) {
override lazy val pattern = p
}
}
private[specs2]
trait StringBeHaveMatchers { outer: StringBaseMatchers =>
implicit def toStringResultMatcher(result: MatchResult[String]) = new StringResultMatcher(result)
class StringResultMatcher(result: MatchResult[String]) {
def matching(s: =>String) = result(beMatching(s))
def matching(s: Pattern) = result(beMatching(s))
def matching(s: Regex) = result(beMatching(s))
def contain(s: String) = result(outer.contain(s))
def containing(s: String) = result(outer.contain(s))
def startWith(s: =>String) = result(outer.startWith(s))
def endWith(s: =>String) = result(outer.endWith(s))
def startingWith(s: =>String) = result(outer.startWith(s))
def endingWith(s: =>String) = result(outer.endWith(s))
def ==/(s: String) = result(outer.be_==/(s))
}
implicit def toNeutralStringMatcher(result: NeutralMatcher[Any]) : NeutralStringMatcher = new NeutralStringMatcher(result)
class NeutralStringMatcher(result: NeutralMatcher[Any]) {
def ==/(s: String) = outer.be_==/(s)
def =~(s: =>String) = outer.=~(s)
def =~(s: Pattern) = outer.=~(s)
def =~(s: Regex) = outer.=~(s)
}
implicit def toNotStringMatcher(result: NotMatcher[Any]) : NotStringMatcher = new NotStringMatcher(result)
class NotStringMatcher(result: NotMatcher[Any]) {
def ==/(s: String) = outer.be_==/(s).not
def =~(s: =>String) = outer.=~(s).not
def =~(s: Pattern) = outer.=~(s).not
def =~(s: Regex) = outer.=~(s).not
}
def matching(t: =>String) = beMatching(t)
def matching(t: Pattern) = beMatching(t)
def matching(r: Regex) = beMatching(r)
def containing(s: String) = outer.contain(s)
def startingWith(s: =>String) = outer.startWith(s)
def endingWith(s: =>String) = outer.endWith(s)
}
protected[specs2]
class BeMatching(t: =>String) extends Matcher[String] {
lazy val pattern = Pattern.compile(t)
def apply[S <: String](b: Expectable[S]) = {
val a = t
result(tryOr(pattern.matcher(b.value).matches){ (e: Exception) => false },
b.description + " matches " + q(a),
b.description + " doesn't match " + q(a), b)
}
}
protected[specs2]
class BeMatchingPattern(p: Pattern) extends BeMatching(p.toString) {
override lazy val pattern = p
}
class BeMatchingRegex(r: Regex) extends BeMatching(r.toString) {
override lazy val pattern = r.pattern
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy