changelog shortlog tags changeset manifest revisions annotate raw

vendor/plugins/rspec/lib/spec/matchers/have.rb

changeset 15: 64acf98d15f4
author: moriq@moriq.com
date: Mon Mar 10 10:12:58 2008 +0900 (16 years ago)
permissions: -rw-r--r--
description: add plugins rspec
1module Spec
2 module Matchers
3
4 class Have #:nodoc:
5 def initialize(expected, relativity=:exactly)
6 @expected = (expected == :no ? 0 : expected)
7 @relativity = relativity
8 end
9
10 def relativities
11 @relativities ||= {
12 :exactly => "",
13 :at_least => "at least ",
14 :at_most => "at most "
15 }
16 end
17
18 def method_missing(sym, *args, &block)
19 @collection_name = sym
20 @plural_collection_name = Inflector.pluralize(sym.to_s) if Object.const_defined?(:Inflector)
21 @args = args
22 @block = block
23 self
24 end
25
26 def matches?(collection_owner)
27 if collection_owner.respond_to?(@collection_name)
28 collection = collection_owner.send(@collection_name, *@args, &@block)
29 elsif (@plural_collection_name && collection_owner.respond_to?(@plural_collection_name))
30 collection = collection_owner.send(@plural_collection_name, *@args, &@block)
31 elsif (collection_owner.respond_to?(:length) || collection_owner.respond_to?(:size))
32 collection = collection_owner
33 else
34 collection_owner.send(@collection_name, *@args, &@block)
35 end
36 @actual = collection.size if collection.respond_to?(:size)
37 @actual = collection.length if collection.respond_to?(:length)
38 raise not_a_collection if @actual.nil?
39 return @actual >= @expected if @relativity == :at_least
40 return @actual <= @expected if @relativity == :at_most
41 return @actual == @expected
42 end
43
44 def not_a_collection
45 "expected #{@collection_name} to be a collection but it does not respond to #length or #size"
46 end
47
48 def failure_message
49 "expected #{relative_expectation} #{@collection_name}, got #{@actual}"
50 end
51
52 def negative_failure_message
53 if @relativity == :exactly
54 return "expected target not to have #{@expected} #{@collection_name}, got #{@actual}"
55 elsif @relativity == :at_most
56 return <<-EOF
57Isn't life confusing enough?
58Instead of having to figure out the meaning of this:
59 should_not have_at_most(#{@expected}).#{@collection_name}
60We recommend that you use this instead:
61 should have_at_least(#{@expected + 1}).#{@collection_name}
62EOF
63 elsif @relativity == :at_least
64 return <<-EOF
65Isn't life confusing enough?
66Instead of having to figure out the meaning of this:
67 should_not have_at_least(#{@expected}).#{@collection_name}
68We recommend that you use this instead:
69 should have_at_most(#{@expected - 1}).#{@collection_name}
70EOF
71 end
72 end
73
74 def description
75 "have #{relative_expectation} #{@collection_name}"
76 end
77
78 private
79
80 def relative_expectation
81 "#{relativities[@relativity]}#{@expected}"
82 end
83 end
84
85 # :call-seq:
86 # should have(number).named_collection__or__sugar
87 # should_not have(number).named_collection__or__sugar
88 #
89 # Passes if receiver is a collection with the submitted
90 # number of items OR if the receiver OWNS a collection
91 # with the submitted number of items.
92 #
93 # If the receiver OWNS the collection, you must use the name
94 # of the collection. So if a <tt>Team</tt> instance has a
95 # collection named <tt>#players</tt>, you must use that name
96 # to set the expectation.
97 #
98 # If the receiver IS the collection, you can use any name
99 # you like for <tt>named_collection</tt>. We'd recommend using
100 # either "elements", "members", or "items" as these are all
101 # standard ways of describing the things IN a collection.
102 #
103 # This also works for Strings, letting you set an expectation
104 # about its length
105 #
106 # == Examples
107 #
108 # # Passes if team.players.size == 11
109 # team.should have(11).players
110 #
111 # # Passes if [1,2,3].length == 3
112 # [1,2,3].should have(3).items #"items" is pure sugar
113 #
114 # # Passes if "this string".length == 11
115 # "this string".should have(11).characters #"characters" is pure sugar
116 def have(n)
117 Matchers::Have.new(n)
118 end
119 alias :have_exactly :have
120
121 # :call-seq:
122 # should have_at_least(number).items
123 #
124 # Exactly like have() with >=.
125 #
126 # == Warning
127 #
128 # +should_not+ +have_at_least+ is not supported
129 def have_at_least(n)
130 Matchers::Have.new(n, :at_least)
131 end
132
133 # :call-seq:
134 # should have_at_most(number).items
135 #
136 # Exactly like have() with <=.
137 #
138 # == Warning
139 #
140 # +should_not+ +have_at_most+ is not supported
141 def have_at_most(n)
142 Matchers::Have.new(n, :at_most)
143 end
144 end
145end