dchelimsky-rspec 1.1.12 → 1.1.99.1
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +35 -0
- data/License.txt +1 -1
- data/Manifest.txt +22 -73
- data/README.txt +2 -2
- data/Rakefile +32 -7
- data/TODO.txt +9 -4
- data/bin/spec +1 -1
- data/cucumber.yml +2 -0
- data/examples/failing/spec_helper.rb +1 -1
- data/examples/passing/filtered_formatter.rb +18 -0
- data/examples/passing/filtered_formatter_example.rb +31 -0
- data/examples/passing/spec_helper.rb +1 -1
- data/examples/ruby1.9.compatibility/access_to_constants_spec.rb +17 -18
- data/features/before_and_after_blocks/before_and_after_blocks.feature +4 -4
- data/features/example_groups/autogenerated_docstrings.feature +2 -2
- data/features/example_groups/example_group_with_should_methods.feature +1 -1
- data/features/example_groups/nested_groups.feature +1 -1
- data/features/interop/examples_and_tests_together.feature +1 -1
- data/features/interop/test_but_not_test_unit.feature +1 -1
- data/features/interop/test_case_with_should_methods.feature +1 -1
- data/features/mock_framework_integration/use_flexmock.feature +22 -4
- data/features/mock_framework_integration/use_mocha.feature +27 -0
- data/features/mock_framework_integration/use_rr.feature +27 -0
- data/features/step_definitions/running_rspec.rb +5 -3
- data/features/support/env.rb +1 -1
- data/features-pending/cli/conditional_exclusion.feature +39 -0
- data/lib/{adapters → spec/adapters}/mock_frameworks/flexmock.rb +1 -0
- data/lib/{adapters → spec/adapters}/mock_frameworks/mocha.rb +1 -0
- data/lib/{adapters → spec/adapters}/mock_frameworks/rr.rb +1 -0
- data/lib/{adapters → spec/adapters}/mock_frameworks/rspec.rb +0 -1
- data/lib/spec/autorun.rb +3 -0
- data/lib/spec/example/before_and_after_hooks.rb +5 -20
- data/lib/spec/example/example_description.rb +15 -0
- data/lib/spec/example/example_group.rb +0 -15
- data/lib/spec/example/example_group_factory.rb +34 -46
- data/lib/spec/example/example_group_hierarchy.rb +53 -0
- data/lib/spec/example/example_group_methods.rb +96 -211
- data/lib/spec/example/example_methods.rb +62 -81
- data/lib/spec/example/module_reopening_fix.rb +23 -1
- data/lib/spec/example/predicate_matchers.rb +47 -0
- data/lib/spec/example/subject.rb +91 -0
- data/lib/spec/example.rb +4 -0
- data/lib/spec/expectations/extensions.rb +0 -1
- data/lib/spec/expectations/handler.rb +6 -1
- data/lib/spec/expectations.rb +1 -1
- data/lib/spec/interop/test/unit/testcase.rb +5 -22
- data/lib/spec/interop/test.rb +1 -0
- data/lib/spec/matchers/be.rb +2 -7
- data/lib/spec/matchers/be_close.rb +20 -5
- data/lib/spec/matchers/change.rb +5 -3
- data/lib/spec/matchers/eql.rb +24 -6
- data/lib/spec/matchers/equal.rb +24 -6
- data/lib/spec/matchers/exist.rb +21 -5
- data/lib/spec/matchers/generated_descriptions.rb +2 -2
- data/lib/spec/matchers/has.rb +28 -11
- data/lib/spec/matchers/match.rb +25 -7
- data/lib/spec/matchers/match_array.rb +1 -1
- data/lib/spec/matchers/method_missing.rb +2 -2
- data/lib/spec/matchers/operator_matcher.rb +12 -5
- data/lib/spec/matchers/raise_error.rb +1 -1
- data/lib/spec/matchers/respond_to.rb +1 -1
- data/lib/spec/matchers/satisfy.rb +5 -5
- data/lib/spec/matchers/throw_symbol.rb +1 -3
- data/lib/spec/mocks/argument_expectation.rb +1 -1
- data/lib/spec/mocks/argument_matchers.rb +233 -0
- data/lib/spec/mocks/error_generator.rb +2 -6
- data/lib/spec/mocks/message_expectation.rb +3 -11
- data/lib/spec/mocks/mock.rb +1 -1
- data/lib/spec/mocks/proxy.rb +5 -1
- data/lib/spec/runner/configuration.rb +3 -3
- data/lib/spec/runner/drb_command_line.rb +2 -1
- data/lib/spec/runner/example_group_runner.rb +2 -1
- data/lib/spec/runner/formatter/base_text_formatter.rb +28 -17
- data/lib/spec/runner/formatter/failing_example_groups_formatter.rb +3 -5
- data/lib/spec/runner/formatter/html_formatter.rb +2 -3
- data/lib/spec/runner/formatter/nested_text_formatter.rb +7 -25
- data/lib/spec/runner/formatter/progress_bar_formatter.rb +1 -1
- data/lib/spec/runner/formatter/specdoc_formatter.rb +1 -7
- data/lib/spec/runner/heckle_runner_unsupported.rb +1 -1
- data/lib/spec/runner/option_parser.rb +16 -19
- data/lib/spec/runner/options.rb +28 -26
- data/lib/spec/runner/reporter.rb +8 -9
- data/lib/spec/runner.rb +6 -28
- data/lib/spec/test/unit.rb +10 -0
- data/lib/spec/version.rb +2 -2
- data/{features/support → resources}/helpers/cmdline.rb +2 -2
- data/resources/rake/verify_rcov.rake +1 -1
- data/resources/spec/example_group_with_should_methods.rb +1 -1
- data/resources/spec/simple_spec.rb +1 -1
- data/resources/test/spec_and_test_together.rb +2 -3
- data/resources/test/spec_including_test_but_not_unit.rb +1 -1
- data/resources/test/test_case_with_should_methods.rb +2 -3
- data/rspec.gemspec +5 -5
- data/spec/spec/dsl/main_spec.rb +3 -3
- data/spec/spec/example/example_group_class_definition_spec.rb +11 -14
- data/spec/spec/example/example_group_factory_spec.rb +31 -44
- data/spec/spec/example/example_group_methods_spec.rb +86 -52
- data/spec/spec/example/example_group_spec.rb +16 -75
- data/spec/spec/example/example_matcher_spec.rb +10 -10
- data/spec/spec/example/example_methods_spec.rb +101 -241
- data/spec/spec/example/nested_example_group_spec.rb +2 -2
- data/spec/spec/example/pending_module_spec.rb +1 -1
- data/spec/spec/example/shared_example_group_spec.rb +2 -2
- data/spec/spec/interop/test/unit/resources/spec_that_fails.rb +2 -2
- data/spec/spec/interop/test/unit/resources/spec_that_passes.rb +2 -2
- data/spec/spec/interop/test/unit/resources/spec_with_errors.rb +2 -2
- data/spec/spec/interop/test/unit/resources/spec_with_options_hash.rb +2 -2
- data/spec/spec/interop/test/unit/resources/test_case_that_fails.rb +2 -2
- data/spec/spec/interop/test/unit/resources/test_case_that_passes.rb +2 -2
- data/spec/spec/interop/test/unit/resources/test_case_with_errors.rb +2 -2
- data/spec/spec/interop/test/unit/resources/testsuite_adapter_spec_with_test_unit.rb +2 -2
- data/spec/spec/matchers/change_spec.rb +8 -0
- data/spec/spec/matchers/exist_spec.rb +8 -4
- data/spec/spec/matchers/handler_spec.rb +8 -1
- data/spec/spec/matchers/matcher_methods_spec.rb +1 -1
- data/spec/spec/mocks/{bug_report_496.rb → bug_report_496_spec.rb} +0 -0
- data/spec/spec/mocks/failing_argument_matchers_spec.rb +95 -0
- data/spec/spec/mocks/nil_expectation_warning_spec.rb +1 -1
- data/spec/spec/mocks/passing_argument_matchers_spec.rb +145 -0
- data/spec/spec/runner/configuration_spec.rb +12 -12
- data/spec/spec/runner/formatter/base_text_formatter_spec.rb +72 -1
- data/spec/spec/runner/formatter/failing_example_groups_formatter_spec.rb +8 -8
- data/spec/spec/runner/formatter/failing_examples_formatter_spec.rb +4 -4
- data/spec/spec/runner/formatter/html_formatted-1.8.6.html +8 -8
- data/spec/spec/runner/formatter/html_formatted-1.8.7.html +38 -26
- data/spec/spec/runner/formatter/html_formatted-1.9.1.html +61 -53
- data/spec/spec/runner/formatter/html_formatter_spec.rb +100 -48
- data/spec/spec/runner/formatter/nested_text_formatter_spec.rb +20 -34
- data/spec/spec/runner/formatter/profile_formatter_spec.rb +1 -1
- data/spec/spec/runner/formatter/progress_bar_formatter_spec.rb +8 -6
- data/spec/spec/runner/formatter/specdoc_formatter_spec.rb +6 -6
- data/spec/spec/runner/formatter/text_mate_formatted-1.8.6.html +20 -20
- data/spec/spec/runner/formatter/text_mate_formatted-1.8.7.html +38 -26
- data/spec/spec/runner/formatter/{spec_mate_formatter_spec.rb → text_mate_formatter_spec.rb} +10 -8
- data/spec/spec/runner/heckle_runner_spec.rb +1 -1
- data/spec/spec/runner/option_parser_spec.rb +15 -13
- data/spec/spec/runner/options_spec.rb +34 -0
- data/spec/spec/runner/reporter_spec.rb +65 -61
- data/spec/spec/runner/spec_drb.opts +1 -0
- data/spec/spec/runner_spec.rb +7 -5
- data/spec/spec_helper.rb +23 -0
- metadata +25 -76
- data/examples/passing/legacy_spec.rb +0 -11
- data/features/support/helpers/story_helper.rb +0 -13
- data/lib/spec/expectations/extensions/string_and_symbol.rb +0 -17
- data/resources/spec/spec_with_flexmock.rb +0 -19
- data/spec/spec/spec_spec.rb +0 -21
@@ -1,6 +1,28 @@
|
|
1
1
|
module Spec
|
2
2
|
module Example
|
3
|
-
#
|
3
|
+
# When you reopen a module that is included in another module that is included in a class,
|
4
|
+
# the new material you define does not make it to the class. This fixes that.
|
5
|
+
#
|
6
|
+
# == Example
|
7
|
+
#
|
8
|
+
# module M1; end
|
9
|
+
#
|
10
|
+
# module M2
|
11
|
+
# def foo; "FOO"; end
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# class C
|
15
|
+
# include M1
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# module M1
|
19
|
+
# include M2
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# c = C.new
|
23
|
+
# c.foo
|
24
|
+
# NoMethodError: undefined method `foo' for #<C:0x5e89a4>
|
25
|
+
# from (irb):12
|
4
26
|
module ModuleReopeningFix
|
5
27
|
def child_modules
|
6
28
|
@child_modules ||= []
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Spec
|
2
|
+
module Example
|
3
|
+
module PredicateMatchers
|
4
|
+
# :call-seq:
|
5
|
+
# predicate_matchers[matcher_name] = method_on_object
|
6
|
+
# predicate_matchers[matcher_name] = [method1_on_object, method2_on_object]
|
7
|
+
#
|
8
|
+
# Dynamically generates a custom matcher that will match
|
9
|
+
# a predicate on your class. RSpec provides a couple of these
|
10
|
+
# out of the box:
|
11
|
+
#
|
12
|
+
# exist (for state expectations)
|
13
|
+
# File.should exist("path/to/file")
|
14
|
+
#
|
15
|
+
# an_instance_of (for mock argument matchers)
|
16
|
+
# mock.should_receive(:message).with(an_instance_of(String))
|
17
|
+
#
|
18
|
+
# == Examples
|
19
|
+
#
|
20
|
+
# class Fish
|
21
|
+
# def can_swim?
|
22
|
+
# true
|
23
|
+
# end
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# describe Fish do
|
27
|
+
# predicate_matchers[:swim] = :can_swim?
|
28
|
+
# it "should swim" do
|
29
|
+
# Fish.new.should swim
|
30
|
+
# end
|
31
|
+
# end
|
32
|
+
def predicate_matchers
|
33
|
+
@predicate_matchers ||= {}
|
34
|
+
end
|
35
|
+
|
36
|
+
def define_methods_from_predicate_matchers # :nodoc:
|
37
|
+
predicate_matchers.each_pair do |matcher_method, method_on_object|
|
38
|
+
define_method matcher_method do |*args|
|
39
|
+
eval("be_#{method_on_object.to_s.gsub('?','')}(*args)")
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module Spec
|
2
|
+
module Example
|
3
|
+
module Subject
|
4
|
+
module ExampleGroupMethods
|
5
|
+
# Defines an explicit subject for an example group which can then be the
|
6
|
+
# implicit receiver (through delegation) of calls to +should+.
|
7
|
+
#
|
8
|
+
# == Examples
|
9
|
+
#
|
10
|
+
# describe CheckingAccount, "with $50" do
|
11
|
+
# subject { CheckingAccount.new(:amount => 50, :currency => :USD) }
|
12
|
+
# it { should have_a_balance_of(50, :USD) }
|
13
|
+
# it { should_not be_overdrawn }
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# See +ExampleMethods#should+ for more information about this approach.
|
17
|
+
def subject(&block)
|
18
|
+
if block.nil?
|
19
|
+
@_subject_block || (described_class ? lambda {described_class.new} : lambda {})
|
20
|
+
else
|
21
|
+
@_subject_block = block
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
module ExampleMethods
|
27
|
+
# Returns the subject defined in ExampleGroupMethods#subject. The
|
28
|
+
# subject block is only executed once per example, the result of which
|
29
|
+
# is cached and returned by any subsequent calls to +subject+.
|
30
|
+
#
|
31
|
+
# If a class is passed to +describe+ and no subject is explicitly
|
32
|
+
# declared in the example group, then +subject+ will return a new
|
33
|
+
# instance of that class.
|
34
|
+
#
|
35
|
+
# == Examples
|
36
|
+
#
|
37
|
+
# # explicit subject defined by the subject method
|
38
|
+
# describe Person do
|
39
|
+
# subject { Person.new(:birthdate => 19.years.ago) }
|
40
|
+
# it "should be eligible to vote" do
|
41
|
+
# subject.should be_eligible_to_vote
|
42
|
+
# end
|
43
|
+
# end
|
44
|
+
#
|
45
|
+
# # implicit subject => { Person.new }
|
46
|
+
# describe Person do
|
47
|
+
# it "should be eligible to vote" do
|
48
|
+
# subject.should be_eligible_to_vote
|
49
|
+
# end
|
50
|
+
# end
|
51
|
+
def subject
|
52
|
+
@subject ||= instance_eval(&self.class.subject)
|
53
|
+
end
|
54
|
+
|
55
|
+
# When +should+ is called with no explicit receiver, the call is
|
56
|
+
# delegated to the object returned by +subject+. Combined with
|
57
|
+
# an implicit subject (see +subject+), this supports very concise
|
58
|
+
# expressions.
|
59
|
+
#
|
60
|
+
# == Examples
|
61
|
+
#
|
62
|
+
# describe Person do
|
63
|
+
# it { should be_eligible_to_vote }
|
64
|
+
# end
|
65
|
+
def should(matcher=nil)
|
66
|
+
if matcher
|
67
|
+
subject.should(matcher)
|
68
|
+
else
|
69
|
+
subject.should
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Just like +should+, +should_not+ delegates to the subject (implicit or
|
74
|
+
# explicit) of the example group.
|
75
|
+
#
|
76
|
+
# == Examples
|
77
|
+
#
|
78
|
+
# describe Person do
|
79
|
+
# it { should_not be_eligible_to_vote }
|
80
|
+
# end
|
81
|
+
def should_not(matcher=nil)
|
82
|
+
if matcher
|
83
|
+
subject.should_not(matcher)
|
84
|
+
else
|
85
|
+
subject.should_not
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
data/lib/spec/example.rb
CHANGED
@@ -173,9 +173,13 @@ module Spec
|
|
173
173
|
end
|
174
174
|
|
175
175
|
require 'timeout'
|
176
|
+
require 'spec/example/predicate_matchers'
|
177
|
+
require 'spec/example/example_description'
|
178
|
+
require 'spec/example/subject'
|
176
179
|
require 'spec/example/before_and_after_hooks'
|
177
180
|
require 'spec/example/pending'
|
178
181
|
require 'spec/example/module_reopening_fix'
|
182
|
+
require 'spec/example/example_group_hierarchy'
|
179
183
|
require 'spec/example/example_group_methods'
|
180
184
|
require 'spec/example/example_methods'
|
181
185
|
require 'spec/example/example_group'
|
@@ -22,7 +22,12 @@ module Spec
|
|
22
22
|
|
23
23
|
return ::Spec::Matchers::NegativeOperatorMatcher.new(actual) if matcher.nil?
|
24
24
|
|
25
|
-
match = matcher.
|
25
|
+
match = if matcher.respond_to?(:does_not_match?)
|
26
|
+
!matcher.does_not_match?(actual, &block)
|
27
|
+
else
|
28
|
+
matcher.matches?(actual, &block)
|
29
|
+
end
|
30
|
+
|
26
31
|
::Spec::Expectations.fail_with(matcher.negative_failure_message) if match
|
27
32
|
match
|
28
33
|
end
|
data/lib/spec/expectations.rb
CHANGED
@@ -44,7 +44,7 @@ module Spec
|
|
44
44
|
# <code>expected</code> and <code>target</code>, passes them
|
45
45
|
# to the differ to append a diff message to the failure message.
|
46
46
|
def self.fail_with(message, expected=nil, target=nil) # :nodoc:
|
47
|
-
if Array === message
|
47
|
+
if (Array === message) & (message.length == 3)
|
48
48
|
message, expected, target = message[0], message[1], message[2]
|
49
49
|
end
|
50
50
|
unless (differ.nil? || expected.nil? || target.nil?)
|
@@ -5,8 +5,7 @@ module Test
|
|
5
5
|
# This extension of the standard Test::Unit::TestCase makes RSpec
|
6
6
|
# available from within, so that you can do things like:
|
7
7
|
#
|
8
|
-
# require 'test/unit'
|
9
|
-
# require 'spec'
|
8
|
+
# require 'spec/test/unit'
|
10
9
|
#
|
11
10
|
# class MyTest < Test::Unit::TestCase
|
12
11
|
# it "should work with Test::Unit assertions" do
|
@@ -41,33 +40,17 @@ module Test
|
|
41
40
|
before(:each) {setup}
|
42
41
|
after(:each) {teardown}
|
43
42
|
|
44
|
-
def initialize(
|
45
|
-
|
46
|
-
|
47
|
-
# TODO - examples fail in rspec-rails if we remove "|| pending_implementation"
|
48
|
-
# - find a way to fail without it in rspec's code examples
|
49
|
-
@_implementation = implementation || pending_implementation
|
50
|
-
|
51
|
-
@_result = ::Test::Unit::TestResult.new
|
52
|
-
# @method_name is important to set here because it complies with Test::Unit's interface.
|
43
|
+
def initialize(description, options={}, &implementation)
|
44
|
+
super
|
53
45
|
# Some Test::Unit extensions depend on @method_name being present.
|
54
|
-
@method_name =
|
55
|
-
|
56
|
-
# TODO - this is necessary to run single examples in rspec-rails, but I haven't
|
57
|
-
# found a good way to write a failing example just within rspec core
|
58
|
-
@_backtrace = caller
|
46
|
+
@method_name = description
|
47
|
+
@_result = ::Test::Unit::TestResult.new
|
59
48
|
end
|
60
49
|
|
61
50
|
def run(ignore_this_argument=nil)
|
62
51
|
super()
|
63
52
|
end
|
64
53
|
|
65
|
-
private
|
66
|
-
|
67
|
-
def pending_implementation
|
68
|
-
error = Spec::Example::NotYetImplementedError.new(caller)
|
69
|
-
lambda { raise(error) }
|
70
|
-
end
|
71
54
|
end
|
72
55
|
end
|
73
56
|
end
|
data/lib/spec/interop/test.rb
CHANGED
data/lib/spec/matchers/be.rb
CHANGED
@@ -60,12 +60,7 @@ it reads really poorly.
|
|
60
60
|
|
61
61
|
private
|
62
62
|
def match_or_compare(actual)
|
63
|
-
|
64
|
-
when TrueClass
|
65
|
-
@actual
|
66
|
-
else
|
67
|
-
@actual.__send__(comparison_method, @expected)
|
68
|
-
end
|
63
|
+
TrueClass === @expected ? @actual : @actual.__send__(comparison_method, @expected)
|
69
64
|
end
|
70
65
|
|
71
66
|
def comparison_method
|
@@ -87,7 +82,7 @@ it reads really poorly.
|
|
87
82
|
def parse_expected(expected)
|
88
83
|
["be_an_","be_a_","be_"].each do |prefix|
|
89
84
|
handling_predicate!
|
90
|
-
if expected.
|
85
|
+
if expected.to_s =~ /^#{prefix}/
|
91
86
|
set_prefix(prefix)
|
92
87
|
expected = expected.to_s.sub(prefix,"")
|
93
88
|
[true, false, nil].each do |val|
|
@@ -1,5 +1,24 @@
|
|
1
1
|
module Spec
|
2
2
|
module Matchers
|
3
|
+
|
4
|
+
class BeClose
|
5
|
+
def initialize(expected, delta)
|
6
|
+
@expected, @delta = expected, delta
|
7
|
+
end
|
8
|
+
|
9
|
+
def matches?(actual)
|
10
|
+
@actual = actual
|
11
|
+
(@actual - @expected).abs < @delta
|
12
|
+
end
|
13
|
+
|
14
|
+
def failure_message
|
15
|
+
"expected #{@expected} +/- (< #{@delta}), got #{@actual}"
|
16
|
+
end
|
17
|
+
|
18
|
+
def description
|
19
|
+
"be close to #{@expected} (within +- #{@delta})"
|
20
|
+
end
|
21
|
+
end
|
3
22
|
|
4
23
|
# :call-seq:
|
5
24
|
# should be_close(expected, delta)
|
@@ -11,11 +30,7 @@ module Spec
|
|
11
30
|
#
|
12
31
|
# result.should be_close(3.0, 0.5)
|
13
32
|
def be_close(expected, delta)
|
14
|
-
|
15
|
-
matcher.failure_message = "expected #{expected} +/- (< #{delta}), got #{actual}"
|
16
|
-
matcher.description = "be close to #{expected} (within +- #{delta})"
|
17
|
-
(actual - expected).abs < delta
|
18
|
-
end
|
33
|
+
BeClose.new(expected, delta)
|
19
34
|
end
|
20
35
|
end
|
21
36
|
end
|
data/lib/spec/matchers/change.rb
CHANGED
@@ -5,9 +5,7 @@ module Spec
|
|
5
5
|
class Change #:nodoc:
|
6
6
|
def initialize(receiver=nil, message=nil, &block)
|
7
7
|
@message = message || "result"
|
8
|
-
@value_proc = block || lambda {
|
9
|
-
receiver.__send__(message)
|
10
|
-
}
|
8
|
+
@value_proc = block || lambda {receiver.__send__(message)}
|
11
9
|
end
|
12
10
|
|
13
11
|
def matches?(event_proc)
|
@@ -84,6 +82,10 @@ MESSAGE
|
|
84
82
|
@from = from
|
85
83
|
self
|
86
84
|
end
|
85
|
+
|
86
|
+
def description
|
87
|
+
"change ##{@message}"
|
88
|
+
end
|
87
89
|
end
|
88
90
|
|
89
91
|
# :call-seq:
|
data/lib/spec/matchers/eql.rb
CHANGED
@@ -1,5 +1,28 @@
|
|
1
1
|
module Spec
|
2
2
|
module Matchers
|
3
|
+
class Eql
|
4
|
+
def initialize(expected)
|
5
|
+
@expected = expected
|
6
|
+
end
|
7
|
+
|
8
|
+
def matches?(actual)
|
9
|
+
@actual = actual
|
10
|
+
@actual.eql?(@expected)
|
11
|
+
end
|
12
|
+
|
13
|
+
def failure_message
|
14
|
+
return "expected #{@expected.inspect}, got #{@actual.inspect} (using .eql?)", @expected, @actual
|
15
|
+
end
|
16
|
+
|
17
|
+
def negative_failure_message
|
18
|
+
return "expected #{@actual.inspect} not to equal #{@expected.inspect} (using .eql?)", @expected, @actual
|
19
|
+
end
|
20
|
+
|
21
|
+
def description
|
22
|
+
"eql #{@expected.inspect}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
3
26
|
|
4
27
|
# :call-seq:
|
5
28
|
# should eql(expected)
|
@@ -14,12 +37,7 @@ module Spec
|
|
14
37
|
# 5.should eql(5)
|
15
38
|
# 5.should_not eql(3)
|
16
39
|
def eql(expected)
|
17
|
-
|
18
|
-
matcher.failure_message = "expected #{expected.inspect}, got #{actual.inspect} (using .eql?)", expected, actual
|
19
|
-
matcher.negative_failure_message = "expected #{actual.inspect} not to equal #{expected.inspect} (using .eql?)", expected, actual
|
20
|
-
matcher.description = "eql #{expected.inspect}"
|
21
|
-
actual.eql?(expected)
|
22
|
-
end
|
40
|
+
Eql.new(expected)
|
23
41
|
end
|
24
42
|
end
|
25
43
|
end
|
data/lib/spec/matchers/equal.rb
CHANGED
@@ -1,5 +1,28 @@
|
|
1
1
|
module Spec
|
2
2
|
module Matchers
|
3
|
+
|
4
|
+
class Equal
|
5
|
+
def initialize(expected)
|
6
|
+
@expected = expected
|
7
|
+
end
|
8
|
+
|
9
|
+
def matches?(actual)
|
10
|
+
@actual = actual
|
11
|
+
@actual.equal?(@expected)
|
12
|
+
end
|
13
|
+
|
14
|
+
def failure_message
|
15
|
+
return "expected #{@expected.inspect}, got #{@actual.inspect} (using .equal?)", @expected, @actual
|
16
|
+
end
|
17
|
+
|
18
|
+
def negative_failure_message
|
19
|
+
return "expected #{@actual.inspect} not to equal #{@expected.inspect} (using .equal?)", @expected, @actual
|
20
|
+
end
|
21
|
+
|
22
|
+
def description
|
23
|
+
"equal #{@expected.inspect}"
|
24
|
+
end
|
25
|
+
end
|
3
26
|
|
4
27
|
# :call-seq:
|
5
28
|
# should equal(expected)
|
@@ -14,12 +37,7 @@ module Spec
|
|
14
37
|
# 5.should equal(5) #Fixnums are equal
|
15
38
|
# "5".should_not equal("5") #Strings that look the same are not the same object
|
16
39
|
def equal(expected)
|
17
|
-
|
18
|
-
matcher.failure_message = "expected #{expected.inspect}, got #{actual.inspect} (using .equal?)", expected, actual
|
19
|
-
matcher.negative_failure_message = "expected #{actual.inspect} not to equal #{expected.inspect} (using .equal?)", expected, actual
|
20
|
-
matcher.description = "equal #{expected.inspect}"
|
21
|
-
actual.equal?(expected)
|
22
|
-
end
|
40
|
+
Equal.new(expected)
|
23
41
|
end
|
24
42
|
end
|
25
43
|
end
|
data/lib/spec/matchers/exist.rb
CHANGED
@@ -1,16 +1,32 @@
|
|
1
1
|
module Spec
|
2
2
|
module Matchers
|
3
|
+
|
4
|
+
class Exist
|
5
|
+
def matches?(actual)
|
6
|
+
@actual = actual
|
7
|
+
actual.exist?
|
8
|
+
end
|
9
|
+
|
10
|
+
def failure_message
|
11
|
+
"expected #{@actual.inspect} to exist, but it doesn't."
|
12
|
+
end
|
13
|
+
|
14
|
+
def negative_failure_message
|
15
|
+
"expected #{@actual.inspect} to not exist, but it does."
|
16
|
+
end
|
17
|
+
|
18
|
+
def description
|
19
|
+
"exists"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
3
23
|
# :call-seq:
|
4
24
|
# should exist
|
5
25
|
# should_not exist
|
6
26
|
#
|
7
27
|
# Passes if actual.exist?
|
8
28
|
def exist
|
9
|
-
|
10
|
-
matcher.failure_message = "expected #{actual.inspect} to exist, but it doesn't."
|
11
|
-
matcher.negative_failure_message = "expected #{actual.inspect} to not exist, but it does."
|
12
|
-
actual.exist?
|
13
|
-
end
|
29
|
+
Exist.new
|
14
30
|
end
|
15
31
|
end
|
16
32
|
end
|
@@ -38,11 +38,11 @@ or this:
|
|
38
38
|
|
39
39
|
it { should matcher }
|
40
40
|
|
41
|
-
the runner expects the matcher to have a #
|
41
|
+
the runner expects the matcher to have a #description method. You should either
|
42
42
|
add a String to the example this matcher is being used in, or give it a
|
43
43
|
description method. Then you won't have to suffer this lengthy warning again.
|
44
44
|
MESSAGE
|
45
45
|
end
|
46
46
|
end
|
47
47
|
end
|
48
|
-
|
48
|
+
|
data/lib/spec/matchers/has.rb
CHANGED
@@ -1,18 +1,35 @@
|
|
1
1
|
module Spec
|
2
2
|
module Matchers
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
actual.__send__(predicate(sym), *args)
|
3
|
+
|
4
|
+
class Has
|
5
|
+
|
6
|
+
def initialize(expected, *args)
|
7
|
+
@expected, @args = expected, args
|
9
8
|
end
|
10
|
-
|
9
|
+
|
10
|
+
def matches?(actual)
|
11
|
+
actual.__send__(predicate(@expected), *@args)
|
12
|
+
end
|
13
|
+
|
14
|
+
def failure_message
|
15
|
+
"expected ##{predicate(@expected)}(#{@args[0].inspect}) to return true, got false"
|
16
|
+
end
|
17
|
+
|
18
|
+
def negative_failure_message
|
19
|
+
"expected ##{predicate(@expected)}(#{@args[0].inspect}) to return false, got true"
|
20
|
+
end
|
21
|
+
|
22
|
+
def description
|
23
|
+
"have key #{@args[0].inspect}"
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
11
27
|
|
12
|
-
|
13
|
-
|
14
|
-
|
28
|
+
def predicate(sym)
|
29
|
+
"#{sym.to_s.sub("have_","has_")}?".to_sym
|
30
|
+
end
|
31
|
+
|
15
32
|
end
|
16
|
-
|
33
|
+
|
17
34
|
end
|
18
35
|
end
|
data/lib/spec/matchers/match.rb
CHANGED
@@ -1,5 +1,28 @@
|
|
1
1
|
module Spec
|
2
2
|
module Matchers
|
3
|
+
class Match
|
4
|
+
def initialize(expected)
|
5
|
+
@expected = expected
|
6
|
+
end
|
7
|
+
|
8
|
+
def matches?(actual)
|
9
|
+
@actual = actual
|
10
|
+
actual =~ @expected
|
11
|
+
end
|
12
|
+
|
13
|
+
def failure_message
|
14
|
+
return "expected #{@actual.inspect} to match #{@expected.inspect}", @expected, @actual
|
15
|
+
end
|
16
|
+
|
17
|
+
def negative_failure_message
|
18
|
+
return "expected #{@actual.inspect} not to match #{@expected.inspect}", @expected, @actual
|
19
|
+
end
|
20
|
+
|
21
|
+
def description
|
22
|
+
"match #{@expected.inspect}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
3
26
|
|
4
27
|
# :call-seq:
|
5
28
|
# should match(regexp)
|
@@ -10,13 +33,8 @@ module Spec
|
|
10
33
|
# == Examples
|
11
34
|
#
|
12
35
|
# email.should match(/^([^\s]+)((?:[-a-z0-9]+\.)+[a-z]{2,})$/i)
|
13
|
-
def match(
|
14
|
-
|
15
|
-
matcher.failure_message = "expected #{actual.inspect} to match #{regexp.inspect}", regexp, actual
|
16
|
-
matcher.negative_failure_message = "expected #{actual.inspect} not to match #{regexp.inspect}", regexp, actual
|
17
|
-
matcher.description = "match #{regexp.inspect}"
|
18
|
-
actual =~ regexp
|
19
|
-
end
|
36
|
+
def match(expected)
|
37
|
+
Match.new(expected)
|
20
38
|
end
|
21
39
|
end
|
22
40
|
end
|
@@ -11,7 +11,7 @@ module Spec
|
|
11
11
|
@actual = actual
|
12
12
|
@extra_items = difference_between_arrays(@actual, @expected)
|
13
13
|
@missing_items = difference_between_arrays(@expected, @actual)
|
14
|
-
@extra_items.empty?
|
14
|
+
@extra_items.empty? & @missing_items.empty?
|
15
15
|
end
|
16
16
|
|
17
17
|
def failure_message
|
@@ -1,8 +1,8 @@
|
|
1
1
|
module Spec
|
2
2
|
module Matchers
|
3
3
|
def method_missing(sym, *args, &block) # :nodoc:
|
4
|
-
return Matchers::Be.new(sym, *args) if sym.
|
5
|
-
return
|
4
|
+
return Matchers::Be.new(sym, *args) if sym.to_s =~ /^be_/
|
5
|
+
return Matchers::Has.new(sym, *args) if sym.to_s =~ /^have_/
|
6
6
|
super
|
7
7
|
end
|
8
8
|
end
|
@@ -4,15 +4,16 @@ module Spec
|
|
4
4
|
class OperatorMatcher
|
5
5
|
class << self
|
6
6
|
def registry
|
7
|
-
@registry ||=
|
7
|
+
@registry ||= {}
|
8
8
|
end
|
9
9
|
|
10
10
|
def register(klass, operator, matcher)
|
11
|
+
registry[klass] ||= {}
|
11
12
|
registry[klass][operator] = matcher
|
12
13
|
end
|
13
14
|
|
14
15
|
def get(klass, operator)
|
15
|
-
registry[klass][operator]
|
16
|
+
registry[klass] && registry[klass][operator]
|
16
17
|
end
|
17
18
|
end
|
18
19
|
|
@@ -25,9 +26,7 @@ module Spec
|
|
25
26
|
if matcher = OperatorMatcher.get(@actual.class, operator)
|
26
27
|
@actual.send(::Spec::Matchers.last_should, matcher.new(expected))
|
27
28
|
else
|
28
|
-
|
29
|
-
@operator, @expected = operator, expected
|
30
|
-
__delegate_operator(@actual, operator, expected)
|
29
|
+
eval_match(@actual, operator, expected)
|
31
30
|
end
|
32
31
|
end
|
33
32
|
end
|
@@ -43,6 +42,14 @@ module Spec
|
|
43
42
|
def description
|
44
43
|
"#{@operator} #{@expected.inspect}"
|
45
44
|
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def eval_match(actual, operator, expected)
|
49
|
+
::Spec::Matchers.last_matcher = self
|
50
|
+
@operator, @expected = operator, expected
|
51
|
+
__delegate_operator(actual, operator, expected)
|
52
|
+
end
|
46
53
|
|
47
54
|
end
|
48
55
|
|
@@ -31,7 +31,7 @@ module Spec
|
|
31
31
|
eval_block if @raised_expected_error && @with_expected_message && @block
|
32
32
|
end
|
33
33
|
ensure
|
34
|
-
return (@raised_expected_error
|
34
|
+
return (@raised_expected_error & @with_expected_message) ? (@eval_block ? @eval_block_passed : true) : false
|
35
35
|
end
|
36
36
|
|
37
37
|
def eval_block
|
@@ -25,7 +25,6 @@ module Spec
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def description
|
28
|
-
# Ruby 1.9 returns the same thing for array.to_s as array.inspect, so just use array.inspect here
|
29
28
|
"respond to #{pp_names}#{with_arity}"
|
30
29
|
end
|
31
30
|
|
@@ -51,6 +50,7 @@ module Spec
|
|
51
50
|
end
|
52
51
|
|
53
52
|
def pp_names
|
53
|
+
# Ruby 1.9 returns the same thing for array.to_s as array.inspect, so just use array.inspect here
|
54
54
|
@names.length == 1 ? "##{@names.first}" : @names.inspect
|
55
55
|
end
|
56
56
|
end
|