rspec 0.7.5.1 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (194) hide show
  1. data/CHANGES +60 -1
  2. data/EXAMPLES.rd +38 -19
  3. data/MIT-LICENSE +1 -1
  4. data/README +24 -17
  5. data/RELEASE-PLAN +117 -0
  6. data/Rakefile +24 -18
  7. data/TODO.0.8.0 +5 -0
  8. data/examples/auto_spec_name_generation_example.rb +18 -0
  9. data/examples/custom_expectation_matchers.rb +53 -0
  10. data/examples/dynamic_spec.rb +9 -0
  11. data/examples/io_processor_spec.rb +2 -2
  12. data/examples/mocking_example.rb +4 -4
  13. data/examples/partial_mock_example.rb +2 -2
  14. data/examples/predicate_example.rb +2 -2
  15. data/examples/stack_spec.rb +32 -36
  16. data/examples/stubbing_example.rb +19 -19
  17. data/examples/test_case_spec.rb +6 -6
  18. data/lib/spec.rb +3 -0
  19. data/lib/spec/callback.rb +8 -0
  20. data/lib/spec/callback/extensions/object.rb +4 -0
  21. data/lib/spec/deprecated.rb +3 -0
  22. data/lib/spec/expectations.rb +44 -17
  23. data/lib/spec/expectations/extensions.rb +1 -2
  24. data/lib/spec/expectations/extensions/object.rb +78 -130
  25. data/lib/spec/expectations/extensions/string_and_symbol.rb +17 -0
  26. data/lib/spec/expectations/handler.rb +47 -0
  27. data/lib/spec/expectations/should/base.rb +32 -29
  28. data/lib/spec/expectations/should/change.rb +1 -1
  29. data/lib/spec/expectations/should/have.rb +9 -17
  30. data/lib/spec/expectations/should/not.rb +54 -56
  31. data/lib/spec/expectations/should/should.rb +59 -65
  32. data/lib/spec/expectations/sugar.rb +27 -4
  33. data/lib/spec/matchers.rb +160 -0
  34. data/lib/spec/matchers/be.rb +161 -0
  35. data/lib/spec/matchers/be_close.rb +37 -0
  36. data/lib/spec/matchers/change.rb +120 -0
  37. data/lib/spec/matchers/eql.rb +43 -0
  38. data/lib/spec/matchers/equal.rb +43 -0
  39. data/lib/spec/matchers/has.rb +44 -0
  40. data/lib/spec/matchers/have.rb +140 -0
  41. data/lib/spec/matchers/include.rb +50 -0
  42. data/lib/spec/matchers/match.rb +41 -0
  43. data/lib/spec/matchers/raise_error.rb +100 -0
  44. data/lib/spec/matchers/respond_to.rb +35 -0
  45. data/lib/spec/matchers/satisfy.rb +47 -0
  46. data/lib/spec/matchers/throw_symbol.rb +75 -0
  47. data/lib/spec/mocks.rb +224 -1
  48. data/lib/spec/mocks/argument_expectation.rb +16 -2
  49. data/lib/spec/mocks/error_generator.rb +5 -3
  50. data/lib/spec/mocks/errors.rb +2 -2
  51. data/lib/spec/mocks/extensions/object.rb +1 -1
  52. data/lib/spec/mocks/message_expectation.rb +29 -19
  53. data/lib/spec/mocks/{mock_methods.rb → methods.rb} +5 -5
  54. data/lib/spec/mocks/mock.rb +2 -2
  55. data/lib/spec/mocks/mock_handler.rb +81 -68
  56. data/lib/spec/rake/spectask.rb +7 -12
  57. data/lib/spec/rake/verify_rcov.rb +1 -1
  58. data/lib/spec/runner.rb +117 -0
  59. data/lib/spec/runner/command_line.rb +8 -5
  60. data/lib/spec/runner/context.rb +13 -37
  61. data/lib/spec/runner/context_eval.rb +4 -3
  62. data/lib/spec/runner/context_runner.rb +7 -4
  63. data/lib/spec/runner/drb_command_line.rb +1 -1
  64. data/lib/spec/runner/execution_context.rb +3 -11
  65. data/lib/spec/runner/extensions/kernel.rb +7 -5
  66. data/lib/spec/runner/extensions/object.rb +4 -1
  67. data/lib/spec/runner/formatter/base_text_formatter.rb +11 -3
  68. data/lib/spec/runner/formatter/html_formatter.rb +21 -10
  69. data/lib/spec/runner/heckle_runner.rb +24 -8
  70. data/lib/spec/runner/heckle_runner_win.rb +10 -0
  71. data/lib/spec/runner/option_parser.rb +58 -13
  72. data/lib/spec/runner/spec_matcher.rb +22 -29
  73. data/lib/spec/runner/spec_parser.rb +1 -0
  74. data/lib/spec/runner/specification.rb +36 -22
  75. data/lib/spec/translator.rb +87 -0
  76. data/lib/spec/version.rb +16 -7
  77. data/spec/spec/callback/callback_container_spec.rb +27 -0
  78. data/spec/spec/callback/module_spec.rb +37 -0
  79. data/spec/spec/callback/object_spec.rb +90 -0
  80. data/spec/spec/callback/object_with_class_callback_spec.rb +19 -0
  81. data/spec/spec/expectations/differs/default_spec.rb +107 -0
  82. data/spec/spec/expectations/extensions/object_spec.rb +46 -0
  83. data/spec/spec/expectations/fail_with_spec.rb +71 -0
  84. data/spec/spec/expectations/should/should_==_spec.rb +19 -0
  85. data/spec/spec/expectations/should/should_=~_spec.rb +13 -0
  86. data/spec/spec/expectations/should/should_be_a_kind_of_spec.rb +21 -0
  87. data/spec/spec/expectations/should/should_be_an_instance_of_spec.rb +30 -0
  88. data/spec/spec/expectations/should/should_be_arbitrary_predicate_spec.rb +81 -0
  89. data/spec/spec/expectations/should/should_be_close_spec.rb +18 -0
  90. data/spec/spec/expectations/should/should_be_comparison_operator_spec.rb +44 -0
  91. data/spec/spec/expectations/should/should_be_false_spec.rb +39 -0
  92. data/spec/spec/expectations/should/should_be_spec.rb +11 -0
  93. data/spec/spec/expectations/should/should_be_true_spec.rb +27 -0
  94. data/spec/spec/expectations/should/should_change_spec.rb +184 -0
  95. data/spec/spec/expectations/should/should_eql_spec.rb +11 -0
  96. data/spec/spec/expectations/should/should_equal_spec.rb +11 -0
  97. data/spec/spec/expectations/should/should_have_at_least_spec.rb +53 -0
  98. data/spec/spec/expectations/should/should_have_at_most_spec.rb +45 -0
  99. data/spec/spec/expectations/should/should_have_key_spec.rb +21 -0
  100. data/spec/spec/expectations/should/should_have_spec.rb +64 -0
  101. data/spec/spec/expectations/should/should_include_spec.rb +59 -0
  102. data/spec/spec/expectations/should/should_match_spec.rb +25 -0
  103. data/spec/spec/expectations/should/should_not_==_spec.rb +15 -0
  104. data/spec/spec/expectations/should/should_not_be_a_kind_of_spec.rb +21 -0
  105. data/spec/spec/expectations/should/should_not_be_an_instance_of_spec.rb +11 -0
  106. data/spec/spec/expectations/should/should_not_be_arbitrary_predicate_spec.rb +68 -0
  107. data/spec/spec/expectations/should/should_not_be_spec.rb +11 -0
  108. data/spec/spec/expectations/should/should_not_change_spec.rb +24 -0
  109. data/spec/spec/expectations/should/should_not_eql_spec.rb +11 -0
  110. data/spec/spec/expectations/should/should_not_equal_spec.rb +11 -0
  111. data/spec/spec/expectations/should/should_not_have_key_spec.rb +15 -0
  112. data/spec/spec/expectations/should/should_not_include_spec.rb +58 -0
  113. data/spec/spec/expectations/should/should_not_match_spec.rb +11 -0
  114. data/spec/spec/expectations/should/should_not_raise_spec.rb +75 -0
  115. data/spec/spec/expectations/should/should_not_respond_to_spec.rb +15 -0
  116. data/spec/spec/expectations/should/should_not_throw_spec.rb +35 -0
  117. data/spec/spec/expectations/should/should_raise_spec.rb +66 -0
  118. data/spec/spec/expectations/should/should_respond_to_spec.rb +15 -0
  119. data/spec/spec/expectations/should/should_satisfy_spec.rb +35 -0
  120. data/spec/spec/expectations/should/should_throw_spec.rb +27 -0
  121. data/spec/spec/matchers/be_close_spec.rb +33 -0
  122. data/spec/spec/matchers/be_spec.rb +182 -0
  123. data/spec/spec/matchers/change_spec.rb +232 -0
  124. data/spec/spec/matchers/description_generation_spec.rb +147 -0
  125. data/spec/spec/matchers/eql_spec.rb +41 -0
  126. data/spec/spec/matchers/equal_spec.rb +41 -0
  127. data/spec/spec/matchers/handler_spec.rb +75 -0
  128. data/spec/spec/matchers/has_spec.rb +37 -0
  129. data/spec/spec/matchers/have_spec.rb +259 -0
  130. data/spec/spec/matchers/include_spec.rb +33 -0
  131. data/spec/spec/matchers/match_spec.rb +37 -0
  132. data/spec/spec/matchers/matcher_methods_spec.rb +85 -0
  133. data/spec/spec/matchers/raise_error_spec.rb +147 -0
  134. data/spec/spec/matchers/respond_to_spec.rb +30 -0
  135. data/spec/spec/matchers/satisfy_spec.rb +36 -0
  136. data/spec/spec/matchers/throw_symbol_spec.rb +59 -0
  137. data/spec/spec/mocks/any_number_of_times_spec.rb +34 -0
  138. data/spec/spec/mocks/at_least_spec.rb +97 -0
  139. data/spec/spec/mocks/at_most_spec.rb +97 -0
  140. data/spec/spec/mocks/bug_report_7611_spec.rb +19 -0
  141. data/spec/spec/mocks/bug_report_7805_spec.rb +22 -0
  142. data/spec/spec/mocks/bug_report_8165_spec.rb +31 -0
  143. data/spec/spec/mocks/bug_report_8302_spec.rb +26 -0
  144. data/spec/spec/mocks/failing_mock_argument_constraints_spec.rb +74 -0
  145. data/spec/spec/mocks/mock_ordering_spec.rb +80 -0
  146. data/spec/spec/mocks/mock_spec.rb +407 -0
  147. data/spec/spec/mocks/multiple_return_value_spec.rb +113 -0
  148. data/spec/spec/mocks/null_object_mock_spec.rb +40 -0
  149. data/spec/spec/mocks/once_counts_spec.rb +56 -0
  150. data/spec/spec/mocks/options_hash_spec.rb +31 -0
  151. data/spec/spec/mocks/partial_mock_spec.rb +52 -0
  152. data/spec/spec/mocks/partial_mock_using_mocks_directly_spec.rb +64 -0
  153. data/spec/spec/mocks/passing_mock_argument_constraints_spec.rb +92 -0
  154. data/spec/spec/mocks/precise_counts_spec.rb +56 -0
  155. data/spec/spec/mocks/record_messages_spec.rb +26 -0
  156. data/spec/spec/mocks/stub_spec.rb +159 -0
  157. data/spec/spec/mocks/twice_counts_spec.rb +67 -0
  158. data/spec/spec/runner/command_line_spec.rb +32 -0
  159. data/spec/spec/runner/context_matching_spec.rb +28 -0
  160. data/spec/spec/runner/context_runner_spec.rb +100 -0
  161. data/spec/spec/runner/context_spec.rb +405 -0
  162. data/spec/spec/runner/drb_command_line_spec.rb +74 -0
  163. data/spec/spec/runner/execution_context_spec.rb +52 -0
  164. data/spec/spec/runner/formatter/html_formatter_spec.rb +40 -0
  165. data/spec/spec/runner/formatter/progress_bar_formatter_dry_run_spec.rb +21 -0
  166. data/spec/spec/runner/formatter/progress_bar_formatter_failure_dump_spec.rb +36 -0
  167. data/spec/spec/runner/formatter/progress_bar_formatter_spec.rb +78 -0
  168. data/spec/spec/runner/formatter/rdoc_formatter_dry_run_spec.rb +18 -0
  169. data/spec/spec/runner/formatter/rdoc_formatter_spec.rb +41 -0
  170. data/spec/spec/runner/formatter/specdoc_formatter_dry_run_spec.rb +21 -0
  171. data/spec/spec/runner/formatter/specdoc_formatter_spec.rb +46 -0
  172. data/spec/spec/runner/heckle_runner_spec.rb +63 -0
  173. data/spec/spec/runner/heckler_spec.rb +14 -0
  174. data/spec/spec/runner/kernel_ext_spec.rb +16 -0
  175. data/spec/spec/runner/noisy_backtrace_tweaker_spec.rb +45 -0
  176. data/spec/spec/runner/object_ext_spec.rb +11 -0
  177. data/spec/spec/runner/option_parser_spec.rb +269 -0
  178. data/spec/spec/runner/quiet_backtrace_tweaker_spec.rb +47 -0
  179. data/spec/spec/runner/reporter_spec.rb +126 -0
  180. data/spec/spec/runner/spec_matcher_spec.rb +107 -0
  181. data/spec/spec/runner/spec_name_generation_spec.rb +102 -0
  182. data/spec/spec/runner/spec_parser_spec.rb +37 -0
  183. data/spec/spec/runner/specification_class_spec.rb +72 -0
  184. data/spec/spec/runner/specification_instance_spec.rb +160 -0
  185. data/spec/spec/runner/specification_should_raise_spec.rb +136 -0
  186. data/spec/spec/spec_classes.rb +102 -0
  187. data/spec/spec/translator_spec.rb +79 -0
  188. data/spec/spec_helper.rb +35 -0
  189. metadata +141 -9
  190. data/bin/drbspec +0 -3
  191. data/lib/spec/expectations/diff.rb +0 -28
  192. data/lib/spec/expectations/extensions/numeric.rb +0 -19
  193. data/lib/spec/expectations/extensions/string.rb +0 -22
  194. data/lib/spec/expectations/message_builder.rb +0 -13
@@ -1,10 +1,10 @@
1
1
  module Spec
2
2
  module Mocks
3
3
  class Mock
4
- include MockMethods
4
+ include Methods
5
5
 
6
6
  # Creates a new mock with a +name+ (that will be used in error messages only)
7
- # Options:
7
+ # == Options:
8
8
  # * <tt>:null_object</tt> - if true, the mock object acts as a forgiving null object allowing any message to be sent to it.
9
9
  def initialize(name, options={})
10
10
  @name = name
@@ -1,6 +1,11 @@
1
1
  module Spec
2
2
  module Mocks
3
3
  class MockHandler
4
+ DEFAULT_OPTIONS = {
5
+ :null_object => false,
6
+ :auto_verify => true
7
+ }
8
+
4
9
  def initialize(target, name, options={})
5
10
  @target = target
6
11
  @name = name
@@ -9,15 +14,10 @@ module Spec
9
14
  @expectations = []
10
15
  @messages_received = []
11
16
  @stubs = []
12
- @proxied_methods = {}
17
+ @proxied_methods = []
13
18
  @options = options ? DEFAULT_OPTIONS.dup.merge(options) : DEFAULT_OPTIONS
14
19
  end
15
20
 
16
- DEFAULT_OPTIONS = {
17
- :null_object => false,
18
- :auto_verify => true
19
- }
20
-
21
21
  def null_object?
22
22
  @options[:null_object]
23
23
  end
@@ -36,26 +36,8 @@ module Spec
36
36
 
37
37
  def add_stub(expected_from, sym)
38
38
  __add expected_from, sym, nil
39
- @stubs << MethodStub.new(@error_generator, @expectation_ordering, expected_from, sym, nil)
40
- @stubs.last
41
- end
42
-
43
- def __add expected_from, sym, block
44
- current_spec = Runner::Specification.current
45
- current_spec.after_teardown {verify} if current_spec && @options[:auto_verify]
46
- define_expected_method(sym)
47
- end
48
-
49
- def define_expected_method(sym)
50
- if @target.respond_to?(sym) && !@proxied_methods[sym]
51
- @proxied_methods[sym] = @target.method(sym)
52
- end
53
-
54
- metaclass_eval %-
55
- def #{sym}(*args, &block)
56
- __mock_handler.message_received :#{sym}, *args, &block
57
- end
58
- -
39
+ @stubs.unshift MethodStub.new(@error_generator, @expectation_ordering, expected_from, sym, nil)
40
+ @stubs.first
59
41
  end
60
42
 
61
43
  def verify #:nodoc:
@@ -73,43 +55,98 @@ module Spec
73
55
  clear_proxied_methods
74
56
  end
75
57
 
76
- def verify_expectations
77
- @expectations.each do |expectation|
78
- expectation.verify_messages_received
79
- end
58
+ def received_message?(sym, *args, &block)
59
+ return true if @messages_received.find {|array| array == [sym, args, block]}
60
+ return false
80
61
  end
81
62
 
82
- def reset_proxied_methods
83
- @proxied_methods.each do |method_name, method_obj|
84
- define_instance_method(method_name, method_obj)
63
+ def has_negative_expectation?(sym)
64
+ @expectations.detect {|expectation| expectation.negative_expectation_for?(sym)}
65
+ end
66
+
67
+ def message_received(sym, *args, &block)
68
+ if expectation = find_matching_expectation(sym, *args)
69
+ expectation.invoke(args, block)
70
+ elsif stub = find_matching_method_stub(sym)
71
+ stub.invoke([], block)
72
+ elsif expectation = find_almost_matching_expectation(sym, *args)
73
+ raise_unexpected_message_args_error(expectation, *args) unless has_negative_expectation?(sym) unless null_object?
74
+ else
75
+ @target.send :method_missing, sym, *args, &block
85
76
  end
86
77
  end
87
78
 
88
- def define_instance_method(method_name, method_obj)
89
- (class << @target; self; end).class_eval do
90
- define_method method_name, &method_obj
79
+ def raise_unexpected_message_args_error(expectation, *args)
80
+ @error_generator.raise_unexpected_message_args_error expectation, *args
81
+ end
82
+
83
+ def raise_unexpected_message_error(sym, *args)
84
+ @error_generator.raise_unexpected_message_error sym, *args
85
+ end
86
+
87
+ private
88
+
89
+ def __add(expected_from, sym, block)
90
+ # TODO - this is the only reference in the 'spec/mocks' to the Runner
91
+ current_spec = Runner::Specification.current
92
+ current_spec.after_teardown {verify} if current_spec && @options[:auto_verify]
93
+ define_expected_method(sym)
94
+ end
95
+
96
+ def define_expected_method(sym)
97
+ if target_responds_to?(sym) && !@proxied_methods.include?(sym)
98
+ @proxied_methods << sym
99
+ metaclass.__send__(:alias_method, munge(sym), sym)
91
100
  end
101
+
102
+ metaclass_eval(<<-EOF, __FILE__, __LINE__)
103
+ def #{sym}(*args, &block)
104
+ __mock_handler.message_received :#{sym}, *args, &block
105
+ end
106
+ EOF
92
107
  end
93
108
 
94
- def clear_expectations #:nodoc:
109
+ def target_responds_to?(sym)
110
+ return @target.send(munge(:respond_to?),sym) if @already_proxied_respond_to
111
+ return @already_proxied_respond_to = true if sym == :respond_to?
112
+ return @target.respond_to?(sym)
113
+ end
114
+
115
+ def munge(sym)
116
+ "proxied_by_rspec__#{sym.to_s}".to_sym
117
+ end
118
+
119
+ def clear_expectations
95
120
  @expectations.clear
96
121
  end
97
122
 
98
- def clear_stubs #:nodoc:
123
+ def clear_stubs
99
124
  @stubs.clear
100
125
  end
101
126
 
102
- def clear_proxied_methods #:nodoc:
127
+ def clear_proxied_methods
103
128
  @proxied_methods.clear
104
129
  end
105
130
 
106
- def metaclass_eval(str)
107
- (class << @target; self; end).class_eval str
131
+ def metaclass_eval(str, filename, lineno)
132
+ metaclass.class_eval(str, filename, lineno)
133
+ end
134
+
135
+ def metaclass
136
+ (class << @target; self; end)
108
137
  end
109
138
 
110
- def received_message?(sym, *args, &block)
111
- return true if @messages_received.find {|array| array == [sym, args, block]}
112
- return false
139
+ def verify_expectations
140
+ @expectations.each do |expectation|
141
+ expectation.verify_messages_received
142
+ end
143
+ end
144
+
145
+ def reset_proxied_methods
146
+ @proxied_methods.each do |sym|
147
+ metaclass.__send__(:alias_method, sym, munge(sym))
148
+ metaclass.__send__(:undef_method, munge(sym))
149
+ end
113
150
  end
114
151
 
115
152
  def find_matching_expectation(sym, *args)
@@ -124,30 +161,6 @@ module Spec
124
161
  @stubs.find {|stub| stub.matches(sym, [])}
125
162
  end
126
163
 
127
- def has_negative_expectation?(sym)
128
- @expectations.detect {|expectation| expectation.negative_expectation_for?(sym)}
129
- end
130
-
131
- def message_received(sym, *args, &block)
132
- if expectation = find_matching_expectation(sym, *args)
133
- expectation.invoke(args, block)
134
- elsif stub = find_matching_method_stub(sym)
135
- stub.invoke([], block)
136
- elsif expectation = find_almost_matching_expectation(sym, *args)
137
- raise_unexpected_message_args_error(expectation, *args) unless has_negative_expectation?(sym) unless null_object?
138
- else
139
- @target.send :method_missing, sym, *args, &block
140
- end
141
- end
142
-
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)
148
- @error_generator.raise_unexpected_message_error sym, *args
149
- end
150
-
151
164
  end
152
165
  end
153
166
  end
@@ -34,7 +34,7 @@ module Spec
34
34
  # E.g. warning=true implies "ruby -w" used to run the specs. Defaults to false.
35
35
  attr_accessor :warning
36
36
 
37
- # Glob pattern to match spec files. (default is 'spec/spec*.rb')
37
+ # Glob pattern to match spec files. (default is 'spec/**/*_spec.rb')
38
38
  attr_accessor :pattern
39
39
 
40
40
  # Array of commandline options to pass to RSpec. Defaults to [].
@@ -64,11 +64,6 @@ module Spec
64
64
 
65
65
  # A message to print to stdout when there are failures.
66
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
72
67
 
73
68
  # Explicitly define the list of spec files to be included in a
74
69
  # spec. +list+ is expected to be an array of file names (a
@@ -90,7 +85,7 @@ module Spec
90
85
  @out = nil
91
86
  @fail_on_error = true
92
87
  @rcov = false
93
- @rcov_opts = ['--exclude', 'lib\/spec,bin\/spec']
88
+ @rcov_opts = ['--exclude', 'lib\/spec,bin\/spec,config\/boot.rb']
94
89
  @rcov_dir = "coverage"
95
90
 
96
91
  yield self if block_given?
@@ -99,7 +94,7 @@ module Spec
99
94
  end
100
95
 
101
96
  def define
102
- spec_script = File.expand_path(File.dirname(__FILE__) + '/../../../bin/' + (drb ? 'drbspec' : 'spec'))
97
+ spec_script = File.expand_path(File.dirname(__FILE__) + '/../../../bin/spec')
103
98
 
104
99
  lib_path = @libs.join(File::PATH_SEPARATOR)
105
100
  actual_name = Hash === name ? name.keys.first : name
@@ -113,9 +108,9 @@ module Spec
113
108
  ruby_opts.push( "-S rcov" ) if @rcov
114
109
  ruby_opts.push( "-w" ) if @warning
115
110
 
116
- redirect = @out.nil? ? "" : " > #{@out}"
111
+ redirect = @out.nil? ? "" : " > \"#{@out}\""
117
112
 
118
- unless file_list.empty?
113
+ unless spec_file_list.empty?
119
114
  # ruby [ruby_opts] -Ilib -S rcov [rcov_opts] bin/spec -- [spec_opts] examples
120
115
  # or
121
116
  # ruby [ruby_opts] -Ilib bin/spec [spec_opts] examples
@@ -126,7 +121,7 @@ module Spec
126
121
  (@rcov ? %[ -o "#{@rcov_dir}" ] : "") +
127
122
  '"' + spec_script + '"' + " " +
128
123
  (@rcov ? "-- " : "") +
129
- file_list.collect { |fn| %["#{fn}"] }.join(' ') + " " +
124
+ spec_file_list.collect { |fn| %["#{fn}"] }.join(' ') + " " +
130
125
  spec_option_list + " " +
131
126
  redirect
132
127
  )
@@ -161,7 +156,7 @@ module Spec
161
156
  ENV['RSPECOPTS'] || @spec_opts.join(" ") || ""
162
157
  end
163
158
 
164
- def file_list # :nodoc:
159
+ def spec_file_list # :nodoc:
165
160
  if ENV['SPEC']
166
161
  FileList[ ENV['SPEC'] ]
167
162
  else
@@ -33,7 +33,7 @@ module RCov
33
33
  task @name do
34
34
  total_coverage = nil
35
35
  File.open(index_html).each_line do |line|
36
- if line =~ /<tt>(\d+\.\d+)%<\/tt>&nbsp;<\/td>/
36
+ if line =~ /<tt.*>(\d+\.\d+)%<\/tt>&nbsp;<\/td>/
37
37
  total_coverage = eval($1)
38
38
  break
39
39
  end
@@ -10,6 +10,123 @@ require 'spec/runner/drb_command_line'
10
10
  require 'spec/runner/backtrace_tweaker'
11
11
  require 'spec/runner/reporter'
12
12
  require 'spec/runner/spec_matcher'
13
+ require 'spec/runner/extensions/object'
13
14
  require 'spec/runner/extensions/kernel'
14
15
  require 'spec/runner/spec_should_raise_handler'
15
16
  require 'spec/runner/spec_parser'
17
+
18
+ module Spec
19
+ # == Contexts and Specifications
20
+ #
21
+ # Rather than expressing examples in classes, RSpec uses a custom domain specific language to express
22
+ # examples using contexts and specifications.
23
+ #
24
+ # A context is the equivalent of a fixture in xUnit-speak. It is a metaphor for the context
25
+ # in which you will run your executable example - a set of known objects in a known starting state.
26
+ #
27
+ # context "A new account" do
28
+ #
29
+ # setup do
30
+ # @account = Account.new
31
+ # end
32
+ #
33
+ # specify "should have a balance of $0" do
34
+ # @account.balance.should_eql Money.new(0, :dollars)
35
+ # end
36
+ #
37
+ # end
38
+ #
39
+ # We use the setup block to set up the context (given), and then the specify method to
40
+ # hold the example code that expresses the event (when) and the expected outcome (then).
41
+ #
42
+ # == Helper Methods
43
+ #
44
+ # A primary goal of RSpec is to keep the examples clear. We therefore prefer
45
+ # less indirection than you might see in xUnit examples and in well factored, DRY production code. We feel
46
+ # that duplication is OK if removing it makes it harder to understand an example without
47
+ # having to look elsewhere to understand its context.
48
+ #
49
+ # That said, RSpec does support some level of encapsulating common code in helper
50
+ # methods that can exist within a context or within an included module.
51
+ #
52
+ # == Setup and Teardown
53
+ #
54
+ # You can use setup, teardown, context_setup and context_teardown within a context:
55
+ #
56
+ # context "..." do
57
+ # context_setup do
58
+ # ...
59
+ # end
60
+ #
61
+ # setup do
62
+ # ...
63
+ # end
64
+ #
65
+ # specify "number one" do
66
+ # ...
67
+ # end
68
+ #
69
+ # specify "number two" do
70
+ # ...
71
+ # end
72
+ #
73
+ # teardown do
74
+ # ...
75
+ # end
76
+ #
77
+ # context_teardown do
78
+ # ...
79
+ # end
80
+ #
81
+ # end
82
+ #
83
+ # The <tt>setup</tt> block will run before each of the specs, once for each spec. Likewise,
84
+ # the <tt>teardown</tt> block will run after each of the specs.
85
+ #
86
+ # It is also possible to specify a <tt>context_setup</tt> and <tt>context_teardown</tt>
87
+ # block that will run only once for each context, respectively before the first <code>setup</code>
88
+ # and after the last <code>teardown</code>. The use of these is generally discouraged, because it
89
+ # introduces dependencies between the specs. Still, it might prove useful for very expensive operations
90
+ # if you know what you are doing.
91
+ #
92
+ # == Local helper methods
93
+ #
94
+ # You can include local helper methods by simply expressing them within a context:
95
+ #
96
+ # context "..." do
97
+ #
98
+ # specify "..." do
99
+ # helper_method
100
+ # end
101
+ #
102
+ # def helper_method
103
+ # ...
104
+ # end
105
+ #
106
+ # end
107
+ #
108
+ # == Included helper methods
109
+ #
110
+ # You can include helper methods in multiple contexts by expressing them within
111
+ # a module, and then including that module in your context:
112
+ #
113
+ # module AccountExampleHelperMethods
114
+ # def helper_method
115
+ # ...
116
+ # end
117
+ # end
118
+ #
119
+ # context "A new account" do
120
+ # include AccountExampleHelperMethods
121
+ # setup do
122
+ # @account = Account.new
123
+ # end
124
+ #
125
+ # specify "should have a balance of $0" do
126
+ # helper_method
127
+ # @account.balance.should eql(Money.new(0, :dollars))
128
+ # end
129
+ # end
130
+ module Runner
131
+ end
132
+ end
@@ -1,15 +1,18 @@
1
+ require 'spec/runner/option_parser'
2
+
1
3
  module Spec
2
4
  module Runner
3
5
  # Facade to run specs without having to fork a new ruby process (using `spec ...`)
4
6
  class CommandLine
5
- # Runs specs. +argv+ is the commandline args as per the spec commandline API, +stderr+
6
- # and +stdiout+ are the streams output will be written to, +exit+ tells whether or
7
+ # Runs specs. +argv+ is the commandline args as per the spec commandline API, +err+
8
+ # and +out+ are the streams output will be written to. +exit+ tells whether or
7
9
  # not a system exit should be called after the specs are run and
8
10
  # +warn_if_no_files+ tells whether or not a warning (the help message)
9
- # should be printed to +stderr+ in case no files are specified.
10
- def self.run(argv, stderr, stdout, exit=false, warn_if_no_files=true)
11
+ # should be printed to +err+ in case no files are specified.
12
+ def self.run(argv, err, out, exit=true, warn_if_no_files=true)
11
13
  old_context_runner = defined?($context_runner) ? $context_runner : nil
12
- $context_runner = OptionParser.new.create_context_runner(argv, stderr, stdout, warn_if_no_files)
14
+ $context_runner = OptionParser.new.create_context_runner(argv, err, out, warn_if_no_files)
15
+ return if $context_runner.nil? # This is the case if we use --drb
13
16
 
14
17
  # If ARGV is a glob, it will actually each over each one of the matching files.
15
18
  argv.each do |file_or_dir|
@@ -4,8 +4,8 @@ module Spec
4
4
  end
5
5
  class Context
6
6
  module InstanceMethods
7
- def initialize(name, &context_block)
8
- @name = name
7
+ def initialize(description, &context_block)
8
+ @description = description
9
9
 
10
10
  @context_eval_module = ContextEvalModule.new
11
11
  @context_eval_module.extend ContextEval::ModuleMethods
@@ -17,43 +17,19 @@ module Spec
17
17
  def before_context_eval
18
18
  end
19
19
 
20
- def inherit(klass)
20
+ #this is here for Spec::Rails
21
+ def inherit_context_eval_module_from(klass)
21
22
  @context_eval_module.inherit klass
22
23
  end
23
- alias :inherit_context_eval_module_from :inherit
24
-
25
- def include(mod)
26
- @context_eval_module.include mod
27
- end
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
-
37
- def setup(&block)
38
- @context_eval_module.setup(&block)
39
- end
40
-
41
- def teardown(&block)
42
- @context_eval_module.teardown(&block)
43
- end
44
-
45
- def specify(spec_name, opts={}, &block)
46
- @context_eval_module.specify(spec_name, opts, &block)
47
- end
48
24
 
49
25
  def run(reporter, dry_run=false)
50
- reporter.add_context(@name)
26
+ reporter.add_context(@description)
51
27
  prepare_execution_context_class
52
28
  errors = run_context_setup(reporter, dry_run)
53
29
 
54
30
  specifications.each do |specification|
55
31
  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?
32
+ specification_execution_context.copy_instance_variables_from(@once_only_execution_context_instance, []) unless context_setup_block.nil?
57
33
  specification.run(reporter, setup_block, teardown_block, dry_run, specification_execution_context)
58
34
  end unless errors.length > 0
59
35
 
@@ -64,19 +40,19 @@ module Spec
64
40
  specifications.length
65
41
  end
66
42
 
67
- def matches? name, matcher=nil
68
- matcher ||= SpecMatcher.new name, @name
43
+ def matches?(full_description)
44
+ matcher ||= SpecMatcher.new(@description)
69
45
  specifications.each do |spec|
70
- return true if spec.matches_matcher? matcher
46
+ return true if spec.matches?(matcher, full_description)
71
47
  end
72
48
  return false
73
49
  end
74
50
 
75
- def run_single_spec name
76
- return if @name == name
77
- matcher = SpecMatcher.new name, @name
51
+ def run_single_spec(full_description)
52
+ return if @description == full_description
53
+ matcher = SpecMatcher.new(@description)
78
54
  specifications.reject! do |spec|
79
- !spec.matches_matcher? matcher
55
+ !spec.matches?(matcher, full_description)
80
56
  end
81
57
  end
82
58