changelog shortlog tags changeset manifest revisions annotate raw

vendor/plugins/rspec/lib/spec/matchers.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
1require 'spec/matchers/simple_matcher'
2require 'spec/matchers/be'
3require 'spec/matchers/be_close'
4require 'spec/matchers/change'
5require 'spec/matchers/eql'
6require 'spec/matchers/equal'
7require 'spec/matchers/exist'
8require 'spec/matchers/has'
9require 'spec/matchers/have'
10require 'spec/matchers/include'
11require 'spec/matchers/match'
12require 'spec/matchers/raise_error'
13require 'spec/matchers/respond_to'
14require 'spec/matchers/satisfy'
15require 'spec/matchers/throw_symbol'
16require 'spec/matchers/operator_matcher'
17
18module Spec
19
20 # RSpec ships with a number of useful Expression Matchers. An Expression Matcher
21 # is any object that responds to the following methods:
22 #
23 # matches?(actual)
24 # failure_message
25 # negative_failure_message #optional
26 # description #optional
27 #
28 # See Spec::Expectations to learn how to use these as Expectation Matchers.
29 # See Spec::Mocks to learn how to use them as Mock Argument Constraints.
30 #
31 # == Predicates
32 #
33 # In addition to those Expression Matchers that are defined explicitly, RSpec will
34 # create custom Matchers on the fly for any arbitrary predicate, giving your specs
35 # a much more natural language feel.
36 #
37 # A Ruby predicate is a method that ends with a "?" and returns true or false.
38 # Common examples are +empty?+, +nil?+, and +instance_of?+.
39 #
40 # All you need to do is write +should be_+ followed by the predicate without
41 # the question mark, and RSpec will figure it out from there. For example:
42 #
43 # [].should be_empty => [].empty? #passes
44 # [].should_not be_empty => [].empty? #fails
45 #
46 # In addtion to prefixing the predicate matchers with "be_", you can also use "be_a_"
47 # and "be_an_", making your specs read much more naturally:
48 #
49 # "a string".should be_an_instance_of(String) =>"a string".instance_of?(String) #passes
50 #
51 # 3.should be_a_kind_of(Fixnum) => 3.kind_of?(Numeric) #passes
52 # 3.should be_a_kind_of(Numeric) => 3.kind_of?(Numeric) #passes
53 # 3.should be_an_instance_of(Fixnum) => 3.instance_of?(Fixnum) #passes
54 # 3.should_not be_instance_of(Numeric) => 3.instance_of?(Numeric) #fails
55 #
56 # RSpec will also create custom matchers for predicates like +has_key?+. To
57 # use this feature, just state that the object should have_key(:key) and RSpec will
58 # call has_key?(:key) on the target. For example:
59 #
60 # {:a => "A"}.should have_key(:a) => {:a => "A"}.has_key?(:a) #passes
61 # {:a => "A"}.should have_key(:b) => {:a => "A"}.has_key?(:b) #fails
62 #
63 # You can use this feature to invoke any predicate that begins with "has_", whether it is
64 # part of the Ruby libraries (like +Hash#has_key?+) or a method you wrote on your own class.
65 #
66 # == Custom Expectation Matchers
67 #
68 # When you find that none of the stock Expectation Matchers provide a natural
69 # feeling expectation, you can very easily write your own.
70 #
71 # For example, imagine that you are writing a game in which players can
72 # be in various zones on a virtual board. To specify that bob should
73 # be in zone 4, you could say:
74 #
75 # bob.current_zone.should eql(Zone.new("4"))
76 #
77 # But you might find it more expressive to say:
78 #
79 # bob.should be_in_zone("4")
80 #
81 # and/or
82 #
83 # bob.should_not be_in_zone("3")
84 #
85 # To do this, you would need to write a class like this:
86 #
87 # class BeInZone
88 # def initialize(expected)
89 # @expected = expected
90 # end
91 # def matches?(target)
92 # @target = target
93 # @target.current_zone.eql?(Zone.new(@expected))
94 # end
95 # def failure_message
96 # "expected #{@target.inspect} to be in Zone #{@expected}"
97 # end
98 # def negative_failure_message
99 # "expected #{@target.inspect} not to be in Zone #{@expected}"
100 # end
101 # end
102 #
103 # ... and a method like this:
104 #
105 # def be_in_zone(expected)
106 # BeInZone.new(expected)
107 # end
108 #
109 # And then expose the method to your specs. This is normally done
110 # by including the method and the class in a module, which is then
111 # included in your spec:
112 #
113 # module CustomGameMatchers
114 # class BeInZone
115 # ...
116 # end
117 #
118 # def be_in_zone(expected)
119 # ...
120 # end
121 # end
122 #
123 # describe "Player behaviour" do
124 # include CustomGameMatchers
125 # ...
126 # end
127 #
128 # or you can include in globally in a spec_helper.rb file <tt>require</tt>d
129 # from your spec file(s):
130 #
131 # Spec::Runner.configure do |config|
132 # config.include(CustomGameMatchers)
133 # end
134 #
135 module Matchers
136 module ModuleMethods
137 attr_accessor :generated_description
138
139 def clear_generated_description
140 self.generated_description = nil
141 end
142 end
143
144 extend ModuleMethods
145
146 def method_missing(sym, *args, &block) # :nodoc:
147 return Matchers::Be.new(sym, *args) if sym.starts_with?("be_")
148 return Matchers::Has.new(sym, *args) if sym.starts_with?("have_")
149 super
150 end
151
152 class MatcherError < StandardError
153 end
154
155 end
156end