dchelimsky-rspec 1.1.12 → 1.1.99.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/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
|