rspec 1.1.12 → 1.2.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 (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