rspec 0.7.2 → 0.7.5.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -1,7 +1,7 @@
|
|
1
1
|
module Spec
|
2
2
|
module Expectations
|
3
3
|
# This module adds syntactic sugar that allows usage of should_* instead of should.*
|
4
|
-
module UnderscoreSugar
|
4
|
+
module UnderscoreSugar # :nodoc:
|
5
5
|
def handle_underscores_for_rspec!
|
6
6
|
original_method_missing = instance_method(:method_missing)
|
7
7
|
class_eval do
|
@@ -14,7 +14,7 @@ module Spec
|
|
14
14
|
return Spec::Expectations::Should::Should.new(self).__send__(__strip_should(sym), *args, &block)
|
15
15
|
end
|
16
16
|
|
17
|
-
def __strip_should
|
17
|
+
def __strip_should(sym) # :nodoc
|
18
18
|
sym.to_s[7..-1]
|
19
19
|
end
|
20
20
|
end
|
data/lib/spec/expectations.rb
CHANGED
@@ -2,3 +2,31 @@ require 'spec/expectations/sugar'
|
|
2
2
|
require 'spec/expectations/errors'
|
3
3
|
require 'spec/expectations/extensions'
|
4
4
|
require 'spec/expectations/should'
|
5
|
+
require 'spec/expectations/message_builder'
|
6
|
+
|
7
|
+
module Spec
|
8
|
+
# See Spec::Expectations::ObjectExpectations for expectations that
|
9
|
+
# are available on all objects.
|
10
|
+
#
|
11
|
+
# See Spec::Expectations::ProcExpectations for expectations that
|
12
|
+
# are available on Proc objects.
|
13
|
+
#
|
14
|
+
# See Spec::Expectations::NumericExpectations for expectations that
|
15
|
+
# are available on Numeric objects.
|
16
|
+
module Expectations
|
17
|
+
class << self
|
18
|
+
# raises a Spec::Expectations::ExpecationNotMetError with message
|
19
|
+
def fail_with(message)
|
20
|
+
Kernel::raise(Spec::Expectations::ExpectationNotMetError.new(message))
|
21
|
+
end
|
22
|
+
|
23
|
+
def build_message(actual, expectation, expected)
|
24
|
+
message_builder.build_message(actual, expectation, expected)
|
25
|
+
end
|
26
|
+
|
27
|
+
def message_builder #:nodoc:
|
28
|
+
@message_builder ||= MessageBuilder.new
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -3,7 +3,7 @@ module Spec
|
|
3
3
|
class ErrorGenerator
|
4
4
|
attr_writer :opts
|
5
5
|
|
6
|
-
def initialize
|
6
|
+
def initialize(target, name)
|
7
7
|
@target = target
|
8
8
|
@name = name
|
9
9
|
end
|
@@ -12,27 +12,34 @@ module Spec
|
|
12
12
|
@opts ||= {}
|
13
13
|
end
|
14
14
|
|
15
|
-
def raise_unexpected_message_error
|
15
|
+
def raise_unexpected_message_error(sym, *args)
|
16
16
|
__raise "#{intro} received unexpected message :#{sym}#{arg_message(*args)}"
|
17
17
|
end
|
18
18
|
|
19
|
-
def
|
19
|
+
def raise_unexpected_message_args_error(expectation, *args)
|
20
|
+
#this is either :no_args or an Array
|
21
|
+
expected_args = (expectation.expected_args == :no_args ? "(no args)" : format_args(*expectation.expected_args))
|
22
|
+
actual_args = args.empty? ? "(no args)" : format_args(*args)
|
23
|
+
__raise "#{intro} expected #{expectation.sym.inspect} with #{expected_args} but received it with #{actual_args}"
|
24
|
+
end
|
25
|
+
|
26
|
+
def raise_expectation_error(sym, expected_received_count, actual_received_count, *args)
|
20
27
|
__raise "#{intro} expected :#{sym}#{arg_message(*args)} #{count_message(expected_received_count)}, but received it #{count_message(actual_received_count)}"
|
21
28
|
end
|
22
29
|
|
23
|
-
def raise_out_of_order_error
|
30
|
+
def raise_out_of_order_error(sym)
|
24
31
|
__raise "#{intro} received :#{sym} out of order"
|
25
32
|
end
|
26
33
|
|
27
|
-
def raise_block_failed_error
|
34
|
+
def raise_block_failed_error(sym, detail)
|
28
35
|
__raise "#{intro} received :#{sym} but passed block failed with: #{detail}"
|
29
36
|
end
|
30
37
|
|
31
|
-
def raise_missing_block_error
|
38
|
+
def raise_missing_block_error(args_to_yield)
|
32
39
|
__raise "#{intro} asked to yield |#{arg_list(*args_to_yield)}| but no block was passed"
|
33
40
|
end
|
34
41
|
|
35
|
-
def raise_wrong_arity_error
|
42
|
+
def raise_wrong_arity_error(args_to_yield, arity)
|
36
43
|
__raise "#{intro} yielded |#{arg_list(*args_to_yield)}| to block with arity of #{arity}"
|
37
44
|
end
|
38
45
|
|
@@ -41,15 +48,19 @@ module Spec
|
|
41
48
|
@name ? "Mock '#{@name}'" : @target.to_s
|
42
49
|
end
|
43
50
|
|
44
|
-
def __raise
|
51
|
+
def __raise(message)
|
45
52
|
message = opts[:message] unless opts[:message].nil?
|
46
53
|
Kernel::raise(Spec::Mocks::MockExpectationError, message)
|
47
54
|
end
|
48
55
|
|
49
|
-
def arg_message
|
50
|
-
|
51
|
-
|
52
|
-
|
56
|
+
def arg_message(*args)
|
57
|
+
" with " + format_args(*args)
|
58
|
+
end
|
59
|
+
|
60
|
+
def format_args(*args)
|
61
|
+
return "(no args)" if args.empty? || args == :no_args || args == [:no_args]
|
62
|
+
return "(any args)" if [:any_args] == args
|
63
|
+
"(" + arg_list(*args) + ")"
|
53
64
|
end
|
54
65
|
|
55
66
|
def arg_list(*args)
|
@@ -22,6 +22,10 @@ module Spec
|
|
22
22
|
@at_most = nil
|
23
23
|
@args_to_yield = nil
|
24
24
|
end
|
25
|
+
|
26
|
+
def expected_args
|
27
|
+
@args_expectation.args
|
28
|
+
end
|
25
29
|
|
26
30
|
def and_return(*values, &return_block)
|
27
31
|
Kernel::raise AmbiguousReturnError unless @method_block.nil?
|
@@ -41,6 +45,14 @@ module Spec
|
|
41
45
|
@exception_to_raise = exception
|
42
46
|
end
|
43
47
|
|
48
|
+
def and_throw(symbol)
|
49
|
+
@symbol_to_throw = symbol
|
50
|
+
end
|
51
|
+
|
52
|
+
def and_yield(*args)
|
53
|
+
@args_to_yield = args
|
54
|
+
end
|
55
|
+
|
44
56
|
def matches(sym, args)
|
45
57
|
@sym == sym and @args_expectation.check_args(args)
|
46
58
|
end
|
@@ -83,7 +95,7 @@ module Spec
|
|
83
95
|
if block.nil?
|
84
96
|
@error_generator.raise_missing_block_error @args_to_yield
|
85
97
|
end
|
86
|
-
if @args_to_yield.length != block.arity
|
98
|
+
if block.arity > -1 && @args_to_yield.length != block.arity
|
87
99
|
@error_generator.raise_wrong_arity_error @args_to_yield, block.arity
|
88
100
|
end
|
89
101
|
block.call(*@args_to_yield)
|
@@ -125,7 +137,6 @@ module Spec
|
|
125
137
|
end
|
126
138
|
end
|
127
139
|
|
128
|
-
|
129
140
|
def with(*args)
|
130
141
|
@args_expectation = ArgumentExpectation.new(args)
|
131
142
|
self
|
@@ -146,7 +157,7 @@ module Spec
|
|
146
157
|
self
|
147
158
|
end
|
148
159
|
|
149
|
-
def set_expected_received_count
|
160
|
+
def set_expected_received_count(relativity, n)
|
150
161
|
@at_least = (relativity == :at_least)
|
151
162
|
@at_most = (relativity == :at_most)
|
152
163
|
@expected_received_count = 1 if n == :once
|
@@ -179,38 +190,30 @@ module Spec
|
|
179
190
|
self
|
180
191
|
end
|
181
192
|
|
182
|
-
def and_throw(symbol)
|
183
|
-
@symbol_to_throw = symbol
|
184
|
-
end
|
185
|
-
|
186
|
-
def and_yield(*args)
|
187
|
-
@args_to_yield = args
|
188
|
-
end
|
189
|
-
|
190
193
|
def ordered
|
191
194
|
@order_group.register(self)
|
192
195
|
@ordered = true
|
193
196
|
self
|
194
197
|
end
|
195
198
|
|
196
|
-
def negative_expectation_for?
|
199
|
+
def negative_expectation_for?(sym)
|
197
200
|
return false
|
198
201
|
end
|
199
202
|
end
|
200
203
|
|
201
204
|
class NegativeMessageExpectation < MessageExpectation
|
202
205
|
def initialize(message, expectation_ordering, expected_from, sym, method_block)
|
203
|
-
super
|
206
|
+
super(message, expectation_ordering, expected_from, sym, method_block, 0)
|
204
207
|
end
|
205
208
|
|
206
|
-
def negative_expectation_for?
|
209
|
+
def negative_expectation_for?(sym)
|
207
210
|
return @sym == sym
|
208
211
|
end
|
209
212
|
end
|
210
213
|
|
211
214
|
class MethodStub < BaseExpectation
|
212
215
|
def initialize(message, expectation_ordering, expected_from, sym, method_block)
|
213
|
-
super
|
216
|
+
super(message, expectation_ordering, expected_from, sym, method_block, 0)
|
214
217
|
@expected_received_count = :any
|
215
218
|
end
|
216
219
|
end
|
@@ -41,14 +41,11 @@ module Spec
|
|
41
41
|
end
|
42
42
|
|
43
43
|
def __add expected_from, sym, block
|
44
|
-
Runner::Specification.
|
44
|
+
current_spec = Runner::Specification.current
|
45
|
+
current_spec.after_teardown {verify} if current_spec && @options[:auto_verify]
|
45
46
|
define_expected_method(sym)
|
46
47
|
end
|
47
48
|
|
48
|
-
def spec_finished spec
|
49
|
-
verify
|
50
|
-
end
|
51
|
-
|
52
49
|
def define_expected_method(sym)
|
53
50
|
if @target.respond_to?(sym) && !@proxied_methods[sym]
|
54
51
|
@proxied_methods[sym] = @target.method(sym)
|
@@ -106,7 +103,7 @@ module Spec
|
|
106
103
|
@proxied_methods.clear
|
107
104
|
end
|
108
105
|
|
109
|
-
def metaclass_eval
|
106
|
+
def metaclass_eval(str)
|
110
107
|
(class << @target; self; end).class_eval str
|
111
108
|
end
|
112
109
|
|
@@ -135,15 +132,19 @@ module Spec
|
|
135
132
|
if expectation = find_matching_expectation(sym, *args)
|
136
133
|
expectation.invoke(args, block)
|
137
134
|
elsif stub = find_matching_method_stub(sym)
|
138
|
-
stub.invoke([],
|
135
|
+
stub.invoke([], block)
|
139
136
|
elsif expectation = find_almost_matching_expectation(sym, *args)
|
140
|
-
|
137
|
+
raise_unexpected_message_args_error(expectation, *args) unless has_negative_expectation?(sym) unless null_object?
|
141
138
|
else
|
142
139
|
@target.send :method_missing, sym, *args, &block
|
143
140
|
end
|
144
141
|
end
|
145
142
|
|
146
|
-
def
|
143
|
+
def raise_unexpected_message_args_error(expectation, *args)
|
144
|
+
@error_generator.raise_unexpected_message_args_error expectation, *args
|
145
|
+
end
|
146
|
+
|
147
|
+
def raise_unexpected_message_error(sym, *args)
|
147
148
|
@error_generator.raise_unexpected_message_error sym, *args
|
148
149
|
end
|
149
150
|
|
data/lib/spec/rake/spectask.rb
CHANGED
@@ -12,8 +12,9 @@ module Spec
|
|
12
12
|
#
|
13
13
|
# Example:
|
14
14
|
#
|
15
|
-
# Rake::SpecTask.new do |t|
|
15
|
+
# Spec::Rake::SpecTask.new do |t|
|
16
16
|
# t.warning = true
|
17
|
+
# t.rcov = true
|
17
18
|
# end
|
18
19
|
#
|
19
20
|
# This will create a task that can be run with:
|
@@ -63,6 +64,11 @@ module Spec
|
|
63
64
|
|
64
65
|
# A message to print to stdout when there are failures.
|
65
66
|
attr_accessor :failure_message
|
67
|
+
|
68
|
+
# Whether or not to run specs via DRb. Setting this to true may
|
69
|
+
# run specs faster, especially in a Rails environment.
|
70
|
+
# Defaults to false
|
71
|
+
attr_accessor :drb
|
66
72
|
|
67
73
|
# Explicitly define the list of spec files to be included in a
|
68
74
|
# spec. +list+ is expected to be an array of file names (a
|
@@ -93,7 +99,7 @@ module Spec
|
|
93
99
|
end
|
94
100
|
|
95
101
|
def define
|
96
|
-
spec_script = File.expand_path(File.dirname(__FILE__) + '/../../../bin/spec')
|
102
|
+
spec_script = File.expand_path(File.dirname(__FILE__) + '/../../../bin/' + (drb ? 'drbspec' : 'spec'))
|
97
103
|
|
98
104
|
lib_path = @libs.join(File::PATH_SEPARATOR)
|
99
105
|
actual_name = Hash === name ? name.keys.first : name
|
@@ -1,42 +1,51 @@
|
|
1
1
|
module Spec
|
2
2
|
module Runner
|
3
|
-
class
|
4
|
-
def
|
5
|
-
line
|
6
|
-
line
|
3
|
+
class BacktraceTweaker
|
4
|
+
def clean_up_double_slashes(line)
|
5
|
+
line.gsub!('//','/')
|
7
6
|
end
|
7
|
+
end
|
8
|
+
|
9
|
+
class NoisyBacktraceTweaker < BacktraceTweaker
|
8
10
|
def tweak_backtrace(error, spec_name)
|
9
11
|
return if error.backtrace.nil?
|
10
|
-
error.backtrace.
|
11
|
-
|
12
|
+
error.backtrace.each do |line|
|
13
|
+
clean_up_double_slashes(line)
|
12
14
|
end
|
13
|
-
error.backtrace.compact!
|
14
15
|
end
|
15
16
|
end
|
16
17
|
|
17
18
|
# Tweaks raised Exceptions to mask noisy (unneeded) parts of the backtrace
|
18
|
-
class QuietBacktraceTweaker
|
19
|
-
|
20
|
-
|
21
|
-
|
19
|
+
class QuietBacktraceTweaker < BacktraceTweaker
|
20
|
+
unless defined?(IGNORE_PATTERNS)
|
21
|
+
root_dir = File.expand_path(File.join(__FILE__, '..', '..', '..', '..'))
|
22
|
+
spec_files = Dir["#{root_dir}/lib/spec/*"].map do |path|
|
23
|
+
subpath = path[root_dir.length..-1]
|
24
|
+
/#{subpath}/
|
25
|
+
end
|
26
|
+
IGNORE_PATTERNS = spec_files + [
|
27
|
+
/\/lib\/ruby\//,
|
28
|
+
/bin\/spec:/,
|
29
|
+
/bin\/rcov:/,
|
30
|
+
/lib\/rspec_on_rails/,
|
31
|
+
/vendor\/rails/,
|
32
|
+
# TextMate's Ruby and RSpec plugins
|
33
|
+
/Ruby\.tmbundle\/Support\/tmruby.rb:/,
|
34
|
+
/RSpec\.tmbundle\/Support\/lib/,
|
35
|
+
/temp_textmate\./
|
36
|
+
]
|
22
37
|
end
|
38
|
+
|
23
39
|
def tweak_backtrace(error, spec_name)
|
24
40
|
return if error.backtrace.nil?
|
25
41
|
error.backtrace.collect! do |line|
|
26
|
-
line
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
line = nil if line =~ /bin\/rcov:/
|
34
|
-
line = nil if line =~ /lib\/rspec_on_rails/
|
35
|
-
line = nil if line =~ /script\/rails_spec/
|
36
|
-
# TextMate's Ruby and RSpec plugins
|
37
|
-
line = nil if line =~ /Ruby\.tmbundle\/Support\/tmruby.rb:/
|
38
|
-
line = nil if line =~ /RSpec\.tmbundle\/Support\/lib/
|
39
|
-
line = nil if line =~ /temp_textmate\./
|
42
|
+
clean_up_double_slashes(line)
|
43
|
+
IGNORE_PATTERNS.each do |ignore|
|
44
|
+
if line =~ ignore
|
45
|
+
line = nil
|
46
|
+
break
|
47
|
+
end
|
48
|
+
end
|
40
49
|
line
|
41
50
|
end
|
42
51
|
error.backtrace.compact!
|
data/lib/spec/runner/context.rb
CHANGED
@@ -20,11 +20,20 @@ module Spec
|
|
20
20
|
def inherit(klass)
|
21
21
|
@context_eval_module.inherit klass
|
22
22
|
end
|
23
|
+
alias :inherit_context_eval_module_from :inherit
|
23
24
|
|
24
25
|
def include(mod)
|
25
26
|
@context_eval_module.include mod
|
26
27
|
end
|
27
28
|
|
29
|
+
def context_setup(&block)
|
30
|
+
@context_eval_module.context_setup(&block)
|
31
|
+
end
|
32
|
+
|
33
|
+
def context_teardown(&block)
|
34
|
+
@context_eval_module.context_teardown(&block)
|
35
|
+
end
|
36
|
+
|
28
37
|
def setup(&block)
|
29
38
|
@context_eval_module.setup(&block)
|
30
39
|
end
|
@@ -39,15 +48,16 @@ module Spec
|
|
39
48
|
|
40
49
|
def run(reporter, dry_run=false)
|
41
50
|
reporter.add_context(@name)
|
42
|
-
|
43
51
|
prepare_execution_context_class
|
52
|
+
errors = run_context_setup(reporter, dry_run)
|
53
|
+
|
44
54
|
specifications.each do |specification|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
55
|
+
specification_execution_context = execution_context(specification)
|
56
|
+
specification_execution_context.copy_instance_variables_from(@once_only_execution_context_instance, [:@spec]) unless context_setup_block.nil?
|
57
|
+
specification.run(reporter, setup_block, teardown_block, dry_run, specification_execution_context)
|
58
|
+
end unless errors.length > 0
|
59
|
+
|
60
|
+
run_context_teardown(reporter, dry_run)
|
51
61
|
end
|
52
62
|
|
53
63
|
def number_of_specs
|
@@ -82,6 +92,14 @@ module Spec
|
|
82
92
|
@context_eval_module.method_missing(*args)
|
83
93
|
end
|
84
94
|
|
95
|
+
def context_setup_block
|
96
|
+
@context_eval_module.send :context_setup_block
|
97
|
+
end
|
98
|
+
|
99
|
+
def context_teardown_block
|
100
|
+
@context_eval_module.send :context_teardown_block
|
101
|
+
end
|
102
|
+
|
85
103
|
def specifications
|
86
104
|
@context_eval_module.send :specifications
|
87
105
|
end
|
@@ -118,6 +136,37 @@ module Spec
|
|
118
136
|
@context_eval_module.send :execution_context_class
|
119
137
|
end
|
120
138
|
|
139
|
+
def execution_context specification
|
140
|
+
execution_context_class.new(specification)
|
141
|
+
end
|
142
|
+
|
143
|
+
def run_context_setup(reporter, dry_run)
|
144
|
+
errors = []
|
145
|
+
unless dry_run
|
146
|
+
begin
|
147
|
+
@once_only_execution_context_instance = execution_context(nil)
|
148
|
+
@once_only_execution_context_instance.instance_eval(&context_setup_block)
|
149
|
+
rescue => e
|
150
|
+
errors << e
|
151
|
+
location = "context_setup"
|
152
|
+
reporter.spec_finished(location, e, location) if reporter
|
153
|
+
end
|
154
|
+
end
|
155
|
+
errors
|
156
|
+
end
|
157
|
+
|
158
|
+
def run_context_teardown(reporter, dry_run)
|
159
|
+
unless dry_run
|
160
|
+
begin
|
161
|
+
@once_only_execution_context_instance ||= execution_context(nil)
|
162
|
+
@once_only_execution_context_instance.instance_eval(&context_teardown_block)
|
163
|
+
rescue => e
|
164
|
+
location = "context_teardown"
|
165
|
+
reporter.spec_finished(location, e, location) if reporter
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
121
170
|
end
|
122
171
|
include InstanceMethods
|
123
172
|
end
|
@@ -11,6 +11,14 @@ module Spec
|
|
11
11
|
context_modules << mod
|
12
12
|
end
|
13
13
|
|
14
|
+
def context_setup(&block)
|
15
|
+
context_setup_parts << block
|
16
|
+
end
|
17
|
+
|
18
|
+
def context_teardown(&block)
|
19
|
+
context_teardown_parts << block
|
20
|
+
end
|
21
|
+
|
14
22
|
def setup(&block)
|
15
23
|
setup_parts << block
|
16
24
|
end
|
@@ -28,7 +36,8 @@ module Spec
|
|
28
36
|
my_methods |= context_superclass.methods
|
29
37
|
my_methods
|
30
38
|
end
|
31
|
-
|
39
|
+
|
40
|
+
protected
|
32
41
|
|
33
42
|
def method_missing(method_name, *args)
|
34
43
|
if context_superclass.respond_to?(method_name)
|
@@ -37,7 +46,20 @@ module Spec
|
|
37
46
|
super
|
38
47
|
end
|
39
48
|
|
40
|
-
|
49
|
+
private
|
50
|
+
|
51
|
+
def context_setup_block
|
52
|
+
parts = context_setup_parts.dup
|
53
|
+
add_context_superclass_method(:context_setup, parts)
|
54
|
+
create_block_from_parts(parts)
|
55
|
+
end
|
56
|
+
|
57
|
+
def context_teardown_block
|
58
|
+
parts = context_teardown_parts.dup
|
59
|
+
add_context_superclass_method(:context_teardown, parts)
|
60
|
+
create_block_from_parts(parts)
|
61
|
+
end
|
62
|
+
|
41
63
|
def setup_block
|
42
64
|
parts = setup_parts.dup
|
43
65
|
add_context_superclass_method(:setup, parts)
|
@@ -73,6 +95,14 @@ module Spec
|
|
73
95
|
@specifications ||= []
|
74
96
|
end
|
75
97
|
|
98
|
+
def context_setup_parts
|
99
|
+
@context_setup_parts ||= []
|
100
|
+
end
|
101
|
+
|
102
|
+
def context_teardown_parts
|
103
|
+
@context_teardown_parts ||= []
|
104
|
+
end
|
105
|
+
|
76
106
|
def setup_parts
|
77
107
|
@setup_parts ||= []
|
78
108
|
end
|
@@ -96,7 +126,7 @@ module Spec
|
|
96
126
|
if part.is_a?(UnboundMethod)
|
97
127
|
part.bind(self).call
|
98
128
|
else
|
99
|
-
|
129
|
+
instance_eval(&part)
|
100
130
|
end
|
101
131
|
end
|
102
132
|
end
|
@@ -4,30 +4,43 @@ module Spec
|
|
4
4
|
module Runner
|
5
5
|
class ContextRunner
|
6
6
|
|
7
|
-
def initialize(
|
7
|
+
def initialize(options)
|
8
8
|
@contexts = []
|
9
|
-
@
|
10
|
-
@dry_run = dry_run
|
11
|
-
@single_spec = single_spec
|
9
|
+
@options = options
|
12
10
|
end
|
13
11
|
|
14
12
|
def add_context(context)
|
15
|
-
return if !@
|
16
|
-
context.run_single_spec
|
13
|
+
return if !@options.spec_name.nil? unless context.matches?(@options.spec_name)
|
14
|
+
context.run_single_spec(@options.spec_name) if context.matches?(@options.spec_name)
|
17
15
|
@contexts << context
|
18
16
|
end
|
19
17
|
|
18
|
+
# Runs all contexts and returns the number of failures.
|
20
19
|
def run(exit_when_done)
|
21
|
-
@reporter.start(number_of_specs)
|
22
|
-
|
23
|
-
|
20
|
+
@options.reporter.start(number_of_specs)
|
21
|
+
begin
|
22
|
+
@contexts.each do |context|
|
23
|
+
context.run(@options.reporter, @options.dry_run)
|
24
|
+
end
|
25
|
+
rescue Interrupt
|
26
|
+
ensure
|
27
|
+
@options.reporter.end
|
24
28
|
end
|
25
|
-
@reporter.
|
26
|
-
|
29
|
+
failure_count = @options.reporter.dump
|
30
|
+
|
31
|
+
if(failure_count == 0 && !@options.heckle_runner.nil?)
|
32
|
+
heckle_runner = @options.heckle_runner
|
33
|
+
@options.heckle_runner = nil
|
34
|
+
context_runner = self.class.new(@options)
|
35
|
+
context_runner.instance_variable_set(:@contexts, @contexts)
|
36
|
+
heckle_runner.heckle_with(context_runner)
|
37
|
+
end
|
38
|
+
|
27
39
|
if(exit_when_done)
|
28
40
|
exit_code = (failure_count == 0) ? 0 : 1
|
29
41
|
exit(exit_code)
|
30
42
|
end
|
43
|
+
failure_count
|
31
44
|
end
|
32
45
|
|
33
46
|
def number_of_specs
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require "drb/drb"
|
2
|
+
|
3
|
+
module Spec
|
4
|
+
module Runner
|
5
|
+
# Facade to run specs by connecting to a DRB server
|
6
|
+
class DrbCommandLine
|
7
|
+
# Runs specs on a DRB server. Note that this API is similar to that of
|
8
|
+
# CommandLine - making it possible for clients to use both interchangeably.
|
9
|
+
def self.run(argv, stderr, stdout, exit=false, warn_if_no_files=true)
|
10
|
+
begin
|
11
|
+
DRb.start_service
|
12
|
+
rails_spec_server = DRbObject.new_with_uri("druby://localhost:8989")
|
13
|
+
rails_spec_server.run(argv, stderr, stdout)
|
14
|
+
rescue DRb::DRbConnError
|
15
|
+
stderr.puts "No server is running"
|
16
|
+
exit 1 if exit
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|