rspec 1.2.4 → 1.2.5
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.tar.gz.sig +0 -0
- data/History.rdoc +59 -32
- data/Manifest.txt +6 -0
- data/Rakefile +2 -2
- data/examples/passing/options_example.rb +31 -0
- data/examples/passing/options_formatter.rb +20 -0
- data/features/expectations/expect_change.feature +65 -0
- data/features/expectations/expect_error.feature +44 -0
- data/lib/spec/example/example_group_factory.rb +4 -2
- data/lib/spec/example/example_group_methods.rb +5 -1
- data/lib/spec/example/example_group_proxy.rb +8 -0
- data/lib/spec/example/example_matcher.rb +2 -3
- data/lib/spec/example/example_methods.rb +14 -1
- data/lib/spec/example/example_proxy.rb +3 -4
- data/lib/spec/example/subject.rb +7 -7
- data/lib/spec/interop/test.rb +2 -1
- data/lib/spec/matchers/be_close.rb +5 -5
- data/lib/spec/matchers/be_instance_of.rb +2 -2
- data/lib/spec/matchers/be_kind_of.rb +2 -2
- data/lib/spec/matchers/compatibility.rb +2 -2
- data/lib/spec/matchers/eql.rb +4 -4
- data/lib/spec/matchers/equal.rb +18 -8
- data/lib/spec/matchers/extensions/instance_exec.rb +1 -3
- data/lib/spec/matchers/include.rb +4 -4
- data/lib/spec/matchers/match.rb +2 -2
- data/lib/spec/matchers/operator_matcher.rb +3 -2
- data/lib/spec/mocks/methods.rb +9 -0
- data/lib/spec/mocks/mock.rb +34 -24
- data/lib/spec/mocks/proxy.rb +1 -0
- data/lib/spec/mocks/spec_methods.rb +5 -5
- data/lib/spec/runner.rb +1 -2
- data/lib/spec/runner/configuration.rb +0 -0
- data/lib/spec/runner/drb_command_line.rb +2 -0
- data/lib/spec/runner/formatter/base_text_formatter.rb +1 -1
- data/lib/spec/runner/formatter/no_op_method_missing.rb +1 -1
- data/lib/spec/version.rb +1 -1
- data/spec/spec/example/example_group_proxy_spec.rb +24 -0
- data/spec/spec/example/example_methods_spec.rb +12 -0
- data/spec/spec/example/predicate_matcher_spec.rb +0 -0
- data/spec/spec/example/subject_spec.rb +16 -6
- data/spec/spec/matchers/change_spec.rb +85 -85
- data/spec/spec/matchers/compatibility_spec.rb +16 -22
- data/spec/spec/matchers/equal_spec.rb +33 -9
- data/spec/spec/matchers/have_spec.rb +1 -8
- data/spec/spec/mocks/mock_ordering_spec.rb +10 -0
- data/spec/spec/mocks/mock_spec.rb +106 -93
- data/spec/spec/mocks/stub_chain_spec.rb +27 -0
- data/spec/spec/mocks/stub_spec.rb +9 -5
- data/spec/spec/runner/configuration_spec.rb +0 -0
- data/spec/spec/runner/drb_command_line_spec.rb +1 -1
- data/spec/spec/runner/formatter/html_formatted-1.8.7.html +31 -46
- data/spec/spec/runner/formatter/html_formatted-1.9.1.html +25 -28
- data/spec/spec/runner/formatter/html_formatter_spec.rb +3 -19
- data/spec/spec/runner/formatter/profile_formatter_spec.rb +3 -18
- data/spec/spec/runner/formatter/progress_bar_formatter_spec.rb +4 -28
- data/spec/spec/runner/formatter/text_mate_formatted-1.8.7.html +31 -46
- data/spec/spec/runner/formatter/text_mate_formatted-1.9.1.html +7 -10
- data/spec/spec/runner/reporter_spec.rb +1 -1
- data/spec/spec_helper.rb +4 -0
- data/spec/support/macros.rb +29 -0
- metadata +36 -8
- metadata.gz.sig +1 -0
@@ -3,6 +3,8 @@ module Spec
|
|
3
3
|
|
4
4
|
class ExampleGroupFactory
|
5
5
|
module ClassMethods
|
6
|
+
include Spec::Example::ArgsAndOptions
|
7
|
+
|
6
8
|
def reset
|
7
9
|
@example_group_types = nil
|
8
10
|
default(ExampleGroup)
|
@@ -23,8 +25,8 @@ module Spec
|
|
23
25
|
end
|
24
26
|
|
25
27
|
def create_example_group(*args, &block)
|
26
|
-
raise ArgumentError if args.empty?
|
27
|
-
|
28
|
+
raise ArgumentError if args.empty? || block.nil?
|
29
|
+
add_options(args)
|
28
30
|
superclass = determine_superclass(args.last)
|
29
31
|
superclass.describe(*args, &block)
|
30
32
|
end
|
@@ -19,7 +19,11 @@ module Spec
|
|
19
19
|
include Spec::Example::PredicateMatchers
|
20
20
|
include Spec::Example::ArgsAndOptions
|
21
21
|
|
22
|
-
attr_reader :
|
22
|
+
attr_reader :location
|
23
|
+
|
24
|
+
def options # :nodoc:
|
25
|
+
@options ||= {}
|
26
|
+
end
|
23
27
|
|
24
28
|
def inherited(klass) # :nodoc:
|
25
29
|
super
|
@@ -10,8 +10,16 @@ module Spec
|
|
10
10
|
@examples = example_group.example_proxies
|
11
11
|
@location = example_group.location
|
12
12
|
@backtrace = example_group.location # deprecated - see the backtrace method below
|
13
|
+
@options = example_group.options.dup
|
14
|
+
@options.delete(:location)
|
15
|
+
@options.delete(:scope)
|
13
16
|
end
|
14
17
|
|
18
|
+
# Optional hash passed to the example group declaration. Note that RSpec uses
|
19
|
+
# this hash internally and reserves the keys :location and :scope for its own
|
20
|
+
# use (and removes them from this hash)
|
21
|
+
attr_reader :options
|
22
|
+
|
15
23
|
# This is the description passed to the <tt>describe()</tt> method or any
|
16
24
|
# of its aliases
|
17
25
|
attr_reader :description
|
@@ -7,10 +7,9 @@ module Spec
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def matches?(specified_examples)
|
10
|
-
specified_examples.
|
11
|
-
|
10
|
+
specified_examples.any? do |specified_example|
|
11
|
+
matches_literal_example?(specified_example) || matches_example_not_considering_modules?(specified_example)
|
12
12
|
end
|
13
|
-
false
|
14
13
|
end
|
15
14
|
|
16
15
|
protected
|
@@ -30,7 +30,6 @@ module Spec
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def execute(run_options, instance_variables) # :nodoc:
|
33
|
-
puts caller unless caller(0)[1] =~ /example_group_methods/
|
34
33
|
run_options.reporter.example_started(@_proxy)
|
35
34
|
set_instance_variables_from_hash(instance_variables)
|
36
35
|
|
@@ -52,6 +51,20 @@ module Spec
|
|
52
51
|
run_options.reporter.example_finished(@_proxy.update(description), execution_error)
|
53
52
|
success = execution_error.nil? || ExamplePendingError === execution_error
|
54
53
|
end
|
54
|
+
|
55
|
+
module BlockAliases
|
56
|
+
alias_method :to, :should
|
57
|
+
alias_method :to_not, :should_not
|
58
|
+
end
|
59
|
+
|
60
|
+
# Extends the submitted block with aliases to and to_not
|
61
|
+
# for should and should_not. Allows expectations like this:
|
62
|
+
#
|
63
|
+
# expect { this_block }.to change{this.expression}.from(old_value).to(new_value)
|
64
|
+
# expect { this_block }.to raise_error
|
65
|
+
def expect(&block)
|
66
|
+
block.extend BlockAliases
|
67
|
+
end
|
55
68
|
|
56
69
|
def eval_each_fail_fast(blocks) # :nodoc:
|
57
70
|
blocks.each {|block| instance_eval(&block)}
|
@@ -8,14 +8,13 @@ module Spec
|
|
8
8
|
@description, @options, @location = description, options, location
|
9
9
|
end
|
10
10
|
|
11
|
+
# Optional hash passed to the example declaration
|
12
|
+
attr_reader :options
|
13
|
+
|
11
14
|
# This is the docstring passed to the <tt>it()</tt> method or any
|
12
15
|
# of its aliases
|
13
16
|
attr_reader :description
|
14
17
|
|
15
|
-
# Internal use only - used to store options to pass to example
|
16
|
-
# when it is initialized
|
17
|
-
attr_reader :options # :nodoc:
|
18
|
-
|
19
18
|
# The file and line number at which the represented example
|
20
19
|
# was declared. This is extracted from <tt>caller</tt>, and is therefore
|
21
20
|
# formatted as an individual line in a backtrace.
|
data/lib/spec/example/subject.rb
CHANGED
@@ -16,18 +16,18 @@ module Spec
|
|
16
16
|
# See +ExampleMethods#should+ for more information about this approach.
|
17
17
|
def subject(&block)
|
18
18
|
block.nil? ?
|
19
|
-
explicit_subject || implicit_subject : @
|
19
|
+
explicit_subject || implicit_subject : @explicit_subject_block = block
|
20
20
|
end
|
21
21
|
|
22
|
+
attr_reader :explicit_subject_block # :nodoc:
|
23
|
+
|
22
24
|
private
|
23
25
|
|
24
26
|
def explicit_subject
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
else
|
30
|
-
nil
|
27
|
+
group = self
|
28
|
+
while group.respond_to?(:explicit_subject_block)
|
29
|
+
return group.explicit_subject_block if group.explicit_subject_block
|
30
|
+
group = group.superclass
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
data/lib/spec/interop/test.rb
CHANGED
@@ -10,21 +10,21 @@ module Spec
|
|
10
10
|
#
|
11
11
|
# result.should be_close(3.0, 0.5)
|
12
12
|
def be_close(expected, delta)
|
13
|
-
Matcher.new :be_close, expected, delta do |
|
13
|
+
Matcher.new :be_close, expected, delta do |_expected_, _delta_|
|
14
14
|
match do |actual|
|
15
|
-
(actual -
|
15
|
+
(actual - _expected_).abs < _delta_
|
16
16
|
end
|
17
17
|
|
18
18
|
failure_message_for_should do |actual|
|
19
|
-
"expected #{
|
19
|
+
"expected #{_expected_} +/- (< #{_delta_}), got #{actual}"
|
20
20
|
end
|
21
21
|
|
22
22
|
failure_message_for_should_not do |actual|
|
23
|
-
"expected #{
|
23
|
+
"expected #{_expected_} +/- (< #{_delta_}), got #{actual}"
|
24
24
|
end
|
25
25
|
|
26
26
|
description do
|
27
|
-
"be close to #{
|
27
|
+
"be close to #{_expected_} (within +- #{_delta_})"
|
28
28
|
end
|
29
29
|
end
|
30
30
|
end
|
@@ -14,9 +14,9 @@ module Spec
|
|
14
14
|
# 5.should_not be_instance_of(Numeric)
|
15
15
|
# 5.should_not be_instance_of(Float)
|
16
16
|
def be_an_instance_of(expected)
|
17
|
-
Matcher.new :be_an_instance_of, expected do |
|
17
|
+
Matcher.new :be_an_instance_of, expected do |_expected_|
|
18
18
|
match do |actual|
|
19
|
-
actual.instance_of?(
|
19
|
+
actual.instance_of?(_expected_)
|
20
20
|
end
|
21
21
|
end
|
22
22
|
end
|
@@ -14,9 +14,9 @@ module Spec
|
|
14
14
|
# 5.should be_kind_of(Numeric)
|
15
15
|
# 5.should_not be_kind_of(Float)
|
16
16
|
def be_a_kind_of(expected)
|
17
|
-
Matcher.new :be_a_kind_of, expected do |
|
17
|
+
Matcher.new :be_a_kind_of, expected do |_expected_|
|
18
18
|
match do |actual|
|
19
|
-
actual.kind_of?(
|
19
|
+
actual.kind_of?(_expected_)
|
20
20
|
end
|
21
21
|
end
|
22
22
|
end
|
@@ -1,11 +1,11 @@
|
|
1
1
|
Spec::Matchers.constants.each do |c|
|
2
2
|
if Class === (klass = Spec::Matchers.const_get(c))
|
3
|
-
if klass.public_instance_methods.
|
3
|
+
if klass.public_instance_methods.any? {|m| ['failure_message_for_should',:failure_message_for_should].include?(m)}
|
4
4
|
klass.class_eval do
|
5
5
|
alias_method :failure_message, :failure_message_for_should
|
6
6
|
end
|
7
7
|
end
|
8
|
-
if klass.public_instance_methods.
|
8
|
+
if klass.public_instance_methods.any? {|m| ['failure_message_for_should_not',:failure_message_for_should_not].include?(m)}
|
9
9
|
klass.class_eval do
|
10
10
|
alias_method :negative_failure_message, :failure_message_for_should_not
|
11
11
|
end
|
data/lib/spec/matchers/eql.rb
CHANGED
@@ -13,15 +13,15 @@ module Spec
|
|
13
13
|
# 5.should eql(5)
|
14
14
|
# 5.should_not eql(3)
|
15
15
|
def eql(expected)
|
16
|
-
Matcher.new :eql, expected do |
|
16
|
+
Matcher.new :eql, expected do |_expected_|
|
17
17
|
match do |actual|
|
18
|
-
actual.eql?(
|
18
|
+
actual.eql?(_expected_)
|
19
19
|
end
|
20
20
|
|
21
21
|
failure_message_for_should do |actual|
|
22
22
|
<<-MESSAGE
|
23
23
|
|
24
|
-
expected #{
|
24
|
+
expected #{_expected_.inspect}
|
25
25
|
got #{actual.inspect}
|
26
26
|
|
27
27
|
(compared using eql?)
|
@@ -31,7 +31,7 @@ MESSAGE
|
|
31
31
|
failure_message_for_should_not do |actual|
|
32
32
|
<<-MESSAGE
|
33
33
|
|
34
|
-
expected #{actual.inspect} not to equal #{
|
34
|
+
expected #{actual.inspect} not to equal #{_expected_.inspect}
|
35
35
|
|
36
36
|
(compared using eql?)
|
37
37
|
MESSAGE
|
data/lib/spec/matchers/equal.rb
CHANGED
@@ -14,27 +14,37 @@ module Spec
|
|
14
14
|
# 5.should equal(5) #Fixnums are equal
|
15
15
|
# "5".should_not equal("5") #Strings that look the same are not the same object
|
16
16
|
def equal(expected)
|
17
|
-
Matcher.new :equal, expected do |
|
17
|
+
Matcher.new :equal, expected do |_expected_|
|
18
18
|
match do |actual|
|
19
|
-
actual.equal?(
|
19
|
+
actual.equal?(_expected_)
|
20
|
+
end
|
21
|
+
|
22
|
+
def inspect_object(o)
|
23
|
+
"#<#{o.class}:#{o.object_id}> => #{o.inspect}"
|
20
24
|
end
|
21
25
|
|
22
26
|
failure_message_for_should do |actual|
|
23
27
|
<<-MESSAGE
|
24
28
|
|
25
|
-
expected #{
|
26
|
-
got #{actual
|
27
|
-
|
28
|
-
|
29
|
+
expected #{inspect_object(_expected_)}
|
30
|
+
got #{inspect_object(actual)}
|
31
|
+
|
32
|
+
Compared using equal?, which compares object identity,
|
33
|
+
but expected and actual are not the same object. Use
|
34
|
+
'actual.should == expected' if you don't care about
|
35
|
+
object identity in this example.
|
36
|
+
|
29
37
|
MESSAGE
|
30
38
|
end
|
31
39
|
|
32
40
|
failure_message_for_should_not do |actual|
|
33
41
|
<<-MESSAGE
|
34
42
|
|
35
|
-
expected
|
43
|
+
expected not #{inspect_object(actual)}
|
44
|
+
got #{inspect_object(_expected_)}
|
45
|
+
|
46
|
+
Compared using equal?, which compares object identity.
|
36
47
|
|
37
|
-
(compared using equal?)
|
38
48
|
MESSAGE
|
39
49
|
end
|
40
50
|
end
|
@@ -17,13 +17,13 @@ module Spec
|
|
17
17
|
# "spread".should include("read")
|
18
18
|
# "spread".should_not include("red")
|
19
19
|
def include(*expected)
|
20
|
-
Matcher.new :include, *expected do |*
|
20
|
+
Matcher.new :include, *expected do |*_expected_|
|
21
21
|
match do |actual|
|
22
|
-
helper(actual, *
|
22
|
+
helper(actual, *_expected_)
|
23
23
|
end
|
24
24
|
|
25
|
-
def helper(actual, *
|
26
|
-
|
25
|
+
def helper(actual, *_expected_)
|
26
|
+
_expected_.each do |expected|
|
27
27
|
if actual.is_a?(Hash)
|
28
28
|
if expected.is_a?(Hash)
|
29
29
|
expected.each_pair do |k,v|
|
data/lib/spec/matchers/match.rb
CHANGED
@@ -10,9 +10,9 @@ module Spec
|
|
10
10
|
#
|
11
11
|
# email.should match(/^([^\s]+)((?:[-a-z0-9]+\.)+[a-z]{2,})$/i)
|
12
12
|
def match(expected)
|
13
|
-
Matcher.new :match, expected do |
|
13
|
+
Matcher.new :match, expected do |_expected_|
|
14
14
|
match do |actual|
|
15
|
-
actual =~
|
15
|
+
actual =~ _expected_
|
16
16
|
end
|
17
17
|
end
|
18
18
|
end
|
@@ -55,8 +55,9 @@ module Spec
|
|
55
55
|
|
56
56
|
class PositiveOperatorMatcher < OperatorMatcher #:nodoc:
|
57
57
|
def __delegate_operator(actual, operator, expected)
|
58
|
-
|
59
|
-
|
58
|
+
if actual.__send__(operator, expected)
|
59
|
+
true
|
60
|
+
elsif ['==','===', '=~'].include?(operator)
|
60
61
|
fail_with_message("expected: #{expected.inspect},\n got: #{actual.inspect} (using #{operator})")
|
61
62
|
else
|
62
63
|
fail_with_message("expected: #{operator} #{expected.inspect},\n got: #{operator.gsub(/./, ' ')} #{actual.inspect}")
|
data/lib/spec/mocks/methods.rb
CHANGED
@@ -17,6 +17,15 @@ module Spec
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
+
alias_method :stub, :stub!
|
21
|
+
|
22
|
+
def stub_chain(*methods)
|
23
|
+
while methods.length > 1
|
24
|
+
stub!(methods.shift).and_return(self)
|
25
|
+
end
|
26
|
+
stub!(methods.shift)
|
27
|
+
end
|
28
|
+
|
20
29
|
def received_message?(sym, *args, &block) #:nodoc:
|
21
30
|
__mock_proxy.received_message?(sym.to_sym, *args, &block)
|
22
31
|
end
|
data/lib/spec/mocks/mock.rb
CHANGED
@@ -7,12 +7,17 @@ module Spec
|
|
7
7
|
# only) == Options:
|
8
8
|
# * <tt>:null_object</tt> - if true, the mock object acts as a forgiving
|
9
9
|
# null object allowing any message to be sent to it.
|
10
|
-
def initialize(name, stubs_and_options={})
|
11
|
-
|
10
|
+
def initialize(name='mock', stubs_and_options={})
|
11
|
+
if name.is_a?(Hash) && stubs_and_options.empty?
|
12
|
+
stubs_and_options = name
|
13
|
+
build_name_from_options stubs_and_options
|
14
|
+
else
|
15
|
+
@name = name
|
16
|
+
end
|
12
17
|
@options = parse_options(stubs_and_options)
|
13
18
|
assign_stubs(stubs_and_options)
|
14
19
|
end
|
15
|
-
|
20
|
+
|
16
21
|
# This allows for comparing the mock to other objects that proxy such as
|
17
22
|
# ActiveRecords belongs_to proxy objects. By making the other object run
|
18
23
|
# the comparison, we're sure the call gets delegated to the proxy
|
@@ -24,32 +29,37 @@ module Spec
|
|
24
29
|
def inspect
|
25
30
|
"#<#{self.class}:#{sprintf '0x%x', self.object_id} @name=#{@name.inspect}>"
|
26
31
|
end
|
27
|
-
|
32
|
+
|
28
33
|
def to_s
|
29
34
|
inspect.gsub('<','[').gsub('>',']')
|
30
35
|
end
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def parse_options(options)
|
45
|
-
options.has_key?(:null_object) ? {:null_object => options.delete(:null_object)} : {}
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def method_missing(sym, *args, &block)
|
40
|
+
__mock_proxy.record_message_received(sym, args, block)
|
41
|
+
begin
|
42
|
+
return self if __mock_proxy.null_object?
|
43
|
+
super(sym, *args, &block)
|
44
|
+
rescue NameError
|
45
|
+
__mock_proxy.raise_unexpected_message_error sym, *args
|
46
46
|
end
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
47
|
+
end
|
48
|
+
|
49
|
+
def parse_options(options)
|
50
|
+
options.has_key?(:null_object) ? {:null_object => options.delete(:null_object)} : {}
|
51
|
+
end
|
52
|
+
|
53
|
+
def assign_stubs(stubs)
|
54
|
+
stubs.each_pair do |message, response|
|
55
|
+
stub!(message).and_return(response)
|
52
56
|
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def build_name_from_options(options)
|
60
|
+
vals = options.inject([]) {|coll, pair| coll << "#{pair.first}: #{pair.last.inspect}"}
|
61
|
+
@name = '{' + vals.join(', ') + '}'
|
62
|
+
end
|
53
63
|
end
|
54
64
|
end
|
55
65
|
end
|
data/lib/spec/mocks/proxy.rb
CHANGED
@@ -213,6 +213,7 @@ module Spec
|
|
213
213
|
end
|
214
214
|
|
215
215
|
def find_matching_expectation(sym, *args)
|
216
|
+
@expectations.find {|expectation| expectation.matches(sym, args) && !expectation.called_max_times?} ||
|
216
217
|
@expectations.find {|expectation| expectation.matches(sym, args)}
|
217
218
|
end
|
218
219
|
|