rspec-core 2.99.0 → 3.0.0
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 +8 -8
- checksums.yaml.gz.sig +0 -0
- data/.yardopts +1 -0
- data/Changelog.md +339 -1
- data/License.txt +1 -0
- data/README.md +19 -37
- data/exe/rspec +2 -23
- data/lib/rspec/core/backport_random.rb +336 -0
- data/lib/rspec/core/backtrace_formatter.rb +70 -0
- data/lib/rspec/core/configuration.rb +479 -577
- data/lib/rspec/core/configuration_options.rb +71 -54
- data/lib/rspec/core/drb.rb +111 -0
- data/lib/rspec/core/dsl.rb +86 -18
- data/lib/rspec/core/example.rb +267 -119
- data/lib/rspec/core/example_group.rb +381 -393
- data/lib/rspec/core/filter_manager.rb +133 -114
- data/lib/rspec/core/flat_map.rb +18 -0
- data/lib/rspec/core/formatters/base_formatter.rb +51 -125
- data/lib/rspec/core/formatters/base_text_formatter.rb +34 -286
- data/lib/rspec/core/formatters/console_codes.rb +24 -1
- data/lib/rspec/core/formatters/deprecation_formatter.rb +25 -26
- data/lib/rspec/core/formatters/documentation_formatter.rb +27 -25
- data/lib/rspec/core/formatters/helpers.rb +14 -36
- data/lib/rspec/core/formatters/html_formatter.rb +58 -65
- data/lib/rspec/core/formatters/html_printer.rb +12 -18
- data/lib/rspec/core/formatters/json_formatter.rb +54 -31
- data/lib/rspec/core/formatters/profile_formatter.rb +67 -0
- data/lib/rspec/core/formatters/progress_formatter.rb +11 -15
- data/lib/rspec/core/formatters/snippet_extractor.rb +22 -11
- data/lib/rspec/core/formatters.rb +90 -43
- data/lib/rspec/core/hooks.rb +325 -270
- data/lib/rspec/core/memoized_helpers.rb +45 -156
- data/lib/rspec/core/metadata.rb +284 -236
- data/lib/rspec/core/metadata_filter.rb +86 -0
- data/lib/rspec/core/mocking_adapters/flexmock.rb +29 -0
- data/lib/rspec/core/{mocking/with_mocha.rb → mocking_adapters/mocha.rb} +19 -16
- data/lib/rspec/core/mocking_adapters/null.rb +12 -0
- data/lib/rspec/core/mocking_adapters/rr.rb +29 -0
- data/lib/rspec/core/mocking_adapters/rspec.rb +30 -0
- data/lib/rspec/core/notifications.rb +511 -0
- data/lib/rspec/core/option_parser.rb +49 -74
- data/lib/rspec/core/ordering.rb +156 -0
- data/lib/rspec/core/pending.rb +94 -96
- data/lib/rspec/core/project_initializer/.rspec +3 -0
- data/lib/rspec/core/project_initializer/spec/spec_helper.rb +78 -0
- data/lib/rspec/core/project_initializer.rb +24 -64
- data/lib/rspec/core/rake_task.rb +44 -130
- data/lib/rspec/core/reporter.rb +76 -59
- data/lib/rspec/core/ruby_project.rb +2 -1
- data/lib/rspec/core/runner.rb +117 -52
- data/lib/rspec/core/shared_context.rb +10 -10
- data/lib/rspec/core/shared_example_group.rb +108 -121
- data/lib/rspec/core/version.rb +3 -1
- data/lib/rspec/core/warnings.rb +40 -0
- data/lib/rspec/core/world.rb +66 -10
- data/lib/rspec/core.rb +64 -104
- data.tar.gz.sig +3 -0
- metadata +75 -322
- metadata.gz.sig +1 -0
- data/exe/autospec +0 -13
- data/features/Autotest.md +0 -38
- data/features/README.md +0 -17
- data/features/Upgrade.md +0 -364
- data/features/command_line/README.md +0 -28
- data/features/command_line/example_name_option.feature +0 -97
- data/features/command_line/exit_status.feature +0 -82
- data/features/command_line/format_option.feature +0 -75
- data/features/command_line/init.feature +0 -18
- data/features/command_line/line_number_appended_to_path.feature +0 -140
- data/features/command_line/line_number_option.feature +0 -53
- data/features/command_line/order.feature +0 -26
- data/features/command_line/pattern_option.feature +0 -49
- data/features/command_line/rake_task.feature +0 -122
- data/features/command_line/require_option.feature +0 -43
- data/features/command_line/ruby.feature +0 -22
- data/features/command_line/tag.feature +0 -98
- data/features/command_line/warnings_option.feature +0 -29
- data/features/configuration/alias_example_to.feature +0 -48
- data/features/configuration/backtrace_clean_patterns.feature +0 -102
- data/features/configuration/custom_settings.feature +0 -84
- data/features/configuration/default_path.feature +0 -38
- data/features/configuration/deprecation_stream.feature +0 -58
- data/features/configuration/fail_fast.feature +0 -77
- data/features/configuration/failure_exit_code.feature +0 -36
- data/features/configuration/order_and_seed.feature +0 -3
- data/features/configuration/output_stream.feature +0 -24
- data/features/configuration/pattern.feature +0 -38
- data/features/configuration/profile.feature +0 -220
- data/features/configuration/read_options_from_file.feature +0 -90
- data/features/configuration/run_all_when_everything_filtered.feature +0 -76
- data/features/configuration/show_failures_in_pending_blocks.feature +0 -61
- data/features/configuration/treat_symbols_as_metadata_keys_with_true_values.feature +0 -52
- data/features/example_groups/basic_structure.feature +0 -55
- data/features/example_groups/shared_context.feature +0 -74
- data/features/example_groups/shared_examples.feature +0 -294
- data/features/expectation_framework_integration/configure_expectation_framework.feature +0 -197
- data/features/filtering/exclusion_filters.feature +0 -138
- data/features/filtering/if_and_unless.feature +0 -168
- data/features/filtering/inclusion_filters.feature +0 -105
- data/features/formatters/configurable_colors.feature +0 -31
- data/features/formatters/custom_formatter.feature +0 -36
- data/features/formatters/json_formatter.feature +0 -30
- data/features/formatters/text_formatter.feature +0 -46
- data/features/helper_methods/arbitrary_methods.feature +0 -40
- data/features/helper_methods/let.feature +0 -50
- data/features/helper_methods/modules.feature +0 -149
- data/features/hooks/around_hooks.feature +0 -343
- data/features/hooks/before_and_after_hooks.feature +0 -427
- data/features/hooks/filtering.feature +0 -234
- data/features/metadata/current_example.feature +0 -56
- data/features/metadata/described_class.feature +0 -17
- data/features/metadata/user_defined.feature +0 -113
- data/features/mock_framework_integration/use_any_framework.feature +0 -106
- data/features/mock_framework_integration/use_flexmock.feature +0 -96
- data/features/mock_framework_integration/use_mocha.feature +0 -97
- data/features/mock_framework_integration/use_rr.feature +0 -98
- data/features/mock_framework_integration/use_rspec.feature +0 -97
- data/features/pending/pending_examples.feature +0 -229
- data/features/spec_files/arbitrary_file_suffix.feature +0 -13
- data/features/step_definitions/additional_cli_steps.rb +0 -49
- data/features/subject/attribute_of_subject.feature +0 -124
- data/features/subject/explicit_subject.feature +0 -101
- data/features/subject/implicit_subject.feature +0 -63
- data/features/subject/one_liner_syntax.feature +0 -71
- data/features/support/env.rb +0 -14
- data/features/support/rubinius.rb +0 -6
- 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/command_line.rb +0 -47
- data/lib/rspec/core/deprecated_mutable_array_proxy.rb +0 -32
- data/lib/rspec/core/deprecation.rb +0 -26
- data/lib/rspec/core/drb_command_line.rb +0 -26
- data/lib/rspec/core/drb_options.rb +0 -87
- 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/text_mate_formatter.rb +0 -34
- data/lib/rspec/core/metadata_hash_builder.rb +0 -97
- data/lib/rspec/core/mocking/with_absolutely_nothing.rb +0 -11
- data/lib/rspec/core/mocking/with_flexmock.rb +0 -27
- data/lib/rspec/core/mocking/with_rr.rb +0 -27
- data/lib/rspec/core/mocking/with_rspec.rb +0 -27
- data/lib/rspec/core/shared_example_group/collection.rb +0 -45
- 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/command_line/order_spec.rb +0 -204
- data/spec/rspec/core/backtrace_cleaner_spec.rb +0 -68
- data/spec/rspec/core/caller_filter_spec.rb +0 -58
- data/spec/rspec/core/command_line_spec.rb +0 -127
- data/spec/rspec/core/command_line_spec_output.txt +0 -0
- data/spec/rspec/core/configuration_options_spec.rb +0 -417
- data/spec/rspec/core/configuration_spec.rb +0 -2072
- data/spec/rspec/core/deprecation_spec.rb +0 -27
- data/spec/rspec/core/deprecations_spec.rb +0 -59
- data/spec/rspec/core/drb_command_line_spec.rb +0 -102
- data/spec/rspec/core/drb_options_spec.rb +0 -193
- data/spec/rspec/core/dsl_spec.rb +0 -25
- data/spec/rspec/core/example_group_spec.rb +0 -1337
- data/spec/rspec/core/example_spec.rb +0 -502
- data/spec/rspec/core/filter_manager_spec.rb +0 -246
- data/spec/rspec/core/formatters/base_formatter_spec.rb +0 -108
- data/spec/rspec/core/formatters/base_text_formatter_spec.rb +0 -524
- data/spec/rspec/core/formatters/console_codes_spec.rb +0 -50
- data/spec/rspec/core/formatters/deprecation_formatter_spec.rb +0 -263
- data/spec/rspec/core/formatters/documentation_formatter_spec.rb +0 -89
- data/spec/rspec/core/formatters/helpers_spec.rb +0 -104
- data/spec/rspec/core/formatters/html_formatted.html +0 -397
- data/spec/rspec/core/formatters/html_formatter_spec.rb +0 -131
- data/spec/rspec/core/formatters/json_formatter_spec.rb +0 -115
- data/spec/rspec/core/formatters/progress_formatter_spec.rb +0 -30
- data/spec/rspec/core/formatters/snippet_extractor_spec.rb +0 -26
- data/spec/rspec/core/formatters/text_mate_formatted.html +0 -397
- data/spec/rspec/core/formatters/text_mate_formatter_spec.rb +0 -107
- data/spec/rspec/core/hooks_filtering_spec.rb +0 -227
- data/spec/rspec/core/hooks_spec.rb +0 -269
- data/spec/rspec/core/kernel_extensions_spec.rb +0 -9
- data/spec/rspec/core/memoized_helpers_spec.rb +0 -776
- data/spec/rspec/core/metadata_spec.rb +0 -514
- data/spec/rspec/core/option_parser_spec.rb +0 -297
- data/spec/rspec/core/pending_example_spec.rb +0 -260
- data/spec/rspec/core/pending_spec.rb +0 -27
- data/spec/rspec/core/project_initializer_spec.rb +0 -130
- data/spec/rspec/core/rake_task_spec.rb +0 -202
- data/spec/rspec/core/reporter_spec.rb +0 -167
- data/spec/rspec/core/resources/a_bar.rb +0 -0
- data/spec/rspec/core/resources/a_foo.rb +0 -0
- data/spec/rspec/core/resources/a_spec.rb +0 -1
- data/spec/rspec/core/resources/custom_example_group_runner.rb +0 -14
- data/spec/rspec/core/resources/formatter_specs.rb +0 -60
- data/spec/rspec/core/resources/utf8_encoded.rb +0 -8
- data/spec/rspec/core/rspec_matchers_spec.rb +0 -45
- data/spec/rspec/core/ruby_project_spec.rb +0 -26
- data/spec/rspec/core/runner_spec.rb +0 -82
- data/spec/rspec/core/shared_context_spec.rb +0 -114
- data/spec/rspec/core/shared_example_group/collection_spec.rb +0 -70
- data/spec/rspec/core/shared_example_group_spec.rb +0 -138
- data/spec/rspec/core/world_spec.rb +0 -142
- data/spec/rspec/core_spec.rb +0 -108
- data/spec/spec_helper.rb +0 -135
- data/spec/support/config_options_helper.rb +0 -15
- data/spec/support/helper_methods.rb +0 -55
- data/spec/support/in_sub_process.rb +0 -37
- data/spec/support/isolate_load_path_mutation.rb +0 -6
- data/spec/support/isolated_directory.rb +0 -10
- data/spec/support/isolated_home_directory.rb +0 -16
- data/spec/support/matchers.rb +0 -65
- data/spec/support/mathn_integration_support.rb +0 -12
- data/spec/support/sandboxed_mock_space.rb +0 -116
- data/spec/support/shared_example_groups.rb +0 -42
- data/spec/support/silence_dsl_deprecations.rb +0 -32
- data/spec/support/spec_files.rb +0 -44
data/lib/rspec/core/hooks.rb
CHANGED
|
@@ -1,164 +1,28 @@
|
|
|
1
1
|
module RSpec
|
|
2
2
|
module Core
|
|
3
|
+
# Provides `before`, `after` and `around` hooks as a means of
|
|
4
|
+
# supporting common setup and teardown. This module is extended
|
|
5
|
+
# onto {ExampleGroup}, making the methods available from any `describe`
|
|
6
|
+
# or `context` block and included in {Configuration}, making them
|
|
7
|
+
# available off of the configuration object to define global setup
|
|
8
|
+
# or teardown logic.
|
|
3
9
|
module Hooks
|
|
4
|
-
include MetadataHashBuilder::WithConfigWarning
|
|
5
|
-
|
|
6
|
-
class Hook
|
|
7
|
-
attr_reader :block, :options
|
|
8
|
-
|
|
9
|
-
def initialize(block, options)
|
|
10
|
-
@block = block
|
|
11
|
-
@options = options
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def options_apply?(example_or_group)
|
|
15
|
-
example_or_group.all_apply?(options)
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
class BeforeHook < Hook
|
|
20
|
-
def run(example)
|
|
21
|
-
example.instance_eval_with_args(example, &block)
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def display_name
|
|
25
|
-
"before hook"
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
class AfterHook < Hook
|
|
30
|
-
def run(example)
|
|
31
|
-
example.instance_eval_with_rescue("in an after hook", &block)
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def display_name
|
|
35
|
-
"after hook"
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
class AfterAllHook < Hook
|
|
40
|
-
def run(example)
|
|
41
|
-
example.instance_exec(example, &block)
|
|
42
|
-
rescue Exception => e
|
|
43
|
-
# TODO: come up with a better solution for this.
|
|
44
|
-
RSpec.configuration.reporter.message <<-EOS
|
|
45
|
-
|
|
46
|
-
An error occurred in an after(:all) hook.
|
|
47
|
-
#{e.class}: #{e.message}
|
|
48
|
-
occurred at #{e.backtrace.first}
|
|
49
|
-
|
|
50
|
-
EOS
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def display_name
|
|
54
|
-
"after(:all) hook"
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
class AroundHook < Hook
|
|
59
|
-
def display_name
|
|
60
|
-
"around hook"
|
|
61
|
-
end
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
module HookCollectionAliases
|
|
65
|
-
def self.included(host)
|
|
66
|
-
host.send :alias_method, :prepend, :unshift
|
|
67
|
-
host.send :alias_method, :append, :push
|
|
68
|
-
end
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
class HookCollection < Array
|
|
72
|
-
include HookCollectionAliases
|
|
73
|
-
|
|
74
|
-
def for(example_or_group)
|
|
75
|
-
self.class.new(select {|hook| hook.options_apply?(example_or_group)}).
|
|
76
|
-
with(example_or_group)
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
def with(example)
|
|
80
|
-
@example = example
|
|
81
|
-
self
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
def run
|
|
85
|
-
each {|h| h.run(@example) } unless empty?
|
|
86
|
-
end
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
class AroundHookCollection < Array
|
|
90
|
-
include HookCollectionAliases
|
|
91
|
-
|
|
92
|
-
def for(example, initial_procsy=nil)
|
|
93
|
-
self.class.new(select {|hook| hook.options_apply?(example)}).
|
|
94
|
-
with(example, initial_procsy)
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
def with(example, initial_procsy)
|
|
98
|
-
@example = example
|
|
99
|
-
@initial_procsy = initial_procsy
|
|
100
|
-
self
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
def run
|
|
104
|
-
inject(@initial_procsy) do |procsy, around_hook|
|
|
105
|
-
Example.procsy(procsy.metadata) do
|
|
106
|
-
@example.instance_eval_with_args(procsy, &around_hook.block)
|
|
107
|
-
end
|
|
108
|
-
end.call
|
|
109
|
-
end
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
class GroupHookCollection < Array
|
|
113
|
-
def for(group)
|
|
114
|
-
@group = group
|
|
115
|
-
self
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
def run
|
|
119
|
-
shift.run(@group) until empty?
|
|
120
|
-
end
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
module RegistersGlobals
|
|
124
|
-
def register_globals host, globals
|
|
125
|
-
[:before, :after, :around].each do |position|
|
|
126
|
-
process host, globals, position, :each
|
|
127
|
-
next if position == :around # no around(:all) hooks
|
|
128
|
-
process host, globals, position, :all
|
|
129
|
-
end
|
|
130
|
-
end
|
|
131
|
-
|
|
132
|
-
private
|
|
133
|
-
def process host, globals, position, scope
|
|
134
|
-
globals[position][scope].each do |hook|
|
|
135
|
-
unless host.parent_groups.any? { |a| a.hooks[position][scope].include? hook }
|
|
136
|
-
self[position][scope] << hook if scope == :each || hook.options_apply?(host)
|
|
137
|
-
end
|
|
138
|
-
end
|
|
139
|
-
end
|
|
140
|
-
end
|
|
141
|
-
|
|
142
|
-
# @private
|
|
143
|
-
def hooks
|
|
144
|
-
@hooks ||= {
|
|
145
|
-
:around => { :each => AroundHookCollection.new },
|
|
146
|
-
:before => { :each => HookCollection.new, :all => HookCollection.new, :suite => HookCollection.new },
|
|
147
|
-
:after => { :each => HookCollection.new, :all => HookCollection.new, :suite => HookCollection.new }
|
|
148
|
-
}.extend(RegistersGlobals)
|
|
149
|
-
end
|
|
150
|
-
|
|
151
10
|
# @api public
|
|
11
|
+
#
|
|
152
12
|
# @overload before(&block)
|
|
153
13
|
# @overload before(scope, &block)
|
|
14
|
+
# @param scope [Symbol] `:example`, `:context`, or `:suite` (defaults to `:example`)
|
|
154
15
|
# @overload before(scope, conditions, &block)
|
|
16
|
+
# @param scope [Symbol] `:example`, `:context`, or `:suite` (defaults to `:example`)
|
|
17
|
+
# @param conditions [Hash]
|
|
18
|
+
# constrains this hook to examples matching these conditions e.g.
|
|
19
|
+
# `before(:example, :ui => true) { ... }` will only run with examples or
|
|
20
|
+
# groups declared with `:ui => true`.
|
|
155
21
|
# @overload before(conditions, &block)
|
|
156
|
-
#
|
|
157
|
-
#
|
|
158
|
-
#
|
|
159
|
-
#
|
|
160
|
-
# `before(:each, :ui => true) { ... }` will only run with examples or
|
|
161
|
-
# groups declared with `:ui => true`.
|
|
22
|
+
# @param conditions [Hash]
|
|
23
|
+
# constrains this hook to examples matching these conditions e.g.
|
|
24
|
+
# `before(:example, :ui => true) { ... }` will only run with examples or
|
|
25
|
+
# groups declared with `:ui => true`.
|
|
162
26
|
#
|
|
163
27
|
# @see #after
|
|
164
28
|
# @see #around
|
|
@@ -167,43 +31,43 @@ EOS
|
|
|
167
31
|
# @see SharedExampleGroup
|
|
168
32
|
# @see Configuration
|
|
169
33
|
#
|
|
170
|
-
# Declare a block of code to be run before each example (using `:
|
|
171
|
-
# or once before any example (using `:
|
|
34
|
+
# Declare a block of code to be run before each example (using `:example`)
|
|
35
|
+
# or once before any example (using `:context`). These are usually declared
|
|
172
36
|
# directly in the {ExampleGroup} to which they apply, but they can also
|
|
173
37
|
# be shared across multiple groups.
|
|
174
38
|
#
|
|
175
39
|
# You can also use `before(:suite)` to run a block of code before any
|
|
176
40
|
# example groups are run. This should be declared in {RSpec.configure}
|
|
177
41
|
#
|
|
178
|
-
# Instance variables declared in `before(:
|
|
42
|
+
# Instance variables declared in `before(:example)` or `before(:context)` are
|
|
179
43
|
# accessible within each example.
|
|
180
44
|
#
|
|
181
45
|
# ### Order
|
|
182
46
|
#
|
|
183
47
|
# `before` hooks are stored in three scopes, which are run in order:
|
|
184
|
-
# `:suite`, `:
|
|
48
|
+
# `:suite`, `:context`, and `:example`. They can also be declared in several
|
|
185
49
|
# different places: `RSpec.configure`, a parent group, the current group.
|
|
186
50
|
# They are run in the following order:
|
|
187
51
|
#
|
|
188
|
-
# before(:suite)
|
|
189
|
-
# before(:
|
|
190
|
-
# before(:
|
|
191
|
-
# before(:
|
|
192
|
-
# before(:
|
|
193
|
-
# before(:
|
|
194
|
-
# before(:
|
|
52
|
+
# before(:suite) # declared in RSpec.configure
|
|
53
|
+
# before(:context) # declared in RSpec.configure
|
|
54
|
+
# before(:context) # declared in a parent group
|
|
55
|
+
# before(:context) # declared in the current group
|
|
56
|
+
# before(:example) # declared in RSpec.configure
|
|
57
|
+
# before(:example) # declared in a parent group
|
|
58
|
+
# before(:example) # declared in the current group
|
|
195
59
|
#
|
|
196
60
|
# If more than one `before` is declared within any one scope, they are run
|
|
197
61
|
# in the order in which they are declared.
|
|
198
62
|
#
|
|
199
63
|
# ### Conditions
|
|
200
64
|
#
|
|
201
|
-
# When you add a conditions hash to `before(:
|
|
65
|
+
# When you add a conditions hash to `before(:example)` or `before(:context)`,
|
|
202
66
|
# RSpec will only apply that hook to groups or examples that match the
|
|
203
67
|
# conditions. e.g.
|
|
204
68
|
#
|
|
205
69
|
# RSpec.configure do |config|
|
|
206
|
-
# config.before(:
|
|
70
|
+
# config.before(:example, :authorized => true) do
|
|
207
71
|
# log_in_as :authorized_user
|
|
208
72
|
# end
|
|
209
73
|
# end
|
|
@@ -232,7 +96,7 @@ EOS
|
|
|
232
96
|
#
|
|
233
97
|
# When an exception is raised in a `before` block, RSpec skips any
|
|
234
98
|
# subsequent `before` blocks and the example, but runs all of the
|
|
235
|
-
# `after(:
|
|
99
|
+
# `after(:example)` and `after(:context)` hooks.
|
|
236
100
|
#
|
|
237
101
|
# ### Warning: implicit before blocks
|
|
238
102
|
#
|
|
@@ -243,20 +107,20 @@ EOS
|
|
|
243
107
|
# before block depends on state that is prepared in another before block
|
|
244
108
|
# that gets run later.
|
|
245
109
|
#
|
|
246
|
-
# ### Warning: `before(:
|
|
110
|
+
# ### Warning: `before(:context)`
|
|
247
111
|
#
|
|
248
|
-
# It is very tempting to use `before(:
|
|
112
|
+
# It is very tempting to use `before(:context)` to speed things up, but we
|
|
249
113
|
# recommend that you avoid this as there are a number of gotchas, as well
|
|
250
114
|
# as things that simply don't work.
|
|
251
115
|
#
|
|
252
116
|
# #### context
|
|
253
117
|
#
|
|
254
|
-
# `before(:
|
|
118
|
+
# `before(:context)` is run in an example that is generated to provide group
|
|
255
119
|
# context for the block.
|
|
256
120
|
#
|
|
257
121
|
# #### instance variables
|
|
258
122
|
#
|
|
259
|
-
# Instance variables declared in `before(:
|
|
123
|
+
# Instance variables declared in `before(:context)` are shared across all the
|
|
260
124
|
# examples in the group. This means that each example can change the
|
|
261
125
|
# state of a shared object, resulting in an ordering dependency that can
|
|
262
126
|
# make it difficult to reason about failures.
|
|
@@ -264,7 +128,7 @@ EOS
|
|
|
264
128
|
# #### unsupported rspec constructs
|
|
265
129
|
#
|
|
266
130
|
# RSpec has several constructs that reset state between each example
|
|
267
|
-
# automatically. These are not intended for use from within `before(:
|
|
131
|
+
# automatically. These are not intended for use from within `before(:context)`:
|
|
268
132
|
#
|
|
269
133
|
# * `let` declarations
|
|
270
134
|
# * `subject` declarations
|
|
@@ -276,17 +140,17 @@ EOS
|
|
|
276
140
|
# ActiveRecord) are typically designed around the idea of setting up
|
|
277
141
|
# before an example, running that one example, and then tearing down.
|
|
278
142
|
# This means that mocks and stubs can (sometimes) be declared in
|
|
279
|
-
# `before(:
|
|
143
|
+
# `before(:context)`, but get torn down before the first real example is ever
|
|
280
144
|
# run.
|
|
281
145
|
#
|
|
282
|
-
# You _can_ create database-backed model objects in a `before(:
|
|
146
|
+
# You _can_ create database-backed model objects in a `before(:context)` in
|
|
283
147
|
# rspec-rails, but it will not be wrapped in a transaction for you, so
|
|
284
|
-
# you are on your own to clean up in an `after(:
|
|
148
|
+
# you are on your own to clean up in an `after(:context)` block.
|
|
285
149
|
#
|
|
286
|
-
# @example before(:
|
|
150
|
+
# @example before(:example) declared in an {ExampleGroup}
|
|
287
151
|
#
|
|
288
152
|
# describe Thing do
|
|
289
|
-
# before(:
|
|
153
|
+
# before(:example) do
|
|
290
154
|
# @thing = Thing.new
|
|
291
155
|
# end
|
|
292
156
|
#
|
|
@@ -295,10 +159,10 @@ EOS
|
|
|
295
159
|
# end
|
|
296
160
|
# end
|
|
297
161
|
#
|
|
298
|
-
# @example before(:
|
|
162
|
+
# @example before(:context) declared in an {ExampleGroup}
|
|
299
163
|
#
|
|
300
164
|
# describe Parser do
|
|
301
|
-
# before(:
|
|
165
|
+
# before(:context) do
|
|
302
166
|
# File.open(file_to_parse, 'w') do |f|
|
|
303
167
|
# f.write <<-CONTENT
|
|
304
168
|
# stuff in the file
|
|
@@ -310,35 +174,42 @@ EOS
|
|
|
310
174
|
# Parser.parse(file_to_parse)
|
|
311
175
|
# end
|
|
312
176
|
#
|
|
313
|
-
# after(:
|
|
177
|
+
# after(:context) do
|
|
314
178
|
# File.delete(file_to_parse)
|
|
315
179
|
# end
|
|
316
180
|
# end
|
|
181
|
+
#
|
|
182
|
+
# @note The `:example` and `:context` scopes are also available as
|
|
183
|
+
# `:each` and `:all`, respectively. Use whichever you prefer.
|
|
317
184
|
def before(*args, &block)
|
|
318
|
-
|
|
185
|
+
hooks.register :append, :before, *args, &block
|
|
319
186
|
end
|
|
320
187
|
|
|
321
188
|
alias_method :append_before, :before
|
|
322
189
|
|
|
323
190
|
# Adds `block` to the front of the list of `before` blocks in the same
|
|
324
|
-
# scope (`:
|
|
191
|
+
# scope (`:example`, `:context`, or `:suite`).
|
|
325
192
|
#
|
|
326
|
-
# See #before for scoping semantics.
|
|
193
|
+
# See {#before} for scoping semantics.
|
|
327
194
|
def prepend_before(*args, &block)
|
|
328
|
-
|
|
195
|
+
hooks.register :prepend, :before, *args, &block
|
|
329
196
|
end
|
|
330
197
|
|
|
331
198
|
# @api public
|
|
332
199
|
# @overload after(&block)
|
|
333
200
|
# @overload after(scope, &block)
|
|
201
|
+
# @param scope [Symbol] `:example`, `:context`, or `:suite` (defaults to `:example`)
|
|
334
202
|
# @overload after(scope, conditions, &block)
|
|
203
|
+
# @param scope [Symbol] `:example`, `:context`, or `:suite` (defaults to `:example`)
|
|
204
|
+
# @param conditions [Hash]
|
|
205
|
+
# constrains this hook to examples matching these conditions e.g.
|
|
206
|
+
# `after(:example, :ui => true) { ... }` will only run with examples or
|
|
207
|
+
# groups declared with `:ui => true`.
|
|
335
208
|
# @overload after(conditions, &block)
|
|
336
|
-
#
|
|
337
|
-
#
|
|
338
|
-
#
|
|
339
|
-
#
|
|
340
|
-
# `after(:each, :ui => true) { ... }` will only run with examples or
|
|
341
|
-
# groups declared with `:ui => true`.
|
|
209
|
+
# @param conditions [Hash]
|
|
210
|
+
# constrains this hook to examples matching these conditions e.g.
|
|
211
|
+
# `after(:example, :ui => true) { ... }` will only run with examples or
|
|
212
|
+
# groups declared with `:ui => true`.
|
|
342
213
|
#
|
|
343
214
|
# @see #before
|
|
344
215
|
# @see #around
|
|
@@ -347,10 +218,9 @@ EOS
|
|
|
347
218
|
# @see SharedExampleGroup
|
|
348
219
|
# @see Configuration
|
|
349
220
|
#
|
|
350
|
-
# Declare a block of code to be run after each example (using `:
|
|
351
|
-
# once after all examples (using `:
|
|
352
|
-
#
|
|
353
|
-
# ordering.
|
|
221
|
+
# Declare a block of code to be run after each example (using `:example`) or
|
|
222
|
+
# once after all examples n the context (using `:context`). See {#before} for
|
|
223
|
+
# more information about ordering.
|
|
354
224
|
#
|
|
355
225
|
# ### Exceptions
|
|
356
226
|
#
|
|
@@ -362,48 +232,57 @@ EOS
|
|
|
362
232
|
# ### Order
|
|
363
233
|
#
|
|
364
234
|
# `after` hooks are stored in three scopes, which are run in order:
|
|
365
|
-
# `:
|
|
235
|
+
# `:example`, `:context`, and `:suite`. They can also be declared in several
|
|
366
236
|
# different places: `RSpec.configure`, a parent group, the current group.
|
|
367
237
|
# They are run in the following order:
|
|
368
238
|
#
|
|
369
|
-
# after(:
|
|
370
|
-
# after(:
|
|
371
|
-
# after(:
|
|
372
|
-
# after(:
|
|
373
|
-
# after(:
|
|
374
|
-
# after(:
|
|
239
|
+
# after(:example) # declared in the current group
|
|
240
|
+
# after(:example) # declared in a parent group
|
|
241
|
+
# after(:example) # declared in RSpec.configure
|
|
242
|
+
# after(:context) # declared in the current group
|
|
243
|
+
# after(:context) # declared in a parent group
|
|
244
|
+
# after(:context) # declared in RSpec.configure
|
|
245
|
+
# after(:suite) # declared in RSpec.configure
|
|
375
246
|
#
|
|
376
247
|
# This is the reverse of the order in which `before` hooks are run.
|
|
377
248
|
# Similarly, if more than one `after` is declared within any one scope,
|
|
378
249
|
# they are run in reverse order of that in which they are declared.
|
|
250
|
+
#
|
|
251
|
+
# @note The `:example` and `:context` scopes are also available as
|
|
252
|
+
# `:each` and `:all`, respectively. Use whichever you prefer.
|
|
379
253
|
def after(*args, &block)
|
|
380
|
-
|
|
254
|
+
hooks.register :prepend, :after, *args, &block
|
|
381
255
|
end
|
|
382
256
|
|
|
383
257
|
alias_method :prepend_after, :after
|
|
384
258
|
|
|
385
259
|
# Adds `block` to the back of the list of `after` blocks in the same
|
|
386
|
-
# scope (`:
|
|
260
|
+
# scope (`:example`, `:context`, or `:suite`).
|
|
387
261
|
#
|
|
388
|
-
# See #after for scoping semantics.
|
|
262
|
+
# See {#after} for scoping semantics.
|
|
389
263
|
def append_after(*args, &block)
|
|
390
|
-
|
|
264
|
+
hooks.register :append, :after, *args, &block
|
|
391
265
|
end
|
|
392
266
|
|
|
393
267
|
# @api public
|
|
394
268
|
# @overload around(&block)
|
|
395
269
|
# @overload around(scope, &block)
|
|
270
|
+
# @param scope [Symbol] `:example` (defaults to `:example`)
|
|
271
|
+
# present for syntax parity with `before` and `after`, but
|
|
272
|
+
# `:example`/`:each` is the only supported value.
|
|
396
273
|
# @overload around(scope, conditions, &block)
|
|
274
|
+
# @param scope [Symbol] `:example` (defaults to `:example`)
|
|
275
|
+
# present for syntax parity with `before` and `after`, but
|
|
276
|
+
# `:example`/`:each` is the only supported value.
|
|
277
|
+
# @param conditions [Hash]
|
|
278
|
+
# constrains this hook to examples matching these conditions e.g.
|
|
279
|
+
# `around(:example, :ui => true) { ... }` will only run with examples or
|
|
280
|
+
# groups declared with `:ui => true`.
|
|
397
281
|
# @overload around(conditions, &block)
|
|
398
|
-
#
|
|
399
|
-
#
|
|
400
|
-
#
|
|
401
|
-
#
|
|
402
|
-
#
|
|
403
|
-
# @param [Hash] conditions
|
|
404
|
-
# constrains this hook to examples matching these conditions e.g.
|
|
405
|
-
# `around(:each, :ui => true) { ... }` will only run with examples or
|
|
406
|
-
# groups declared with `:ui => true`.
|
|
282
|
+
# @param conditions [Hash]
|
|
283
|
+
# constrains this hook to examples matching these conditions e.g.
|
|
284
|
+
# `around(:example, :ui => true) { ... }` will only run with examples or
|
|
285
|
+
# groups declared with `:ui => true`.
|
|
407
286
|
#
|
|
408
287
|
# @yield [Example] the example to run
|
|
409
288
|
#
|
|
@@ -415,12 +294,12 @@ EOS
|
|
|
415
294
|
# resources that are made available within the examples and their
|
|
416
295
|
# associated `before` and `after` hooks.
|
|
417
296
|
#
|
|
418
|
-
# @note `:each` is the only supported scope.
|
|
297
|
+
# @note `:example`/`:each` is the only supported scope.
|
|
419
298
|
#
|
|
420
299
|
# Declare a block of code, parts of which will be run before and parts
|
|
421
300
|
# after the example. It is your responsibility to run the example:
|
|
422
301
|
#
|
|
423
|
-
# around(:
|
|
302
|
+
# around(:example) do |ex|
|
|
424
303
|
# # do some stuff before
|
|
425
304
|
# ex.run
|
|
426
305
|
# # do some stuff after
|
|
@@ -431,87 +310,263 @@ EOS
|
|
|
431
310
|
# that manage their own setup and teardown using a block or proc syntax,
|
|
432
311
|
# e.g.
|
|
433
312
|
#
|
|
434
|
-
# around(:
|
|
435
|
-
# around(:
|
|
313
|
+
# around(:example) {|ex| Database.transaction(&ex)}
|
|
314
|
+
# around(:example) {|ex| FakeFS(&ex)}
|
|
436
315
|
#
|
|
437
316
|
def around(*args, &block)
|
|
438
|
-
|
|
317
|
+
hooks.register :prepend, :around, *args, &block
|
|
439
318
|
end
|
|
440
319
|
|
|
441
320
|
# @private
|
|
442
|
-
#
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
# @private
|
|
450
|
-
def around_each_hooks_for(example, initial_procsy=nil)
|
|
451
|
-
AroundHookCollection.new(parent_groups.map {|a| a.hooks[:around][:each]}.flatten).for(example, initial_procsy)
|
|
321
|
+
# Holds the various registered hooks.
|
|
322
|
+
def hooks
|
|
323
|
+
@hooks ||= HookCollections.new(self,
|
|
324
|
+
:around => { :example => AroundHookCollection.new },
|
|
325
|
+
:before => { :example => HookCollection.new, :context => HookCollection.new, :suite => HookCollection.new },
|
|
326
|
+
:after => { :example => HookCollection.new, :context => HookCollection.new, :suite => HookCollection.new }
|
|
327
|
+
)
|
|
452
328
|
end
|
|
453
329
|
|
|
454
330
|
private
|
|
455
331
|
|
|
456
|
-
|
|
332
|
+
# @private
|
|
333
|
+
class Hook
|
|
334
|
+
attr_reader :block, :options
|
|
457
335
|
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
}
|
|
336
|
+
def initialize(block, options)
|
|
337
|
+
@block = block
|
|
338
|
+
@options = options
|
|
339
|
+
end
|
|
463
340
|
|
|
464
|
-
|
|
341
|
+
def options_apply?(example_or_group)
|
|
342
|
+
example_or_group.all_apply?(options)
|
|
343
|
+
end
|
|
344
|
+
end
|
|
465
345
|
|
|
466
|
-
|
|
467
|
-
|
|
346
|
+
# @private
|
|
347
|
+
class BeforeHook < Hook
|
|
348
|
+
def run(example)
|
|
349
|
+
example.instance_exec(example, &block)
|
|
350
|
+
end
|
|
468
351
|
end
|
|
469
352
|
|
|
470
|
-
|
|
471
|
-
|
|
353
|
+
# @private
|
|
354
|
+
class AfterHook < Hook
|
|
355
|
+
def run(example)
|
|
356
|
+
example.instance_exec_with_rescue("in an after hook", &block)
|
|
357
|
+
end
|
|
472
358
|
end
|
|
473
359
|
|
|
474
|
-
|
|
475
|
-
|
|
360
|
+
# @private
|
|
361
|
+
class AfterContextHook < Hook
|
|
362
|
+
def run(example)
|
|
363
|
+
example.instance_exec(example, &block)
|
|
364
|
+
rescue Exception => e
|
|
365
|
+
# TODO: come up with a better solution for this.
|
|
366
|
+
RSpec.configuration.reporter.message <<-EOS
|
|
367
|
+
|
|
368
|
+
An error occurred in an `after(:context)` hook.
|
|
369
|
+
#{e.class}: #{e.message}
|
|
370
|
+
occurred at #{e.backtrace.first}
|
|
371
|
+
|
|
372
|
+
EOS
|
|
373
|
+
end
|
|
476
374
|
end
|
|
477
375
|
|
|
478
|
-
|
|
479
|
-
|
|
376
|
+
# @private
|
|
377
|
+
AroundHook = Hook
|
|
378
|
+
|
|
379
|
+
# @private
|
|
380
|
+
class BaseHookCollection
|
|
381
|
+
Array.public_instance_methods(false).each do |name|
|
|
382
|
+
define_method(name) { |*a, &b| hooks.__send__(name, *a, &b) }
|
|
383
|
+
end
|
|
384
|
+
|
|
385
|
+
attr_reader :hooks
|
|
386
|
+
protected :hooks
|
|
387
|
+
|
|
388
|
+
alias append push
|
|
389
|
+
alias prepend unshift
|
|
390
|
+
|
|
391
|
+
def initialize(hooks=[])
|
|
392
|
+
@hooks = hooks
|
|
393
|
+
end
|
|
480
394
|
end
|
|
481
395
|
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
396
|
+
# @private
|
|
397
|
+
class HookCollection < BaseHookCollection
|
|
398
|
+
def for(example_or_group)
|
|
399
|
+
self.class.
|
|
400
|
+
new(hooks.select {|hook| hook.options_apply?(example_or_group)}).
|
|
401
|
+
with(example_or_group)
|
|
402
|
+
end
|
|
403
|
+
|
|
404
|
+
def with(example)
|
|
405
|
+
@example = example
|
|
406
|
+
self
|
|
407
|
+
end
|
|
408
|
+
|
|
409
|
+
def run
|
|
410
|
+
hooks.each {|h| h.run(@example)}
|
|
411
|
+
end
|
|
485
412
|
end
|
|
486
413
|
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
414
|
+
# @private
|
|
415
|
+
class AroundHookCollection < BaseHookCollection
|
|
416
|
+
def for(example, initial_procsy=nil)
|
|
417
|
+
self.class.new(hooks.select {|hook| hook.options_apply?(example)}).
|
|
418
|
+
with(example, initial_procsy)
|
|
419
|
+
end
|
|
420
|
+
|
|
421
|
+
def with(example, initial_procsy)
|
|
422
|
+
@example = example
|
|
423
|
+
@initial_procsy = initial_procsy
|
|
424
|
+
self
|
|
425
|
+
end
|
|
426
|
+
|
|
427
|
+
def run
|
|
428
|
+
hooks.inject(@initial_procsy) do |procsy, around_hook|
|
|
429
|
+
procsy.wrap do
|
|
430
|
+
@example.instance_exec(procsy, &around_hook.block)
|
|
431
|
+
end
|
|
432
|
+
end.call
|
|
501
433
|
end
|
|
502
434
|
end
|
|
503
435
|
|
|
504
|
-
|
|
505
|
-
|
|
436
|
+
# @private
|
|
437
|
+
class GroupHookCollection < BaseHookCollection
|
|
438
|
+
def for(group)
|
|
439
|
+
@group = group
|
|
440
|
+
self
|
|
441
|
+
end
|
|
442
|
+
|
|
443
|
+
def run
|
|
444
|
+
hooks.shift.run(@group) until hooks.empty?
|
|
445
|
+
end
|
|
506
446
|
end
|
|
507
447
|
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
448
|
+
# @private
|
|
449
|
+
class HookCollections
|
|
450
|
+
def initialize(owner, data)
|
|
451
|
+
@owner = owner
|
|
452
|
+
@data = data
|
|
453
|
+
end
|
|
454
|
+
|
|
455
|
+
def [](key)
|
|
456
|
+
@data[key]
|
|
457
|
+
end
|
|
458
|
+
|
|
459
|
+
def register_globals(host, globals)
|
|
460
|
+
process(host, globals, :before, :example)
|
|
461
|
+
process(host, globals, :after, :example)
|
|
462
|
+
process(host, globals, :around, :example)
|
|
463
|
+
|
|
464
|
+
process(host, globals, :before, :context)
|
|
465
|
+
process(host, globals, :after, :context)
|
|
466
|
+
end
|
|
467
|
+
|
|
468
|
+
def around_example_hooks_for(example, initial_procsy=nil)
|
|
469
|
+
AroundHookCollection.new(FlatMap.flat_map(@owner.parent_groups) do |a|
|
|
470
|
+
a.hooks[:around][:example]
|
|
471
|
+
end).for(example, initial_procsy)
|
|
472
|
+
end
|
|
473
|
+
|
|
474
|
+
def register(prepend_or_append, hook, *args, &block)
|
|
475
|
+
scope, options = scope_and_options_from(*args)
|
|
476
|
+
self[hook][scope].__send__(prepend_or_append, HOOK_TYPES[hook][scope].new(block, options))
|
|
477
|
+
end
|
|
478
|
+
|
|
479
|
+
# @private
|
|
480
|
+
#
|
|
481
|
+
# Runs all of the blocks stored with the hook in the context of the
|
|
482
|
+
# example. If no example is provided, just calls the hook directly.
|
|
483
|
+
def run(hook, scope, example_or_group, initial_procsy=nil)
|
|
484
|
+
return if RSpec.configuration.dry_run?
|
|
485
|
+
find_hook(hook, scope, example_or_group, initial_procsy).run
|
|
486
|
+
end
|
|
487
|
+
|
|
488
|
+
SCOPES = [:example, :context, :suite]
|
|
489
|
+
|
|
490
|
+
SCOPE_ALIASES = { :each => :example, :all => :context }
|
|
491
|
+
|
|
492
|
+
HOOK_TYPES = {
|
|
493
|
+
:before => Hash.new { BeforeHook },
|
|
494
|
+
:after => Hash.new { AfterHook },
|
|
495
|
+
:around => Hash.new { AroundHook }
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
HOOK_TYPES[:after][:context] = AfterContextHook
|
|
499
|
+
|
|
500
|
+
private
|
|
501
|
+
|
|
502
|
+
def process(host, globals, position, scope)
|
|
503
|
+
globals[position][scope].each do |hook|
|
|
504
|
+
next unless scope == :example || hook.options_apply?(host)
|
|
505
|
+
next if host.parent_groups.any? {|a| a.hooks[position][scope].include?(hook)}
|
|
506
|
+
self[position][scope] << hook
|
|
507
|
+
end
|
|
508
|
+
end
|
|
509
|
+
|
|
510
|
+
def scope_and_options_from(*args)
|
|
511
|
+
return extract_scope_from(args), Metadata.build_hash_from(args)
|
|
512
|
+
end
|
|
513
|
+
|
|
514
|
+
def extract_scope_from(args)
|
|
515
|
+
if known_scope?(args.first)
|
|
516
|
+
normalized_scope_for(args.shift)
|
|
517
|
+
elsif args.any? { |a| a.is_a?(Symbol) }
|
|
518
|
+
error_message = "You must explicitly give a scope (#{SCOPES.join(", ")}) or scope alias (#{SCOPE_ALIASES.keys.join(", ")}) when using symbols as metadata for a hook."
|
|
519
|
+
raise ArgumentError.new error_message
|
|
520
|
+
else
|
|
521
|
+
:example
|
|
522
|
+
end
|
|
523
|
+
end
|
|
524
|
+
|
|
525
|
+
# @api private
|
|
526
|
+
def known_scope?(scope)
|
|
527
|
+
SCOPES.include?(scope) || SCOPE_ALIASES.keys.include?(scope)
|
|
528
|
+
end
|
|
529
|
+
|
|
530
|
+
# @api private
|
|
531
|
+
def normalized_scope_for(scope)
|
|
532
|
+
SCOPE_ALIASES[scope] || scope
|
|
533
|
+
end
|
|
534
|
+
|
|
535
|
+
def find_hook(hook, scope, example_or_group, initial_procsy)
|
|
536
|
+
case [hook, scope]
|
|
537
|
+
when [:before, :context]
|
|
538
|
+
before_context_hooks_for(example_or_group)
|
|
539
|
+
when [:after, :context]
|
|
540
|
+
after_context_hooks_for(example_or_group)
|
|
541
|
+
when [:around, :example]
|
|
542
|
+
around_example_hooks_for(example_or_group, initial_procsy)
|
|
543
|
+
when [:before, :example]
|
|
544
|
+
before_example_hooks_for(example_or_group)
|
|
545
|
+
when [:after, :example]
|
|
546
|
+
after_example_hooks_for(example_or_group)
|
|
547
|
+
when [:before, :suite], [:after, :suite]
|
|
548
|
+
self[hook][:suite].with(example_or_group)
|
|
549
|
+
end
|
|
550
|
+
end
|
|
551
|
+
|
|
552
|
+
def before_context_hooks_for(group)
|
|
553
|
+
GroupHookCollection.new(self[:before][:context]).for(group)
|
|
554
|
+
end
|
|
555
|
+
|
|
556
|
+
def after_context_hooks_for(group)
|
|
557
|
+
GroupHookCollection.new(self[:after][:context]).for(group)
|
|
558
|
+
end
|
|
559
|
+
|
|
560
|
+
def before_example_hooks_for(example)
|
|
561
|
+
HookCollection.new(FlatMap.flat_map(@owner.parent_groups.reverse) do |a|
|
|
562
|
+
a.hooks[:before][:example]
|
|
563
|
+
end).for(example)
|
|
564
|
+
end
|
|
565
|
+
|
|
566
|
+
def after_example_hooks_for(example)
|
|
567
|
+
HookCollection.new(FlatMap.flat_map(@owner.parent_groups) do |a|
|
|
568
|
+
a.hooks[:after][:example]
|
|
569
|
+
end).for(example)
|
|
515
570
|
end
|
|
516
571
|
end
|
|
517
572
|
end
|