rspec-core 2.99.2 → 3.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -16,9 +16,7 @@ module RSpec
|
|
16
16
|
|
17
17
|
def printer
|
18
18
|
@printer ||= case deprecation_stream
|
19
|
-
when File
|
20
|
-
ImmediatePrinter.new(FileStream.new(deprecation_stream), summary_stream, self)
|
21
|
-
when RaiseErrorStream
|
19
|
+
when File, RaiseErrorStream
|
22
20
|
ImmediatePrinter.new(deprecation_stream, summary_stream, self)
|
23
21
|
else
|
24
22
|
DelayedPrinter.new(deprecation_stream, summary_stream, self)
|
@@ -37,10 +35,6 @@ module RSpec
|
|
37
35
|
printer.deprecation_summary
|
38
36
|
end
|
39
37
|
|
40
|
-
def start(example_count=nil)
|
41
|
-
#no-op to fix #966
|
42
|
-
end
|
43
|
-
|
44
38
|
def deprecation_message_for(data)
|
45
39
|
if data[:message]
|
46
40
|
SpecifiedDeprecationMessage.new(data)
|
@@ -57,9 +51,6 @@ module RSpec
|
|
57
51
|
|deprecation warnings into errors, giving you the full backtrace.
|
58
52
|
EOS
|
59
53
|
|
60
|
-
DEPRECATION_STREAM_NOTICE = "Pass `--deprecation-out` or set " +
|
61
|
-
"`config.deprecation_stream` to a file for full output."
|
62
|
-
|
63
54
|
SpecifiedDeprecationMessage = Struct.new(:type) do
|
64
55
|
def initialize(data)
|
65
56
|
@message = data[:message]
|
@@ -67,23 +58,17 @@ module RSpec
|
|
67
58
|
end
|
68
59
|
|
69
60
|
def to_s
|
70
|
-
|
61
|
+
@message
|
71
62
|
end
|
72
63
|
|
73
64
|
def too_many_warnings_message
|
74
|
-
msg = "Too many similar deprecation messages reported, disregarding further reports.
|
75
|
-
msg <<
|
65
|
+
msg = "Too many similar deprecation messages reported, disregarding further reports."
|
66
|
+
msg << " Set config.deprecation_stream to a File for full output."
|
76
67
|
msg
|
77
68
|
end
|
78
69
|
|
79
70
|
private
|
80
71
|
|
81
|
-
def output_formatted(str)
|
82
|
-
return str unless str.lines.count > 1
|
83
|
-
separator = "#{'-' * 80}"
|
84
|
-
"#{separator}\n#{str.chomp}\n#{separator}"
|
85
|
-
end
|
86
|
-
|
87
72
|
def deprecation_type_for(data)
|
88
73
|
data[:message].gsub(/(\w+\/)+\w+\.rb:\d+/, '')
|
89
74
|
end
|
@@ -92,7 +77,7 @@ module RSpec
|
|
92
77
|
GeneratedDeprecationMessage = Struct.new(:type) do
|
93
78
|
def initialize(data)
|
94
79
|
@data = data
|
95
|
-
super data
|
80
|
+
super data[:deprecated]
|
96
81
|
end
|
97
82
|
|
98
83
|
def to_s
|
@@ -103,18 +88,26 @@ module RSpec
|
|
103
88
|
end
|
104
89
|
|
105
90
|
def too_many_warnings_message
|
106
|
-
msg = "Too many uses of deprecated '#{type}'.
|
107
|
-
msg <<
|
91
|
+
msg = "Too many uses of deprecated '#{type}'."
|
92
|
+
msg << " Set config.deprecation_stream to a File for full output."
|
108
93
|
msg
|
109
94
|
end
|
110
95
|
end
|
111
96
|
|
112
97
|
class ImmediatePrinter
|
98
|
+
include ::RSpec::Core::Formatters::Helpers
|
99
|
+
|
113
100
|
attr_reader :deprecation_stream, :summary_stream, :deprecation_formatter
|
114
101
|
|
115
102
|
def initialize(deprecation_stream, summary_stream, deprecation_formatter)
|
116
103
|
@deprecation_stream = deprecation_stream
|
117
104
|
|
105
|
+
# In one of my test suites, I got lots of duplicate output in the
|
106
|
+
# deprecation file (e.g. 200 of the same deprecation, even though
|
107
|
+
# the `puts` below was only called 6 times). Setting `sync = true`
|
108
|
+
# fixes this (but we really have no idea why!).
|
109
|
+
@deprecation_stream.sync = true
|
110
|
+
|
118
111
|
@summary_stream = summary_stream
|
119
112
|
@deprecation_formatter = deprecation_formatter
|
120
113
|
end
|
@@ -125,8 +118,10 @@ module RSpec
|
|
125
118
|
end
|
126
119
|
|
127
120
|
def deprecation_summary
|
128
|
-
|
129
|
-
|
121
|
+
if deprecation_formatter.count > 0
|
122
|
+
summary_stream.puts "\n#{pluralize(deprecation_formatter.count, 'deprecation')} logged to #{deprecation_stream.path}"
|
123
|
+
deprecation_stream.puts RAISE_ERROR_CONFIG_NOTICE
|
124
|
+
end
|
130
125
|
end
|
131
126
|
end
|
132
127
|
|
@@ -181,38 +176,12 @@ module RSpec
|
|
181
176
|
|
182
177
|
# Not really a stream, but is usable in place of one.
|
183
178
|
class RaiseErrorStream
|
184
|
-
include ::RSpec::Core::Formatters::Helpers
|
185
|
-
|
186
179
|
def puts(message)
|
187
180
|
raise DeprecationError, message
|
188
181
|
end
|
189
182
|
|
190
|
-
def
|
191
|
-
|
192
|
-
end
|
193
|
-
end
|
194
|
-
|
195
|
-
# Wraps a File object and provides file-specific operations.
|
196
|
-
class FileStream
|
197
|
-
include ::RSpec::Core::Formatters::Helpers
|
198
|
-
|
199
|
-
def initialize(file)
|
200
|
-
@file = file
|
201
|
-
|
202
|
-
# In one of my test suites, I got lots of duplicate output in the
|
203
|
-
# deprecation file (e.g. 200 of the same deprecation, even though
|
204
|
-
# the `puts` below was only called 6 times). Setting `sync = true`
|
205
|
-
# fixes this (but we really have no idea why!).
|
206
|
-
@file.sync = true
|
207
|
-
end
|
208
|
-
|
209
|
-
def puts(*args)
|
210
|
-
@file.puts(*args)
|
211
|
-
end
|
212
|
-
|
213
|
-
def summarize(summary_stream, deprecation_count)
|
214
|
-
summary_stream.puts "\n#{pluralize(deprecation_count, 'deprecation')} logged to #{@file.path}"
|
215
|
-
puts RAISE_ERROR_CONFIG_NOTICE
|
183
|
+
def sync=(value)
|
184
|
+
# no-op
|
216
185
|
end
|
217
186
|
end
|
218
187
|
|
@@ -1,34 +1,7 @@
|
|
1
1
|
module RSpec
|
2
2
|
module Core
|
3
|
-
module BacktraceFormatter
|
4
|
-
extend self
|
5
|
-
|
6
|
-
def format_backtrace(backtrace, options = {})
|
7
|
-
return "" unless backtrace
|
8
|
-
return backtrace if options[:full_backtrace] == true
|
9
|
-
|
10
|
-
if at_exit_index = backtrace.index(RSpec::Core::Runner::AT_EXIT_HOOK_BACKTRACE_LINE)
|
11
|
-
backtrace = backtrace[0, at_exit_index]
|
12
|
-
end
|
13
|
-
|
14
|
-
cleansed = backtrace.map { |line| backtrace_line(line) }.compact
|
15
|
-
cleansed.empty? ? backtrace : cleansed
|
16
|
-
end
|
17
|
-
|
18
|
-
protected
|
19
|
-
|
20
|
-
def backtrace_line(line)
|
21
|
-
return nil if RSpec.configuration.backtrace_formatter.exclude?(line)
|
22
|
-
RSpec::Core::Metadata::relative_path(line)
|
23
|
-
rescue SecurityError
|
24
|
-
nil
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
3
|
module Formatters
|
29
4
|
module Helpers
|
30
|
-
include BacktraceFormatter
|
31
|
-
|
32
5
|
SUB_SECOND_PRECISION = 5
|
33
6
|
DEFAULT_PRECISION = 2
|
34
7
|
|
@@ -104,7 +77,6 @@ module RSpec
|
|
104
77
|
"#{count} #{string}#{'s' unless count.to_f == 1}"
|
105
78
|
end
|
106
79
|
end
|
107
|
-
|
108
80
|
end
|
109
81
|
end
|
110
82
|
end
|
@@ -119,7 +119,7 @@ module RSpec
|
|
119
119
|
#
|
120
120
|
def extra_failure_content(exception)
|
121
121
|
require 'rspec/core/formatters/snippet_extractor'
|
122
|
-
backtrace = exception.backtrace.map {|line| backtrace_line(line)}
|
122
|
+
backtrace = exception.backtrace.map {|line| configuration.backtrace_formatter.backtrace_line(line)}
|
123
123
|
backtrace.compact!
|
124
124
|
@snippet_extractor ||= SnippetExtractor.new
|
125
125
|
" <pre class=\"ruby\"><code>#{@snippet_extractor.snippet(backtrace)}</code></pre>"
|
@@ -27,6 +27,8 @@ module RSpec
|
|
27
27
|
:pending_count => pending_count
|
28
28
|
}
|
29
29
|
@output_hash[:summary_line] = summary_line(example_count, failure_count, pending_count)
|
30
|
+
|
31
|
+
dump_profile unless mute_profile_output?(failure_count)
|
30
32
|
end
|
31
33
|
|
32
34
|
def summary_line(example_count, failure_count, pending_count)
|
@@ -39,15 +41,7 @@ module RSpec
|
|
39
41
|
def stop
|
40
42
|
super
|
41
43
|
@output_hash[:examples] = examples.map do |example|
|
42
|
-
|
43
|
-
:description => example.description,
|
44
|
-
:full_description => example.full_description,
|
45
|
-
:status => example.execution_result[:status],
|
46
|
-
# :example_group,
|
47
|
-
# :execution_result,
|
48
|
-
:file_path => example.metadata[:file_path],
|
49
|
-
:line_number => example.metadata[:line_number],
|
50
|
-
}.tap do |hash|
|
44
|
+
format_example(example).tap do |hash|
|
51
45
|
if e=example.exception
|
52
46
|
hash[:exception] = {
|
53
47
|
:class => e.class.name,
|
@@ -64,6 +58,41 @@ module RSpec
|
|
64
58
|
output.close if IO === output && output != $stdout
|
65
59
|
end
|
66
60
|
|
61
|
+
def dump_profile
|
62
|
+
@output_hash[:profile] = {}
|
63
|
+
dump_profile_slowest_examples
|
64
|
+
dump_profile_slowest_example_groups
|
65
|
+
end
|
66
|
+
|
67
|
+
def dump_profile_slowest_examples
|
68
|
+
@output_hash[:profile] = {}
|
69
|
+
sorted_examples = slowest_examples
|
70
|
+
@output_hash[:profile][:examples] = sorted_examples[:examples].map do |example|
|
71
|
+
format_example(example).tap do |hash|
|
72
|
+
hash[:run_time] = example.execution_result[:run_time]
|
73
|
+
end
|
74
|
+
end
|
75
|
+
@output_hash[:profile][:slowest] = sorted_examples[:slows]
|
76
|
+
@output_hash[:profile][:total] = sorted_examples[:total]
|
77
|
+
end
|
78
|
+
|
79
|
+
def dump_profile_slowest_example_groups
|
80
|
+
@output_hash[:profile] ||= {}
|
81
|
+
@output_hash[:profile][:groups] = slowest_groups.map do |loc, hash|
|
82
|
+
hash.update(:location => loc)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
private
|
87
|
+
def format_example(example)
|
88
|
+
{
|
89
|
+
:description => example.description,
|
90
|
+
:full_description => example.full_description,
|
91
|
+
:status => example.execution_result[:status],
|
92
|
+
:file_path => example.metadata[:file_path],
|
93
|
+
:line_number => example.metadata[:line_number]
|
94
|
+
}
|
95
|
+
end
|
67
96
|
end
|
68
97
|
end
|
69
98
|
end
|
@@ -5,11 +5,21 @@ module RSpec
|
|
5
5
|
#
|
6
6
|
# Extracts code snippets by looking at the backtrace of the passed error and applies synax highlighting and line numbers using html.
|
7
7
|
class SnippetExtractor
|
8
|
-
class NullConverter
|
8
|
+
class NullConverter
|
9
|
+
def convert(code)
|
10
|
+
%Q(#{code}\n<span class="comment"># Install the coderay gem to get syntax highlighting</span>)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class CoderayConverter
|
15
|
+
def convert(code)
|
16
|
+
CodeRay.scan(code, :ruby).html(:line_numbers => false)
|
17
|
+
end
|
18
|
+
end
|
9
19
|
|
10
20
|
begin
|
11
|
-
require '
|
12
|
-
@@converter =
|
21
|
+
require 'coderay'
|
22
|
+
@@converter = CoderayConverter.new
|
13
23
|
rescue LoadError
|
14
24
|
@@converter = NullConverter.new
|
15
25
|
end
|
@@ -24,8 +34,7 @@ module RSpec
|
|
24
34
|
# @see #post_process
|
25
35
|
def snippet(backtrace)
|
26
36
|
raw_code, line = snippet_for(backtrace[0])
|
27
|
-
highlighted = @@converter.convert(raw_code
|
28
|
-
highlighted << "\n<span class=\"comment\"># gem install syntax to get syntax highlighting</span>" if @@converter.is_a?(NullConverter)
|
37
|
+
highlighted = @@converter.convert(raw_code)
|
29
38
|
post_process(highlighted, line)
|
30
39
|
end
|
31
40
|
|
data/lib/rspec/core/hooks.rb
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
module RSpec
|
2
2
|
module Core
|
3
3
|
module Hooks
|
4
|
-
include MetadataHashBuilder::WithConfigWarning
|
5
|
-
|
6
4
|
class Hook
|
7
5
|
attr_reader :block, :options
|
8
6
|
|
@@ -18,7 +16,7 @@ module RSpec
|
|
18
16
|
|
19
17
|
class BeforeHook < Hook
|
20
18
|
def run(example)
|
21
|
-
example.
|
19
|
+
example.instance_exec(example, &block)
|
22
20
|
end
|
23
21
|
|
24
22
|
def display_name
|
@@ -28,7 +26,7 @@ module RSpec
|
|
28
26
|
|
29
27
|
class AfterHook < Hook
|
30
28
|
def run(example)
|
31
|
-
example.
|
29
|
+
example.instance_exec_with_rescue("in an after hook", &block)
|
32
30
|
end
|
33
31
|
|
34
32
|
def display_name
|
@@ -61,18 +59,26 @@ EOS
|
|
61
59
|
end
|
62
60
|
end
|
63
61
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
host.send :alias_method, :append, :push
|
62
|
+
class BaseHookCollection
|
63
|
+
Array.public_instance_methods(false).each do |name|
|
64
|
+
define_method(name) { |*a, &b| hooks.__send__(name, *a, &b) }
|
68
65
|
end
|
69
|
-
end
|
70
66
|
|
71
|
-
|
72
|
-
|
67
|
+
attr_reader :hooks
|
68
|
+
protected :hooks
|
73
69
|
|
70
|
+
alias append push
|
71
|
+
alias prepend unshift
|
72
|
+
|
73
|
+
def initialize(hooks=[])
|
74
|
+
@hooks = hooks
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
class HookCollection < BaseHookCollection
|
74
79
|
def for(example_or_group)
|
75
|
-
self.class.
|
80
|
+
self.class.
|
81
|
+
new(hooks.select {|hook| hook.options_apply?(example_or_group)}).
|
76
82
|
with(example_or_group)
|
77
83
|
end
|
78
84
|
|
@@ -82,15 +88,13 @@ EOS
|
|
82
88
|
end
|
83
89
|
|
84
90
|
def run
|
85
|
-
each {|h| h.run(@example)
|
91
|
+
hooks.each {|h| h.run(@example)}
|
86
92
|
end
|
87
93
|
end
|
88
94
|
|
89
|
-
class AroundHookCollection <
|
90
|
-
include HookCollectionAliases
|
91
|
-
|
95
|
+
class AroundHookCollection < BaseHookCollection
|
92
96
|
def for(example, initial_procsy=nil)
|
93
|
-
self.class.new(select {|hook| hook.options_apply?(example)}).
|
97
|
+
self.class.new(hooks.select {|hook| hook.options_apply?(example)}).
|
94
98
|
with(example, initial_procsy)
|
95
99
|
end
|
96
100
|
|
@@ -101,51 +105,61 @@ EOS
|
|
101
105
|
end
|
102
106
|
|
103
107
|
def run
|
104
|
-
|
105
|
-
|
106
|
-
@example.
|
108
|
+
hooks.reduce(@initial_procsy) do |procsy, around_hook|
|
109
|
+
procsy.wrap do
|
110
|
+
@example.instance_exec(procsy, &around_hook.block)
|
107
111
|
end
|
108
112
|
end.call
|
109
113
|
end
|
110
114
|
end
|
111
115
|
|
112
|
-
class GroupHookCollection <
|
116
|
+
class GroupHookCollection < BaseHookCollection
|
113
117
|
def for(group)
|
114
118
|
@group = group
|
115
119
|
self
|
116
120
|
end
|
117
121
|
|
118
122
|
def run
|
119
|
-
shift.run(@group) until empty?
|
123
|
+
hooks.shift.run(@group) until hooks.empty?
|
120
124
|
end
|
121
125
|
end
|
122
126
|
|
123
|
-
|
124
|
-
def
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
127
|
+
class HookCollections
|
128
|
+
def initialize(data)
|
129
|
+
@data = data
|
130
|
+
end
|
131
|
+
|
132
|
+
def [](key)
|
133
|
+
@data[key]
|
134
|
+
end
|
135
|
+
|
136
|
+
def register_globals(host, globals)
|
137
|
+
process(host, globals, :before, :each)
|
138
|
+
process(host, globals, :after, :each)
|
139
|
+
process(host, globals, :around, :each)
|
140
|
+
|
141
|
+
process(host, globals, :before, :all)
|
142
|
+
process(host, globals, :after, :all)
|
130
143
|
end
|
131
144
|
|
132
145
|
private
|
133
|
-
|
146
|
+
|
147
|
+
def process(host, globals, position, scope)
|
134
148
|
globals[position][scope].each do |hook|
|
135
|
-
unless
|
136
|
-
|
137
|
-
|
149
|
+
next unless scope == :each || hook.options_apply?(host)
|
150
|
+
next if host.parent_groups.any? {|a| a.hooks[position][scope].include?(hook)}
|
151
|
+
self[position][scope] << hook
|
138
152
|
end
|
139
153
|
end
|
140
154
|
end
|
141
155
|
|
142
156
|
# @private
|
143
157
|
def hooks
|
144
|
-
@hooks ||=
|
158
|
+
@hooks ||= HookCollections.new(
|
145
159
|
:around => { :each => AroundHookCollection.new },
|
146
160
|
:before => { :each => HookCollection.new, :all => HookCollection.new, :suite => HookCollection.new },
|
147
161
|
:after => { :each => HookCollection.new, :all => HookCollection.new, :suite => HookCollection.new }
|
148
|
-
|
162
|
+
)
|
149
163
|
end
|
150
164
|
|
151
165
|
# @api public
|
@@ -443,12 +457,14 @@ EOS
|
|
443
457
|
# Runs all of the blocks stored with the hook in the context of the
|
444
458
|
# example. If no example is provided, just calls the hook directly.
|
445
459
|
def run_hook(hook, scope, example_or_group=ExampleGroup.new, initial_procsy=nil)
|
460
|
+
return if RSpec.configuration.dry_run?
|
461
|
+
|
446
462
|
find_hook(hook, scope, example_or_group, initial_procsy).run
|
447
463
|
end
|
448
464
|
|
449
465
|
# @private
|
450
466
|
def around_each_hooks_for(example, initial_procsy=nil)
|
451
|
-
AroundHookCollection.new(parent_groups
|
467
|
+
AroundHookCollection.new(FlatMap.flat_map(parent_groups) {|a| a.hooks[:around][:each]}).for(example, initial_procsy)
|
452
468
|
end
|
453
469
|
|
454
470
|
private
|
@@ -472,11 +488,11 @@ EOS
|
|
472
488
|
end
|
473
489
|
|
474
490
|
def before_each_hooks_for(example)
|
475
|
-
HookCollection.new(parent_groups.reverse
|
491
|
+
HookCollection.new(FlatMap.flat_map(parent_groups.reverse) {|a| a.hooks[:before][:each]}).for(example)
|
476
492
|
end
|
477
493
|
|
478
494
|
def after_each_hooks_for(example)
|
479
|
-
HookCollection.new(parent_groups
|
495
|
+
HookCollection.new(FlatMap.flat_map(parent_groups) {|a| a.hooks[:after][:each]}).for(example)
|
480
496
|
end
|
481
497
|
|
482
498
|
def register_hook prepend_or_append, hook, *args, &block
|
@@ -502,7 +518,7 @@ EOS
|
|
502
518
|
end
|
503
519
|
|
504
520
|
def scope_and_options_from(*args)
|
505
|
-
return extract_scope_from(args),
|
521
|
+
return extract_scope_from(args), Metadata.build_hash_from(args)
|
506
522
|
end
|
507
523
|
|
508
524
|
def extract_scope_from(args)
|