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,72 @@
1
+ require File.dirname(__FILE__) + '/story_helper'
2
+
3
+ module Spec
4
+ module Story
5
+ describe StepMother do
6
+ it 'should store a step by name and type' do
7
+ # given
8
+ step_mother = StepMother.new
9
+ step = Step.new("a given", &lambda {})
10
+ step_mother.store(:given, step)
11
+
12
+ # when
13
+ found = step_mother.find(:given, "a given")
14
+
15
+ # then
16
+ found.should == step
17
+ end
18
+
19
+ it 'should NOT raise an error if a step is missing' do
20
+ # given
21
+ step_mother = StepMother.new
22
+
23
+ # then
24
+ lambda do
25
+ # when
26
+ step_mother.find(:given, "doesn't exist")
27
+ end.should_not raise_error
28
+ end
29
+
30
+ it "should create a default step which raises a pending error" do
31
+ # given
32
+ step_mother = StepMother.new
33
+
34
+ # when
35
+ step = step_mother.find(:given, "doesn't exist")
36
+
37
+ # then
38
+ step.should be_an_instance_of(Step)
39
+
40
+ lambda do
41
+ step.perform(Object.new, "doesn't exist")
42
+ end.should raise_error(Spec::Example::ExamplePendingError, /Unimplemented/)
43
+ end
44
+
45
+ it 'should clear itself' do
46
+ # given
47
+ step_mother = StepMother.new
48
+ step = Step.new("a given") do end
49
+ step_mother.store(:given, step)
50
+
51
+ # when
52
+ step_mother.clear
53
+
54
+ # then
55
+ step_mother.should be_empty
56
+ end
57
+
58
+ it "should use assigned steps" do
59
+ step_mother = StepMother.new
60
+
61
+ step = Step.new('step') {}
62
+ step_group = StepGroup.new
63
+ step_group.add(:given, step)
64
+
65
+ step_mother.use(step_group)
66
+
67
+ step_mother.find(:given, "step").should equal(step)
68
+ end
69
+
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,147 @@
1
+ require File.dirname(__FILE__) + '/story_helper'
2
+
3
+ module Spec
4
+ module Story
5
+ describe Step, "matching" do
6
+ it "should match a text string" do
7
+ step = Step.new("this text") {}
8
+ step.matches?("this text").should be_true
9
+ end
10
+
11
+ it "should not match a text string that does not start the same" do
12
+ step = Step.new("this text") {}
13
+ step.matches?("Xthis text").should be_false
14
+ end
15
+
16
+ it "should not match a text string that does not end the same" do
17
+ step = Step.new("this text") {}
18
+ step.matches?("this textX").should be_false
19
+ end
20
+
21
+ it "should match a text string with a param" do
22
+ step = Step.new("this $param text") {}
23
+ step.matches?("this anything text").should be_true
24
+ end
25
+
26
+ it "should not be greedy" do
27
+ step = Step.new("enter $value for $key") {}
28
+ step.parse_args("enter 3 for keys for a piano").should == ['3','keys for a piano']
29
+ end
30
+
31
+ it "should match a text string with 3 params" do
32
+ step = Step.new("1 $one 2 $two 3 $three 4") {}
33
+ step.matches?("1 a 2 b 3 c 4").should be_true
34
+ end
35
+
36
+ it "should match a text string with a param at the beginning" do
37
+ step = Step.new("$one 2 3") {}
38
+ step.matches?("a 2 3").should be_true
39
+ end
40
+
41
+ it "should match a text string with a param at the end" do
42
+ step = Step.new("1 2 $three") {}
43
+ step.matches?("1 2 c").should be_true
44
+ end
45
+
46
+ it "should not match a different string" do
47
+ step = Step.new("this text") {}
48
+ step.matches?("other text").should be_false
49
+ end
50
+
51
+ it "should match a regexp" do
52
+ step = Step.new(/this text/) {}
53
+ step.matches?("this text").should be_true
54
+ end
55
+
56
+ it "should match a regexp with a match group" do
57
+ step = Step.new(/this (.*) text/) {}
58
+ step.matches?("this anything text").should be_true
59
+ end
60
+
61
+ it "should not match a non matching regexp" do
62
+ step = Step.new(/this (.*) text/) {}
63
+ step.matches?("other anything text").should be_false
64
+ end
65
+
66
+ it "should not get bogged down by parens in strings" do
67
+ step = Step.new("before () after") {}
68
+ step.matches?("before () after").should be_true
69
+ end
70
+
71
+ end
72
+
73
+ describe Step do
74
+ it "should make complain with no block" do
75
+ lambda {
76
+ step = Step.new("foo")
77
+ }.should raise_error
78
+ end
79
+
80
+ it "should perform itself on an object" do
81
+ # given
82
+ $instance = nil
83
+ step = Step.new 'step' do
84
+ $instance = self
85
+ end
86
+ instance = Object.new
87
+
88
+ # when
89
+ step.perform(instance, "step")
90
+
91
+ # then
92
+ $instance.should == instance
93
+ end
94
+
95
+ it "should perform itself with one parameter with match expression" do
96
+ # given
97
+ $result = nil
98
+ step = Step.new 'an account with $count dollars' do |count|
99
+ $result = count
100
+ end
101
+ instance = Object.new
102
+
103
+ # when
104
+ args = step.parse_args("an account with 3 dollars")
105
+ step.perform(instance, *args)
106
+
107
+ # then
108
+ $result.should == "3"
109
+ end
110
+
111
+ it "should perform itself with one parameter without a match expression" do
112
+ # given
113
+ $result = nil
114
+ step = Step.new 'an account with a balance of' do |amount|
115
+ $result = amount
116
+ end
117
+ instance = Object.new
118
+
119
+ # when
120
+ step.perform(instance, 20)
121
+
122
+ # then
123
+ $result.should == 20
124
+ end
125
+
126
+ it "should perform itself with 2 parameters" do
127
+ # given
128
+ $account_type = nil
129
+ $amount = nil
130
+ step = Step.new 'a $account_type account with $amount dollars' do |account_type, amount|
131
+ $account_type = account_type
132
+ $amount = amount
133
+ end
134
+ instance = Object.new
135
+
136
+ # when
137
+ args = step.parse_args("a savings account with 3 dollars")
138
+ step.perform(instance, *args)
139
+
140
+ # then
141
+ $account_type.should == "savings"
142
+ $amount.should == "3"
143
+ end
144
+
145
+ end
146
+ end
147
+ end
@@ -0,0 +1,2 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+ require File.dirname(__FILE__) + '/builders'
@@ -0,0 +1,86 @@
1
+ require File.dirname(__FILE__) + '/story_helper'
2
+
3
+ module Spec
4
+ module Story
5
+ describe Story do
6
+ it 'should run itself in a given object' do
7
+ # given
8
+ $instance = nil
9
+ story = Story.new 'title', 'narrative' do
10
+ $instance = self
11
+ end
12
+ object = Object.new
13
+
14
+ # when
15
+ story.run_in(object)
16
+
17
+ # then
18
+ $instance.should be(object)
19
+ end
20
+
21
+ it 'should not raise an error if no block is supplied' do
22
+ # when
23
+ error = exception_from do
24
+ Story.new 'title', 'narrative'
25
+ end
26
+
27
+ # then
28
+ error.should be_nil
29
+ end
30
+
31
+ it "should raise when error raised running in another object" do
32
+ #given
33
+ story = Story.new 'title', 'narrative' do
34
+ raise "this is raised in the story"
35
+ end
36
+ object = Object.new
37
+
38
+ # when/then
39
+ lambda do
40
+ story.run_in(object)
41
+ end.should raise_error
42
+ end
43
+
44
+ it "should use the steps it is told to using a StepGroup" do
45
+ story = Story.new("title", "narrative", :steps => steps = StepGroup.new) do end
46
+ assignee = mock("assignee")
47
+ assignee.should_receive(:use).with(steps)
48
+ story.assign_steps_to(assignee)
49
+ end
50
+
51
+ it "should use the steps it is told to using a key" do
52
+ begin
53
+ orig_rspec_story_steps = $rspec_story_steps
54
+ $rspec_story_steps = StepGroupHash.new
55
+ $rspec_story_steps[:foo] = steps = Object.new
56
+
57
+ story = Story.new("title", "narrative", :steps_for => :foo) do end
58
+ assignee = mock("assignee")
59
+
60
+ assignee.should_receive(:use).with(steps)
61
+ story.assign_steps_to(assignee)
62
+ ensure
63
+ $rspec_story_steps = orig_rspec_story_steps
64
+ end
65
+ end
66
+
67
+ it "should use the steps it is told to using multiple keys" do
68
+ begin
69
+ orig_rspec_story_steps = $rspec_story_steps
70
+ $rspec_story_steps = StepGroupHash.new
71
+ $rspec_story_steps[:foo] = foo_steps = Object.new
72
+ $rspec_story_steps[:bar] = bar_steps = Object.new
73
+
74
+ story = Story.new("title", "narrative", :steps_for => [:foo, :bar]) do end
75
+ assignee = mock("assignee")
76
+
77
+ assignee.should_receive(:use).with(foo_steps)
78
+ assignee.should_receive(:use).with(bar_steps)
79
+ story.assign_steps_to(assignee)
80
+ ensure
81
+ $rspec_story_steps = orig_rspec_story_steps
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,416 @@
1
+ require File.dirname(__FILE__) + '/story_helper'
2
+
3
+ require 'spec/story'
4
+
5
+ module Spec
6
+ module Story
7
+ describe World do
8
+ before :each do
9
+ World.listeners.clear
10
+ end
11
+
12
+ after :each do
13
+ World.listeners.clear
14
+ World.step_mother.clear
15
+ end
16
+
17
+ it 'should create an object that mixes in a World' do
18
+ # when
19
+ obj = World::create
20
+
21
+ # then
22
+ obj.should be_kind_of(World)
23
+ end
24
+
25
+ it 'should create a World from any object type' do
26
+ # when
27
+ obj = World::create String
28
+
29
+ # then
30
+ obj.should be_kind_of(String)
31
+ obj.should be_kind_of(World)
32
+ end
33
+
34
+ it 'should pass arguments to #new when creating an object of a specified type that mixes in a world' do
35
+ # given
36
+ Thing = Struct.new(:name, :age)
37
+
38
+ # when
39
+ obj = World::create Thing, "David", "I'm not telling"
40
+
41
+ # then
42
+ obj.should be_an_instance_of(Thing)
43
+ obj.name.should == "David"
44
+ obj.age.should == "I'm not telling"
45
+ obj.should be_kind_of(World)
46
+ end
47
+
48
+ def ensure_world_executes_step(&block)
49
+ # given
50
+ obj = World::create
51
+ $step_ran = false
52
+
53
+ # when
54
+ obj.instance_eval(&block)
55
+
56
+ # then
57
+ $step_ran.should be_true
58
+ end
59
+
60
+ it 'should execute a Given, When or Then step' do
61
+ ensure_world_executes_step do
62
+ Given 'a given' do
63
+ $step_ran = true
64
+ end
65
+ end
66
+
67
+ ensure_world_executes_step do
68
+ When 'an event' do
69
+ $step_ran = true
70
+ end
71
+ end
72
+
73
+ ensure_world_executes_step do
74
+ Then 'an outcome' do
75
+ $step_ran = true
76
+ end
77
+ end
78
+ end
79
+
80
+ it 'should interpret Given... And... as multiple givens' do
81
+ # given
82
+ world = World.create
83
+ $steps = []
84
+
85
+ # when
86
+ world.instance_eval do
87
+ Given 'step 1' do
88
+ $steps << 1
89
+ end
90
+ And 'step 2' do
91
+ $steps << 2
92
+ end
93
+ end
94
+
95
+ # then
96
+ $steps.should == [1,2]
97
+ World.step_mother.find(:given, 'step 1').should_not be_nil
98
+ World.step_mother.find(:given, 'step 2').should_not be_nil
99
+ end
100
+
101
+ it 'should interpret When... And... as multiple events' do
102
+ # given
103
+ world = World.create
104
+ $steps = []
105
+
106
+ # when
107
+ world.instance_eval do
108
+ When 'step 1' do
109
+ $steps << 1
110
+ end
111
+ And 'step 2' do
112
+ $steps << 2
113
+ end
114
+ end
115
+
116
+ # then
117
+ $steps.should == [1,2]
118
+ World.step_mother.find(:when, 'step 1').should_not be_nil
119
+ World.step_mother.find(:when, 'step 2').should_not be_nil
120
+ end
121
+
122
+ it 'should interpret Then... And... as multiple outcomes' do
123
+ # given
124
+ world = World.create
125
+ $steps = []
126
+
127
+ # when
128
+ world.instance_eval do
129
+ Then 'step 1' do
130
+ $steps << 1
131
+ end
132
+ And 'step 2' do
133
+ $steps << 2
134
+ end
135
+ end
136
+
137
+ # then
138
+ $steps.should == [1,2]
139
+ World.step_mother.find(:then, 'step 1').should_not be_nil
140
+ World.step_mother.find(:then, 'step 2').should_not be_nil
141
+ end
142
+
143
+ it 'should reuse a given across scenarios' do
144
+ # given
145
+ $num_invoked = 0
146
+ a_world = World::create
147
+ a_world.instance_eval do
148
+ Given 'a given' do
149
+ $num_invoked += 1
150
+ end
151
+ end
152
+ another_world = World::create
153
+
154
+ # when
155
+ another_world.instance_eval do
156
+ Given 'a given' # without a body
157
+ end
158
+
159
+ # then
160
+ $num_invoked.should == 2
161
+ end
162
+
163
+ it 'should reuse an event across scenarios' do
164
+ # given
165
+ $num_invoked = 0
166
+ a_world = World::create
167
+ a_world.instance_eval do
168
+ When 'an event' do
169
+ $num_invoked += 1
170
+ end
171
+ end
172
+
173
+ another_world = World::create
174
+
175
+ # when
176
+ another_world.instance_eval do
177
+ When 'an event' # without a body
178
+ end
179
+
180
+ # then
181
+ $num_invoked.should == 2
182
+ end
183
+
184
+ it 'should reuse an outcome across scenarios' do
185
+ # given
186
+ $num_invoked = 0
187
+ a_world = World::create
188
+ a_world.instance_eval do
189
+ Then 'an outcome' do
190
+ $num_invoked += 1
191
+ end
192
+ end
193
+
194
+ another_world = World::create
195
+
196
+ # when
197
+ another_world.instance_eval do
198
+ Then 'an outcome' # without a body
199
+ end
200
+
201
+ # then
202
+ $num_invoked.should == 2
203
+ end
204
+
205
+ it 'should preserve instance variables between steps within a scenario' do
206
+ # given
207
+ world = World::create
208
+ $first = nil
209
+ $second = nil
210
+
211
+ # when
212
+ world.instance_eval do
213
+ Given 'given' do
214
+ @first = 'first'
215
+ end
216
+ When 'event' do
217
+ @second = @first # from given
218
+ end
219
+ Then 'outcome' do
220
+ $first = @first # from given
221
+ $second = @second # from event
222
+ end
223
+ end
224
+
225
+ # then
226
+ $first.should == 'first'
227
+ $second.should == 'first'
228
+ end
229
+
230
+ it 'should invoke a reused step in the new object instance' do
231
+ # given
232
+ $instances = []
233
+ $debug = true
234
+ world1 = World.create
235
+ world1.instance_eval do
236
+ Given 'a given' do
237
+ $instances << self.__id__
238
+ end
239
+ end
240
+ world2 = World.create
241
+
242
+ # when
243
+ world2.instance_eval do
244
+ Given 'a given' # reused
245
+ Then 'an outcome' do
246
+ $instances << __id__
247
+ end
248
+ end
249
+ $debug = false
250
+ # then
251
+ $instances.should == [ world1.__id__, world2.__id__, world2.__id__ ]
252
+ end
253
+
254
+ def ensure_world_collects_error(expected_error, &block)
255
+ # given
256
+ world = World.create
257
+ # $error = nil
258
+
259
+ # when
260
+ world.start_collecting_errors
261
+ world.instance_eval(&block)
262
+
263
+ # then
264
+ world.should have(1).errors
265
+ world.errors[0].should be_kind_of(expected_error)
266
+ end
267
+
268
+ it 'should collect a failure from a Given step' do
269
+ ensure_world_collects_error RuntimeError do
270
+ Given 'a given' do
271
+ raise RuntimeError, "oops"
272
+ end
273
+ end
274
+ end
275
+
276
+ it 'should collect a failure from a When step' do
277
+ ensure_world_collects_error RuntimeError do
278
+ When 'an event' do
279
+ raise RuntimeError, "oops"
280
+ end
281
+ end
282
+ end
283
+
284
+ it 'should collect a failure from a Then step' do
285
+ ensure_world_collects_error RuntimeError do
286
+ Then 'an outcome' do
287
+ raise RuntimeError, "oops"
288
+ end
289
+ end
290
+ end
291
+
292
+ it 'should inform listeners when it runs a Given, When or Then step' do
293
+ # given
294
+ world = World.create
295
+ mock_listener1 = mock('listener1')
296
+ mock_listener2 = mock('listener2')
297
+ World.add_listener(mock_listener1)
298
+ World.add_listener(mock_listener2)
299
+
300
+ # expect
301
+ mock_listener1.should_receive(:step_succeeded).with(:given, 'a context')
302
+ mock_listener1.should_receive(:step_succeeded).with(:when, 'an event')
303
+ mock_listener1.should_receive(:step_succeeded).with(:then, 'an outcome')
304
+
305
+ mock_listener2.should_receive(:step_succeeded).with(:given, 'a context')
306
+ mock_listener2.should_receive(:step_succeeded).with(:when, 'an event')
307
+ mock_listener2.should_receive(:step_succeeded).with(:then, 'an outcome')
308
+
309
+ # when
310
+ world.instance_eval do
311
+ Given 'a context' do end
312
+ When 'an event' do end
313
+ Then 'an outcome' do end
314
+ end
315
+
316
+ # then
317
+ end
318
+
319
+ it 'should tell listeners but not execute the step in dry-run mode' do
320
+ # given
321
+ Runner.stub!(:dry_run).and_return(true)
322
+ mock_listener = mock('listener')
323
+ World.add_listener(mock_listener)
324
+ $step_invoked = false
325
+ world = World.create
326
+
327
+ # expect
328
+ mock_listener.should_receive(:step_succeeded).with(:given, 'a context')
329
+
330
+ # when
331
+ world.instance_eval do
332
+ Given 'a context' do
333
+ $step_invoked = true
334
+ end
335
+ end
336
+
337
+ # then
338
+ $step_invoked.should be(false)
339
+ end
340
+
341
+ it 'should suppress listeners while it runs a GivenScenario' do
342
+ # given
343
+ $scenario_ran = false
344
+
345
+ scenario = ScenarioBuilder.new.name('a scenario').to_scenario do
346
+ $scenario_ran = true
347
+ Given 'given' do end
348
+ When 'event' do end
349
+ Then 'outcome' do end
350
+ end
351
+
352
+ given_scenario = GivenScenario.new('a scenario')
353
+ Runner::StoryRunner.should_receive(:scenario_from_current_story).
354
+ with('a scenario').and_return(scenario)
355
+
356
+ world = World.create
357
+ listener = mock('listener')
358
+ World.add_listener(listener)
359
+
360
+ # expect
361
+ listener.should_receive(:found_scenario).with(:'given scenario', 'a scenario')
362
+ listener.should_receive(:step_succeeded).never.with(:given, 'given')
363
+ listener.should_receive(:step_succeeded).never.with(:when, 'event')
364
+ listener.should_receive(:step_succeeded).never.with(:then, 'outcome')
365
+
366
+ # when
367
+ world.GivenScenario 'a scenario'
368
+
369
+ # then
370
+ $scenario_ran.should be_true
371
+ end
372
+
373
+ it 'should interpret GivenScenario... And... as multiple givens' do
374
+ # given
375
+ world = World.create
376
+ $steps = []
377
+
378
+ scenario = ScenarioBuilder.new.name('a scenario').to_scenario do
379
+ $steps << 1
380
+ end
381
+ Runner::StoryRunner.should_receive(:scenario_from_current_story).
382
+ with('a scenario').and_return(scenario)
383
+
384
+ # when
385
+ world.instance_eval do
386
+ GivenScenario 'a scenario'
387
+ And 'step 2' do
388
+ $steps << 2
389
+ end
390
+ end
391
+
392
+ # then
393
+ $steps.should == [1,2]
394
+ World.step_mother.find(:given, 'step 2').should_not be_nil
395
+ end
396
+
397
+ it 'should provide rspec matchers' do
398
+ # given
399
+ world = World.create
400
+
401
+ # then
402
+ world.instance_eval do
403
+ 'hello'.should match(/^hello$/)
404
+ end
405
+ end
406
+
407
+ it "should use assigned matchers" do
408
+ world = World.create
409
+
410
+ World.should_receive(:use).with(steps = Object.new)
411
+
412
+ World.use(steps)
413
+ end
414
+ end
415
+ end
416
+ end