interaktor 0.1.4 → 0.1.5
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/interaktor.gemspec +1 -1
- data/lib/interaktor.rb +55 -10
- data/spec/integration_spec.rb +4 -0
- data/spec/support/lint.rb +8 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 99cf1e62638c0d275243c18799d225ec5f6e44eb6e75ac0cb12418775f8d2ebe
|
4
|
+
data.tar.gz: 8e53e5c94af31544e37222810b123bf7817db54a3667f94e01a10c64d9536ba3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7fcd8dfeabdbacd828471bac5d80e57582e98f02c9ecf31188c2300aa24e19e2dde04453aeb82b439b8f048a4c10bb00147f2b7e9927d028aa4adbcfa22ebcf0
|
7
|
+
data.tar.gz: 1ddb2a5b49de3269b02b1c1264991ae126385ed2c22fd7f9fb953361820d9f373620fee434be064310e3aaaabe394bf3cab2d2085a9c37ac43619b8f04f92313
|
data/interaktor.gemspec
CHANGED
data/lib/interaktor.rb
CHANGED
@@ -33,6 +33,13 @@ module Interaktor
|
|
33
33
|
@optional_attributes ||= []
|
34
34
|
end
|
35
35
|
|
36
|
+
# A list of optional attributes and their default values.
|
37
|
+
#
|
38
|
+
# @return [Array<Symbol>]
|
39
|
+
def optional_defaults
|
40
|
+
@optional_defaults ||= {}
|
41
|
+
end
|
42
|
+
|
36
43
|
# The list of attributes which are required to be passed in when calling
|
37
44
|
# `#fail!` from within the interaktor.
|
38
45
|
#
|
@@ -52,29 +59,39 @@ module Interaktor
|
|
52
59
|
# A DSL method for documenting required interaktor attributes.
|
53
60
|
#
|
54
61
|
# @param attributes [Symbol, Array<Symbol>] the list of attribute names
|
62
|
+
# @param options [Hash]
|
55
63
|
#
|
56
64
|
# @return [void]
|
57
|
-
def required(*attributes)
|
65
|
+
def required(*attributes, **options)
|
58
66
|
required_attributes.concat attributes
|
59
67
|
|
60
68
|
attributes.each do |attribute|
|
69
|
+
# Define getter
|
61
70
|
define_method(attribute) { @context.send(attribute) }
|
71
|
+
|
72
|
+
# Define setter
|
62
73
|
define_method("#{attribute}=".to_sym) do |value|
|
63
74
|
@context.send("#{attribute}=".to_sym, value)
|
64
75
|
end
|
76
|
+
|
77
|
+
raise "Unknown option(s): #{options.keys.join(", ")}" if options.any?
|
65
78
|
end
|
66
79
|
end
|
67
80
|
|
68
81
|
# A DSL method for documenting optional interaktor attributes.
|
69
82
|
#
|
70
83
|
# @param attributes [Symbol, Array<Symbol>] the list of attribute names
|
84
|
+
# @param options [Hash]
|
71
85
|
#
|
72
86
|
# @return [void]
|
73
|
-
def optional(*attributes)
|
87
|
+
def optional(*attributes, **options)
|
74
88
|
optional_attributes.concat attributes
|
75
89
|
|
76
90
|
attributes.each do |attribute|
|
91
|
+
# Define getter
|
77
92
|
define_method(attribute) { @context.send(attribute) }
|
93
|
+
|
94
|
+
# Define setter
|
78
95
|
define_method("#{attribute}=".to_sym) do |value|
|
79
96
|
unless @context.to_h.key?(attribute)
|
80
97
|
raise <<~ERROR
|
@@ -86,6 +103,12 @@ module Interaktor
|
|
86
103
|
|
87
104
|
@context.send("#{attribute}=".to_sym, value)
|
88
105
|
end
|
106
|
+
|
107
|
+
# Handle options
|
108
|
+
optional_defaults[attribute] = options[:default] if options[:default]
|
109
|
+
options.delete(:default)
|
110
|
+
|
111
|
+
raise "Unknown option(s): #{options.keys.join(", ")}" if options.any?
|
89
112
|
end
|
90
113
|
end
|
91
114
|
|
@@ -115,11 +138,10 @@ module Interaktor
|
|
115
138
|
#
|
116
139
|
# @return [Interaktor::Context] the context, following interaktor execution
|
117
140
|
def call(context = {})
|
141
|
+
apply_default_optional_attributes(context)
|
118
142
|
verify_attribute_presence(context)
|
119
143
|
|
120
|
-
|
121
|
-
new(context).tap(&:run).instance_variable_get(:@context)
|
122
|
-
end
|
144
|
+
new(context).tap(&:run).instance_variable_get(:@context)
|
123
145
|
end
|
124
146
|
|
125
147
|
# Invoke an Interaktor. This method behaves identically to `#call`, with
|
@@ -133,18 +155,18 @@ module Interaktor
|
|
133
155
|
#
|
134
156
|
# @return [Interaktor::Context] the context, following interaktor execution
|
135
157
|
def call!(context = {})
|
158
|
+
apply_default_optional_attributes(context)
|
136
159
|
verify_attribute_presence(context)
|
137
160
|
|
138
|
-
|
139
|
-
new(context).tap(&:run!).instance_variable_get(:@context)
|
140
|
-
end
|
161
|
+
new(context).tap(&:run!).instance_variable_get(:@context)
|
141
162
|
end
|
142
163
|
|
143
164
|
private
|
144
165
|
|
145
166
|
# Check the provided context against the attributes defined with the DSL
|
146
167
|
# methods, and determine if there are any attributes which are required and
|
147
|
-
# have not been provided
|
168
|
+
# have not been provided, or if there are any attributes which have been
|
169
|
+
# provided but are not listed as either required or optional.
|
148
170
|
#
|
149
171
|
# @param context [Interaktor::Context] the context to check
|
150
172
|
#
|
@@ -157,6 +179,26 @@ module Interaktor
|
|
157
179
|
Required attribute(s) were not provided when initializing #{name} interaktor:
|
158
180
|
#{missing_attrs.join("\n ")}
|
159
181
|
ERROR
|
182
|
+
|
183
|
+
allowed_attrs = required_attributes + optional_attributes
|
184
|
+
extra_attrs = context.to_h.keys.reject { |attr| allowed_attrs.include?(attr) }
|
185
|
+
|
186
|
+
raise <<~ERROR if extra_attrs.any?
|
187
|
+
One or more provided attributes were not recognized when initializing #{name} interaktor:
|
188
|
+
#{extra_attrs.join("\n ")}
|
189
|
+
ERROR
|
190
|
+
end
|
191
|
+
|
192
|
+
# Given the list of optional default attribute values defined by the class,
|
193
|
+
# assign those default values to the context if they were omitted.
|
194
|
+
#
|
195
|
+
# @param context [Interaktor::Context]
|
196
|
+
#
|
197
|
+
# @return [void]
|
198
|
+
def apply_default_optional_attributes(context)
|
199
|
+
optional_defaults.each do |attribute, default|
|
200
|
+
context[attribute] ||= default
|
201
|
+
end
|
160
202
|
end
|
161
203
|
end
|
162
204
|
|
@@ -238,7 +280,10 @@ module Interaktor
|
|
238
280
|
# @return [void]
|
239
281
|
def run!
|
240
282
|
with_hooks do
|
241
|
-
|
283
|
+
catch(:early_return) do
|
284
|
+
call
|
285
|
+
end
|
286
|
+
|
242
287
|
@context.called!(self)
|
243
288
|
end
|
244
289
|
rescue StandardError
|
data/spec/integration_spec.rb
CHANGED
@@ -8,6 +8,8 @@ describe "Integration" do
|
|
8
8
|
interaktor = Class.new.send(:include, Interaktor)
|
9
9
|
interaktor.class_eval(&block) if block
|
10
10
|
interaktor.class_eval do
|
11
|
+
optional :steps
|
12
|
+
|
11
13
|
def unexpected_error!
|
12
14
|
raise "foo"
|
13
15
|
end
|
@@ -20,6 +22,8 @@ describe "Integration" do
|
|
20
22
|
organizer.organize(options[:organize]) if options[:organize]
|
21
23
|
organizer.class_eval(&block) if block
|
22
24
|
organizer.class_eval do
|
25
|
+
optional :steps
|
26
|
+
|
23
27
|
def unexpected_error!
|
24
28
|
raise "foo"
|
25
29
|
end
|
data/spec/support/lint.rb
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
shared_examples "lint" do
|
2
|
-
let(:interaktor)
|
2
|
+
let(:interaktor) do
|
3
|
+
klass = Class.new.include(described_class)
|
4
|
+
klass.class_eval do
|
5
|
+
optional :foo
|
6
|
+
end
|
7
|
+
|
8
|
+
klass
|
9
|
+
end
|
3
10
|
|
4
11
|
describe ".call" do
|
5
12
|
let(:context) { instance_double(Interaktor::Context) }
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: interaktor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Taylor Thurlow
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-09-
|
11
|
+
date: 2020-09-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: zeitwerk
|