Provides the methods the test framework needs to test functions that
take and/or return data of type A
.
- Companion:
- object
Value members
Abstract methods
Returns a string representation of the name of the type A
.
Returns a string representation of the name of the type A
.
Abstract method that must be defined when instantiating a new Testable
.
Returns a function that reads a value of the indicated type from a given src
.
Returns a function that reads a value of the indicated type from a given src
.
Abstract method that must be defined when instantiating a new Testable
.
Will usually be defined using a function either predefined in
hwtest.parser
or built from combinators provided by hwtest.parser
.
Concrete methods
Throws an exception if an invariant fails. Otherwise, returns Unit.
Throws an exception if an invariant fails. Otherwise, returns Unit.
checkInvariant
defaults to {}
.
Override this default for types that have meaningful internal invariants
that you want to check automatically. Indicate that an invariant has been
violated by throwing an exception, preferably with a meaningful error
message. Note that checkInvariant
will be called on each answer before
comparing to the expected answer. That comparison would presumably
also fail, so the advantage of checkInvariant
is that it can display
a different error message for failed invariants than ordinary errors,
which matters because failed invariants often provide better clues for
debugging than ordinary errors.
For example, checkInvariant
might check if the keys in a binary
search tree are ordered in the way they should be, and throw an
exception if they aren't (ideally including a useful description
in the message of the exception).
Returns a deep copy of x
.
Returns a deep copy of x
.
Intended for storing copies of mutable inputs for later display
in error messages. Also used by testV
where the validation
function needs access to the original state of the input.
Because so many types in Scala are immutable, the default implementation
of copy
simply returns the original value. This method must be
overwritten for mutable values and also for immutable collections that
could contain mutable values.
Tests if x
and y
are equivalent.
Tests if x
and y
are equivalent.
Used to check if the result of a function is equivalent to the expected result, to determine whether a test passed.
The defalt implementation for equiv
uses ==
, because that's
usually what we want. In situations where we want a broader notion
of equivalance, we need to override equiv
with an appropriate
definition.
For example, if a function returns a list of integers, but the
order of those integers doesn't matter, then we may want to create
a new instance of Testable[List[Int]]
with
override def equiv(x: List[Int], y: List[Int]): Boolean = (x.sorted == y.sorted)
As another example, floating-point numbers typically need a notion of equivalence where numbers can be considered "close enough", even though that wreaks havoc with traditional properties of equivalence such as transitivity.
Returns a possibly-formatted string representing the given top-level value for display to the user.
Returns a possibly-formatted string representing the given top-level value for display to the user.
A top-level value is one that is a direct argument to or the direct
result from a function being tested. All nested values should be
displayed using show
.
For example, if a function returns a BinaryTree
, that result will be
displayed in a graphical format, but if a function returns a list of
BinaryTree
s, that list (including the trees) will be displayed in
a single-line format.
Equivalent to _format
except includes a check for null
.
To change the behavior of format
, override _format
instead.
Tests if x
is considered less than y
.
Tests if x
is considered less than y
.
Supports the ability to dispay unordered collections (eg, Sets) in a manner that makes it easier to spot the differences. For example, suppose an error message displays these two sets:
Set(3, 9, 8, 2, 1, 4, 6, 7)
Set(4, 2, 7, 5, 9, 3, 1, 8)
Even if the error message tells us they are different, it still takes some effort to spot the difference. But if the same two sets are displayed as
Set(1, 2, 3, 4, 6, 7, 8, 9)
Set(1, 2, 3, 4, 5, 7, 8, 9)
then it's much faster to see that the sets differ in the 6 and 5, which in turn can make debugging easier.
Not all types have an obvious comparison function. The default implementation converts the two values to strings and compares the strings. THE DEFAULT IMPLEMENTATION SHOULD BE OVERRIDDEN WHENEVER THERE IS A MORE MEANINGFUL COMPARISON.
Check if two collections are equivalent.
Check if two collections are equivalent.
The collections are given as iterators. To be equivalent, the two
iterators must be the same length, and the value at each position
of iter1
must be equivalent to the value at the same position
in iter2
.
When multiequiv
is called, the collections must be converted
to iterators, and might need to be normalized, usually by
sorting, so that corresponding elements end up in corresponding
order. (Typcially such normalization would be needed for unordered
collections but not for ordered collections.)
Check if one collection is considered "less than" another collection.
Check if one collection is considered "less than" another collection.
Typically used when normalizing a collection of collections.
The collections are given as iterators, which are compared lexicographically.
When multilt
is called, the collections must be converted
to iterators, and may need to be normalized, usually by
sorting, so that corresponding elements end up in corresponding order.
(Typically such normalization would be needed for unordered
collections but not for ordered collections.)
Like parse
but also checks that the parsed value satisfies any
invariant expected of a value of this type. Throws an exception
in an invariant is not met.
Like parse
but also checks that the parsed value satisfies any
invariant expected of a value of this type. Throws an exception
in an invariant is not met.
Returns a string representing the given value for display to the user.
Returns a string representing the given value for display to the user.
The returned string should normally not contain any line breaks,
except possibly when a line break occurs in the contents of a quoted
String
or Char
.
Equivalent to _show
except includes a check for null
.
To change the behavior of show
, override _show
instead.