xdotcommer-rspec-custom-matchers 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.markdown +54 -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,54 @@
|
|
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
|
+
TODO
|
49
|
+
----
|
50
|
+
|
51
|
+
- should support `matcher(:x){}` as well as merb's `Spec::Matcher.create`, which has more features and can be found at `merb-core/lib/merb-core/test/test_ext/rspec.rb`
|
52
|
+
|
53
|
+
|
54
|
+
[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: xdotcommer-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 mcowden@yahoo.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
|
+
|