rspec 0.7.2 → 0.7.5.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/CHANGES +72 -1
- data/EXAMPLES.rd +6 -0
- data/README +27 -6
- data/Rakefile +32 -81
- data/bin/drbspec +3 -0
- data/bin/spec +2 -3
- data/examples/file_accessor_spec.rb +1 -1
- data/examples/greeter_spec.rb +30 -0
- data/examples/helper_method_example.rb +1 -1
- data/examples/io_processor_spec.rb +1 -1
- data/examples/mocking_example.rb +1 -1
- data/examples/partial_mock_example.rb +1 -1
- data/examples/predicate_example.rb +1 -1
- data/examples/setup_teardown_example.rb +34 -0
- data/examples/spec_helper.rb +1 -0
- data/examples/stack_spec.rb +1 -1
- data/examples/stubbing_example.rb +1 -1
- data/examples/test_case_spec.rb +1 -1
- data/lib/spec/callback/callback_container.rb +60 -0
- data/lib/spec/callback/extensions/module.rb +24 -0
- data/lib/spec/callback/extensions/object.rb +33 -0
- data/lib/spec/callback.rb +3 -0
- data/lib/spec/expectations/diff.rb +10 -14
- data/lib/spec/expectations/extensions/numeric.rb +17 -3
- data/lib/spec/expectations/extensions/object.rb +145 -0
- data/lib/spec/expectations/extensions/proc.rb +57 -0
- data/lib/spec/expectations/extensions/string.rb +22 -0
- data/lib/spec/expectations/extensions.rb +2 -2
- data/lib/spec/expectations/message_builder.rb +13 -0
- data/lib/spec/expectations/should/base.rb +29 -10
- data/lib/spec/expectations/should/change.rb +69 -0
- data/lib/spec/expectations/should/have.rb +94 -37
- data/lib/spec/expectations/should/not.rb +6 -2
- data/lib/spec/expectations/should/should.rb +9 -5
- data/lib/spec/expectations/should.rb +1 -0
- data/lib/spec/expectations/sugar.rb +2 -2
- data/lib/spec/expectations.rb +28 -0
- data/lib/spec/mocks/error_generator.rb +23 -12
- data/lib/spec/mocks/message_expectation.rb +18 -15
- data/lib/spec/mocks/mock_handler.rb +10 -9
- data/lib/spec/mocks/mock_methods.rb +1 -1
- data/lib/spec/rake/spectask.rb +8 -2
- data/lib/spec/runner/backtrace_tweaker.rb +34 -25
- data/lib/spec/runner/context.rb +56 -7
- data/lib/spec/runner/context_eval.rb +33 -3
- data/lib/spec/runner/context_runner.rb +24 -11
- data/lib/spec/runner/drb_command_line.rb +21 -0
- data/lib/spec/runner/execution_context.rb +1 -0
- data/lib/spec/runner/extensions/kernel.rb +2 -0
- data/lib/spec/runner/extensions/object.rb +26 -18
- data/lib/spec/runner/formatter/base_text_formatter.rb +1 -1
- data/lib/spec/runner/formatter/html_formatter.rb +94 -74
- data/lib/spec/runner/heckle_runner.rb +55 -0
- data/lib/spec/runner/option_parser.rb +15 -3
- data/lib/spec/runner/reporter.rb +13 -8
- data/lib/spec/runner/specification.rb +67 -42
- data/lib/spec/runner.rb +1 -1
- data/lib/spec/version.rb +6 -5
- data/lib/spec.rb +1 -0
- metadata +20 -19
- data/lib/spec/expectations/extensions/inspect_for_expectation_not_met_error.rb +0 -14
- data/lib/spec/expectations/extensions/symbol.rb +0 -5
- data/vendor/selenium/README.txt +0 -23
- data/vendor/selenium/find_rspecs_home_page.rb +0 -23
- data/vendor/selenium/rspec_selenium.rb +0 -33
- data/vendor/selenium/start_browser_once.patch +0 -65
- data/vendor/watir/README.txt +0 -32
- data/vendor/watir/find_rspecs_home_page.rb +0 -21
- data/vendor/watir/find_rspecs_home_page.txt +0 -15
- data/vendor/watir/rspec_watir.rb +0 -45
@@ -9,23 +9,19 @@ module Spec
|
|
9
9
|
@@differ = differ
|
10
10
|
end
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
elsif ! @target.is_a? Proc
|
21
|
-
result << "\nDiff:" << @@differ.diff_as_object(@target,expected)
|
22
|
-
end
|
12
|
+
alias old_default_message default_message
|
13
|
+
def default_message(expectation, expected=:no_expectation_specified)
|
14
|
+
result = old_default_message(expectation, expected)
|
15
|
+
if expected != :no_expectation_specified
|
16
|
+
if expected.is_a?(String)
|
17
|
+
result << "\nDiff:" << @@differ.diff_as_string(@target.to_s, expected) unless @@differ.nil?
|
18
|
+
elsif ! @target.is_a? Proc
|
19
|
+
result << "\nDiff:" << @@differ.diff_as_object(@target, expected) unless @@differ.nil?
|
23
20
|
end
|
24
|
-
|
25
|
-
result
|
26
21
|
end
|
27
|
-
end
|
28
22
|
|
23
|
+
result
|
24
|
+
end
|
29
25
|
end
|
30
26
|
end
|
31
27
|
end
|
@@ -1,5 +1,19 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
module Spec
|
2
|
+
module Expectations
|
3
|
+
module NumericExpectations
|
4
|
+
# Passes if receiver is less than +-delta away from other
|
5
|
+
def should_be_close(other, delta)
|
6
|
+
should.be._close_for_rspec(other, delta)
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
def _close_for_rspec?(other, delta)
|
11
|
+
(self - other).abs < delta
|
12
|
+
end
|
13
|
+
end
|
4
14
|
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class Numeric
|
18
|
+
include Spec::Expectations::NumericExpectations
|
5
19
|
end
|
@@ -1,9 +1,154 @@
|
|
1
1
|
module Spec
|
2
2
|
module Expectations
|
3
|
+
# rspec adds all of these expectations to every Object (and,
|
4
|
+
# implicitly, every Class).
|
3
5
|
module ObjectExpectations
|
6
|
+
|
7
|
+
# Supports the following expectations:
|
8
|
+
# receiver.should == expected #any value
|
9
|
+
# Passes if (receiver == expected)
|
10
|
+
#
|
11
|
+
# receiver.should =~ expected #a regexp
|
12
|
+
# Passes if (receiver =~ expected), where expected
|
13
|
+
# is a Regexp.
|
14
|
+
#
|
15
|
+
# NOTE that this does NOT support receiver.should != expected.
|
16
|
+
# Instead, use receiver.should_not == expected
|
4
17
|
def should
|
5
18
|
Should::Should.new self
|
6
19
|
end
|
20
|
+
|
21
|
+
# Supports the following expectations:
|
22
|
+
# receiver.should_not == expected #any value
|
23
|
+
# Passes unless (receiver == expected)
|
24
|
+
#
|
25
|
+
# receiver.should_not =~ expected #a regexp
|
26
|
+
# Passes unless (receiver =~ expected), where expected
|
27
|
+
# is a Regexp.
|
28
|
+
def should_not
|
29
|
+
should.not
|
30
|
+
end
|
31
|
+
|
32
|
+
# Passes if receiver.equal?(expected)
|
33
|
+
def should_equal(expected)
|
34
|
+
should.equal(expected)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Passes unless receiver.equal?(expected)
|
38
|
+
def should_not_equal(expected)
|
39
|
+
should.not.equal(expected)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Passes if receiver.eql?(expected)
|
43
|
+
def should_eql(expected)
|
44
|
+
should.eql(expected)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Passes unless receiver.eql?(expected)
|
48
|
+
def should_not_eql(expected)
|
49
|
+
should.not.eql(expected)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Specify that the receiver should have a
|
53
|
+
# specified number of items in a named collection. For example:
|
54
|
+
#
|
55
|
+
# team.should_have(40).players
|
56
|
+
#
|
57
|
+
# Passes if team.players.size == 40.
|
58
|
+
#
|
59
|
+
# Works for collections with size() and/or length() methods.
|
60
|
+
def should_have(expected)
|
61
|
+
should.have(expected)
|
62
|
+
end
|
63
|
+
alias_method :should_have_exactly, :should_have
|
64
|
+
|
65
|
+
# Specify that the receiver should have at least a
|
66
|
+
# specified number of items in a named collection. For example:
|
67
|
+
#
|
68
|
+
# team.should_have_at_least(10).players
|
69
|
+
#
|
70
|
+
# Passes if team.players.size == 10 (or more)
|
71
|
+
#
|
72
|
+
# Fails if team.players.size == 9 (or less)
|
73
|
+
#
|
74
|
+
# Works for collections with size() and/or length() methods.
|
75
|
+
def should_have_at_least(expected)
|
76
|
+
should.have.at_least(expected)
|
77
|
+
end
|
78
|
+
|
79
|
+
# Specify that the receiver should have at most a
|
80
|
+
# specified number of items in a named collection. For example:
|
81
|
+
#
|
82
|
+
# team.should_have_at_most(10).players
|
83
|
+
#
|
84
|
+
# Passes if team.players.size == 10 (or less)
|
85
|
+
#
|
86
|
+
# Fails if team.players.size == 11 (or more)
|
87
|
+
#
|
88
|
+
# Works for collections with size() and/or length() methods.
|
89
|
+
def should_have_at_most(expected)
|
90
|
+
should.have.at_most(expected)
|
91
|
+
end
|
92
|
+
|
93
|
+
# Passes if receiver.include?(expected)
|
94
|
+
def should_include(expected)
|
95
|
+
should.include(expected)
|
96
|
+
end
|
97
|
+
|
98
|
+
# Passes unless receiver.include?(expected)
|
99
|
+
def should_not_include(expected)
|
100
|
+
should.not.include(expected)
|
101
|
+
end
|
102
|
+
|
103
|
+
def should_be(expected = :___no_arg)
|
104
|
+
should.be(expected)
|
105
|
+
end
|
106
|
+
|
107
|
+
def should_not_be(expected = :___no_arg)
|
108
|
+
should.not.be(expected)
|
109
|
+
end
|
110
|
+
|
111
|
+
# Passes if &block returns true
|
112
|
+
def should_satisfy(&block)
|
113
|
+
should.satisfy(&block)
|
114
|
+
end
|
115
|
+
|
116
|
+
# Passes unless &block returns true
|
117
|
+
def should_not_satisfy(&block)
|
118
|
+
should.not.satisfy(&block)
|
119
|
+
end
|
120
|
+
|
121
|
+
# Passes if receiver is an instance of expected_class
|
122
|
+
def should_be_an_instance_of(expected_class)
|
123
|
+
should.be.an_instance_of(expected_class)
|
124
|
+
end
|
125
|
+
alias_method :should_be_instance_of, :should_be_an_instance_of
|
126
|
+
|
127
|
+
# Passes unless receiver is an instance of expected_class
|
128
|
+
def should_not_be_an_instance_of(expected_class)
|
129
|
+
should.not.be.an_instance_of(expected_class)
|
130
|
+
end
|
131
|
+
|
132
|
+
# Passes if receiver is an instance of either expected_class
|
133
|
+
# or a subclass of expected_class
|
134
|
+
def should_be_a_kind_of(expected_class)
|
135
|
+
should.be.a_kind_of(expected_class)
|
136
|
+
end
|
137
|
+
alias_method :should_be_kind_of, :should_be_a_kind_of
|
138
|
+
|
139
|
+
# Passes unless receiver is an instance of either expected_class
|
140
|
+
# or a subclass of expected_class
|
141
|
+
def should_not_be_a_kind_of(expected_class)
|
142
|
+
should.not.be.a_kind_of(expected_class)
|
143
|
+
end
|
144
|
+
|
145
|
+
def should_respond_to(message)
|
146
|
+
should.respond_to(message)
|
147
|
+
end
|
148
|
+
|
149
|
+
def should_not_respond_to(message)
|
150
|
+
should.not.respond_to(message)
|
151
|
+
end
|
7
152
|
end
|
8
153
|
end
|
9
154
|
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Spec
|
2
|
+
module Expectations
|
3
|
+
module ProcExpectations
|
4
|
+
# Given a receiver and a message (Symbol), specifies that the result
|
5
|
+
# of sending that message that receiver should change after
|
6
|
+
# executing the proc.
|
7
|
+
#
|
8
|
+
# lambda { @team.add player }.should_change(@team.players, :size)
|
9
|
+
# lambda { @team.add player }.should_change(@team.players, :size).by(1)
|
10
|
+
# lambda { @team.add player }.should_change(@team.players, :size).to(23)
|
11
|
+
# lambda { @team.add player }.should_change(@team.players, :size).from(22).to(23)
|
12
|
+
#
|
13
|
+
# You can use a block instead of a message and receiver.
|
14
|
+
#
|
15
|
+
# lambda { @team.add player }.should_change{@team.players.size}
|
16
|
+
# lambda { @team.add player }.should_change{@team.players.size}.by(1)
|
17
|
+
# lambda { @team.add player }.should_change{@team.players.size}.to(23)
|
18
|
+
# lambda { @team.add player }.should_change{@team.players.size}.from(22).to(23)
|
19
|
+
def should_change(receiver=nil, message=nil, &block)
|
20
|
+
should.change(receiver, message, &block)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Given a receiver and a message (Symbol), specifies that the result
|
24
|
+
# of sending that message that receiver should NOT change after
|
25
|
+
# executing the proc.
|
26
|
+
#
|
27
|
+
# lambda { @team.add player }.should_not_change(@team.players, :size)
|
28
|
+
#
|
29
|
+
# You can use a block instead of a message and receiver.
|
30
|
+
#
|
31
|
+
# lambda { @team.add player }.should_not_change{@team.players.size}
|
32
|
+
def should_not_change(receiver, message)
|
33
|
+
should.not.change(receiver, message)
|
34
|
+
end
|
35
|
+
|
36
|
+
def should_raise(exception=Exception, message=nil)
|
37
|
+
should.raise(exception, message)
|
38
|
+
end
|
39
|
+
|
40
|
+
def should_not_raise(exception=Exception, message=nil)
|
41
|
+
should.not.raise(exception, message)
|
42
|
+
end
|
43
|
+
|
44
|
+
def should_throw(symbol)
|
45
|
+
should.throw(symbol)
|
46
|
+
end
|
47
|
+
|
48
|
+
def should_not_throw(symbol=:___this_is_a_symbol_that_will_likely_never_occur___)
|
49
|
+
should.not.throw(symbol)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
class Proc
|
56
|
+
include Spec::Expectations::ProcExpectations
|
57
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Spec
|
2
|
+
module Expectations
|
3
|
+
# rspec adds all of these expectations to every String object.
|
4
|
+
module StringExpectations
|
5
|
+
|
6
|
+
# Passes if receiver =~ expression
|
7
|
+
def should_match(expression)
|
8
|
+
should.match(expression)
|
9
|
+
end
|
10
|
+
|
11
|
+
# Passes unless receiver =~ expression
|
12
|
+
def should_not_match(expression)
|
13
|
+
should.not.match(expression)
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class String
|
21
|
+
include Spec::Expectations::StringExpectations
|
22
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
1
|
require 'spec/expectations/extensions/object'
|
2
|
+
require 'spec/expectations/extensions/proc'
|
2
3
|
require 'spec/expectations/extensions/numeric'
|
3
|
-
require 'spec/expectations/extensions/
|
4
|
-
require 'spec/expectations/extensions/inspect_for_expectation_not_met_error'
|
4
|
+
require 'spec/expectations/extensions/string'
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Spec
|
2
|
+
module Expectations
|
3
|
+
# TODO - DAC - This is mid-refactoring right now - I'd like to get ALL failure messages
|
4
|
+
# for rspec and rspec_on_rails generated by this class so that we can
|
5
|
+
# make any enhancements, improvements in one place. Right now it's pretty
|
6
|
+
# scattered.
|
7
|
+
class MessageBuilder
|
8
|
+
def build_message(actual, expectation, expected)
|
9
|
+
"#{actual.inspect} #{expectation} #{expected.inspect}"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -2,26 +2,44 @@ module Spec
|
|
2
2
|
module Expectations
|
3
3
|
module Should
|
4
4
|
class Base
|
5
|
+
|
6
|
+
def <(expected)
|
7
|
+
__delegate_method_missing_to_target "<", "<", expected
|
8
|
+
end
|
9
|
+
|
10
|
+
def <=(expected)
|
11
|
+
__delegate_method_missing_to_target "<=", "<=", expected
|
12
|
+
end
|
13
|
+
|
14
|
+
def ==(expected)
|
15
|
+
__delegate_method_missing_to_target "==", "==", expected
|
16
|
+
end
|
17
|
+
|
18
|
+
def =~(expected)
|
19
|
+
__delegate_method_missing_to_target "=~", "=~", expected
|
20
|
+
end
|
21
|
+
|
22
|
+
def >=(expected)
|
23
|
+
__delegate_method_missing_to_target ">=", ">=", expected
|
24
|
+
end
|
25
|
+
|
26
|
+
def >(expected)
|
27
|
+
__delegate_method_missing_to_target ">", ">", expected
|
28
|
+
end
|
5
29
|
|
6
|
-
|
7
|
-
|
8
|
-
def default_message(expectation, expected=:no_expectation_specified)
|
9
|
-
message = "#{@target.inspect_for_expectation_not_met_error} #{expectation}"
|
10
|
-
if (expected != :no_expectation_specified)
|
11
|
-
message << " " << expected.inspect_for_expectation_not_met_error
|
12
|
-
end
|
13
|
-
message
|
30
|
+
def default_message(expectation, expected=nil)
|
31
|
+
Spec::Expectations.build_message(@target, expectation, expected)
|
14
32
|
end
|
15
33
|
|
16
34
|
def fail_with_message(message)
|
17
|
-
|
35
|
+
Spec::Expectations.fail_with(message)
|
18
36
|
end
|
19
37
|
|
20
38
|
def find_supported_sym(original_sym)
|
21
39
|
["#{original_sym}?", "#{original_sym}s?"].each do |alternate_sym|
|
22
40
|
return alternate_sym.to_s if @target.respond_to?(alternate_sym.to_s)
|
23
41
|
end
|
24
|
-
return
|
42
|
+
return ["<","<=",">=",">","==","=~"].include?(original_sym) ? original_sym : "#{original_sym}?"
|
25
43
|
end
|
26
44
|
|
27
45
|
def method_missing(original_sym, *args, &block)
|
@@ -29,6 +47,7 @@ module Spec
|
|
29
47
|
return Not.new(@target).__send__(original_sym.to_s[4..-1].to_sym, *args, &block)
|
30
48
|
end
|
31
49
|
if original_sym.to_s =~ /^be_/
|
50
|
+
@be_seen = true
|
32
51
|
return __send__(original_sym.to_s[3..-1].to_sym, *args, &block)
|
33
52
|
end
|
34
53
|
if original_sym.to_s =~ /^have_/
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module Spec
|
2
|
+
module Expectations
|
3
|
+
module Should
|
4
|
+
class Change < Base
|
5
|
+
|
6
|
+
def initialize(target, receiver=nil, message=nil, &block)
|
7
|
+
@block = block
|
8
|
+
@target = target
|
9
|
+
@receiver = receiver
|
10
|
+
@message = message
|
11
|
+
execute_change
|
12
|
+
evaluate_change
|
13
|
+
end
|
14
|
+
|
15
|
+
def execute_change
|
16
|
+
@before_change = @block.nil? ? @receiver.send(@message) : @block.call
|
17
|
+
@target.call
|
18
|
+
@after_change = @block.nil? ? @receiver.send(@message) : @block.call
|
19
|
+
end
|
20
|
+
|
21
|
+
def message
|
22
|
+
@message.nil? ? 'result' : @message
|
23
|
+
end
|
24
|
+
|
25
|
+
def evaluate_change
|
26
|
+
if @before_change == @after_change
|
27
|
+
fail_with_message "#{message} should have changed, but is still #{@after_change.inspect}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def from(value)
|
32
|
+
if @before_change != value
|
33
|
+
fail_with_message "#{message} should have initially been #{value.inspect}, but was #{@before_change.inspect}"
|
34
|
+
end
|
35
|
+
self
|
36
|
+
end
|
37
|
+
|
38
|
+
def to(value)
|
39
|
+
if @after_change != value
|
40
|
+
fail_with_message "#{message} should have been changed to #{value.inspect}, but is now #{@after_change.inspect}"
|
41
|
+
end
|
42
|
+
self
|
43
|
+
end
|
44
|
+
|
45
|
+
def by(expected_delta)
|
46
|
+
if actual_delta != expected_delta
|
47
|
+
fail_with_message "#{message} should have been changed by #{expected_delta}, but was changed by #{actual_delta}"
|
48
|
+
end
|
49
|
+
self
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
def actual_delta
|
54
|
+
@after_change - @before_change
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
class NotChange < Change
|
59
|
+
def evaluate_change
|
60
|
+
if @before_change != @after_change
|
61
|
+
fail_with_message "#{@message} should not have changed, but is now #{@after_change.inspect}"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
@@ -1,23 +1,46 @@
|
|
1
1
|
module Spec
|
2
2
|
module Expectations
|
3
3
|
module Should
|
4
|
-
class Have
|
5
|
-
|
6
|
-
|
4
|
+
class Have
|
5
|
+
def initialize(target, relativity=:exactly, expected=nil)
|
6
|
+
@target = target
|
7
|
+
init_collection_handler(target, relativity, expected)
|
8
|
+
init_item_handler(target)
|
9
|
+
end
|
10
|
+
|
11
|
+
def init_collection_handler(target, relativity, expected)
|
12
|
+
@collection_handler = CollectionHandler.new(target, relativity, expected)
|
13
|
+
end
|
14
|
+
|
15
|
+
def init_item_handler(target)
|
16
|
+
@item_handler = PositiveItemHandler.new(target)
|
17
|
+
end
|
18
|
+
|
19
|
+
def method_missing(sym, *args)
|
20
|
+
if @collection_handler.wants_to_handle(sym)
|
21
|
+
@collection_handler.handle_message(sym, *args)
|
22
|
+
elsif @item_handler.wants_to_handle(sym)
|
23
|
+
@item_handler.handle_message(sym, *args)
|
24
|
+
else
|
25
|
+
raise NoMethodError.new("#{@target.inspect} does not respond to `#{sym}' or `has_#{sym}?'")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class NotHave < Have
|
31
|
+
def init_item_handler(target)
|
32
|
+
@item_handler = NegativeItemHandler.new(target)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class CollectionHandler
|
37
|
+
def initialize(target, relativity=:exactly, expected=nil)
|
7
38
|
@target = target
|
8
39
|
@expected = expected == :no ? 0 : expected
|
9
40
|
@at_least = (relativity == :at_least)
|
10
41
|
@at_most = (relativity == :at_most)
|
11
|
-
@negate = negate
|
12
|
-
end
|
13
|
-
|
14
|
-
def exactly(expected_number=nil)
|
15
|
-
@at_least = false
|
16
|
-
@at_most = false
|
17
|
-
@expected = expected_number == :no ? 0 : expected_number
|
18
|
-
self
|
19
42
|
end
|
20
|
-
|
43
|
+
|
21
44
|
def at_least(expected_number=nil)
|
22
45
|
@at_least = true
|
23
46
|
@at_most = false
|
@@ -34,45 +57,79 @@ module Spec
|
|
34
57
|
|
35
58
|
def method_missing(sym, *args)
|
36
59
|
if @target.respond_to?(sym)
|
37
|
-
|
38
|
-
elsif @target.respond_to?("has_#{sym}?")
|
39
|
-
if @negate
|
40
|
-
return unless @target.send("has_#{sym}?", *args)
|
41
|
-
fail_with_message msg(sym, args, "should not have")
|
42
|
-
else
|
43
|
-
return if @target.send("has_#{sym}?", *args)
|
44
|
-
fail_with_message msg(sym, args, "should have")
|
45
|
-
end
|
46
|
-
else
|
47
|
-
raise NoMethodError.new("#{@target.inspect} does not respond to `#{sym}' or `has_#{sym}?'")
|
60
|
+
handle_message(sym, *args)
|
48
61
|
end
|
49
62
|
end
|
50
|
-
|
51
|
-
def
|
52
|
-
|
63
|
+
|
64
|
+
def wants_to_handle(sym)
|
65
|
+
respond_to?(sym) || @target.respond_to?(sym)
|
53
66
|
end
|
54
|
-
|
55
|
-
def
|
56
|
-
return
|
57
|
-
return
|
67
|
+
|
68
|
+
def handle_message(sym, *args)
|
69
|
+
return at_least(args[0]) if sym == :at_least
|
70
|
+
return at_most(args[0]) if sym == :at_most
|
71
|
+
Spec::Expectations.fail_with(build_message(sym, args)) unless as_specified?(sym, args)
|
58
72
|
end
|
59
|
-
|
73
|
+
|
60
74
|
def build_message(sym, args)
|
61
|
-
message = "#{@target.
|
75
|
+
message = "#{@target.inspect} should have"
|
62
76
|
message += " at least" if @at_least
|
63
77
|
message += " at most" if @at_most
|
64
|
-
message += " #{@expected} #{sym} (has #{
|
78
|
+
message += " #{@expected} #{sym} (has #{actual_size_of(collection(sym, args))})"
|
65
79
|
end
|
66
|
-
|
80
|
+
|
67
81
|
def as_specified?(sym, args)
|
68
|
-
return
|
69
|
-
return
|
70
|
-
return
|
82
|
+
return actual_size_of(collection(sym, args)) >= @expected if @at_least
|
83
|
+
return actual_size_of(collection(sym, args)) <= @expected if @at_most
|
84
|
+
return actual_size_of(collection(sym, args)) == @expected
|
71
85
|
end
|
72
86
|
|
73
87
|
def collection(sym, args)
|
74
88
|
@target.send(sym, *args)
|
75
89
|
end
|
90
|
+
|
91
|
+
def actual_size_of(collection)
|
92
|
+
return collection.length if collection.respond_to? :length
|
93
|
+
return collection.size if collection.respond_to? :size
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
class ItemHandler
|
98
|
+
def wants_to_handle(sym)
|
99
|
+
@target.respond_to?("has_#{sym}?")
|
100
|
+
end
|
101
|
+
|
102
|
+
def initialize(target)
|
103
|
+
@target = target
|
104
|
+
end
|
105
|
+
|
106
|
+
def build_message(sym, args)
|
107
|
+
"#{@target.inspect} #{item_expectation} #{sym}: #{args.collect{|arg| arg.inspect}.join(', ')}"
|
108
|
+
end
|
109
|
+
|
110
|
+
def fail_with(message)
|
111
|
+
Spec::Expectations.fail_with(message)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
class PositiveItemHandler < ItemHandler
|
116
|
+
def handle_message(sym, *args)
|
117
|
+
fail_with(build_message(sym, args)) unless @target.send("has_#{sym}?", *args)
|
118
|
+
end
|
119
|
+
|
120
|
+
def item_expectation
|
121
|
+
"should have"
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
class NegativeItemHandler < ItemHandler
|
126
|
+
def handle_message(sym, *args)
|
127
|
+
fail_with(build_message(sym, args)) if @target.send("has_#{sym}?", *args)
|
128
|
+
end
|
129
|
+
|
130
|
+
def item_expectation
|
131
|
+
"should not have"
|
132
|
+
end
|
76
133
|
end
|
77
134
|
end
|
78
135
|
end
|
@@ -9,7 +9,11 @@ module Spec
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def have(expected_number=nil)
|
12
|
-
|
12
|
+
NotHave.new(@target, :exactly, expected_number)
|
13
|
+
end
|
14
|
+
|
15
|
+
def change(receiver, message)
|
16
|
+
NotChange.new(@target, receiver, message)
|
13
17
|
end
|
14
18
|
|
15
19
|
def satisfy
|
@@ -64,7 +68,7 @@ module Spec
|
|
64
68
|
|
65
69
|
def __delegate_method_missing_to_target original_sym, actual_sym, *args
|
66
70
|
return unless @target.__send__(actual_sym, *args)
|
67
|
-
fail_with_message(default_message("should not#{@be_seen ? ' be' : ''} #{original_sym}" + (args.empty? ? '' :
|
71
|
+
fail_with_message(default_message("should not#{@be_seen ? ' be' : ''} #{original_sym}" + (args.empty? ? '' : ' ' + args[0].inspect)))
|
68
72
|
end
|
69
73
|
end
|
70
74
|
end
|
@@ -1,17 +1,21 @@
|
|
1
1
|
module Spec
|
2
2
|
module Expectations
|
3
|
-
module Should
|
3
|
+
module Should # :nodoc:
|
4
4
|
class Should < Base
|
5
5
|
|
6
6
|
def initialize(target)
|
7
7
|
@target = target
|
8
8
|
@be_seen = false
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
def have(expected_number=nil)
|
12
12
|
Have.new(@target, :exactly, expected_number)
|
13
13
|
end
|
14
14
|
|
15
|
+
def change(receiver=nil, message=nil, &block)
|
16
|
+
Change.new(@target, receiver, message, &block)
|
17
|
+
end
|
18
|
+
|
15
19
|
def not
|
16
20
|
Not.new(@target)
|
17
21
|
end
|
@@ -55,9 +59,9 @@ module Spec
|
|
55
59
|
rescue exception => e
|
56
60
|
unless message.nil?
|
57
61
|
if message.is_a?(Regexp)
|
58
|
-
e.message.
|
62
|
+
e.message.should =~ message
|
59
63
|
else
|
60
|
-
e.message.
|
64
|
+
e.message.should == message
|
61
65
|
end
|
62
66
|
end
|
63
67
|
return
|
@@ -80,4 +84,4 @@ module Spec
|
|
80
84
|
end
|
81
85
|
end
|
82
86
|
end
|
83
|
-
end
|
87
|
+
end
|