rspec-core 2.8.0.rc1 → 2.8.0.rc2

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