rspec 1.1.11 → 1.1.12

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 (269) hide show
  1. data/.autotest +4 -0
  2. data/History.txt +55 -0
  3. data/Manifest.txt +102 -122
  4. data/README.txt +30 -12
  5. data/Rakefile +10 -10
  6. data/TODO.txt +10 -2
  7. data/{failing_examples → examples/failing}/README.txt +0 -0
  8. data/{failing_examples → examples/failing}/diffing_spec.rb +0 -0
  9. data/{failing_examples → examples/failing}/failing_autogenerated_docstrings_example.rb +0 -0
  10. data/{failing_examples/failure_in_teardown.rb → examples/failing/failure_in_after.rb} +1 -1
  11. data/{failing_examples/failure_in_setup.rb → examples/failing/failure_in_before.rb} +1 -1
  12. data/{failing_examples → examples/failing}/mocking_example.rb +0 -0
  13. data/{failing_examples → examples/failing}/mocking_with_flexmock.rb +0 -0
  14. data/{failing_examples → examples/failing}/mocking_with_mocha.rb +0 -0
  15. data/{failing_examples → examples/failing}/mocking_with_rr.rb +0 -0
  16. data/{failing_examples → examples/failing}/partial_mock_example.rb +0 -0
  17. data/{failing_examples → examples/failing}/predicate_example.rb +5 -0
  18. data/{failing_examples → examples/failing}/raising_example.rb +0 -0
  19. data/{failing_examples → examples/failing}/spec_helper.rb +1 -1
  20. data/{failing_examples → examples/failing}/syntax_error_example.rb +0 -0
  21. data/{failing_examples → examples/failing}/team_spec.rb +0 -0
  22. data/{failing_examples → examples/failing}/timeout_behaviour.rb +0 -0
  23. data/examples/{pure → passing}/autogenerated_docstrings_example.rb +6 -0
  24. data/examples/{pure → passing}/before_and_after_example.rb +0 -0
  25. data/examples/{pure → passing}/behave_as_example.rb +0 -0
  26. data/examples/{pure → passing}/custom_expectation_matchers.rb +0 -0
  27. data/examples/{pure → passing}/custom_formatter.rb +1 -1
  28. data/examples/{pure → passing}/dynamic_spec.rb +2 -2
  29. data/examples/{pure → passing}/file_accessor.rb +0 -0
  30. data/examples/{pure → passing}/file_accessor_spec.rb +0 -0
  31. data/examples/{pure → passing}/greeter_spec.rb +0 -0
  32. data/examples/{pure → passing}/helper_method_example.rb +0 -0
  33. data/examples/{pure → passing}/io_processor.rb +0 -0
  34. data/examples/{pure → passing}/io_processor_spec.rb +0 -0
  35. data/examples/{pure → passing}/legacy_spec.rb +0 -0
  36. data/examples/{pure → passing}/mocking_example.rb +0 -0
  37. data/examples/{pure/multi_threaded_behaviour_runner.rb → passing/multi_threaded_example_group_runner.rb} +1 -3
  38. data/examples/{pure → passing}/nested_classes_example.rb +0 -0
  39. data/examples/{pure → passing}/partial_mock_example.rb +0 -0
  40. data/examples/{pure → passing}/pending_example.rb +0 -0
  41. data/examples/{pure → passing}/predicate_example.rb +0 -0
  42. data/examples/{pure → passing}/priority.txt +0 -0
  43. data/examples/{pure → passing}/shared_example_group_example.rb +0 -0
  44. data/examples/{pure → passing}/shared_stack_examples.rb +1 -3
  45. data/examples/passing/simple_matcher_example.rb +31 -0
  46. data/examples/{pure → passing}/spec_helper.rb +0 -0
  47. data/examples/{pure → passing}/stack.rb +0 -0
  48. data/examples/{pure → passing}/stack_spec.rb +3 -2
  49. data/examples/{pure → passing}/stack_spec_with_nested_example_groups.rb +0 -0
  50. data/examples/{pure → passing}/stubbing_example.rb +0 -0
  51. data/examples/{pure → passing}/yielding_example.rb +0 -0
  52. data/examples/ruby1.9.compatibility/access_to_constants_spec.rb +86 -0
  53. data/features/before_and_after_blocks/before_and_after_blocks.feature +168 -0
  54. data/{stories/example_groups/autogenerated_docstrings → features/example_groups/autogenerated_docstrings.feature} +5 -5
  55. data/{stories/example_groups/example_group_with_should_methods → features/example_groups/example_group_with_should_methods.feature} +3 -3
  56. data/{stories/example_groups/nested_groups → features/example_groups/nested_groups.feature} +4 -4
  57. data/{stories/example_groups/output → features/example_groups/output.feature} +3 -8
  58. data/{stories/interop/examples_and_tests_together → features/interop/examples_and_tests_together.feature} +5 -4
  59. data/features/interop/test_but_not_test_unit.feature +14 -0
  60. data/{stories/interop/test_case_with_should_methods → features/interop/test_case_with_should_methods.feature} +2 -2
  61. data/{stories/mock_framework_integration/use_flexmock.story → features/mock_framework_integration/use_flexmock.feature} +1 -1
  62. data/features/step_definitions/running_rspec.rb +54 -0
  63. data/features/support/env.rb +26 -0
  64. data/{stories/resources → features/support}/helpers/cmdline.rb +0 -0
  65. data/{stories/resources → features/support}/helpers/story_helper.rb +1 -1
  66. data/{stories/resources → features/support}/matchers/smart_match.rb +0 -0
  67. data/{plugins → lib/adapters}/mock_frameworks/flexmock.rb +1 -1
  68. data/{plugins → lib/adapters}/mock_frameworks/mocha.rb +1 -1
  69. data/{plugins → lib/adapters}/mock_frameworks/rr.rb +1 -1
  70. data/{plugins → lib/adapters}/mock_frameworks/rspec.rb +2 -2
  71. data/lib/autotest/rspec.rb +4 -3
  72. data/lib/spec.rb +2 -27
  73. data/lib/spec/dsl.rb +1 -0
  74. data/lib/spec/{extensions → dsl}/main.rb +10 -10
  75. data/lib/spec/example.rb +175 -1
  76. data/lib/spec/example/before_and_after_hooks.rb +30 -24
  77. data/lib/spec/example/example_group.rb +1 -0
  78. data/lib/spec/example/example_group_factory.rb +26 -9
  79. data/lib/spec/example/example_group_methods.rb +138 -113
  80. data/lib/spec/example/example_methods.rb +88 -25
  81. data/lib/spec/example/shared_example_group.rb +28 -21
  82. data/lib/spec/expectations.rb +22 -18
  83. data/lib/spec/expectations/handler.rb +16 -36
  84. data/lib/spec/interop/test/unit/testcase.rb +19 -17
  85. data/lib/spec/interop/test/unit/testresult.rb +1 -1
  86. data/lib/spec/interop/test/unit/testsuite_adapter.rb +1 -1
  87. data/lib/spec/matchers.rb +7 -28
  88. data/lib/spec/matchers/be.rb +103 -116
  89. data/lib/spec/matchers/be_close.rb +6 -22
  90. data/lib/spec/matchers/eql.rb +7 -25
  91. data/lib/spec/matchers/equal.rb +7 -25
  92. data/lib/spec/matchers/errors.rb +5 -0
  93. data/lib/spec/matchers/exist.rb +8 -14
  94. data/lib/spec/matchers/generated_descriptions.rb +48 -0
  95. data/lib/spec/matchers/has.rb +12 -28
  96. data/lib/spec/matchers/include.rb +12 -9
  97. data/lib/spec/matchers/match.rb +8 -27
  98. data/lib/spec/matchers/match_array.rb +79 -0
  99. data/lib/spec/matchers/method_missing.rb +9 -0
  100. data/lib/spec/matchers/operator_matcher.rb +39 -48
  101. data/lib/spec/matchers/raise_error.rb +4 -8
  102. data/lib/spec/matchers/respond_to.rb +33 -8
  103. data/lib/spec/matchers/throw_symbol.rb +49 -17
  104. data/lib/spec/matchers/wrap_expectation.rb +55 -0
  105. data/lib/spec/mocks/argument_constraints.rb +77 -5
  106. data/lib/spec/mocks/message_expectation.rb +7 -7
  107. data/lib/spec/mocks/proxy.rb +14 -12
  108. data/lib/spec/rake/spectask.rb +4 -6
  109. data/lib/spec/ruby.rb +9 -0
  110. data/lib/spec/runner.rb +37 -162
  111. data/lib/spec/runner/backtrace_tweaker.rb +5 -3
  112. data/lib/spec/runner/class_and_arguments_parser.rb +7 -9
  113. data/lib/spec/runner/command_line.rb +6 -8
  114. data/lib/spec/{example → runner}/configuration.rb +46 -47
  115. data/lib/spec/runner/example_group_runner.rb +15 -4
  116. data/lib/spec/runner/formatter/base_text_formatter.rb +4 -3
  117. data/lib/spec/runner/formatter/html_formatter.rb +14 -11
  118. data/lib/spec/runner/formatter/nested_text_formatter.rb +2 -2
  119. data/lib/spec/runner/heckle_runner.rb +58 -56
  120. data/lib/spec/runner/option_parser.rb +8 -4
  121. data/lib/spec/runner/options.rb +29 -14
  122. data/lib/spec/runner/reporter.rb +1 -1
  123. data/lib/spec/runner/spec_parser.rb +11 -9
  124. data/lib/spec/story/runner.rb +40 -42
  125. data/lib/spec/story/runner/story_runner.rb +10 -6
  126. data/lib/spec/story/world.rb +66 -70
  127. data/lib/spec/version.rb +4 -2
  128. data/{rake_tasks → resources/rake}/examples.rake +0 -0
  129. data/{rake_tasks → resources/rake}/examples_with_rcov.rake +0 -0
  130. data/{rake_tasks → resources/rake}/failing_examples_with_html.rake +0 -0
  131. data/{rake_tasks → resources/rake}/verify_rcov.rake +0 -0
  132. data/{stories/resources → resources}/spec/example_group_with_should_methods.rb +1 -1
  133. data/{stories/resources → resources}/spec/simple_spec.rb +1 -1
  134. data/resources/spec/spec_with_flexmock.rb +19 -0
  135. data/{stories/resources → resources}/test/spec_and_test_together.rb +1 -1
  136. data/resources/test/spec_including_test_but_not_unit.rb +11 -0
  137. data/{stories/resources → resources}/test/test_case_with_should_methods.rb +2 -2
  138. data/rspec.gemspec +16 -6
  139. data/spec/autotest/autotest_helper.rb +2 -2
  140. data/spec/autotest/discover_spec.rb +4 -15
  141. data/spec/autotest/failed_results_re_spec.rb +24 -0
  142. data/spec/autotest/rspec_spec.rb +2 -38
  143. data/spec/spec/dsl/main_spec.rb +88 -0
  144. data/spec/spec/example/example_group_class_definition_spec.rb +6 -2
  145. data/spec/spec/example/example_group_factory_spec.rb +50 -10
  146. data/spec/spec/example/example_group_methods_spec.rb +210 -160
  147. data/spec/spec/example/example_group_spec.rb +44 -52
  148. data/spec/spec/example/example_matcher_spec.rb +6 -23
  149. data/spec/spec/example/example_methods_spec.rb +176 -54
  150. data/spec/spec/example/helper_method_spec.rb +24 -0
  151. data/spec/spec/example/pending_module_spec.rb +2 -8
  152. data/spec/spec/example/shared_example_group_spec.rb +56 -80
  153. data/spec/spec/expectations/extensions/object_spec.rb +0 -50
  154. data/spec/spec/expectations/wrap_expectation_spec.rb +30 -0
  155. data/spec/spec/interop/test/unit/spec_spec.rb +1 -5
  156. data/spec/spec/interop/test/unit/test_unit_spec_helper.rb +4 -0
  157. data/spec/spec/matchers/be_close_spec.rb +12 -10
  158. data/spec/spec/matchers/be_spec.rb +62 -7
  159. data/spec/spec/matchers/description_generation_spec.rb +19 -0
  160. data/spec/spec/matchers/eql_spec.rb +7 -6
  161. data/spec/spec/matchers/equal_spec.rb +7 -6
  162. data/spec/spec/matchers/handler_spec.rb +4 -43
  163. data/spec/spec/matchers/has_spec.rb +1 -1
  164. data/spec/spec/matchers/have_spec.rb +23 -18
  165. data/spec/spec/matchers/include_spec.rb +24 -0
  166. data/spec/spec/matchers/match_array_spec.rb +83 -0
  167. data/spec/spec/matchers/matcher_methods_spec.rb +1 -13
  168. data/spec/spec/matchers/raise_error_spec.rb +18 -0
  169. data/spec/spec/matchers/respond_to_spec.rb +71 -9
  170. data/spec/spec/matchers/throw_symbol_spec.rb +85 -43
  171. data/spec/spec/mocks/bug_report_11545_spec.rb +4 -5
  172. data/spec/spec/mocks/bug_report_496.rb +11 -9
  173. data/spec/spec/mocks/bug_report_600_spec.rb +22 -0
  174. data/spec/spec/mocks/hash_including_matcher_spec.rb +39 -2
  175. data/spec/spec/mocks/hash_not_including_matcher_spec.rb +67 -0
  176. data/spec/spec/mocks/mock_spec.rb +5 -6
  177. data/spec/spec/mocks/nil_expectation_warning_spec.rb +2 -2
  178. data/spec/spec/mocks/passing_mock_argument_constraints_spec.rb +18 -3
  179. data/spec/spec/mocks/stub_spec.rb +6 -0
  180. data/spec/spec/mocks/stubbed_message_expectations_spec.rb +14 -0
  181. data/spec/spec/runner/command_line_spec.rb +4 -4
  182. data/spec/spec/runner/configuration_spec.rb +301 -0
  183. data/spec/spec/runner/drb_command_line_spec.rb +4 -4
  184. data/spec/spec/runner/example_group_runner_spec.rb +33 -0
  185. data/spec/spec/runner/formatter/base_formatter_spec.rb +13 -102
  186. data/spec/spec/runner/formatter/base_text_formatter_spec.rb +23 -0
  187. data/spec/spec/runner/formatter/failing_example_groups_formatter_spec.rb +5 -5
  188. data/spec/spec/runner/formatter/failing_examples_formatter_spec.rb +3 -3
  189. data/spec/spec/runner/formatter/html_formatted-1.8.4.html +6 -6
  190. data/spec/spec/runner/formatter/html_formatted-1.8.5-jruby.html +9 -9
  191. data/spec/spec/runner/formatter/html_formatted-1.8.5.html +6 -6
  192. data/spec/spec/runner/formatter/html_formatted-1.8.6-jruby.html +10 -10
  193. data/spec/spec/runner/formatter/html_formatted-1.8.6.html +39 -30
  194. data/spec/spec/runner/formatter/html_formatted-1.8.7.html +379 -0
  195. data/spec/spec/runner/formatter/html_formatted-1.9.1.html +379 -0
  196. data/spec/spec/runner/formatter/html_formatter_spec.rb +14 -13
  197. data/spec/spec/runner/formatter/nested_text_formatter_spec.rb +5 -5
  198. data/spec/spec/runner/formatter/progress_bar_formatter_spec.rb +7 -17
  199. data/spec/spec/runner/formatter/spec_mate_formatter_spec.rb +18 -17
  200. data/spec/spec/runner/formatter/specdoc_formatter_spec.rb +5 -5
  201. data/spec/spec/runner/formatter/text_mate_formatted-1.8.4.html +6 -6
  202. data/spec/spec/runner/formatter/text_mate_formatted-1.8.6.html +33 -30
  203. data/spec/spec/runner/formatter/text_mate_formatted-1.8.7.html +373 -0
  204. data/spec/spec/runner/formatter/text_mate_formatted-1.9.1.html +373 -0
  205. data/spec/spec/runner/heckler_spec.rb +16 -9
  206. data/spec/spec/runner/option_parser_spec.rb +3 -18
  207. data/spec/spec/runner/options_spec.rb +27 -8
  208. data/spec/spec/runner/reporter_spec.rb +5 -5
  209. data/spec/spec/runner/resources/custom_example_group_runner.rb +14 -0
  210. data/spec/spec/runner/resources/utf8_encoded.rb +7 -0
  211. data/spec/spec/runner/spec_parser_spec.rb +85 -79
  212. data/spec/spec/spec_spec.rb +21 -0
  213. data/spec/spec_helper.rb +9 -1
  214. data/story_server/prototype/javascripts/prototype.js +1 -1
  215. metadata +119 -131
  216. data/examples/stories/adder.rb +0 -13
  217. data/examples/stories/addition +0 -34
  218. data/examples/stories/addition.rb +0 -9
  219. data/examples/stories/calculator.rb +0 -65
  220. data/examples/stories/game-of-life/.loadpath +0 -5
  221. data/examples/stories/game-of-life/README.txt +0 -21
  222. data/examples/stories/game-of-life/behaviour/everything.rb +0 -6
  223. data/examples/stories/game-of-life/behaviour/examples/examples.rb +0 -3
  224. data/examples/stories/game-of-life/behaviour/examples/game_behaviour.rb +0 -35
  225. data/examples/stories/game-of-life/behaviour/examples/grid_behaviour.rb +0 -66
  226. data/examples/stories/game-of-life/behaviour/stories/CellsWithLessThanTwoNeighboursDie.story +0 -21
  227. data/examples/stories/game-of-life/behaviour/stories/CellsWithMoreThanThreeNeighboursDie.story +0 -21
  228. data/examples/stories/game-of-life/behaviour/stories/EmptySpacesWithThreeNeighboursCreateACell.story +0 -42
  229. data/examples/stories/game-of-life/behaviour/stories/ICanCreateACell.story +0 -42
  230. data/examples/stories/game-of-life/behaviour/stories/ICanKillACell.story +0 -17
  231. data/examples/stories/game-of-life/behaviour/stories/TheGridWraps.story +0 -53
  232. data/examples/stories/game-of-life/behaviour/stories/create_a_cell.rb +0 -52
  233. data/examples/stories/game-of-life/behaviour/stories/helper.rb +0 -6
  234. data/examples/stories/game-of-life/behaviour/stories/kill_a_cell.rb +0 -26
  235. data/examples/stories/game-of-life/behaviour/stories/steps.rb +0 -5
  236. data/examples/stories/game-of-life/behaviour/stories/stories.rb +0 -3
  237. data/examples/stories/game-of-life/behaviour/stories/stories.txt +0 -22
  238. data/examples/stories/game-of-life/life.rb +0 -3
  239. data/examples/stories/game-of-life/life/game.rb +0 -23
  240. data/examples/stories/game-of-life/life/grid.rb +0 -43
  241. data/examples/stories/helper.rb +0 -9
  242. data/examples/stories/steps/addition_steps.rb +0 -18
  243. data/lib/spec/adapters.rb +0 -1
  244. data/lib/spec/adapters/ruby_engine.rb +0 -26
  245. data/lib/spec/adapters/ruby_engine/mri.rb +0 -8
  246. data/lib/spec/adapters/ruby_engine/rubinius.rb +0 -8
  247. data/lib/spec/extensions.rb +0 -4
  248. data/lib/spec/extensions/class.rb +0 -24
  249. data/lib/spec/extensions/metaclass.rb +0 -7
  250. data/lib/spec/extensions/object.rb +0 -6
  251. data/spec/spec/adapters/ruby_engine_spec.rb +0 -16
  252. data/spec/spec/example/configuration_spec.rb +0 -296
  253. data/spec/spec/example/example_runner_spec.rb +0 -194
  254. data/spec/spec/extensions/main_spec.rb +0 -71
  255. data/stories/all.rb +0 -5
  256. data/stories/configuration/before_blocks.story +0 -21
  257. data/stories/configuration/stories.rb +0 -7
  258. data/stories/example_groups/stories.rb +0 -7
  259. data/stories/helper.rb +0 -6
  260. data/stories/interop/stories.rb +0 -7
  261. data/stories/mock_framework_integration/stories.rb +0 -7
  262. data/stories/pending_stories/README +0 -3
  263. data/stories/resources/spec/before_blocks_example.rb +0 -32
  264. data/stories/resources/spec/spec_with_flexmock.rb +0 -18
  265. data/stories/resources/steps/running_rspec.rb +0 -50
  266. data/stories/resources/stories/failing_story.rb +0 -15
  267. data/stories/stories/multiline_steps.story +0 -23
  268. data/stories/stories/steps/multiline_steps.rb +0 -13
  269. data/stories/stories/stories.rb +0 -6
@@ -2,39 +2,60 @@ module Spec
2
2
  module Matchers
3
3
 
4
4
  class ThrowSymbol #:nodoc:
5
- def initialize(expected=nil)
6
- @expected = expected
7
- @actual = nil
5
+ def initialize(expected_symbol = nil, expected_arg=nil)
6
+ @expected_symbol = expected_symbol
7
+ @expected_arg = expected_arg
8
+ @caught_symbol = nil
8
9
  end
9
10
 
10
11
  def matches?(given_proc)
11
12
  begin
12
- given_proc.call
13
- rescue NameError => e
14
- raise e unless e.message =~ /uncaught throw/
15
- @actual = e.name.to_sym
13
+ if @expected_symbol.nil?
14
+ given_proc.call
15
+ else
16
+ @caught_arg = catch :proc_did_not_throw_anything do
17
+ catch @expected_symbol do
18
+ given_proc.call
19
+ throw :proc_did_not_throw_anything, :nothing_thrown
20
+ end
21
+ end
22
+ @caught_symbol = @expected_symbol unless @caught_arg == :nothing_thrown
23
+ end
24
+
25
+ # Ruby 1.8 uses NameError with `symbol'
26
+ # Ruby 1.9 uses ArgumentError with :symbol
27
+ rescue NameError, ArgumentError => e
28
+ raise e unless e.message =~ /uncaught throw (`|\:)([a-zA-Z0-9_]*)(')?/
29
+ @caught_symbol = $2.to_sym
30
+
16
31
  ensure
17
- if @expected.nil?
18
- return @actual.nil? ? false : true
32
+ if @expected_symbol.nil?
33
+ return !@caught_symbol.nil?
19
34
  else
20
- return @actual == @expected
35
+ if @expected_arg.nil?
36
+ return @caught_symbol == @expected_symbol
37
+ else
38
+ # puts [@caught_symbol, @expected_symbol].inspect
39
+ # puts [@caught_arg, @expected_arg].inspect
40
+ return @caught_symbol == @expected_symbol && @caught_arg == @expected_arg
41
+ end
21
42
  end
22
43
  end
23
44
  end
24
45
 
25
46
  def failure_message
26
- if @actual
27
- "expected #{expected}, got #{@actual.inspect}"
47
+ if @caught_symbol
48
+ "expected #{expected}, got #{@caught_symbol.inspect}"
28
49
  else
29
50
  "expected #{expected} but nothing was thrown"
30
51
  end
31
52
  end
32
53
 
33
54
  def negative_failure_message
34
- if @expected
55
+ if @expected_symbol
35
56
  "expected #{expected} not to be thrown"
36
57
  else
37
- "expected no Symbol, got :#{@actual}"
58
+ "expected no Symbol, got :#{@caught_symbol}"
38
59
  end
39
60
  end
40
61
 
@@ -45,7 +66,11 @@ module Spec
45
66
  private
46
67
 
47
68
  def expected
48
- @expected.nil? ? "a Symbol" : @expected.inspect
69
+ @expected_symbol.nil? ? "a Symbol" : "#{@expected_symbol.inspect}#{args}"
70
+ end
71
+
72
+ def args
73
+ @expected_arg.nil? ? "" : " with #{@expected_arg.inspect}"
49
74
  end
50
75
 
51
76
  end
@@ -53,20 +78,27 @@ module Spec
53
78
  # :call-seq:
54
79
  # should throw_symbol()
55
80
  # should throw_symbol(:sym)
81
+ # should throw_symbol(:sym, arg)
56
82
  # should_not throw_symbol()
57
83
  # should_not throw_symbol(:sym)
58
- #
59
- # Given a Symbol argument, matches if the given proc throws the specified Symbol.
84
+ # should_not throw_symbol(:sym, arg)
60
85
  #
61
86
  # Given no argument, matches if a proc throws any Symbol.
62
87
  #
88
+ # Given a Symbol, matches if the given proc throws the specified Symbol.
89
+ #
90
+ # Given a Symbol and an arg, matches if the given proc throws the
91
+ # specified Symbol with the specified arg.
92
+ #
63
93
  # == Examples
64
94
  #
65
95
  # lambda { do_something_risky }.should throw_symbol
66
96
  # lambda { do_something_risky }.should throw_symbol(:that_was_risky)
97
+ # lambda { do_something_risky }.should throw_symbol(:that_was_risky, culprit)
67
98
  #
68
99
  # lambda { do_something_risky }.should_not throw_symbol
69
100
  # lambda { do_something_risky }.should_not throw_symbol(:that_was_risky)
101
+ # lambda { do_something_risky }.should_not throw_symbol(:that_was_risky, culprit)
70
102
  def throw_symbol(sym=nil)
71
103
  Matchers::ThrowSymbol.new(sym)
72
104
  end
@@ -0,0 +1,55 @@
1
+ module Spec
2
+ module Matchers
3
+ # wraps an expectation in a block that will return true if the
4
+ # expectation passes and false if it fails (without bubbling up
5
+ # the failure).
6
+ #
7
+ # This is intended to be used in the context of a simple matcher,
8
+ # and is especially useful for wrapping multiple expectations or
9
+ # one or more assertions from test/unit extensions when running
10
+ # with test/unit.
11
+ #
12
+ # == Examples
13
+ #
14
+ # def eat_cheese(cheese)
15
+ # simple_matcher do |mouse, matcher|
16
+ # matcher.failure_message = "expected #{mouse} to eat cheese"
17
+ # wrap_expectation do |matcher|
18
+ # assert_eats_cheese(mouse)
19
+ # end
20
+ # end
21
+ # end
22
+ #
23
+ # describe Mouse do
24
+ # it "eats cheese" do
25
+ # Mouse.new.should eat_cheese
26
+ # end
27
+ # end
28
+ #
29
+ # You might be wondering "why would I do this if I could just say"
30
+ # assert_eats_cheese?", a fair question, indeed. You might prefer
31
+ # to replace the word assert with something more aligned with the
32
+ # rest of your code examples. You are using rspec, after all.
33
+ #
34
+ # The other benefit you get is that you can use the negative version
35
+ # of the matcher:
36
+ #
37
+ # describe Cat do
38
+ # it "does not eat cheese" do
39
+ # Cat.new.should_not eat_cheese
40
+ # end
41
+ # end
42
+ #
43
+ # So in the event there is no assert_does_not_eat_cheese available,
44
+ # you're all set!
45
+ def wrap_expectation(matcher, &block)
46
+ begin
47
+ block.call(matcher)
48
+ return true
49
+ rescue Exception => e
50
+ matcher.failure_message = e.message
51
+ return false
52
+ end
53
+ end
54
+ end
55
+ end
@@ -73,6 +73,25 @@ module Spec
73
73
  end
74
74
  end
75
75
 
76
+ class HashNotIncludingConstraint
77
+ def initialize(expected)
78
+ @expected = expected
79
+ end
80
+
81
+ def ==(actual)
82
+ @expected.each do | key, value |
83
+ return false if actual.has_key?(key) && value == actual[key]
84
+ end
85
+ true
86
+ rescue NoMethodError => ex
87
+ return false
88
+ end
89
+
90
+ def description
91
+ "hash_not_including(#{@expected.inspect.sub(/^\{/,"").sub(/\}$/,"")})"
92
+ end
93
+ end
94
+
76
95
  class DuckTypeConstraint
77
96
  def initialize(*methods_to_respond_to)
78
97
  @methods_to_respond_to = methods_to_respond_to
@@ -102,6 +121,26 @@ module Spec
102
121
  @given == expected
103
122
  end
104
123
  end
124
+
125
+ class InstanceOf
126
+ def initialize(klass)
127
+ @klass = klass
128
+ end
129
+
130
+ def ==(actual)
131
+ actual.instance_of?(@klass)
132
+ end
133
+ end
134
+
135
+ class KindOf
136
+ def initialize(klass)
137
+ @klass = klass
138
+ end
139
+
140
+ def ==(actual)
141
+ actual.kind_of?(@klass)
142
+ end
143
+ end
105
144
 
106
145
  # :call-seq:
107
146
  # object.should_receive(:message).with(any_args())
@@ -153,12 +192,45 @@ module Spec
153
192
  end
154
193
 
155
194
  # :call-seq:
156
- # object.should_receive(:message).with(hash_including(:this => that))
157
- #
158
- # Passes if the argument is a hash that includes the specified key/value
195
+ # object.should_receive(:message).with(hash_including(:key => val))
196
+ # object.should_receive(:message).with(hash_including(:key))
197
+ # object.should_receive(:message).with(hash_including(:key, :key2 => val2))
198
+ # Passes if the argument is a hash that includes the specified key(s) or key/value
159
199
  # pairs. If the hash includes other keys, it will still pass.
160
- def hash_including(expected={})
161
- HashIncludingConstraint.new(expected)
200
+ def hash_including(*args)
201
+ HashIncludingConstraint.new(anythingize_lonely_keys(*args))
202
+ end
203
+
204
+ # :call-seq:
205
+ # object.should_receive(:message).with(hash_not_including(:key => val))
206
+ # object.should_receive(:message).with(hash_not_including(:key))
207
+ # object.should_receive(:message).with(hash_not_including(:key, :key2 => :val2))
208
+ #
209
+ # Passes if the argument is a hash that doesn't include the specified key(s) or key/value
210
+ def hash_not_including(*args)
211
+ HashNotIncludingConstraint.new(anythingize_lonely_keys(*args))
212
+ end
213
+
214
+ # Passes if arg.instance_of?(klass)
215
+ def instance_of(klass)
216
+ InstanceOf.new(klass)
217
+ end
218
+
219
+ alias_method :an_instance_of, :instance_of
220
+
221
+ # Passes if arg.kind_of?(klass)
222
+ def kind_of(klass)
223
+ KindOf.new(klass)
224
+ end
225
+
226
+ alias_method :a_kind_of, :kind_of
227
+
228
+ private
229
+
230
+ def anythingize_lonely_keys(*args)
231
+ hash = args.last.class == Hash ? args.delete_at(-1) : {}
232
+ args.each { | arg | hash[arg] = anything }
233
+ hash
162
234
  end
163
235
  end
164
236
  end
@@ -32,6 +32,7 @@ module Spec
32
32
  child.expected_from = expected_from
33
33
  child.method_block = method_block
34
34
  child.expected_received_count = expected_received_count
35
+ child.clear_actual_received_count!
35
36
  new_gen = error_generator.clone
36
37
  new_gen.opts = opts
37
38
  child.error_generator = new_gen
@@ -39,11 +40,6 @@ module Spec
39
40
  child
40
41
  end
41
42
 
42
- def error_generator_opts=(opts={})
43
- @error_generator.opts = opts
44
- end
45
- protected :error_generator_opts=
46
-
47
43
  def expected_args
48
44
  @args_expectation.args
49
45
  end
@@ -92,7 +88,7 @@ module Spec
92
88
  @args_to_yield << args
93
89
  self
94
90
  end
95
-
91
+
96
92
  def matches(sym, args)
97
93
  @sym == sym and @args_expectation.args_match?(args)
98
94
  end
@@ -196,7 +192,7 @@ module Spec
196
192
  @sym == sym and not @args_expectation.args_match?(args)
197
193
  end
198
194
 
199
- def verify_messages_received
195
+ def verify_messages_received
200
196
  return if expected_messages_received? || failed_fast?
201
197
 
202
198
  generate_error
@@ -314,6 +310,10 @@ module Spec
314
310
  2
315
311
  end
316
312
  end
313
+
314
+ def clear_actual_received_count!
315
+ @actual_received_count = 0
316
+ end
317
317
 
318
318
  end
319
319
 
@@ -60,7 +60,7 @@ module Spec
60
60
  @stubs.unshift MessageExpectation.new(@error_generator, @expectation_ordering, expected_from, sym, nil, :any, opts)
61
61
  @stubs.first
62
62
  end
63
-
63
+
64
64
  def verify #:nodoc:
65
65
  verify_expectations
66
66
  ensure
@@ -91,14 +91,14 @@ module Spec
91
91
  if expectation = find_almost_matching_expectation(sym, *args)
92
92
  expectation.advise(args, block) unless expectation.expected_messages_received?
93
93
  end
94
- stub.invoke([], block)
94
+ stub.invoke(args, block)
95
95
  elsif expectation
96
96
  expectation.invoke(args, block)
97
97
  elsif expectation = find_almost_matching_expectation(sym, *args)
98
98
  expectation.advise(args, block) if null_object? unless expectation.expected_messages_received?
99
99
  raise_unexpected_message_args_error(expectation, *args) unless (has_negative_expectation?(sym) or null_object?)
100
100
  else
101
- @target.send :method_missing, sym, *args, &block
101
+ @target.__send__ :method_missing, sym, *args, &block
102
102
  end
103
103
  end
104
104
 
@@ -125,14 +125,16 @@ module Spec
125
125
 
126
126
  def define_expected_method(sym)
127
127
  visibility_string = "#{visibility(sym)} :#{sym}"
128
- if target_responds_to?(sym) && !target_metaclass.method_defined?(munge(sym))
129
- munged_sym = munge(sym)
130
- target_metaclass.instance_eval do
131
- alias_method munged_sym, sym if method_defined?(sym.to_s)
128
+ unless @proxied_methods.include?(sym)
129
+ if target_responds_to?(sym)
130
+ munged_sym = munge(sym)
131
+ target_metaclass.instance_eval do
132
+ alias_method munged_sym, sym if method_defined?(sym.to_s)
133
+ end
134
+ @proxied_methods << sym
132
135
  end
133
- @proxied_methods << sym
134
136
  end
135
-
137
+
136
138
  target_metaclass.class_eval(<<-EOF, __FILE__, __LINE__)
137
139
  def #{sym}(*args, &block)
138
140
  __mock_proxy.message_received :#{sym}, *args, &block
@@ -142,9 +144,9 @@ module Spec
142
144
  end
143
145
 
144
146
  def target_responds_to?(sym)
145
- return @target.send(munge(:respond_to?),sym) if @already_proxied_respond_to
147
+ return @target.__send__(munge(:respond_to?),sym) if @already_proxied_respond_to
146
148
  return @already_proxied_respond_to = true if sym == :respond_to?
147
- return @target.respond_to?(sym)
149
+ return @target.respond_to?(sym, true)
148
150
  end
149
151
 
150
152
  def visibility(sym)
@@ -193,7 +195,7 @@ module Spec
193
195
  alias_method sym, munged_sym
194
196
  undef_method munged_sym
195
197
  else
196
- undef_method sym
198
+ remove_method sym
197
199
  end
198
200
  end
199
201
  end
@@ -56,12 +56,10 @@ module Spec
56
56
  # end
57
57
  #
58
58
  class SpecTask < ::Rake::TaskLib
59
- class << self
60
- def attr_accessor(*names)
61
- super(*names)
62
- names.each do |name|
63
- module_eval "def #{name}() evaluate(@#{name}) end" # Allows use of procs
64
- end
59
+ def self.attr_accessor(*names)
60
+ super(*names)
61
+ names.each do |name|
62
+ module_eval "def #{name}() evaluate(@#{name}) end" # Allows use of procs
65
63
  end
66
64
  end
67
65
 
@@ -0,0 +1,9 @@
1
+ module Spec
2
+ module Ruby
3
+ class << self
4
+ def version
5
+ RUBY_VERSION
6
+ end
7
+ end
8
+ end
9
+ end
@@ -1,3 +1,4 @@
1
+ require 'spec/runner/configuration'
1
2
  require 'spec/runner/options'
2
3
  require 'spec/runner/option_parser'
3
4
  require 'spec/runner/example_group_runner'
@@ -9,166 +10,22 @@ require 'spec/runner/spec_parser'
9
10
  require 'spec/runner/class_and_arguments_parser'
10
11
 
11
12
  module Spec
12
- # == ExampleGroups and Examples
13
- #
14
- # Rather than expressing examples in classes, RSpec uses a custom DSLL (DSL light) to
15
- # describe groups of examples.
16
- #
17
- # A ExampleGroup is the equivalent of a fixture in xUnit-speak. It is a metaphor for the context
18
- # in which you will run your executable example - a set of known objects in a known starting state.
19
- # We begin be describing
20
- #
21
- # describe Account do
22
- #
23
- # before do
24
- # @account = Account.new
25
- # end
26
- #
27
- # it "should have a balance of $0" do
28
- # @account.balance.should == Money.new(0, :dollars)
29
- # end
30
- #
31
- # end
32
- #
33
- # We use the before block to set up the Example (given), and then the #it method to
34
- # hold the example code that expresses the event (when) and the expected outcome (then).
35
- #
36
- # == Helper Methods
37
- #
38
- # A primary goal of RSpec is to keep the examples clear. We therefore prefer
39
- # less indirection than you might see in xUnit examples and in well factored, DRY production code. We feel
40
- # that duplication is OK if removing it makes it harder to understand an example without
41
- # having to look elsewhere to understand its context.
42
- #
43
- # That said, RSpec does support some level of encapsulating common code in helper
44
- # methods that can exist within a context or within an included module.
45
- #
46
- # == Setup and Teardown
47
- #
48
- # You can use before and after within a Example. Both methods take an optional
49
- # scope argument so you can run the block before :each example or before :all examples
50
- #
51
- # describe "..." do
52
- # before :all do
53
- # ...
54
- # end
55
- #
56
- # before :each do
57
- # ...
58
- # end
59
- #
60
- # it "should do something" do
61
- # ...
62
- # end
63
- #
64
- # it "should do something else" do
65
- # ...
66
- # end
67
- #
68
- # after :each do
69
- # ...
70
- # end
71
- #
72
- # after :all do
73
- # ...
74
- # end
75
- #
76
- # end
77
- #
78
- # The <tt>before :each</tt> block will run before each of the examples, once for each example. Likewise,
79
- # the <tt>after :each</tt> block will run after each of the examples.
80
- #
81
- # It is also possible to specify a <tt>before :all</tt> and <tt>after :all</tt>
82
- # block that will run only once for each behaviour, respectively before the first <code>before :each</code>
83
- # and after the last <code>after :each</code>. The use of these is generally discouraged, because it
84
- # introduces dependencies between the examples. Still, it might prove useful for very expensive operations
85
- # if you know what you are doing.
86
- #
87
- # == Local helper methods
88
- #
89
- # You can include local helper methods by simply expressing them within a context:
90
- #
91
- # describe "..." do
92
- #
93
- # it "..." do
94
- # helper_method
95
- # end
96
- #
97
- # def helper_method
98
- # ...
99
- # end
100
- #
101
- # end
102
- #
103
- # == Included helper methods
104
- #
105
- # You can include helper methods in multiple contexts by expressing them within
106
- # a module, and then including that module in your context:
107
- #
108
- # module AccountExampleHelperMethods
109
- # def helper_method
110
- # ...
111
- # end
112
- # end
113
- #
114
- # describe "A new account" do
115
- # include AccountExampleHelperMethods
116
- # before do
117
- # @account = Account.new
118
- # end
119
- #
120
- # it "should have a balance of $0" do
121
- # helper_method
122
- # @account.balance.should eql(Money.new(0, :dollars))
123
- # end
124
- # end
125
- #
126
- # == Shared Example Groups
127
- #
128
- # You can define a shared Example Group, that may be used on other groups
129
- #
130
- # share_examples_for "All Editions" do
131
- # it "all editions behaviour" ...
132
- # end
133
- #
134
- # describe SmallEdition do
135
- # it_should_behave_like "All Editions"
136
- #
137
- # it "should do small edition stuff" do
138
- # ...
139
- # end
140
- # end
141
- #
142
- # You can also assign the shared group to a module and include that
143
- #
144
- # share_as :AllEditions do
145
- # it "should do all editions stuff" ...
146
- # end
147
- #
148
- # describe SmallEdition do
149
- # it_should_behave_like AllEditions
150
- #
151
- # it "should do small edition stuff" do
152
- # ...
153
- # end
154
- # end
155
- #
156
- # And, for those of you who prefer to use something more like Ruby, you
157
- # can just include the module directly
158
- #
159
- # describe SmallEdition do
160
- # include AllEditions
161
- #
162
- # it "should do small edition stuff" do
163
- # ...
164
- # end
165
- # end
166
13
  module Runner
14
+
15
+ class ExampleGroupCreationListener
16
+ def register_example_group(klass)
17
+ Spec::Runner.options.add_example_group klass
18
+ Spec::Runner.register_at_exit_hook
19
+ end
20
+ end
21
+
22
+ Spec::Example::ExampleGroupMethods.example_group_creation_listeners << ExampleGroupCreationListener.new
23
+
167
24
  class << self
168
25
  def configuration # :nodoc:
169
- @configuration ||= Spec::Example::Configuration.new
26
+ @configuration ||= Spec::Runner::Configuration.new
170
27
  end
171
-
28
+
172
29
  # Use this to configure various configurable aspects of
173
30
  # RSpec:
174
31
  #
@@ -177,19 +34,19 @@ module Spec
177
34
  # end
178
35
  #
179
36
  # The yielded <tt>configuration</tt> object is a
180
- # Spec::Example::Configuration instance. See its RDoc
37
+ # Spec::Runner::Configuration instance. See its RDoc
181
38
  # for details about what you can do with it.
182
39
  #
183
40
  def configure
184
41
  yield configuration
185
42
  end
186
-
43
+
187
44
  def register_at_exit_hook # :nodoc:
188
45
  unless @already_registered_at_exit_hook
189
46
  at_exit do
190
- unless $! || Spec.run? || Spec::Example::ExampleGroupFactory.all_registered?(options.example_groups)
191
- success = Spec.run
192
- exit success if Spec.exit?
47
+ unless $! || run? || Spec::Example::ExampleGroupFactory.registered_or_ancestor_of_registered?(options.example_groups)
48
+ success = run
49
+ exit success if exit?
193
50
  end
194
51
  end
195
52
  @already_registered_at_exit_hook = true
@@ -203,11 +60,29 @@ module Spec
203
60
  parser.options
204
61
  end
205
62
  end
206
-
63
+
207
64
  def use options
208
65
  @options = options
209
66
  end
210
67
 
68
+ def test_unit_defined?
69
+ Object.const_defined?(:Test) && Test.const_defined?(:Unit) && Test::Unit.respond_to?(:run?)
70
+ end
71
+
72
+ def run?
73
+ Runner.options.examples_run?
74
+ end
75
+
76
+ def run
77
+ return true if run?
78
+ options.run_examples
79
+ end
80
+
81
+ def exit?
82
+ !test_unit_defined? || Test::Unit.run?
83
+ end
211
84
  end
212
85
  end
213
86
  end
87
+
88
+ require 'spec/interop/test' if Spec::Runner::test_unit_defined?