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.
Files changed (70) hide show
  1. data/CHANGES +72 -1
  2. data/EXAMPLES.rd +6 -0
  3. data/README +27 -6
  4. data/Rakefile +32 -81
  5. data/bin/drbspec +3 -0
  6. data/bin/spec +2 -3
  7. data/examples/file_accessor_spec.rb +1 -1
  8. data/examples/greeter_spec.rb +30 -0
  9. data/examples/helper_method_example.rb +1 -1
  10. data/examples/io_processor_spec.rb +1 -1
  11. data/examples/mocking_example.rb +1 -1
  12. data/examples/partial_mock_example.rb +1 -1
  13. data/examples/predicate_example.rb +1 -1
  14. data/examples/setup_teardown_example.rb +34 -0
  15. data/examples/spec_helper.rb +1 -0
  16. data/examples/stack_spec.rb +1 -1
  17. data/examples/stubbing_example.rb +1 -1
  18. data/examples/test_case_spec.rb +1 -1
  19. data/lib/spec/callback/callback_container.rb +60 -0
  20. data/lib/spec/callback/extensions/module.rb +24 -0
  21. data/lib/spec/callback/extensions/object.rb +33 -0
  22. data/lib/spec/callback.rb +3 -0
  23. data/lib/spec/expectations/diff.rb +10 -14
  24. data/lib/spec/expectations/extensions/numeric.rb +17 -3
  25. data/lib/spec/expectations/extensions/object.rb +145 -0
  26. data/lib/spec/expectations/extensions/proc.rb +57 -0
  27. data/lib/spec/expectations/extensions/string.rb +22 -0
  28. data/lib/spec/expectations/extensions.rb +2 -2
  29. data/lib/spec/expectations/message_builder.rb +13 -0
  30. data/lib/spec/expectations/should/base.rb +29 -10
  31. data/lib/spec/expectations/should/change.rb +69 -0
  32. data/lib/spec/expectations/should/have.rb +94 -37
  33. data/lib/spec/expectations/should/not.rb +6 -2
  34. data/lib/spec/expectations/should/should.rb +9 -5
  35. data/lib/spec/expectations/should.rb +1 -0
  36. data/lib/spec/expectations/sugar.rb +2 -2
  37. data/lib/spec/expectations.rb +28 -0
  38. data/lib/spec/mocks/error_generator.rb +23 -12
  39. data/lib/spec/mocks/message_expectation.rb +18 -15
  40. data/lib/spec/mocks/mock_handler.rb +10 -9
  41. data/lib/spec/mocks/mock_methods.rb +1 -1
  42. data/lib/spec/rake/spectask.rb +8 -2
  43. data/lib/spec/runner/backtrace_tweaker.rb +34 -25
  44. data/lib/spec/runner/context.rb +56 -7
  45. data/lib/spec/runner/context_eval.rb +33 -3
  46. data/lib/spec/runner/context_runner.rb +24 -11
  47. data/lib/spec/runner/drb_command_line.rb +21 -0
  48. data/lib/spec/runner/execution_context.rb +1 -0
  49. data/lib/spec/runner/extensions/kernel.rb +2 -0
  50. data/lib/spec/runner/extensions/object.rb +26 -18
  51. data/lib/spec/runner/formatter/base_text_formatter.rb +1 -1
  52. data/lib/spec/runner/formatter/html_formatter.rb +94 -74
  53. data/lib/spec/runner/heckle_runner.rb +55 -0
  54. data/lib/spec/runner/option_parser.rb +15 -3
  55. data/lib/spec/runner/reporter.rb +13 -8
  56. data/lib/spec/runner/specification.rb +67 -42
  57. data/lib/spec/runner.rb +1 -1
  58. data/lib/spec/version.rb +6 -5
  59. data/lib/spec.rb +1 -0
  60. metadata +20 -19
  61. data/lib/spec/expectations/extensions/inspect_for_expectation_not_met_error.rb +0 -14
  62. data/lib/spec/expectations/extensions/symbol.rb +0 -5
  63. data/vendor/selenium/README.txt +0 -23
  64. data/vendor/selenium/find_rspecs_home_page.rb +0 -23
  65. data/vendor/selenium/rspec_selenium.rb +0 -33
  66. data/vendor/selenium/start_browser_once.patch +0 -65
  67. data/vendor/watir/README.txt +0 -32
  68. data/vendor/watir/find_rspecs_home_page.rb +0 -21
  69. data/vendor/watir/find_rspecs_home_page.txt +0 -15
  70. 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 sym
17
+ def __strip_should(sym) # :nodoc
18
18
  sym.to_s[7..-1]
19
19
  end
20
20
  end
@@ -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 target, name
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 sym, *args
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 raise_expectation_error sym, expected_received_count, actual_received_count, *args
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 sym
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 sym, detail
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 args_to_yield
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 args_to_yield, arity
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 message
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 *args
50
- return "" if [:any_args] == args
51
- return if args.empty?
52
- " with [" + arg_list(*args) + "]"
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 relativity, n
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? sym
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 message, expectation_ordering, expected_from, sym, method_block, 0
206
+ super(message, expectation_ordering, expected_from, sym, method_block, 0)
204
207
  end
205
208
 
206
- def negative_expectation_for? sym
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 message, expectation_ordering, expected_from, sym, method_block, 0
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.add_listener(self) if @options[:auto_verify]
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 str
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([], nil)
135
+ stub.invoke([], block)
139
136
  elsif expectation = find_almost_matching_expectation(sym, *args)
140
- raise_unexpected_message_error(sym, *args) unless has_negative_expectation?(sym) unless null_object?
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 raise_unexpected_message_error sym, *args
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
 
@@ -10,7 +10,7 @@ module Spec
10
10
  end
11
11
 
12
12
  def stub!(sym)
13
- __mock_handler.add_stub caller(1)[0], sym
13
+ __mock_handler.add_stub(caller(1)[0], sym)
14
14
  end
15
15
 
16
16
  def received_message?(sym, *args, &block)
@@ -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 NoisyBacktraceTweaker
4
- def tweak_instance_exec_line line, spec_name
5
- line = line.split(':in')[0] + ":in `#{spec_name}'" if line.include?('__instance_exec')
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.collect! do |line|
11
- tweak_instance_exec_line line, spec_name
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
- def tweak_instance_exec_line line, spec_name
20
- line = line.split(':in')[0] if line.include?('__instance_exec')
21
- line
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 = tweak_instance_exec_line line, spec_name
27
- line = nil if line =~ /\/lib\/ruby\//
28
- line = nil if line =~ /\/lib\/spec\/expectations\//
29
- line = nil if line =~ /\/lib\/spec\/mocks\//
30
- line = nil if line =~ /\/lib\/spec\/rake\//
31
- line = nil if line =~ /\/lib\/spec\/runner\//
32
- line = nil if line =~ /bin\/spec:/
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!
@@ -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
- specification.run(reporter, setup_block, teardown_block, dry_run, execution_context(specification))
46
- end
47
- end
48
-
49
- def execution_context specification
50
- execution_context_class.new(specification)
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
- protected
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
- private
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
- instance_exec(&part)
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(reporter, dry_run, single_spec=nil)
7
+ def initialize(options)
8
8
  @contexts = []
9
- @reporter = reporter
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 !@single_spec.nil? unless context.matches?(@single_spec)
16
- context.run_single_spec @single_spec if context.matches?(@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
- @contexts.each do |context|
23
- context.run(@reporter, @dry_run)
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.end
26
- failure_count = @reporter.dump
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
@@ -17,6 +17,7 @@ module Spec
17
17
  def violated(message="")
18
18
  raise Spec::Expectations::ExpectationNotMetError.new(message)
19
19
  end
20
+
20
21
  end
21
22
  include InstanceMethods
22
23
  end
@@ -1,3 +1,5 @@
1
+ require 'spec/runner/extensions/object'
2
+
1
3
  module Kernel
2
4
  def context(name, &block)
3
5
  context = Spec::Runner::Context.new(name, &block)