subroutine 0.9.0 → 0.10.0.beta
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/subroutine/association.rb +17 -20
- data/lib/subroutine/auth.rb +2 -2
- data/lib/subroutine/fields.rb +58 -31
- data/lib/subroutine/op.rb +5 -25
- data/lib/subroutine/version.rb +2 -2
- data/subroutine.gemspec +1 -0
- data/test/subroutine/base_test.rb +34 -34
- data/test/subroutine/fields_test.rb +28 -11
- data/test/support/ops.rb +0 -4
- data/test/test_helper.rb +2 -0
- metadata +18 -5
- data/lib/subroutine/filtered_errors.rb +0 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0dbba6e4428e540eddcfb16df3079f0d9c2db2d2
|
4
|
+
data.tar.gz: bd752b132b834c5c35e07fa2434f8d381da3c385
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 439bce703b933575f763ac2aa4428e65babc620275a5ca45cae8ed255592428966867281d20f6093dea7fd2dde8fbc764d82f57dd5bc81e5e21d2562e5f94db0
|
7
|
+
data.tar.gz: 8e95b71122f2dcabf504c5c0f7674f12a79923175434cf65300161cc7251123b11a0f9a797889b4bd71b4a2d823921e3d6026f43e9200d8ffbb1d75f17a1a3a9
|
@@ -1,16 +1,18 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
require "active_support/concern"
|
2
3
|
|
3
4
|
module Subroutine
|
4
5
|
module Association
|
5
|
-
|
6
|
-
|
7
|
-
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
class << self
|
8
10
|
alias_method :field_without_associations, :field
|
9
11
|
alias_method :field, :field_with_associations
|
10
12
|
end
|
11
13
|
|
12
|
-
|
13
|
-
|
14
|
+
alias_method :setup_fields_without_association, :setup_fields
|
15
|
+
alias_method :setup_fields, :setup_fields_with_association
|
14
16
|
end
|
15
17
|
|
16
18
|
module ClassMethods
|
@@ -75,34 +77,28 @@ module Subroutine
|
|
75
77
|
|
76
78
|
integer foreign_key_method
|
77
79
|
|
78
|
-
field_without_associations as, options.merge(association: true)
|
80
|
+
field_without_associations as, options.merge(association: true, field_writer: false, field_reader: false)
|
79
81
|
|
80
82
|
class_eval <<-EV, __FILE__, __LINE__ + 1
|
81
|
-
|
83
|
+
try(:silence_redefinition_of_method, :#{as})
|
84
|
+
def #{as}
|
82
85
|
return @#{as} if defined?(@#{as})
|
83
|
-
@#{as} =
|
84
|
-
#{as}_without_association ||
|
85
|
-
polymorphic_instance(#{klass.nil? ? foreign_type_method : klass.to_s}, #{foreign_key_method}, #{unscoped.inspect})
|
86
|
-
end
|
86
|
+
@#{as} = polymorphic_instance(#{klass.nil? ? foreign_type_method : klass.to_s}, #{foreign_key_method}, #{unscoped.inspect})
|
87
87
|
end
|
88
88
|
|
89
|
-
|
89
|
+
try(:silence_redefinition_of_method, :#{as}=)
|
90
|
+
def #{as}=(r)
|
90
91
|
@#{as} = r
|
91
|
-
#{poly || klass ? "
|
92
|
-
|
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)
|
93
94
|
r
|
94
95
|
end
|
95
96
|
|
97
|
+
try(:silence_redefinition_of_method, :#{as}_field_provided?)
|
96
98
|
def #{as}_field_provided?
|
97
99
|
field_provided?('#{foreign_key_method}')#{poly ? "&& field_provided?('#{foreign_type_method}')" : ""}
|
98
100
|
end
|
99
101
|
EV
|
100
|
-
|
101
|
-
alias_method :"#{as}_without_association", :"#{as}"
|
102
|
-
alias_method :"#{as}", :"#{as}_with_association"
|
103
|
-
|
104
|
-
alias_method :"#{as}_without_association=", :"#{as}="
|
105
|
-
alias_method :"#{as}=", :"#{as}_with_association="
|
106
102
|
end
|
107
103
|
end
|
108
104
|
|
@@ -111,6 +107,7 @@ module Subroutine
|
|
111
107
|
|
112
108
|
_fields.each_pair do |field, config|
|
113
109
|
next unless config[:association]
|
110
|
+
next if config[:mass_assignable] == false
|
114
111
|
next unless @original_params.key?(field)
|
115
112
|
|
116
113
|
send("#{field}=", @original_params[field]) # this gets the _id and _type into the params hash
|
data/lib/subroutine/auth.rb
CHANGED
@@ -98,10 +98,10 @@ module Subroutine
|
|
98
98
|
end
|
99
99
|
end
|
100
100
|
|
101
|
-
def initialize(*args)
|
101
|
+
def initialize(*args, &block)
|
102
102
|
raise Subroutine::Auth::AuthorizationNotDeclaredError unless self.class.authorization_declared
|
103
103
|
|
104
|
-
super(args.extract_options
|
104
|
+
super(args.extract_options!, &block)
|
105
105
|
@skip_auth_checks = false
|
106
106
|
@current_user = args.shift
|
107
107
|
|
data/lib/subroutine/fields.rb
CHANGED
@@ -72,81 +72,108 @@ module Subroutine
|
|
72
72
|
|
73
73
|
protected
|
74
74
|
|
75
|
-
def _field(field_name,
|
75
|
+
def _field(field_name, field_writer: true, field_reader: true, **options)
|
76
76
|
self._fields = _fields.merge(field_name.to_sym => options)
|
77
77
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
78
|
+
if field_writer
|
79
|
+
class_eval <<-EV, __FILE__, __LINE__ + 1
|
80
|
+
try(:silence_redefinition_of_method, :#{field_name}=)
|
81
|
+
def #{field_name}=(v)
|
82
|
+
config = #{field_name}_config
|
83
|
+
@fields_provided["#{field_name}"] = true
|
84
|
+
@params["#{field_name}"] = attempt_cast(v, config) do |e|
|
85
|
+
"Error during assignment of field `#{field_name}`: \#{e}"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
EV
|
89
|
+
end
|
85
90
|
|
86
|
-
|
87
|
-
|
88
|
-
|
91
|
+
if field_reader
|
92
|
+
class_eval <<-EV, __FILE__, __LINE__ + 1
|
93
|
+
try(:silence_redefinition_of_method, :#{field_name})
|
94
|
+
def #{field_name}
|
95
|
+
@params["#{field_name}"]
|
96
|
+
end
|
97
|
+
EV
|
98
|
+
end
|
89
99
|
|
100
|
+
class_eval <<-EV, __FILE__, __LINE__ + 1
|
101
|
+
try(:silence_redefinition_of_method, :#{field_name}_config)
|
90
102
|
def #{field_name}_config
|
91
103
|
_fields[:#{field_name}]
|
92
104
|
end
|
93
|
-
|
94
105
|
EV
|
95
106
|
end
|
96
107
|
end
|
97
108
|
|
98
109
|
def setup_fields(inputs = {})
|
99
110
|
@original_params = inputs.with_indifferent_access
|
100
|
-
@
|
101
|
-
@
|
111
|
+
@defaults = build_defaults
|
112
|
+
@fields_provided = {}.with_indifferent_access
|
113
|
+
@params = build_params(@original_params, @defaults)
|
102
114
|
end
|
103
115
|
|
104
116
|
# check if a specific field was provided
|
105
117
|
def field_provided?(key)
|
106
118
|
return send(:"#{key}_field_provided?") if respond_to?(:"#{key}_field_provided?", true)
|
107
119
|
|
108
|
-
|
120
|
+
!!@fields_provided[key]
|
109
121
|
end
|
110
122
|
|
111
123
|
# if you want to use strong parameters or something in your form object you can do so here.
|
112
124
|
# by default we just slice the inputs to the defined fields
|
113
|
-
def
|
125
|
+
def build_params(inputs, defaults)
|
114
126
|
out = {}.with_indifferent_access
|
127
|
+
|
115
128
|
_fields.each_pair do |field, config|
|
116
|
-
next unless inputs.key?(field)
|
117
129
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
130
|
+
if config[:mass_assignable] == false && inputs.key?(field)
|
131
|
+
raise ArgumentError, "`#{field}` is not mass assignable"
|
132
|
+
end
|
133
|
+
|
134
|
+
if inputs.key?(field)
|
135
|
+
@fields_provided[field] = true
|
136
|
+
out[field] = attempt_cast(inputs[field], config) do |e|
|
137
|
+
"Error for field `#{field}`: #{e}"
|
138
|
+
end
|
139
|
+
elsif defaults.key?(field)
|
140
|
+
out[field] = defaults[field]
|
141
|
+
else
|
142
|
+
next
|
122
143
|
end
|
123
144
|
end
|
124
145
|
|
125
146
|
out
|
126
147
|
end
|
127
148
|
|
128
|
-
def
|
129
|
-
@defaults.
|
130
|
-
end
|
131
|
-
|
132
|
-
def sanitize_defaults
|
133
|
-
defaults = {}.with_indifferent_access
|
149
|
+
def build_defaults
|
150
|
+
@defaults = {}.with_indifferent_access
|
134
151
|
|
135
152
|
_fields.each_pair do |field, config|
|
136
|
-
next
|
153
|
+
next unless config.key?(:default)
|
137
154
|
|
138
155
|
deflt = config[:default]
|
139
156
|
if deflt.respond_to?(:call)
|
140
157
|
deflt = deflt.call
|
141
|
-
elsif deflt.duplicable? # from active_support
|
158
|
+
elsif deflt.try(:duplicable?) # from active_support
|
142
159
|
# Some classes of default values need to be duplicated, or the instance field value will end up referencing
|
143
160
|
# the class global default value, and potentially modify it.
|
144
161
|
deflt = deflt.deep_dup # from active_support
|
145
162
|
end
|
146
|
-
|
163
|
+
|
164
|
+
@defaults[field.to_s] = attempt_cast(deflt, config) do |e|
|
165
|
+
"Error for default `#{field}`: #{e}"
|
166
|
+
end
|
147
167
|
end
|
148
168
|
|
149
|
-
defaults
|
169
|
+
@defaults
|
170
|
+
end
|
171
|
+
|
172
|
+
def attempt_cast(value, config)
|
173
|
+
::Subroutine::TypeCaster.cast(value, config)
|
174
|
+
rescue ::Subroutine::TypeCaster::TypeCastError => e
|
175
|
+
message = block_given? ? yield(e) : e.to_s
|
176
|
+
raise ::Subroutine::TypeCaster::TypeCastError, message, e.backtrace
|
150
177
|
end
|
151
178
|
|
152
179
|
end
|
data/lib/subroutine/op.rb
CHANGED
@@ -4,16 +4,15 @@ require "active_model"
|
|
4
4
|
|
5
5
|
require "subroutine/fields"
|
6
6
|
require "subroutine/failure"
|
7
|
-
require "subroutine/filtered_errors"
|
8
7
|
require "subroutine/output_not_set_error"
|
9
8
|
require "subroutine/unknown_output_error"
|
10
9
|
|
11
10
|
module Subroutine
|
12
11
|
class Op
|
13
12
|
|
14
|
-
include ::
|
15
|
-
include ::ActiveModel::Model
|
13
|
+
include ::ActiveModel::Validations
|
16
14
|
include ::ActiveModel::Validations::Callbacks
|
15
|
+
include ::Subroutine::Fields
|
17
16
|
|
18
17
|
DEFAULT_OUTPUT_OPTIONS = {
|
19
18
|
required: true,
|
@@ -34,14 +33,8 @@ module Subroutine
|
|
34
33
|
end
|
35
34
|
end
|
36
35
|
|
37
|
-
def ignore_error(*field_names)
|
38
|
-
field_names.each do |f|
|
39
|
-
_ignore_errors(f)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
alias ignore_errors ignore_error
|
43
|
-
|
44
36
|
def submit!(*args)
|
37
|
+
raise ArgumentError, "Blocks cannot be provided to `submit!`" if block_given?
|
45
38
|
op = new(*args)
|
46
39
|
op.submit!
|
47
40
|
|
@@ -49,6 +42,7 @@ module Subroutine
|
|
49
42
|
end
|
50
43
|
|
51
44
|
def submit(*args)
|
45
|
+
raise ArgumentError, "Blocks cannot be provided to `submit`." if block_given?
|
52
46
|
op = new(*args)
|
53
47
|
op.submit
|
54
48
|
op
|
@@ -65,15 +59,9 @@ module Subroutine
|
|
65
59
|
end
|
66
60
|
end
|
67
61
|
|
68
|
-
_ignore_errors(field_name) if options[:ignore_errors]
|
69
|
-
|
70
62
|
result
|
71
63
|
end
|
72
64
|
|
73
|
-
def _ignore_errors(field_name)
|
74
|
-
self._error_ignores = _error_ignores.merge(field_name.to_sym => true)
|
75
|
-
end
|
76
|
-
|
77
65
|
end
|
78
66
|
|
79
67
|
class_attribute :_outputs
|
@@ -82,16 +70,10 @@ module Subroutine
|
|
82
70
|
class_attribute :_error_map
|
83
71
|
self._error_map = {}
|
84
72
|
|
85
|
-
class_attribute :_error_ignores
|
86
|
-
self._error_ignores = {}
|
87
|
-
|
88
73
|
def initialize(inputs = {})
|
89
74
|
setup_fields(inputs)
|
90
75
|
@outputs = {}
|
91
|
-
|
92
|
-
|
93
|
-
def errors
|
94
|
-
@filtered_errors ||= Subroutine::FilteredErrors.new(super)
|
76
|
+
yield self if block_given?
|
95
77
|
end
|
96
78
|
|
97
79
|
def output(name, value)
|
@@ -175,8 +157,6 @@ module Subroutine
|
|
175
157
|
error_object = error_object.errors if error_object.respond_to?(:errors)
|
176
158
|
|
177
159
|
error_object.each do |k, v|
|
178
|
-
next if _error_ignores[k.to_sym]
|
179
|
-
|
180
160
|
if respond_to?(k)
|
181
161
|
errors.add(k, v)
|
182
162
|
elsif _error_map[k.to_sym]
|
data/lib/subroutine/version.rb
CHANGED
data/subroutine.gemspec
CHANGED
@@ -151,33 +151,16 @@ module Subroutine
|
|
151
151
|
assert_equal 'foo@bar.com', op.created_user.email_address
|
152
152
|
end
|
153
153
|
|
154
|
-
def test_it_ignores_specific_errors
|
155
|
-
op = ::WhateverSignupOp.submit
|
156
|
-
assert_equal [], op.errors[:whatever]
|
157
|
-
end
|
158
|
-
|
159
|
-
def test_it_does_not_inherit_ignored_errors
|
160
|
-
op = ::WhateverSignupOp.new
|
161
|
-
other = ::SignupOp.new
|
162
|
-
other.errors.add(:whatever, 'fail')
|
163
|
-
op.send(:inherit_errors, other)
|
164
|
-
assert_equal [], op.errors[:whatever]
|
165
|
-
end
|
166
|
-
|
167
154
|
def test_it_sets_the_params_and_defaults_immediately
|
168
155
|
op = ::AdminSignupOp.new(email: 'foo')
|
169
156
|
assert_equal({
|
170
|
-
'email' => 'foo'
|
157
|
+
'email' => 'foo',
|
158
|
+
'privileges' => 'min',
|
171
159
|
}, op.params)
|
172
160
|
|
173
161
|
assert_equal({
|
174
162
|
'privileges' => 'min'
|
175
163
|
}, op.defaults)
|
176
|
-
|
177
|
-
assert_equal({
|
178
|
-
'email' => 'foo',
|
179
|
-
'privileges' => 'min'
|
180
|
-
}, op.params_with_defaults)
|
181
164
|
end
|
182
165
|
|
183
166
|
def test_it_allows_defaults_to_be_overridden
|
@@ -188,14 +171,7 @@ module Subroutine
|
|
188
171
|
'privileges' => nil
|
189
172
|
}, op.params)
|
190
173
|
|
191
|
-
assert_equal({
|
192
|
-
'privileges' => 'min'
|
193
|
-
}, op.defaults)
|
194
|
-
|
195
|
-
assert_equal({
|
196
|
-
'email' => 'foo',
|
197
|
-
'privileges' => nil
|
198
|
-
}, op.params_with_defaults)
|
174
|
+
assert_equal({"privileges" => "min"}, op.defaults)
|
199
175
|
end
|
200
176
|
|
201
177
|
def test_it_overriding_default_does_not_alter_default
|
@@ -212,11 +188,6 @@ module Subroutine
|
|
212
188
|
assert_equal({
|
213
189
|
'privileges' => 'min'
|
214
190
|
}, op.defaults)
|
215
|
-
|
216
|
-
assert_equal({
|
217
|
-
'email' => 'foo',
|
218
|
-
'privileges' => nil
|
219
|
-
}, op.params_with_defaults)
|
220
191
|
end
|
221
192
|
|
222
193
|
def test_it_overrides_defaults_with_nils
|
@@ -229,10 +200,10 @@ module Subroutine
|
|
229
200
|
|
230
201
|
def test_it_casts_params_on_the_way_in
|
231
202
|
op = ::TypeCastOp.new(integer_input: '25')
|
232
|
-
assert_equal(25, op.
|
203
|
+
assert_equal(25, op.params['integer_input'])
|
233
204
|
|
234
205
|
op.decimal_input = '25.3'
|
235
|
-
assert_equal(BigDecimal('25.3'), op.
|
206
|
+
assert_equal(BigDecimal('25.3'), op.params['decimal_input'])
|
236
207
|
end
|
237
208
|
|
238
209
|
def test_it_allow_retrival_of_outputs
|
@@ -278,5 +249,34 @@ module Subroutine
|
|
278
249
|
refute_nil found, 'Expected backtrace to include original caller of foo'
|
279
250
|
end
|
280
251
|
end
|
252
|
+
|
253
|
+
def test_a_block_is_accepted_on_instantiation
|
254
|
+
op = ::SignupOp.new do |o|
|
255
|
+
o.email = "foo@bar.com"
|
256
|
+
o.password = "password123!"
|
257
|
+
end
|
258
|
+
|
259
|
+
assert_equal "foo@bar.com", op.email
|
260
|
+
assert_equal "password123!", op.password
|
261
|
+
|
262
|
+
assert_equal true, op.field_provided?(:email)
|
263
|
+
assert_equal true, op.field_provided?(:password)
|
264
|
+
end
|
265
|
+
|
266
|
+
def test_a_block_is_not_accepted_with_submit
|
267
|
+
assert_raises ::ArgumentError do
|
268
|
+
::SignupOp.submit! do |o|
|
269
|
+
o.email = "foo@bar.com"
|
270
|
+
o.password = "password123!"
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
assert_raises ::ArgumentError do
|
275
|
+
::SignupOp.submit do |o|
|
276
|
+
o.email = "foo@bar.com"
|
277
|
+
o.password = "password123!"
|
278
|
+
end
|
279
|
+
end
|
280
|
+
end
|
281
281
|
end
|
282
282
|
end
|
@@ -14,6 +14,8 @@ module Subroutine
|
|
14
14
|
integer :bar, default: -> { 3 }
|
15
15
|
date :baz
|
16
16
|
|
17
|
+
string :protekted, mass_assignable: false
|
18
|
+
|
17
19
|
def initialize(options = {})
|
18
20
|
setup_fields(options)
|
19
21
|
end
|
@@ -21,10 +23,11 @@ module Subroutine
|
|
21
23
|
end
|
22
24
|
|
23
25
|
def test_fields_are_configured
|
24
|
-
assert_equal
|
26
|
+
assert_equal 4, Whatever._fields.size
|
25
27
|
assert_equal :string, Whatever._fields[:foo][:type]
|
26
28
|
assert_equal :integer, Whatever._fields[:bar][:type]
|
27
29
|
assert_equal :date, Whatever._fields[:baz][:type]
|
30
|
+
assert_equal :string, Whatever._fields[:protekted][:type]
|
28
31
|
end
|
29
32
|
|
30
33
|
def test_field_defaults_are_handled
|
@@ -43,13 +46,6 @@ module Subroutine
|
|
43
46
|
instance = Whatever.new(foo: "abc")
|
44
47
|
assert_equal true, instance.field_provided?(:foo)
|
45
48
|
assert_equal false, instance.field_provided?(:bar)
|
46
|
-
end
|
47
|
-
|
48
|
-
def test_field_provided
|
49
|
-
|
50
|
-
instance = Whatever.new(foo: "abc")
|
51
|
-
assert_equal true, instance.field_provided?(:foo)
|
52
|
-
assert_equal false, instance.field_provided?(:bar)
|
53
49
|
|
54
50
|
instance = DefaultsOp.new
|
55
51
|
assert_equal false, instance.field_provided?(:foo)
|
@@ -58,18 +54,39 @@ module Subroutine
|
|
58
54
|
assert_equal true, instance.field_provided?(:foo)
|
59
55
|
end
|
60
56
|
|
57
|
+
def test_field_provided_include_manual_assigned_fields
|
58
|
+
instance = Whatever.new
|
59
|
+
instance.foo = "bar"
|
60
|
+
|
61
|
+
assert_equal true, instance.field_provided?(:foo)
|
62
|
+
assert_equal false, instance.field_provided?(:bar)
|
63
|
+
end
|
64
|
+
|
61
65
|
def test_invalid_typecast
|
62
66
|
assert_raises "Error for field `baz`: invalid date" do
|
63
67
|
Whatever.new(baz: "2015-13-01")
|
64
68
|
end
|
65
69
|
end
|
66
70
|
|
67
|
-
def
|
71
|
+
def test_params_include_defaults
|
68
72
|
instance = Whatever.new(foo: "abc")
|
69
|
-
assert_equal({ "foo" => "abc" }, instance.params)
|
70
|
-
assert_equal({ "foo" => "abc", "bar" => 3 }, instance.params_with_defaults)
|
73
|
+
assert_equal({ "foo" => "abc", "bar" => 3 }, instance.params)
|
71
74
|
assert_equal({ "foo" => "foo", "bar" => 3 }, instance.defaults)
|
72
75
|
end
|
73
76
|
|
77
|
+
def test_fields_can_opt_out_of_mass_assignment
|
78
|
+
assert_raises "`protekted` is not mass assignable" do
|
79
|
+
Whatever.new(foo: "abc", protekted: "foo")
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_non_mass_assignment_fields_can_be_individually_assigned
|
84
|
+
instance = Whatever.new(foo: "abc")
|
85
|
+
instance.protekted = "bar"
|
86
|
+
|
87
|
+
assert_equal "bar", instance.protekted
|
88
|
+
assert_equal true, instance.field_provided?(:protekted)
|
89
|
+
end
|
90
|
+
|
74
91
|
end
|
75
92
|
end
|
data/test/support/ops.rb
CHANGED
@@ -64,10 +64,6 @@ class SignupOp < ::Subroutine::Op
|
|
64
64
|
::User
|
65
65
|
end
|
66
66
|
end
|
67
|
-
class WhateverSignupOp < ::SignupOp
|
68
|
-
string :whatever, ignore_errors: true
|
69
|
-
validates :whatever, presence: true
|
70
|
-
end
|
71
67
|
|
72
68
|
class AdminSignupOp < ::SignupOp
|
73
69
|
field :privileges, default: 'min'
|
data/test/test_helper.rb
CHANGED
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.
|
4
|
+
version: 0.10.0.beta
|
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
|
+
date: 2019-11-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|
@@ -108,6 +108,20 @@ dependencies:
|
|
108
108
|
- - ">="
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: byebug
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
111
125
|
description: An interface for creating feature-driven operations.
|
112
126
|
email:
|
113
127
|
- mike@mnelson.io
|
@@ -134,7 +148,6 @@ files:
|
|
134
148
|
- lib/subroutine/auth.rb
|
135
149
|
- lib/subroutine/failure.rb
|
136
150
|
- lib/subroutine/fields.rb
|
137
|
-
- lib/subroutine/filtered_errors.rb
|
138
151
|
- lib/subroutine/op.rb
|
139
152
|
- lib/subroutine/output_not_set_error.rb
|
140
153
|
- lib/subroutine/type_caster.rb
|
@@ -163,9 +176,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
163
176
|
version: '0'
|
164
177
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
165
178
|
requirements:
|
166
|
-
- - "
|
179
|
+
- - ">"
|
167
180
|
- !ruby/object:Gem::Version
|
168
|
-
version:
|
181
|
+
version: 1.3.1
|
169
182
|
requirements: []
|
170
183
|
rubyforge_project:
|
171
184
|
rubygems_version: 2.6.14.4
|