]> git.openstreetmap.org Git - rails.git/blob - vendor/gems/rspec-1.1.2/lib/spec/matchers/be.rb
2b25b11f4dd713d1db2329a33639699b7b9b1dd3
[rails.git] / vendor / gems / rspec-1.1.2 / lib / spec / matchers / be.rb
1 module Spec
2   module Matchers
3     
4     class Be #:nodoc:
5       def initialize(*args)
6         if args.empty?
7           @expected = :satisfy_if
8         else
9           @expected = parse_expected(args.shift)
10         end
11         @args = args
12         @comparison = ""
13       end
14       
15       def matches?(actual)
16         @actual = actual
17         if handling_predicate?
18           begin
19             return @result = actual.__send__(predicate, *@args)
20           rescue => predicate_error
21             # This clause should be empty, but rcov will not report it as covered
22             # unless something (anything) is executed within the clause
23             rcov_error_report = "http://eigenclass.org/hiki.rb?rcov-0.8.0"
24           end
25
26           # This supports should_exist > target.exists? in the old world.
27           # We should consider deprecating that ability as in the new world
28           # you can't write "should exist" unless you have your own custom matcher.
29           begin
30             return @result = actual.__send__(present_tense_predicate, *@args)
31           rescue
32             raise predicate_error
33           end
34         else
35           return match_or_compare
36         end
37       end
38       
39       def failure_message
40         return "expected #{@comparison}#{expected}, got #{@actual.inspect}" unless handling_predicate?
41         return "expected #{predicate}#{args_to_s} to return true, got #{@result.inspect}"
42       end
43       
44       def negative_failure_message
45         return "expected not #{expected}, got #{@actual.inspect}" unless handling_predicate?
46         return "expected #{predicate}#{args_to_s} to return false, got #{@result.inspect}"
47       end
48       
49       def expected
50         return "if to be satisfied" if @expected == :satisfy_if
51         return true if @expected == :true
52         return false if @expected == :false
53         return "nil" if @expected == :nil
54         return @expected.inspect
55       end
56       
57       def match_or_compare
58         return @actual ? true : false if @expected == :satisfy_if
59         return @actual == true if @expected == :true
60         return @actual == false if @expected == :false
61         return @actual.nil? if @expected == :nil
62         return @actual < @expected if @less_than
63         return @actual <= @expected if @less_than_or_equal
64         return @actual >= @expected if @greater_than_or_equal
65         return @actual > @expected if @greater_than
66         return @actual == @expected if @double_equal
67         return @actual === @expected if @triple_equal
68         return @actual.equal?(@expected)
69       end
70       
71       def ==(expected)
72         @prefix = "be "
73         @double_equal = true
74         @comparison = "== "
75         @expected = expected
76         self
77       end
78
79       def ===(expected)
80         @prefix = "be "
81         @triple_equal = true
82         @comparison = "=== "
83         @expected = expected
84         self
85       end
86
87       def <(expected)
88         @prefix = "be "
89         @less_than = true
90         @comparison = "< "
91         @expected = expected
92         self
93       end
94
95       def <=(expected)
96         @prefix = "be "
97         @less_than_or_equal = true
98         @comparison = "<= "
99         @expected = expected
100         self
101       end
102
103       def >=(expected)
104         @prefix = "be "
105         @greater_than_or_equal = true
106         @comparison = ">= "
107         @expected = expected
108         self
109       end
110
111       def >(expected)
112         @prefix = "be "
113         @greater_than = true
114         @comparison = "> "
115         @expected = expected
116         self
117       end
118       
119       def description
120         "#{prefix_to_sentence}#{comparison}#{expected_to_sentence}#{args_to_sentence}"
121       end
122
123       private
124         def parse_expected(expected)
125           if Symbol === expected
126             @handling_predicate = true
127             ["be_an_","be_a_","be_"].each do |prefix|
128               if expected.starts_with?(prefix)
129                 @prefix = prefix
130                 return "#{expected.to_s.sub(@prefix,"")}".to_sym
131               end
132             end
133           end
134           @prefix = ""
135           return expected
136         end
137         
138         def handling_predicate?
139           return false if [:true, :false, :nil].include?(@expected)
140           return @handling_predicate
141         end
142
143         def predicate
144           "#{@expected.to_s}?".to_sym
145         end
146         
147         def present_tense_predicate
148           "#{@expected.to_s}s?".to_sym
149         end
150         
151         def args_to_s
152           return "" if @args.empty?
153           inspected_args = @args.collect{|a| a.inspect}
154           return "(#{inspected_args.join(', ')})"
155         end
156         
157         def comparison
158           @comparison
159         end
160         
161         def expected_to_sentence
162           split_words(@expected)
163         end
164         
165         def prefix_to_sentence
166           split_words(@prefix)
167         end
168
169         def split_words(sym)
170           sym.to_s.gsub(/_/,' ')
171         end
172
173         def args_to_sentence
174           case @args.length
175             when 0
176               ""
177             when 1
178               " #{@args[0]}"
179             else
180               " #{@args[0...-1].join(', ')} and #{@args[-1]}"
181           end
182         end
183         
184     end
185  
186     # :call-seq:
187     #   should be
188     #   should be_true
189     #   should be_false
190     #   should be_nil
191     #   should be_arbitrary_predicate(*args)
192     #   should_not be_nil
193     #   should_not be_arbitrary_predicate(*args)
194     #
195     # Given true, false, or nil, will pass if actual is
196     # true, false or nil (respectively). Given no args means
197     # the caller should satisfy an if condition (to be or not to be). 
198     #
199     # Predicates are any Ruby method that ends in a "?" and returns true or false.
200     # Given be_ followed by arbitrary_predicate (without the "?"), RSpec will match
201     # convert that into a query against the target object.
202     #
203     # The arbitrary_predicate feature will handle any predicate
204     # prefixed with "be_an_" (e.g. be_an_instance_of), "be_a_" (e.g. be_a_kind_of)
205     # or "be_" (e.g. be_empty), letting you choose the prefix that best suits the predicate.
206     #
207     # == Examples 
208     #
209     #   target.should be
210     #   target.should be_true
211     #   target.should be_false
212     #   target.should be_nil
213     #   target.should_not be_nil
214     #
215     #   collection.should be_empty #passes if target.empty?
216     #   "this string".should be_an_intance_of(String)
217     #
218     #   target.should_not be_empty #passes unless target.empty?
219     #   target.should_not be_old_enough(16) #passes unless target.old_enough?(16)
220     def be(*args)
221       Matchers::Be.new(*args)
222     end
223   end
224 end