1/*
2 * Copyright 2001-2008 Artima, Inc.
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 */
16package org.scalatest.matchers
17
18import org.scalatest.prop.Checkers
19import org.scalacheck._
20import Arbitrary._
21import Prop._
22import scala.reflect.BeanProperty
23
24trait BookPropertyMatchers {
25
26  case class Book(
27    var title: String,
28    val author: String,
29    val pubYear: Int,
30    val length: Int,
31    val isGoodRead: Boolean
32  )
33
34/*
35  case class JavaBook(
36    @BeanProperty var title: String,
37    private val author: String,
38    @BeanProperty val pubYear: Int,
39    private var length: Int,
40    private val goodRead: Boolean
41  ) {
42    def getAuthor: String = author
43    def getLength: Int = length
44    def setLength(len: Int) { length = len }
45    def isGoodRead: Boolean = goodRead
46  }
47*/
48
49/*
50
51The  BookPropertiesMatcher didn't compile in 2.8, and rightly so. There was a type error in it that wasn't caught by the 2.7 compiler.
52Since I'd already decided I didn't like the nested syntax because it isn't readable enough, I am not too concerned this doesn't compile.
53Probably better that it doesn't.
54
55  case class Bookshelf(
56    val book1: Book,
57    val book2: Book,
58    val book3: Book
59  )
60
61  class BookPropertiesMatcher(firstPropertyMatcher: HavePropertyMatcher[Book, _], propertyMatchers: HavePropertyMatcher[Book, _]*)
62      extends HavePropertyMatcher[Bookshelf, Book] {
63
64    def apply(bookshelf: Bookshelf) = {
65      val propertyMatcherList = firstPropertyMatcher :: propertyMatchers.toList
66      val propertyMatchResults = // This is the list of results
67        for (propertyMatcher <- propertyMatcherList) yield
68          propertyMatcher(bookshelf.book1)
69
70      val firstFailure = propertyMatchResults.find(_.matches == false)
71      firstFailure match {
72        case Some(failure) =>
73          new HavePropertyMatchResult(false, "book1." + failure.propertyName, failure.expectedValue, failure.actualValue)
74        case None =>
75          new HavePropertyMatchResult(true, "book1", null, null) // What to do here?
76      }
77    }
78  }
79
80  def book1(firstPropertyMatcher: HavePropertyMatcher[Book, _], propertyMatchers: HavePropertyMatcher[Book, _]*) =
81    new BookPropertiesMatcher(firstPropertyMatcher, propertyMatchers: _*)
82*/
83
84  class TitleMatcher(expectedValue: String) extends HavePropertyMatcher[Book, String] {
85    def apply(book: Book) = {
86      new HavePropertyMatchResult(book.title == expectedValue, "title", expectedValue, book.title)
87    }
88  }
89
90  def title(expectedValue: String) = new TitleMatcher(expectedValue)
91
92  class AuthorMatcher(expectedValue: String) extends HavePropertyMatcher[Book, String] {
93    def apply(book: Book) = {
94      new HavePropertyMatchResult(book.author == expectedValue, "author", expectedValue, book.author)
95    }
96  }
97
98  def author(expectedValue: String) = new AuthorMatcher(expectedValue)
99
100  class PubYearMatcher(expectedValue: Int) extends HavePropertyMatcher[Book, Int] {
101    def apply(book: Book) = {
102      new HavePropertyMatchResult(book.pubYear == expectedValue, "pubYear", expectedValue, book.pubYear)
103    }
104  }
105
106  def pubYear(expectedValue: Int) = new PubYearMatcher(expectedValue)
107
108  class GoodReadMatcher(expectedValue: Boolean) extends HavePropertyMatcher[Book, Boolean] {
109    def apply(book: Book) = {
110      new HavePropertyMatchResult(book.isGoodRead == expectedValue, "goodRead", expectedValue, book.isGoodRead)
111    }
112  }
113
114  class GoodReadBePropertyMatcher extends BePropertyMatcher[Book] {
115    def apply(book: Book) = {
116      new BePropertyMatchResult(book.isGoodRead, "goodRead")
117    }
118  }
119
120  def goodRead(expectedValue: Boolean) = new GoodReadMatcher(expectedValue)
121  def goodRead = new GoodReadBePropertyMatcher
122}
123
124