rspec 1.1.12 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (267) hide show
  1. data/.autotest +2 -1
  2. data/.document +7 -0
  3. data/History.txt +58 -0
  4. data/License.txt +1 -1
  5. data/Manifest.txt +45 -82
  6. data/README.txt +3 -6
  7. data/Rakefile +33 -13
  8. data/Ruby1.9.markdown +32 -0
  9. data/TODO.txt +10 -4
  10. data/Upgrade.markdown +63 -0
  11. data/bin/spec +1 -1
  12. data/cucumber.yml +3 -0
  13. data/examples/failing/{failing_autogenerated_docstrings_example.rb → failing_implicit_docstrings_example.rb} +0 -0
  14. data/examples/failing/pending_example.rb +9 -0
  15. data/examples/failing/spec_helper.rb +1 -1
  16. data/examples/passing/{custom_expectation_matchers.rb → custom_matchers.rb} +0 -0
  17. data/examples/passing/filtered_formatter.rb +18 -0
  18. data/examples/passing/filtered_formatter_example.rb +31 -0
  19. data/examples/passing/implicit_docstrings_example.rb +18 -0
  20. data/examples/passing/spec_helper.rb +1 -1
  21. data/examples/ruby1.9.compatibility/access_to_constants_spec.rb +17 -18
  22. data/features/before_and_after_blocks/before_and_after_blocks.feature +4 -4
  23. data/features/example_groups/example_group_with_should_methods.feature +1 -1
  24. data/features/example_groups/{autogenerated_docstrings.feature → implicit_docstrings.feature} +7 -9
  25. data/features/example_groups/nested_groups.feature +1 -1
  26. data/features/heckle/heckle.feature +56 -0
  27. data/features/interop/examples_and_tests_together.feature +1 -1
  28. data/features/interop/test_but_not_test_unit.feature +1 -1
  29. data/features/interop/test_case_with_should_methods.feature +1 -1
  30. data/features/matchers/create_matcher.feature +115 -0
  31. data/features/mock_framework_integration/use_flexmock.feature +22 -4
  32. data/features/mock_framework_integration/use_mocha.feature +27 -0
  33. data/features/mock_framework_integration/use_rr.feature +27 -0
  34. data/features/mocks/mix_stubs_and_mocks.feature +22 -0
  35. data/features/pending/pending_examples.feature +81 -0
  36. data/features/step_definitions/running_rspec.rb +5 -3
  37. data/features/support/env.rb +1 -1
  38. data/features/support/matchers/smart_match.rb +2 -2
  39. data/lib/autotest/rspec.rb +1 -1
  40. data/lib/spec.rb +1 -1
  41. data/lib/{adapters → spec/adapters}/mock_frameworks/flexmock.rb +0 -0
  42. data/lib/{adapters → spec/adapters}/mock_frameworks/mocha.rb +0 -0
  43. data/lib/{adapters → spec/adapters}/mock_frameworks/rr.rb +0 -0
  44. data/lib/{adapters → spec/adapters}/mock_frameworks/rspec.rb +0 -1
  45. data/lib/spec/autorun.rb +3 -0
  46. data/lib/spec/dsl.rb +3 -1
  47. data/lib/spec/dsl/matchers.rb +13 -0
  48. data/lib/spec/example.rb +4 -0
  49. data/lib/spec/example/before_and_after_hooks.rb +5 -20
  50. data/lib/spec/example/errors.rb +3 -3
  51. data/lib/spec/example/example_description.rb +15 -0
  52. data/lib/spec/example/example_group.rb +0 -15
  53. data/lib/spec/example/example_group_factory.rb +34 -46
  54. data/lib/spec/example/example_group_hierarchy.rb +53 -0
  55. data/lib/spec/example/example_group_methods.rb +101 -211
  56. data/lib/spec/example/example_methods.rb +61 -81
  57. data/lib/spec/example/module_reopening_fix.rb +23 -1
  58. data/lib/spec/example/pending.rb +3 -2
  59. data/lib/spec/example/predicate_matchers.rb +47 -0
  60. data/lib/spec/example/subject.rb +91 -0
  61. data/lib/spec/expectations.rb +1 -1
  62. data/lib/spec/expectations/differs/default.rb +0 -1
  63. data/lib/spec/expectations/extensions.rb +0 -1
  64. data/lib/spec/expectations/handler.rb +13 -6
  65. data/lib/spec/interop/test.rb +5 -0
  66. data/lib/spec/interop/test/unit/testcase.rb +5 -22
  67. data/lib/spec/matchers.rb +22 -8
  68. data/lib/spec/matchers/be.rb +4 -9
  69. data/lib/spec/matchers/be_close.rb +20 -5
  70. data/lib/spec/matchers/be_instance_of.rb +45 -0
  71. data/lib/spec/matchers/be_kind_of.rb +45 -0
  72. data/lib/spec/matchers/change.rb +8 -6
  73. data/lib/spec/matchers/compatibility.rb +14 -0
  74. data/lib/spec/matchers/eql.rb +24 -6
  75. data/lib/spec/matchers/equal.rb +24 -6
  76. data/lib/spec/matchers/exist.rb +21 -5
  77. data/lib/spec/matchers/extensions/instance_exec.rb +25 -0
  78. data/lib/spec/matchers/generated_descriptions.rb +2 -2
  79. data/lib/spec/matchers/has.rb +28 -11
  80. data/lib/spec/matchers/have.rb +2 -2
  81. data/lib/spec/matchers/include.rb +2 -2
  82. data/lib/spec/matchers/match.rb +25 -7
  83. data/lib/spec/matchers/match_array.rb +3 -3
  84. data/lib/spec/matchers/matcher.rb +51 -0
  85. data/lib/spec/matchers/method_missing.rb +2 -2
  86. data/lib/spec/matchers/operator_matcher.rb +12 -5
  87. data/lib/spec/matchers/raise_error.rb +3 -3
  88. data/lib/spec/matchers/respond_to.rb +3 -3
  89. data/lib/spec/matchers/satisfy.rb +7 -7
  90. data/lib/spec/matchers/throw_symbol.rb +3 -5
  91. data/lib/spec/mocks.rb +3 -3
  92. data/lib/spec/mocks/argument_expectation.rb +15 -15
  93. data/lib/spec/mocks/{argument_constraints.rb → argument_matchers.rb} +19 -23
  94. data/lib/spec/mocks/error_generator.rb +5 -8
  95. data/lib/spec/mocks/framework.rb +1 -1
  96. data/lib/spec/mocks/message_expectation.rb +5 -13
  97. data/lib/spec/mocks/mock.rb +4 -5
  98. data/lib/spec/mocks/proxy.rb +9 -5
  99. data/lib/spec/mocks/spec_methods.rb +10 -1
  100. data/lib/spec/rake/spectask.rb +0 -1
  101. data/lib/spec/runner.rb +6 -28
  102. data/lib/spec/runner/configuration.rb +3 -3
  103. data/lib/spec/runner/drb_command_line.rb +2 -1
  104. data/lib/spec/runner/example_group_runner.rb +3 -2
  105. data/lib/spec/runner/formatter/base_text_formatter.rb +34 -19
  106. data/lib/spec/runner/formatter/failing_example_groups_formatter.rb +3 -5
  107. data/lib/spec/runner/formatter/html_formatter.rb +2 -3
  108. data/lib/spec/runner/formatter/nested_text_formatter.rb +7 -25
  109. data/lib/spec/runner/formatter/progress_bar_formatter.rb +1 -1
  110. data/lib/spec/runner/formatter/snippet_extractor.rb +1 -1
  111. data/lib/spec/runner/formatter/specdoc_formatter.rb +1 -7
  112. data/lib/spec/runner/heckle_runner.rb +3 -6
  113. data/lib/spec/runner/heckle_runner_unsupported.rb +1 -1
  114. data/lib/spec/runner/option_parser.rb +19 -21
  115. data/lib/spec/runner/options.rb +32 -27
  116. data/lib/spec/runner/reporter.rb +8 -9
  117. data/lib/spec/test/unit.rb +10 -0
  118. data/lib/spec/version.rb +2 -2
  119. data/{features/support → resources}/helpers/cmdline.rb +2 -2
  120. data/resources/rake/verify_rcov.rake +1 -1
  121. data/resources/spec/example_group_with_should_methods.rb +1 -1
  122. data/resources/spec/simple_spec.rb +1 -1
  123. data/resources/test/spec_and_test_together.rb +2 -3
  124. data/resources/test/spec_including_test_but_not_unit.rb +1 -1
  125. data/resources/test/test_case_with_should_methods.rb +2 -3
  126. data/spec/autotest/autotest_helper.rb +0 -1
  127. data/spec/autotest/rspec_spec.rb +95 -98
  128. data/spec/spec/dsl/main_spec.rb +3 -3
  129. data/spec/spec/dsl/matchers_spec.rb +25 -0
  130. data/spec/spec/example/example_group_class_definition_spec.rb +14 -15
  131. data/spec/spec/example/example_group_factory_spec.rb +31 -44
  132. data/spec/spec/example/example_group_methods_spec.rb +86 -52
  133. data/spec/spec/example/example_group_spec.rb +32 -79
  134. data/spec/spec/example/example_matcher_spec.rb +10 -10
  135. data/spec/spec/example/example_methods_spec.rb +108 -242
  136. data/spec/spec/example/nested_example_group_spec.rb +2 -2
  137. data/spec/spec/example/pending_module_spec.rb +66 -41
  138. data/spec/spec/example/shared_example_group_spec.rb +4 -4
  139. data/spec/spec/{matchers → expectations}/handler_spec.rb +52 -4
  140. data/spec/spec/interop/test/unit/resources/spec_that_fails.rb +2 -2
  141. data/spec/spec/interop/test/unit/resources/spec_that_passes.rb +2 -2
  142. data/spec/spec/interop/test/unit/resources/spec_with_errors.rb +2 -2
  143. data/spec/spec/interop/test/unit/resources/spec_with_options_hash.rb +2 -2
  144. data/spec/spec/interop/test/unit/resources/test_case_that_fails.rb +2 -2
  145. data/spec/spec/interop/test/unit/resources/test_case_that_passes.rb +2 -2
  146. data/spec/spec/interop/test/unit/resources/test_case_with_errors.rb +2 -2
  147. data/spec/spec/interop/test/unit/resources/testsuite_adapter_spec_with_test_unit.rb +2 -2
  148. data/spec/spec/interop/test/unit/testcase_spec.rb +0 -4
  149. data/spec/spec/matchers/be_close_spec.rb +1 -1
  150. data/spec/spec/matchers/be_instance_of_spec.rb +29 -0
  151. data/spec/spec/matchers/be_kind_of_spec.rb +29 -0
  152. data/spec/spec/matchers/change_spec.rb +20 -0
  153. data/spec/spec/matchers/compatibility_spec.rb +34 -0
  154. data/spec/spec/matchers/description_generation_spec.rb +0 -12
  155. data/spec/spec/matchers/eql_spec.rb +2 -2
  156. data/spec/spec/matchers/equal_spec.rb +2 -2
  157. data/spec/spec/matchers/exist_spec.rb +8 -4
  158. data/spec/spec/matchers/have_spec.rb +4 -4
  159. data/spec/spec/matchers/match_spec.rb +2 -2
  160. data/spec/spec/matchers/matcher_methods_spec.rb +1 -1
  161. data/spec/spec/matchers/matcher_spec.rb +97 -0
  162. data/spec/spec/matchers/throw_symbol_spec.rb +8 -8
  163. data/spec/spec/mocks/{bug_report_496.rb → bug_report_496_spec.rb} +0 -0
  164. data/spec/spec/mocks/{failing_mock_argument_constraints_spec.rb → failing_argument_matchers_spec.rb} +2 -2
  165. data/spec/spec/mocks/hash_including_matcher_spec.rb +4 -4
  166. data/spec/spec/mocks/hash_not_including_matcher_spec.rb +3 -3
  167. data/spec/spec/mocks/mock_spec.rb +27 -2
  168. data/spec/spec/mocks/nil_expectation_warning_spec.rb +1 -1
  169. data/spec/spec/mocks/partial_mock_spec.rb +18 -3
  170. data/spec/spec/mocks/{passing_mock_argument_constraints_spec.rb → passing_argument_matchers_spec.rb} +6 -6
  171. data/spec/spec/mocks/stubbed_message_expectations_spec.rb +13 -1
  172. data/spec/spec/package/bin_spec_spec.rb +2 -2
  173. data/spec/spec/runner/configuration_spec.rb +12 -12
  174. data/spec/spec/runner/drb_command_line_spec.rb +71 -73
  175. data/spec/spec/runner/formatter/base_text_formatter_spec.rb +82 -1
  176. data/spec/spec/runner/formatter/failing_example_groups_formatter_spec.rb +8 -8
  177. data/spec/spec/runner/formatter/failing_examples_formatter_spec.rb +4 -4
  178. data/spec/spec/runner/formatter/html_formatted-1.8.6.html +8 -8
  179. data/spec/spec/runner/formatter/html_formatted-1.8.7.html +38 -26
  180. data/spec/spec/runner/formatter/html_formatted-1.9.1.html +61 -53
  181. data/spec/spec/runner/formatter/html_formatter_spec.rb +100 -48
  182. data/spec/spec/runner/formatter/nested_text_formatter_spec.rb +20 -34
  183. data/spec/spec/runner/formatter/profile_formatter_spec.rb +2 -1
  184. data/spec/spec/runner/formatter/progress_bar_formatter_spec.rb +9 -6
  185. data/spec/spec/runner/formatter/specdoc_formatter_spec.rb +6 -6
  186. data/spec/spec/runner/formatter/text_mate_formatted-1.8.6.html +20 -20
  187. data/spec/spec/runner/formatter/text_mate_formatted-1.8.7.html +38 -26
  188. data/spec/spec/runner/formatter/text_mate_formatted-1.9.1.html +55 -47
  189. data/spec/spec/runner/formatter/{spec_mate_formatter_spec.rb → text_mate_formatter_spec.rb} +11 -9
  190. data/spec/spec/runner/heckle_runner_spec.rb +1 -1
  191. data/spec/spec/runner/heckler_spec.rb +1 -1
  192. data/spec/spec/runner/option_parser_spec.rb +28 -11
  193. data/spec/spec/runner/options_spec.rb +34 -0
  194. data/spec/spec/runner/reporter_spec.rb +66 -62
  195. data/spec/spec/runner/resources/utf8_encoded.rb +1 -0
  196. data/spec/spec/runner/spec_drb.opts +1 -0
  197. data/spec/spec/runner_spec.rb +7 -5
  198. data/spec/spec_helper.rb +24 -2
  199. metadata +49 -90
  200. data/examples/passing/autogenerated_docstrings_example.rb +0 -25
  201. data/examples/passing/before_and_after_example.rb +0 -40
  202. data/examples/passing/behave_as_example.rb +0 -45
  203. data/examples/passing/legacy_spec.rb +0 -11
  204. data/examples/passing/priority.txt +0 -1
  205. data/features/support/helpers/story_helper.rb +0 -16
  206. data/lib/spec/expectations/extensions/string_and_symbol.rb +0 -17
  207. data/lib/spec/runner/formatter/story/html_formatter.rb +0 -174
  208. data/lib/spec/runner/formatter/story/plain_text_formatter.rb +0 -194
  209. data/lib/spec/runner/formatter/story/progress_bar_formatter.rb +0 -42
  210. data/lib/spec/story.rb +0 -10
  211. data/lib/spec/story/extensions.rb +0 -3
  212. data/lib/spec/story/extensions/main.rb +0 -86
  213. data/lib/spec/story/extensions/regexp.rb +0 -9
  214. data/lib/spec/story/extensions/string.rb +0 -9
  215. data/lib/spec/story/given_scenario.rb +0 -14
  216. data/lib/spec/story/runner.rb +0 -57
  217. data/lib/spec/story/runner/plain_text_story_runner.rb +0 -48
  218. data/lib/spec/story/runner/scenario_collector.rb +0 -18
  219. data/lib/spec/story/runner/scenario_runner.rb +0 -54
  220. data/lib/spec/story/runner/story_mediator.rb +0 -137
  221. data/lib/spec/story/runner/story_parser.rb +0 -247
  222. data/lib/spec/story/runner/story_runner.rb +0 -74
  223. data/lib/spec/story/scenario.rb +0 -14
  224. data/lib/spec/story/step.rb +0 -70
  225. data/lib/spec/story/step_group.rb +0 -89
  226. data/lib/spec/story/step_mother.rb +0 -38
  227. data/lib/spec/story/story.rb +0 -39
  228. data/lib/spec/story/world.rb +0 -124
  229. data/resources/spec/spec_with_flexmock.rb +0 -19
  230. data/rspec.gemspec +0 -32
  231. data/spec/spec/matchers/mock_constraint_matchers_spec.rb +0 -24
  232. data/spec/spec/runner/formatter/story/html_formatter_spec.rb +0 -135
  233. data/spec/spec/runner/formatter/story/plain_text_formatter_spec.rb +0 -600
  234. data/spec/spec/runner/formatter/story/progress_bar_formatter_spec.rb +0 -82
  235. data/spec/spec/spec_spec.rb +0 -21
  236. data/spec/spec/story/builders.rb +0 -46
  237. data/spec/spec/story/extensions/main_spec.rb +0 -161
  238. data/spec/spec/story/extensions_spec.rb +0 -14
  239. data/spec/spec/story/given_scenario_spec.rb +0 -27
  240. data/spec/spec/story/runner/plain_text_story_runner_spec.rb +0 -90
  241. data/spec/spec/story/runner/scenario_collector_spec.rb +0 -27
  242. data/spec/spec/story/runner/scenario_runner_spec.rb +0 -214
  243. data/spec/spec/story/runner/story_mediator_spec.rb +0 -143
  244. data/spec/spec/story/runner/story_parser_spec.rb +0 -401
  245. data/spec/spec/story/runner/story_runner_spec.rb +0 -294
  246. data/spec/spec/story/runner_spec.rb +0 -93
  247. data/spec/spec/story/scenario_spec.rb +0 -18
  248. data/spec/spec/story/step_group_spec.rb +0 -157
  249. data/spec/spec/story/step_mother_spec.rb +0 -84
  250. data/spec/spec/story/step_spec.rb +0 -272
  251. data/spec/spec/story/story_helper.rb +0 -2
  252. data/spec/spec/story/story_spec.rb +0 -84
  253. data/spec/spec/story/world_spec.rb +0 -423
  254. data/story_server/prototype/javascripts/builder.js +0 -136
  255. data/story_server/prototype/javascripts/controls.js +0 -972
  256. data/story_server/prototype/javascripts/dragdrop.js +0 -976
  257. data/story_server/prototype/javascripts/effects.js +0 -1117
  258. data/story_server/prototype/javascripts/prototype.js +0 -4140
  259. data/story_server/prototype/javascripts/rspec.js +0 -149
  260. data/story_server/prototype/javascripts/scriptaculous.js +0 -58
  261. data/story_server/prototype/javascripts/slider.js +0 -276
  262. data/story_server/prototype/javascripts/sound.js +0 -55
  263. data/story_server/prototype/javascripts/unittest.js +0 -568
  264. data/story_server/prototype/lib/server.rb +0 -24
  265. data/story_server/prototype/stories.html +0 -176
  266. data/story_server/prototype/stylesheets/rspec.css +0 -136
  267. data/story_server/prototype/stylesheets/test.css +0 -90
@@ -37,21 +37,14 @@ module Spec
37
37
  after_parts(*args) << block
38
38
  end
39
39
 
40
- # TODO - deprecate this unless there is a reason why it exists
41
- def remove_after(scope, &block) # :nodoc:
42
- after_each_parts.delete(block)
43
- end
44
-
45
- # Deprecated. Use before(:each)
46
- def setup(&block)
47
- before(:each, &block)
40
+ def before_each_parts # :nodoc:
41
+ @before_each_parts ||= []
48
42
  end
49
43
 
50
- # Deprecated. Use after(:each)
51
- def teardown(&block)
52
- after(:each, &block)
44
+ def after_each_parts # :nodoc:
45
+ @after_each_parts ||= []
53
46
  end
54
-
47
+
55
48
  def before_all_parts # :nodoc:
56
49
  @before_all_parts ||= []
57
50
  end
@@ -60,14 +53,6 @@ module Spec
60
53
  @after_all_parts ||= []
61
54
  end
62
55
 
63
- def before_each_parts # :nodoc:
64
- @before_each_parts ||= []
65
- end
66
-
67
- def after_each_parts # :nodoc:
68
- @after_each_parts ||= []
69
- end
70
-
71
56
  def before_suite_parts
72
57
  BeforeAndAfterHooks.before_suite_parts
73
58
  end
@@ -3,9 +3,9 @@ module Spec
3
3
  class ExamplePendingError < StandardError
4
4
  attr_reader :pending_caller
5
5
 
6
- def initialize(message=nil)
7
- super
8
- @pending_caller = caller[2]
6
+ def initialize(message=nil, pending_caller=nil)
7
+ super(message)
8
+ @pending_caller = pending_caller || caller[2]
9
9
  end
10
10
  end
11
11
 
@@ -0,0 +1,15 @@
1
+ module Spec
2
+ module Example
3
+ class ExampleDescription
4
+ attr_reader :description, :options, :backtrace
5
+
6
+ def initialize(description, options={}, backtrace=nil)
7
+ @description, @options, @backtrace = description, options, backtrace
8
+ end
9
+
10
+ def ==(other)
11
+ (other.description == description) & (other.backtrace == backtrace)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -5,22 +5,7 @@ module Spec
5
5
  class ExampleGroup
6
6
  extend Spec::Example::ExampleGroupMethods
7
7
  include Spec::Example::ExampleMethods
8
-
9
- def initialize(defined_description, options={}, &implementation)
10
- @_options = options
11
- @_defined_description = defined_description
12
- @_implementation = implementation || pending_implementation
13
- @_backtrace = caller
14
- end
15
-
16
- private
17
-
18
- def pending_implementation
19
- error = NotYetImplementedError.new(caller)
20
- lambda { raise(error) }
21
- end
22
8
  end
23
9
  end
24
10
  end
25
11
 
26
- Spec::ExampleGroup = Spec::Example::ExampleGroup
@@ -1,5 +1,6 @@
1
1
  module Spec
2
2
  module Example
3
+
3
4
  class ExampleGroupFactory
4
5
  module ClassMethods
5
6
  def reset
@@ -7,13 +8,27 @@ module Spec
7
8
  default(ExampleGroup)
8
9
  end
9
10
 
10
- def registered_or_ancestor_of_registered?(example_group_classes) # :nodoc:
11
- example_group_classes.each do |example_group_class|
12
- return false unless registered_types.any? do |registered_type|
13
- registered_type.ancestors.include? example_group_class
14
- end
11
+ def example_group_creation_listeners
12
+ @example_group_creation_listeners ||= []
13
+ end
14
+
15
+ def register_example_group(klass)
16
+ example_group_creation_listeners.each do |listener|
17
+ listener.register_example_group(klass)
15
18
  end
16
- return true
19
+ end
20
+
21
+ def create_shared_example_group(*args, &example_group_block) # :nodoc:
22
+ ::Spec::Example::add_spec_path_to(args)
23
+ ::Spec::Example::SharedExampleGroup.register(*args, &example_group_block)
24
+ end
25
+
26
+ def create_example_group(*args, &block)
27
+ raise ArgumentError if args.empty?
28
+ raise ArgumentError unless block
29
+ Spec::Example::add_spec_path_to(args)
30
+ superclass = determine_superclass(args.last)
31
+ superclass.describe(*args, &block)
17
32
  end
18
33
 
19
34
  # Registers an example group class +klass+ with the symbol +type+. For
@@ -31,44 +46,22 @@ module Spec
31
46
  # implicitly use an instance of FarmExampleGroup for any file loaded
32
47
  # from the <tt>./spec/farm</tt> directory.
33
48
  def register(key, example_group_class)
34
- @example_group_types[key] = example_group_class
49
+ @example_group_types[key.to_sym] = example_group_class
35
50
  end
36
-
51
+
37
52
  # Sets the default ExampleGroup class
38
53
  def default(example_group_class)
54
+ Spec.__send__ :remove_const, :ExampleGroup if Spec.const_defined?(:ExampleGroup)
55
+ Spec.const_set(:ExampleGroup, example_group_class)
39
56
  old = @example_group_types
40
57
  @example_group_types = Hash.new(example_group_class)
41
58
  @example_group_types.merge!(old) if old
42
59
  end
43
60
 
44
- def get(key=nil)
45
- if @example_group_types.values.include?(key)
46
- key
47
- else
48
- @example_group_types[key]
49
- end
50
- end
51
-
52
- def create_example_group(*args, &block)
53
- raise ArgumentError if args.empty?
54
- raise ArgumentError unless block
55
- Spec::Example::add_spec_path_to(args)
56
- superclass = determine_superclass(args.last)
57
- superclass.describe(*args, &block)
58
- end
59
-
60
- def create_shared_example_group(*args, &block)
61
- Spec::Example::add_spec_path_to(args)
62
- SharedExampleGroup.register(*args, &block)
61
+ def [](key)
62
+ @example_group_types[key]
63
63
  end
64
-
65
- def include_constants_in(context, &block)
66
- if (Spec::Ruby.version.to_f >= 1.9 && Module === context && !(Class === context))
67
- return lambda {include context;instance_eval(&block)}
68
- end
69
- block
70
- end
71
-
64
+
72
65
  def assign_scope(scope, args)
73
66
  args.last[:scope] = scope
74
67
  end
@@ -76,18 +69,13 @@ module Spec
76
69
  protected
77
70
 
78
71
  def determine_superclass(opts)
79
- key = if opts[:type]
80
- opts[:type]
81
- elsif opts[:spec_path] =~ /spec(\\|\/)(#{@example_group_types.keys.join('|')})/
82
- $2 == '' ? nil : $2.to_sym
72
+ if type = opts[:type]
73
+ self[type]
74
+ elsif opts[:spec_path] =~ /spec(\\|\/)(#{@example_group_types.keys.sort_by{|k| k.to_s.length}.reverse.join('|')})/
75
+ self[$2 == '' ? nil : $2.to_sym]
76
+ else
77
+ self[nil]
83
78
  end
84
- get(key)
85
- end
86
-
87
- private
88
-
89
- def registered_types
90
- @example_group_types.values
91
79
  end
92
80
 
93
81
  end
@@ -0,0 +1,53 @@
1
+ module Spec
2
+ module Example
3
+ class ExampleGroupHierarchy < Array
4
+ def initialize(example_group_class)
5
+ push example_group_class
6
+ if example_group_class.respond_to?(:superclass) && example_group_class.superclass.respond_to?(:example_group_hierarchy)
7
+ unshift example_group_class.superclass.example_group_hierarchy
8
+ flatten!
9
+ end
10
+ end
11
+
12
+ def run_before_all(example)
13
+ example.eval_each_fail_fast(before_all_parts)
14
+ end
15
+
16
+ def run_before_each(example)
17
+ example.eval_each_fail_fast(before_each_parts)
18
+ end
19
+
20
+ def run_after_each(example)
21
+ example.eval_each_fail_slow(after_each_parts)
22
+ end
23
+
24
+ def run_after_all(example)
25
+ example.eval_each_fail_slow(after_all_parts)
26
+ end
27
+
28
+ def before_all_parts
29
+ @before_all_parts ||= collect {|klass| klass.before_all_parts}.flatten
30
+ end
31
+
32
+ def before_each_parts
33
+ @before_each_parts ||= collect {|klass| klass.before_each_parts}.flatten
34
+ end
35
+
36
+ def after_each_parts
37
+ @after_each_parts ||= reverse.collect {|klass| klass.after_each_parts}.flatten
38
+ end
39
+
40
+ def after_all_parts
41
+ @after_all_parts ||= reverse.collect {|klass| klass.after_all_parts}.flatten
42
+ end
43
+
44
+ def nested_descriptions
45
+ @nested_descriptions ||= collect {|eg| nested_description_from(eg) == "" ? nil : nested_description_from(eg) }.compact
46
+ end
47
+
48
+ def nested_description_from(example_group)
49
+ example_group.description_args.join
50
+ end
51
+ end
52
+ end
53
+ end
@@ -4,23 +4,18 @@ module Spec
4
4
  module ExampleGroupMethods
5
5
  class << self
6
6
  attr_accessor :matcher_class
7
-
8
- def description_text(*args)
9
- args.inject("") do |description, arg|
10
- description << " " unless (description == "" || arg.to_s =~ /^(\s|\.|#)/)
11
- description << arg.to_s
12
- end
13
- end
14
-
15
- def example_group_creation_listeners
16
- @example_group_creation_listeners ||= []
17
- end
18
7
  end
19
8
 
20
9
  include Spec::Example::BeforeAndAfterHooks
10
+ include Spec::Example::Subject::ExampleGroupMethods
11
+ include Spec::Example::PredicateMatchers
21
12
 
22
- attr_reader :description_options, :spec_path
23
- alias :options :description_options
13
+ attr_reader :options, :spec_path
14
+
15
+ def inherited(klass) # :nodoc:
16
+ super
17
+ ExampleGroupFactory.register_example_group(klass)
18
+ end
24
19
 
25
20
  # Provides the backtrace up to where this example_group was declared.
26
21
  def backtrace
@@ -36,21 +31,6 @@ WARNING
36
31
  backtrace
37
32
  end
38
33
 
39
- def description_args
40
- @description_args ||= []
41
- end
42
-
43
- def inherited(klass)
44
- super
45
- register_example_group(klass)
46
- end
47
-
48
- def register_example_group(klass)
49
- ExampleGroupMethods.example_group_creation_listeners.each do |l|
50
- l.register_example_group(klass)
51
- end
52
- end
53
-
54
34
  # Makes the describe/it syntax available from a class. For example:
55
35
  #
56
36
  # class StackSpec < Spec::ExampleGroup
@@ -70,9 +50,9 @@ WARNING
70
50
  Spec::Example::add_spec_path_to(args)
71
51
  options = args.last
72
52
  if options[:shared]
73
- create_shared_example_group(*args, &example_group_block)
53
+ ExampleGroupFactory.create_shared_example_group(*args, &example_group_block)
74
54
  else
75
- create_example_group_subclass(*args, &example_group_block)
55
+ subclass(*args, &example_group_block)
76
56
  end
77
57
  else
78
58
  set_description(*args)
@@ -80,26 +60,6 @@ WARNING
80
60
  end
81
61
  alias :context :describe
82
62
 
83
- def create_shared_example_group(*args, &example_group_block) # :nodoc:
84
- SharedExampleGroup.register(*args, &example_group_block)
85
- end
86
-
87
- # Creates a new subclass of self, with a name "under" our own name.
88
- # Example:
89
- #
90
- # x = Foo::Bar.subclass('Zap'){}
91
- # x.name # => Foo::Bar::Zap_1
92
- # x.superclass.name # => Foo::Bar
93
- def create_example_group_subclass(*args, &example_group_block) # :nodoc:
94
- @class_count ||= 0
95
- @class_count += 1
96
- klass = const_set("Subclass_#{@class_count}", Class.new(self))
97
- klass.set_description(*args)
98
- example_group_block = ExampleGroupFactory.include_constants_in(args.last[:scope], &example_group_block)
99
- klass.module_eval(&example_group_block)
100
- klass
101
- end
102
-
103
63
  # Use this to pull in examples from shared example groups.
104
64
  def it_should_behave_like(*shared_example_groups)
105
65
  shared_example_groups.each do |group|
@@ -107,44 +67,18 @@ WARNING
107
67
  end
108
68
  end
109
69
 
110
- # :call-seq:
111
- # predicate_matchers[matcher_name] = method_on_object
112
- # predicate_matchers[matcher_name] = [method1_on_object, method2_on_object]
113
- #
114
- # Dynamically generates a custom matcher that will match
115
- # a predicate on your class. RSpec provides a couple of these
116
- # out of the box:
117
- #
118
- # exist (for state expectations)
119
- # File.should exist("path/to/file")
120
- #
121
- # an_instance_of (for mock argument constraints)
122
- # mock.should_receive(:message).with(an_instance_of(String))
123
- #
124
- # == Examples
125
- #
126
- # class Fish
127
- # def can_swim?
128
- # true
129
- # end
130
- # end
131
- #
132
- # describe Fish do
133
- # predicate_matchers[:swim] = :can_swim?
134
- # it "should swim" do
135
- # Fish.new.should swim
136
- # end
137
- # end
138
- def predicate_matchers
139
- @predicate_matchers ||= {}
140
- end
141
-
142
70
  # Creates an instance of the current example group class and adds it to
143
71
  # a collection of examples of the current example group.
144
- def example(description=nil, options={}, &implementation)
145
- e = new(description, options, &implementation)
146
- example_objects << e
147
- e
72
+ def example(description=nil, options={}, backtrace=nil, &implementation)
73
+ example_description = ExampleDescription.new(description, options, backtrace || caller(0)[1])
74
+ example_descriptions << example_description
75
+ example_implementations[example_description] = implementation || pending_implementation
76
+ example_description
77
+ end
78
+
79
+ def pending_implementation
80
+ error = Spec::Example::NotYetImplementedError.new(caller)
81
+ lambda { raise(error) }
148
82
  end
149
83
 
150
84
  alias_method :it, :example
@@ -157,105 +91,101 @@ WARNING
157
91
 
158
92
  alias_method :xit, :xexample
159
93
  alias_method :xspecify, :xexample
160
-
94
+
161
95
  def run(run_options)
162
96
  examples = examples_to_run(run_options)
163
- run_options.reporter.add_example_group(self) unless examples.empty?
97
+ notify(run_options.reporter) unless examples.empty?
164
98
  return true if examples.empty?
165
99
  return dry_run(examples, run_options) if run_options.dry_run?
166
100
 
167
- plugin_mock_framework(run_options)
168
- define_methods_from_predicate_matchers(run_options)
101
+ define_methods_from_predicate_matchers
169
102
 
170
103
  success, before_all_instance_variables = run_before_all(run_options)
171
104
  success, after_all_instance_variables = execute_examples(success, before_all_instance_variables, examples, run_options)
172
105
  success = run_after_all(success, after_all_instance_variables, run_options)
173
106
  end
174
107
 
108
+ def set_description(*args)
109
+ @description_args, @options = Spec::Example.args_and_options(*args)
110
+ @backtrace = caller(1)
111
+ @spec_path = File.expand_path(options[:spec_path]) if options[:spec_path]
112
+ self
113
+ end
114
+
115
+ def notify(listener) # :nodoc:
116
+ listener.add_example_group(self)
117
+ end
118
+
175
119
  def description
176
- result = ExampleGroupMethods.description_text(*description_parts)
177
- (result.nil? || result == "") ? to_s : result
120
+ @description ||= build_description_from(*description_parts) || to_s
178
121
  end
179
122
 
180
123
  def described_type
181
- description_parts.reverse.find {|part| part.is_a?(Module)}
124
+ @described_type ||= description_parts.reverse.find {|part| part.is_a?(Module)}
182
125
  end
183
126
 
184
- # Defines an explicit subject for an example group which can then be the
185
- # implicit receiver (through delegation) of calls to +should+.
186
- #
187
- # == Examples
188
- #
189
- # describe CheckingAccount, "with $50" do
190
- # subject { CheckingAccount.new(:amount => 50, :currency => :USD) }
191
- # it { should have_a_balance_of(50, :USD)}
192
- # it { should_not be_overdrawn}
193
- # end
194
- #
195
- # See +ExampleMethods#should+ for more information about this approach.
196
- def subject(&block)
197
- @_subject_block = block
127
+ def described_class
128
+ @described_class ||= Class === described_type ? described_type : nil
198
129
  end
199
130
 
200
- def subject_block
201
- @_subject_block || lambda {nil}
131
+ def description_args
132
+ @description_args ||= []
202
133
  end
203
134
 
204
135
  def description_parts #:nodoc:
205
- example_group_hierarchy.inject([]) do |parts, example_group_class|
136
+ @description_parts ||= example_group_hierarchy.inject([]) do |parts, example_group_class|
206
137
  [parts << example_group_class.description_args].flatten
207
138
  end
208
139
  end
209
-
210
- def set_description(*args)
211
- args, options = Spec::Example.args_and_options(*args)
212
- @description_args = args
213
- @description_options = options
214
- @description_text = ExampleGroupMethods.description_text(*args)
215
- @backtrace = caller(1)
216
- @spec_path = File.expand_path(options[:spec_path]) if options[:spec_path]
217
- self
140
+
141
+ def example_descriptions # :nodoc:
142
+ @example_descriptions ||= []
218
143
  end
219
144
 
145
+ def example_implementations # :nodoc:
146
+ @example_implementations ||= {}
147
+ end
148
+
220
149
  def examples(run_options=nil) #:nodoc:
221
- examples = example_objects.dup
222
- add_method_examples(examples)
223
- (run_options && run_options.reverse) ? examples.reverse : examples
150
+ (run_options && run_options.reverse) ? example_descriptions.reverse : example_descriptions
224
151
  end
225
152
 
226
153
  def number_of_examples #:nodoc:
227
- examples.length
154
+ example_descriptions.length
228
155
  end
229
156
 
230
- # Only used from RSpec's own examples
231
- def reset # :nodoc:
232
- @before_all_parts = nil
233
- @after_all_parts = nil
234
- @before_each_parts = nil
235
- @after_each_parts = nil
236
- end
237
-
238
- def run_before_each(example)
239
- example.eval_each_fail_fast(all_before_each_parts)
157
+ def example_group_hierarchy
158
+ @example_group_hierarchy ||= ExampleGroupHierarchy.new(self)
240
159
  end
241
160
 
242
- def all_before_each_parts
243
- unless @all_before_each_parts
244
- @all_before_each_parts = []
245
- example_group_hierarchy.each do |example_group_class|
246
- @all_before_each_parts += example_group_class.before_each_parts
161
+ def filtered_description(filter)
162
+ build_description_from(
163
+ *nested_descriptions.collect do |description|
164
+ description =~ filter ? $1 : description
247
165
  end
248
- end
249
- @all_before_each_parts
166
+ )
167
+ end
168
+
169
+ def nested_descriptions
170
+ example_group_hierarchy.nested_descriptions
250
171
  end
172
+
173
+ def include_constants_in(mod)
174
+ include mod if (Spec::Ruby.version.to_f >= 1.9) & (Module === mod) & !(Class === mod)
175
+ end
176
+
177
+ private
251
178
 
252
- def run_after_each(example)
253
- example_group_hierarchy.reverse.each do |example_group_class|
254
- example.eval_each_fail_slow(example_group_class.after_each_parts)
255
- end
179
+ def subclass(*args, &example_group_block)
180
+ @class_count ||= 0
181
+ @class_count += 1
182
+ klass = const_set("Subclass_#{@class_count}", Class.new(self))
183
+ klass.set_description(*args)
184
+ klass.include_constants_in(args.last[:scope])
185
+ klass.module_eval(&example_group_block)
186
+ klass
256
187
  end
257
188
 
258
- private
259
189
  def dry_run(examples, run_options)
260
190
  examples.each do |example|
261
191
  run_options.reporter.example_started(example)
@@ -264,14 +194,13 @@ WARNING
264
194
  end
265
195
 
266
196
  def run_before_all(run_options)
197
+ return [true,{}] if example_group_hierarchy.before_all_parts.empty?
267
198
  before_all = new("before(:all)")
268
199
  begin
269
- example_group_hierarchy.each do |example_group_class|
270
- before_all.eval_each_fail_fast(example_group_class.before_all_parts)
271
- end
200
+ example_group_hierarchy.run_before_all(before_all)
272
201
  return [true, before_all.instance_variable_hash]
273
202
  rescue Exception => e
274
- run_options.reporter.failure(before_all, e)
203
+ run_options.reporter.example_failed(ExampleDescription.new("before(:all)"), e)
275
204
  return [false, before_all.instance_variable_hash]
276
205
  end
277
206
  end
@@ -280,29 +209,30 @@ WARNING
280
209
  return [success, instance_variables] unless success
281
210
 
282
211
  after_all_instance_variables = instance_variables
283
- examples.each do |example_group_instance|
212
+
213
+ examples.each do |example|
214
+ example_group_instance = new(example.description,example.options,&example_implementations[example])
284
215
  success &= example_group_instance.execute(run_options, instance_variables)
285
216
  after_all_instance_variables = example_group_instance.instance_variable_hash
286
217
  end
218
+
287
219
  return [success, after_all_instance_variables]
288
220
  end
289
-
221
+
290
222
  def run_after_all(success, instance_variables, run_options)
223
+ return success if example_group_hierarchy.after_all_parts.empty?
291
224
  after_all = new("after(:all)")
292
225
  after_all.set_instance_variables_from_hash(instance_variables)
293
- example_group_hierarchy.reverse.each do |example_group_class|
294
- after_all.eval_each_fail_slow(example_group_class.after_all_parts)
295
- end
226
+ example_group_hierarchy.run_after_all(after_all)
296
227
  return success
297
228
  rescue Exception => e
298
- run_options.reporter.failure(after_all, e)
229
+ run_options.reporter.example_failed(ExampleDescription.new("after(:all)"), e)
299
230
  return false
300
231
  end
301
-
232
+
302
233
  def examples_to_run(run_options)
303
- all_examples = examples(run_options)
304
- return all_examples unless specified_examples?(run_options)
305
- all_examples.reject do |example|
234
+ return example_descriptions unless specified_examples?(run_options)
235
+ example_descriptions.reject do |example|
306
236
  matcher = ExampleGroupMethods.matcher_class.
307
237
  new(description.to_s, example.description)
308
238
  !matcher.matches?(run_options.examples)
@@ -310,68 +240,21 @@ WARNING
310
240
  end
311
241
 
312
242
  def specified_examples?(run_options)
313
- run_options.examples && !run_options.examples.empty?
243
+ !run_options.examples.empty?
314
244
  end
315
245
 
316
- def example_objects
317
- @example_objects ||= []
318
- end
319
-
320
- class ExampleGroupHierarchy < Array
321
- def initialize(example_group_class)
322
- current_class = example_group_class
323
- while current_class.kind_of?(ExampleGroupMethods)
324
- unshift(current_class)
325
- break unless current_class.respond_to? :superclass
326
- current_class = current_class.superclass
327
- end
328
- end
246
+ def method_added(name) # :nodoc:
247
+ example(name.to_s, {}, caller(0)[1]) {__send__ name.to_s} if example_method?(name.to_s)
329
248
  end
330
249
 
331
- def example_group_hierarchy
332
- @example_group_hierarchy ||= ExampleGroupHierarchy.new(self)
333
- end
334
-
335
- def plugin_mock_framework(run_options)
336
- case mock_framework = run_options.mock_framework
337
- when Module
338
- include mock_framework
339
- else
340
- require mock_framework
341
- include Spec::Adapters::MockFramework
342
- end
343
- end
344
-
345
- def define_methods_from_predicate_matchers(run_options) # :nodoc:
346
- all_predicate_matchers = predicate_matchers.merge(
347
- run_options.predicate_matchers
348
- )
349
- all_predicate_matchers.each_pair do |matcher_method, method_on_object|
350
- define_method matcher_method do |*args|
351
- eval("be_#{method_on_object.to_s.gsub('?','')}(*args)")
352
- end
353
- end
354
- end
355
-
356
- def add_method_examples(examples)
357
- instance_methods.each do |method_name|
358
- if example_method?(method_name)
359
- examples << new(method_name) do
360
- __send__(method_name)
361
- end
362
- end
363
- end
364
- end
365
-
366
250
  def example_method?(method_name)
367
251
  should_method?(method_name)
368
252
  end
369
253
 
370
254
  def should_method?(method_name)
371
255
  !(method_name =~ /^should(_not)?$/) &&
372
- method_name =~ /^should/ && (
373
- [-1,0].include?(instance_method(method_name).arity)
374
- )
256
+ method_name =~ /^should/ &&
257
+ instance_method(method_name).arity < 1
375
258
  end
376
259
 
377
260
  def include_shared_example_group(shared_example_group)
@@ -387,6 +270,13 @@ WARNING
387
270
  end
388
271
  end
389
272
 
273
+ def build_description_from(*args)
274
+ text = args.inject("") do |description, arg|
275
+ description << " " unless (description == "" || arg.to_s =~ /^(\s|\.|#)/)
276
+ description << arg.to_s
277
+ end
278
+ text == "" ? nil : text
279
+ end
390
280
  end
391
281
 
392
282
  end