Skip to content

Instantly share code, notes, and snippets.

@joshaven
Created March 5, 2010 03:48
Show Gist options
  • Save joshaven/322435 to your computer and use it in GitHub Desktop.
Save joshaven/322435 to your computer and use it in GitHub Desktop.
From e5d5ee1cafe47b93dfa604954a6c3cc82a9fad9e Mon Sep 17 00:00:00 2001
From: Joshaven Potter <joshaven@Joshaven-Potters-MacBook-Pro.local>
Date: Thu, 4 Mar 2010 22:45:47 -0500
Subject: [PATCH] Add the following matchers: :be_one_of, :be_in, & :be_part_of
---
lib/spec/matchers.rb | 1 +
lib/spec/matchers/be_one_of.rb | 46 +++++++++++++++++++++++++++++++++++++++
spec/spec/matchers/be_one_of.rb | 42 +++++++++++++++++++++++++++++++++++
3 files changed, 89 insertions(+), 0 deletions(-)
create mode 100644 lib/spec/matchers/be_one_of.rb
create mode 100644 spec/spec/matchers/be_one_of.rb
diff --git a/lib/spec/matchers.rb b/lib/spec/matchers.rb
index 4ef8329..06bfef1 100644
--- a/lib/spec/matchers.rb
+++ b/lib/spec/matchers.rb
@@ -6,6 +6,7 @@ require 'spec/matchers/be'
require 'spec/matchers/be_close'
require 'spec/matchers/be_instance_of'
require 'spec/matchers/be_kind_of'
+require 'spec/matchers/be_one_of'
require 'spec/matchers/change'
require 'spec/matchers/eql'
require 'spec/matchers/equal'
diff --git a/lib/spec/matchers/be_one_of.rb b/lib/spec/matchers/be_one_of.rb
new file mode 100644
index 0000000..8a8f5c1
--- /dev/null
+++ b/lib/spec/matchers/be_one_of.rb
@@ -0,0 +1,46 @@
+module Spec
+ module Matchers
+ # :call-seq:
+ # should be_one_of(expected)
+ # should_not be_one_of(expected)
+ #
+ # Passes if expected includes actual. This works for Arrays Hashes and Strings.
+ #
+ # Aliased as :be_in & :be_part_of
+ #
+ # == Examples
+ # "a".should be_one_of(["a", "b", "c"])
+ # :a.should be_one_of([[[:a], :b], :c])
+ # {:a => true}.should be_one_of({:a => true, :b => true})
+
+
+ def be_one_of(*expected)
+ called_by_name = Kernel.caller(0).first[/`([^'?!]+)[?!]?'/, 1].to_sym
+
+ Matcher.new called_by_name, *expected do |*_expected_|
+ match do |actual|
+ helper(actual, *_expected_)
+ end
+
+ def helper(actual, *_expected_)
+ _expected_.each do |expected|
+ if expected.is_a? Array
+ return true if expected.flatten.include? actual
+ elsif expected.is_a? String
+ return true if expected.include? actual
+ elsif expected.is_a? Hash
+ actual.each_pair do |k,v|
+ return false unless expected[k] == v
+ end
+ return true
+ end
+ end
+ false
+ end
+
+ end
+ end
+ alias_method :be_in, :be_one_of
+ alias_method :be_part_of, :be_one_of
+ end
+end
diff --git a/spec/spec/matchers/be_one_of.rb b/spec/spec/matchers/be_one_of.rb
new file mode 100644
index 0000000..f0f2d7d
--- /dev/null
+++ b/spec/spec/matchers/be_one_of.rb
@@ -0,0 +1,42 @@
+require 'spec/spec_helper'
+
+require File.dirname(__FILE__) + '/../../../lib/spec'
+require File.dirname(__FILE__) + '/../../../lib/spec/matchers/be_one_of'
+
+describe 'should be_one_of()' do
+ [:be_one_of, :be_in, :be_part_of].each do |method|
+ describe 'successes' do
+ it 'should pass when expected is a String which contains the actual' do
+ 'b'.should send(method, 'abc')
+ end
+
+ it 'should pass when expected is an Array which contains the actual' do
+ 'a'.should send(method, %w(a b c))
+ end
+
+ it 'should pass when expected is a multi-dimensional Array which contains the actual' do
+ :a.should send(method, [[[:a], :b], :c])
+ :b.should send(method, [[[:a], :b], :c])
+ :c.should send(method, [[[:a], :b], :c])
+ end
+
+ it 'should pass when expected is a Hash which contains a Hash' do
+ {:b=>true, :a=>true}.should send(method, {:a=>true, :b=>true, :c=>true})
+ end
+ end
+
+ describe 'failures' do
+ it 'should fail when expected is a String which does not contain the actual' do
+ 'd'.should_not send(method, 'abc')
+ end
+
+ it 'should fail when expected is an array which does not contains the actual' do
+ 'd'.should_not send(method, %w(a b c))
+ end
+
+ it 'should fail when expected is a hash which does not contain a hash' do
+ {:b=>true, :a=>true}.should send(method, {:a=>true, :b=>true, :c=>true})
+ end
+ end
+ end
+end
\ No newline at end of file
--
1.6.6
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment