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.
- data/License.txt +24 -0
- data/README.md +197 -37
- data/features/command_line/format_option.feature +3 -3
- data/features/command_line/init.feature +18 -0
- data/features/example_groups/shared_examples.feature +1 -1
- data/features/hooks/around_hooks.feature +4 -4
- data/features/pending/pending_examples.feature +5 -5
- data/features/support/env.rb +8 -1
- data/lib/autotest/rspec2.rb +2 -6
- data/lib/rspec/core.rb +48 -158
- data/lib/rspec/core/backward_compatibility.rb +2 -0
- data/lib/rspec/core/command_line.rb +4 -0
- data/lib/rspec/core/configuration.rb +201 -106
- data/lib/rspec/core/configuration_options.rb +2 -1
- data/lib/rspec/core/deprecation.rb +2 -3
- data/lib/rspec/core/drb_options.rb +69 -58
- data/lib/rspec/core/dsl.rb +12 -0
- data/lib/rspec/core/example.rb +53 -18
- data/lib/rspec/core/example_group.rb +144 -54
- data/lib/rspec/core/extensions.rb +4 -4
- data/lib/rspec/core/extensions/instance_eval_with_args.rb +5 -0
- data/lib/rspec/core/extensions/kernel.rb +1 -1
- data/lib/rspec/core/extensions/module_eval_with_args.rb +4 -0
- data/lib/rspec/core/extensions/ordered.rb +7 -2
- data/lib/rspec/core/filter_manager.rb +69 -36
- data/lib/rspec/core/formatters/base_text_formatter.rb +1 -1
- data/lib/rspec/core/formatters/html_formatter.rb +10 -4
- data/lib/rspec/core/hooks.rb +93 -34
- data/lib/rspec/core/let.rb +62 -61
- data/lib/rspec/core/metadata.rb +103 -80
- data/lib/rspec/core/metadata_hash_builder.rb +4 -0
- data/lib/rspec/core/option_parser.rb +42 -44
- data/lib/rspec/core/pending.rb +25 -3
- data/lib/rspec/core/project_initializer.rb +62 -0
- data/lib/rspec/core/rake_task.rb +7 -13
- data/lib/rspec/core/runner.rb +2 -2
- data/lib/rspec/core/shared_context.rb +1 -1
- data/lib/rspec/core/shared_example_group.rb +11 -5
- data/lib/rspec/core/subject.rb +3 -3
- data/lib/rspec/core/version.rb +1 -1
- data/lib/rspec/monkey.rb +1 -1
- data/lib/rspec/monkey/spork/test_framework/rspec.rb +2 -0
- data/spec/command_line/order_spec.rb +19 -13
- data/spec/rspec/core/command_line_spec.rb +1 -5
- data/spec/rspec/core/configuration_options_spec.rb +22 -27
- data/spec/rspec/core/configuration_spec.rb +32 -14
- data/spec/rspec/core/drb_command_line_spec.rb +20 -37
- data/spec/rspec/core/drb_options_spec.rb +51 -3
- data/spec/rspec/core/example_group_spec.rb +101 -84
- data/spec/rspec/core/example_spec.rb +14 -0
- data/spec/rspec/core/filter_manager_spec.rb +114 -33
- data/spec/rspec/core/formatters/html_formatted-1.8.7-jruby.html +17 -69
- data/spec/rspec/core/formatters/html_formatted-1.8.7.html +14 -4
- data/spec/rspec/core/formatters/html_formatted-1.9.2.html +14 -4
- data/spec/rspec/core/formatters/html_formatted-1.9.3.html +14 -4
- data/spec/rspec/core/formatters/html_formatter_spec.rb +1 -1
- data/spec/rspec/core/formatters/text_mate_formatted-1.8.7-jruby.html +20 -72
- data/spec/rspec/core/formatters/text_mate_formatted-1.8.7.html +24 -14
- data/spec/rspec/core/formatters/text_mate_formatted-1.9.2.html +29 -19
- data/spec/rspec/core/formatters/text_mate_formatted-1.9.3.html +29 -19
- data/spec/rspec/core/formatters/text_mate_formatter_spec.rb +1 -2
- data/spec/rspec/core/metadata_spec.rb +77 -45
- data/spec/rspec/core/option_parser_spec.rb +5 -0
- data/spec/rspec/core/pending_example_spec.rb +44 -12
- data/spec/rspec/core/project_initializer_spec.rb +130 -0
- data/spec/rspec/core/rake_task_spec.rb +1 -1
- data/spec/spec_helper.rb +2 -0
- data/spec/support/matchers.rb +2 -12
- metadata +18 -16
- data/features/command_line/configure.feature +0 -22
- data/lib/rspec/core/command_line_configuration.rb +0 -62
- data/lib/rspec/core/errors.rb +0 -13
- 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, :
|
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
|
-
# @
|
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
|
-
# @
|
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
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
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
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
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
|
-
|
27
|
-
|
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
|
-
|
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
|
-
|
40
|
-
|
41
|
-
|
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
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
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
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
end
|
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
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
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
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
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
|
data/lib/rspec/core/dsl.rb
CHANGED
@@ -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
|
data/lib/rspec/core/example.rb
CHANGED
@@ -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
|
-
# @
|
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
|
-
|
32
|
-
|
33
|
-
|
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
|
-
|
91
|
-
|
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
|
-
# @
|
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
|
-
# @
|
146
|
+
# @private
|
113
147
|
def around_hooks
|
114
148
|
@around_hooks ||= example_group.around_hooks_for(self)
|
115
149
|
end
|
116
150
|
|
117
|
-
# @
|
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
|
-
# @
|
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 =>
|
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::
|
18
|
+
extend Subject::ExampleGroupMethods
|
7
19
|
extend Hooks
|
8
20
|
|
9
21
|
include Extensions::InstanceEvalWithArgs
|
10
|
-
include Subject::
|
22
|
+
include Subject::ExampleMethods
|
11
23
|
include Pending
|
12
24
|
include Let
|
13
25
|
|
14
|
-
|
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, :
|
46
|
+
delegate_to_metadata :description, :described_class, :file_path
|
39
47
|
alias_method :display_name, :description
|
40
|
-
|
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 =>
|
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
|
-
|
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
|
-
|
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
|
-
|
97
|
-
|
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
|
-
|
101
|
-
|
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
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
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
|
-
# @
|
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
|
-
|
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
|
-
# @
|
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)
|