rspec-core 2.8.0.rc1 → 2.8.0.rc2

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 (73) hide show
  1. data/License.txt +24 -0
  2. data/README.md +197 -37
  3. data/features/command_line/format_option.feature +3 -3
  4. data/features/command_line/init.feature +18 -0
  5. data/features/example_groups/shared_examples.feature +1 -1
  6. data/features/hooks/around_hooks.feature +4 -4
  7. data/features/pending/pending_examples.feature +5 -5
  8. data/features/support/env.rb +8 -1
  9. data/lib/autotest/rspec2.rb +2 -6
  10. data/lib/rspec/core.rb +48 -158
  11. data/lib/rspec/core/backward_compatibility.rb +2 -0
  12. data/lib/rspec/core/command_line.rb +4 -0
  13. data/lib/rspec/core/configuration.rb +201 -106
  14. data/lib/rspec/core/configuration_options.rb +2 -1
  15. data/lib/rspec/core/deprecation.rb +2 -3
  16. data/lib/rspec/core/drb_options.rb +69 -58
  17. data/lib/rspec/core/dsl.rb +12 -0
  18. data/lib/rspec/core/example.rb +53 -18
  19. data/lib/rspec/core/example_group.rb +144 -54
  20. data/lib/rspec/core/extensions.rb +4 -4
  21. data/lib/rspec/core/extensions/instance_eval_with_args.rb +5 -0
  22. data/lib/rspec/core/extensions/kernel.rb +1 -1
  23. data/lib/rspec/core/extensions/module_eval_with_args.rb +4 -0
  24. data/lib/rspec/core/extensions/ordered.rb +7 -2
  25. data/lib/rspec/core/filter_manager.rb +69 -36
  26. data/lib/rspec/core/formatters/base_text_formatter.rb +1 -1
  27. data/lib/rspec/core/formatters/html_formatter.rb +10 -4
  28. data/lib/rspec/core/hooks.rb +93 -34
  29. data/lib/rspec/core/let.rb +62 -61
  30. data/lib/rspec/core/metadata.rb +103 -80
  31. data/lib/rspec/core/metadata_hash_builder.rb +4 -0
  32. data/lib/rspec/core/option_parser.rb +42 -44
  33. data/lib/rspec/core/pending.rb +25 -3
  34. data/lib/rspec/core/project_initializer.rb +62 -0
  35. data/lib/rspec/core/rake_task.rb +7 -13
  36. data/lib/rspec/core/runner.rb +2 -2
  37. data/lib/rspec/core/shared_context.rb +1 -1
  38. data/lib/rspec/core/shared_example_group.rb +11 -5
  39. data/lib/rspec/core/subject.rb +3 -3
  40. data/lib/rspec/core/version.rb +1 -1
  41. data/lib/rspec/monkey.rb +1 -1
  42. data/lib/rspec/monkey/spork/test_framework/rspec.rb +2 -0
  43. data/spec/command_line/order_spec.rb +19 -13
  44. data/spec/rspec/core/command_line_spec.rb +1 -5
  45. data/spec/rspec/core/configuration_options_spec.rb +22 -27
  46. data/spec/rspec/core/configuration_spec.rb +32 -14
  47. data/spec/rspec/core/drb_command_line_spec.rb +20 -37
  48. data/spec/rspec/core/drb_options_spec.rb +51 -3
  49. data/spec/rspec/core/example_group_spec.rb +101 -84
  50. data/spec/rspec/core/example_spec.rb +14 -0
  51. data/spec/rspec/core/filter_manager_spec.rb +114 -33
  52. data/spec/rspec/core/formatters/html_formatted-1.8.7-jruby.html +17 -69
  53. data/spec/rspec/core/formatters/html_formatted-1.8.7.html +14 -4
  54. data/spec/rspec/core/formatters/html_formatted-1.9.2.html +14 -4
  55. data/spec/rspec/core/formatters/html_formatted-1.9.3.html +14 -4
  56. data/spec/rspec/core/formatters/html_formatter_spec.rb +1 -1
  57. data/spec/rspec/core/formatters/text_mate_formatted-1.8.7-jruby.html +20 -72
  58. data/spec/rspec/core/formatters/text_mate_formatted-1.8.7.html +24 -14
  59. data/spec/rspec/core/formatters/text_mate_formatted-1.9.2.html +29 -19
  60. data/spec/rspec/core/formatters/text_mate_formatted-1.9.3.html +29 -19
  61. data/spec/rspec/core/formatters/text_mate_formatter_spec.rb +1 -2
  62. data/spec/rspec/core/metadata_spec.rb +77 -45
  63. data/spec/rspec/core/option_parser_spec.rb +5 -0
  64. data/spec/rspec/core/pending_example_spec.rb +44 -12
  65. data/spec/rspec/core/project_initializer_spec.rb +130 -0
  66. data/spec/rspec/core/rake_task_spec.rb +1 -1
  67. data/spec/spec_helper.rb +2 -0
  68. data/spec/support/matchers.rb +2 -12
  69. metadata +18 -16
  70. data/features/command_line/configure.feature +0 -22
  71. data/lib/rspec/core/command_line_configuration.rb +0 -62
  72. data/lib/rspec/core/errors.rb +0 -13
  73. data/spec/rspec/core/command_line_configuration_spec.rb +0 -26
@@ -2,6 +2,7 @@ require 'erb'
2
2
 
3
3
  module RSpec
4
4
  module Core
5
+ # @private
5
6
  class ConfigurationOptions
6
7
  attr_reader :options
7
8
 
@@ -37,7 +38,7 @@ module RSpec
37
38
 
38
39
  private
39
40
 
40
- NON_FORCED_OPTIONS = [:debug, :order, :seed, :requires, :libs, :files_or_directories_to_run, :line_numbers, :full_description]
41
+ NON_FORCED_OPTIONS = [:debug, :requires, :libs, :files_or_directories_to_run, :line_numbers, :full_description]
41
42
 
42
43
  def force?(key)
43
44
  !NON_FORCED_OPTIONS.include?(key)
@@ -1,7 +1,6 @@
1
1
  module RSpec
2
-
3
2
  class << self
4
- # @api private
3
+ # @private
5
4
  #
6
5
  # Used internally to print deprecation warnings
7
6
  def deprecate(method, alternate_method=nil, version=nil)
@@ -27,7 +26,7 @@ ADDITIONAL
27
26
  warn_deprecation(message)
28
27
  end
29
28
 
30
- # @api private
29
+ # @private
31
30
  #
32
31
  # Used internally to print deprecation warnings
33
32
  def warn_deprecation(message)
@@ -1,72 +1,83 @@
1
1
  # Builds command line arguments to pass to the rspec command over DRb
2
- class RSpec::Core::DrbOptions
3
- def initialize(submitted_options, filter_manager)
4
- @submitted_options = submitted_options
5
- @filter_manager = filter_manager
6
- end
7
2
 
8
- def options
9
- argv = []
10
- argv << "--color" if @submitted_options[:color]
11
- argv << "--profile" if @submitted_options[:profile_examples]
12
- argv << "--backtrace" if @submitted_options[:full_backtrace]
13
- argv << "--tty" if @submitted_options[:tty]
14
- argv << "--fail-fast" if @submitted_options[:fail_fast]
15
- argv << "--options" << @submitted_options[:custom_options_file] if @submitted_options[:custom_options_file]
16
- argv << "--order" << @submitted_options[:order] if @submitted_options[:order]
3
+ module RSpec::Core
4
+ # @private
5
+ class DrbOptions
6
+ def initialize(submitted_options, filter_manager)
7
+ @submitted_options = submitted_options
8
+ @filter_manager = filter_manager
9
+ end
17
10
 
18
- add_full_description(argv)
19
- add_line_numbers(argv)
20
- add_filter(argv, :inclusion, @filter_manager.inclusions)
21
- add_filter(argv, :exclusion, @filter_manager.exclusions)
22
- add_formatters(argv)
23
- add_libs(argv)
24
- add_requires(argv)
11
+ def options
12
+ argv = []
13
+ argv << "--color" if @submitted_options[:color]
14
+ argv << "--profile" if @submitted_options[:profile_examples]
15
+ argv << "--backtrace" if @submitted_options[:full_backtrace]
16
+ argv << "--tty" if @submitted_options[:tty]
17
+ argv << "--fail-fast" if @submitted_options[:fail_fast]
18
+ argv << "--options" << @submitted_options[:custom_options_file] if @submitted_options[:custom_options_file]
19
+ argv << "--order" << @submitted_options[:order] if @submitted_options[:order]
25
20
 
26
- argv + @submitted_options[:files_or_directories_to_run]
27
- end
21
+ add_failure_exit_code(argv)
22
+ add_full_description(argv)
23
+ add_line_numbers(argv)
24
+ add_filter(argv, :inclusion, @filter_manager.inclusions)
25
+ add_filter(argv, :exclusion, @filter_manager.exclusions)
26
+ add_formatters(argv)
27
+ add_libs(argv)
28
+ add_requires(argv)
28
29
 
29
- def add_full_description(argv)
30
- if @submitted_options[:full_description]
31
- # The argument to --example is regexp-escaped before being stuffed
32
- # into a regexp when received for the first time (see OptionParser).
33
- # Hence, merely grabbing the source of this regexp will retain the
34
- # backslashes, so we must remove them.
35
- argv << "--example" << @submitted_options[:full_description].source.delete('\\')
30
+ argv + @submitted_options[:files_or_directories_to_run]
36
31
  end
37
- end
38
32
 
39
- def add_line_numbers(argv)
40
- if @submitted_options[:line_numbers]
41
- argv.push(*@submitted_options[:line_numbers].inject([]){|a,l| a << "--line_number" << l})
33
+ def add_failure_exit_code(argv)
34
+ if @submitted_options[:failure_exit_code]
35
+ argv << "--failure-exit-code" << @submitted_options[:failure_exit_code].to_s
36
+ end
42
37
  end
43
- end
44
38
 
45
- def add_filter(argv, name, hash)
46
- hash.each_pair do |k, v|
47
- next if [:if,:unless].include?(k)
48
- tag = name == :inclusion ? k.to_s : "~#{k.to_s}"
49
- tag << ":#{v.to_s}" if v.is_a?(String)
50
- argv << "--tag" << tag
51
- end unless hash.empty?
52
- end
39
+ def add_full_description(argv)
40
+ if @submitted_options[:full_description]
41
+ # The argument to --example is regexp-escaped before being stuffed
42
+ # into a regexp when received for the first time (see OptionParser).
43
+ # Hence, merely grabbing the source of this regexp will retain the
44
+ # backslashes, so we must remove them.
45
+ argv << "--example" << @submitted_options[:full_description].source.delete('\\')
46
+ end
47
+ end
53
48
 
54
- def add_formatters(argv)
55
- @submitted_options[:formatters].each do |pair|
56
- argv << "--format" << pair[0]
57
- argv << "--out" << pair[1] if pair[1]
58
- end if @submitted_options[:formatters]
59
- end
49
+ def add_line_numbers(argv)
50
+ if @submitted_options[:line_numbers]
51
+ argv.push(*@submitted_options[:line_numbers].inject([]){|a,l| a << "--line_number" << l})
52
+ end
53
+ end
60
54
 
61
- def add_libs(argv)
62
- @submitted_options[:libs].each do |path|
63
- argv << "-I" << path
64
- end if @submitted_options[:libs]
65
- end
55
+ def add_filter(argv, name, hash)
56
+ hash.each_pair do |k, v|
57
+ next if [:if,:unless].include?(k)
58
+ tag = name == :inclusion ? k.to_s : "~#{k}"
59
+ tag << ":#{v}" if v.is_a?(String)
60
+ argv << "--tag" << tag
61
+ end unless hash.empty?
62
+ end
63
+
64
+ def add_formatters(argv)
65
+ @submitted_options[:formatters].each do |pair|
66
+ argv << "--format" << pair[0]
67
+ argv << "--out" << pair[1] if pair[1]
68
+ end if @submitted_options[:formatters]
69
+ end
70
+
71
+ def add_libs(argv)
72
+ @submitted_options[:libs].each do |path|
73
+ argv << "-I" << path
74
+ end if @submitted_options[:libs]
75
+ end
66
76
 
67
- def add_requires(argv)
68
- @submitted_options[:requires].each do |path|
69
- argv << "--require" << path
70
- end if @submitted_options[:requires]
77
+ def add_requires(argv)
78
+ @submitted_options[:requires].each do |path|
79
+ argv << "--require" << path
80
+ end if @submitted_options[:requires]
81
+ end
71
82
  end
72
83
  end
@@ -1,6 +1,18 @@
1
1
  module RSpec
2
2
  module Core
3
3
  module DSL
4
+ # Generates a subclass of [ExampleGroup](ExampleGroup)
5
+ #
6
+ # ## Examples:
7
+ #
8
+ # describe "something" do
9
+ # it "does something" do
10
+ # # example code goes here
11
+ # end
12
+ # end
13
+ #
14
+ # @see ExampleGroup
15
+ # @see ExampleGroup.describe
4
16
  def describe(*args, &example_group_block)
5
17
  RSpec::Core::ExampleGroup.describe(*args, &example_group_block).register
6
18
  end
@@ -1,7 +1,16 @@
1
1
  module RSpec
2
2
  module Core
3
+ # Wrapper for an instance of a subclass of [ExampleGroup](ExampleGroup). An
4
+ # instance of `Example` is returned by the
5
+ # [example](ExampleGroup#example-instance_method) method available in
6
+ # examples, [before](Hooks#before-instance_method) and
7
+ # [after](Hooks#after-instance_method) hooks, and yielded to
8
+ # [around](Hooks#around-instance_method) hooks.
9
+ # @see ExampleGroup
3
10
  class Example
4
-
11
+ # @private
12
+ #
13
+ # Used to define methods that delegate to this example's metadata
5
14
  def self.delegate_to_metadata(*keys)
6
15
  keys.each do |key|
7
16
  define_method(key) {@metadata[key]}
@@ -20,17 +29,22 @@ module RSpec
20
29
  #
21
30
  # Returns the metadata object associated with this example.
22
31
  attr_reader :metadata
23
-
32
+
24
33
  # @attr_reader
25
- # @api private
34
+ # @private
26
35
  #
27
36
  # Returns the example_group_instance that provides the context for
28
37
  # running this example.
29
38
  attr_reader :example_group_instance
30
39
 
31
- def initialize(example_group_class, desc, options, example_block=nil)
32
- @example_group_class, @options, @example_block = example_group_class, options, example_block
33
- @metadata = @example_group_class.metadata.for_example(desc, options)
40
+ # Creates a new instance of Example.
41
+ # @param example_group_class the subclass of ExampleGroup in which this Example is declared
42
+ # @param description the String passed to the `it` method (or alias)
43
+ # @param metadata additional args passed to `it` to be used as metadata
44
+ # @param example_block the block of code that represents the example
45
+ def initialize(example_group_class, description, metadata, example_block=nil)
46
+ @example_group_class, @options, @example_block = example_group_class, metadata, example_block
47
+ @metadata = @example_group_class.metadata.for_example(description, metadata)
34
48
  @exception = nil
35
49
  @pending_declared_in_example = false
36
50
  end
@@ -48,6 +62,10 @@ module RSpec
48
62
 
49
63
  alias_method :pending?, :pending
50
64
 
65
+ # @api private
66
+ # @param example_group_instance the instance of an ExampleGroup subclass
67
+ # instance_evals the block submitted to the constructor in the
68
+ # context of the instance of ExampleGroup
51
69
  def run(example_group_instance, reporter)
52
70
  @example_group_instance = example_group_instance
53
71
  @example_group_instance.example = self
@@ -87,34 +105,50 @@ module RSpec
87
105
  finish(reporter)
88
106
  end
89
107
 
90
- def self.procsy(metadata, &block)
91
- Proc.new(&block).extend(Procsy).with(metadata)
108
+ # @private
109
+ #
110
+ # Wraps the example block in a Proc so it can invoked using `run` or
111
+ # `call` in [around](../Hooks#around-instance_method) hooks.
112
+ def self.procsy(metadata, &proc)
113
+ Proc.new(&proc).extend(Procsy).with(metadata)
92
114
  end
93
115
 
116
+ # @private
94
117
  module Procsy
95
118
  attr_reader :metadata
96
119
 
120
+ # @private
121
+ # @param [Proc]
122
+ # Adds a `run` method to the extended Proc, allowing it to be invoked
123
+ # in an [around](../Hooks#around-instance_method) hook using either
124
+ # `run` or `call`.
97
125
  def self.extended(object)
98
126
  def object.run; call; end
99
127
  end
100
128
 
129
+ # @private
101
130
  def with(metadata)
102
131
  @metadata = metadata
103
132
  self
104
133
  end
105
134
  end
106
135
 
107
- # @api private
136
+ # @private
137
+ def any_apply?(filters)
138
+ metadata.any_apply?(filters)
139
+ end
140
+
141
+ # @private
108
142
  def all_apply?(filters)
109
143
  @metadata.all_apply?(filters) || @example_group_class.all_apply?(filters)
110
144
  end
111
145
 
112
- # @api private
146
+ # @private
113
147
  def around_hooks
114
148
  @around_hooks ||= example_group.around_hooks_for(self)
115
149
  end
116
150
 
117
- # @api private
151
+ # @private
118
152
  #
119
153
  # Used internally to set an exception in an after hook, which
120
154
  # captures the exception but doesn't raise it.
@@ -122,7 +156,7 @@ module RSpec
122
156
  @exception ||= exception
123
157
  end
124
158
 
125
- # @api private
159
+ # @private
126
160
  #
127
161
  # Used internally to set an exception and fail without actually executing
128
162
  # the example when an exception is raised in before(:all).
@@ -132,11 +166,6 @@ module RSpec
132
166
  finish(reporter)
133
167
  end
134
168
 
135
- # @api private
136
- def any_apply?(filters)
137
- metadata.any_apply?(filters)
138
- end
139
-
140
169
  private
141
170
 
142
171
  def with_around_hooks(&block)
@@ -152,8 +181,14 @@ module RSpec
152
181
  record :started_at => Time.now
153
182
  end
154
183
 
184
+ # @private
185
+ module NotPendingExampleFixed
186
+ def pending_fixed?; false; end
187
+ end
188
+
155
189
  def finish(reporter)
156
190
  if @exception
191
+ @exception.extend(NotPendingExampleFixed) unless @exception.respond_to?(:pending_fixed?)
157
192
  record_finished 'failed', :exception => @exception
158
193
  reporter.example_failed self
159
194
  false
@@ -162,7 +197,7 @@ module RSpec
162
197
  reporter.example_pending self
163
198
  true
164
199
  elsif pending
165
- record_finished 'pending', :pending_message => 'Not Yet Implemented'
200
+ record_finished 'pending', :pending_message => String === pending ? pending : Pending::NO_REASON_GIVEN
166
201
  reporter.example_pending self
167
202
  true
168
203
  else
@@ -1,32 +1,40 @@
1
1
  module RSpec
2
2
  module Core
3
+ # ExampleGroup and Example are the main structural elements of rspec-core.
4
+ # Consider this example:
5
+ #
6
+ # describe Thing do
7
+ # it "does something" do
8
+ # end
9
+ # end
10
+ #
11
+ # The object returned by `describe Thing` is a subclass of ExampleGroup.
12
+ # The object returned by `it "does something"` is an instance of Example,
13
+ # which serves as a wrapper for an instance of the ExampleGroup in which it
14
+ # is declared.
3
15
  class ExampleGroup
4
16
  extend MetadataHashBuilder::WithDeprecationWarning
5
17
  extend Extensions::ModuleEvalWithArgs
6
- extend Subject::ClassMethods
18
+ extend Subject::ExampleGroupMethods
7
19
  extend Hooks
8
20
 
9
21
  include Extensions::InstanceEvalWithArgs
10
- include Subject::InstanceMethods
22
+ include Subject::ExampleMethods
11
23
  include Pending
12
24
  include Let
13
25
 
14
- attr_accessor :example
15
-
16
- def running_example
17
- RSpec.deprecate("running_example", "example")
18
- example
19
- end
20
-
26
+ # @private
21
27
  def self.world
22
28
  RSpec.world
23
29
  end
24
30
 
31
+ # @private
25
32
  def self.register
26
33
  world.register(self)
27
34
  end
28
35
 
29
36
  class << self
37
+ # @private
30
38
  def self.delegate_to_metadata(*names)
31
39
  names.each do |name|
32
40
  define_method name do
@@ -35,16 +43,18 @@ module RSpec
35
43
  end
36
44
  end
37
45
 
38
- delegate_to_metadata :description, :describes, :file_path
46
+ delegate_to_metadata :description, :described_class, :file_path
39
47
  alias_method :display_name, :description
40
- alias_method :described_class, :describes
48
+ # @private
49
+ alias_method :describes, :described_class
41
50
  end
42
51
 
52
+ # @private
43
53
  def self.define_example_method(name, extra_options={})
44
54
  module_eval(<<-END_RUBY, __FILE__, __LINE__)
45
55
  def self.#{name}(desc=nil, *args, &block)
46
56
  options = build_metadata_hash_from(args)
47
- options.update(:pending => true) unless block
57
+ options.update(:pending => RSpec::Core::Pending::NOT_YET_IMPLEMENTED) unless block
48
58
  options.update(#{extra_options.inspect})
49
59
  examples << RSpec::Core::Example.new(self, desc, options, block)
50
60
  examples.last
@@ -53,31 +63,27 @@ module RSpec
53
63
  end
54
64
 
55
65
  define_example_method :example
66
+ define_example_method :it
67
+ define_example_method :specify
68
+
69
+ define_example_method :focused, :focused => true, :focus => true
70
+ define_example_method :focus, :focused => true, :focus => true
71
+
72
+ define_example_method :pending, :pending => true
73
+ define_example_method :xexample, :pending => 'Temporarily disabled with xexample'
74
+ define_example_method :xit, :pending => 'Temporarily disabled with xit'
75
+ define_example_method :xspecify, :pending => 'Temporarily disabled with xspecify'
56
76
 
57
77
  class << self
58
78
  alias_method :alias_example_to, :define_example_method
59
79
  end
60
80
 
61
- alias_example_to :it
62
- alias_example_to :specify
63
-
64
- alias_example_to :pending, :pending => true
65
- alias_example_to :xexample, :pending => true
66
- alias_example_to :xit, :pending => true
67
- alias_example_to :xspecify, :pending => true
68
-
69
- alias_example_to :focused, :focused => true, :focus => true
70
- alias_example_to :focus, :focused => true, :focus => true
71
-
81
+ # @private
72
82
  def self.define_nested_shared_group_method(new_name, report_label=nil)
73
83
  module_eval(<<-END_RUBY, __FILE__, __LINE__)
74
84
  def self.#{new_name}(name, *args, &customization_block)
75
- shared_block = find_shared("examples", name)
76
- raise "Could not find shared examples \#{name.inspect}" unless shared_block
77
-
78
85
  group = describe("#{report_label || "it should behave like"} \#{name}") do
79
- module_eval_with_args(*args, &shared_block)
80
- module_eval(&customization_block) if customization_block
86
+ find_and_eval_shared("examples", name, *args, &customization_block)
81
87
  end
82
88
  group.metadata[:shared_group_name] = name
83
89
  group
@@ -93,45 +99,82 @@ module RSpec
93
99
 
94
100
  alias_it_should_behave_like_to :it_behaves_like, "behaves like"
95
101
 
96
- def self.include_context(name)
97
- module_eval(&find_shared("context", name))
102
+ # Includes shared content declared with `name`.
103
+ #
104
+ # @see SharedExampleGroup
105
+ def self.include_context(name, *args)
106
+ block_given? ? block_not_supported("context") : find_and_eval_shared("context", name, *args)
107
+ end
108
+
109
+ # Includes shared content declared with `name`.
110
+ #
111
+ # @see SharedExampleGroup
112
+ def self.include_examples(name, *args)
113
+ block_given? ? block_not_supported("examples") : find_and_eval_shared("examples", name, *args)
98
114
  end
99
115
 
100
- def self.include_examples(name)
101
- module_eval(&find_shared("examples", name))
116
+ # @private
117
+ def self.block_not_supported(label)
118
+ warn("Customization blocks not supported for include_#{label}. Use it_behaves_like instead.")
102
119
  end
103
120
 
104
- def self.find_shared(label, name)
105
- if world.shared_example_groups.has_key?(name)
106
- world.shared_example_groups[name]
107
- else
108
- raise ArgumentError, "Could not find shared #{label} #{name.inspect}"
109
- end
121
+ # @private
122
+ def self.find_and_eval_shared(label, name, *args, &customization_block)
123
+ raise ArgumentError, "Could not find shared #{label} #{name.inspect}" unless
124
+ shared_block = world.shared_example_groups[name]
125
+
126
+ module_eval_with_args(*args, &shared_block)
127
+ module_eval(&customization_block) if customization_block
110
128
  end
111
129
 
130
+ # @private
112
131
  def self.examples
113
132
  @examples ||= []
114
133
  end
115
-
134
+
135
+ # @private
116
136
  def self.filtered_examples
117
137
  world.filtered_examples[self]
118
138
  end
119
139
 
140
+ # @private
120
141
  def self.descendant_filtered_examples
121
142
  @descendant_filtered_examples ||= filtered_examples + children.inject([]){|l,c| l + c.descendant_filtered_examples}
122
143
  end
123
144
 
145
+ # The [Metadata](Metadata) object associated with this group.
124
146
  # @see Metadata
125
147
  def self.metadata
126
148
  @metadata if defined?(@metadata)
127
149
  end
128
150
 
129
- # @api private
151
+ # @private
130
152
  # @return [Metadata] belonging to the parent of a nested [ExampleGroup](ExampleGroup)
131
153
  def self.superclass_metadata
132
154
  @superclass_metadata ||= self.superclass.respond_to?(:metadata) ? self.superclass.metadata : nil
133
155
  end
134
156
 
157
+ # Generates a subclass of this example group which inherits
158
+ # everything except the examples themselves.
159
+ #
160
+ # ## Examples
161
+ #
162
+ # describe "something" do # << This describe method is defined in
163
+ # # << RSpec::Core::DSL, included in the
164
+ # # << global namespace
165
+ # before do
166
+ # do_something_before
167
+ # end
168
+ #
169
+ # let(:thing) { Thing.new }
170
+ #
171
+ # describe "attribute (of something)" do
172
+ # # examples in the group get the before hook
173
+ # # declared above, and can access `thing`
174
+ # end
175
+ # end
176
+ #
177
+ # @see DSL#describe
135
178
  def self.describe(*args, &example_group_block)
136
179
  @_subclass_count ||= 0
137
180
  @_subclass_count += 1
@@ -151,6 +194,7 @@ module RSpec
151
194
  alias_method :context, :describe
152
195
  end
153
196
 
197
+ # @private
154
198
  def self.subclass(parent, args, &example_group_block)
155
199
  subclass = Class.new(parent)
156
200
  subclass.set_it_up(*args)
@@ -158,22 +202,27 @@ module RSpec
158
202
  subclass
159
203
  end
160
204
 
205
+ # @private
161
206
  def self.children
162
207
  @children ||= [].extend(Extensions::Ordered)
163
208
  end
164
209
 
210
+ # @private
165
211
  def self.descendants
166
212
  @_descendants ||= [self] + children.inject([]) {|list, c| list + c.descendants}
167
213
  end
168
214
 
215
+ # @private
169
216
  def self.ancestors
170
217
  @_ancestors ||= super().select {|a| a < RSpec::Core::ExampleGroup}
171
218
  end
172
219
 
220
+ # @private
173
221
  def self.top_level?
174
222
  @top_level ||= superclass == ExampleGroup
175
223
  end
176
224
 
225
+ # @private
177
226
  def self.ensure_example_groups_are_configured
178
227
  unless defined?(@@example_groups_configured)
179
228
  RSpec.configuration.configure_mock_framework
@@ -182,6 +231,7 @@ module RSpec
182
231
  end
183
232
  end
184
233
 
234
+ # @private
185
235
  def self.set_it_up(*args)
186
236
  # Ruby 1.9 has a bug that can lead to infinite recursion and a
187
237
  # SystemStackError if you include a module in a superclass after
@@ -199,22 +249,26 @@ module RSpec
199
249
  world.configure_group(self)
200
250
  end
201
251
 
252
+ # @private
202
253
  def self.before_all_ivars
203
254
  @before_all_ivars ||= {}
204
255
  end
205
256
 
257
+ # @private
206
258
  def self.store_before_all_ivars(example_group_instance)
207
259
  return if example_group_instance.instance_variables.empty?
208
- example_group_instance.instance_variables.each { |ivar|
260
+ example_group_instance.instance_variables.each { |ivar|
209
261
  before_all_ivars[ivar] = example_group_instance.instance_variable_get(ivar)
210
262
  }
211
263
  end
212
264
 
265
+ # @private
213
266
  def self.assign_before_all_ivars(ivars, example_group_instance)
214
267
  return if ivars.empty?
215
268
  ivars.each { |ivar, val| example_group_instance.instance_variable_set(ivar, val) }
216
269
  end
217
270
 
271
+ # @private
218
272
  def self.run_before_all_hooks(example_group_instance)
219
273
  return if descendant_filtered_examples.empty?
220
274
  assign_before_all_ivars(superclass.before_all_ivars, example_group_instance)
@@ -223,6 +277,7 @@ module RSpec
223
277
  store_before_all_ivars(example_group_instance)
224
278
  end
225
279
 
280
+ # @private
226
281
  def self.run_around_each_hooks(example, initial_procsy)
227
282
  example.around_hooks.reverse.inject(initial_procsy) do |procsy, around_hook|
228
283
  Example.procsy(procsy.metadata) do
@@ -231,16 +286,19 @@ module RSpec
231
286
  end
232
287
  end
233
288
 
289
+ # @private
234
290
  def self.run_before_each_hooks(example)
235
291
  world.run_hook_filtered(:before, :each, self, example.example_group_instance, example)
236
292
  ancestors.reverse.each { |ancestor| ancestor.run_hook(:before, :each, example.example_group_instance) }
237
293
  end
238
294
 
295
+ # @private
239
296
  def self.run_after_each_hooks(example)
240
297
  ancestors.each { |ancestor| ancestor.run_hook(:after, :each, example.example_group_instance) }
241
298
  world.run_hook_filtered(:after, :each, self, example.example_group_instance, example)
242
299
  end
243
300
 
301
+ # @private
244
302
  def self.run_after_all_hooks(example_group_instance)
245
303
  return if descendant_filtered_examples.empty?
246
304
  assign_before_all_ivars(before_all_ivars, example_group_instance)
@@ -261,10 +319,12 @@ An error occurred in an after(:all) hook.
261
319
  world.run_hook_filtered(:after, :all, self, example_group_instance)
262
320
  end
263
321
 
322
+ # @private
264
323
  def self.around_hooks_for(example)
265
324
  world.find_hook(:around, :each, self, example) + ancestors.reverse.inject([]){|l,a| l + a.find_hook(:around, :each, self, example)}
266
325
  end
267
326
 
327
+ # Runs all the examples in this group
268
328
  def self.run(reporter)
269
329
  if RSpec.wants_to_quit
270
330
  RSpec.clear_remaining_example_groups if top_level?
@@ -286,6 +346,19 @@ An error occurred in an after(:all) hook.
286
346
  end
287
347
  end
288
348
 
349
+ # @private
350
+ def self.run_examples(reporter)
351
+ filtered_examples.ordered.map do |example|
352
+ next if RSpec.wants_to_quit
353
+ instance = new
354
+ set_ivars(instance, before_all_ivars)
355
+ succeeded = example.run(instance, reporter)
356
+ RSpec.wants_to_quit = true if fail_fast? && !succeeded
357
+ succeeded
358
+ end.all?
359
+ end
360
+
361
+ # @private
289
362
  def self.fail_filtered_examples(exception, reporter)
290
363
  filtered_examples.each { |example| example.fail_with_exception(reporter, exception) }
291
364
 
@@ -297,49 +370,66 @@ An error occurred in an after(:all) hook.
297
370
  false
298
371
  end
299
372
 
373
+ # @private
300
374
  def self.fail_fast?
301
375
  RSpec.configuration.fail_fast?
302
376
  end
303
377
 
304
- def self.run_examples(reporter)
305
- filtered_examples.ordered.map do |example|
306
- next if RSpec.wants_to_quit
307
- instance = new
308
- set_ivars(instance, before_all_ivars)
309
- succeeded = example.run(instance, reporter)
310
- RSpec.wants_to_quit = true if fail_fast? && !succeeded
311
- succeeded
312
- end.all?
313
- end
314
-
315
- # @api private
378
+ # @private
316
379
  def self.any_apply?(filters)
317
380
  metadata.any_apply?(filters)
318
381
  end
319
382
 
320
- # @api private
383
+ # @private
321
384
  def self.all_apply?(filters)
322
385
  metadata.all_apply?(filters)
323
386
  end
324
387
 
388
+ # @private
325
389
  def self.declaration_line_numbers
326
390
  @declaration_line_numbers ||= [metadata[:example_group][:line_number]] +
327
391
  examples.collect {|e| e.metadata[:line_number]} +
328
392
  children.inject([]) {|l,c| l + c.declaration_line_numbers}
329
393
  end
330
394
 
395
+ # @private
331
396
  def self.top_level_description
332
397
  ancestors.last.description
333
398
  end
334
399
 
400
+ # @private
335
401
  def self.set_ivars(instance, ivars)
336
402
  ivars.each {|name, value| instance.instance_variable_set(name, value)}
337
403
  end
338
404
 
405
+ # @attr_reader
406
+ # Returns the [Example](Example) object that wraps this instance of
407
+ # `ExampleGroup`
408
+ attr_accessor :example
409
+
410
+ # @deprecated use [example](ExampleGroup#example-instance_method)
411
+ def running_example
412
+ RSpec.deprecate("running_example", "example")
413
+ example
414
+ end
415
+
416
+ # Returns the class or module passed to the `describe` method (or alias).
417
+ # Returns nil if the subject is not a class or module.
418
+ # @example
419
+ # describe Thing do
420
+ # it "does something" do
421
+ # described_class == Thing
422
+ # end
423
+ # end
424
+ #
425
+ #
339
426
  def described_class
340
427
  self.class.described_class
341
428
  end
342
429
 
430
+ # @private
431
+ # instance_evals the block, capturing and reporting an exception if
432
+ # raised
343
433
  def instance_eval_with_rescue(&hook)
344
434
  begin
345
435
  instance_eval(&hook)