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
@@ -1,40 +1,52 @@
1
1
  module Spec
2
2
  module Runner
3
3
  class Reporter
4
+ attr_reader :options, :example_groups
4
5
 
5
- def initialize(formatters, backtrace_tweaker)
6
- @formatters = formatters
7
- @backtrace_tweaker = backtrace_tweaker
8
- clear!
6
+ def initialize(options)
7
+ @options = options
8
+ @options.reporter = self
9
+ clear
9
10
  end
10
11
 
11
- def add_behaviour(name)
12
- @formatters.each{|f| f.add_behaviour(name)}
13
- @behaviour_names << name
12
+ def add_example_group(example_group)
13
+ formatters.each do |f|
14
+ f.add_example_group(example_group)
15
+ end
16
+ example_groups << example_group
14
17
  end
15
18
 
16
- def example_started(name)
17
- @formatters.each{|f| f.example_started(name)}
19
+ def example_started(example)
20
+ formatters.each{|f| f.example_started(example)}
18
21
  end
19
22
 
20
- def example_finished(name, error=nil, failure_location=nil, not_implemented = false)
21
- @example_names << name
23
+ def example_finished(example, error=nil)
24
+ @examples << example
22
25
 
23
- if not_implemented
24
- example_pending(@behaviour_names.last, name)
25
- elsif error.nil?
26
- example_passed(name)
27
- elsif Spec::DSL::ExamplePendingError === error
28
- example_pending(@behaviour_names.last, name, error.message)
26
+ if error.nil?
27
+ example_passed(example)
28
+ elsif Spec::Example::ExamplePendingError === error
29
+ example_pending(example_groups.last, example, error.message)
29
30
  else
30
- example_failed(name, error, failure_location)
31
+ example_failed(example, error)
32
+ end
33
+ end
34
+
35
+ def failure(example, error)
36
+ backtrace_tweaker.tweak_backtrace(error)
37
+ example_name = "#{example_groups.last.description} #{example.description}"
38
+ failure = Failure.new(example_name, error)
39
+ @failures << failure
40
+ formatters.each do |f|
41
+ f.example_failed(example, @failures.length, failure)
31
42
  end
32
43
  end
44
+ alias_method :example_failed, :failure
33
45
 
34
46
  def start(number_of_examples)
35
- clear!
47
+ clear
36
48
  @start_time = Time.new
37
- @formatters.each{|f| f.start(number_of_examples)}
49
+ formatters.each{|f| f.start(number_of_examples)}
38
50
  end
39
51
 
40
52
  def end
@@ -43,22 +55,31 @@ module Spec
43
55
 
44
56
  # Dumps the summary and returns the total number of failures
45
57
  def dump
46
- @formatters.each{|f| f.start_dump}
58
+ formatters.each{|f| f.start_dump}
59
+ dump_pending
47
60
  dump_failures
48
- @formatters.each do |f|
49
- f.dump_summary(duration, @example_names.length, @failures.length, @pending_count)
61
+ formatters.each do |f|
62
+ f.dump_summary(duration, @examples.length, @failures.length, @pending_count)
50
63
  f.close
51
64
  end
52
65
  @failures.length
53
66
  end
54
67
 
55
68
  private
69
+
70
+ def formatters
71
+ @options.formatters
72
+ end
73
+
74
+ def backtrace_tweaker
75
+ @options.backtrace_tweaker
76
+ end
56
77
 
57
- def clear!
58
- @behaviour_names = []
78
+ def clear
79
+ @example_groups = []
59
80
  @failures = []
60
81
  @pending_count = 0
61
- @example_names = []
82
+ @examples = []
62
83
  @start_time = nil
63
84
  @end_time = nil
64
85
  end
@@ -66,31 +87,28 @@ module Spec
66
87
  def dump_failures
67
88
  return if @failures.empty?
68
89
  @failures.inject(1) do |index, failure|
69
- @formatters.each{|f| f.dump_failure(index, failure)}
90
+ formatters.each{|f| f.dump_failure(index, failure)}
70
91
  index + 1
71
92
  end
72
93
  end
94
+ def dump_pending
95
+ formatters.each{|f| f.dump_pending}
96
+ end
73
97
 
74
98
  def duration
75
99
  return @end_time - @start_time unless (@end_time.nil? or @start_time.nil?)
76
100
  return "0.0"
77
101
  end
78
102
 
79
- def example_passed(name)
80
- @formatters.each{|f| f.example_passed(name)}
81
- end
82
-
83
- def example_failed(name, error, failure_location)
84
- @backtrace_tweaker.tweak_backtrace(error, failure_location)
85
- example_name = "#{@behaviour_names.last} #{name}"
86
- failure = Failure.new(example_name, error)
87
- @failures << failure
88
- @formatters.each{|f| f.example_failed(name, @failures.length, failure)}
103
+ def example_passed(example)
104
+ formatters.each{|f| f.example_passed(example)}
89
105
  end
90
106
 
91
- def example_pending(behaviour_name, example_name, message="Not Yet Implemented")
107
+ def example_pending(example_group, example, message="Not Yet Implemented")
92
108
  @pending_count += 1
93
- @formatters.each{|f| f.example_pending(behaviour_name, example_name, message)}
109
+ formatters.each do |f|
110
+ f.example_pending(example_group.description, example, message)
111
+ end
94
112
  end
95
113
 
96
114
  class Failure
@@ -112,7 +130,7 @@ module Spec
112
130
  end
113
131
 
114
132
  def pending_fixed?
115
- @exception.is_a?(Spec::DSL::PendingFixedError)
133
+ @exception.is_a?(Spec::Example::PendingExampleFixedError)
116
134
  end
117
135
 
118
136
  def expectation_not_met?
@@ -4,12 +4,12 @@ module Spec
4
4
  class SpecParser
5
5
  def spec_name_for(io, line_number)
6
6
  source = io.read
7
- behaviour, behaviour_line = behaviour_at_line(source, line_number)
7
+ example_group, example_group_line = example_group_at_line(source, line_number)
8
8
  example, example_line = example_at_line(source, line_number)
9
- if behaviour && example && (behaviour_line < example_line)
10
- "#{behaviour} #{example}"
11
- elsif behaviour
12
- behaviour
9
+ if example_group && example && (example_group_line < example_line)
10
+ "#{example_group} #{example}"
11
+ elsif example_group
12
+ example_group
13
13
  else
14
14
  nil
15
15
  end
@@ -17,7 +17,7 @@ module Spec
17
17
 
18
18
  protected
19
19
 
20
- def behaviour_at_line(source, line_number)
20
+ def example_group_at_line(source, line_number)
21
21
  find_above(source, line_number, /^\s*(context|describe)\s+(.*)\s+do/)
22
22
  end
23
23
 
@@ -40,8 +40,11 @@ module Spec
40
40
 
41
41
  def parse_description(str)
42
42
  return str[1..-2] if str =~ /^['"].*['"]$/
43
- if matches = /^(.*)\s*,\s*['"](.*)['"]$/.match(str)
44
- return ::Spec::DSL::Description.generate_description(matches[1], matches[2])
43
+ if matches = /^['"](.*)['"](,.*)?$/.match(str)
44
+ return ::Spec::Example::ExampleGroupMethods.description_text(matches[1])
45
+ end
46
+ if matches = /^(.*)\s*,\s*['"](.*)['"](,.*)?$/.match(str)
47
+ return ::Spec::Example::ExampleGroupMethods.description_text(matches[1], matches[2])
45
48
  end
46
49
  return str
47
50
  end
@@ -0,0 +1,10 @@
1
+ require 'spec'
2
+ require 'spec/story/extensions'
3
+ require 'spec/story/given_scenario'
4
+ require 'spec/story/runner'
5
+ require 'spec/story/scenario'
6
+ require 'spec/story/step'
7
+ require 'spec/story/step_group'
8
+ require 'spec/story/step_mother'
9
+ require 'spec/story/story'
10
+ require 'spec/story/world'
@@ -0,0 +1 @@
1
+ require 'spec/story/extensions/main'
@@ -0,0 +1,86 @@
1
+ module Spec
2
+ module Story
3
+ module Extensions
4
+ module Main
5
+ def Story(title, narrative, params = {}, &body)
6
+ ::Spec::Story::Runner.story_runner.Story(title, narrative, params, &body)
7
+ end
8
+
9
+ # Calling this deprecated is silly, since it hasn't been released yet. But, for
10
+ # those who are reading this - this will be deleted before the 1.1 release.
11
+ def run_story(*args, &block)
12
+ runner = Spec::Story::Runner::PlainTextStoryRunner.new(*args)
13
+ runner.instance_eval(&block) if block
14
+ runner.run
15
+ end
16
+
17
+ # Creates (or appends to an existing) a namespaced group of steps for use in Stories
18
+ #
19
+ # == Examples
20
+ #
21
+ # # Creating a new group
22
+ # steps_for :forms do
23
+ # When("user enters $value in the $field field") do ... end
24
+ # When("user submits the $form form") do ... end
25
+ # end
26
+ def steps_for(tag, &block)
27
+ steps = rspec_story_steps[tag]
28
+ steps.instance_eval(&block) if block
29
+ steps
30
+ end
31
+
32
+ # Creates a context for running a Plain Text Story with specific groups of Steps.
33
+ # Also supports adding arbitrary steps that will only be accessible to
34
+ # the Story being run.
35
+ #
36
+ # == Examples
37
+ #
38
+ # # Run a Story with one group of steps
39
+ # with_steps_for :checking_accounts do
40
+ # run File.dirname(__FILE__) + "/withdraw_cash"
41
+ # end
42
+ #
43
+ # # Run a Story, adding steps that are only available for this Story
44
+ # with_steps_for :accounts do
45
+ # Given "user is logged in as account administrator"
46
+ # run File.dirname(__FILE__) + "/reconcile_accounts"
47
+ # end
48
+ #
49
+ # # Run a Story with steps from two groups
50
+ # with_steps_for :checking_accounts, :savings_accounts do
51
+ # run File.dirname(__FILE__) + "/transfer_money"
52
+ # end
53
+ #
54
+ # # Run a Story with a specific Story extension
55
+ # with_steps_for :login, :navigation do
56
+ # run File.dirname(__FILE__) + "/user_changes_password", :type => RailsStory
57
+ # end
58
+ def with_steps_for(*tags, &block)
59
+ steps = Spec::Story::StepGroup.new do
60
+ extend StoryRunnerStepGroupAdapter
61
+ end
62
+ tags.each {|tag| steps << rspec_story_steps[tag]}
63
+ steps.instance_eval(&block) if block
64
+ steps
65
+ end
66
+
67
+ private
68
+
69
+ module StoryRunnerStepGroupAdapter
70
+ def run(path, options={})
71
+ runner = Spec::Story::Runner::PlainTextStoryRunner.new(path, options)
72
+ runner.steps << self
73
+ runner.run
74
+ end
75
+ end
76
+
77
+ def rspec_story_steps # :nodoc:
78
+ $rspec_story_steps ||= Spec::Story::StepGroupHash.new
79
+ end
80
+
81
+ end
82
+ end
83
+ end
84
+ end
85
+
86
+ include Spec::Story::Extensions::Main
@@ -0,0 +1,14 @@
1
+ module Spec
2
+ module Story
3
+ class GivenScenario
4
+ def initialize(name)
5
+ @name = name
6
+ end
7
+
8
+ def perform(instance, ignore_name)
9
+ scenario = Runner::StoryRunner.scenario_from_current_story(@name)
10
+ Runner::ScenarioRunner.new.run(scenario, instance)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,58 @@
1
+ require 'spec/story/runner/scenario_collector.rb'
2
+ require 'spec/story/runner/scenario_runner.rb'
3
+ require 'spec/story/runner/story_runner.rb'
4
+ require 'spec/story/runner/story_parser.rb'
5
+ require 'spec/story/runner/story_mediator.rb'
6
+ require 'spec/story/runner/plain_text_story_runner.rb'
7
+
8
+ module Spec
9
+ module Story
10
+ module Runner
11
+ class << self
12
+ def run_options # :nodoc:
13
+ @run_options ||= ::Spec::Runner::OptionParser.parse(ARGV, $stderr, $stdout)
14
+ end
15
+
16
+ def story_runner # :nodoc:
17
+ unless @story_runner
18
+ @story_runner = StoryRunner.new(scenario_runner, world_creator)
19
+ run_options.story_formatters.each do |formatter|
20
+ register_listener(formatter)
21
+ end
22
+ Runner.register_exit_hook
23
+ end
24
+ @story_runner
25
+ end
26
+
27
+ def scenario_runner # :nodoc:
28
+ @scenario_runner ||= ScenarioRunner.new
29
+ end
30
+
31
+ def world_creator # :nodoc:
32
+ @world_creator ||= World
33
+ end
34
+
35
+ # Use this to register a customer output formatter.
36
+ def register_listener(listener)
37
+ story_runner.add_listener(listener) # run_started, story_started, story_ended, #run_ended
38
+ world_creator.add_listener(listener) # found_scenario, step_succeeded, step_failed, step_failed
39
+ scenario_runner.add_listener(listener) # scenario_started, scenario_succeeded, scenario_pending, scenario_failed
40
+ end
41
+
42
+ def register_exit_hook # :nodoc:
43
+ # TODO - when story runner uses test/unit runners like example runner does we can kill
44
+ # this and also the assorted Kernel.stub!(:at_exit) in examples
45
+ at_exit do
46
+ Runner.story_runner.run_stories unless $!
47
+ end
48
+ # TODO exit with non-zero status if run fails
49
+ end
50
+
51
+ def dry_run
52
+ run_options.dry_run
53
+ end
54
+
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,48 @@
1
+ module Spec
2
+ module Story
3
+ module Runner
4
+ class PlainTextStoryRunner
5
+ # You can initialize a PlainTextStoryRunner with the path to the
6
+ # story file or a block, in which you can define the path using load.
7
+ #
8
+ # == Examples
9
+ #
10
+ # PlainTextStoryRunner.new('path/to/file')
11
+ #
12
+ # PlainTextStoryRunner.new do |runner|
13
+ # runner.load 'path/to/file'
14
+ # end
15
+ def initialize(*args)
16
+ @options = Hash === args.last ? args.pop : {}
17
+ @story_file = args.empty? ? nil : args.shift
18
+ yield self if block_given?
19
+ end
20
+
21
+ def []=(key, value)
22
+ @options[key] = value
23
+ end
24
+
25
+ def load(path)
26
+ @story_file = path
27
+ end
28
+
29
+ def run
30
+ raise "You must set a path to the file with the story. See the RDoc." if @story_file.nil?
31
+ mediator = Spec::Story::Runner::StoryMediator.new(steps, Spec::Story::Runner.story_runner, @options)
32
+ parser = Spec::Story::Runner::StoryParser.new(mediator)
33
+
34
+ story_text = File.read(@story_file)
35
+ parser.parse(story_text.split("\n"))
36
+
37
+ mediator.run_stories
38
+ end
39
+
40
+ def steps
41
+ @step_group ||= Spec::Story::StepGroup.new
42
+ yield @step_group if block_given?
43
+ @step_group
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,18 @@
1
+ module Spec
2
+ module Story
3
+ module Runner
4
+ class ScenarioCollector
5
+ attr_accessor :scenarios
6
+
7
+ def initialize(story)
8
+ @story = story
9
+ @scenarios = []
10
+ end
11
+
12
+ def Scenario(name, &body)
13
+ @scenarios << Scenario.new(@story, name, &body)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,46 @@
1
+ module Spec
2
+ module Story
3
+ module Runner
4
+ class ScenarioRunner
5
+ def initialize
6
+ @listeners = []
7
+ end
8
+
9
+ def run(scenario, world)
10
+ @listeners.each { |l| l.scenario_started(scenario.story.title, scenario.name) }
11
+ run_story_ignoring_scenarios(scenario.story, world)
12
+
13
+ world.start_collecting_errors
14
+ world.instance_eval(&scenario.body)
15
+ if world.errors.empty?
16
+ @listeners.each { |l| l.scenario_succeeded(scenario.story.title, scenario.name) }
17
+ else
18
+ if Spec::Example::ExamplePendingError === (e = world.errors.first)
19
+ @listeners.each { |l| l.scenario_pending(scenario.story.title, scenario.name, e.message) }
20
+ else
21
+ @listeners.each { |l| l.scenario_failed(scenario.story.title, scenario.name, e) }
22
+ end
23
+ end
24
+ end
25
+
26
+ def add_listener(listener)
27
+ @listeners << listener
28
+ end
29
+
30
+ private
31
+
32
+ def run_story_ignoring_scenarios(story, world)
33
+ class << world
34
+ def Scenario(name, &block)
35
+ # do nothing
36
+ end
37
+ end
38
+ story.run_in(world)
39
+ class << world
40
+ remove_method(:Scenario)
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end