Catching up after the holidays.
[kakapo:kakapo.git] / src / Matchers / Factory.nqp
1 # Copyright (C) 2009, Austin Hastings. See accompanying LICENSE file, or 
2 # http://www.opensource.org/licenses/artistic-license-2.0.php for license.
3
4 module Matcher::Factory;
5 # Provides factory methods to facilitate constructing matchers.
6
7 INIT {
8         use(Dumper);
9         my $class_name := 'Matcher::Factory';
10
11         # FIXME: The class is created only for the sake of multis, which I don't think require the class anymore. Check and if true get 
12         # rid of the SUBCLASS call.
13         NOTE("Creating class ", $class_name);
14         Class::SUBCLASS($class_name,
15                 'Class::HashBased',
16         );
17
18         Class::multi_sub($class_name, 'equals', :starting_with('_equals_'));
19         Class::multi_sub($class_name, 'make_matcher', :starting_with('_make_'));
20         Class::multi_sub($class_name, 'returns', :starting_with('_returns_'));
21         Global::export('assert_that', 'empty', 'equals', 'has', 'instance_of', 'null', 'returns', 'same_as');
22                         
23         NOTE("done");
24 }
25
26 sub assert_that($item, $matcher) {
27         if ! $matcher.matches($item) {
28                 my $explain := $matcher.describe_self("Expected: ")
29                         ~ $matcher.describe_failure($item, "\n     but: ");
30                 return 0;
31         }
32         
33         return 1;
34 }
35
36 sub export_sub($sub, :$as, :$tags?) {
37 # Used to export a C< $sub > from a Matcher's namespace as a Factory method.
38                 
39         unless $tags {
40                 $tags := 'DEFAULT';
41         }
42         
43         Global::export($sub, :as($as), :tags($tags));
44 }
45
46 sub empty()                             { return Matcher::Empty.new(); }
47
48 sub _equals_Float($value)               { return Matcher::EqualsFloat.new($value); }
49 sub _equals_Integer($value)     { return Matcher::Equals.new($value, :match_type('Integer')); }
50 sub _equals_String($value)              { return Matcher::Equals.new($value, :match_type('String')); }
51 sub _equals_ResizablePMCArray($value) { return Matcher::EqualsArray.new($value); }
52
53 sub has($matcher)                       { return Matcher::DescribedAs.new('has', $matcher); }
54 sub instance_of($type)          { return Matcher::InstanceOf.new($type); }
55
56 sub _make_Float($value)         { return equals($value); }
57 sub _make_Integer($value)       { return equals($value); }
58 sub _make_Matcher($matcher)     { return $matcher; }
59 sub _make_String($value)                { return equals($value); }
60
61 sub make_matcher_list(@list) {
62         my @matchers := Array::empty();
63         
64         while @list {
65                 @matchers.push(make_matcher(@list.shift));
66         }
67         
68         return Matcher::AnyOne(@matchers);
69 }
70                         
71 sub null()                              { return Matcher::Null.new(); } 
72
73 sub _returns_Float($value)              { return returns(Matcher::IsCloseTo.new($value)); }
74 sub _returns_Integer($value)    { return returns(Matcher::Equals.new($value)); }
75 sub _returns_Matcher($value)    { return Matcher::DescribedAs.new('returns', $value); }
76 sub _returns_String($value)     { return returns(Matcher::Equals.new($value)); }
77
78 sub same_as($value)             { return Matcher::IdenticalTo.new($value); }