rspec 1.2.6 → 1.2.7
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.rdoc +22 -0
- data/Manifest.txt +9 -4
- data/Rakefile +13 -12
- data/Upgrade.rdoc +1 -1
- data/features/command_line/line_number_option.feature +56 -0
- data/features/command_line/line_number_option_with_example_with_no_name.feature +22 -0
- data/features/mocks/stub_implementation.feature +26 -0
- data/lib/autotest/rspec.rb +7 -7
- data/lib/spec/autorun.rb +1 -1
- data/lib/spec/deprecation.rb +3 -3
- data/lib/spec/dsl.rb +0 -1
- data/lib/spec/dsl/main.rb +6 -6
- data/lib/spec/example.rb +28 -29
- data/lib/spec/example/args_and_options.rb +1 -1
- data/lib/spec/example/before_and_after_hooks.rb +10 -10
- data/lib/spec/example/errors.rb +8 -3
- data/lib/spec/example/example_group.rb +0 -1
- data/lib/spec/example/example_group_factory.rb +3 -3
- data/lib/spec/example/example_group_hierarchy.rb +10 -10
- data/lib/spec/example/example_group_methods.rb +37 -29
- data/lib/spec/example/example_group_proxy.rb +9 -10
- data/lib/spec/example/example_matcher.rb +3 -3
- data/lib/spec/example/example_methods.rb +11 -11
- data/lib/spec/example/example_proxy.rb +5 -5
- data/lib/spec/example/module_reopening_fix.rb +7 -7
- data/lib/spec/example/pending.rb +1 -1
- data/lib/spec/example/predicate_matchers.rb +0 -1
- data/lib/spec/example/shared_example_group.rb +5 -5
- data/lib/spec/example/subject.rb +12 -16
- data/lib/spec/expectations/extensions/kernel.rb +1 -1
- data/lib/spec/expectations/fail_with.rb +4 -0
- data/lib/spec/matchers/generated_descriptions.rb +4 -16
- data/lib/spec/matchers/match.rb +5 -4
- data/lib/spec/matchers/matcher.rb +21 -3
- data/lib/spec/matchers/operator_matcher.rb +1 -1
- data/lib/spec/mocks/errors.rb +1 -1
- data/lib/spec/mocks/message_expectation.rb +3 -2
- data/lib/spec/mocks/methods.rb +8 -5
- data/lib/spec/mocks/proxy.rb +2 -2
- data/lib/spec/rake/spectask.rb +9 -3
- data/lib/spec/runner.rb +1 -1
- data/lib/spec/runner/{spec_parser.rb → line_number_query.rb} +20 -9
- data/lib/spec/runner/options.rb +10 -2
- data/lib/spec/version.rb +3 -2
- data/spec/autotest/failed_results_re_spec.rb +7 -0
- data/spec/spec/example/example_group_methods_spec.rb +61 -0
- data/spec/spec/example/example_matcher_spec.rb +7 -0
- data/spec/spec/example/example_methods_spec.rb +35 -7
- data/spec/spec/expectations/fail_with_spec.rb +18 -1
- data/spec/spec/matchers/match_spec.rb +20 -0
- data/spec/spec/matchers/matcher_spec.rb +27 -28
- data/spec/spec/matchers/operator_matcher_spec.rb +1 -1
- data/spec/spec/mocks/bug_report_10263_spec.rb +4 -1
- data/spec/spec/mocks/bug_report_830_spec.rb +21 -0
- data/spec/spec/mocks/options_hash_spec.rb +1 -1
- data/spec/spec/mocks/stub_chain_spec.rb +7 -0
- data/spec/spec/mocks/stub_implementation_spec.rb +31 -0
- data/spec/spec/rake/spectask_spec.rb +150 -0
- data/spec/spec/runner/{spec_parser/spec_parser_fixture.rb → line_number_query/line_number_query_fixture.rb} +4 -4
- data/spec/spec/runner/{spec_parser_spec.rb → line_number_query_spec.rb} +31 -10
- data/spec/spec/runner/option_parser_spec.rb +1 -1
- data/spec/spec/runner/options_spec.rb +33 -25
- metadata +15 -10
- data/.autotest +0 -5
@@ -1,10 +1,10 @@
|
|
1
1
|
module Spec
|
2
2
|
module Example
|
3
3
|
module ExampleMethods
|
4
|
-
|
4
|
+
|
5
5
|
extend Spec::Example::ModuleReopeningFix
|
6
6
|
include Spec::Example::Subject::ExampleMethods
|
7
|
-
|
7
|
+
|
8
8
|
def violated(message="")
|
9
9
|
raise Spec::Expectations::ExpectationNotMetError.new(message)
|
10
10
|
end
|
@@ -21,10 +21,10 @@ module Spec
|
|
21
21
|
if description = @_proxy.description || ::Spec::Matchers.generated_description
|
22
22
|
description
|
23
23
|
else
|
24
|
-
|
24
|
+
Spec.warn Spec::Example::NoDescriptionError.message("example", @_proxy.location)
|
25
25
|
end
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
def options # :nodoc:
|
29
29
|
@_proxy.options
|
30
30
|
end
|
@@ -32,7 +32,7 @@ module Spec
|
|
32
32
|
def execute(run_options, instance_variables) # :nodoc:
|
33
33
|
run_options.reporter.example_started(@_proxy)
|
34
34
|
set_instance_variables_from_hash(instance_variables)
|
35
|
-
|
35
|
+
|
36
36
|
execution_error = nil
|
37
37
|
Timeout.timeout(run_options.timeout) do
|
38
38
|
begin
|
@@ -51,12 +51,12 @@ module Spec
|
|
51
51
|
run_options.reporter.example_finished(@_proxy.update(description), execution_error)
|
52
52
|
success = execution_error.nil? || ExamplePendingError === execution_error
|
53
53
|
end
|
54
|
-
|
54
|
+
|
55
55
|
module BlockAliases
|
56
56
|
alias_method :to, :should
|
57
57
|
alias_method :to_not, :should_not
|
58
58
|
end
|
59
|
-
|
59
|
+
|
60
60
|
# Extends the submitted block with aliases to and to_not
|
61
61
|
# for should and should_not. Allows expectations like this:
|
62
62
|
#
|
@@ -115,10 +115,10 @@ module Spec
|
|
115
115
|
end
|
116
116
|
|
117
117
|
private
|
118
|
-
|
118
|
+
|
119
119
|
include Matchers
|
120
120
|
include Pending
|
121
|
-
|
121
|
+
|
122
122
|
def before_each_example
|
123
123
|
setup_mocks_for_rspec
|
124
124
|
run_before_each
|
@@ -134,7 +134,7 @@ module Spec
|
|
134
134
|
def described_class
|
135
135
|
self.class.described_class
|
136
136
|
end
|
137
|
-
|
137
|
+
|
138
138
|
def description_args
|
139
139
|
self.class.description_args
|
140
140
|
end
|
@@ -142,7 +142,7 @@ module Spec
|
|
142
142
|
def example_group_hierarchy
|
143
143
|
self.class.example_group_hierarchy
|
144
144
|
end
|
145
|
-
|
145
|
+
|
146
146
|
end
|
147
147
|
end
|
148
148
|
end
|
@@ -7,32 +7,32 @@ module Spec
|
|
7
7
|
def initialize(description=nil, options={}, location=nil) # :nodoc:
|
8
8
|
@description, @options, @location = description, options, location
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
# Optional hash passed to the example declaration
|
12
12
|
attr_reader :options
|
13
13
|
|
14
14
|
# This is the docstring passed to the <tt>it()</tt> method or any
|
15
15
|
# of its aliases
|
16
16
|
attr_reader :description
|
17
|
-
|
17
|
+
|
18
18
|
# The file and line number at which the represented example
|
19
19
|
# was declared. This is extracted from <tt>caller</tt>, and is therefore
|
20
20
|
# formatted as an individual line in a backtrace.
|
21
21
|
attr_reader :location
|
22
|
-
|
22
|
+
|
23
23
|
# Deprecated - use location()
|
24
24
|
def backtrace
|
25
25
|
Spec.deprecate("ExampleProxy#backtrace","ExampleProxy#location")
|
26
26
|
location
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
# Convenience method for example group - updates the value of
|
30
30
|
# <tt>description</tt> and returns self.
|
31
31
|
def update(description) # :nodoc:
|
32
32
|
@description = description
|
33
33
|
self
|
34
34
|
end
|
35
|
-
|
35
|
+
|
36
36
|
def ==(other) # :nodoc:
|
37
37
|
(other.description == description) & (other.location == location)
|
38
38
|
end
|
@@ -2,23 +2,23 @@ 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
4
|
# the new material you define does not make it to the class. This fixes that.
|
5
|
-
#
|
5
|
+
#
|
6
6
|
# == Example
|
7
|
-
#
|
7
|
+
#
|
8
8
|
# module M1; end
|
9
|
-
#
|
9
|
+
#
|
10
10
|
# module M2
|
11
11
|
# def foo; "FOO"; end
|
12
12
|
# end
|
13
|
-
#
|
13
|
+
#
|
14
14
|
# class C
|
15
15
|
# include M1
|
16
16
|
# end
|
17
|
-
#
|
17
|
+
#
|
18
18
|
# module M1
|
19
19
|
# include M2
|
20
20
|
# end
|
21
|
-
#
|
21
|
+
#
|
22
22
|
# c = C.new
|
23
23
|
# c.foo
|
24
24
|
# NoMethodError: undefined method `foo' for #<C:0x5e89a4>
|
@@ -40,4 +40,4 @@ module Spec
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
end
|
43
|
-
end
|
43
|
+
end
|
data/lib/spec/example/pending.rb
CHANGED
@@ -7,7 +7,7 @@ module Spec
|
|
7
7
|
shared_example_groups << new_example_group unless already_registered?(new_example_group)
|
8
8
|
new_example_group
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
def find(example_group_description)
|
12
12
|
shared_example_groups.find {|b| b.description == example_group_description}
|
13
13
|
end
|
@@ -15,21 +15,21 @@ module Spec
|
|
15
15
|
def clear
|
16
16
|
shared_example_groups.clear
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
def include?(group)
|
20
20
|
shared_example_groups.include?(group)
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
def count
|
24
24
|
shared_example_groups.length
|
25
25
|
end
|
26
26
|
|
27
27
|
private
|
28
|
-
|
28
|
+
|
29
29
|
def shared_example_groups
|
30
30
|
@shared_example_groups ||= []
|
31
31
|
end
|
32
|
-
|
32
|
+
|
33
33
|
def already_registered?(new_example_group)
|
34
34
|
existing_example_group = find(new_example_group.description)
|
35
35
|
return false unless existing_example_group
|
data/lib/spec/example/subject.rb
CHANGED
@@ -18,11 +18,11 @@ module Spec
|
|
18
18
|
block.nil? ?
|
19
19
|
explicit_subject || implicit_subject : @explicit_subject_block = block
|
20
20
|
end
|
21
|
-
|
21
|
+
|
22
22
|
attr_reader :explicit_subject_block # :nodoc:
|
23
|
-
|
23
|
+
|
24
24
|
private
|
25
|
-
|
25
|
+
|
26
26
|
def explicit_subject
|
27
27
|
group = self
|
28
28
|
while group.respond_to?(:explicit_subject_block)
|
@@ -30,13 +30,17 @@ module Spec
|
|
30
30
|
group = group.superclass
|
31
31
|
end
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
34
|
def implicit_subject
|
35
35
|
(described_class ? lambda {described_class.new} : lambda {description_args.first})
|
36
36
|
end
|
37
37
|
end
|
38
|
-
|
38
|
+
|
39
39
|
module ExampleMethods
|
40
|
+
|
41
|
+
alias_method :__should_for_example_group__, :should
|
42
|
+
alias_method :__should_not_for_example_group__, :should_not
|
43
|
+
|
40
44
|
# Returns the subject defined in ExampleGroupMethods#subject. The
|
41
45
|
# subject block is only executed once per example, the result of which
|
42
46
|
# is cached and returned by any subsequent calls to +subject+.
|
@@ -76,11 +80,7 @@ module Spec
|
|
76
80
|
# it { should be_eligible_to_vote }
|
77
81
|
# end
|
78
82
|
def should(matcher=nil)
|
79
|
-
|
80
|
-
subject.should(matcher)
|
81
|
-
else
|
82
|
-
subject.should
|
83
|
-
end
|
83
|
+
self == subject ? self.__should_for_example_group__(matcher) : subject.should(matcher)
|
84
84
|
end
|
85
85
|
|
86
86
|
# Just like +should+, +should_not+ delegates to the subject (implicit or
|
@@ -92,13 +92,9 @@ module Spec
|
|
92
92
|
# it { should_not be_eligible_to_vote }
|
93
93
|
# end
|
94
94
|
def should_not(matcher=nil)
|
95
|
-
|
96
|
-
subject.should_not(matcher)
|
97
|
-
else
|
98
|
-
subject.should_not
|
99
|
-
end
|
95
|
+
self == subject ? self.__should_not_for_example_group__(matcher) : subject.should_not(matcher)
|
100
96
|
end
|
101
97
|
end
|
102
98
|
end
|
103
99
|
end
|
104
|
-
end
|
100
|
+
end
|
@@ -9,6 +9,10 @@ module Spec
|
|
9
9
|
# <code>expected</code> and <code>target</code>, passes them
|
10
10
|
# to the differ to append a diff message to the failure message.
|
11
11
|
def fail_with(message, expected=nil, target=nil) # :nodoc:
|
12
|
+
if message.nil?
|
13
|
+
raise ArgumentError, "Failure message is nil. Does your matcher define the " +
|
14
|
+
"appropriate failure_message_for_* method to return a string?"
|
15
|
+
end
|
12
16
|
if (Array === message) & (message.length == 3)
|
13
17
|
::Spec.warn(<<-NOTICE
|
14
18
|
|
@@ -1,19 +1,7 @@
|
|
1
1
|
module Spec
|
2
2
|
module Matchers
|
3
|
-
|
4
|
-
|
5
|
-
end
|
6
|
-
|
7
|
-
def self.last_matcher=(last_matcher)
|
8
|
-
@last_matcher = last_matcher
|
9
|
-
end
|
10
|
-
|
11
|
-
def self.last_should
|
12
|
-
@last_should
|
13
|
-
end
|
14
|
-
|
15
|
-
def self.last_should=(last_should)
|
16
|
-
@last_should = last_should
|
3
|
+
class << self
|
4
|
+
attr_accessor :last_matcher, :last_should # :nodoc:
|
17
5
|
end
|
18
6
|
|
19
7
|
def self.clear_generated_description
|
@@ -26,7 +14,7 @@ module Spec
|
|
26
14
|
"#{last_should.to_s.gsub('_',' ')} #{last_description}"
|
27
15
|
end
|
28
16
|
|
29
|
-
|
17
|
+
private
|
30
18
|
|
31
19
|
def self.last_description
|
32
20
|
last_matcher.respond_to?(:description) ? last_matcher.description : <<-MESSAGE
|
@@ -38,7 +26,7 @@ or this:
|
|
38
26
|
|
39
27
|
it { should matcher }
|
40
28
|
|
41
|
-
|
29
|
+
RSpec expects the matcher to have a #description method. You should either
|
42
30
|
add a String to the example this matcher is being used in, or give it a
|
43
31
|
description method. Then you won't have to suffer this lengthy warning again.
|
44
32
|
MESSAGE
|
data/lib/spec/matchers/match.rb
CHANGED
@@ -1,18 +1,19 @@
|
|
1
1
|
module Spec
|
2
2
|
module Matchers
|
3
3
|
# :call-seq:
|
4
|
-
# should match(
|
5
|
-
# should_not match(
|
4
|
+
# should match(pattern)
|
5
|
+
# should_not match(pattern)
|
6
6
|
#
|
7
|
-
# Given a Regexp, passes if actual
|
7
|
+
# Given a Regexp or String, passes if actual.match(pattern)
|
8
8
|
#
|
9
9
|
# == Examples
|
10
10
|
#
|
11
11
|
# email.should match(/^([^\s]+)((?:[-a-z0-9]+\.)+[a-z]{2,})$/i)
|
12
|
+
# email.should match("@example.com")
|
12
13
|
def match(expected)
|
13
14
|
Matcher.new :match, expected do |_expected_|
|
14
15
|
match do |actual|
|
15
|
-
actual
|
16
|
+
actual.match(_expected_)
|
16
17
|
end
|
17
18
|
end
|
18
19
|
end
|
@@ -8,18 +8,19 @@ module Spec
|
|
8
8
|
def initialize(name, *expected, &declarations)
|
9
9
|
@name = name
|
10
10
|
@expected = expected
|
11
|
-
@declarations = declarations
|
12
11
|
@diffable = false
|
13
12
|
@messages = {
|
14
13
|
:description => lambda {"#{name_to_sentence}#{expected_to_sentence}"},
|
15
14
|
:failure_message_for_should => lambda {|actual| "expected #{actual.inspect} to #{name_to_sentence}#{expected_to_sentence}"},
|
16
15
|
:failure_message_for_should_not => lambda {|actual| "expected #{actual.inspect} not to #{name_to_sentence}#{expected_to_sentence}"}
|
17
16
|
}
|
17
|
+
making_declared_methods_public do
|
18
|
+
instance_exec(*@expected, &declarations)
|
19
|
+
end
|
18
20
|
end
|
19
21
|
|
20
22
|
def matches?(actual)
|
21
23
|
@actual = actual
|
22
|
-
instance_exec(*@expected, &@declarations)
|
23
24
|
instance_exec(@actual, &@match_block)
|
24
25
|
end
|
25
26
|
|
@@ -46,9 +47,26 @@ module Spec
|
|
46
47
|
def diffable
|
47
48
|
@diffable = true
|
48
49
|
end
|
49
|
-
|
50
|
+
|
50
51
|
private
|
51
52
|
|
53
|
+
def making_declared_methods_public # :nodoc:
|
54
|
+
# Our home-grown instance_exec in ruby 1.8.6 results in any methods
|
55
|
+
# declared in the block eval'd by instance_exec in the block to which we
|
56
|
+
# are yielding here are scoped private. This is NOT the case for Ruby
|
57
|
+
# 1.8.7 or 1.9.
|
58
|
+
#
|
59
|
+
# Also, due some crazy scoping that I don't understand, these methods
|
60
|
+
# are actually available in the specs (something about the matcher being
|
61
|
+
# defined in the scope of Spec::Matchers or within an example), so not
|
62
|
+
# doing the following will not cause specs to fail, but they *will*
|
63
|
+
# cause features to fail and that will make users unhappy. So don't.
|
64
|
+
orig_private_methods = private_methods
|
65
|
+
yield
|
66
|
+
st = (class << self; self; end)
|
67
|
+
(private_methods - orig_private_methods).each {|m| st.__send__ :public, m}
|
68
|
+
end
|
69
|
+
|
52
70
|
def cache_or_call_cached(key, actual=nil, &block)
|
53
71
|
block ? @messages[key] = block :
|
54
72
|
actual.nil? ? @messages[key].call : @messages[key].call(actual)
|
@@ -68,7 +68,7 @@ module Spec
|
|
68
68
|
|
69
69
|
class NegativeOperatorMatcher < OperatorMatcher #:nodoc:
|
70
70
|
def __delegate_operator(actual, operator, expected)
|
71
|
-
return
|
71
|
+
return false unless actual.__send__(operator, expected)
|
72
72
|
return fail_with_message("expected not: #{operator} #{expected.inspect},\n got: #{operator.gsub(/./, ' ')} #{actual.inspect}")
|
73
73
|
end
|
74
74
|
|
data/lib/spec/mocks/errors.rb
CHANGED
@@ -8,7 +8,7 @@ module Spec
|
|
8
8
|
attr_accessor :error_generator
|
9
9
|
protected :error_generator, :error_generator=
|
10
10
|
|
11
|
-
def initialize(error_generator, expectation_ordering, expected_from, sym, method_block, expected_received_count=1, opts={})
|
11
|
+
def initialize(error_generator, expectation_ordering, expected_from, sym, method_block, expected_received_count=1, opts={}, &implementation)
|
12
12
|
@error_generator = error_generator
|
13
13
|
@error_generator.opts = opts
|
14
14
|
@expected_from = expected_from
|
@@ -27,6 +27,7 @@ module Spec
|
|
27
27
|
@args_to_yield = []
|
28
28
|
@failed_fast = nil
|
29
29
|
@args_to_yield_were_cloned = false
|
30
|
+
@return_block = implementation
|
30
31
|
end
|
31
32
|
|
32
33
|
def build_child(expected_from, method_block, expected_received_count, opts={})
|
@@ -167,7 +168,7 @@ module Spec
|
|
167
168
|
# Ruby 1.9 - when we set @return_block to return values
|
168
169
|
# regardless of arguments, any arguments will result in
|
169
170
|
# a "wrong number of arguments" error
|
170
|
-
@return_block.arity
|
171
|
+
@return_block.arity == 0 ? @return_block.call : @return_block.call(*args)
|
171
172
|
end
|
172
173
|
|
173
174
|
def clone_args_to_yield(args)
|
data/lib/spec/mocks/methods.rb
CHANGED
@@ -9,21 +9,24 @@ module Spec
|
|
9
9
|
__mock_proxy.add_negative_message_expectation(caller(1)[0], sym.to_sym, &block)
|
10
10
|
end
|
11
11
|
|
12
|
-
def stub!(sym_or_hash, opts={})
|
12
|
+
def stub!(sym_or_hash, opts={}, &block)
|
13
13
|
if Hash === sym_or_hash
|
14
14
|
sym_or_hash.each {|method, value| stub!(method).and_return value }
|
15
15
|
else
|
16
|
-
__mock_proxy.add_stub(caller(1)[0], sym_or_hash.to_sym, opts)
|
16
|
+
__mock_proxy.add_stub(caller(1)[0], sym_or_hash.to_sym, opts, &block)
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
20
|
alias_method :stub, :stub!
|
21
21
|
|
22
22
|
def stub_chain(*methods)
|
23
|
-
|
24
|
-
|
23
|
+
if methods.length > 1
|
24
|
+
next_in_chain = Object.new
|
25
|
+
stub!(methods.shift) {next_in_chain}
|
26
|
+
next_in_chain.stub_chain(*methods)
|
27
|
+
else
|
28
|
+
stub!(methods.shift)
|
25
29
|
end
|
26
|
-
stub!(methods.shift)
|
27
30
|
end
|
28
31
|
|
29
32
|
def received_message?(sym, *args, &block) #:nodoc:
|