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