rspec 0.8.2 → 0.9.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 (245) hide show
  1. data/CHANGES +125 -9
  2. data/EXAMPLES.rd +50 -27
  3. data/README +14 -1
  4. data/Rakefile +95 -42
  5. data/UPGRADE +31 -0
  6. data/bin/spec +0 -1
  7. data/bin/spec_translator +6 -0
  8. data/examples/auto_spec_description_example.rb +19 -0
  9. data/examples/{setup_teardown_example.rb → before_and_after_example.rb} +6 -6
  10. data/examples/behave_as_example.rb +45 -0
  11. data/examples/custom_expectation_matchers.rb +13 -12
  12. data/examples/dynamic_spec.rb +2 -2
  13. data/examples/file_accessor_spec.rb +2 -2
  14. data/examples/greeter_spec.rb +3 -3
  15. data/examples/helper_method_example.rb +2 -2
  16. data/examples/io_processor_spec.rb +4 -4
  17. data/examples/legacy_spec.rb +10 -0
  18. data/examples/mocking_example.rb +5 -5
  19. data/examples/multi_threaded_behaviour_runner.rb +25 -0
  20. data/examples/partial_mock_example.rb +4 -4
  21. data/examples/predicate_example.rb +4 -4
  22. data/examples/priority.txt +1 -0
  23. data/examples/shared_behaviours_example.rb +31 -0
  24. data/examples/stack_spec.rb +52 -69
  25. data/examples/stubbing_example.rb +10 -10
  26. data/examples/test_case_adapter_example.rb +26 -0
  27. data/examples/test_case_spec.rb +6 -6
  28. data/lib/spec.rb +9 -4
  29. data/lib/spec/dsl.rb +10 -0
  30. data/lib/spec/dsl/behaviour.rb +189 -0
  31. data/lib/spec/dsl/behaviour_callbacks.rb +43 -0
  32. data/lib/spec/dsl/behaviour_eval.rb +170 -0
  33. data/lib/spec/dsl/behaviour_factory.rb +32 -0
  34. data/lib/spec/dsl/composite_proc_builder.rb +28 -0
  35. data/lib/spec/dsl/configuration.rb +38 -0
  36. data/lib/spec/dsl/description.rb +34 -0
  37. data/lib/spec/dsl/example.rb +114 -0
  38. data/lib/spec/dsl/example_matcher.rb +28 -0
  39. data/lib/spec/{runner/spec_should_raise_handler.rb → dsl/example_should_raise_handler.rb} +4 -4
  40. data/lib/spec/expectations.rb +0 -3
  41. data/lib/spec/expectations/differs/default.rb +0 -1
  42. data/lib/spec/expectations/extensions.rb +0 -1
  43. data/lib/spec/expectations/extensions/object.rb +10 -53
  44. data/lib/spec/expectations/handler.rb +14 -18
  45. data/lib/spec/extensions.rb +1 -0
  46. data/lib/spec/extensions/object.rb +6 -0
  47. data/lib/spec/matchers.rb +19 -21
  48. data/lib/spec/matchers/be.rb +40 -11
  49. data/lib/spec/matchers/be_close.rb +2 -2
  50. data/lib/spec/matchers/operator_matcher.rb +52 -0
  51. data/lib/spec/matchers/respond_to.rb +21 -11
  52. data/lib/spec/mocks.rb +5 -28
  53. data/lib/spec/mocks/argument_constraint_matchers.rb +12 -0
  54. data/lib/spec/mocks/argument_expectation.rb +7 -4
  55. data/lib/spec/mocks/methods.rb +11 -16
  56. data/lib/spec/mocks/mock.rb +6 -3
  57. data/lib/spec/mocks/{mock_handler.rb → proxy.rb} +4 -7
  58. data/lib/spec/mocks/space.rb +28 -0
  59. data/lib/spec/mocks/spec_methods.rb +30 -0
  60. data/lib/spec/rake/spectask.rb +23 -21
  61. data/lib/spec/rake/verify_rcov.rb +1 -0
  62. data/lib/spec/runner.rb +88 -35
  63. data/lib/spec/runner/backtrace_tweaker.rb +2 -1
  64. data/lib/spec/runner/behaviour_runner.rb +102 -0
  65. data/lib/spec/runner/command_line.rb +5 -17
  66. data/lib/spec/runner/drb_command_line.rb +2 -2
  67. data/lib/spec/runner/extensions/kernel.rb +22 -9
  68. data/lib/spec/runner/formatter.rb +4 -0
  69. data/lib/spec/runner/formatter/base_formatter.rb +63 -0
  70. data/lib/spec/runner/formatter/base_text_formatter.rb +22 -52
  71. data/lib/spec/runner/formatter/failing_behaviours_formatter.rb +25 -0
  72. data/lib/spec/runner/formatter/failing_examples_formatter.rb +22 -0
  73. data/lib/spec/runner/formatter/html_formatter.rb +74 -29
  74. data/lib/spec/runner/formatter/progress_bar_formatter.rb +6 -8
  75. data/lib/spec/runner/formatter/rdoc_formatter.rb +6 -6
  76. data/lib/spec/runner/formatter/snippet_extractor.rb +52 -0
  77. data/lib/spec/runner/formatter/specdoc_formatter.rb +6 -6
  78. data/lib/spec/runner/heckle_runner.rb +8 -7
  79. data/lib/spec/runner/option_parser.rb +136 -55
  80. data/lib/spec/runner/options.rb +26 -0
  81. data/lib/spec/runner/reporter.rb +38 -31
  82. data/lib/spec/runner/spec_parser.rb +22 -13
  83. data/lib/spec/test_case_adapter.rb +10 -0
  84. data/lib/spec/translator.rb +103 -86
  85. data/lib/spec/version.rb +7 -15
  86. data/plugins/mock_frameworks/flexmock.rb +27 -0
  87. data/plugins/mock_frameworks/mocha.rb +21 -0
  88. data/plugins/mock_frameworks/rspec.rb +18 -0
  89. data/spec/spec/dsl/behaviour_eval_spec.rb +49 -0
  90. data/spec/spec/dsl/behaviour_factory_spec.rb +30 -0
  91. data/spec/spec/dsl/behaviour_spec.rb +508 -0
  92. data/spec/spec/dsl/composite_proc_builder_spec.rb +57 -0
  93. data/spec/spec/dsl/configuration_spec.rb +43 -0
  94. data/spec/spec/dsl/description_spec.rb +51 -0
  95. data/spec/spec/dsl/example_class_spec.rb +24 -0
  96. data/spec/spec/dsl/example_instance_spec.rb +140 -0
  97. data/spec/spec/dsl/example_should_raise_spec.rb +137 -0
  98. data/spec/spec/dsl/predicate_matcher_spec.rb +21 -0
  99. data/spec/spec/dsl/shared_behaviour_spec.rb +186 -0
  100. data/spec/spec/expectations/differs/default_spec.rb +12 -12
  101. data/spec/spec/expectations/extensions/object_spec.rb +10 -10
  102. data/spec/spec/expectations/fail_with_spec.rb +20 -20
  103. data/spec/spec/matchers/be_close_spec.rb +37 -31
  104. data/spec/spec/matchers/be_spec.rb +50 -41
  105. data/spec/spec/matchers/change_spec.rb +54 -54
  106. data/spec/spec/matchers/description_generation_spec.rb +43 -31
  107. data/spec/spec/matchers/eql_spec.rb +24 -37
  108. data/spec/spec/matchers/equal_spec.rb +24 -37
  109. data/spec/spec/matchers/exist_spec.rb +48 -0
  110. data/spec/spec/matchers/handler_spec.rb +36 -23
  111. data/spec/spec/matchers/has_spec.rb +8 -8
  112. data/spec/spec/matchers/have_spec.rb +38 -38
  113. data/spec/spec/matchers/include_spec.rb +6 -6
  114. data/spec/spec/matchers/match_spec.rb +8 -8
  115. data/spec/spec/matchers/matcher_methods_spec.rb +24 -31
  116. data/spec/spec/matchers/raise_error_spec.rb +34 -34
  117. data/spec/spec/matchers/respond_to_spec.rb +32 -8
  118. data/spec/spec/matchers/satisfy_spec.rb +6 -6
  119. data/spec/spec/matchers/should_===_spec.rb +38 -0
  120. data/spec/spec/matchers/should_==_spec.rb +37 -0
  121. data/spec/spec/matchers/should_=~_spec.rb +36 -0
  122. data/spec/spec/matchers/throw_symbol_spec.rb +47 -55
  123. data/spec/spec/mocks/any_number_of_times_spec.rb +16 -21
  124. data/spec/spec/mocks/argument_expectation_spec.rb +3 -3
  125. data/spec/spec/mocks/at_least_spec.rb +30 -30
  126. data/spec/spec/mocks/at_most_spec.rb +53 -57
  127. data/spec/spec/mocks/bug_report_10260_spec.rb +8 -0
  128. data/spec/spec/mocks/bug_report_7611_spec.rb +3 -3
  129. data/spec/spec/mocks/bug_report_7805_spec.rb +3 -3
  130. data/spec/spec/mocks/bug_report_8165_spec.rb +5 -5
  131. data/spec/spec/mocks/bug_report_8302_spec.rb +5 -5
  132. data/spec/spec/mocks/failing_mock_argument_constraints_spec.rb +26 -27
  133. data/spec/spec/mocks/mock_ordering_spec.rb +19 -15
  134. data/spec/spec/mocks/mock_space_spec.rb +54 -0
  135. data/spec/spec/mocks/mock_spec.rb +111 -141
  136. data/spec/spec/mocks/multiple_return_value_spec.rb +48 -48
  137. data/spec/spec/mocks/null_object_mock_spec.rb +10 -10
  138. data/spec/spec/mocks/once_counts_spec.rb +32 -35
  139. data/spec/spec/mocks/options_hash_spec.rb +12 -10
  140. data/spec/spec/mocks/partial_mock_spec.rb +15 -15
  141. data/spec/spec/mocks/partial_mock_using_mocks_directly_spec.rb +24 -22
  142. data/spec/spec/mocks/passing_mock_argument_constraints_spec.rb +19 -19
  143. data/spec/spec/mocks/precise_counts_spec.rb +28 -32
  144. data/spec/spec/mocks/record_messages_spec.rb +10 -10
  145. data/spec/spec/mocks/stub_spec.rb +45 -45
  146. data/spec/spec/mocks/twice_counts_spec.rb +21 -21
  147. data/spec/spec/package/bin_spec_spec.rb +12 -0
  148. data/spec/spec/runner/behaviour_runner_spec.rb +114 -0
  149. data/spec/spec/runner/command_line_spec.rb +8 -8
  150. data/spec/spec/runner/context_matching_spec.rb +14 -15
  151. data/spec/spec/runner/drb_command_line_spec.rb +12 -12
  152. data/spec/spec/runner/execution_context_spec.rb +8 -29
  153. data/spec/spec/runner/extensions/kernel_spec.rb +36 -0
  154. data/spec/spec/runner/formatter/failing_behaviours_formatter_spec.rb +27 -0
  155. data/spec/spec/runner/formatter/failing_examples_formatter_spec.rb +28 -0
  156. data/spec/spec/runner/formatter/html_formatter_spec.rb +9 -8
  157. data/spec/spec/runner/formatter/progress_bar_formatter_dry_run_spec.rb +6 -6
  158. data/spec/spec/runner/formatter/progress_bar_formatter_failure_dump_spec.rb +10 -10
  159. data/spec/spec/runner/formatter/progress_bar_formatter_spec.rb +22 -27
  160. data/spec/spec/runner/formatter/rdoc_formatter_dry_run_spec.rb +6 -5
  161. data/spec/spec/runner/formatter/rdoc_formatter_spec.rb +17 -17
  162. data/spec/spec/runner/formatter/snippet_extractor_spec.rb +11 -0
  163. data/spec/spec/runner/formatter/specdoc_formatter_dry_run_spec.rb +6 -6
  164. data/spec/spec/runner/formatter/specdoc_formatter_spec.rb +17 -17
  165. data/spec/spec/runner/heckle_runner_spec.rb +21 -21
  166. data/spec/spec/runner/heckler_spec.rb +5 -5
  167. data/spec/spec/runner/noisy_backtrace_tweaker_spec.rb +12 -12
  168. data/spec/spec/runner/object_ext_spec.rb +3 -3
  169. data/spec/spec/runner/option_parser_spec.rb +171 -102
  170. data/spec/spec/runner/quiet_backtrace_tweaker_spec.rb +21 -12
  171. data/spec/spec/runner/reporter_spec.rb +106 -97
  172. data/spec/spec/runner/spec_matcher_spec.rb +46 -51
  173. data/spec/spec/runner/spec_parser_spec.rb +72 -16
  174. data/spec/spec/spec_classes.rb +12 -3
  175. data/spec/spec/translator_spec.rb +165 -36
  176. metadata +66 -76
  177. data/RELEASE-PLAN +0 -117
  178. data/examples/auto_spec_name_generation_example.rb +0 -18
  179. data/lib/spec/callback.rb +0 -11
  180. data/lib/spec/callback/callback_container.rb +0 -60
  181. data/lib/spec/callback/extensions/module.rb +0 -24
  182. data/lib/spec/callback/extensions/object.rb +0 -37
  183. data/lib/spec/deprecated.rb +0 -3
  184. data/lib/spec/expectations/extensions/proc.rb +0 -57
  185. data/lib/spec/expectations/should.rb +0 -5
  186. data/lib/spec/expectations/should/base.rb +0 -64
  187. data/lib/spec/expectations/should/change.rb +0 -69
  188. data/lib/spec/expectations/should/have.rb +0 -128
  189. data/lib/spec/expectations/should/not.rb +0 -74
  190. data/lib/spec/expectations/should/should.rb +0 -81
  191. data/lib/spec/expectations/sugar.rb +0 -47
  192. data/lib/spec/runner/context.rb +0 -154
  193. data/lib/spec/runner/context_eval.rb +0 -142
  194. data/lib/spec/runner/context_runner.rb +0 -55
  195. data/lib/spec/runner/execution_context.rb +0 -17
  196. data/lib/spec/runner/spec_matcher.rb +0 -25
  197. data/lib/spec/runner/specification.rb +0 -114
  198. data/spec/spec/callback/callback_container_spec.rb +0 -27
  199. data/spec/spec/callback/module_spec.rb +0 -37
  200. data/spec/spec/callback/object_spec.rb +0 -90
  201. data/spec/spec/callback/object_with_class_callback_spec.rb +0 -19
  202. data/spec/spec/expectations/should/should_==_spec.rb +0 -19
  203. data/spec/spec/expectations/should/should_=~_spec.rb +0 -13
  204. data/spec/spec/expectations/should/should_be_a_kind_of_spec.rb +0 -21
  205. data/spec/spec/expectations/should/should_be_an_instance_of_spec.rb +0 -30
  206. data/spec/spec/expectations/should/should_be_arbitrary_predicate_spec.rb +0 -81
  207. data/spec/spec/expectations/should/should_be_close_spec.rb +0 -18
  208. data/spec/spec/expectations/should/should_be_comparison_operator_spec.rb +0 -44
  209. data/spec/spec/expectations/should/should_be_false_spec.rb +0 -39
  210. data/spec/spec/expectations/should/should_be_spec.rb +0 -11
  211. data/spec/spec/expectations/should/should_be_true_spec.rb +0 -27
  212. data/spec/spec/expectations/should/should_change_spec.rb +0 -184
  213. data/spec/spec/expectations/should/should_eql_spec.rb +0 -11
  214. data/spec/spec/expectations/should/should_equal_spec.rb +0 -11
  215. data/spec/spec/expectations/should/should_have_at_least_spec.rb +0 -53
  216. data/spec/spec/expectations/should/should_have_at_most_spec.rb +0 -45
  217. data/spec/spec/expectations/should/should_have_key_spec.rb +0 -21
  218. data/spec/spec/expectations/should/should_have_spec.rb +0 -64
  219. data/spec/spec/expectations/should/should_include_spec.rb +0 -59
  220. data/spec/spec/expectations/should/should_match_spec.rb +0 -25
  221. data/spec/spec/expectations/should/should_not_==_spec.rb +0 -15
  222. data/spec/spec/expectations/should/should_not_be_a_kind_of_spec.rb +0 -21
  223. data/spec/spec/expectations/should/should_not_be_an_instance_of_spec.rb +0 -11
  224. data/spec/spec/expectations/should/should_not_be_arbitrary_predicate_spec.rb +0 -68
  225. data/spec/spec/expectations/should/should_not_be_spec.rb +0 -11
  226. data/spec/spec/expectations/should/should_not_change_spec.rb +0 -24
  227. data/spec/spec/expectations/should/should_not_eql_spec.rb +0 -11
  228. data/spec/spec/expectations/should/should_not_equal_spec.rb +0 -11
  229. data/spec/spec/expectations/should/should_not_have_key_spec.rb +0 -15
  230. data/spec/spec/expectations/should/should_not_include_spec.rb +0 -58
  231. data/spec/spec/expectations/should/should_not_match_spec.rb +0 -11
  232. data/spec/spec/expectations/should/should_not_raise_spec.rb +0 -75
  233. data/spec/spec/expectations/should/should_not_respond_to_spec.rb +0 -15
  234. data/spec/spec/expectations/should/should_not_throw_spec.rb +0 -35
  235. data/spec/spec/expectations/should/should_raise_spec.rb +0 -66
  236. data/spec/spec/expectations/should/should_respond_to_spec.rb +0 -15
  237. data/spec/spec/expectations/should/should_satisfy_spec.rb +0 -35
  238. data/spec/spec/expectations/should/should_throw_spec.rb +0 -27
  239. data/spec/spec/runner/context_runner_spec.rb +0 -100
  240. data/spec/spec/runner/context_spec.rb +0 -405
  241. data/spec/spec/runner/kernel_ext_spec.rb +0 -16
  242. data/spec/spec/runner/spec_name_generation_spec.rb +0 -102
  243. data/spec/spec/runner/specification_class_spec.rb +0 -72
  244. data/spec/spec/runner/specification_instance_spec.rb +0 -160
  245. data/spec/spec/runner/specification_should_raise_spec.rb +0 -136
@@ -1,7 +1,7 @@
1
1
  require File.dirname(__FILE__) + '/spec_helper'
2
2
 
3
- context "A consumer of a stub" do
4
- specify "should be able to stub methods on any Object" do
3
+ describe "A consumer of a stub" do
4
+ it "should be able to stub methods on any Object" do
5
5
  obj = Object.new
6
6
  obj.stub!(:foobar).and_return {:return_value}
7
7
  obj.foobar.should equal(:return_value)
@@ -14,17 +14,17 @@ class StubbableClass
14
14
  end
15
15
  end
16
16
 
17
- context "A stubbed method on a class" do
18
- specify "should return the stubbed value" do
17
+ describe "A stubbed method on a class" do
18
+ it "should return the stubbed value" do
19
19
  StubbableClass.stub!(:find).and_return(:stub_return)
20
20
  StubbableClass.find(1).should equal(:stub_return)
21
21
  end
22
22
 
23
- specify "should revert to the original method after each spec" do
23
+ it "should revert to the original method after each spec" do
24
24
  StubbableClass.find(1).should equal(:original_return)
25
25
  end
26
26
 
27
- specify "can stub! and mock the same message" do
27
+ it "can stub! and mock the same message" do
28
28
  StubbableClass.stub!(:msg).and_return(:stub_value)
29
29
  StubbableClass.should_receive(:msg).with(:arg).and_return(:mock_value)
30
30
 
@@ -37,14 +37,14 @@ context "A stubbed method on a class" do
37
37
  end
38
38
  end
39
39
 
40
- context "A mock" do
41
- specify "can stub!" do
40
+ describe "A mock" do
41
+ it "can stub!" do
42
42
  mock = mock("stubbing mock")
43
43
  mock.stub!(:msg).and_return(:value)
44
44
  (1..10).each {mock.msg.should equal(:value)}
45
45
  end
46
46
 
47
- specify "can stub! and mock" do
47
+ it "can stub! and mock" do
48
48
  mock = mock("stubbing mock")
49
49
  mock.stub!(:stub_message).and_return(:stub_value)
50
50
  mock.should_receive(:mock_message).once.and_return(:mock_value)
@@ -53,7 +53,7 @@ context "A mock" do
53
53
  (1..10).each {mock.stub_message.should equal(:stub_value)}
54
54
  end
55
55
 
56
- specify "can stub! and mock the same message" do
56
+ it "can stub! and mock the same message" do
57
57
  mock = mock("stubbing mock")
58
58
  mock.stub!(:msg).and_return(:stub_value)
59
59
  mock.should_receive(:msg).with(:arg).and_return(:mock_value)
@@ -0,0 +1,26 @@
1
+ #This is an example of using RSpec's expectations in test/unit.
2
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), "..", "lib")
3
+
4
+ require 'test/unit'
5
+ require 'spec/test_case_adapter'
6
+
7
+ class IntegratingRSpecExpectationsIntoTestCaseTest < Test::Unit::TestCase
8
+
9
+ def test_should_support_rspecs_equality_expectations
10
+ 5.should == 5
11
+ end
12
+
13
+ def test_should_support_rspecs_comparison_expectations
14
+ 5.should be > 4
15
+ end
16
+
17
+ class Band
18
+ def players
19
+ ["John", "Paul", "George", "Ringo"]
20
+ end
21
+ end
22
+
23
+ def test_should_support_rspecs_collection_expectations
24
+ Band.new.should have(4).players
25
+ end
26
+ end
@@ -32,32 +32,32 @@ module RandomHelperModule
32
32
  end
33
33
  end
34
34
 
35
- context "RSpec should integrate with Test::Unit::TestCase" do
35
+ describe "RSpec should integrate with Test::Unit::TestCase" do
36
36
  inherit RSpecIntegrationTest
37
37
  include RandomHelperModule
38
38
 
39
39
  fixtures :some_table
40
40
 
41
- setup do
41
+ before(:each) do
42
42
  @rspec_setup_called = true
43
43
  end
44
44
 
45
- specify "TestCase#setup should be called." do
45
+ it "TestCase#setup should be called." do
46
46
  @test_case_setup_called.should be_true
47
47
  @rspec_setup_called.should be_true
48
48
  end
49
49
 
50
- specify "RSpec should be able to access TestCase methods" do
50
+ it "RSpec should be able to access TestCase methods" do
51
51
  helper_method
52
52
  @helper_method_called.should be_true
53
53
  end
54
54
 
55
- specify "RSpec should be able to accept included modules" do
55
+ it "RSpec should be able to accept included modules" do
56
56
  random_task
57
57
  @random_task_called.should be_true
58
58
  end
59
59
 
60
- teardown do
60
+ after(:each) do
61
61
  RSpecIntegrationTest.verify_class_method
62
62
  end
63
63
  end
@@ -1,8 +1,13 @@
1
- require 'spec/deprecated'
1
+ require 'spec/extensions'
2
2
  require 'spec/version'
3
- require 'spec/callback'
4
3
  require 'spec/matchers'
5
4
  require 'spec/expectations'
6
- require 'spec/mocks'
7
- require 'spec/runner'
8
5
  require 'spec/translator'
6
+ require 'spec/dsl'
7
+ require 'spec/runner'
8
+
9
+ class Object
10
+ def metaclass
11
+ class << self; self; end
12
+ end
13
+ end
@@ -0,0 +1,10 @@
1
+ require 'spec/dsl/description'
2
+ require 'spec/dsl/configuration'
3
+ require 'spec/dsl/behaviour_callbacks'
4
+ require 'spec/dsl/behaviour'
5
+ require 'spec/dsl/behaviour_eval'
6
+ require 'spec/dsl/composite_proc_builder'
7
+ require 'spec/dsl/example'
8
+ require 'spec/dsl/example_matcher'
9
+ require 'spec/dsl/example_should_raise_handler'
10
+ require 'spec/dsl/behaviour_factory'
@@ -0,0 +1,189 @@
1
+ module Spec
2
+ module DSL
3
+ class EvalModule < Module; end
4
+ class Behaviour
5
+ extend BehaviourCallbacks
6
+
7
+ class << self
8
+ def add_shared_behaviour(behaviour)
9
+ raise ArgumentError.new("Shared Behaviour '#{behaviour.description}' already exists") if find_shared_behaviour(behaviour.description)
10
+ shared_behaviours << behaviour
11
+ end
12
+
13
+ def find_shared_behaviour(behaviour_description)
14
+ shared_behaviours.find { |b| b.description == behaviour_description }
15
+ end
16
+
17
+ def shared_behaviours
18
+ # TODO - this needs to be global, or at least accessible from
19
+ # from subclasses of Behaviour in a centralized place. I'm not loving
20
+ # this as a solution, but it works for now.
21
+ $shared_behaviours ||= []
22
+ end
23
+ end
24
+
25
+ def initialize(*args, &behaviour_block)
26
+ init_description(*args)
27
+ init_eval_module
28
+ before_eval
29
+ eval_behaviour(&behaviour_block)
30
+ end
31
+
32
+ private
33
+
34
+ def init_description(*args)
35
+ @description = Description.new(*args)
36
+ end
37
+
38
+ def init_eval_module
39
+ @eval_module = EvalModule.new
40
+ @eval_module.extend BehaviourEval::ModuleMethods
41
+ @eval_module.include BehaviourEval::InstanceMethods
42
+ @eval_module.behaviour = self
43
+ @eval_module.description = @description
44
+ end
45
+
46
+ def eval_behaviour(&behaviour_block)
47
+ @eval_module.class_eval(&behaviour_block)
48
+ end
49
+
50
+ protected
51
+
52
+ def before_eval
53
+ end
54
+
55
+ public
56
+
57
+ def run(reporter, dry_run=false, reverse=false, timeout=nil)
58
+ return if shared?
59
+ reporter.add_behaviour(description)
60
+ prepare_execution_context_class
61
+ errors = run_before_all(reporter, dry_run)
62
+
63
+ specs = reverse ? examples.reverse : examples
64
+ example_execution_context = nil
65
+
66
+ if errors.empty?
67
+ specs.each do |example|
68
+ example_execution_context = execution_context(example)
69
+ example_execution_context.copy_instance_variables_from(@before_and_after_all_context_instance) unless before_all_proc.nil?
70
+ example.run(reporter, before_each_proc, after_each_proc, dry_run, example_execution_context, timeout)
71
+ end
72
+ end
73
+
74
+ @before_and_after_all_context_instance.copy_instance_variables_from(example_execution_context) unless after_all_proc.nil?
75
+ run_after_all(reporter, dry_run)
76
+ end
77
+
78
+ def number_of_examples
79
+ examples.length
80
+ end
81
+
82
+ def matches?(specified_examples)
83
+ matcher ||= ExampleMatcher.new(description)
84
+
85
+ examples.each do |example|
86
+ return true if example.matches?(matcher, specified_examples)
87
+ end
88
+ return false
89
+ end
90
+
91
+ def shared?
92
+ @description[:shared]
93
+ end
94
+
95
+ def retain_examples_matching!(specified_examples)
96
+ return if specified_examples.index(description)
97
+ matcher = ExampleMatcher.new(description)
98
+ examples.reject! do |example|
99
+ !example.matches?(matcher, specified_examples)
100
+ end
101
+ end
102
+
103
+ def methods
104
+ my_methods = super
105
+ my_methods |= @eval_module.methods
106
+ my_methods
107
+ end
108
+
109
+ protected
110
+
111
+ # Messages that this class does not understand
112
+ # are passed directly to the @eval_module.
113
+ def method_missing(sym, *args, &block)
114
+ @eval_module.send(sym, *args, &block)
115
+ end
116
+
117
+ def prepare_execution_context_class
118
+ plugin_mock_framework
119
+ weave_in_included_modules
120
+ define_predicate_matchers #this is in behaviour_eval
121
+ execution_context_class
122
+ end
123
+
124
+ def weave_in_included_modules
125
+ mods = included_modules
126
+ eval_module = @eval_module
127
+ execution_context_class.class_eval do
128
+ include eval_module
129
+ Spec::Runner.configuration.included_modules.each do |mod|
130
+ include mod
131
+ end
132
+ mods.each do |mod|
133
+ include mod
134
+ end
135
+ end
136
+ end
137
+
138
+ def execution_context(example)
139
+ execution_context_class.new(example)
140
+ end
141
+
142
+ def run_before_all(reporter, dry_run)
143
+ errors = []
144
+ unless dry_run
145
+ begin
146
+ @before_and_after_all_context_instance = execution_context(nil)
147
+ @before_and_after_all_context_instance.instance_eval(&before_all_proc)
148
+ rescue => e
149
+ errors << e
150
+ location = "before(:all)"
151
+ reporter.example_finished(location, e, location) if reporter
152
+ end
153
+ end
154
+ errors
155
+ end
156
+
157
+ def run_after_all(reporter, dry_run)
158
+ unless dry_run
159
+ begin
160
+ @before_and_after_all_context_instance ||= execution_context(nil)
161
+ @before_and_after_all_context_instance.instance_eval(&after_all_proc)
162
+ rescue => e
163
+ location = "after(:all)"
164
+ reporter.example_finished(location, e, location) if reporter
165
+ end
166
+ end
167
+ end
168
+
169
+ def plugin_mock_framework
170
+ case mock_framework = Spec::Runner.configuration.mock_framework
171
+ when Module
172
+ include mock_framework
173
+ else
174
+ require Spec::Runner.configuration.mock_framework
175
+ include Spec::Plugins::MockFramework
176
+ end
177
+ end
178
+
179
+ def description
180
+ @description.to_s
181
+ end
182
+
183
+ def described_type
184
+ @description.described_type
185
+ end
186
+
187
+ end
188
+ end
189
+ end
@@ -0,0 +1,43 @@
1
+ module Spec
2
+ module DSL
3
+ module BehaviourCallbacks
4
+ def before(scope=:each, &block)
5
+ case scope
6
+ when :each; before_each_parts << block
7
+ when :all; before_all_parts << block
8
+ end
9
+ end
10
+
11
+ def after(scope=:each, &block)
12
+ case scope
13
+ when :each; after_each_parts.unshift(block)
14
+ when :all; after_all_parts.unshift(block)
15
+ end
16
+ end
17
+
18
+ def setup(&block)
19
+ before(:each, &block)
20
+ end
21
+
22
+ def teardown(&block)
23
+ after(:each, &block)
24
+ end
25
+
26
+ def before_all_parts
27
+ @before_all_parts ||= []
28
+ end
29
+
30
+ def after_all_parts
31
+ @after_all_parts ||= []
32
+ end
33
+
34
+ def before_each_parts
35
+ @before_each_parts ||= []
36
+ end
37
+
38
+ def after_each_parts
39
+ @after_each_parts ||= []
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,170 @@
1
+ module Spec
2
+ module DSL
3
+ module BehaviourEval
4
+ module ModuleMethods
5
+ include BehaviourCallbacks
6
+
7
+ attr_writer :behaviour
8
+ attr_accessor :description
9
+
10
+ def inherit(klass)
11
+ raise ArgumentError.new("Shared behaviours cannot inherit from classes") if @behaviour.shared?
12
+ @behaviour_superclass = klass
13
+ derive_execution_context_class_from_behaviour_superclass
14
+ end
15
+
16
+ def include(mod)
17
+ included_modules << mod
18
+ mod.send :included, self
19
+ end
20
+
21
+ def it_should_behave_like(behaviour_description)
22
+ behaviour = @behaviour.class.find_shared_behaviour(behaviour_description)
23
+ if behaviour.nil?
24
+ raise RuntimeError.new("Shared Behaviour '#{behaviour_description}' can not be found")
25
+ end
26
+ behaviour.copy_to(self)
27
+ end
28
+
29
+ def copy_to(eval_module)
30
+ examples.each { |e| eval_module.examples << e; }
31
+ before_each_parts.each { |p| eval_module.before_each_parts << p }
32
+ after_each_parts.each { |p| eval_module.after_each_parts << p }
33
+ before_all_parts.each { |p| eval_module.before_all_parts << p }
34
+ after_all_parts.each { |p| eval_module.after_all_parts << p }
35
+ included_modules.each { |m| eval_module.included_modules << m }
36
+ end
37
+
38
+ # :call-seq:
39
+ # predicate_matchers[method_on_object] = matcher_name
40
+ #
41
+ # Dynamically generates a custom matcher that will match
42
+ # a predicate on your class.
43
+ #
44
+ # == Example
45
+ #
46
+ # class Fish
47
+ # def can_swim?
48
+ # true
49
+ # end
50
+ # end
51
+ #
52
+ # describe Fish do
53
+ # predicate_matchers[:can_swim?] = :swim
54
+ # it "should swim" do
55
+ # Fish.new.should swim
56
+ # end
57
+ # end
58
+ def predicate_matchers
59
+ @predicate_matchers ||= {:exist? => :exist}
60
+ end
61
+
62
+ def define_predicate_matchers(hash=nil) # :nodoc:
63
+ if hash.nil?
64
+ define_predicate_matchers(predicate_matchers)
65
+ define_predicate_matchers(Spec::Runner.configuration.predicate_matchers)
66
+ else
67
+ hash.each_pair do |method_on_object, matcher_method|
68
+ define_method matcher_method do |*args|
69
+ eval("be_#{method_on_object.to_s.gsub('?','')}(*args)")
70
+ end
71
+ end
72
+ end
73
+ end
74
+
75
+ def it(description=:__generate_description, opts={}, &block)
76
+ examples << Example.new(description, opts, &block)
77
+ end
78
+
79
+ def specify(description, opts={}, &block)
80
+ it(description, opts, &block)
81
+ end
82
+
83
+ def methods
84
+ my_methods = super
85
+ my_methods |= behaviour_superclass.methods
86
+ my_methods
87
+ end
88
+
89
+ protected
90
+
91
+ def method_missing(method_name, *args)
92
+ if behaviour_superclass.respond_to?(method_name)
93
+ return execution_context_class.send(method_name, *args)
94
+ end
95
+ super
96
+ end
97
+
98
+ def before_all_proc(&error_handler)
99
+ parts = []
100
+ parts.push(*Behaviour.before_all_parts)
101
+ parts.push(*before_all_parts)
102
+ CompositeProcBuilder.new(parts).proc(&error_handler)
103
+ end
104
+
105
+ def after_all_proc(&error_handler)
106
+ parts = []
107
+ parts.push(*after_all_parts)
108
+ parts.push(*Behaviour.after_all_parts)
109
+ CompositeProcBuilder.new(parts).proc(&error_handler)
110
+ end
111
+
112
+ def before_each_proc(&error_handler)
113
+ parts = []
114
+ add_superclass_method(parts, 'setup')
115
+ parts.push(*Behaviour.before_each_parts)
116
+ parts.push(*before_each_parts)
117
+ CompositeProcBuilder.new(parts).proc(&error_handler)
118
+ end
119
+
120
+ def after_each_proc(&error_handler)
121
+ parts = []
122
+ parts.push(*after_each_parts)
123
+ add_superclass_method(parts, 'teardown')
124
+ parts.push(*Behaviour.after_each_parts)
125
+ CompositeProcBuilder.new(parts).proc(&error_handler)
126
+ end
127
+
128
+ def add_superclass_method(parts, method_name)
129
+ parts << behaviour_superclass.instance_method(method_name) if behaviour_superclass.instance_methods.include?(method_name)
130
+ end
131
+
132
+ private
133
+
134
+ def execution_context_class
135
+ @execution_context_class ||= derive_execution_context_class_from_behaviour_superclass
136
+ end
137
+
138
+ def derive_execution_context_class_from_behaviour_superclass
139
+ @execution_context_class = Class.new(behaviour_superclass)
140
+ end
141
+
142
+ def behaviour_superclass
143
+ @behaviour_superclass ||= Object
144
+ end
145
+
146
+ protected
147
+ def included_modules
148
+ @included_modules ||= [::Spec::Matchers]
149
+ end
150
+
151
+ def examples
152
+ @examples ||= []
153
+ end
154
+ end
155
+
156
+ module InstanceMethods
157
+ def initialize(*args, &block) #:nodoc:
158
+ # TODO - inheriting from TestUnit::TestCase fails without this
159
+ # - let's figure out why and move this somewhere else
160
+ end
161
+
162
+ def violated(message="")
163
+ raise Spec::Expectations::ExpectationNotMetError.new(message)
164
+ end
165
+
166
+ end
167
+
168
+ end
169
+ end
170
+ end