rspec-expectations 2.0.0.a1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. data/.document +5 -0
  2. data/.gitignore +5 -0
  3. data/License.txt +22 -0
  4. data/README.markdown +8 -0
  5. data/Rakefile +43 -0
  6. data/VERSION +1 -0
  7. data/VERSION.yml +5 -0
  8. data/lib/rspec/expectations.rb +36 -0
  9. data/lib/rspec/expectations/differs/default.rb +62 -0
  10. data/lib/rspec/expectations/differs/load-diff-lcs.rb +12 -0
  11. data/lib/rspec/expectations/errors.rb +12 -0
  12. data/lib/rspec/expectations/extensions.rb +1 -0
  13. data/lib/rspec/expectations/extensions/kernel.rb +52 -0
  14. data/lib/rspec/expectations/fail_with.rb +43 -0
  15. data/lib/rspec/expectations/handler.rb +50 -0
  16. data/lib/rspec/matchers.rb +195 -0
  17. data/lib/rspec/matchers/be.rb +210 -0
  18. data/lib/rspec/matchers/be_close.rb +32 -0
  19. data/lib/rspec/matchers/be_instance_of.rb +26 -0
  20. data/lib/rspec/matchers/be_kind_of.rb +26 -0
  21. data/lib/rspec/matchers/change.rb +151 -0
  22. data/lib/rspec/matchers/compatibility.rb +14 -0
  23. data/lib/rspec/matchers/dsl.rb +14 -0
  24. data/lib/rspec/matchers/eql.rb +42 -0
  25. data/lib/rspec/matchers/equal.rb +53 -0
  26. data/lib/rspec/matchers/errors.rb +5 -0
  27. data/lib/rspec/matchers/exist.rb +16 -0
  28. data/lib/rspec/matchers/extensions/instance_exec.rb +23 -0
  29. data/lib/rspec/matchers/generated_descriptions.rb +36 -0
  30. data/lib/rspec/matchers/has.rb +35 -0
  31. data/lib/rspec/matchers/have.rb +151 -0
  32. data/lib/rspec/matchers/include.rb +44 -0
  33. data/lib/rspec/matchers/match.rb +21 -0
  34. data/lib/rspec/matchers/match_array.rb +71 -0
  35. data/lib/rspec/matchers/matcher.rb +86 -0
  36. data/lib/rspec/matchers/method_missing.rb +9 -0
  37. data/lib/rspec/matchers/operator_matcher.rb +78 -0
  38. data/lib/rspec/matchers/pretty.rb +37 -0
  39. data/lib/rspec/matchers/raise_error.rb +129 -0
  40. data/lib/rspec/matchers/respond_to.rb +71 -0
  41. data/lib/rspec/matchers/satisfy.rb +47 -0
  42. data/lib/rspec/matchers/simple_matcher.rb +133 -0
  43. data/lib/rspec/matchers/throw_symbol.rb +104 -0
  44. data/lib/rspec/matchers/wrap_expectation.rb +55 -0
  45. data/rspec-expectations.gemspec +104 -0
  46. data/spec/rspec/expectations/differs/default_spec.rb +128 -0
  47. data/spec/rspec/expectations/extensions/kernel_spec.rb +45 -0
  48. data/spec/rspec/expectations/fail_with_spec.rb +88 -0
  49. data/spec/rspec/expectations/handler_spec.rb +206 -0
  50. data/spec/rspec/expectations/wrap_expectation_spec.rb +30 -0
  51. data/spec/spec.opts +6 -0
  52. data/spec/spec_helper.rb +31 -0
  53. data/spec/suite.rb +1 -0
  54. data/spec/support/macros.rb +29 -0
  55. metadata +135 -0
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
@@ -0,0 +1,5 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
@@ -0,0 +1,22 @@
1
+ (The MIT License)
2
+
3
+ Copyright (c) 2005-2009 The RSpec Development Team
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,8 @@
1
+ # RSpec Expectations
2
+
3
+ See README.markdown at [http://github.com/rspec/meta](http://github.com/rspec/meta)
4
+
5
+ #### Also see
6
+
7
+ * [http://github.com/rspec/core](http://github.com/rspec/core)
8
+ * [http://github.com/rspec/mocks](http://github.com/rspec/mocks)
@@ -0,0 +1,43 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "rspec-expectations"
8
+ gem.summary = "rspec expectations (should[_not] and matchers)"
9
+ gem.email = "dchelimsky@gmail.com;chad.humphries@gmail.com"
10
+ gem.homepage = "http://github.com/rspec/expectations"
11
+ gem.authors = ["David Chelimsky", "Chad Humphries"]
12
+ gem.add_development_dependency('rspec-core', '>= 2.0.0.a1')
13
+ gem.add_development_dependency('rspec-mocks', '>= 2.0.0.a1')
14
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
15
+ end
16
+
17
+ rescue LoadError
18
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
19
+ end
20
+
21
+ $:.unshift File.join(File.dirname(__FILE__), "/../core/lib")
22
+ require 'rspec/core/rake_task'
23
+ Rspec::Core::RakeTask.new(:spec) do |spec|
24
+ spec.pattern = "spec/**/*_spec.rb"
25
+ end
26
+
27
+ task :default => :spec
28
+
29
+ require 'rake/rdoctask'
30
+ Rake::RDocTask.new do |rdoc|
31
+ if File.exist?('VERSION.yml')
32
+ config = YAML.load(File.read('VERSION.yml'))
33
+ version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
34
+ else
35
+ version = ""
36
+ end
37
+
38
+ rdoc.rdoc_dir = 'rdoc'
39
+ rdoc.title = "rspec-expectations #{version}"
40
+ rdoc.rdoc_files.include('README*')
41
+ rdoc.rdoc_files.include('lib/**/*.rb')
42
+ end
43
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 2.0.0.a1
@@ -0,0 +1,5 @@
1
+ ---
2
+ :patch: 0
3
+ :major: 2
4
+ :minor: 0
5
+ :build: a1
@@ -0,0 +1,36 @@
1
+ require 'rspec/matchers'
2
+ require 'rspec/expectations/differs/default'
3
+ require 'rspec/expectations/fail_with'
4
+ require 'rspec/expectations/errors'
5
+ require 'rspec/expectations/extensions'
6
+ require 'rspec/expectations/handler'
7
+
8
+ module Rspec
9
+
10
+ # Rspec::Expectations lets you set expectations on your objects.
11
+ #
12
+ # result.should == 37
13
+ # team.should have(11).players_on_the_field
14
+ #
15
+ # == How Expectations work.
16
+ #
17
+ # Rspec::Expectations adds two methods to Object:
18
+ #
19
+ # should(matcher=nil)
20
+ # should_not(matcher=nil)
21
+ #
22
+ # Both methods take an optional Expression Matcher (See Rspec::Matchers).
23
+ #
24
+ # When +should+ receives an Expression Matcher, it calls <tt>matches?(self)</tt>. If
25
+ # it returns +true+, the spec passes and execution continues. If it returns
26
+ # +false+, then the spec fails with the message returned by <tt>matcher.failure_message</tt>.
27
+ #
28
+ # Similarly, when +should_not+ receives a matcher, it calls <tt>matches?(self)</tt>. If
29
+ # it returns +false+, the spec passes and execution continues. If it returns
30
+ # +true+, then the spec fails with the message returned by <tt>matcher.negative_failure_message</tt>.
31
+ #
32
+ # RSpec ships with a standard set of useful matchers, and writing your own
33
+ # matchers is quite simple. See Rspec::Matchers for details.
34
+ module Expectations
35
+ end
36
+ end
@@ -0,0 +1,62 @@
1
+ require File.join(File.dirname(__FILE__), "/load-diff-lcs")
2
+ require 'pp'
3
+
4
+ module Rspec
5
+ module Expectations
6
+ module Differs
7
+ unless defined?(Default)
8
+ class Default
9
+ def initialize(options)
10
+ @options = options
11
+ end
12
+
13
+ # This is snagged from diff/lcs/ldiff.rb (which is a commandline tool)
14
+ def diff_as_string(data_new, data_old)
15
+ data_old = data_old.split(/\n/).map! { |e| e.chomp }
16
+ data_new = data_new.split(/\n/).map! { |e| e.chomp }
17
+ output = ""
18
+ diffs = Diff::LCS.diff(data_old, data_new)
19
+ return output if diffs.empty?
20
+ oldhunk = hunk = nil
21
+ file_length_difference = 0
22
+ diffs.each do |piece|
23
+ begin
24
+ hunk = Diff::LCS::Hunk.new(data_old, data_new, piece, context_lines,
25
+ file_length_difference)
26
+ file_length_difference = hunk.file_length_difference
27
+ next unless oldhunk
28
+ # Hunks may overlap, which is why we need to be careful when our
29
+ # diff includes lines of context. Otherwise, we might print
30
+ # redundant lines.
31
+ if (context_lines > 0) and hunk.overlaps?(oldhunk)
32
+ hunk.unshift(oldhunk)
33
+ else
34
+ output << oldhunk.diff(format)
35
+ end
36
+ ensure
37
+ oldhunk = hunk
38
+ output << "\n"
39
+ end
40
+ end
41
+ #Handle the last remaining hunk
42
+ output << oldhunk.diff(format) << "\n"
43
+ end
44
+
45
+ def diff_as_object(target,expected)
46
+ diff_as_string(PP.pp(target,""), PP.pp(expected,""))
47
+ end
48
+
49
+ protected
50
+ def format
51
+ @options.diff_format
52
+ end
53
+
54
+ def context_lines
55
+ @options.context_lines
56
+ end
57
+ end
58
+
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,12 @@
1
+ begin
2
+ require 'diff/lcs'
3
+ rescue LoadError
4
+ begin
5
+ require 'rubygems' unless ENV['NO_RUBYGEMS']
6
+ require 'diff/lcs'
7
+ rescue LoadError
8
+ raise "You must gem install diff-lcs to use diffing"
9
+ end
10
+ end
11
+
12
+ require 'diff/lcs/hunk'
@@ -0,0 +1,12 @@
1
+ module Rspec
2
+ module Expectations
3
+ # If Test::Unit is loaed, we'll use its error as baseclass, so that Test::Unit
4
+ # will report unmet RSpec expectations as failures rather than errors.
5
+ superclass = ['Test::Unit::AssertionFailedError', '::StandardError'].map do |c|
6
+ eval(c) rescue nil
7
+ end.compact.first
8
+
9
+ class ExpectationNotMetError < superclass
10
+ end
11
+ end
12
+ end
@@ -0,0 +1 @@
1
+ require 'rspec/expectations/extensions/kernel'
@@ -0,0 +1,52 @@
1
+ module Kernel
2
+ # :call-seq:
3
+ # should(matcher)
4
+ # should == expected
5
+ # should === expected
6
+ # should =~ expected
7
+ #
8
+ # receiver.should(matcher)
9
+ # => Passes if matcher.matches?(receiver)
10
+ #
11
+ # receiver.should == expected #any value
12
+ # => Passes if (receiver == expected)
13
+ #
14
+ # receiver.should === expected #any value
15
+ # => Passes if (receiver === expected)
16
+ #
17
+ # receiver.should =~ regexp
18
+ # => Passes if (receiver =~ regexp)
19
+ #
20
+ # See Rspec::Matchers for more information about matchers
21
+ #
22
+ # == Warning
23
+ #
24
+ # NOTE that this does NOT support receiver.should != expected.
25
+ # Instead, use receiver.should_not == expected
26
+ def should(matcher=nil, message=nil, &block)
27
+ Rspec::Expectations::PositiveExpectationHandler.handle_matcher(self, matcher, message, &block)
28
+ end
29
+
30
+ # :call-seq:
31
+ # should_not(matcher)
32
+ # should_not == expected
33
+ # should_not === expected
34
+ # should_not =~ expected
35
+ #
36
+ # receiver.should_not(matcher)
37
+ # => Passes unless matcher.matches?(receiver)
38
+ #
39
+ # receiver.should_not == expected
40
+ # => Passes unless (receiver == expected)
41
+ #
42
+ # receiver.should_not === expected
43
+ # => Passes unless (receiver === expected)
44
+ #
45
+ # receiver.should_not =~ regexp
46
+ # => Passes unless (receiver =~ regexp)
47
+ #
48
+ # See Rspec::Matchers for more information about matchers
49
+ def should_not(matcher=nil, message=nil, &block)
50
+ Rspec::Expectations::NegativeExpectationHandler.handle_matcher(self, matcher, message, &block)
51
+ end
52
+ end
@@ -0,0 +1,43 @@
1
+ module Rspec
2
+ module Expectations
3
+ class << self
4
+ attr_accessor :differ
5
+
6
+ # raises a Rspec::Expectations::ExpectationNotMetError with message
7
+ #
8
+ # When a differ has been assigned and fail_with is passed
9
+ # <code>expected</code> and <code>target</code>, passes them
10
+ # to the differ to append a diff message to the failure message.
11
+ def fail_with(message, expected=nil, target=nil) # :nodoc:
12
+ if message.nil?
13
+ raise ArgumentError, "Failure message is nil. Does your matcher define the " +
14
+ "appropriate failure_message_for_* method to return a string?"
15
+ end
16
+ if (Array === message) & (message.length == 3)
17
+ ::Rspec::Core.warn(<<-NOTICE
18
+
19
+ *****************************************************************
20
+ DEPRECATION WARNING: you are using deprecated behaviour that will
21
+ be removed from a future version of RSpec.
22
+
23
+ * Support for matchers that return arrays from failure message
24
+ methods is deprecated.
25
+ * Instead, the matcher should return a string, and expose methods
26
+ for the expected() and actual() values.
27
+ *****************************************************************
28
+ NOTICE
29
+ )
30
+ message, expected, target = message[0], message[1], message[2]
31
+ end
32
+ unless (differ.nil? || expected.nil? || target.nil?)
33
+ if expected.is_a?(String)
34
+ message << "\nDiff:" << self.differ.diff_as_string(target.to_s, expected)
35
+ elsif !target.is_a?(Proc)
36
+ message << "\nDiff:" << self.differ.diff_as_object(target, expected)
37
+ end
38
+ end
39
+ Kernel::raise(Rspec::Expectations::ExpectationNotMetError.new(message))
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,50 @@
1
+ module Rspec
2
+ module Expectations
3
+ class InvalidMatcherError < ArgumentError; end
4
+
5
+ class PositiveExpectationHandler
6
+ def self.handle_matcher(actual, matcher, message=nil, &block)
7
+ ::Rspec::Matchers.last_should = :should
8
+ ::Rspec::Matchers.last_matcher = matcher
9
+ return ::Rspec::Matchers::PositiveOperatorMatcher.new(actual) if matcher.nil?
10
+
11
+ match = matcher.matches?(actual, &block)
12
+ return match if match
13
+
14
+ message ||= matcher.respond_to?(:failure_message_for_should) ?
15
+ matcher.failure_message_for_should :
16
+ matcher.failure_message
17
+
18
+ if matcher.respond_to?(:diffable?) && matcher.diffable?
19
+ ::Rspec::Expectations.fail_with message, matcher.expected.first, matcher.actual
20
+ else
21
+ ::Rspec::Expectations.fail_with message
22
+ end
23
+ end
24
+ end
25
+
26
+ class NegativeExpectationHandler
27
+ def self.handle_matcher(actual, matcher, message=nil, &block)
28
+ ::Rspec::Matchers.last_should = :should_not
29
+ ::Rspec::Matchers.last_matcher = matcher
30
+ return ::Rspec::Matchers::NegativeOperatorMatcher.new(actual) if matcher.nil?
31
+
32
+ match = matcher.respond_to?(:does_not_match?) ?
33
+ !matcher.does_not_match?(actual, &block) :
34
+ matcher.matches?(actual, &block)
35
+ return match unless match
36
+
37
+ message ||= matcher.respond_to?(:failure_message_for_should_not) ?
38
+ matcher.failure_message_for_should_not :
39
+ matcher.negative_failure_message
40
+
41
+ if matcher.respond_to?(:diffable?) && matcher.diffable?
42
+ ::Rspec::Expectations.fail_with message, matcher.expected.first, matcher.actual
43
+ else
44
+ ::Rspec::Expectations.fail_with message
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+
@@ -0,0 +1,195 @@
1
+ require 'rspec/matchers/extensions/instance_exec'
2
+ require 'rspec/matchers/pretty'
3
+ require 'rspec/matchers/matcher'
4
+ require 'rspec/matchers/operator_matcher'
5
+ require 'rspec/matchers/be'
6
+ require 'rspec/matchers/be_close'
7
+ require 'rspec/matchers/be_instance_of'
8
+ require 'rspec/matchers/be_kind_of'
9
+ require 'rspec/matchers/change'
10
+ require 'rspec/matchers/eql'
11
+ require 'rspec/matchers/equal'
12
+ require 'rspec/matchers/errors'
13
+ require 'rspec/matchers/exist'
14
+ require 'rspec/matchers/generated_descriptions'
15
+ require 'rspec/matchers/has'
16
+ require 'rspec/matchers/have'
17
+ require 'rspec/matchers/include'
18
+ require 'rspec/matchers/match'
19
+ require 'rspec/matchers/match_array'
20
+ require 'rspec/matchers/method_missing'
21
+ require 'rspec/matchers/raise_error'
22
+ require 'rspec/matchers/respond_to'
23
+ require 'rspec/matchers/satisfy'
24
+ require 'rspec/matchers/simple_matcher'
25
+ require 'rspec/matchers/throw_symbol'
26
+ require 'rspec/matchers/wrap_expectation'
27
+ require 'rspec/matchers/compatibility'
28
+ require 'rspec/matchers/dsl'
29
+
30
+ module Rspec
31
+
32
+ # RSpec ships with a number of useful Expression Matchers. An Expression Matcher
33
+ # is any object that responds to the following methods:
34
+ #
35
+ # matches?(actual)
36
+ # failure_message_for_should
37
+ #
38
+ # These methods are also part of the matcher protocol, but are optional:
39
+ #
40
+ # does_not_match?(actual)
41
+ # failure_message_for_should_not
42
+ # description #optional
43
+ #
44
+ # These methods are from older versions of the protocol. They are still supported,
45
+ # but are not recommended:
46
+ #
47
+ # failure_message (use failure_message_for_should instead)
48
+ # negative_failure_message (use failure_message_for_should_not instead)
49
+ #
50
+ # See Rspec::Expectations to learn how to use these as Expectation Matchers.
51
+ #
52
+ # == Predicates
53
+ #
54
+ # In addition to those Expression Matchers that are defined explicitly, RSpec will
55
+ # create custom Matchers on the fly for any arbitrary predicate, giving your specs
56
+ # a much more natural language feel.
57
+ #
58
+ # A Ruby predicate is a method that ends with a "?" and returns true or false.
59
+ # Common examples are +empty?+, +nil?+, and +instance_of?+.
60
+ #
61
+ # All you need to do is write +should be_+ followed by the predicate without
62
+ # the question mark, and RSpec will figure it out from there. For example:
63
+ #
64
+ # [].should be_empty => [].empty? #passes
65
+ # [].should_not be_empty => [].empty? #fails
66
+ #
67
+ # In addtion to prefixing the predicate matchers with "be_", you can also use "be_a_"
68
+ # and "be_an_", making your specs read much more naturally:
69
+ #
70
+ # "a string".should be_an_instance_of(String) =>"a string".instance_of?(String) #passes
71
+ #
72
+ # 3.should be_a_kind_of(Fixnum) => 3.kind_of?(Numeric) #passes
73
+ # 3.should be_a_kind_of(Numeric) => 3.kind_of?(Numeric) #passes
74
+ # 3.should be_an_instance_of(Fixnum) => 3.instance_of?(Fixnum) #passes
75
+ # 3.should_not be_instance_of(Numeric) => 3.instance_of?(Numeric) #fails
76
+ #
77
+ # RSpec will also create custom matchers for predicates like +has_key?+. To
78
+ # use this feature, just state that the object should have_key(:key) and RSpec will
79
+ # call has_key?(:key) on the target. For example:
80
+ #
81
+ # {:a => "A"}.should have_key(:a) => {:a => "A"}.has_key?(:a) #passes
82
+ # {:a => "A"}.should have_key(:b) => {:a => "A"}.has_key?(:b) #fails
83
+ #
84
+ # You can use this feature to invoke any predicate that begins with "has_", whether it is
85
+ # part of the Ruby libraries (like +Hash#has_key?+) or a method you wrote on your own class.
86
+ #
87
+ # == Custom Matchers
88
+ #
89
+ # When you find that none of the stock Expectation Matchers provide a natural
90
+ # feeling expectation, you can very easily write your own using RSpec's matcher
91
+ # DSL or writing one from scratch.
92
+ #
93
+ # === Matcher DSL
94
+ #
95
+ # Imagine that you are writing a game in which players can be in various
96
+ # zones on a virtual board. To specify that bob should be in zone 4, you
97
+ # could say:
98
+ #
99
+ # bob.current_zone.should eql(Zone.new("4"))
100
+ #
101
+ # But you might find it more expressive to say:
102
+ #
103
+ # bob.should be_in_zone("4")
104
+ #
105
+ # and/or
106
+ #
107
+ # bob.should_not be_in_zone("3")
108
+ #
109
+ # You can create such a matcher like so:
110
+ #
111
+ # Rspec::Matchers.define :be_in_zone do |zone|
112
+ # match do |player|
113
+ # player.in_zone?(zone)
114
+ # end
115
+ # end
116
+ #
117
+ # This will generate a <tt>be_in_zone</tt> method that returns a matcher
118
+ # with logical default messages for failures. You can override the failure
119
+ # messages and the generated description as follows:
120
+ #
121
+ # Rspec::Matchers.define :be_in_zone do |zone|
122
+ # match do |player|
123
+ # player.in_zone?(zone)
124
+ # end
125
+ # failure_message_for_should do |player|
126
+ # # generate and return the appropriate string.
127
+ # end
128
+ # failure_message_for_should_not do |player|
129
+ # # generate and return the appropriate string.
130
+ # end
131
+ # description do
132
+ # # generate and return the appropriate string.
133
+ # end
134
+ # end
135
+ #
136
+ # Each of the message-generation methods has access to the block arguments
137
+ # passed to the <tt>create</tt> method (in this case, <tt>zone</tt>). The
138
+ # failure message methods (<tt>failure_message_for_should</tt> and
139
+ # <tt>failure_message_for_should_not</tt>) are passed the actual value (the
140
+ # receiver of <tt>should</tt> or <tt>should_not</tt>).
141
+ #
142
+ # === Custom Matcher from scratch
143
+ #
144
+ # You could also write a custom matcher from scratch, as follows:
145
+ #
146
+ # class BeInZone
147
+ # def initialize(expected)
148
+ # @expected = expected
149
+ # end
150
+ # def matches?(target)
151
+ # @target = target
152
+ # @target.current_zone.eql?(Zone.new(@expected))
153
+ # end
154
+ # def failure_message_for_should
155
+ # "expected #{@target.inspect} to be in Zone #{@expected}"
156
+ # end
157
+ # def failure_message_for_should_not
158
+ # "expected #{@target.inspect} not to be in Zone #{@expected}"
159
+ # end
160
+ # end
161
+ #
162
+ # ... and a method like this:
163
+ #
164
+ # def be_in_zone(expected)
165
+ # BeInZone.new(expected)
166
+ # end
167
+ #
168
+ # And then expose the method to your specs. This is normally done
169
+ # by including the method and the class in a module, which is then
170
+ # included in your spec:
171
+ #
172
+ # module CustomGameMatchers
173
+ # class BeInZone
174
+ # ...
175
+ # end
176
+ #
177
+ # def be_in_zone(expected)
178
+ # ...
179
+ # end
180
+ # end
181
+ #
182
+ # describe "Player behaviour" do
183
+ # include CustomGameMatchers
184
+ # ...
185
+ # end
186
+ #
187
+ # or you can include in globally in a spec_helper.rb file <tt>require</tt>d
188
+ # from your spec file(s):
189
+ #
190
+ # Rspec::Runner.configure do |config|
191
+ # config.include(CustomGameMatchers)
192
+ # end
193
+ #
194
+ module Matchers; end
195
+ end