rspec-core 2.99.2 → 3.0.0.beta1
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.
- checksums.yaml +14 -6
- checksums.yaml.gz.sig +2 -0
- data.tar.gz.sig +0 -0
- data/Changelog.md +103 -191
- data/License.txt +1 -0
- data/README.md +4 -25
- data/features/Upgrade.md +2 -14
- data/features/command_line/dry_run.feature +29 -0
- data/features/command_line/example_name_option.feature +1 -1
- data/features/command_line/fail_fast.feature +26 -0
- data/features/command_line/format_option.feature +3 -3
- data/features/command_line/line_number_option.feature +16 -11
- data/features/command_line/order.feature +2 -3
- data/features/command_line/pattern_option.feature +3 -3
- data/features/command_line/randomization.feature +63 -0
- data/features/command_line/require_option.feature +2 -2
- data/features/command_line/ruby.feature +1 -1
- data/features/configuration/alias_example_to.feature +13 -22
- data/features/configuration/{backtrace_clean_patterns.feature → backtrace_exclusion_patterns.feature} +17 -14
- data/features/configuration/custom_settings.feature +11 -11
- data/features/configuration/overriding_global_ordering.feature +93 -0
- data/features/configuration/profile.feature +13 -13
- data/features/configuration/read_options_from_file.feature +7 -7
- data/features/example_groups/basic_structure.feature +1 -1
- data/features/example_groups/shared_context.feature +8 -8
- data/features/example_groups/shared_examples.feature +6 -14
- data/features/expectation_framework_integration/configure_expectation_framework.feature +27 -122
- data/features/filtering/exclusion_filters.feature +2 -5
- data/features/filtering/inclusion_filters.feature +1 -5
- data/features/formatters/json_formatter.feature +2 -2
- data/features/formatters/text_formatter.feature +4 -4
- data/features/helper_methods/arbitrary_methods.feature +2 -2
- data/features/helper_methods/let.feature +5 -5
- data/features/helper_methods/modules.feature +5 -8
- data/features/hooks/around_hooks.feature +2 -2
- data/features/hooks/before_and_after_hooks.feature +14 -14
- data/features/hooks/filtering.feature +12 -14
- data/features/metadata/described_class.feature +1 -1
- data/features/metadata/user_defined.feature +16 -29
- data/features/mock_framework_integration/use_flexmock.feature +1 -1
- data/features/mock_framework_integration/use_mocha.feature +1 -1
- data/features/mock_framework_integration/use_rr.feature +1 -1
- data/features/mock_framework_integration/use_rspec.feature +5 -5
- data/features/pending/pending_examples.feature +5 -5
- data/features/spec_files/arbitrary_file_suffix.feature +1 -1
- data/features/step_definitions/additional_cli_steps.rb +3 -3
- data/features/subject/explicit_subject.feature +8 -8
- data/features/subject/implicit_receiver.feature +29 -0
- data/features/subject/implicit_subject.feature +4 -4
- data/features/support/env.rb +10 -3
- data/features/support/require_expect_syntax_in_aruba_specs.rb +16 -0
- data/lib/rspec/core.rb +11 -48
- data/lib/rspec/core/backport_random.rb +302 -0
- data/lib/rspec/core/backtrace_formatter.rb +65 -0
- data/lib/rspec/core/command_line.rb +7 -18
- data/lib/rspec/core/configuration.rb +202 -507
- data/lib/rspec/core/configuration_options.rb +17 -30
- data/lib/rspec/core/example.rb +29 -39
- data/lib/rspec/core/example_group.rb +166 -259
- data/lib/rspec/core/filter_manager.rb +30 -47
- data/lib/rspec/core/flat_map.rb +17 -0
- data/lib/rspec/core/formatters.rb +0 -138
- data/lib/rspec/core/formatters/base_formatter.rb +46 -1
- data/lib/rspec/core/formatters/base_text_formatter.rb +38 -61
- data/lib/rspec/core/formatters/deprecation_formatter.rb +21 -52
- data/lib/rspec/core/formatters/helpers.rb +0 -28
- data/lib/rspec/core/formatters/html_formatter.rb +1 -1
- data/lib/rspec/core/formatters/json_formatter.rb +38 -9
- data/lib/rspec/core/formatters/snippet_extractor.rb +14 -5
- data/lib/rspec/core/hooks.rb +55 -39
- data/lib/rspec/core/memoized_helpers.rb +17 -167
- data/lib/rspec/core/metadata.rb +16 -64
- data/lib/rspec/core/option_parser.rb +30 -39
- data/lib/rspec/core/ordering.rb +154 -0
- data/lib/rspec/core/pending.rb +12 -69
- data/lib/rspec/core/project_initializer.rb +12 -10
- data/lib/rspec/core/rake_task.rb +5 -108
- data/lib/rspec/core/reporter.rb +15 -18
- data/lib/rspec/core/runner.rb +16 -30
- data/lib/rspec/core/shared_context.rb +3 -5
- data/lib/rspec/core/shared_example_group.rb +3 -51
- data/lib/rspec/core/shared_example_group/collection.rb +1 -19
- data/lib/rspec/core/version.rb +1 -1
- data/lib/rspec/core/warnings.rb +22 -0
- data/lib/rspec/core/world.rb +12 -8
- data/spec/command_line/order_spec.rb +20 -23
- data/spec/rspec/core/backtrace_formatter_spec.rb +216 -0
- data/spec/rspec/core/command_line_spec.rb +32 -48
- data/spec/rspec/core/configuration_options_spec.rb +19 -50
- data/spec/rspec/core/configuration_spec.rb +142 -713
- data/spec/rspec/core/drb_command_line_spec.rb +2 -0
- data/spec/rspec/core/dsl_spec.rb +0 -1
- data/spec/rspec/core/example_group_spec.rb +192 -223
- data/spec/rspec/core/example_spec.rb +40 -16
- data/spec/rspec/core/filter_manager_spec.rb +2 -2
- data/spec/rspec/core/formatters/base_formatter_spec.rb +0 -41
- data/spec/rspec/core/formatters/base_text_formatter_spec.rb +5 -123
- data/spec/rspec/core/formatters/deprecation_formatter_spec.rb +2 -87
- data/spec/rspec/core/formatters/documentation_formatter_spec.rb +2 -3
- data/spec/rspec/core/formatters/{text_mate_formatted.html → html_formatted-1.8.7-jruby.html} +44 -25
- data/spec/rspec/core/formatters/html_formatted-1.8.7-rbx.html +477 -0
- data/spec/rspec/core/formatters/{html_formatted.html → html_formatted-1.8.7.html} +42 -25
- data/spec/rspec/core/formatters/html_formatted-1.9.2.html +425 -0
- data/spec/rspec/core/formatters/html_formatted-1.9.3-jruby.html +416 -0
- data/spec/rspec/core/formatters/html_formatted-1.9.3-rbx.html +477 -0
- data/spec/rspec/core/formatters/html_formatted-1.9.3.html +419 -0
- data/spec/rspec/core/formatters/html_formatted-2.0.0.html +425 -0
- data/spec/rspec/core/formatters/html_formatter_spec.rb +21 -46
- data/spec/rspec/core/formatters/json_formatter_spec.rb +97 -8
- data/spec/rspec/core/hooks_filtering_spec.rb +5 -5
- data/spec/rspec/core/hooks_spec.rb +61 -47
- data/spec/rspec/core/memoized_helpers_spec.rb +20 -322
- data/spec/rspec/core/metadata_spec.rb +1 -24
- data/spec/rspec/core/option_parser_spec.rb +20 -62
- data/spec/rspec/core/ordering_spec.rb +102 -0
- data/spec/rspec/core/pending_example_spec.rb +0 -40
- data/spec/rspec/core/project_initializer_spec.rb +1 -25
- data/spec/rspec/core/rake_task_spec.rb +5 -72
- data/spec/rspec/core/random_spec.rb +47 -0
- data/spec/rspec/core/reporter_spec.rb +23 -48
- data/spec/rspec/core/runner_spec.rb +31 -39
- data/spec/rspec/core/shared_context_spec.rb +3 -15
- data/spec/rspec/core/shared_example_group/collection_spec.rb +4 -17
- data/spec/rspec/core/shared_example_group_spec.rb +12 -45
- data/spec/rspec/core/{deprecation_spec.rb → warnings_spec.rb} +3 -1
- data/spec/rspec/core_spec.rb +4 -21
- data/spec/spec_helper.rb +41 -5
- data/spec/support/helper_methods.rb +0 -29
- data/spec/support/sandboxed_mock_space.rb +0 -16
- data/spec/support/shared_example_groups.rb +7 -36
- data/spec/support/stderr_splitter.rb +36 -0
- metadata +163 -157
- metadata.gz.sig +1 -0
- data/exe/autospec +0 -13
- data/features/Autotest.md +0 -38
- data/features/configuration/treat_symbols_as_metadata_keys_with_true_values.feature +0 -52
- data/features/subject/attribute_of_subject.feature +0 -124
- data/features/subject/one_liner_syntax.feature +0 -71
- data/lib/autotest/discover.rb +0 -10
- data/lib/autotest/rspec2.rb +0 -77
- data/lib/rspec/core/backtrace_cleaner.rb +0 -46
- data/lib/rspec/core/backward_compatibility.rb +0 -55
- data/lib/rspec/core/caller_filter.rb +0 -60
- data/lib/rspec/core/deprecated_mutable_array_proxy.rb +0 -32
- data/lib/rspec/core/deprecation.rb +0 -26
- data/lib/rspec/core/extensions/instance_eval_with_args.rb +0 -44
- data/lib/rspec/core/extensions/kernel.rb +0 -9
- data/lib/rspec/core/extensions/module_eval_with_args.rb +0 -38
- data/lib/rspec/core/extensions/ordered.rb +0 -27
- data/lib/rspec/core/formatters/console_codes.rb +0 -42
- data/lib/rspec/core/formatters/text_mate_formatter.rb +0 -34
- data/lib/rspec/core/metadata_hash_builder.rb +0 -97
- data/lib/rspec/core/minitest_assertions_adapter.rb +0 -28
- data/lib/rspec/core/test_unit_assertions_adapter.rb +0 -30
- data/spec/autotest/discover_spec.rb +0 -49
- data/spec/autotest/failed_results_re_spec.rb +0 -45
- data/spec/autotest/rspec_spec.rb +0 -133
- data/spec/rspec/core/backtrace_cleaner_spec.rb +0 -68
- data/spec/rspec/core/caller_filter_spec.rb +0 -58
- data/spec/rspec/core/deprecations_spec.rb +0 -59
- data/spec/rspec/core/formatters/console_codes_spec.rb +0 -50
- data/spec/rspec/core/formatters/text_mate_formatter_spec.rb +0 -107
- data/spec/rspec/core/kernel_extensions_spec.rb +0 -9
- data/spec/rspec/core/pending_spec.rb +0 -27
- data/spec/support/silence_dsl_deprecations.rb +0 -32
|
@@ -8,14 +8,9 @@ module RSpec
|
|
|
8
8
|
attr_reader :options
|
|
9
9
|
|
|
10
10
|
def initialize(args)
|
|
11
|
-
@args = args.
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
if @args.include?("--line_number")
|
|
17
|
-
@args[@args.index("--line_number")] = "--line-number"
|
|
18
|
-
end
|
|
11
|
+
@args = args.map {|a|
|
|
12
|
+
a.sub("default_path", "default-path").sub("line_number", "line-number")
|
|
13
|
+
}
|
|
19
14
|
end
|
|
20
15
|
|
|
21
16
|
def configure(config)
|
|
@@ -29,11 +24,16 @@ module RSpec
|
|
|
29
24
|
end
|
|
30
25
|
|
|
31
26
|
def parse_options
|
|
32
|
-
@options
|
|
33
|
-
|
|
34
|
-
|
|
27
|
+
@options = (file_options << command_line_options << env_options).
|
|
28
|
+
each {|opts|
|
|
29
|
+
filter_manager.include opts.delete(:inclusion_filter) if opts.has_key?(:inclusion_filter)
|
|
30
|
+
filter_manager.exclude opts.delete(:exclusion_filter) if opts.has_key?(:exclusion_filter)
|
|
31
|
+
}.
|
|
32
|
+
inject {|h, opts|
|
|
33
|
+
h.merge(opts) {|k, oldval, newval|
|
|
34
|
+
[:libs, :requires].include?(k) ? oldval + newval : newval
|
|
35
|
+
}
|
|
35
36
|
}
|
|
36
|
-
end
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
def drb_argv
|
|
@@ -46,17 +46,15 @@ module RSpec
|
|
|
46
46
|
|
|
47
47
|
private
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
:
|
|
49
|
+
UNFORCED_OPTIONS = [
|
|
50
|
+
:requires, :profile, :drb, :libs, :files_or_directories_to_run,
|
|
51
51
|
:line_numbers, :full_description, :full_backtrace, :tty
|
|
52
52
|
].to_set
|
|
53
53
|
|
|
54
|
-
MERGED_OPTIONS = [:requires, :libs].to_set
|
|
55
|
-
|
|
56
54
|
UNPROCESSABLE_OPTIONS = [:libs, :formatters, :requires].to_set
|
|
57
55
|
|
|
58
56
|
def force?(key)
|
|
59
|
-
!
|
|
57
|
+
!UNFORCED_OPTIONS.include?(key)
|
|
60
58
|
end
|
|
61
59
|
|
|
62
60
|
def order(keys, *ordered)
|
|
@@ -78,17 +76,6 @@ module RSpec
|
|
|
78
76
|
options[:formatters].each { |pair| config.add_formatter(*pair) } if options[:formatters]
|
|
79
77
|
end
|
|
80
78
|
|
|
81
|
-
def extract_filters_from(*configs)
|
|
82
|
-
configs.compact.each do |config|
|
|
83
|
-
filter_manager.include config.delete(:inclusion_filter) if config.has_key?(:inclusion_filter)
|
|
84
|
-
filter_manager.exclude config.delete(:exclusion_filter) if config.has_key?(:exclusion_filter)
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
def all_configs
|
|
89
|
-
@all_configs ||= file_options << command_line_options << env_options
|
|
90
|
-
end
|
|
91
|
-
|
|
92
79
|
def file_options
|
|
93
80
|
custom_options_file ? [custom_options] : [global_options, project_options, local_options]
|
|
94
81
|
end
|
|
@@ -124,7 +111,7 @@ module RSpec
|
|
|
124
111
|
def args_from_options_file(path)
|
|
125
112
|
return [] unless path && File.exist?(path)
|
|
126
113
|
config_string = options_file_as_erb_string(path)
|
|
127
|
-
config_string.split(/\n+/)
|
|
114
|
+
FlatMap.flat_map(config_string.split(/\n+/), &:shellsplit)
|
|
128
115
|
end
|
|
129
116
|
|
|
130
117
|
def options_file_as_erb_string(path)
|
|
@@ -147,7 +134,7 @@ module RSpec
|
|
|
147
134
|
begin
|
|
148
135
|
File.join(File.expand_path("~"), ".rspec")
|
|
149
136
|
rescue ArgumentError
|
|
150
|
-
|
|
137
|
+
RSpec.warning "Unable to find ~/.rspec because the HOME environment variable is not set"
|
|
151
138
|
nil
|
|
152
139
|
end
|
|
153
140
|
end
|
data/lib/rspec/core/example.rb
CHANGED
|
@@ -44,7 +44,7 @@ module RSpec
|
|
|
44
44
|
delegate_to_metadata :full_description, :execution_result, :file_path, :pending, :location
|
|
45
45
|
|
|
46
46
|
# Returns the string submitted to `example` or its aliases (e.g.
|
|
47
|
-
# `specify`, `it`, etc). If no string is submitted (e.g. `it {
|
|
47
|
+
# `specify`, `it`, etc). If no string is submitted (e.g. `it { should
|
|
48
48
|
# do_something }`) it returns the message generated by the matcher if
|
|
49
49
|
# there is one, otherwise returns a message including the location of the
|
|
50
50
|
# example.
|
|
@@ -85,8 +85,6 @@ module RSpec
|
|
|
85
85
|
|
|
86
86
|
# @deprecated access options via metadata instead
|
|
87
87
|
def options
|
|
88
|
-
RSpec.deprecate("`RSpec::Core::Example#options`",
|
|
89
|
-
:replacement => "`RSpec::Core::Example#metadata`")
|
|
90
88
|
@options
|
|
91
89
|
end
|
|
92
90
|
|
|
@@ -109,17 +107,16 @@ module RSpec
|
|
|
109
107
|
start(reporter)
|
|
110
108
|
|
|
111
109
|
begin
|
|
112
|
-
unless pending
|
|
110
|
+
unless pending || RSpec.configuration.dry_run?
|
|
113
111
|
with_around_each_hooks do
|
|
114
112
|
begin
|
|
115
113
|
run_before_each
|
|
116
|
-
@example_group_instance.
|
|
117
|
-
rescue Pending::
|
|
114
|
+
@example_group_instance.instance_exec(self, &@example_block)
|
|
115
|
+
rescue Pending::PendingDeclaredInExample => e
|
|
118
116
|
@pending_declared_in_example = e.message
|
|
119
117
|
rescue Exception => e
|
|
120
118
|
set_exception(e)
|
|
121
119
|
ensure
|
|
122
|
-
assign_generated_description
|
|
123
120
|
run_after_each
|
|
124
121
|
end
|
|
125
122
|
end
|
|
@@ -131,6 +128,12 @@ module RSpec
|
|
|
131
128
|
@example_group_instance.instance_variable_set(ivar, nil)
|
|
132
129
|
end
|
|
133
130
|
@example_group_instance = nil
|
|
131
|
+
|
|
132
|
+
begin
|
|
133
|
+
assign_generated_description
|
|
134
|
+
rescue Exception => e
|
|
135
|
+
set_exception(e, "while assigning the example description")
|
|
136
|
+
end
|
|
134
137
|
end
|
|
135
138
|
|
|
136
139
|
finish(reporter)
|
|
@@ -138,16 +141,8 @@ module RSpec
|
|
|
138
141
|
RSpec.current_example = nil
|
|
139
142
|
end
|
|
140
143
|
|
|
141
|
-
#
|
|
142
|
-
#
|
|
143
|
-
# Wraps the example block in a Proc so it can invoked using `run` or
|
|
144
|
-
# `call` in [around](../Hooks#around-instance_method) hooks.
|
|
145
|
-
def self.procsy(metadata, &proc)
|
|
146
|
-
proc.extend(Procsy).with(metadata)
|
|
147
|
-
end
|
|
148
|
-
|
|
149
|
-
# Used to extend a `Proc` with behavior that makes it look something like
|
|
150
|
-
# an {Example} in an {Hooks#around around} hook.
|
|
144
|
+
# Wraps a `Proc` and exposes a `run` method for use in {Hooks#around
|
|
145
|
+
# around} hooks.
|
|
151
146
|
#
|
|
152
147
|
# @note Procsy, itself, is not a public API, but we're documenting it
|
|
153
148
|
# here to document how to interact with the object yielded to an
|
|
@@ -156,32 +151,30 @@ module RSpec
|
|
|
156
151
|
# @example
|
|
157
152
|
#
|
|
158
153
|
# RSpec.configure do |c|
|
|
159
|
-
# c.around do |ex| #
|
|
154
|
+
# c.around do |ex| # Procsy which wraps the example
|
|
160
155
|
# if ex.metadata[:key] == :some_value && some_global_condition
|
|
161
156
|
# raise "some message"
|
|
162
157
|
# end
|
|
163
158
|
# ex.run # run delegates to ex.call
|
|
164
159
|
# end
|
|
165
160
|
# end
|
|
166
|
-
|
|
161
|
+
class Procsy
|
|
167
162
|
# The `metadata` of the {Example} instance.
|
|
168
163
|
attr_reader :metadata
|
|
169
164
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
# Adds a `run` method to the extended Proc, allowing it to be invoked
|
|
173
|
-
# in an [around](../Hooks#around-instance_method) hook using either
|
|
174
|
-
# `run` or `call`.
|
|
175
|
-
def self.extended(proc)
|
|
176
|
-
# @api public
|
|
177
|
-
# Foo bar
|
|
178
|
-
def proc.run; call; end
|
|
165
|
+
Proc.public_instance_methods(false).each do |name|
|
|
166
|
+
define_method(name) { |*a, &b| @proc.__send__(name, *a, &b) }
|
|
179
167
|
end
|
|
168
|
+
alias run call
|
|
180
169
|
|
|
181
|
-
|
|
182
|
-
def with(metadata)
|
|
170
|
+
def initialize(metadata, &block)
|
|
183
171
|
@metadata = metadata
|
|
184
|
-
|
|
172
|
+
@proc = block
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
# @api private
|
|
176
|
+
def wrap(&block)
|
|
177
|
+
self.class.new(metadata, &block)
|
|
185
178
|
end
|
|
186
179
|
end
|
|
187
180
|
|
|
@@ -232,13 +225,13 @@ An error occurred #{context}
|
|
|
232
225
|
end
|
|
233
226
|
|
|
234
227
|
# @private
|
|
235
|
-
def
|
|
236
|
-
@example_group_instance.
|
|
228
|
+
def instance_exec_with_rescue(context = nil, &block)
|
|
229
|
+
@example_group_instance.instance_exec_with_rescue(self, context, &block)
|
|
237
230
|
end
|
|
238
231
|
|
|
239
232
|
# @private
|
|
240
|
-
def
|
|
241
|
-
@example_group_instance.
|
|
233
|
+
def instance_exec(*args, &block)
|
|
234
|
+
@example_group_instance.instance_exec(*args, &block)
|
|
242
235
|
end
|
|
243
236
|
|
|
244
237
|
private
|
|
@@ -247,7 +240,7 @@ An error occurred #{context}
|
|
|
247
240
|
if around_each_hooks.empty?
|
|
248
241
|
yield
|
|
249
242
|
else
|
|
250
|
-
@example_group_class.run_around_each_hooks(self,
|
|
243
|
+
@example_group_class.run_around_each_hooks(self, Procsy.new(metadata, &block))
|
|
251
244
|
end
|
|
252
245
|
rescue Exception => e
|
|
253
246
|
set_exception(e, "in an around(:each) hook")
|
|
@@ -308,9 +301,6 @@ An error occurred #{context}
|
|
|
308
301
|
if metadata[:description_args].empty? and !pending?
|
|
309
302
|
metadata[:description_args] << RSpec::Matchers.generated_description
|
|
310
303
|
end
|
|
311
|
-
rescue Exception => e
|
|
312
|
-
set_exception(e, "while assigning the example description")
|
|
313
|
-
ensure
|
|
314
304
|
RSpec::Matchers.clear_generated_description
|
|
315
305
|
end
|
|
316
306
|
|
|
@@ -13,14 +13,10 @@ module RSpec
|
|
|
13
13
|
# which serves as a wrapper for an instance of the ExampleGroup in which it
|
|
14
14
|
# is declared.
|
|
15
15
|
class ExampleGroup
|
|
16
|
-
extend MetadataHashBuilder::WithDeprecationWarning
|
|
17
|
-
extend Extensions::ModuleEvalWithArgs
|
|
18
16
|
extend Hooks
|
|
19
17
|
|
|
20
18
|
include MemoizedHelpers
|
|
21
|
-
include Extensions::InstanceEvalWithArgs
|
|
22
19
|
include Pending
|
|
23
|
-
include SharedExampleGroup
|
|
24
20
|
extend SharedExampleGroup
|
|
25
21
|
|
|
26
22
|
# @private
|
|
@@ -49,166 +45,116 @@ module RSpec
|
|
|
49
45
|
end
|
|
50
46
|
|
|
51
47
|
delegate_to_metadata :described_class, :file_path
|
|
52
|
-
|
|
48
|
+
alias_method :display_name, :description
|
|
53
49
|
# @private
|
|
54
|
-
|
|
55
|
-
RSpec.deprecate('`RSpec::Core::ExampleGroup.display_name`',
|
|
56
|
-
:replacement => "`RSpec::Core::ExampleGroup.description`")
|
|
57
|
-
description
|
|
58
|
-
end
|
|
50
|
+
alias_method :describes, :described_class
|
|
59
51
|
|
|
60
52
|
# @private
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
# @param [String] name
|
|
71
|
-
# @param [Hash] extra_options
|
|
72
|
-
# @param [Block] implementation
|
|
73
|
-
# @yield [Example] the example object
|
|
74
|
-
def self.define_example_method(name, extra_options={})
|
|
75
|
-
module_eval(<<-END_RUBY, __FILE__, __LINE__)
|
|
76
|
-
def self.#{name}(desc=nil, *args, &block)
|
|
77
|
-
if #{name.inspect} == :pending
|
|
78
|
-
RSpec.warn_deprecation(<<-EOS.gsub(/^\s+\\|/, ''))
|
|
79
|
-
|The semantics of `RSpec::Core::ExampleGroup.pending` are changing in RSpec 3.
|
|
80
|
-
|In RSpec 2.x, it caused the example to be skipped. In RSpec 3, the example will
|
|
81
|
-
|still be run but is expected to fail, and will be marked as a failure (rather
|
|
82
|
-
|than as pending) if the example passes, just like how `pending` with a block
|
|
83
|
-
|from within an example already works.
|
|
84
|
-
|
|
|
85
|
-
|To keep the same skip semantics, change `pending` to `skip`. Otherwise, if you
|
|
86
|
-
|want the new RSpec 3 behavior, you can safely ignore this warning and continue
|
|
87
|
-
|to upgrade to RSpec 3 without addressing it.
|
|
88
|
-
|
|
|
89
|
-
|Called from \#{CallerFilter.first_non_rspec_line}.
|
|
90
|
-
|
|
|
91
|
-
EOS
|
|
92
|
-
end
|
|
93
|
-
options = build_metadata_hash_from(args)
|
|
53
|
+
# @macro [attach] define_example_method
|
|
54
|
+
# @param [String] name
|
|
55
|
+
# @param [Hash] extra_options
|
|
56
|
+
# @param [Block] implementation
|
|
57
|
+
# @yield [Example] the example object
|
|
58
|
+
def self.define_example_method(name, extra_options={})
|
|
59
|
+
define_method(name) do |*all_args, &block|
|
|
60
|
+
desc, *args = *all_args
|
|
61
|
+
options = Metadata.build_hash_from(args)
|
|
94
62
|
options.update(:pending => RSpec::Core::Pending::NOT_YET_IMPLEMENTED) unless block
|
|
95
|
-
|
|
96
|
-
options.update(:pending => options[:skip]) if options[:skip]
|
|
97
|
-
options.update(#{extra_options.inspect})
|
|
63
|
+
options.update(extra_options)
|
|
98
64
|
examples << RSpec::Core::Example.new(self, desc, options, block)
|
|
99
65
|
examples.last
|
|
100
66
|
end
|
|
101
|
-
|
|
102
|
-
end
|
|
67
|
+
end
|
|
103
68
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
example(desc, *args, &block)
|
|
163
|
-
end
|
|
164
|
-
|
|
165
|
-
# Works like `alias_method :name, :example` with the added benefit of
|
|
166
|
-
# assigning default metadata to the generated example.
|
|
167
|
-
#
|
|
168
|
-
# @note Use with caution. This extends the language used in your
|
|
169
|
-
# specs, but does not add any additional documentation. We use this
|
|
170
|
-
# in rspec to define methods like `focus` and `xit`, but we also add
|
|
171
|
-
# docs for those methods.
|
|
172
|
-
def self.alias_example_to name, extra={}
|
|
173
|
-
RSpec.deprecate("`RSpec::Core::ExampleGroup.alias_example_to`",
|
|
174
|
-
:replacement => "`RSpec::Core::Configuration#alias_example_to`")
|
|
175
|
-
define_example_method name, extra
|
|
176
|
-
end
|
|
69
|
+
# Defines an example within a group.
|
|
70
|
+
# @example
|
|
71
|
+
# example do
|
|
72
|
+
# end
|
|
73
|
+
#
|
|
74
|
+
# example "does something" do
|
|
75
|
+
# end
|
|
76
|
+
#
|
|
77
|
+
# example "does something", :with => 'additional metadata' do
|
|
78
|
+
# end
|
|
79
|
+
#
|
|
80
|
+
# example "does something" do |ex|
|
|
81
|
+
# # ex is the Example object that evals this block
|
|
82
|
+
# end
|
|
83
|
+
define_example_method :example
|
|
84
|
+
# Defines an example within a group.
|
|
85
|
+
# @example
|
|
86
|
+
define_example_method :it
|
|
87
|
+
# Defines an example within a group.
|
|
88
|
+
# This is here primarily for backward compatibility with early versions
|
|
89
|
+
# of RSpec which used `context` and `specify` instead of `describe` and
|
|
90
|
+
# `it`.
|
|
91
|
+
define_example_method :specify
|
|
92
|
+
|
|
93
|
+
# Shortcut to define an example with `:focus` => true
|
|
94
|
+
# @see example
|
|
95
|
+
define_example_method :focus, :focused => true, :focus => true
|
|
96
|
+
# Shortcut to define an example with `:focus` => true
|
|
97
|
+
# @see example
|
|
98
|
+
define_example_method :focused, :focused => true, :focus => true
|
|
99
|
+
# Shortcut to define an example with `:focus` => true
|
|
100
|
+
# @see example
|
|
101
|
+
define_example_method :fit, :focused => true, :focus => true
|
|
102
|
+
|
|
103
|
+
# Shortcut to define an example with :pending => true
|
|
104
|
+
# @see example
|
|
105
|
+
define_example_method :pending, :pending => true
|
|
106
|
+
# Shortcut to define an example with :pending => 'Temporarily disabled with xexample'
|
|
107
|
+
# @see example
|
|
108
|
+
define_example_method :xexample, :pending => 'Temporarily disabled with xexample'
|
|
109
|
+
# Shortcut to define an example with :pending => 'Temporarily disabled with xit'
|
|
110
|
+
# @see example
|
|
111
|
+
define_example_method :xit, :pending => 'Temporarily disabled with xit'
|
|
112
|
+
# Shortcut to define an example with :pending => 'Temporarily disabled with xspecify'
|
|
113
|
+
# @see example
|
|
114
|
+
define_example_method :xspecify, :pending => 'Temporarily disabled with xspecify'
|
|
115
|
+
|
|
116
|
+
# Works like `alias_method :name, :example` with the added benefit of
|
|
117
|
+
# assigning default metadata to the generated example.
|
|
118
|
+
#
|
|
119
|
+
# @note Use with caution. This extends the language used in your
|
|
120
|
+
# specs, but does not add any additional documentation. We use this
|
|
121
|
+
# in rspec to define methods like `focus` and `xit`, but we also add
|
|
122
|
+
# docs for those methods.
|
|
123
|
+
def alias_example_to name, extra={}
|
|
124
|
+
(class << self; self; end).define_example_method name, extra
|
|
125
|
+
end
|
|
177
126
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
group = describe("#{report_label || "it should behave like"} \#{name}") do
|
|
127
|
+
# @private
|
|
128
|
+
# @macro [attach] define_nested_shared_group_method
|
|
129
|
+
#
|
|
130
|
+
# @see SharedExampleGroup
|
|
131
|
+
def self.define_nested_shared_group_method(new_name, report_label="it should behave like")
|
|
132
|
+
define_method(new_name) do |name, *args, &customization_block|
|
|
133
|
+
group = describe("#{report_label} #{name}") do
|
|
186
134
|
find_and_eval_shared("examples", name, *args, &customization_block)
|
|
187
135
|
end
|
|
188
136
|
group.metadata[:shared_group_name] = name
|
|
189
137
|
group
|
|
190
138
|
end
|
|
191
|
-
|
|
192
|
-
end
|
|
139
|
+
end
|
|
193
140
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
141
|
+
# Generates a nested example group and includes the shared content
|
|
142
|
+
# mapped to `name` in the nested group.
|
|
143
|
+
define_nested_shared_group_method :it_behaves_like, "behaves like"
|
|
144
|
+
# Generates a nested example group and includes the shared content
|
|
145
|
+
# mapped to `name` in the nested group.
|
|
146
|
+
define_nested_shared_group_method :it_should_behave_like
|
|
200
147
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
define_nested_shared_group_method name, *args, &block
|
|
148
|
+
# Works like `alias_method :name, :it_behaves_like` with the added
|
|
149
|
+
# benefit of assigning default metadata to the generated example.
|
|
150
|
+
#
|
|
151
|
+
# @note Use with caution. This extends the language used in your
|
|
152
|
+
# specs, but does not add any additional documentation. We use this
|
|
153
|
+
# in rspec to define `it_should_behave_like` (for backward
|
|
154
|
+
# compatibility), but we also add docs for that method.
|
|
155
|
+
def alias_it_behaves_like_to name, *args, &block
|
|
156
|
+
(class << self; self; end).define_nested_shared_group_method name, *args, &block
|
|
157
|
+
end
|
|
212
158
|
end
|
|
213
159
|
|
|
214
160
|
# Includes shared content mapped to `name` directly in the group in which
|
|
@@ -229,46 +175,12 @@ module RSpec
|
|
|
229
175
|
find_and_eval_shared("examples", name, *args, &block)
|
|
230
176
|
end
|
|
231
177
|
|
|
232
|
-
if Proc.method_defined?(:parameters) # for >= 1.9
|
|
233
|
-
# Warn when submitting the name of more than one example group to
|
|
234
|
-
# include_examples, it_behaves_like, etc.
|
|
235
|
-
#
|
|
236
|
-
# Helpful when upgrading from rspec-1 (which supported multiple shared
|
|
237
|
-
# groups in one call) to rspec-2 (which does not).
|
|
238
|
-
#
|
|
239
|
-
# See https://github.com/rspec/rspec-core/issues/1066 for background.
|
|
240
|
-
def self.warn_unexpected_args(label, name, args, shared_block)
|
|
241
|
-
if !args.empty? && shared_block.parameters.count == 0
|
|
242
|
-
if shared_example_groups[args.first]
|
|
243
|
-
warn <<-WARNING
|
|
244
|
-
shared #{label} support#{'s' if /context/ =~ label.to_s} the name of only one example group, received #{[name, *args].inspect}
|
|
245
|
-
called from #{CallerFilter.first_non_rspec_line}"
|
|
246
|
-
WARNING
|
|
247
|
-
else
|
|
248
|
-
warn <<-WARNING
|
|
249
|
-
shared #{label} #{name.inspect} expected #{shared_block.arity} args, got #{args.inspect}
|
|
250
|
-
called from #{CallerFilter.first_non_rspec_line}"
|
|
251
|
-
WARNING
|
|
252
|
-
end
|
|
253
|
-
end
|
|
254
|
-
end
|
|
255
|
-
else
|
|
256
|
-
# no-op for Ruby < 1.9
|
|
257
|
-
#
|
|
258
|
-
# Ruby 1.8 reports lambda {}.arity == -1, so can't support this warning
|
|
259
|
-
# reliably
|
|
260
|
-
def self.warn_unexpected_args(*)
|
|
261
|
-
end
|
|
262
|
-
end
|
|
263
|
-
|
|
264
178
|
# @private
|
|
265
179
|
def self.find_and_eval_shared(label, name, *args, &customization_block)
|
|
266
180
|
raise ArgumentError, "Could not find shared #{label} #{name.inspect}" unless
|
|
267
181
|
shared_block = shared_example_groups[name]
|
|
268
182
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
module_eval_with_args(*args, &shared_block)
|
|
183
|
+
module_exec(*args, &shared_block)
|
|
272
184
|
module_eval(&customization_block) if customization_block
|
|
273
185
|
end
|
|
274
186
|
|
|
@@ -321,43 +233,14 @@ WARNING
|
|
|
321
233
|
#
|
|
322
234
|
# @see DSL#describe
|
|
323
235
|
def self.describe(*args, &example_group_block)
|
|
324
|
-
@_subclass_count ||= 0
|
|
325
|
-
@_subclass_count += 1
|
|
326
|
-
|
|
327
|
-
if Symbol === args.first || Hash === args.first
|
|
328
|
-
description_arg_behavior_changing_in_rspec_3 = DescriptionBehaviorChange.new(
|
|
329
|
-
args.first, CallerFilter.first_non_rspec_line
|
|
330
|
-
)
|
|
331
|
-
end
|
|
332
|
-
|
|
333
236
|
args << {} unless args.last.is_a?(Hash)
|
|
334
|
-
args.last.update(
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
)
|
|
338
|
-
|
|
339
|
-
# TODO 2010-05-05: Because we don't know if const_set is thread-safe
|
|
340
|
-
child = const_set(
|
|
341
|
-
"Nested_#{@_subclass_count}",
|
|
342
|
-
subclass(self, args, &example_group_block)
|
|
343
|
-
)
|
|
237
|
+
args.last.update(:example_group_block => example_group_block)
|
|
238
|
+
|
|
239
|
+
child = subclass(self, args, &example_group_block)
|
|
344
240
|
children << child
|
|
345
241
|
child
|
|
346
242
|
end
|
|
347
243
|
|
|
348
|
-
DescriptionBehaviorChange = Struct.new(:arg, :call_site) do
|
|
349
|
-
def warning
|
|
350
|
-
<<-EOS.gsub(/^\s+\|/, '')
|
|
351
|
-
|The semantics of `describe <a #{arg.class.name}>` are changing in RSpec 3. In RSpec 2,
|
|
352
|
-
|this would be treated as metadata, but as the first `describe` argument,
|
|
353
|
-
|this will be treated as the described object (affecting the value of
|
|
354
|
-
|`described_class`) in RSpec 3. If you want this to be treated as metadata,
|
|
355
|
-
|pass a description as the first argument.
|
|
356
|
-
|(Example group defined at #{call_site})
|
|
357
|
-
EOS
|
|
358
|
-
end
|
|
359
|
-
end
|
|
360
|
-
|
|
361
244
|
class << self
|
|
362
245
|
alias_method :context, :describe
|
|
363
246
|
end
|
|
@@ -366,6 +249,7 @@ WARNING
|
|
|
366
249
|
def self.subclass(parent, args, &example_group_block)
|
|
367
250
|
subclass = Class.new(parent)
|
|
368
251
|
subclass.set_it_up(*args)
|
|
252
|
+
ExampleGroups.assign_const(subclass)
|
|
369
253
|
subclass.module_eval(&example_group_block) if example_group_block
|
|
370
254
|
|
|
371
255
|
# The LetDefinitions module must be included _after_ other modules
|
|
@@ -379,7 +263,7 @@ WARNING
|
|
|
379
263
|
|
|
380
264
|
# @private
|
|
381
265
|
def self.children
|
|
382
|
-
@children ||= []
|
|
266
|
+
@children ||= []
|
|
383
267
|
end
|
|
384
268
|
|
|
385
269
|
# @private
|
|
@@ -418,9 +302,10 @@ WARNING
|
|
|
418
302
|
ensure_example_groups_are_configured
|
|
419
303
|
|
|
420
304
|
symbol_description = args.shift if args.first.is_a?(Symbol)
|
|
421
|
-
args <<
|
|
305
|
+
args << Metadata.build_hash_from(args)
|
|
422
306
|
args.unshift(symbol_description) if symbol_description
|
|
423
307
|
@metadata = RSpec::Core::Metadata.new(superclass_metadata).process(*args)
|
|
308
|
+
@order = nil
|
|
424
309
|
hooks.register_globals(self, RSpec.configuration.hooks)
|
|
425
310
|
world.configure_group(self)
|
|
426
311
|
end
|
|
@@ -494,7 +379,7 @@ WARNING
|
|
|
494
379
|
begin
|
|
495
380
|
run_before_all_hooks(new)
|
|
496
381
|
result_for_this_group = run_examples(reporter)
|
|
497
|
-
results_for_descendants = children.
|
|
382
|
+
results_for_descendants = ordering_strategy.order(children).map { |child| child.run(reporter) }.all?
|
|
498
383
|
result_for_this_group && results_for_descendants
|
|
499
384
|
rescue Exception => ex
|
|
500
385
|
RSpec.wants_to_quit = true if fail_fast?
|
|
@@ -506,9 +391,25 @@ WARNING
|
|
|
506
391
|
end
|
|
507
392
|
end
|
|
508
393
|
|
|
394
|
+
# @private
|
|
395
|
+
def self.ordering_strategy
|
|
396
|
+
order = metadata.fetch(:order, :global)
|
|
397
|
+
registry = RSpec.configuration.ordering_registry
|
|
398
|
+
|
|
399
|
+
registry.fetch(order) do
|
|
400
|
+
warn <<-WARNING.gsub(/^ +\|/, '')
|
|
401
|
+
|WARNING: Ignoring unknown ordering specified using `:order => #{order.inspect}` metadata.
|
|
402
|
+
| Falling back to configured global ordering.
|
|
403
|
+
| Unrecognized ordering specified at: #{metadata[:example_group][:location]}
|
|
404
|
+
WARNING
|
|
405
|
+
|
|
406
|
+
registry.fetch(:global)
|
|
407
|
+
end
|
|
408
|
+
end
|
|
409
|
+
|
|
509
410
|
# @private
|
|
510
411
|
def self.run_examples(reporter)
|
|
511
|
-
filtered_examples.
|
|
412
|
+
ordering_strategy.order(filtered_examples).map do |example|
|
|
512
413
|
next if RSpec.wants_to_quit
|
|
513
414
|
instance = new
|
|
514
415
|
set_ivars(instance, before_all_ivars)
|
|
@@ -562,44 +463,6 @@ WARNING
|
|
|
562
463
|
ivars.each {|name, value| instance.instance_variable_set(name, value)}
|
|
563
464
|
end
|
|
564
465
|
|
|
565
|
-
def example=(current_example)
|
|
566
|
-
RSpec.current_example = current_example
|
|
567
|
-
end
|
|
568
|
-
|
|
569
|
-
# @deprecated use a block argument
|
|
570
|
-
def example
|
|
571
|
-
warn_deprecation_of_example_accessor :example
|
|
572
|
-
RSpec.current_example
|
|
573
|
-
end
|
|
574
|
-
|
|
575
|
-
# @deprecated use a block argument
|
|
576
|
-
def running_example
|
|
577
|
-
warn_deprecation_of_example_accessor :running_example
|
|
578
|
-
RSpec.current_example
|
|
579
|
-
end
|
|
580
|
-
|
|
581
|
-
def warn_deprecation_of_example_accessor(name)
|
|
582
|
-
RSpec.warn_deprecation(<<-EOS.gsub(/^\s*\|/, ''))
|
|
583
|
-
|RSpec::Core::ExampleGroup##{name} is deprecated and will be removed
|
|
584
|
-
|in RSpec 3. There are a few options for what you can use instead:
|
|
585
|
-
|
|
|
586
|
-
| - rspec-core's DSL methods (`it`, `before`, `after`, `let`, `subject`, etc)
|
|
587
|
-
| now yield the example as a block argument, and that is the recommended
|
|
588
|
-
| way to access the current example from those contexts.
|
|
589
|
-
| - The current example is now exposed via `RSpec.current_example`,
|
|
590
|
-
| which is accessible from any context.
|
|
591
|
-
| - If you can't update the code at this call site (e.g. because it is in
|
|
592
|
-
| an extension gem), you can use this snippet to continue making this
|
|
593
|
-
| method available in RSpec 2.99 and RSpec 3:
|
|
594
|
-
|
|
|
595
|
-
| RSpec.configure do |c|
|
|
596
|
-
| c.expose_current_running_example_as :#{name}
|
|
597
|
-
| end
|
|
598
|
-
|
|
|
599
|
-
|(Called from #{CallerFilter.first_non_rspec_line})
|
|
600
|
-
EOS
|
|
601
|
-
end
|
|
602
|
-
|
|
603
466
|
# Returns the class or module passed to the `describe` method (or alias).
|
|
604
467
|
# Returns nil if the subject is not a class or module.
|
|
605
468
|
# @example
|
|
@@ -617,9 +480,9 @@ WARNING
|
|
|
617
480
|
# @private
|
|
618
481
|
# instance_evals the block, capturing and reporting an exception if
|
|
619
482
|
# raised
|
|
620
|
-
def
|
|
483
|
+
def instance_exec_with_rescue(example, context = nil, &hook)
|
|
621
484
|
begin
|
|
622
|
-
|
|
485
|
+
instance_exec(example, &hook)
|
|
623
486
|
rescue Exception => e
|
|
624
487
|
if RSpec.current_example
|
|
625
488
|
RSpec.current_example.set_exception(e, context)
|
|
@@ -630,4 +493,48 @@ WARNING
|
|
|
630
493
|
end
|
|
631
494
|
end
|
|
632
495
|
end
|
|
496
|
+
|
|
497
|
+
# Namespace for the example group subclasses generated by top-level `describe`.
|
|
498
|
+
module ExampleGroups
|
|
499
|
+
def self.assign_const(group)
|
|
500
|
+
base_name = base_name_for(group)
|
|
501
|
+
const_scope = constant_scope_for(group)
|
|
502
|
+
name = disambiguate(base_name, const_scope)
|
|
503
|
+
|
|
504
|
+
const_scope.const_set(name, group)
|
|
505
|
+
end
|
|
506
|
+
|
|
507
|
+
def self.constant_scope_for(group)
|
|
508
|
+
const_scope = group.superclass
|
|
509
|
+
const_scope = self if const_scope == Core::ExampleGroup
|
|
510
|
+
const_scope
|
|
511
|
+
end
|
|
512
|
+
|
|
513
|
+
def self.base_name_for(group)
|
|
514
|
+
return "Anonymous" if group.description.empty?
|
|
515
|
+
|
|
516
|
+
# convert to CamelCase
|
|
517
|
+
name = ' ' + group.description
|
|
518
|
+
name.gsub!(/[^0-9a-zA-Z]+([0-9a-zA-Z])/) { $1.upcase }
|
|
519
|
+
|
|
520
|
+
name.lstrip! # Remove leading whitespace
|
|
521
|
+
name.gsub!(/\W/, '') # JRuby, RBX and others don't like non-ascii in const names
|
|
522
|
+
|
|
523
|
+
# Ruby requires first const letter to be A-Z. Use `Nested`
|
|
524
|
+
# as necessary to enforce that.
|
|
525
|
+
name.gsub!(/\A([^A-Z]|\z)/, 'Nested\1')
|
|
526
|
+
|
|
527
|
+
name
|
|
528
|
+
end
|
|
529
|
+
|
|
530
|
+
def self.disambiguate(name, const_scope)
|
|
531
|
+
return name unless const_scope.const_defined?(name)
|
|
532
|
+
|
|
533
|
+
# Add a trailing number if needed to disambiguate from an existing constant.
|
|
534
|
+
name << "_2"
|
|
535
|
+
name.next! while const_scope.const_defined?(name)
|
|
536
|
+
name
|
|
537
|
+
end
|
|
538
|
+
end
|
|
633
539
|
end
|
|
540
|
+
|