rspec-sleeping_king_studios 2.7.0 → 2.8.0.rc.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 +4 -4
- data/CHANGELOG.md +25 -0
- data/README.md +228 -9
- data/config/rubocop-rspec.yml +41 -0
- data/lib/rspec/sleeping_king_studios/concerns/example_constants.rb +107 -74
- data/lib/rspec/sleeping_king_studios/concerns/memoized_helpers.rb +19 -0
- data/lib/rspec/sleeping_king_studios/concerns/shared_example_group.rb +5 -2
- data/lib/rspec/sleeping_king_studios/concerns.rb +8 -3
- data/lib/rspec/sleeping_king_studios/configuration.rb +45 -37
- data/lib/rspec/sleeping_king_studios/deferred/call.rb +74 -0
- data/lib/rspec/sleeping_king_studios/deferred/calls/example.rb +42 -0
- data/lib/rspec/sleeping_king_studios/deferred/calls/example_group.rb +42 -0
- data/lib/rspec/sleeping_king_studios/deferred/calls/hook.rb +64 -0
- data/lib/rspec/sleeping_king_studios/deferred/calls/included_examples.rb +34 -0
- data/lib/rspec/sleeping_king_studios/deferred/calls/shared_examples.rb +41 -0
- data/lib/rspec/sleeping_king_studios/deferred/calls.rb +19 -0
- data/lib/rspec/sleeping_king_studios/deferred/consumer.rb +159 -0
- data/lib/rspec/sleeping_king_studios/deferred/definitions.rb +42 -0
- data/lib/rspec/sleeping_king_studios/deferred/dependencies.rb +138 -0
- data/lib/rspec/sleeping_king_studios/deferred/dsl/example_constants.rb +72 -0
- data/lib/rspec/sleeping_king_studios/deferred/dsl/example_groups.rb +69 -0
- data/lib/rspec/sleeping_king_studios/deferred/dsl/examples.rb +84 -0
- data/lib/rspec/sleeping_king_studios/deferred/dsl/hooks.rb +125 -0
- data/lib/rspec/sleeping_king_studios/deferred/dsl/memoized_helpers.rb +123 -0
- data/lib/rspec/sleeping_king_studios/deferred/dsl/shared_examples.rb +128 -0
- data/lib/rspec/sleeping_king_studios/deferred/dsl.rb +26 -0
- data/lib/rspec/sleeping_king_studios/deferred/examples.rb +83 -0
- data/lib/rspec/sleeping_king_studios/deferred/missing.rb +46 -0
- data/lib/rspec/sleeping_king_studios/deferred/provider.rb +164 -0
- data/lib/rspec/sleeping_king_studios/deferred.rb +142 -0
- data/lib/rspec/sleeping_king_studios/matchers/built_in/include_matcher.rb +85 -70
- data/lib/rspec/sleeping_king_studios/matchers/core/deep_matcher.rb +28 -23
- data/lib/rspec/sleeping_king_studios/sandbox.rb +105 -0
- data/lib/rspec/sleeping_king_studios/version.rb +4 -3
- data/lib/rspec/sleeping_king_studios.rb +10 -4
- metadata +36 -141
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'rspec/sleeping_king_studios'
|
4
4
|
|
@@ -19,7 +19,7 @@ module RSpec::SleepingKingStudios
|
|
19
19
|
# @return [Symbol] The current missing message handler.
|
20
20
|
def handle_missing_failure_message_with
|
21
21
|
@handle_missing_failure_message_with ||= :pending
|
22
|
-
end
|
22
|
+
end
|
23
23
|
|
24
24
|
# Sets the handler for missing failure messages when using the matcher
|
25
25
|
# examples.
|
@@ -29,17 +29,19 @@ module RSpec::SleepingKingStudios
|
|
29
29
|
#
|
30
30
|
# @raise ArgumentError If the handler is not one of the recognized
|
31
31
|
# values.
|
32
|
-
def handle_missing_failure_message_with=
|
32
|
+
def handle_missing_failure_message_with=(value)
|
33
33
|
value = value.to_s.intern
|
34
34
|
|
35
35
|
unless MISSING_FAILURE_MESSAGE_HANDLERS.include?(value)
|
36
|
-
message =
|
36
|
+
message =
|
37
|
+
'unrecognized handler value -- must be in ' \
|
38
|
+
"#{MISSING_FAILURE_MESSAGE_HANDLERS.join ', '}"
|
37
39
|
|
38
|
-
raise ArgumentError
|
39
|
-
end
|
40
|
+
raise ArgumentError, message
|
41
|
+
end
|
40
42
|
|
41
43
|
@handle_missing_failure_message_with = value
|
42
|
-
end
|
44
|
+
end
|
43
45
|
|
44
46
|
# Gets the option for matching failure messages to strings, and sets to
|
45
47
|
# :substring if unset.
|
@@ -47,7 +49,7 @@ module RSpec::SleepingKingStudios
|
|
47
49
|
# @return [Symbol] The current failure message string matching option.
|
48
50
|
def match_string_failure_message_as
|
49
51
|
@match_string_failure_message_as ||= :substring
|
50
|
-
end
|
52
|
+
end
|
51
53
|
|
52
54
|
# Sets the option for matching failure messages to strings.
|
53
55
|
#
|
@@ -56,19 +58,21 @@ module RSpec::SleepingKingStudios
|
|
56
58
|
#
|
57
59
|
# @raise ArgumentError If the handler is not one of the recognized
|
58
60
|
# values.
|
59
|
-
def match_string_failure_message_as=
|
61
|
+
def match_string_failure_message_as=(value)
|
60
62
|
value = value.to_s.intern
|
61
63
|
value = :substring if value == :partial
|
62
64
|
|
63
65
|
unless STRING_FAILURE_MESSAGE_MATCH_OPTIONS.include?(value)
|
64
|
-
message =
|
66
|
+
message =
|
67
|
+
'unrecognized value -- must be in ' \
|
68
|
+
"#{STRING_FAILURE_MESSAGE_MATCH_OPTIONS.join ', '}"
|
65
69
|
|
66
|
-
raise ArgumentError
|
67
|
-
end
|
70
|
+
raise ArgumentError, message
|
71
|
+
end
|
68
72
|
|
69
73
|
@match_string_failure_message_as = value
|
70
|
-
end
|
71
|
-
end
|
74
|
+
end
|
75
|
+
end
|
72
76
|
|
73
77
|
# Configuration options for RSpec::SleepingKingStudios::Matchers.
|
74
78
|
class Matchers
|
@@ -77,12 +81,14 @@ module RSpec::SleepingKingStudios
|
|
77
81
|
#
|
78
82
|
# @return [Boolean] True if the empty include matchers are permitted,
|
79
83
|
# otherwise false.
|
84
|
+
#
|
85
|
+
# @deprecated [3.0] Will be removed in version 3.0.
|
80
86
|
def allow_empty_include_matchers
|
81
87
|
value = @allow_empty_include_matchers
|
82
88
|
|
83
|
-
value.nil? ? true : value
|
84
|
-
end
|
85
|
-
|
89
|
+
value.nil? ? true : value # rubocop:disable Style/RedundantCondition
|
90
|
+
end
|
91
|
+
alias allow_empty_include_matchers? allow_empty_include_matchers
|
86
92
|
|
87
93
|
# Sets whether the #include matcher can be instantiated without an
|
88
94
|
# expectation object or block. If this option is set to false, an
|
@@ -97,9 +103,11 @@ module RSpec::SleepingKingStudios
|
|
97
103
|
#
|
98
104
|
# @return [Boolean] True if the empty include matchers are permitted,
|
99
105
|
# otherwise false.
|
100
|
-
|
106
|
+
#
|
107
|
+
# @deprecated [3.0] Will be removed in version 3.0.
|
108
|
+
def allow_empty_include_matchers=(value)
|
101
109
|
@allow_empty_include_matchers = !!value
|
102
|
-
end
|
110
|
+
end
|
103
111
|
|
104
112
|
# Checks whether predicates are matched "strictly", meaning that they must
|
105
113
|
# return either true or false.
|
@@ -108,47 +116,47 @@ module RSpec::SleepingKingStudios
|
|
108
116
|
# false.
|
109
117
|
def strict_predicate_matching
|
110
118
|
@strict_predicate_matching ||= false
|
111
|
-
end
|
112
|
-
|
119
|
+
end
|
120
|
+
alias strict_predicate_matching? strict_predicate_matching
|
113
121
|
|
114
122
|
# Sets whether predicates are matched "strictly", meaning that they must
|
115
123
|
# return either true or false.
|
116
124
|
#
|
117
125
|
# @param [Boolean] value The desired value. Is coerced to true or false.
|
118
|
-
def strict_predicate_matching=
|
126
|
+
def strict_predicate_matching=(value)
|
119
127
|
@strict_predicate_matching = !!value
|
120
|
-
end
|
121
|
-
end
|
128
|
+
end
|
129
|
+
end
|
122
130
|
|
123
131
|
# Get or set the configuration options for
|
124
132
|
# RSpec::SleepingKingStudios::Examples.
|
125
|
-
def examples
|
133
|
+
def examples(&)
|
126
134
|
@examples ||= RSpec::SleepingKingStudios::Configuration::Examples.new
|
127
135
|
|
128
|
-
@examples.instance_eval(&
|
136
|
+
@examples.instance_eval(&) if block_given?
|
129
137
|
|
130
138
|
@examples
|
131
|
-
end
|
139
|
+
end
|
132
140
|
|
133
141
|
# Get or set the configuration options for
|
134
142
|
# RSpec::SleepingKingStudios::Matchers.
|
135
|
-
def matchers
|
143
|
+
def matchers(&)
|
136
144
|
@matchers ||= RSpec::SleepingKingStudios::Configuration::Matchers.new
|
137
145
|
|
138
|
-
@matchers.instance_eval(&
|
146
|
+
@matchers.instance_eval(&) if block_given?
|
139
147
|
|
140
148
|
@matchers
|
141
|
-
end
|
142
|
-
end
|
143
|
-
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
144
152
|
|
145
|
-
class RSpec::Core::Configuration
|
153
|
+
class RSpec::Core::Configuration # rubocop:disable Style/Documentation
|
146
154
|
# Get or set the configuration options for RSpec::SleepingKingStudios.
|
147
|
-
def sleeping_king_studios
|
155
|
+
def sleeping_king_studios(&)
|
148
156
|
@sleeping_king_studios ||= RSpec::SleepingKingStudios::Configuration.new
|
149
157
|
|
150
|
-
@sleeping_king_studios.instance_eval(&
|
158
|
+
@sleeping_king_studios.instance_eval(&) if block_given?
|
151
159
|
|
152
160
|
@sleeping_king_studios
|
153
|
-
end
|
154
|
-
end
|
161
|
+
end
|
162
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'sleeping_king_studios/tools/toolbelt'
|
4
|
+
|
5
|
+
require 'rspec/sleeping_king_studios/deferred'
|
6
|
+
|
7
|
+
module RSpec::SleepingKingStudios::Deferred
|
8
|
+
# Value object representing a deferred call to a method.
|
9
|
+
class Call
|
10
|
+
# @param method_name [String, Symbol] the name of the method to call.
|
11
|
+
# @param arguments [Array] the arguments to pass to the method.
|
12
|
+
# @param keywords [Hash] the keywords to pass to the method.
|
13
|
+
# @param block [Proc] the block to pass to the method.
|
14
|
+
def initialize(method_name, *arguments, **keywords, &block)
|
15
|
+
@method_name = method_name
|
16
|
+
@arguments = arguments
|
17
|
+
@keywords = keywords
|
18
|
+
@block = block
|
19
|
+
|
20
|
+
validate_parameters!
|
21
|
+
end
|
22
|
+
|
23
|
+
# @return [Array] the arguments to pass to the method.
|
24
|
+
attr_reader :arguments
|
25
|
+
|
26
|
+
# @return [Proc] the block to pass to the method.
|
27
|
+
attr_reader :block
|
28
|
+
|
29
|
+
# @return [Hash] the keywords to pass to the method.
|
30
|
+
attr_reader :keywords
|
31
|
+
|
32
|
+
# @return [String, Symbol] the name of the method to call.
|
33
|
+
attr_reader :method_name
|
34
|
+
|
35
|
+
# Compares the other object with the deferred call.
|
36
|
+
#
|
37
|
+
# Returns true if and only if:
|
38
|
+
# - The other object is an instance of Deferred::Call.
|
39
|
+
# - The other object's method name and type match the deferred call.
|
40
|
+
# - The other object's arguments, keywords, and block all match the deferred
|
41
|
+
# call.
|
42
|
+
#
|
43
|
+
# @param other [Object] the object to compare.
|
44
|
+
#
|
45
|
+
# @return [Boolean] true if the other matches the deferred call; otherwise
|
46
|
+
# false.
|
47
|
+
def ==(other)
|
48
|
+
other.class == self.class &&
|
49
|
+
other.method_name == method_name &&
|
50
|
+
other.arguments == arguments &&
|
51
|
+
other.keywords == keywords &&
|
52
|
+
other.block == block
|
53
|
+
end
|
54
|
+
|
55
|
+
# Invokes the deferred method call on the receiver.
|
56
|
+
#
|
57
|
+
# @param receiver [Object] the receiver for the method call.
|
58
|
+
#
|
59
|
+
# @return [Object] the returned value of the method call.
|
60
|
+
def call(receiver)
|
61
|
+
receiver.send(method_name, *arguments, **keywords, &block)
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def tools
|
67
|
+
SleepingKingStudios::Tools::Toolbelt.instance
|
68
|
+
end
|
69
|
+
|
70
|
+
def validate_parameters!
|
71
|
+
tools.assertions.validate_name(method_name, as: 'method_name')
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rspec/sleeping_king_studios/deferred/call'
|
4
|
+
require 'rspec/sleeping_king_studios/deferred/calls'
|
5
|
+
|
6
|
+
module RSpec::SleepingKingStudios::Deferred::Calls
|
7
|
+
# Value object representing a deferred RSpec example.
|
8
|
+
class Example < RSpec::SleepingKingStudios::Deferred::Call
|
9
|
+
# @param method_name [String, Symbol] the name of the method to call.
|
10
|
+
# @param arguments [Array] the arguments to pass to the method.
|
11
|
+
# @param keywords [Hash] the keywords to pass to the method.
|
12
|
+
# @param deferred_example_group [Deferred::Examples] the deferred example
|
13
|
+
# group defining the deferred call.
|
14
|
+
# @param block [Proc] the block to pass to the method.
|
15
|
+
def initialize(
|
16
|
+
method_name,
|
17
|
+
*arguments,
|
18
|
+
deferred_example_group: nil,
|
19
|
+
**keywords,
|
20
|
+
&block
|
21
|
+
)
|
22
|
+
super(method_name, *arguments, **keywords, &block)
|
23
|
+
|
24
|
+
@deferred_example_group = deferred_example_group
|
25
|
+
end
|
26
|
+
|
27
|
+
# @return [Deferred::Examples] the deferred example group defining the
|
28
|
+
# deferred call.
|
29
|
+
attr_reader :deferred_example_group
|
30
|
+
|
31
|
+
# (see RSpec::SleepingKingStudios::Deferred::Call#call)
|
32
|
+
def call(receiver)
|
33
|
+
example = super
|
34
|
+
|
35
|
+
# Store a reference to the deferred group when adding to an actual example
|
36
|
+
# group.
|
37
|
+
example.metadata[:deferred_example_group] = @deferred_example_group
|
38
|
+
|
39
|
+
example
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rspec/sleeping_king_studios/deferred/call'
|
4
|
+
require 'rspec/sleeping_king_studios/deferred/calls'
|
5
|
+
|
6
|
+
module RSpec::SleepingKingStudios::Deferred::Calls
|
7
|
+
# Value object representing a deferred RSpec example group.
|
8
|
+
class ExampleGroup < RSpec::SleepingKingStudios::Deferred::Call
|
9
|
+
# @param method_name [String, Symbol] the name of the method to call.
|
10
|
+
# @param arguments [Array] the arguments to pass to the method.
|
11
|
+
# @param keywords [Hash] the keywords to pass to the method.
|
12
|
+
# @param deferred_example_group [Deferred::Examples] the deferred example
|
13
|
+
# group defining the deferred call.
|
14
|
+
# @param block [Proc] the block to pass to the method.
|
15
|
+
def initialize(
|
16
|
+
method_name,
|
17
|
+
*arguments,
|
18
|
+
deferred_example_group: nil,
|
19
|
+
**keywords,
|
20
|
+
&block
|
21
|
+
)
|
22
|
+
super(method_name, *arguments, **keywords, &block)
|
23
|
+
|
24
|
+
@deferred_example_group = deferred_example_group
|
25
|
+
end
|
26
|
+
|
27
|
+
# @return [Deferred::Examples] the deferred example group defining the
|
28
|
+
# deferred call.
|
29
|
+
attr_reader :deferred_example_group
|
30
|
+
|
31
|
+
# (see RSpec::SleepingKingStudios::Deferred::Call#call)
|
32
|
+
def call(receiver)
|
33
|
+
example_group = super
|
34
|
+
|
35
|
+
# Store a reference to the deferred group when adding to an actual example
|
36
|
+
# group.
|
37
|
+
example_group.metadata[:deferred_example_group] = @deferred_example_group
|
38
|
+
|
39
|
+
example_group
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'set'
|
4
|
+
|
5
|
+
require 'rspec/sleeping_king_studios/deferred/call'
|
6
|
+
require 'rspec/sleeping_king_studios/deferred/calls'
|
7
|
+
|
8
|
+
module RSpec::SleepingKingStudios::Deferred::Calls
|
9
|
+
# Value object representing a deferred RSpec example.
|
10
|
+
class Hook < RSpec::SleepingKingStudios::Deferred::Call
|
11
|
+
VALID_METHOD_NAMES = Set.new(
|
12
|
+
%i[after append_after around before prepend_before]
|
13
|
+
).freeze
|
14
|
+
private_constant :VALID_METHOD_NAMES
|
15
|
+
|
16
|
+
VALID_SCOPES = Set.new(%i[context each example]).freeze
|
17
|
+
private_constant :VALID_SCOPES
|
18
|
+
|
19
|
+
# @return [Symbol] the scope of the hook.
|
20
|
+
def scope
|
21
|
+
arguments.first&.intern
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def validate_block!
|
27
|
+
return if block
|
28
|
+
|
29
|
+
raise ArgumentError, 'no block given'
|
30
|
+
end
|
31
|
+
|
32
|
+
def validate_method_name!
|
33
|
+
return if VALID_METHOD_NAMES.include?(method_name)
|
34
|
+
|
35
|
+
raise ArgumentError, "invalid hook method #{method_name.inspect}"
|
36
|
+
end
|
37
|
+
|
38
|
+
def validate_parameters!
|
39
|
+
super
|
40
|
+
|
41
|
+
validate_block!
|
42
|
+
validate_method_name!
|
43
|
+
validate_scope!
|
44
|
+
end
|
45
|
+
|
46
|
+
def validate_scope! # rubocop:disable Metrics/MethodLength
|
47
|
+
tools.assertions.validate_name(arguments.first, as: :scope)
|
48
|
+
|
49
|
+
if method_name == :around
|
50
|
+
return if scope == :each || scope == :example # rubocop:disable Style/MultipleComparison
|
51
|
+
|
52
|
+
raise ArgumentError, 'scope for an :around hook must be :example'
|
53
|
+
else
|
54
|
+
return if VALID_SCOPES.include?(scope)
|
55
|
+
|
56
|
+
message =
|
57
|
+
"scope for a #{method_name.inspect} hook must be :context, :each, " \
|
58
|
+
'or :example'
|
59
|
+
|
60
|
+
raise ArgumentError, message
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rspec/sleeping_king_studios/deferred/call'
|
4
|
+
require 'rspec/sleeping_king_studios/deferred/calls'
|
5
|
+
|
6
|
+
module RSpec::SleepingKingStudios::Deferred::Calls
|
7
|
+
# Value object representing a deferred RSpec included example group.
|
8
|
+
class IncludedExamples < RSpec::SleepingKingStudios::Deferred::Call
|
9
|
+
# @return [String] the description for the shared example group.
|
10
|
+
def name
|
11
|
+
arguments.first
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def validate_name!
|
17
|
+
return if name.is_a?(Module)
|
18
|
+
|
19
|
+
return if (name.is_a?(String) || name.is_a?(Symbol)) && !name.to_s.empty?
|
20
|
+
|
21
|
+
message =
|
22
|
+
'shared example group name must be a non-empty String, Symbol, or ' \
|
23
|
+
'Module'
|
24
|
+
|
25
|
+
raise ArgumentError, message
|
26
|
+
end
|
27
|
+
|
28
|
+
def validate_parameters!
|
29
|
+
super
|
30
|
+
|
31
|
+
validate_name!
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rspec/sleeping_king_studios/deferred/call'
|
4
|
+
require 'rspec/sleeping_king_studios/deferred/calls'
|
5
|
+
|
6
|
+
module RSpec::SleepingKingStudios::Deferred::Calls
|
7
|
+
# Value object representing a deferred RSpec shared example group.
|
8
|
+
class SharedExamples < RSpec::SleepingKingStudios::Deferred::Call
|
9
|
+
# @return [String] the description for the shared example group.
|
10
|
+
def name
|
11
|
+
arguments.first
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def validate_block!
|
17
|
+
return if block
|
18
|
+
|
19
|
+
raise ArgumentError, 'no block given'
|
20
|
+
end
|
21
|
+
|
22
|
+
def validate_name!
|
23
|
+
return if name.is_a?(Module)
|
24
|
+
|
25
|
+
return if (name.is_a?(String) || name.is_a?(Symbol)) && !name.to_s.empty?
|
26
|
+
|
27
|
+
message =
|
28
|
+
'shared example group name must be a non-empty String, Symbol, or ' \
|
29
|
+
'Module'
|
30
|
+
|
31
|
+
raise ArgumentError, message
|
32
|
+
end
|
33
|
+
|
34
|
+
def validate_parameters!
|
35
|
+
super
|
36
|
+
|
37
|
+
validate_name!
|
38
|
+
validate_block!
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rspec/sleeping_king_studios/deferred'
|
4
|
+
|
5
|
+
module RSpec::SleepingKingStudios::Deferred
|
6
|
+
# Namespace for deferred call implementations.
|
7
|
+
module Calls
|
8
|
+
autoload :Example,
|
9
|
+
'rspec/sleeping_king_studios/deferred/calls/example'
|
10
|
+
autoload :ExampleGroup,
|
11
|
+
'rspec/sleeping_king_studios/deferred/calls/example_group'
|
12
|
+
autoload :Hook,
|
13
|
+
'rspec/sleeping_king_studios/deferred/calls/hook'
|
14
|
+
autoload :IncludedExamples,
|
15
|
+
'rspec/sleeping_king_studios/deferred/calls/included_examples'
|
16
|
+
autoload :SharedExamples,
|
17
|
+
'rspec/sleeping_king_studios/deferred/calls/shared_examples'
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,159 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'sleeping_king_studios/tools/toolbox/mixin'
|
4
|
+
|
5
|
+
require 'rspec/sleeping_king_studios/deferred'
|
6
|
+
require 'rspec/sleeping_king_studios/deferred/examples'
|
7
|
+
require 'rspec/sleeping_king_studios/deferred/provider'
|
8
|
+
|
9
|
+
module RSpec::SleepingKingStudios::Deferred
|
10
|
+
# Methods for including deferred examples.
|
11
|
+
module Consumer
|
12
|
+
extend SleepingKingStudios::Tools::Toolbox::Mixin
|
13
|
+
include RSpec::SleepingKingStudios::Deferred::Provider
|
14
|
+
|
15
|
+
# Class methods for registering deferred examples.
|
16
|
+
module ClassMethods
|
17
|
+
# @overload finclude_deferred(description, *arguments, **keywords, &block)
|
18
|
+
# Includes the deferred examples inside a focused example group.
|
19
|
+
#
|
20
|
+
# @param description [String] the name of the deferred examples.
|
21
|
+
# @param arguments [Array] arguments passed to the deferred examples.
|
22
|
+
# @param keywords [Hash] keywords passed to the deferred examples.
|
23
|
+
# @param block [Block] a block passed to the deferred examples.
|
24
|
+
def finclude_deferred(description, ...)
|
25
|
+
fdescribe '(focused)' do
|
26
|
+
include_deferred(description, ...)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# @overload fwrap_deferred(description, *arguments, **keywords, &block)
|
31
|
+
# Includes the deferred examples inside a focused example group.
|
32
|
+
#
|
33
|
+
# Unlike #include_deferred, a block parameter will be included in the
|
34
|
+
# created example group, not passed to the deferred examples. To wrap
|
35
|
+
# deferred examples that require a block, create the example group
|
36
|
+
# separately and call #include_deferred.
|
37
|
+
#
|
38
|
+
# @param description [String] the name of the deferred examples.
|
39
|
+
# @param arguments [Array] arguments passed to the deferred examples.
|
40
|
+
# @param keywords [Hash] keywords passed to the deferred examples.
|
41
|
+
# @param block [Block] additional examples to be evaluated inside the
|
42
|
+
# example group.
|
43
|
+
def fwrap_deferred(description, *args, **kwargs, &block)
|
44
|
+
fdescribe "(focused) #{description}" do
|
45
|
+
include_deferred(description, *args, **kwargs)
|
46
|
+
|
47
|
+
instance_exec(&block) if block_given?
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# @overload include_deferred(description, *arguments, **keywords, &block)
|
52
|
+
# Includes the deferred examples with the given definition.
|
53
|
+
#
|
54
|
+
# @param description [String] the name of the deferred examples.
|
55
|
+
# @param arguments [Array] arguments passed to the deferred examples.
|
56
|
+
# @param keywords [Hash] keywords passed to the deferred examples.
|
57
|
+
# @param block [Block] a block passed to the deferred examples.
|
58
|
+
def include_deferred(description, ...)
|
59
|
+
deferred = find_deferred_examples(description)
|
60
|
+
|
61
|
+
deferred =
|
62
|
+
if deferred.is_a?(Proc)
|
63
|
+
define_deferred_module(deferred, description, ...)
|
64
|
+
else
|
65
|
+
wrap_deferred_module(deferred)
|
66
|
+
end
|
67
|
+
|
68
|
+
deferred.parent_group = self
|
69
|
+
|
70
|
+
include deferred
|
71
|
+
end
|
72
|
+
|
73
|
+
# @overload wrap_deferred(description, *arguments, **keywords, &block)
|
74
|
+
# Includes the deferred examples inside an example group.
|
75
|
+
#
|
76
|
+
# Unlike #include_deferred, a block parameter will be included in the
|
77
|
+
# created example group, not passed to the deferred examples. To wrap
|
78
|
+
# deferred examples that require a block, create the example group
|
79
|
+
# separately and call #include_deferred.
|
80
|
+
#
|
81
|
+
# @param description [String] the name of the deferred examples.
|
82
|
+
# @param arguments [Array] arguments passed to the deferred examples.
|
83
|
+
# @param keywords [Hash] keywords passed to the deferred examples.
|
84
|
+
# @param block [Block] additional examples to be evaluated inside the
|
85
|
+
# example group.
|
86
|
+
def wrap_deferred(description, *args, **kwargs, &block)
|
87
|
+
describe description do
|
88
|
+
include_deferred(description, *args, **kwargs)
|
89
|
+
|
90
|
+
instance_exec(&block) if block_given?
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# @overload xinclude_deferred(description, *arguments, **keywords, &block)
|
95
|
+
# Includes the deferred examples inside a skipped example group.
|
96
|
+
#
|
97
|
+
# @param description [String] the name of the deferred examples.
|
98
|
+
# @param arguments [Array] arguments passed to the deferred examples.
|
99
|
+
# @param keywords [Hash] keywords passed to the deferred examples.
|
100
|
+
# @param block [Block] a block passed to the deferred examples.
|
101
|
+
def xinclude_deferred(description, ...)
|
102
|
+
xdescribe '(skipped)' do
|
103
|
+
include_deferred(description, ...)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# @overload xwrap_deferred(description, *arguments, **keywords, &block)
|
108
|
+
# Includes the deferred examples inside a skipped example group.
|
109
|
+
#
|
110
|
+
# Unlike #include_deferred, a block parameter will be included in the
|
111
|
+
# created example group, not passed to the deferred examples. To wrap
|
112
|
+
# deferred examples that require a block, create the example group
|
113
|
+
# separately and call #include_deferred.
|
114
|
+
#
|
115
|
+
# @param description [String] the name of the deferred examples.
|
116
|
+
# @param arguments [Array] arguments passed to the deferred examples.
|
117
|
+
# @param keywords [Hash] keywords passed to the deferred examples.
|
118
|
+
# @param block [Block] additional examples to be evaluated inside the
|
119
|
+
# example group.
|
120
|
+
def xwrap_deferred(description, *args, **kwargs, &block)
|
121
|
+
xdescribe "(skipped) #{description}" do
|
122
|
+
include_deferred(description, *args, **kwargs)
|
123
|
+
|
124
|
+
instance_exec(&block) if block_given?
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
private
|
129
|
+
|
130
|
+
def define_deferred_module(implementation, description, ...) # rubocop:disable Metrics/MethodLength
|
131
|
+
Module.new do
|
132
|
+
extend RSpec::SleepingKingStudios::Deferred::Examples::ClassMethods
|
133
|
+
include RSpec::SleepingKingStudios::Deferred::Examples
|
134
|
+
|
135
|
+
self.description = description
|
136
|
+
self.source_location = implementation.source_location
|
137
|
+
|
138
|
+
define_singleton_method(
|
139
|
+
:deferred_examples_implementation,
|
140
|
+
&implementation
|
141
|
+
)
|
142
|
+
|
143
|
+
deferred_examples_implementation(...)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
def wrap_deferred_module(examples)
|
148
|
+
Module.new do
|
149
|
+
extend RSpec::SleepingKingStudios::Deferred::Examples::ClassMethods
|
150
|
+
include RSpec::SleepingKingStudios::Deferred::Examples
|
151
|
+
include examples
|
152
|
+
|
153
|
+
self.description = examples.description
|
154
|
+
self.source_location = examples.source_location
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|