remi-rspec-custom-matchers 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +49 -0
- data/VERSION.yml +4 -0
- data/lib/rspec-custom-matchers.rb +68 -0
- data/spec/custom_matcher_spec.rb +41 -0
- data/spec/matcher_spec.rb +38 -0
- data/spec/spec_helper.rb +1 -0
- metadata +60 -0
data/README.markdown
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
RSpec Custom Matchers
|
2
|
+
=====================
|
3
|
+
|
4
|
+
This gem makes it really easy to define your own
|
5
|
+
RSpec custom matchers in 1 line of code.
|
6
|
+
|
7
|
+
This class / project is created by [xdotcommer][].
|
8
|
+
I forked it to make it an easy-to-install RubyGem
|
9
|
+
|
10
|
+
|
11
|
+
Install
|
12
|
+
-------
|
13
|
+
|
14
|
+
sudo gem install remi-rspec-custom-matchers -s http://gems.github.com
|
15
|
+
|
16
|
+
Usage
|
17
|
+
-----
|
18
|
+
|
19
|
+
Wherever you want to include the `matcher` method, `include CustomMatcher::Helper`
|
20
|
+
|
21
|
+
Remember, if you want to be able to call `matcher(:foo)` in the body of a class,
|
22
|
+
you might want to `extend CustomMatcher::Helper` instead of including it.
|
23
|
+
|
24
|
+
Personally, I like to keep all of my own custom matchers for a project in
|
25
|
+
a module, so I do ...
|
26
|
+
|
27
|
+
require 'rspec-custom-matchers'
|
28
|
+
|
29
|
+
module MyMatchers
|
30
|
+
extend CustomMatcher::Helper
|
31
|
+
|
32
|
+
matcher(:be_divisible_by) { |number, divisor| number % divisor == 0 }
|
33
|
+
matcher(:be_even) { |even| even % 2 == 0 }
|
34
|
+
matcher(:be_odd) { |odd| odd % 2 != 0 }
|
35
|
+
matcher(:be_equal_to)
|
36
|
+
end
|
37
|
+
|
38
|
+
and then, in my `spec_helper.rb`
|
39
|
+
|
40
|
+
require 'my_matchers'
|
41
|
+
|
42
|
+
Spec::Runner.configure do |config|
|
43
|
+
config.include MyMatchers # this will make the matchers available to your specs
|
44
|
+
end
|
45
|
+
|
46
|
+
That's how I do it!
|
47
|
+
|
48
|
+
|
49
|
+
[xdotcommer]: http://github.com/xdotcommer
|
data/VERSION.yml
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
$:.unshift File.dirname(__FILE__)
|
2
|
+
|
3
|
+
class CustomMatcher
|
4
|
+
|
5
|
+
def self.create(class_name, &block)
|
6
|
+
klass = Class.new(CustomMatcher)
|
7
|
+
klass.send(:define_method, :matcher, &block) if block_given?
|
8
|
+
Object.const_set(build_class_name(class_name), klass)
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(expected = nil)
|
12
|
+
@expected = expected
|
13
|
+
end
|
14
|
+
|
15
|
+
def failure_message
|
16
|
+
message
|
17
|
+
end
|
18
|
+
|
19
|
+
def negative_failure_message
|
20
|
+
message(false)
|
21
|
+
end
|
22
|
+
|
23
|
+
def matcher(target, expected)
|
24
|
+
target == expected
|
25
|
+
end
|
26
|
+
|
27
|
+
def matches?(target)
|
28
|
+
@target = target
|
29
|
+
if self.method(:matcher).arity == 2
|
30
|
+
matcher(@target, @expected)
|
31
|
+
else
|
32
|
+
matcher(@target)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def description *args
|
37
|
+
class_display_name
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def message(positive = true)
|
43
|
+
"#{positive ? 'Expected' : 'Did not expect'} #{@target.inspect} to #{class_display_name} #{@expected.inspect if self.method(:matcher).arity == 2}"
|
44
|
+
end
|
45
|
+
|
46
|
+
def class_display_name
|
47
|
+
self.class.to_s.gsub(/[A-Z]/) {|m| ' ' + m.downcase }.lstrip
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.build_class_name(class_name)
|
51
|
+
class_name.to_s.split('_').map {|s| s.capitalize}.join
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# module to include wherever you want the #matcher method defined
|
56
|
+
module CustomMatcher::Helper
|
57
|
+
def matcher(name, context = self, &block)
|
58
|
+
klass = CustomMatcher.create(name, &block)
|
59
|
+
begin
|
60
|
+
context.send(:define_method, name) { |*args| klass.new(*args) }
|
61
|
+
rescue NoMethodError
|
62
|
+
# the object we're trying to define this method on doesn't
|
63
|
+
# have a define_method method. let's be nice and go ahead
|
64
|
+
# and try defining this method on the class of the object.
|
65
|
+
context.class.send(:define_method, name) { |*args| klass.new(*args) }
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe CustomMatcher do
|
4
|
+
describe "subclasses, in general (initialized without a block)" do
|
5
|
+
before(:all) do
|
6
|
+
CustomMatcher.create(:be_an_example)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should inherit from Custom Matcher" do
|
10
|
+
BeAnExample.superclass.should == CustomMatcher
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should have the default matcher (==)" do
|
14
|
+
BeAnExample.new(10).matches?(10).should be_true
|
15
|
+
BeAnExample.new("10").matches?("10").should be_true
|
16
|
+
BeAnExample.new(Object.new).matches?(Object.new).should be_false
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should provide a failure message based on it's class" do
|
20
|
+
BeAnExample.new(10).failure_message.should == "Expected nil to be an example 10"
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should provide a negative failure message based on it's class" do
|
24
|
+
BeAnExample.new(10).negative_failure_message.should == "Did not expect nil to be an example 10"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "subclasses, initialized with a matcher block" do
|
29
|
+
before(:all) do
|
30
|
+
CustomMatcher.create(:be_divisible_by) do |target, expectation|
|
31
|
+
target % expectation == 0
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should take use the create block as the custom matcher" do
|
36
|
+
BeDivisibleBy.new(10).matches?(5).should be_false # 5 is NOT divisible by 10
|
37
|
+
BeDivisibleBy.new(10).matches?(20).should be_true # 20 IS divisible by 10
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
include CustomMatcher::Helper
|
4
|
+
|
5
|
+
matcher(:be_divisible_by) { |number, divisor| number % divisor == 0 }
|
6
|
+
matcher(:be_even) {|even| even % 2 == 0}
|
7
|
+
matcher(:be_odd) {|odd| odd % 2 != 0}
|
8
|
+
matcher(:be_equal_to)
|
9
|
+
|
10
|
+
describe "6" do
|
11
|
+
it "should be divisible by 3" do
|
12
|
+
6.should be_divisible_by(3)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should be divisible by 2" do
|
16
|
+
6.should be_divisible_by(2)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should not be divisible by 12" do
|
20
|
+
6.should_not be_divisible_by(12)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should be even" do
|
24
|
+
6.should be_even
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should not be odd" do
|
28
|
+
6.should_not be_odd
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should be equal to 6" do
|
32
|
+
6.should be_equal_to(6)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should not be equal to 7" do
|
36
|
+
6.should_not be_equal_to(7)
|
37
|
+
end
|
38
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../lib/rspec-custom-matchers'
|
metadata
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: remi-rspec-custom-matchers
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- xdotcommer
|
8
|
+
- remi
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2009-01-28 00:00:00 -08:00
|
14
|
+
default_executable:
|
15
|
+
dependencies: []
|
16
|
+
|
17
|
+
description: Define RSpec custom matchers in 1 line
|
18
|
+
email: remi@remitaylor.com
|
19
|
+
executables: []
|
20
|
+
|
21
|
+
extensions: []
|
22
|
+
|
23
|
+
extra_rdoc_files: []
|
24
|
+
|
25
|
+
files:
|
26
|
+
- VERSION.yml
|
27
|
+
- README.markdown
|
28
|
+
- lib/rspec-custom-matchers.rb
|
29
|
+
- spec/custom_matcher_spec.rb
|
30
|
+
- spec/matcher_spec.rb
|
31
|
+
- spec/spec_helper.rb
|
32
|
+
has_rdoc: true
|
33
|
+
homepage: http://github.com/remi/rspec-custom-matchers
|
34
|
+
post_install_message:
|
35
|
+
rdoc_options:
|
36
|
+
- --inline-source
|
37
|
+
- --charset=UTF-8
|
38
|
+
require_paths:
|
39
|
+
- lib
|
40
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: "0"
|
45
|
+
version:
|
46
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: "0"
|
51
|
+
version:
|
52
|
+
requirements: []
|
53
|
+
|
54
|
+
rubyforge_project:
|
55
|
+
rubygems_version: 1.2.0
|
56
|
+
signing_key:
|
57
|
+
specification_version: 2
|
58
|
+
summary: Define RSpec custom matchers in 1 line
|
59
|
+
test_files: []
|
60
|
+
|