aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/plugins/rspec/lib/spec/matchers
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/plugins/rspec/lib/spec/matchers')
-rw-r--r--vendor/plugins/rspec/lib/spec/matchers/be_instance_of.rb26
-rw-r--r--vendor/plugins/rspec/lib/spec/matchers/be_kind_of.rb26
-rw-r--r--vendor/plugins/rspec/lib/spec/matchers/compatibility.rb14
-rw-r--r--vendor/plugins/rspec/lib/spec/matchers/dsl.rb20
-rw-r--r--vendor/plugins/rspec/lib/spec/matchers/errors.rb5
-rw-r--r--vendor/plugins/rspec/lib/spec/matchers/extensions/instance_exec.rb31
-rw-r--r--vendor/plugins/rspec/lib/spec/matchers/generated_descriptions.rb36
-rw-r--r--vendor/plugins/rspec/lib/spec/matchers/match_array.rb71
-rw-r--r--vendor/plugins/rspec/lib/spec/matchers/matcher.rb87
-rw-r--r--vendor/plugins/rspec/lib/spec/matchers/method_missing.rb9
-rw-r--r--vendor/plugins/rspec/lib/spec/matchers/pretty.rb37
-rw-r--r--vendor/plugins/rspec/lib/spec/matchers/wrap_expectation.rb55
12 files changed, 417 insertions, 0 deletions
diff --git a/vendor/plugins/rspec/lib/spec/matchers/be_instance_of.rb b/vendor/plugins/rspec/lib/spec/matchers/be_instance_of.rb
new file mode 100644
index 000000000..ffc238405
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/matchers/be_instance_of.rb
@@ -0,0 +1,26 @@
+module Spec
+ module Matchers
+ # :call-seq:
+ # should be_instance_of(expected)
+ # should be_an_instance_of(expected)
+ # should_not be_instance_of(expected)
+ # should_not be_an_instance_of(expected)
+ #
+ # Passes if actual.instance_of?(expected)
+ #
+ # == Examples
+ #
+ # 5.should be_instance_of(Fixnum)
+ # 5.should_not be_instance_of(Numeric)
+ # 5.should_not be_instance_of(Float)
+ def be_an_instance_of(expected)
+ Matcher.new :be_an_instance_of, expected do |_expected_|
+ match do |actual|
+ actual.instance_of?(_expected_)
+ end
+ end
+ end
+
+ alias_method :be_instance_of, :be_an_instance_of
+ end
+end
diff --git a/vendor/plugins/rspec/lib/spec/matchers/be_kind_of.rb b/vendor/plugins/rspec/lib/spec/matchers/be_kind_of.rb
new file mode 100644
index 000000000..6a1fddc13
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/matchers/be_kind_of.rb
@@ -0,0 +1,26 @@
+module Spec
+ module Matchers
+ # :call-seq:
+ # should be_kind_of(expected)
+ # should be_a_kind_of(expected)
+ # should_not be_kind_of(expected)
+ # should_not be_a_kind_of(expected)
+ #
+ # Passes if actual.kind_of?(expected)
+ #
+ # == Examples
+ #
+ # 5.should be_kind_of(Fixnum)
+ # 5.should be_kind_of(Numeric)
+ # 5.should_not be_kind_of(Float)
+ def be_a_kind_of(expected)
+ Matcher.new :be_a_kind_of, expected do |_expected_|
+ match do |actual|
+ actual.kind_of?(_expected_)
+ end
+ end
+ end
+
+ alias_method :be_kind_of, :be_a_kind_of
+ end
+end
diff --git a/vendor/plugins/rspec/lib/spec/matchers/compatibility.rb b/vendor/plugins/rspec/lib/spec/matchers/compatibility.rb
new file mode 100644
index 000000000..3b3ddb9b6
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/matchers/compatibility.rb
@@ -0,0 +1,14 @@
+Spec::Matchers.constants.each do |c|
+ if Class === (klass = Spec::Matchers.const_get(c))
+ if klass.public_instance_methods.any? {|m| ['failure_message_for_should',:failure_message_for_should].include?(m)}
+ klass.class_eval do
+ alias_method :failure_message, :failure_message_for_should
+ end
+ end
+ if klass.public_instance_methods.any? {|m| ['failure_message_for_should_not',:failure_message_for_should_not].include?(m)}
+ klass.class_eval do
+ alias_method :negative_failure_message, :failure_message_for_should_not
+ end
+ end
+ end
+end
diff --git a/vendor/plugins/rspec/lib/spec/matchers/dsl.rb b/vendor/plugins/rspec/lib/spec/matchers/dsl.rb
new file mode 100644
index 000000000..73f363457
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/matchers/dsl.rb
@@ -0,0 +1,20 @@
+module Spec
+ module Matchers
+ module DSL
+ # See Spec::Matchers
+ def define(name, &declarations)
+ define_method name do |*expected|
+ Spec::Matchers::Matcher.new name, *expected, &declarations
+ end
+ end
+
+ # Deprecated - use define
+ def create(name, &declarations)
+ Spec.deprecate("Spec::Matchers.create","Spec::Matchers.define")
+ define(name, &declarations)
+ end
+ end
+ end
+end
+
+Spec::Matchers.extend Spec::Matchers::DSL
diff --git a/vendor/plugins/rspec/lib/spec/matchers/errors.rb b/vendor/plugins/rspec/lib/spec/matchers/errors.rb
new file mode 100644
index 000000000..49c267797
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/matchers/errors.rb
@@ -0,0 +1,5 @@
+module Spec
+ module Matchers
+ class MatcherError < StandardError; end
+ end
+end \ No newline at end of file
diff --git a/vendor/plugins/rspec/lib/spec/matchers/extensions/instance_exec.rb b/vendor/plugins/rspec/lib/spec/matchers/extensions/instance_exec.rb
new file mode 100644
index 000000000..ca7e14ead
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/matchers/extensions/instance_exec.rb
@@ -0,0 +1,31 @@
+module Spec
+ module Matchers
+ module InstanceExec
+ unless respond_to?(:instance_exec)
+ # based on Bounded Spec InstanceExec (Mauricio Fernandez)
+ # http://eigenclass.org/hiki/bounded+space+instance_exec
+ # - uses singleton_class of matcher instead of global
+ # InstanceExecHelper module
+ # - this keeps it scoped to this class only, which is the
+ # only place we need it
+ # - only necessary for ruby 1.8.6
+ def instance_exec(*args, &block)
+ singleton_class = (class << self; self; end)
+ begin
+ orig_critical, Thread.critical = Thread.critical, true
+ n = 0
+ n += 1 while respond_to?(method_name="__instance_exec#{n}")
+ singleton_class.module_eval{ define_method(:__instance_exec, &block) }
+ ensure
+ Thread.critical = orig_critical
+ end
+ begin
+ return send(:__instance_exec, *args)
+ ensure
+ singleton_class.module_eval{ remove_method(:__instance_exec) } rescue nil
+ end
+ end
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/vendor/plugins/rspec/lib/spec/matchers/generated_descriptions.rb b/vendor/plugins/rspec/lib/spec/matchers/generated_descriptions.rb
new file mode 100644
index 000000000..2340f57d8
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/matchers/generated_descriptions.rb
@@ -0,0 +1,36 @@
+module Spec
+ module Matchers
+ class << self
+ attr_accessor :last_matcher, :last_should # :nodoc:
+ end
+
+ def self.clear_generated_description
+ self.last_matcher = nil
+ self.last_should = nil
+ end
+
+ def self.generated_description
+ return nil if last_should.nil?
+ "#{last_should.to_s.gsub('_',' ')} #{last_description}"
+ end
+
+ private
+
+ def self.last_description
+ last_matcher.respond_to?(:description) ? last_matcher.description : <<-MESSAGE
+When you call a matcher in an example without a String, like this:
+
+specify { object.should matcher }
+
+or this:
+
+it { should matcher }
+
+RSpec expects the matcher to have a #description method. You should either
+add a String to the example this matcher is being used in, or give it a
+description method. Then you won't have to suffer this lengthy warning again.
+MESSAGE
+ end
+ end
+end
+
diff --git a/vendor/plugins/rspec/lib/spec/matchers/match_array.rb b/vendor/plugins/rspec/lib/spec/matchers/match_array.rb
new file mode 100644
index 000000000..51b4f3929
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/matchers/match_array.rb
@@ -0,0 +1,71 @@
+module Spec
+ module Matchers
+
+ class MatchArray #:nodoc:
+ include Spec::Matchers::Pretty
+
+ def initialize(expected)
+ @expected = expected
+ end
+
+ def matches?(actual)
+ @actual = actual
+ @extra_items = difference_between_arrays(@actual, @expected)
+ @missing_items = difference_between_arrays(@expected, @actual)
+ @extra_items.empty? & @missing_items.empty?
+ end
+
+ def failure_message_for_should
+ message = "expected collection contained: #{safe_sort(@expected).inspect}\n"
+ message += "actual collection contained: #{safe_sort(@actual).inspect}\n"
+ message += "the missing elements were: #{safe_sort(@missing_items).inspect}\n" unless @missing_items.empty?
+ message += "the extra elements were: #{safe_sort(@extra_items).inspect}\n" unless @extra_items.empty?
+ message
+ end
+
+ def failure_message_for_should_not
+ "Matcher does not support should_not"
+ end
+
+ def description
+ "contain exactly #{_pretty_print(@expected)}"
+ end
+
+ private
+
+ def safe_sort(array)
+ array.all?{|item| item.respond_to?(:<=>)} ? array.sort : array
+ end
+
+ def difference_between_arrays(array_1, array_2)
+ difference = array_1.dup
+ array_2.each do |element|
+ if index = difference.index(element)
+ difference.delete_at(index)
+ end
+ end
+ difference
+ end
+
+
+ end
+
+ # :call-seq:
+ # should =~ expected
+ #
+ # Passes if actual contains all of the expected regardless of order.
+ # This works for collections. Pass in multiple args and it will only
+ # pass if all args are found in collection.
+ #
+ # NOTE: there is no should_not version of array.should =~ other_array
+ #
+ # == Examples
+ #
+ # [1,2,3].should =~ [1,2,3] # => would pass
+ # [1,2,3].should =~ [2,3,1] # => would pass
+ # [1,2,3,4].should =~ [1,2,3] # => would fail
+ # [1,2,2,3].should =~ [1,2,3] # => would fail
+ # [1,2,3].should =~ [1,2,3,4] # => would fail
+ OperatorMatcher.register(Array, '=~', Spec::Matchers::MatchArray)
+ end
+end
diff --git a/vendor/plugins/rspec/lib/spec/matchers/matcher.rb b/vendor/plugins/rspec/lib/spec/matchers/matcher.rb
new file mode 100644
index 000000000..165ddffb5
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/matchers/matcher.rb
@@ -0,0 +1,87 @@
+module Spec
+ module Matchers
+ class Matcher
+ include Spec::Matchers::InstanceExec
+ include Spec::Matchers::Pretty
+ include Spec::Matchers
+
+ attr_reader :expected, :actual
+
+ def initialize(name, *expected, &declarations)
+ @name = name
+ @expected = expected
+ @actual = nil
+ @diffable = false
+ @messages = {
+ :description => lambda {"#{name_to_sentence}#{expected_to_sentence}"},
+ :failure_message_for_should => lambda {|actual| "expected #{actual.inspect} to #{name_to_sentence}#{expected_to_sentence}"},
+ :failure_message_for_should_not => lambda {|actual| "expected #{actual.inspect} not to #{name_to_sentence}#{expected_to_sentence}"}
+ }
+ making_declared_methods_public do
+ instance_exec(*@expected, &declarations)
+ end
+ end
+
+ def matches?(actual)
+ instance_exec(@actual = actual, &@match_block)
+ end
+
+ def description(&block)
+ cache_or_call_cached(:description, &block)
+ end
+
+ def failure_message_for_should(&block)
+ cache_or_call_cached(:failure_message_for_should, actual, &block)
+ end
+
+ def failure_message_for_should_not(&block)
+ cache_or_call_cached(:failure_message_for_should_not, actual, &block)
+ end
+
+ def match(&block)
+ @match_block = block
+ end
+
+ def diffable?
+ @diffable
+ end
+
+ def diffable
+ @diffable = true
+ end
+
+ private
+
+ def making_declared_methods_public # :nodoc:
+ # Our home-grown instance_exec in ruby 1.8.6 results in any methods
+ # declared in the block eval'd by instance_exec in the block to which we
+ # are yielding here are scoped private. This is NOT the case for Ruby
+ # 1.8.7 or 1.9.
+ #
+ # Also, due some crazy scoping that I don't understand, these methods
+ # are actually available in the specs (something about the matcher being
+ # defined in the scope of Spec::Matchers or within an example), so not
+ # doing the following will not cause specs to fail, but they *will*
+ # cause features to fail and that will make users unhappy. So don't.
+ orig_private_methods = private_methods
+ yield
+ st = (class << self; self; end)
+ (private_methods - orig_private_methods).each {|m| st.__send__ :public, m}
+ end
+
+ def cache_or_call_cached(key, actual=nil, &block)
+ block ? @messages[key] = block :
+ actual.nil? ? @messages[key].call : @messages[key].call(actual)
+ end
+
+ def name_to_sentence
+ split_words(@name)
+ end
+
+ def expected_to_sentence
+ to_sentence(@expected)
+ end
+
+ end
+ end
+end
diff --git a/vendor/plugins/rspec/lib/spec/matchers/method_missing.rb b/vendor/plugins/rspec/lib/spec/matchers/method_missing.rb
new file mode 100644
index 000000000..ae7f39795
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/matchers/method_missing.rb
@@ -0,0 +1,9 @@
+module Spec
+ module Matchers
+ def method_missing(sym, *args, &block) # :nodoc:
+ return Matchers::Be.new(sym, *args) if sym.to_s =~ /^be_/
+ return Matchers::Has.new(sym, *args) if sym.to_s =~ /^have_/
+ super
+ end
+ end
+end
diff --git a/vendor/plugins/rspec/lib/spec/matchers/pretty.rb b/vendor/plugins/rspec/lib/spec/matchers/pretty.rb
new file mode 100644
index 000000000..152058373
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/matchers/pretty.rb
@@ -0,0 +1,37 @@
+module Spec
+ module Matchers
+ module Pretty
+ def split_words(sym)
+ sym.to_s.gsub(/_/,' ')
+ end
+
+ def to_sentence(words)
+ words = words.map{|w| w.inspect}
+ case words.length
+ when 0
+ ""
+ when 1
+ " #{words[0]}"
+ when 2
+ " #{words[0]} and #{words[1]}"
+ else
+ " #{words[0...-1].join(', ')}, and #{words[-1]}"
+ end
+ end
+
+ def _pretty_print(array)
+ result = ""
+ array.each_with_index do |item, index|
+ if index < (array.length - 2)
+ result << "#{item.inspect}, "
+ elsif index < (array.length - 1)
+ result << "#{item.inspect} and "
+ else
+ result << "#{item.inspect}"
+ end
+ end
+ result
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/vendor/plugins/rspec/lib/spec/matchers/wrap_expectation.rb b/vendor/plugins/rspec/lib/spec/matchers/wrap_expectation.rb
new file mode 100644
index 000000000..95162cae1
--- /dev/null
+++ b/vendor/plugins/rspec/lib/spec/matchers/wrap_expectation.rb
@@ -0,0 +1,55 @@
+module Spec
+ module Matchers
+ # wraps an expectation in a block that will return true if the
+ # expectation passes and false if it fails (without bubbling up
+ # the failure).
+ #
+ # This is intended to be used in the context of a simple matcher,
+ # and is especially useful for wrapping multiple expectations or
+ # one or more assertions from test/unit extensions when running
+ # with test/unit.
+ #
+ # == Examples
+ #
+ # def eat_cheese(cheese)
+ # simple_matcher do |mouse, matcher|
+ # matcher.failure_message = "expected #{mouse} to eat cheese"
+ # wrap_expectation do |matcher|
+ # assert_eats_cheese(mouse)
+ # end
+ # end
+ # end
+ #
+ # describe Mouse do
+ # it "eats cheese" do
+ # Mouse.new.should eat_cheese
+ # end
+ # end
+ #
+ # You might be wondering "why would I do this if I could just say"
+ # assert_eats_cheese?", a fair question, indeed. You might prefer
+ # to replace the word assert with something more aligned with the
+ # rest of your code examples. You are using rspec, after all.
+ #
+ # The other benefit you get is that you can use the negative version
+ # of the matcher:
+ #
+ # describe Cat do
+ # it "does not eat cheese" do
+ # Cat.new.should_not eat_cheese
+ # end
+ # end
+ #
+ # So in the event there is no assert_does_not_eat_cheese available,
+ # you're all set!
+ def wrap_expectation(matcher, &block)
+ begin
+ block.call(matcher)
+ return true
+ rescue Exception => e
+ matcher.failure_message = e.message
+ return false
+ end
+ end
+ end
+end