subroutine 0.10.0.beta → 0.10.0.beta2

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.
data/test/support/ops.rb CHANGED
@@ -1,11 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'subroutine/auth'
4
- require 'subroutine/association'
3
+ require "subroutine/auth"
4
+ require "subroutine/association_fields"
5
5
 
6
6
  ## Models ##
7
7
 
8
8
  class User
9
+
9
10
  include ::ActiveModel::Model
10
11
 
11
12
  attr_accessor :id
@@ -17,15 +18,19 @@ class User
17
18
  def self.find(id)
18
19
  new(id: id)
19
20
  end
21
+
20
22
  end
21
23
 
22
24
  class AdminUser < ::User
23
- validates :email_address, format: { with: /@admin\.com/, message: 'has gotta be @admin.com' }
25
+
26
+ validates :email_address, format: { with: /@admin\.com/, message: "has gotta be @admin.com" }
27
+
24
28
  end
25
29
 
26
30
  ## Ops ##
27
31
 
28
32
  class SignupOp < ::Subroutine::Op
33
+
29
34
  string :email, aka: :email_address
30
35
  string :password
31
36
 
@@ -63,43 +68,57 @@ class SignupOp < ::Subroutine::Op
63
68
  def user_class
64
69
  ::User
65
70
  end
71
+
66
72
  end
67
73
 
68
74
  class AdminSignupOp < ::SignupOp
69
- field :privileges, default: 'min'
75
+
76
+ field :privileges, default: "min"
70
77
 
71
78
  protected
72
79
 
73
80
  def user_class
74
81
  ::AdminUser
75
82
  end
83
+
76
84
  end
77
85
 
78
86
  class BusinessSignupOp < ::Subroutine::Op
87
+
79
88
  string :business_name
80
89
 
81
90
  inputs_from ::SignupOp
91
+
82
92
  end
83
93
 
84
94
  class DefaultsOp < ::Subroutine::Op
85
- field :foo, default: 'foo'
86
- field :bar, default: 'bar'
95
+
96
+ field :foo, default: "foo"
97
+ field :bar, default: "bar"
87
98
  field :baz, default: false
99
+
88
100
  end
89
101
 
90
102
  class ExceptFooBarOp < ::Subroutine::Op
91
- inputs_from ::DefaultsOp, except: [:foo, :bar]
103
+
104
+ inputs_from ::DefaultsOp, except: %i[foo bar]
105
+
92
106
  end
93
107
 
94
108
  class OnlyFooBarOp < ::Subroutine::Op
95
- inputs_from ::DefaultsOp, only: [:foo, :bar]
109
+
110
+ inputs_from ::DefaultsOp, only: %i[foo bar]
111
+
96
112
  end
97
113
 
98
114
  class InheritedDefaultsOp < ::DefaultsOp
99
- field :bar, default: 'barstool'
115
+
116
+ field :bar, default: "barstool", allow_overwrite: true
117
+
100
118
  end
101
119
 
102
120
  class TypeCastOp < ::Subroutine::Op
121
+
103
122
  integer :integer_input
104
123
  number :number_input
105
124
  decimal :decimal_input
@@ -110,39 +129,51 @@ class TypeCastOp < ::Subroutine::Op
110
129
  iso_date :iso_date_input
111
130
  iso_time :iso_time_input
112
131
  object :object_input
113
- array :array_input, default: 'foo'
132
+ array :array_input, default: "foo"
114
133
  array :type_array_input, of: :integer
115
134
  file :file_input
135
+
116
136
  end
117
137
 
118
138
  class OpWithAuth < ::Subroutine::Op
139
+
119
140
  include ::Subroutine::Auth
120
141
  def perform
121
142
  true
122
143
  end
144
+
123
145
  end
124
146
 
125
147
  class MissingAuthOp < OpWithAuth
126
148
  end
127
149
 
128
150
  class RequireUserOp < OpWithAuth
151
+
129
152
  require_user!
153
+
130
154
  end
131
155
 
132
156
  class RequireNoUserOp < OpWithAuth
157
+
133
158
  require_no_user!
159
+
134
160
  end
135
161
 
136
162
  class NoUserRequirementsOp < OpWithAuth
163
+
137
164
  no_user_requirements!
165
+
138
166
  end
139
167
 
140
168
  class DifferentUserClassOp < OpWithAuth
169
+
141
170
  self.user_class_name = "AdminUser"
142
171
  require_user!
172
+
143
173
  end
144
174
 
145
175
  class CustomAuthorizeOp < OpWithAuth
176
+
146
177
  require_user!
147
178
  authorize :authorize_user_is_correct
148
179
 
@@ -151,13 +182,17 @@ class CustomAuthorizeOp < OpWithAuth
151
182
  def authorize_user_is_correct
152
183
  unauthorized! unless current_user.email_address.to_s =~ /example\.com$/
153
184
  end
185
+
154
186
  end
155
187
 
156
188
  class PolicyOp < OpWithAuth
189
+
157
190
  class FakePolicy
191
+
158
192
  def user_can_access?
159
193
  false
160
194
  end
195
+
161
196
  end
162
197
 
163
198
  require_user!
@@ -166,13 +201,17 @@ class PolicyOp < OpWithAuth
166
201
  def policy
167
202
  @policy ||= FakePolicy.new
168
203
  end
204
+
169
205
  end
170
206
 
171
207
  class IfConditionalPolicyOp < OpWithAuth
208
+
172
209
  class FakePolicy
210
+
173
211
  def user_can_access?
174
212
  false
175
213
  end
214
+
176
215
  end
177
216
 
178
217
  require_user!
@@ -183,13 +222,17 @@ class IfConditionalPolicyOp < OpWithAuth
183
222
  def policy
184
223
  @policy ||= FakePolicy.new
185
224
  end
225
+
186
226
  end
187
227
 
188
228
  class UnlessConditionalPolicyOp < OpWithAuth
229
+
189
230
  class FakePolicy
231
+
190
232
  def user_can_access?
191
233
  false
192
234
  end
235
+
193
236
  end
194
237
 
195
238
  require_user!
@@ -200,95 +243,149 @@ class UnlessConditionalPolicyOp < OpWithAuth
200
243
  def policy
201
244
  @policy ||= FakePolicy.new
202
245
  end
246
+
203
247
  end
204
248
 
205
249
  class OpWithAssociation < ::Subroutine::Op
206
- include ::Subroutine::Association
250
+
251
+ include ::Subroutine::AssociationFields
252
+
207
253
  end
208
254
 
209
255
  class SimpleAssociationOp < ::OpWithAssociation
256
+
210
257
  association :user
258
+
211
259
  end
212
260
 
213
261
  class UnscopedSimpleAssociationOp < ::OpWithAssociation
214
- association :user, unscoped: true
262
+
263
+ association :user, unscoped: true, allow_overwrite: true
264
+
215
265
  end
216
266
 
217
267
  class PolymorphicAssociationOp < ::OpWithAssociation
268
+
218
269
  association :admin, polymorphic: true
270
+
219
271
  end
220
272
 
221
273
  class AssociationWithClassOp < ::OpWithAssociation
222
- association :admin, class_name: 'AdminUser'
274
+
275
+ association :admin, class_name: "AdminUser"
276
+
223
277
  end
224
278
 
225
279
  class InheritedSimpleAssociation < ::Subroutine::Op
280
+
226
281
  inputs_from SimpleAssociationOp
282
+
227
283
  end
228
284
 
229
285
  class InheritedUnscopedAssociation < ::Subroutine::Op
286
+
230
287
  inputs_from UnscopedSimpleAssociationOp
288
+
231
289
  end
232
290
 
233
291
  class InheritedPolymorphicAssociationOp < ::Subroutine::Op
292
+
234
293
  inputs_from PolymorphicAssociationOp
294
+
235
295
  end
236
296
 
237
297
  class FalsePerformOp < ::Subroutine::Op
298
+
238
299
  def perform
239
300
  false
240
301
  end
302
+
241
303
  end
242
304
 
243
305
  class MissingOutputOp < ::Subroutine::Op
306
+
244
307
  def perform
245
- output :foo, 'bar'
308
+ output :foo, "bar"
246
309
  end
310
+
247
311
  end
248
312
 
249
313
  class MissingOutputSetOp < ::Subroutine::Op
314
+
250
315
  outputs :foo
251
316
  def perform
252
317
  true
253
318
  end
319
+
254
320
  end
255
321
 
256
322
  class OutputNotRequiredOp < ::Subroutine::Op
323
+
257
324
  outputs :foo, required: false
258
325
  def perform
259
326
  true
260
327
  end
328
+
261
329
  end
262
330
 
263
331
  class NoOutputNoSuccessOp < ::Subroutine::Op
332
+
264
333
  outputs :foo
265
334
  def perform
266
- errors.add(:foo, 'bar')
335
+ errors.add(:foo, "bar")
267
336
  end
337
+
268
338
  end
269
339
 
270
340
  class ErrorTraceOp < ::Subroutine::Op
341
+
271
342
  class SomeObject
343
+
272
344
  include ::ActiveModel::Model
273
345
  include ::ActiveModel::Validations::Callbacks
274
346
 
275
347
  def foo
276
- errors.add(:base, 'Failure of things')
348
+ errors.add(:base, "Failure of things")
277
349
  raise Subroutine::Failure, self
278
350
  end
279
351
 
280
352
  def bar
281
353
  foo
282
354
  end
355
+
283
356
  end
284
357
 
285
358
  class SubOp < ::Subroutine::Op
359
+
286
360
  def perform
287
361
  SomeObject.new.bar
288
362
  end
363
+
289
364
  end
290
365
 
291
366
  def perform
292
367
  SubOp.submit!
293
368
  end
369
+
370
+ end
371
+
372
+ class CustomFailureClassOp < ::Subroutine::Op
373
+
374
+ class Failure < StandardError
375
+
376
+ attr_reader :record
377
+ def initialize(record)
378
+ @record = record
379
+ errors = @record.errors.full_messages.join(", ")
380
+ super(errors)
381
+ end
382
+
383
+ end
384
+
385
+ failure_class Failure
386
+
387
+ def perform
388
+ errors.add(:base, "Will never work")
389
+ end
390
+
294
391
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: subroutine
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.0.beta
4
+ version: 0.10.0.beta2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Nelson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-11-14 00:00:00.000000000 Z
11
+ date: 2019-11-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -144,14 +144,20 @@ files:
144
144
  - gemfiles/am52.gemfile
145
145
  - gemfiles/am60.gemfile
146
146
  - lib/subroutine.rb
147
- - lib/subroutine/association.rb
147
+ - lib/subroutine/association_fields.rb
148
+ - lib/subroutine/association_fields/component_configuration.rb
149
+ - lib/subroutine/association_fields/configuration.rb
148
150
  - lib/subroutine/auth.rb
149
151
  - lib/subroutine/failure.rb
150
152
  - lib/subroutine/fields.rb
153
+ - lib/subroutine/fields/configuration.rb
154
+ - lib/subroutine/fields/mass_assignment_error.rb
151
155
  - lib/subroutine/op.rb
152
- - lib/subroutine/output_not_set_error.rb
156
+ - lib/subroutine/outputs.rb
157
+ - lib/subroutine/outputs/configuration.rb
158
+ - lib/subroutine/outputs/output_not_set_error.rb
159
+ - lib/subroutine/outputs/unknown_output_error.rb
153
160
  - lib/subroutine/type_caster.rb
154
- - lib/subroutine/unknown_output_error.rb
155
161
  - lib/subroutine/version.rb
156
162
  - subroutine.gemspec
157
163
  - test/subroutine/association_test.rb
@@ -180,8 +186,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
180
186
  - !ruby/object:Gem::Version
181
187
  version: 1.3.1
182
188
  requirements: []
183
- rubyforge_project:
184
- rubygems_version: 2.6.14.4
189
+ rubygems_version: 3.0.6
185
190
  signing_key:
186
191
  specification_version: 4
187
192
  summary: Feature-driven operation objects.
@@ -1,131 +0,0 @@
1
- # frozen_string_literal: true
2
- require "active_support/concern"
3
-
4
- module Subroutine
5
- module Association
6
- extend ActiveSupport::Concern
7
-
8
- included do
9
- class << self
10
- alias_method :field_without_associations, :field
11
- alias_method :field, :field_with_associations
12
- end
13
-
14
- alias_method :setup_fields_without_association, :setup_fields
15
- alias_method :setup_fields, :setup_fields_with_association
16
- end
17
-
18
- module ClassMethods
19
- def field_with_associations(*args)
20
- opts = args.extract_options!
21
- if opts[:association]
22
- args.each do |arg|
23
- association(arg, opts)
24
- end
25
- else
26
- field_without_associations(*args, opts)
27
- end
28
- end
29
-
30
- # association :user
31
- # - user_id
32
- # - user_type => "User"
33
-
34
- # association :user, polymorphic: true
35
- # - user_id
36
- # - user_type
37
- # - user => polymorphic_lookup(user_type, user_id)
38
-
39
- # association :inbound_user_request, as: :request
40
- # - inbound_user_request_id
41
- # - inbound_user_request_type => "InboundUserRequest"
42
- # - request => polymorphic_lookup(inbound_user_request_type, inbound_user_request_id)
43
-
44
- # association :inbound_user_request, foreign_key: :request_id
45
- # - request_id
46
- # - request_type
47
- # - inbound_user_request => polymorphic_lookup(request_type, request_id)
48
-
49
- # Other options:
50
- # - unscoped => set true if the record should be looked up via Type.unscoped
51
-
52
- def association(field, options = {})
53
- if options[:as] && options[:foreign_key]
54
- raise ArgumentError, ':as and :foreign_key options should be provided together to an association invocation'
55
- end
56
-
57
- class_name = options[:class_name]
58
-
59
- poly = options[:polymorphic] || !class_name.nil?
60
- as = options[:as] || field
61
- unscoped = !!options[:unscoped]
62
-
63
- klass = class_name.to_s if class_name
64
-
65
- foreign_key_method = (options[:foreign_key] || "#{field}_id").to_s
66
- foreign_type_method = foreign_key_method.gsub(/_id$/, '_type')
67
-
68
- if poly
69
- string foreign_type_method
70
- else
71
- class_eval <<-EV, __FILE__, __LINE__ + 1
72
- def #{foreign_type_method}
73
- #{as.to_s.camelize.inspect}
74
- end
75
- EV
76
- end
77
-
78
- integer foreign_key_method
79
-
80
- field_without_associations as, options.merge(association: true, field_writer: false, field_reader: false)
81
-
82
- class_eval <<-EV, __FILE__, __LINE__ + 1
83
- try(:silence_redefinition_of_method, :#{as})
84
- def #{as}
85
- return @#{as} if defined?(@#{as})
86
- @#{as} = polymorphic_instance(#{klass.nil? ? foreign_type_method : klass.to_s}, #{foreign_key_method}, #{unscoped.inspect})
87
- end
88
-
89
- try(:silence_redefinition_of_method, :#{as}=)
90
- def #{as}=(r)
91
- @#{as} = r
92
- #{poly || klass ? "send('#{foreign_type_method}=', r.nil? ? nil : #{klass.nil? ? 'r.class.name' : klass.to_s.inspect})" : ''}
93
- send('#{foreign_key_method}=', r.nil? ? nil : r.id)
94
- r
95
- end
96
-
97
- try(:silence_redefinition_of_method, :#{as}_field_provided?)
98
- def #{as}_field_provided?
99
- field_provided?('#{foreign_key_method}')#{poly ? "&& field_provided?('#{foreign_type_method}')" : ""}
100
- end
101
- EV
102
- end
103
- end
104
-
105
- def setup_fields_with_association(*args)
106
- setup_fields_without_association(*args)
107
-
108
- _fields.each_pair do |field, config|
109
- next unless config[:association]
110
- next if config[:mass_assignable] == false
111
- next unless @original_params.key?(field)
112
-
113
- send("#{field}=", @original_params[field]) # this gets the _id and _type into the params hash
114
- end
115
- end
116
-
117
- def polymorphic_instance(_type, _id, _unscoped = false)
118
- return nil unless _type && _id
119
-
120
- klass = _type
121
- klass = klass.classify.constantize if klass.is_a?(String)
122
-
123
- return nil unless klass
124
-
125
- scope = klass.all
126
- scope = scope.unscoped if _unscoped
127
-
128
- scope.find(_id)
129
- end
130
- end
131
- end
@@ -1,9 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Subroutine
4
- class OutputNotSetError < StandardError
5
- def initialize(name)
6
- super("Expected output '#{name}' to be set upon completion of perform but was not.")
7
- end
8
- end
9
- end
@@ -1,9 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Subroutine
4
- class UnknownOutputError < StandardError
5
- def initialize(name)
6
- super("Unknown output '#{name}'")
7
- end
8
- end
9
- end