rspec 1.0.8 → 1.1.0

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 (301) hide show
  1. data/CHANGES +122 -2
  2. data/README +10 -9
  3. data/Rakefile +22 -49
  4. data/TODO +2 -0
  5. data/bin/spec +1 -1
  6. data/bin/spec_translator +8 -8
  7. data/examples/{auto_spec_description_example.rb → pure/autogenerated_docstrings_example.rb} +0 -0
  8. data/examples/{before_and_after_example.rb → pure/before_and_after_example.rb} +1 -0
  9. data/examples/{behave_as_example.rb → pure/behave_as_example.rb} +0 -0
  10. data/examples/{custom_expectation_matchers.rb → pure/custom_expectation_matchers.rb} +0 -0
  11. data/examples/{custom_formatter.rb → pure/custom_formatter.rb} +1 -0
  12. data/examples/{dynamic_spec.rb → pure/dynamic_spec.rb} +0 -0
  13. data/examples/{file_accessor.rb → pure/file_accessor.rb} +1 -0
  14. data/examples/{file_accessor_spec.rb → pure/file_accessor_spec.rb} +0 -0
  15. data/examples/{greeter_spec.rb → pure/greeter_spec.rb} +1 -0
  16. data/examples/{helper_method_example.rb → pure/helper_method_example.rb} +0 -0
  17. data/examples/{io_processor.rb → pure/io_processor.rb} +0 -0
  18. data/examples/{io_processor_spec.rb → pure/io_processor_spec.rb} +0 -0
  19. data/examples/{legacy_spec.rb → pure/legacy_spec.rb} +1 -0
  20. data/examples/{mocking_example.rb → pure/mocking_example.rb} +0 -0
  21. data/examples/pure/multi_threaded_behaviour_runner.rb +28 -0
  22. data/examples/pure/nested_classes_example.rb +36 -0
  23. data/examples/{partial_mock_example.rb → pure/partial_mock_example.rb} +0 -0
  24. data/examples/{pending_example.rb → pure/pending_example.rb} +0 -0
  25. data/examples/{predicate_example.rb → pure/predicate_example.rb} +0 -0
  26. data/examples/{priority.txt → pure/priority.txt} +0 -0
  27. data/examples/pure/shared_example_group_example.rb +66 -0
  28. data/examples/pure/shared_stack_examples.rb +38 -0
  29. data/examples/pure/spec_helper.rb +3 -0
  30. data/examples/{stack.rb → pure/stack.rb} +0 -0
  31. data/examples/{stack_spec.rb → pure/stack_spec.rb} +1 -35
  32. data/examples/pure/stack_spec_with_nested_example_groups.rb +67 -0
  33. data/examples/{stubbing_example.rb → pure/stubbing_example.rb} +0 -0
  34. data/examples/stories/adder.rb +13 -0
  35. data/examples/stories/addition +34 -0
  36. data/examples/stories/addition.rb +9 -0
  37. data/examples/stories/calculator.rb +65 -0
  38. data/examples/stories/game-of-life/README.txt +21 -0
  39. data/examples/stories/game-of-life/behaviour/everything.rb +6 -0
  40. data/examples/stories/game-of-life/behaviour/examples/examples.rb +3 -0
  41. data/examples/stories/game-of-life/behaviour/examples/game_behaviour.rb +35 -0
  42. data/examples/stories/game-of-life/behaviour/examples/grid_behaviour.rb +66 -0
  43. data/examples/stories/game-of-life/behaviour/stories/CellsWithLessThanTwoNeighboursDie.story +21 -0
  44. data/examples/stories/game-of-life/behaviour/stories/CellsWithMoreThanThreeNeighboursDie.story +21 -0
  45. data/examples/stories/game-of-life/behaviour/stories/EmptySpacesWithThreeNeighboursCreateACell.story +42 -0
  46. data/examples/stories/game-of-life/behaviour/stories/ICanCreateACell.story +42 -0
  47. data/examples/stories/game-of-life/behaviour/stories/ICanKillACell.story +17 -0
  48. data/examples/stories/game-of-life/behaviour/stories/TheGridWraps.story +53 -0
  49. data/examples/stories/game-of-life/behaviour/stories/create_a_cell.rb +52 -0
  50. data/examples/stories/game-of-life/behaviour/stories/helper.rb +6 -0
  51. data/examples/stories/game-of-life/behaviour/stories/kill_a_cell.rb +26 -0
  52. data/examples/stories/game-of-life/behaviour/stories/steps.rb +5 -0
  53. data/examples/stories/game-of-life/behaviour/stories/stories.rb +3 -0
  54. data/examples/stories/game-of-life/behaviour/stories/stories.txt +22 -0
  55. data/examples/stories/game-of-life/life.rb +3 -0
  56. data/examples/stories/game-of-life/life/game.rb +23 -0
  57. data/examples/stories/game-of-life/life/grid.rb +43 -0
  58. data/examples/stories/helper.rb +9 -0
  59. data/examples/stories/steps/addition_steps.rb +18 -0
  60. data/lib/autotest/rspec.rb +1 -2
  61. data/lib/spec.rb +30 -6
  62. data/lib/spec/example.rb +12 -0
  63. data/lib/spec/{dsl → example}/configuration.rb +48 -39
  64. data/lib/spec/{dsl → example}/errors.rb +2 -2
  65. data/lib/spec/example/example_group.rb +16 -0
  66. data/lib/spec/example/example_group_factory.rb +62 -0
  67. data/lib/spec/example/example_group_methods.rb +412 -0
  68. data/lib/spec/example/example_matcher.rb +42 -0
  69. data/lib/spec/example/example_methods.rb +101 -0
  70. data/lib/spec/example/module_reopening_fix.rb +21 -0
  71. data/lib/spec/example/pending.rb +18 -0
  72. data/lib/spec/example/shared_example_group.rb +58 -0
  73. data/lib/spec/expectations/differs/default.rb +15 -10
  74. data/lib/spec/expectations/errors.rb +7 -1
  75. data/lib/spec/expectations/extensions/object.rb +12 -7
  76. data/lib/spec/expectations/handler.rb +13 -4
  77. data/lib/spec/extensions.rb +2 -0
  78. data/lib/spec/extensions/class.rb +24 -0
  79. data/lib/spec/extensions/main.rb +54 -0
  80. data/lib/spec/extensions/object.rb +5 -1
  81. data/lib/spec/interop/test.rb +10 -0
  82. data/lib/spec/interop/test/unit/autorunner.rb +6 -0
  83. data/lib/spec/interop/test/unit/testcase.rb +61 -0
  84. data/lib/spec/interop/test/unit/testresult.rb +6 -0
  85. data/lib/spec/interop/test/unit/testsuite_adapter.rb +34 -0
  86. data/lib/spec/interop/test/unit/ui/console/testrunner.rb +60 -0
  87. data/lib/spec/matchers.rb +11 -15
  88. data/lib/spec/matchers/be.rb +23 -6
  89. data/lib/spec/matchers/change.rb +25 -1
  90. data/lib/spec/matchers/exist.rb +17 -0
  91. data/lib/spec/matchers/operator_matcher.rb +1 -0
  92. data/lib/spec/matchers/simple_matcher.rb +29 -0
  93. data/lib/spec/matchers/throw_symbol.rb +2 -0
  94. data/lib/spec/mocks.rb +5 -2
  95. data/lib/spec/mocks/argument_expectation.rb +1 -1
  96. data/lib/spec/mocks/message_expectation.rb +62 -44
  97. data/lib/spec/mocks/methods.rb +2 -2
  98. data/lib/spec/mocks/mock.rb +24 -3
  99. data/lib/spec/mocks/proxy.rb +26 -23
  100. data/lib/spec/mocks/space.rb +1 -1
  101. data/lib/spec/mocks/spec_methods.rb +20 -12
  102. data/lib/spec/rake/spectask.rb +19 -1
  103. data/lib/spec/rake/verify_rcov.rb +1 -1
  104. data/lib/spec/runner.rb +33 -10
  105. data/lib/spec/runner/backtrace_tweaker.rb +3 -3
  106. data/lib/spec/runner/class_and_arguments_parser.rb +16 -0
  107. data/lib/spec/runner/command_line.rb +18 -12
  108. data/lib/spec/runner/drb_command_line.rb +4 -5
  109. data/lib/spec/runner/example_group_runner.rb +59 -0
  110. data/lib/spec/runner/formatter/base_formatter.rb +10 -8
  111. data/lib/spec/runner/formatter/base_text_formatter.rb +18 -18
  112. data/lib/spec/runner/formatter/failing_example_groups_formatter.rb +31 -0
  113. data/lib/spec/runner/formatter/failing_examples_formatter.rb +3 -5
  114. data/lib/spec/runner/formatter/html_formatter.rb +37 -27
  115. data/lib/spec/runner/formatter/profile_formatter.rb +47 -0
  116. data/lib/spec/runner/formatter/progress_bar_formatter.rb +3 -4
  117. data/lib/spec/runner/formatter/specdoc_formatter.rb +27 -13
  118. data/lib/spec/runner/formatter/story/html_formatter.rb +124 -0
  119. data/lib/spec/runner/formatter/story/plain_text_formatter.rb +123 -0
  120. data/lib/spec/runner/formatter/text_mate_formatter.rb +16 -0
  121. data/lib/spec/runner/heckle_runner.rb +9 -9
  122. data/lib/spec/runner/option_parser.rb +140 -138
  123. data/lib/spec/runner/options.rb +168 -90
  124. data/lib/spec/runner/reporter.rb +58 -40
  125. data/lib/spec/runner/spec_parser.rb +11 -8
  126. data/lib/spec/story.rb +10 -0
  127. data/lib/spec/story/extensions.rb +1 -0
  128. data/lib/spec/story/extensions/main.rb +86 -0
  129. data/lib/spec/story/given_scenario.rb +14 -0
  130. data/lib/spec/story/runner.rb +58 -0
  131. data/lib/spec/story/runner/plain_text_story_runner.rb +48 -0
  132. data/lib/spec/story/runner/scenario_collector.rb +18 -0
  133. data/lib/spec/story/runner/scenario_runner.rb +46 -0
  134. data/lib/spec/story/runner/story_mediator.rb +123 -0
  135. data/lib/spec/story/runner/story_parser.rb +227 -0
  136. data/lib/spec/story/runner/story_runner.rb +67 -0
  137. data/lib/spec/story/scenario.rb +14 -0
  138. data/lib/spec/story/step.rb +48 -0
  139. data/lib/spec/story/step_group.rb +89 -0
  140. data/lib/spec/story/step_mother.rb +37 -0
  141. data/lib/spec/story/story.rb +42 -0
  142. data/lib/spec/story/world.rb +124 -0
  143. data/lib/spec/version.rb +4 -5
  144. data/plugins/mock_frameworks/rspec.rb +1 -1
  145. data/spec/autotest/rspec_spec.rb +13 -7
  146. data/spec/autotest_helper.rb +4 -3
  147. data/spec/rspec_suite.rb +7 -0
  148. data/spec/ruby_forker.rb +13 -0
  149. data/spec/spec/example/configuration_spec.rb +290 -0
  150. data/spec/spec/example/example_group_class_definition_spec.rb +48 -0
  151. data/spec/spec/example/example_group_factory_spec.rb +129 -0
  152. data/spec/spec/example/example_group_methods_spec.rb +465 -0
  153. data/spec/spec/example/example_group_spec.rb +711 -0
  154. data/spec/spec/{dsl → example}/example_matcher_spec.rb +23 -18
  155. data/spec/spec/example/example_methods_spec.rb +75 -0
  156. data/spec/spec/example/example_runner_spec.rb +194 -0
  157. data/spec/spec/example/example_spec.rb +53 -0
  158. data/spec/spec/example/nested_example_group_spec.rb +59 -0
  159. data/spec/spec/example/pending_module_spec.rb +31 -0
  160. data/spec/spec/{dsl → example}/predicate_matcher_spec.rb +1 -1
  161. data/spec/spec/example/shared_example_group_spec.rb +265 -0
  162. data/spec/spec/example/subclassing_example_group_spec.rb +25 -0
  163. data/spec/spec/expectations/differs/default_spec.rb +5 -3
  164. data/spec/spec/expectations/extensions/object_spec.rb +63 -2
  165. data/spec/spec/extensions/main_spec.rb +50 -0
  166. data/spec/spec/interop/test/unit/test_unit_spec_helper.rb +14 -0
  167. data/spec/spec/interop/test/unit/testcase_spec.rb +10 -0
  168. data/spec/spec/interop/test/unit/testcase_spec_with_test_unit.rb +20 -0
  169. data/spec/spec/interop/test/unit/testsuite_adapter_spec.rb +9 -0
  170. data/spec/spec/interop/test/unit/testsuite_adapter_spec_with_test_unit.rb +34 -0
  171. data/spec/spec/matchers/be_spec.rb +15 -0
  172. data/spec/spec/matchers/change_spec.rb +87 -0
  173. data/spec/spec/matchers/description_generation_spec.rb +31 -37
  174. data/spec/spec/matchers/exist_spec.rb +31 -22
  175. data/spec/spec/matchers/handler_spec.rb +42 -1
  176. data/spec/spec/matchers/have_spec.rb +1 -1
  177. data/spec/spec/matchers/mock_constraint_matchers_spec.rb +1 -1
  178. data/spec/spec/matchers/operator_matcher_spec.rb +1 -1
  179. data/spec/spec/matchers/simple_matcher_spec.rb +31 -0
  180. data/spec/spec/matchers/throw_symbol_spec.rb +4 -1
  181. data/spec/spec/mocks/bug_report_10263.rb +24 -0
  182. data/spec/spec/mocks/bug_report_15719_spec.rb +30 -0
  183. data/spec/spec/mocks/bug_report_8165_spec.rb +2 -2
  184. data/spec/spec/mocks/failing_mock_argument_constraints_spec.rb +1 -0
  185. data/spec/spec/mocks/mock_spec.rb +200 -102
  186. data/spec/spec/mocks/multiple_return_value_spec.rb +1 -1
  187. data/spec/spec/mocks/options_hash_spec.rb +19 -7
  188. data/spec/spec/mocks/partial_mock_spec.rb +31 -9
  189. data/spec/spec/mocks/passing_mock_argument_constraints_spec.rb +6 -0
  190. data/spec/spec/mocks/stub_spec.rb +120 -98
  191. data/spec/spec/package/bin_spec_spec.rb +7 -5
  192. data/spec/spec/runner/class_and_argument_parser_spec.rb +23 -0
  193. data/spec/spec/runner/command_line_spec.rb +140 -27
  194. data/spec/spec/runner/drb_command_line_spec.rb +39 -31
  195. data/spec/spec/runner/formatter/failing_example_groups_formatter_spec.rb +44 -0
  196. data/spec/spec/runner/formatter/failing_examples_formatter_spec.rb +16 -11
  197. data/spec/spec/runner/formatter/html_formatter_spec.rb +60 -50
  198. data/spec/spec/runner/formatter/profile_formatter_spec.rb +65 -0
  199. data/spec/spec/runner/formatter/progress_bar_formatter_spec.rb +29 -13
  200. data/spec/spec/runner/formatter/snippet_extractor_spec.rb +14 -7
  201. data/spec/spec/runner/formatter/spec_mate_formatter_spec.rb +103 -0
  202. data/spec/spec/runner/formatter/specdoc_formatter_spec.rb +103 -39
  203. data/spec/spec/runner/formatter/story/html_formatter_spec.rb +56 -0
  204. data/spec/spec/runner/formatter/story/plain_text_formatter_spec.rb +289 -0
  205. data/spec/spec/runner/heckle_runner_spec.rb +29 -14
  206. data/spec/spec/runner/heckler_spec.rb +4 -5
  207. data/spec/spec/runner/noisy_backtrace_tweaker_spec.rb +5 -5
  208. data/spec/spec/runner/option_parser_spec.rb +86 -58
  209. data/spec/spec/runner/options_spec.rb +239 -120
  210. data/spec/spec/runner/output_one_time_fixture.rb +7 -0
  211. data/spec/spec/runner/output_one_time_fixture_runner.rb +8 -0
  212. data/spec/spec/runner/output_one_time_spec.rb +16 -0
  213. data/spec/spec/runner/quiet_backtrace_tweaker_spec.rb +6 -6
  214. data/spec/spec/runner/reporter_spec.rb +147 -163
  215. data/spec/spec/runner/spec_parser_spec.rb +31 -0
  216. data/spec/spec/runner_spec.rb +11 -0
  217. data/spec/spec/spec_classes.rb +12 -5
  218. data/spec/spec/story/builders.rb +46 -0
  219. data/spec/spec/story/extensions/main_spec.rb +161 -0
  220. data/spec/spec/story/extensions_spec.rb +14 -0
  221. data/spec/spec/story/given_scenario_spec.rb +27 -0
  222. data/spec/spec/story/runner/plain_text_story_runner_spec.rb +92 -0
  223. data/spec/spec/story/runner/scenario_collector_spec.rb +27 -0
  224. data/spec/spec/story/runner/scenario_runner_spec.rb +142 -0
  225. data/spec/spec/story/runner/story_mediator_spec.rb +133 -0
  226. data/spec/spec/story/runner/story_parser_spec.rb +384 -0
  227. data/spec/spec/story/runner/story_runner_spec.rb +219 -0
  228. data/spec/spec/story/runner_spec.rb +106 -0
  229. data/spec/spec/story/scenario_spec.rb +20 -0
  230. data/spec/spec/story/step_group_spec.rb +157 -0
  231. data/spec/spec/story/step_mother_spec.rb +72 -0
  232. data/spec/spec/story/step_spec.rb +147 -0
  233. data/spec/spec/story/story_helper.rb +2 -0
  234. data/spec/spec/story/story_spec.rb +86 -0
  235. data/spec/spec/story/world_spec.rb +416 -0
  236. data/spec/spec/translator_spec.rb +2 -1
  237. data/spec/spec_helper.rb +59 -2
  238. data/stories/all.rb +5 -0
  239. data/stories/example_groups/autogenerated_docstrings +26 -0
  240. data/stories/example_groups/example_group_with_should_methods +17 -0
  241. data/stories/example_groups/nested_groups +17 -0
  242. data/stories/example_groups/output +20 -0
  243. data/stories/example_groups/stories.rb +7 -0
  244. data/stories/helper.rb +6 -0
  245. data/stories/interop/examples_and_tests_together +30 -0
  246. data/stories/interop/stories.rb +7 -0
  247. data/stories/interop/test_case_with_should_methods +17 -0
  248. data/stories/pending_stories/README +3 -0
  249. data/stories/resources/helpers/cmdline.rb +9 -0
  250. data/stories/resources/helpers/story_helper.rb +16 -0
  251. data/stories/resources/matchers/smart_match.rb +37 -0
  252. data/stories/resources/spec/example_group_with_should_methods.rb +12 -0
  253. data/stories/resources/spec/simple_spec.rb +8 -0
  254. data/stories/resources/steps/running_rspec.rb +50 -0
  255. data/stories/resources/test/spec_and_test_together.rb +57 -0
  256. data/stories/resources/test/test_case_with_should_methods.rb +30 -0
  257. metadata +232 -106
  258. data/EXAMPLES.rd +0 -111
  259. data/examples/multi_threaded_behaviour_runner.rb +0 -25
  260. data/examples/shared_behaviours_example.rb +0 -39
  261. data/examples/spec_helper.rb +0 -1
  262. data/examples/test_case_adapter_example.rb +0 -26
  263. data/examples/test_case_spec.rb +0 -65
  264. data/lib/spec/dsl.rb +0 -11
  265. data/lib/spec/dsl/behaviour.rb +0 -220
  266. data/lib/spec/dsl/behaviour_callbacks.rb +0 -82
  267. data/lib/spec/dsl/behaviour_eval.rb +0 -231
  268. data/lib/spec/dsl/behaviour_factory.rb +0 -42
  269. data/lib/spec/dsl/composite_proc_builder.rb +0 -33
  270. data/lib/spec/dsl/description.rb +0 -76
  271. data/lib/spec/dsl/example.rb +0 -135
  272. data/lib/spec/dsl/example_matcher.rb +0 -40
  273. data/lib/spec/dsl/example_should_raise_handler.rb +0 -74
  274. data/lib/spec/runner/behaviour_runner.rb +0 -123
  275. data/lib/spec/runner/extensions/kernel.rb +0 -50
  276. data/lib/spec/runner/extensions/object.rb +0 -32
  277. data/lib/spec/runner/formatter.rb +0 -9
  278. data/lib/spec/runner/formatter/failing_behaviours_formatter.rb +0 -29
  279. data/lib/spec/runner/formatter/rdoc_formatter.rb +0 -24
  280. data/lib/spec/test_case_adapter.rb +0 -10
  281. data/spec/spec/dsl/behaviour_eval_spec.rb +0 -79
  282. data/spec/spec/dsl/behaviour_factory_spec.rb +0 -48
  283. data/spec/spec/dsl/behaviour_spec.rb +0 -661
  284. data/spec/spec/dsl/composite_proc_builder_spec.rb +0 -44
  285. data/spec/spec/dsl/configuration_spec.rb +0 -55
  286. data/spec/spec/dsl/description_spec.rb +0 -89
  287. data/spec/spec/dsl/example_class_spec.rb +0 -24
  288. data/spec/spec/dsl/example_instance_spec.rb +0 -160
  289. data/spec/spec/dsl/example_should_raise_spec.rb +0 -137
  290. data/spec/spec/dsl/shared_behaviour_spec.rb +0 -252
  291. data/spec/spec/runner/behaviour_runner_spec.rb +0 -229
  292. data/spec/spec/runner/context_matching_spec.rb +0 -27
  293. data/spec/spec/runner/extensions/bug_report_10577_spec.rb +0 -35
  294. data/spec/spec/runner/extensions/kernel_spec.rb +0 -36
  295. data/spec/spec/runner/formatter/failing_behaviours_formatter_spec.rb +0 -40
  296. data/spec/spec/runner/formatter/progress_bar_formatter_dry_run_spec.rb +0 -20
  297. data/spec/spec/runner/formatter/progress_bar_formatter_failure_dump_spec.rb +0 -36
  298. data/spec/spec/runner/formatter/rdoc_formatter_dry_run_spec.rb +0 -19
  299. data/spec/spec/runner/formatter/rdoc_formatter_spec.rb +0 -46
  300. data/spec/spec/runner/formatter/specdoc_formatter_dry_run_spec.rb +0 -21
  301. data/spec/spec/runner/object_ext_spec.rb +0 -11
@@ -0,0 +1,16 @@
1
+ require 'spec/runner/formatter/html_formatter'
2
+
3
+ module Spec
4
+ module Runner
5
+ module Formatter
6
+ # Formats backtraces so they're clickable by TextMate
7
+ class TextMateFormatter < HtmlFormatter
8
+ def backtrace_line(line)
9
+ line.gsub(/([^:]*\.rb):(\d*)/) do
10
+ "<a href=\"txmt://open?url=file://#{File.expand_path($1)}&line=#{$2}\">#{$1}:#{$2}</a> "
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -13,9 +13,9 @@ module Spec
13
13
  @heckle_class = heckle_class
14
14
  end
15
15
 
16
- # Runs all the contexts held by +behaviour_runner+ once for each of the
16
+ # Runs all the example groups held by +rspec_options+ once for each of the
17
17
  # methods in the matched classes.
18
- def heckle_with(behaviour_runner)
18
+ def heckle_with
19
19
  if @filter =~ /(.*)[#\.](.*)/
20
20
  heckle_method($1, $2)
21
21
  else
@@ -25,7 +25,7 @@ module Spec
25
25
 
26
26
  def heckle_method(class_name, method_name)
27
27
  verify_constant(class_name)
28
- heckle = @heckle_class.new(class_name, method_name, behaviour_runner)
28
+ heckle = @heckle_class.new(class_name, method_name, rspec_options)
29
29
  heckle.validate
30
30
  end
31
31
 
@@ -39,7 +39,7 @@ module Spec
39
39
 
40
40
  classes.each do |klass|
41
41
  klass.instance_methods(false).each do |method_name|
42
- heckle = @heckle_class.new(klass.name, method_name, behaviour_runner)
42
+ heckle = @heckle_class.new(klass.name, method_name, rspec_options)
43
43
  heckle.validate
44
44
  end
45
45
  end
@@ -57,16 +57,16 @@ module Spec
57
57
 
58
58
  #Supports Heckle 1.2 and prior (earlier versions used Heckle::Base)
59
59
  class Heckler < (Heckle.const_defined?(:Base) ? Heckle::Base : Heckle)
60
- def initialize(klass_name, method_name, behaviour_runner)
60
+ def initialize(klass_name, method_name, rspec_options)
61
61
  super(klass_name, method_name)
62
- @behaviour_runner = behaviour_runner
62
+ @rspec_options = rspec_options
63
63
  end
64
64
 
65
65
  def tests_pass?
66
- paths = [] # We can pass an empty array of paths - our specs are already loaded.
67
- failure_count = @behaviour_runner.run(paths, false)
68
- failure_count == 0
66
+ success = @rspec_options.run_examples
67
+ success
69
68
  end
69
+
70
70
  end
71
71
  end
72
72
  end
@@ -3,23 +3,18 @@ require 'stringio'
3
3
 
4
4
  module Spec
5
5
  module Runner
6
- class OptionParser
7
- BUILT_IN_FORMATTERS = {
8
- 'specdoc' => Formatter::SpecdocFormatter,
9
- 's' => Formatter::SpecdocFormatter,
10
- 'html' => Formatter::HtmlFormatter,
11
- 'h' => Formatter::HtmlFormatter,
12
- 'rdoc' => Formatter::RdocFormatter,
13
- 'r' => Formatter::RdocFormatter,
14
- 'progress' => Formatter::ProgressBarFormatter,
15
- 'p' => Formatter::ProgressBarFormatter,
16
- 'failing_examples' => Formatter::FailingExamplesFormatter,
17
- 'e' => Formatter::FailingExamplesFormatter,
18
- 'failing_behaviours' => Formatter::FailingBehavioursFormatter,
19
- 'b' => Formatter::FailingBehavioursFormatter
20
- }
6
+ class OptionParser < ::OptionParser
7
+ class << self
8
+ def parse(args, err, out)
9
+ parser = new(err, out)
10
+ parser.parse(args)
11
+ parser.options
12
+ end
13
+ end
14
+
15
+ attr_reader :options
21
16
 
22
- COMMAND_LINE = {
17
+ OPTIONS = {
23
18
  :diff => ["-D", "--diff [FORMAT]", "Show diff of objects that are expected to be equal when they are not",
24
19
  "Builtin formats: unified|u|context|c",
25
20
  "You can also specify a custom differ class",
@@ -43,13 +38,17 @@ module Spec
43
38
  "not specified. The --format option may be specified several times",
44
39
  "if you want several outputs",
45
40
  " ",
46
- "Builtin formats: ",
47
- "progress|p : Text progress",
48
- "specdoc|s : Behaviour doc as text",
49
- "rdoc|r : Behaviour doc as RDoc",
41
+ "Builtin formats for examples: ",
42
+ "progress|p : Text progress",
43
+ "profile|o : Text progress with profiling of 10 slowest examples",
44
+ "specdoc|s : Example doc as text",
45
+ "html|h : A nice HTML report",
46
+ "failing_examples|e : Write all failing examples - input for --example",
47
+ "failing_example_groups|g : Write all failing example groups - input for --example",
48
+ " ",
49
+ "Builtin formats for stories: ",
50
+ "plain|p : Plain Text",
50
51
  "html|h : A nice HTML report",
51
- "failing_examples|e : Write all failing examples - input for --example",
52
- "failing_behaviours|b : Write all failing behaviours - input for --example",
53
52
  " ",
54
53
  "FORMAT can also be the name of a custom formatter class",
55
54
  "(in which case you should also specify --require to load it)"],
@@ -73,155 +72,158 @@ module Spec
73
72
  :dry_run => ["-d", "--dry-run", "Invokes formatters without executing the examples."],
74
73
  :options_file => ["-O", "--options PATH", "Read options from a file"],
75
74
  :generate_options => ["-G", "--generate-options PATH", "Generate an options file for --options"],
76
- :runner => ["-U", "--runner RUNNER", "Use a custom BehaviourRunner."],
75
+ :runner => ["-U", "--runner RUNNER", "Use a custom Runner."],
77
76
  :drb => ["-X", "--drb", "Run examples via DRb. (For example against script/spec_server)"],
78
77
  :version => ["-v", "--version", "Show version"],
79
78
  :help => ["-h", "--help", "You're looking at it"]
80
79
  }
81
80
 
82
- def initialize
81
+ def initialize(err, out)
82
+ super()
83
+ @error_stream = err
84
+ @out_stream = out
85
+ @options = Options.new(@error_stream, @out_stream)
86
+
83
87
  @spec_parser = SpecParser.new
84
88
  @file_factory = File
85
- end
86
-
87
- def create_behaviour_runner(args, err, out, warn_if_no_files)
88
- options = parse(args, err, out, warn_if_no_files)
89
- # Some exit points in parse (--generate-options, --drb) don't return the options,
90
- # but hand over control. In that case we don't want to continue.
91
- return nil unless options.is_a?(Options)
92
- options.configure
93
- options.behaviour_runner
94
- end
95
-
96
- def parse(args, err, out, warn_if_no_files)
97
- options_file = nil
98
- args_copy = args.dup
99
- options = Options.new(err, out)
100
-
101
- opts = ::OptionParser.new do |opts|
102
- opts.banner = "Usage: spec (FILE|DIRECTORY|GLOB)+ [options]"
103
- opts.separator ""
104
-
105
- def opts.rspec_on(name, &block)
106
- on(*COMMAND_LINE[name], &block)
107
- end
108
-
109
- opts.rspec_on(:diff) {|diff| options.parse_diff(diff)}
110
-
111
- opts.rspec_on(:colour) {options.colour = true}
112
-
113
- opts.rspec_on(:example) {|example| options.parse_example(example)}
114
-
115
- opts.rspec_on(:specification) {|example| options.parse_example(example)}
116
-
117
- opts.rspec_on(:line) {|line_number| options.line_number = line_number.to_i}
118
-
119
- opts.rspec_on(:format) {|format| options.parse_format(format)}
120
-
121
- opts.rspec_on(:require) {|req| options.parse_require(req)}
122
-
123
- opts.rspec_on(:backtrace) {options.backtrace_tweaker = NoisyBacktraceTweaker.new}
124
-
125
- opts.rspec_on(:loadby) {|loadby| options.loadby = loadby}
126
-
127
- opts.rspec_on(:reverse) {options.reverse = true}
128
-
129
- opts.rspec_on(:timeout) {|timeout| options.timeout = timeout.to_f}
130
-
131
- opts.rspec_on(:heckle) {|heckle| options.parse_heckle(heckle)}
132
-
133
- opts.rspec_on(:dry_run) {options.dry_run = true}
134
89
 
135
- opts.rspec_on(:options_file) do |options_file|
136
- return parse_options_file(options_file, out, err, args_copy, warn_if_no_files)
137
- end
138
-
139
- opts.rspec_on(:generate_options) do |options_file|
140
- options.parse_generate_options(options_file, args_copy, out)
141
- end
142
-
143
- opts.rspec_on(:runner) do |runner|
144
- options.runner_arg = runner
145
- end
146
-
147
- opts.rspec_on(:drb) do
148
- return parse_drb(args_copy, out, err, warn_if_no_files)
149
- end
150
-
151
- opts.rspec_on(:version) {parse_version(out)}
152
-
153
- opts.on_tail(*COMMAND_LINE[:help]) {parse_help(opts, out)}
90
+ self.banner = "Usage: spec (FILE|DIRECTORY|GLOB)+ [options]"
91
+ self.separator ""
92
+ on(*OPTIONS[:diff]) {|diff| @options.parse_diff(diff)}
93
+ on(*OPTIONS[:colour]) {@options.colour = true}
94
+ on(*OPTIONS[:example]) {|example| @options.parse_example(example)}
95
+ on(*OPTIONS[:specification]) {|example| @options.parse_example(example)}
96
+ on(*OPTIONS[:line]) {|line_number| @options.line_number = line_number.to_i}
97
+ on(*OPTIONS[:format]) {|format| @options.parse_format(format)}
98
+ on(*OPTIONS[:require]) {|requires| invoke_requires(requires)}
99
+ on(*OPTIONS[:backtrace]) {@options.backtrace_tweaker = NoisyBacktraceTweaker.new}
100
+ on(*OPTIONS[:loadby]) {|loadby| @options.loadby = loadby}
101
+ on(*OPTIONS[:reverse]) {@options.reverse = true}
102
+ on(*OPTIONS[:timeout]) {|timeout| @options.timeout = timeout.to_f}
103
+ on(*OPTIONS[:heckle]) {|heckle| @options.load_heckle_runner(heckle)}
104
+ on(*OPTIONS[:dry_run]) {@options.dry_run = true}
105
+ on(*OPTIONS[:options_file]) {|options_file| parse_options_file(options_file)}
106
+ on(*OPTIONS[:generate_options]) do |options_file|
154
107
  end
155
- opts.parse!(args)
156
-
157
- if args.empty? && warn_if_no_files
158
- err.puts "No files specified."
159
- err.puts opts
160
- exit(6) if err == $stderr
108
+ on(*OPTIONS[:runner]) do |runner|
109
+ @options.user_input_for_runner = runner
161
110
  end
111
+ on(*OPTIONS[:drb]) {}
112
+ on(*OPTIONS[:version]) {parse_version}
113
+ on_tail(*OPTIONS[:help]) {parse_help}
114
+ end
162
115
 
163
- if options.line_number
164
- set_spec_from_line_number(options, args, err)
116
+ def order!(argv, &blk)
117
+ @argv = argv
118
+ @options.argv = @argv.dup
119
+ return if parse_generate_options
120
+ return if parse_drb
121
+
122
+ super(@argv) do |file|
123
+ @options.files << file
124
+ blk.call(file) if blk
165
125
  end
166
126
 
167
- if options.formatters.empty?
168
- options.formatters << Formatter::ProgressBarFormatter.new(out)
127
+ if @options.line_number
128
+ set_spec_from_line_number
169
129
  end
170
130
 
171
- options
131
+ @options
172
132
  end
173
133
 
174
- def parse_options_file(options_file, out_stream, error_stream, args_copy, warn_if_no_files)
175
- # Remove the --options option and the argument before writing to file
176
- index = args_copy.index("-O") || args_copy.index("--options")
177
- args_copy.delete_at(index)
178
- args_copy.delete_at(index)
179
-
180
- new_args = args_copy + IO.readlines(options_file).map {|l| l.chomp.split " "}.flatten
181
- return CommandLine.run(new_args, error_stream, out_stream, true, warn_if_no_files)
134
+ protected
135
+ def invoke_requires(requires)
136
+ requires.split(",").each do |file|
137
+ require file
138
+ end
139
+ end
140
+
141
+ def parse_options_file(options_file)
142
+ option_file_args = IO.readlines(options_file).map {|l| l.chomp.split " "}.flatten
143
+ @argv.push(*option_file_args)
182
144
  end
183
145
 
184
- def parse_drb(args_copy, out_stream, error_stream, warn_if_no_files)
185
- # Remove the --drb option
186
- index = args_copy.index("-X") || args_copy.index("--drb")
187
- args_copy.delete_at(index)
146
+ def parse_generate_options
147
+ # Remove the --generate-options option and the argument before writing to file
148
+ options_file = nil
149
+ ['-G', '--generate-options'].each do |option|
150
+ if index = @argv.index(option)
151
+ @argv.delete_at(index)
152
+ options_file = @argv.delete_at(index)
153
+ end
154
+ end
155
+
156
+ if options_file
157
+ write_generated_options(options_file)
158
+ return true
159
+ else
160
+ return false
161
+ end
162
+ end
163
+
164
+ def write_generated_options(options_file)
165
+ File.open(options_file, 'w') do |io|
166
+ io.puts @argv.join("\n")
167
+ end
168
+ @out_stream.puts "\nOptions written to #{options_file}. You can now use these options with:"
169
+ @out_stream.puts "spec --options #{options_file}"
170
+ @options.examples_should_not_be_run
171
+ end
188
172
 
189
- return DrbCommandLine.run(args_copy, error_stream, out_stream, true, warn_if_no_files)
173
+ def parse_drb
174
+ is_drb = false
175
+ argv = @options.argv
176
+ is_drb ||= argv.delete(OPTIONS[:drb][0])
177
+ is_drb ||= argv.delete(OPTIONS[:drb][1])
178
+ return nil unless is_drb
179
+ @options.examples_should_not_be_run
180
+ DrbCommandLine.run(
181
+ self.class.parse(argv, @error_stream, @out_stream)
182
+ )
183
+ true
190
184
  end
191
185
 
192
- def parse_version(out_stream)
193
- out_stream.puts ::Spec::VERSION::DESCRIPTION
194
- exit if out_stream == $stdout
186
+ def parse_version
187
+ @out_stream.puts ::Spec::VERSION::DESCRIPTION
188
+ exit if stdout?
195
189
  end
196
190
 
197
- def parse_help(opts, out_stream)
198
- out_stream.puts opts
199
- exit if out_stream == $stdout
191
+ def parse_help
192
+ @out_stream.puts self
193
+ exit if stdout?
200
194
  end
201
195
 
202
- def set_spec_from_line_number(options, args, err)
203
- if options.examples.empty?
204
- if args.length == 1
205
- if @file_factory.file?(args[0])
206
- source = @file_factory.open(args[0])
207
- example = @spec_parser.spec_name_for(source, options.line_number)
208
- options.parse_example(example)
209
- elsif @file_factory.directory?(args[0])
210
- err.puts "You must specify one file, not a directory when using the --line option"
211
- exit(1) if err == $stderr
196
+ def set_spec_from_line_number
197
+ if @options.examples.empty?
198
+ if @options.files.length == 1
199
+ if @file_factory.file?(@options.files[0])
200
+ source = @file_factory.open(@options.files[0])
201
+ example = @spec_parser.spec_name_for(source, @options.line_number)
202
+ @options.parse_example(example)
203
+ elsif @file_factory.directory?(@options.files[0])
204
+ @error_stream.puts "You must specify one file, not a directory when using the --line option"
205
+ exit(1) if stderr?
212
206
  else
213
- err.puts "#{args[0]} does not exist"
214
- exit(2) if err == $stderr
207
+ @error_stream.puts "#{@options.files[0]} does not exist"
208
+ exit(2) if stderr?
215
209
  end
216
210
  else
217
- err.puts "Only one file can be specified when using the --line option: #{args.inspect}"
218
- exit(3) if err == $stderr
211
+ @error_stream.puts "Only one file can be specified when using the --line option: #{@options.files.inspect}"
212
+ exit(3) if stderr?
219
213
  end
220
214
  else
221
- err.puts "You cannot use both --line and --example"
222
- exit(4) if err == $stderr
215
+ @error_stream.puts "You cannot use both --line and --example"
216
+ exit(4) if stderr?
223
217
  end
224
218
  end
219
+
220
+ def stdout?
221
+ @out_stream == $stdout
222
+ end
223
+
224
+ def stderr?
225
+ @error_stream == $stderr
226
+ end
225
227
  end
226
228
  end
227
229
  end
@@ -1,32 +1,40 @@
1
1
  module Spec
2
2
  module Runner
3
3
  class Options
4
- BUILT_IN_FORMATTERS = {
5
- 'specdoc' => Formatter::SpecdocFormatter,
6
- 's' => Formatter::SpecdocFormatter,
7
- 'html' => Formatter::HtmlFormatter,
8
- 'h' => Formatter::HtmlFormatter,
9
- 'rdoc' => Formatter::RdocFormatter,
10
- 'r' => Formatter::RdocFormatter,
11
- 'progress' => Formatter::ProgressBarFormatter,
12
- 'p' => Formatter::ProgressBarFormatter,
13
- 'failing_examples' => Formatter::FailingExamplesFormatter,
14
- 'e' => Formatter::FailingExamplesFormatter,
15
- 'failing_behaviours' => Formatter::FailingBehavioursFormatter,
16
- 'b' => Formatter::FailingBehavioursFormatter
4
+ FILE_SORTERS = {
5
+ 'mtime' => lambda {|file_a, file_b| File.mtime(file_b) <=> File.mtime(file_a)}
17
6
  }
18
-
7
+
8
+ EXAMPLE_FORMATTERS = { # Load these lazily for better speed
9
+ 'specdoc' => ['spec/runner/formatter/specdoc_formatter', 'Formatter::SpecdocFormatter'],
10
+ 's' => ['spec/runner/formatter/specdoc_formatter', 'Formatter::SpecdocFormatter'],
11
+ 'html' => ['spec/runner/formatter/html_formatter', 'Formatter::HtmlFormatter'],
12
+ 'h' => ['spec/runner/formatter/html_formatter', 'Formatter::HtmlFormatter'],
13
+ 'progress' => ['spec/runner/formatter/progress_bar_formatter', 'Formatter::ProgressBarFormatter'],
14
+ 'p' => ['spec/runner/formatter/progress_bar_formatter', 'Formatter::ProgressBarFormatter'],
15
+ 'failing_examples' => ['spec/runner/formatter/failing_examples_formatter', 'Formatter::FailingExamplesFormatter'],
16
+ 'e' => ['spec/runner/formatter/failing_examples_formatter', 'Formatter::FailingExamplesFormatter'],
17
+ 'failing_example_groups' => ['spec/runner/formatter/failing_example_groups_formatter', 'Formatter::FailingExampleGroupsFormatter'],
18
+ 'g' => ['spec/runner/formatter/failing_example_groups_formatter', 'Formatter::FailingExampleGroupsFormatter'],
19
+ 'profile' => ['spec/runner/formatter/profile_formatter', 'Formatter::ProfileFormatter'],
20
+ 'o' => ['spec/runner/formatter/profile_formatter', 'Formatter::ProfileFormatter'],
21
+ 'textmate' => ['spec/runner/formatter/text_mate_formatter', 'Formatter::TextMateFormatter']
22
+ }
23
+
24
+ STORY_FORMATTERS = {
25
+ 'plain' => ['spec/runner/formatter/story/plain_text_formatter', 'Formatter::Story::PlainTextFormatter'],
26
+ 'p' => ['spec/runner/formatter/story/plain_text_formatter', 'Formatter::Story::PlainTextFormatter'],
27
+ 'html' => ['spec/runner/formatter/story/html_formatter', 'Formatter::Story::HtmlFormatter'],
28
+ 'h' => ['spec/runner/formatter/story/html_formatter', 'Formatter::Story::HtmlFormatter']
29
+ }
30
+
19
31
  attr_accessor(
20
32
  :backtrace_tweaker,
21
- :colour,
22
33
  :context_lines,
23
34
  :diff_format,
24
- :differ_class,
25
35
  :dry_run,
36
+ :profile,
26
37
  :examples,
27
- :failure_file,
28
- :formatters,
29
- :generate,
30
38
  :heckle_runner,
31
39
  :line_number,
32
40
  :loadby,
@@ -34,69 +42,83 @@ module Spec
34
42
  :reverse,
35
43
  :timeout,
36
44
  :verbose,
37
- :runner_arg,
38
- :behaviour_runner
45
+ :user_input_for_runner,
46
+ :error_stream,
47
+ :output_stream,
48
+ # TODO: BT - Figure out a better name
49
+ :argv
39
50
  )
51
+ attr_reader :colour, :differ_class, :files, :example_groups
40
52
 
41
- def initialize(err, out)
42
- @err, @out = err, out
53
+ def initialize(error_stream, output_stream)
54
+ @error_stream = error_stream
55
+ @output_stream = output_stream
43
56
  @backtrace_tweaker = QuietBacktraceTweaker.new
44
57
  @examples = []
45
- @formatters = []
46
58
  @colour = false
59
+ @profile = false
47
60
  @dry_run = false
61
+ @reporter = Reporter.new(self)
62
+ @context_lines = 3
63
+ @diff_format = :unified
64
+ @files = []
65
+ @example_groups = []
66
+ @examples_run = false
67
+ @examples_should_be_run = nil
68
+ @user_input_for_runner = nil
48
69
  end
49
70
 
50
- def configure
51
- configure_formatters
52
- create_reporter
53
- configure_differ
54
- create_behaviour_runner
71
+ def add_example_group(example_group)
72
+ @example_groups << example_group
55
73
  end
56
74
 
57
- def create_behaviour_runner
58
- return nil if @generate
59
- @behaviour_runner = if @runner_arg
60
- klass_name, arg = split_at_colon(@runner_arg)
61
- runner_type = load_class(klass_name, 'behaviour runner', '--runner')
62
- runner_type.new(self, arg)
63
- else
64
- BehaviourRunner.new(self)
65
- end
75
+ def remove_example_group(example_group)
76
+ @example_groups.delete(example_group)
66
77
  end
67
78
 
68
- def configure_formatters
69
- @formatters.each do |formatter|
70
- formatter.colour = @colour if formatter.respond_to?(:colour=)
71
- formatter.dry_run = @dry_run if formatter.respond_to?(:dry_run=)
79
+ def run_examples
80
+ return true unless examples_should_be_run?
81
+ runner = custom_runner || ExampleGroupRunner.new(self)
82
+
83
+ runner.load_files(files_to_load)
84
+ if example_groups.empty?
85
+ true
86
+ else
87
+ success = runner.run
88
+ @examples_run = true
89
+ heckle if heckle_runner
90
+ success
72
91
  end
73
92
  end
74
93
 
75
- def create_reporter
76
- @reporter = Reporter.new(@formatters, @backtrace_tweaker)
94
+ def examples_run?
95
+ @examples_run
77
96
  end
78
97
 
79
- def configure_differ
80
- if @differ_class
81
- Spec::Expectations.differ = @differ_class.new(@diff_format, @context_lines, @colour)
98
+ def examples_should_not_be_run
99
+ @examples_should_be_run = false
100
+ end
101
+
102
+ def colour=(colour)
103
+ @colour = colour
104
+ begin; \
105
+ require 'Win32/Console/ANSI' if @colour && PLATFORM =~ /win32/; \
106
+ rescue LoadError ; \
107
+ raise "You must gem install win32console to use colour on Windows" ; \
82
108
  end
83
109
  end
84
110
 
85
111
  def parse_diff(format)
86
- @context_lines = 3
87
112
  case format
88
- when :context, 'context', 'c'
89
- @diff_format = :context
90
- when :unified, 'unified', 'u', '', nil
91
- @diff_format = :unified
92
- end
93
-
94
- if [:context,:unified].include? @diff_format
95
- require 'spec/expectations/differs/default'
96
- @differ_class = Spec::Expectations::Differs::Default
113
+ when :context, 'context', 'c'
114
+ @diff_format = :context
115
+ default_differ
116
+ when :unified, 'unified', 'u', '', nil
117
+ @diff_format = :unified
118
+ default_differ
97
119
  else
98
120
  @diff_format = :custom
99
- @differ_class = load_class(format, 'differ', '--diff')
121
+ self.differ_class = load_class(format, 'differ', '--diff')
100
122
  end
101
123
  end
102
124
 
@@ -109,67 +131,123 @@ module Spec
109
131
  end
110
132
 
111
133
  def parse_format(format_arg)
112
- format, where = split_at_colon(format_arg)
113
- # This funky regexp checks whether we have a FILE_NAME or not
114
- if where.nil?
134
+ format, where = ClassAndArgumentsParser.parse(format_arg)
135
+ unless where
115
136
  raise "When using several --format options only one of them can be without a file" if @out_used
116
- where = @out
137
+ where = @output_stream
117
138
  @out_used = true
118
139
  end
119
-
120
- formatter_type = BUILT_IN_FORMATTERS[format] || load_class(format, 'formatter', '--format')
121
- @formatters << formatter_type.new(where)
140
+ @format_options ||= []
141
+ @format_options << [format, where]
142
+ end
143
+
144
+ def formatters
145
+ @format_options ||= [['progress', @output_stream]]
146
+ @formatters ||= load_formatters(@format_options, EXAMPLE_FORMATTERS)
122
147
  end
123
148
 
124
- def parse_require(req)
125
- req.split(",").each{|file| require file}
149
+ def story_formatters
150
+ @format_options ||= [['plain', @output_stream]]
151
+ @formatters ||= load_formatters(@format_options, STORY_FORMATTERS)
152
+ end
153
+
154
+ def load_formatters(format_options, formatters)
155
+ format_options.map do |format, where|
156
+ formatter_type = if formatters[format]
157
+ require formatters[format][0]
158
+ eval(formatters[format][1], binding, __FILE__, __LINE__)
159
+ else
160
+ load_class(format, 'formatter', '--format')
161
+ end
162
+ formatter_type.new(self, where)
163
+ end
126
164
  end
127
165
 
128
- def parse_heckle(heckle)
129
- heckle_require = [/mswin/, /java/].detect{|p| p =~ RUBY_PLATFORM} ? 'spec/runner/heckle_runner_unsupported' : 'spec/runner/heckle_runner'
130
- require heckle_require
166
+ def load_heckle_runner(heckle)
167
+ suffix = [/mswin/, /java/].detect{|p| p =~ RUBY_PLATFORM} ? '_unsupported' : ''
168
+ require "spec/runner/heckle_runner#{suffix}"
131
169
  @heckle_runner = HeckleRunner.new(heckle)
132
170
  end
133
171
 
134
- def parse_generate_options(options_file, args_copy, out_stream)
135
- # Remove the --generate-options option and the argument before writing to file
136
- index = args_copy.index("-G") || args_copy.index("--generate-options")
137
- args_copy.delete_at(index)
138
- args_copy.delete_at(index)
139
- File.open(options_file, 'w') do |io|
140
- io.puts args_copy.join("\n")
172
+ def number_of_examples
173
+ @example_groups.inject(0) do |sum, example_group|
174
+ sum + example_group.number_of_examples
141
175
  end
142
- out_stream.puts "\nOptions written to #{options_file}. You can now use these options with:"
143
- out_stream.puts "spec --options #{options_file}"
144
- @generate = true
145
176
  end
146
177
 
147
- def split_at_colon(s)
148
- if s =~ /([a-zA-Z_]+(?:::[a-zA-Z_]+)*):?(.*)/
149
- arg = $2 == "" ? nil : $2
150
- [$1, arg]
151
- else
152
- raise "Couldn't parse #{s.inspect}"
153
- end
178
+ protected
179
+ def examples_should_be_run?
180
+ return @examples_should_be_run unless @examples_should_be_run.nil?
181
+ @examples_should_be_run = true
154
182
  end
155
183
 
184
+ def differ_class=(klass)
185
+ return unless klass
186
+ @differ_class = klass
187
+ Spec::Expectations.differ = self.differ_class.new(self)
188
+ end
189
+
156
190
  def load_class(name, kind, option)
157
191
  if name =~ /\A(?:::)?([A-Z]\w*(?:::[A-Z]\w*)*)\z/
158
192
  arg = $2 == "" ? nil : $2
159
193
  [$1, arg]
160
194
  else
161
195
  m = "#{name.inspect} is not a valid class name"
162
- @err.puts m
196
+ @error_stream.puts m
163
197
  raise m
164
198
  end
165
199
  begin
166
200
  eval(name, binding, __FILE__, __LINE__)
167
201
  rescue NameError => e
168
- @err.puts "Couldn't find #{kind} class #{name}"
169
- @err.puts "Make sure the --require option is specified *before* #{option}"
202
+ @error_stream.puts "Couldn't find #{kind} class #{name}"
203
+ @error_stream.puts "Make sure the --require option is specified *before* #{option}"
170
204
  if $_spec_spec ; raise e ; else exit(1) ; end
171
205
  end
172
206
  end
207
+
208
+ def files_to_load
209
+ result = []
210
+ sorted_files.each do |file|
211
+ if test ?d, file
212
+ result += Dir[File.expand_path("#{file}/**/*.rb")]
213
+ elsif test ?f, file
214
+ result << file
215
+ else
216
+ raise "File or directory not found: #{file}"
217
+ end
218
+ end
219
+ result
220
+ end
221
+
222
+ def custom_runner
223
+ return nil unless custom_runner?
224
+ klass_name, arg = ClassAndArgumentsParser.parse(user_input_for_runner)
225
+ runner_type = load_class(klass_name, 'behaviour runner', '--runner')
226
+ return runner_type.new(self, arg)
227
+ end
228
+
229
+ def custom_runner?
230
+ return user_input_for_runner ? true : false
231
+ end
232
+
233
+ def heckle
234
+ returns = self.heckle_runner.heckle_with
235
+ self.heckle_runner = nil
236
+ returns
237
+ end
238
+
239
+ def sorted_files
240
+ return sorter ? files.sort(&sorter) : files
241
+ end
242
+
243
+ def sorter
244
+ FILE_SORTERS[loadby]
245
+ end
246
+
247
+ def default_differ
248
+ require 'spec/expectations/differs/default'
249
+ self.differ_class = Spec::Expectations::Differs::Default
250
+ end
173
251
  end
174
252
  end
175
253
  end