rspec 1.2.6 → 1.2.7
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|