rspec 1.1.11 → 1.1.12

Sign up to get free protection for your applications and to get access to all the features.
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?