acfs 1.4.0 → 1.7.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.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +26 -0
  3. data/README.md +22 -39
  4. data/acfs.gemspec +8 -14
  5. data/lib/acfs/adapter/base.rb +2 -0
  6. data/lib/acfs/adapter/typhoeus.rb +16 -11
  7. data/lib/acfs/collections/paginatable.rb +1 -1
  8. data/lib/acfs/configuration.rb +13 -3
  9. data/lib/acfs/errors.rb +41 -21
  10. data/lib/acfs/global.rb +2 -2
  11. data/lib/acfs/location.rb +26 -32
  12. data/lib/acfs/middleware/base.rb +2 -2
  13. data/lib/acfs/middleware/json.rb +4 -2
  14. data/lib/acfs/middleware/logger.rb +4 -6
  15. data/lib/acfs/middleware/serializer.rb +1 -1
  16. data/lib/acfs/operation.rb +21 -8
  17. data/lib/acfs/request/callbacks.rb +4 -4
  18. data/lib/acfs/request.rb +4 -11
  19. data/lib/acfs/resource/attributes/date_time.rb +1 -1
  20. data/lib/acfs/resource/attributes/uuid.rb +1 -1
  21. data/lib/acfs/resource/attributes.rb +16 -15
  22. data/lib/acfs/resource/dirty.rb +2 -2
  23. data/lib/acfs/resource/initialization.rb +5 -5
  24. data/lib/acfs/resource/locatable.rb +11 -8
  25. data/lib/acfs/resource/operational.rb +6 -3
  26. data/lib/acfs/resource/persistence.rb +13 -15
  27. data/lib/acfs/resource/query_methods.rb +10 -10
  28. data/lib/acfs/resource/service.rb +2 -2
  29. data/lib/acfs/resource/validation.rb +17 -7
  30. data/lib/acfs/response.rb +5 -5
  31. data/lib/acfs/runner.rb +15 -15
  32. data/lib/acfs/service.rb +16 -19
  33. data/lib/acfs/singleton_resource.rb +2 -2
  34. data/lib/acfs/stub.rb +41 -31
  35. data/lib/acfs/version.rb +2 -2
  36. data/spec/acfs/adapter/typhoeus_spec.rb +2 -2
  37. data/spec/acfs/collection_spec.rb +66 -41
  38. data/spec/acfs/configuration_spec.rb +22 -12
  39. data/spec/acfs/global_spec.rb +11 -9
  40. data/spec/acfs/location_spec.rb +2 -2
  41. data/spec/acfs/middleware/json_spec.rb +22 -8
  42. data/spec/acfs/middleware/{msgpack_spec.rb → message_pack_spec.rb} +6 -6
  43. data/spec/acfs/operation_spec.rb +3 -2
  44. data/spec/acfs/request/callbacks_spec.rb +19 -10
  45. data/spec/acfs/request_spec.rb +16 -20
  46. data/spec/acfs/resource/attributes/boolean_spec.rb +32 -32
  47. data/spec/acfs/resource/attributes/date_time_spec.rb +16 -8
  48. data/spec/acfs/resource/attributes/dict_spec.rb +15 -9
  49. data/spec/acfs/resource/attributes/float_spec.rb +20 -10
  50. data/spec/acfs/resource/attributes/integer_spec.rb +10 -5
  51. data/spec/acfs/resource/attributes/list_spec.rb +13 -8
  52. data/spec/acfs/resource/attributes/uuid_spec.rb +12 -6
  53. data/spec/acfs/resource/attributes_spec.rb +37 -38
  54. data/spec/acfs/resource/dirty_spec.rb +6 -3
  55. data/spec/acfs/resource/initialization_spec.rb +4 -5
  56. data/spec/acfs/resource/loadable_spec.rb +3 -1
  57. data/spec/acfs/resource/locatable_spec.rb +24 -18
  58. data/spec/acfs/resource/{persistance_spec.rb → persistence_spec.rb} +122 -90
  59. data/spec/acfs/resource/query_methods_spec.rb +143 -110
  60. data/spec/acfs/resource/validation_spec.rb +34 -27
  61. data/spec/acfs/response/formats_spec.rb +8 -8
  62. data/spec/acfs/response/status_spec.rb +16 -9
  63. data/spec/acfs/runner_spec.rb +10 -8
  64. data/spec/acfs/service/middleware_spec.rb +3 -3
  65. data/spec/acfs/service_spec.rb +6 -5
  66. data/spec/acfs/singleton_resource_spec.rb +2 -1
  67. data/spec/acfs/stub_spec.rb +57 -53
  68. data/spec/acfs_spec.rb +111 -93
  69. data/spec/spec_helper.rb +1 -2
  70. data/spec/support/response.rb +2 -2
  71. data/spec/support/service.rb +1 -1
  72. data/spec/support/shared/find_callbacks.rb +14 -10
  73. metadata +30 -29
@@ -8,10 +8,11 @@ module Acfs
8
8
  #
9
9
  class Operation
10
10
  attr_reader :action, :params, :resource, :data, :callback, :location, :url
11
+
11
12
  delegate :service, to: :resource
12
13
  delegate :call, to: :callback
13
14
 
14
- def initialize(resource, action, opts = {}, &block)
15
+ def initialize(resource, action, **opts, &block)
15
16
  @resource = resource
16
17
  @action = action.to_sym
17
18
 
@@ -20,9 +21,7 @@ module Acfs
20
21
  @params = (opts[:params] || {}).dup
21
22
  @data = (opts[:data] || {}).dup
22
23
 
23
- if opts[:url]
24
- @url = opts[:url]
25
- else
24
+ unless (@url = opts[:url])
26
25
  @location = resource.location(action: @action).extract_from(@params, @data)
27
26
  @url = location.str
28
27
  end
@@ -44,11 +43,11 @@ module Acfs
44
43
  end
45
44
 
46
45
  def full_params
47
- (id ? params.merge(id: id) : params).merge location_args
46
+ (id ? params.merge(id: id) : params).merge(location_vars)
48
47
  end
49
48
 
50
- def location_args
51
- location ? location.args : {}
49
+ def location_vars
50
+ location ? location.vars : {}
52
51
  end
53
52
 
54
53
  def method
@@ -57,7 +56,7 @@ module Acfs
57
56
 
58
57
  def request
59
58
  request = ::Acfs::Request.new url, method: method, params: params,
60
- data: data, operation: self
59
+ data: data, operation: self
61
60
  request.on_complete do |response|
62
61
  ::ActiveSupport::Notifications.instrument 'acfs.operation.complete',
63
62
  operation: self,
@@ -71,10 +70,24 @@ module Acfs
71
70
 
72
71
  def handle_failure(response)
73
72
  case response.code
73
+ when 400
74
+ raise ::Acfs::BadRequest.new response: response
75
+ when 401
76
+ raise ::Acfs::Unauthorized.new response: response
77
+ when 403
78
+ raise ::Acfs::Forbidden.new response: response
74
79
  when 404
75
80
  raise ::Acfs::ResourceNotFound.new response: response
76
81
  when 422
77
82
  raise ::Acfs::InvalidResource.new response: response, errors: response.data.try(:[], 'errors')
83
+ when 500
84
+ raise ::Acfs::ServerError.new response: response
85
+ when 502
86
+ raise ::Acfs::BadGateway.new response: response
87
+ when 503
88
+ raise ::Acfs::ServiceUnavailable.new response: response
89
+ when 504
90
+ raise ::Acfs::GatewayTimeout.new response: response
78
91
  else
79
92
  raise ::Acfs::ErroneousResponse.new response: response
80
93
  end
@@ -21,7 +21,7 @@ module Acfs
21
21
  # @return [ Acfs::Request ] The request itself.
22
22
  #
23
23
  def on_complete(&block)
24
- callbacks.insert 0, block if block_given?
24
+ callbacks.insert 0, block if block
25
25
  self
26
26
  end
27
27
 
@@ -45,9 +45,9 @@ module Acfs
45
45
  private
46
46
 
47
47
  def call_callback(res, index)
48
- if index < callbacks.size
49
- callbacks[index].call res, proc {|bres| call_callback bres, index + 1 }
50
- end
48
+ return if index >= callbacks.size
49
+
50
+ callbacks[index].call(res, proc {|bres| call_callback bres, index + 1 })
51
51
  end
52
52
  end
53
53
  end
data/lib/acfs/request.rb CHANGED
@@ -11,8 +11,7 @@ module Acfs
11
11
  attr_reader :url, :headers, :params, :data, :method, :operation
12
12
 
13
13
  include Request::Callbacks
14
-
15
- def initialize(url, options = {}, &block)
14
+ def initialize(url, **options, &block)
16
15
  @url = URI.parse(url.to_s).tap do |_url|
17
16
  @data = options.delete(:data) || nil
18
17
  @format = options.delete(:format) || :json
@@ -20,20 +19,14 @@ module Acfs
20
19
  @params = options.delete(:params) || {}
21
20
  @method = options.delete(:method) || :get
22
21
  end.to_s
22
+
23
23
  @operation = options.delete(:operation) || nil
24
- on_complete(&block) if block_given?
24
+
25
+ on_complete(&block) if block
25
26
  end
26
27
 
27
28
  def data?
28
29
  !data.nil?
29
30
  end
30
-
31
- class << self
32
- def new(*attrs)
33
- return attrs[0] if attrs[0].is_a? self
34
-
35
- super
36
- end
37
- end
38
31
  end
39
32
  end
@@ -22,7 +22,7 @@ module Acfs::Resource::Attributes
22
22
  def cast_value(value)
23
23
  if value.blank?
24
24
  nil
25
- elsif value.acts_like?(:time) || value.acts_like?(:date)
25
+ elsif !value.is_a?(::String) && value.respond_to?(:to_datetime)
26
26
  value.to_datetime
27
27
  else
28
28
  ::DateTime.iso8601 value
@@ -35,7 +35,7 @@ module Acfs::Resource::Attributes
35
35
  def cast_value(value)
36
36
  if value.blank?
37
37
  nil
38
- elsif value.to_s =~ UUID_REGEXP
38
+ elsif UUID_REGEXP.match?(value.to_s)
39
39
  value
40
40
  else
41
41
  raise TypeError.new "Invalid UUID: `#{value}'"
@@ -48,9 +48,11 @@ class Acfs::Resource
48
48
  # @return [HashWithIndifferentAccess{Symbol => Object}]
49
49
  # Attributes and their values.
50
50
  #
51
+ # rubocop:disable Naming/MemoizedInstanceVariableName
51
52
  def attributes
52
53
  @_attrs ||= HashWithIndifferentAccess.new
53
54
  end
55
+ # rubocop:enable Naming/MemoizedInstanceVariableName
54
56
 
55
57
  # @api public
56
58
  #
@@ -66,7 +68,7 @@ class Acfs::Resource
66
68
  # @see #write_attributes Delegates attributes hash to {#write_attributes}.
67
69
  #
68
70
  def attributes=(attributes)
69
- write_attributes attributes
71
+ write_attributes(attributes)
70
72
  end
71
73
 
72
74
  # @api public
@@ -101,17 +103,16 @@ class Acfs::Resource
101
103
  #
102
104
  # @see #write_attribute Delegates attribute values to `#write_attribute`.
103
105
  #
104
- def write_attributes(attributes, opts = {})
106
+ def write_attributes(attributes, **opts)
105
107
  unless attributes.respond_to?(:each) && attributes.respond_to?(:keys)
106
108
  return false
107
109
  end
108
110
 
109
- if opts.fetch(:unknown, :ignore) == :raise
110
- if (attributes.keys.map(&:to_s) - self.class.attributes.keys).any?
111
- missing = attributes.keys - self.class.attributes.keys
112
- missing.map!(&:inspect)
113
- raise ArgumentError.new "Unknown attributes: #{missing.join(', ')}"
114
- end
111
+ if opts.fetch(:unknown, :ignore) == :raise &&
112
+ (attributes.keys.map(&:to_s) - self.class.attributes.keys).any?
113
+ missing = attributes.keys - self.class.attributes.keys
114
+ missing.map!(&:inspect)
115
+ raise ArgumentError.new "Unknown attributes: #{missing.join(', ')}"
115
116
  end
116
117
 
117
118
  procs = {}
@@ -120,12 +121,12 @@ class Acfs::Resource
120
121
  if attributes[key].is_a? Proc
121
122
  procs[key] = attributes[key]
122
123
  else
123
- write_local_attribute key, attributes[key], opts
124
+ write_local_attribute(key, attributes[key], **opts)
124
125
  end
125
126
  end
126
127
 
127
128
  procs.each do |key, proc|
128
- write_local_attribute key, instance_exec(&proc), opts
129
+ write_local_attribute(key, instance_exec(&proc), **opts)
129
130
  end
130
131
 
131
132
  true
@@ -199,12 +200,12 @@ class Acfs::Resource
199
200
  # @param [Symbol, String, Class] type Attribute
200
201
  # type identifier or type class.
201
202
  #
202
- def attribute(name, type, opts = {})
203
+ def attribute(name, type, **opts)
203
204
  if type.is_a?(Symbol) || type.is_a?(String)
204
205
  type = "#{ATTR_CLASS_BASE}::#{type.to_s.classify}".constantize
205
206
  end
206
207
 
207
- define_attribute name.to_sym, type, opts
208
+ define_attribute(name.to_sym, type, **opts)
208
209
  end
209
210
 
210
211
  # @api public
@@ -242,9 +243,9 @@ class Acfs::Resource
242
243
  @local_attributes ||= {}
243
244
  end
244
245
 
245
- def define_attribute(name, type, opts = {})
246
+ def define_attribute(name, type, **opts)
246
247
  name = name.to_s
247
- attribute = type.new opts
248
+ attribute = type.new(**opts)
248
249
 
249
250
  local_attributes[name] = attribute
250
251
  define_attribute_method name
@@ -263,7 +264,7 @@ end
263
264
 
264
265
  # Load attribute type classes.
265
266
  #
266
- Dir[File.dirname(__FILE__) + '/attributes/*.rb'].sort.each do |path|
267
+ Dir[File.join(__dir__, 'attributes/*.rb')].sort.each do |path|
267
268
  filename = File.basename(path)
268
269
  require "acfs/resource/attributes/#{filename}"
269
270
  end
@@ -16,8 +16,8 @@ class Acfs::Resource
16
16
 
17
17
  # @api private
18
18
  #
19
- def save!(*)
20
- super.tap {|_| changes_applied }
19
+ def save!(**kwargs)
20
+ super(**kwargs).tap {|_| changes_applied }
21
21
  end
22
22
 
23
23
  # @api private
@@ -8,7 +8,7 @@ class Acfs::Resource
8
8
  #
9
9
  # @api public
10
10
  #
11
- # Initializes a new model with the given `params`. fff
11
+ # Initializes a new model with the given `params`.
12
12
  #
13
13
  # @example
14
14
  # class User < Acfs::Resource
@@ -17,15 +17,15 @@ class Acfs::Resource
17
17
  # attribute :age, :integer, default: 18
18
18
  # end
19
19
  #
20
- # user = User.new(name: 'bob')
20
+ # user = User.new({name: 'bob'})
21
21
  # user.name # => "bob"
22
22
  # user.email # => "bob@dom.tld"
23
23
  # user.age # => 18
24
24
  #
25
- # @param params [Hash{Symbol => Object}] Attributes to set on resource.
25
+ # @param attributes [Hash{Symbol => Object}] Attributes to set on resource.
26
26
  #
27
- def initialize(params = {})
28
- write_attributes params if params
27
+ def initialize(attributes = {})
28
+ write_attributes(attributes) if attributes
29
29
  end
30
30
  end
31
31
  end
@@ -40,15 +40,18 @@ class Acfs::Resource
40
40
  # usually `:list`, `:create`, `:read`, `:update` or`:delete`.
41
41
  # @return [String] Generated URL.
42
42
  #
43
- def url(suffix = nil, opts = {})
43
+ def url(suffix = nil, **opts)
44
44
  if suffix.is_a? Hash
45
45
  opts = suffix
46
46
  suffix = nil
47
47
  end
48
48
 
49
- opts[:action] = :list if suffix
49
+ kwargs = {}
50
+ kwargs[:path] = opts[:path] if opts.key?(:path)
51
+ kwargs[:action] = opts.delete(:action) if opts.key?(:action)
52
+ kwargs[:action] = :list if suffix
50
53
 
51
- url = location(opts).build(opts).str
54
+ url = location(**kwargs).build(opts.stringify_keys).str
52
55
  url += "/#{suffix}" if suffix.to_s.present?
53
56
  url
54
57
  end
@@ -81,8 +84,8 @@ class Acfs::Resource
81
84
  #
82
85
  # @return [Location] Location object.
83
86
  #
84
- def location(opts = {})
85
- service.location(self, opts)
87
+ def location(**opts)
88
+ service.location(self, **opts)
86
89
  end
87
90
 
88
91
  # @api private
@@ -109,12 +112,12 @@ class Acfs::Resource
109
112
  # @return [ String ] Generated URL.
110
113
  # @see ClassMethods#url
111
114
  #
112
- def url(opts = {})
115
+ def url(**opts)
113
116
  return nil if need_primary_key? && !primary_key?
114
117
 
115
118
  self.class.service
116
- .location(self.class, opts.reverse_merge(action: :read))
117
- .build(attributes).str
119
+ .location(self.class, **opts, action: :read)
120
+ .build(attributes).str
118
121
  end
119
122
 
120
123
  # @api private
@@ -11,12 +11,15 @@ class Acfs::Resource
11
11
  #
12
12
  module Operational
13
13
  extend ActiveSupport::Concern
14
- delegate :operation, to: :'self.class'
14
+
15
+ def operation(*args, **kwargs, &block)
16
+ self.class.operation(*args, **kwargs, &block)
17
+ end
15
18
 
16
19
  module ClassMethods
17
20
  # Invoke CRUD operation.
18
- def operation(action, opts = {}, &block)
19
- Acfs.runner.process ::Acfs::Operation.new self, action, opts, &block
21
+ def operation(action, **opts, &block)
22
+ Acfs.runner.process ::Acfs::Operation.new(self, action, **opts, &block)
20
23
  end
21
24
  end
22
25
  end
@@ -57,8 +57,8 @@ class Acfs::Resource
57
57
  # false otherwise.
58
58
  # @see #save! See {#save!} for available options.
59
59
  #
60
- def save(*args)
61
- save!(*args)
60
+ def save(**opts)
61
+ save!(**opts)
62
62
  true
63
63
  rescue Acfs::Error
64
64
  false
@@ -82,10 +82,10 @@ class Acfs::Resource
82
82
  #
83
83
  # @see #save
84
84
  #
85
- def save!(opts = {})
85
+ def save!(**opts)
86
86
  opts[:data] = attributes unless opts[:data]
87
87
 
88
- operation((new? ? :create : :update), opts) do |data|
88
+ operation((new? ? :create : :update), **opts) do |data|
89
89
  update_with data
90
90
  end
91
91
  rescue ::Acfs::InvalidResource => e
@@ -109,11 +109,11 @@ class Acfs::Resource
109
109
  # @see #attributes=
110
110
  # @see #update_attributes!
111
111
  #
112
- def update_attributes(attrs, opts = {})
113
- check_loaded! opts
112
+ def update_attributes(attrs, **opts)
113
+ check_loaded!(**opts)
114
114
 
115
115
  self.attributes = attrs
116
- save opts
116
+ save(**opts)
117
117
  end
118
118
 
119
119
  # @api public
@@ -136,11 +136,11 @@ class Acfs::Resource
136
136
  # @see #attributes=
137
137
  # @see #update_attributes
138
138
  #
139
- def update_attributes!(attrs, opts = {})
139
+ def update_attributes!(attrs, **opts)
140
140
  check_loaded! opts
141
141
 
142
142
  self.attributes = attrs
143
- save! opts
143
+ save!(**opts)
144
144
  end
145
145
 
146
146
  # @api public
@@ -152,8 +152,8 @@ class Acfs::Resource
152
152
  # @return [Boolean]
153
153
  # @see #delete!
154
154
  #
155
- def delete(opts = {})
156
- delete! opts
155
+ def delete(**opts)
156
+ delete!(**opts)
157
157
  true
158
158
  rescue Acfs::Error
159
159
  false
@@ -172,11 +172,11 @@ class Acfs::Resource
172
172
  # @return [undefined]
173
173
  # @see #delete
174
174
  #
175
- def delete!(opts = {})
175
+ def delete!(**opts)
176
176
  opts[:params] ||= {}
177
177
  opts[:params] = attributes_for_url(:delete).merge opts[:params]
178
178
 
179
- operation :delete, opts do |data|
179
+ operation(:delete, **opts) do |data|
180
180
  update_with data
181
181
  freeze
182
182
  end
@@ -244,8 +244,6 @@ class Acfs::Resource
244
244
  end
245
245
  end
246
246
 
247
- private
248
-
249
247
  def update_with(data)
250
248
  self.attributes = data
251
249
  loaded!
@@ -56,7 +56,7 @@ class Acfs::Resource
56
56
  #
57
57
  # @return [Collection] Collection of requested resources.
58
58
  #
59
- def find(id_or_ids, opts = {}, &block)
59
+ def find(id_or_ids, **opts, &block)
60
60
  if id_or_ids.respond_to? :each
61
61
  find_multiple id_or_ids, opts, &block
62
62
  else
@@ -81,7 +81,7 @@ class Acfs::Resource
81
81
  collection = ::Acfs::Collection.new self
82
82
  collection.__callbacks__ << block if block
83
83
 
84
- operation :list, opts.merge(params: params) do |data, response|
84
+ operation(:list, **opts, params: params) do |data, response|
85
85
  data.each {|obj| collection << create_resource(obj) }
86
86
  collection.process_response response
87
87
  collection.loaded!
@@ -109,7 +109,7 @@ class Acfs::Resource
109
109
  def find_by(params, &block)
110
110
  Acfs::Util::ResourceDelegator.new(new).tap do |m|
111
111
  m.__callbacks__ << block unless block.nil?
112
- operation :list, params: params do |data|
112
+ operation(:list, params: params) do |data|
113
113
  if data.empty?
114
114
  m.__setobj__ nil
115
115
  else
@@ -139,7 +139,7 @@ class Acfs::Resource
139
139
  find_by params do |m|
140
140
  if m.nil?
141
141
  raise Acfs::ResourceNotFound.new message: 'Received erroneous ' \
142
- "response: no `#{name}` with params #{params} found"
142
+ "response: no `#{name}` with params #{params} found"
143
143
  end
144
144
  block&.call m
145
145
  end
@@ -210,11 +210,11 @@ class Acfs::Resource
210
210
  model = Acfs::Util::ResourceDelegator.new new
211
211
 
212
212
  opts[:params] ||= {}
213
- opts[:params].merge! id: id unless id.nil?
213
+ opts[:params][:id] = id unless id.nil?
214
214
 
215
215
  model.__callbacks__ << block unless block.nil?
216
216
 
217
- operation :read, opts do |data|
217
+ operation(:read, **opts) do |data|
218
218
  model.__setobj__ create_resource data, origin: model.__getobj__
219
219
  model.__invoke__
220
220
  end
@@ -228,7 +228,7 @@ class Acfs::Resource
228
228
 
229
229
  counter = 0
230
230
  ids.each_with_index do |id, index|
231
- find_single id, opts do |resource|
231
+ find_single(id, opts) do |resource|
232
232
  collection[index] = resource
233
233
  if (counter += 1) == ids.size
234
234
  collection.loaded!
@@ -239,11 +239,11 @@ class Acfs::Resource
239
239
  end
240
240
  end
241
241
 
242
- def create_resource(data, opts = {})
242
+ def create_resource(data, **opts)
243
243
  type = data.delete 'type'
244
244
  klass = resource_class_lookup(type)
245
245
  (opts[:origin].is_a?(klass) ? opts[:origin] : klass.new).tap do |m|
246
- m.write_attributes data, opts
246
+ m.write_attributes(data, **opts)
247
247
  m.loaded!
248
248
  end
249
249
  end
@@ -258,7 +258,7 @@ class Acfs::Resource
258
258
  end
259
259
 
260
260
  klass
261
- rescue NameError, NoMethodError
261
+ rescue NameError
262
262
  raise Acfs::ResourceTypeError.new type_name: type, base_class: self
263
263
  end
264
264
  end
@@ -34,8 +34,8 @@ class Acfs::Resource
34
34
  # @param options [Object] Option delegated to
35
35
  # service class initializer.
36
36
  #
37
- def service(klass = nil, options = {})
38
- return (@service = klass.new options) if klass
37
+ def service(klass = nil, **options)
38
+ return (@service = klass.new(**options)) if klass
39
39
 
40
40
  @service || superclass.service
41
41
  end
@@ -2,12 +2,6 @@
2
2
 
3
3
  class Acfs::Resource
4
4
  module Validation
5
- def valid?(*args)
6
- super
7
- remote_errors.each {|f, e| errors.add f, e }
8
- errors.empty?
9
- end
10
-
11
5
  def remote_errors
12
6
  @remote_errors ||= ActiveModel::Errors.new self
13
7
  end
@@ -28,12 +22,28 @@ class Acfs::Resource
28
22
  end
29
23
  end
30
24
 
31
- def save!(*_)
25
+ def save!(**kwargs)
32
26
  unless valid?(new? ? :create : :save)
33
27
  raise ::Acfs::InvalidResource.new resource: self, errors: errors.to_a
34
28
  end
35
29
 
36
30
  super
37
31
  end
32
+
33
+ if ::ActiveModel.version >= Gem::Version.new('6.1')
34
+ def valid?(*args)
35
+ super
36
+
37
+ remote_errors.each {|e| errors.add(e.attribute, e.message) }
38
+ errors.empty?
39
+ end
40
+ else
41
+ def valid?(*args)
42
+ super
43
+
44
+ remote_errors.each {|f, e| errors.add(f, e) }
45
+ errors.empty?
46
+ end
47
+ end
38
48
  end
39
49
  end
data/lib/acfs/response.rb CHANGED
@@ -19,12 +19,12 @@ module Acfs
19
19
  # :response_body, :response_headers, :response_code, :headers,
20
20
  # to: :response
21
21
 
22
- def initialize(request, data = {})
22
+ def initialize(request, **opts)
23
23
  @request = request
24
- @status = data[:status] || 0
25
- @headers = data[:headers] || {}
26
- @body = data[:body] || ''
27
- @data = data[:data] || nil
24
+ @status = opts[:status] || 0
25
+ @headers = opts[:headers] || {}
26
+ @body = opts[:body] || ''
27
+ @data = opts[:data] || nil
28
28
  end
29
29
  end
30
30
  end
data/lib/acfs/runner.rb CHANGED
@@ -17,16 +17,16 @@ module Acfs
17
17
  # Process an operation. Synchronous operations will be run
18
18
  # and parallel operations will be queued.
19
19
  #
20
- def process(op)
21
- ::ActiveSupport::Notifications.instrument 'acfs.operation.before_process', operation: op
22
- op.synchronous? ? run(op) : enqueue(op)
20
+ def process(operation)
21
+ ::ActiveSupport::Notifications.instrument('acfs.operation.before_process', operation: operation)
22
+ operation.synchronous? ? run(operation) : enqueue(operation)
23
23
  end
24
24
 
25
25
  # Run operation right now skipping queue.
26
26
  #
27
- def run(op)
28
- ::ActiveSupport::Notifications.instrument 'acfs.runner.sync_run', operation: op do
29
- op_request(op) {|req| adapter.run req }
27
+ def run(operation)
28
+ ::ActiveSupport::Notifications.instrument('acfs.runner.sync_run', operation: operation) do
29
+ operation_request(operation) {|req| adapter.run req }
30
30
  end
31
31
  end
32
32
 
@@ -38,12 +38,12 @@ module Acfs
38
38
 
39
39
  # Enqueue operation to be run later.
40
40
  #
41
- def enqueue(op)
42
- ::ActiveSupport::Notifications.instrument 'acfs.runner.enqueue', operation: op do
41
+ def enqueue(operation)
42
+ ::ActiveSupport::Notifications.instrument('acfs.runner.enqueue', operation: operation) do
43
43
  if running?
44
- op_request(op) {|req| adapter.queue req }
44
+ operation_request(operation) {|req| adapter.queue req }
45
45
  else
46
- queue << op
46
+ queue << operation
47
47
  end
48
48
  end
49
49
  end
@@ -82,15 +82,15 @@ module Acfs
82
82
  end
83
83
 
84
84
  def enqueue_operations
85
- while (op = queue.shift)
86
- op_request(op) {|req| adapter.queue req }
85
+ while (operation = queue.shift)
86
+ operation_request(operation) {|req| adapter.queue req }
87
87
  end
88
88
  end
89
89
 
90
- def op_request(op)
91
- return if Acfs::Stub.enabled? && Acfs::Stub.stubbed(op)
90
+ def operation_request(operation)
91
+ return if Acfs::Stub.enabled? && Acfs::Stub.stubbed(operation)
92
92
 
93
- req = op.service.prepare op.request
93
+ req = operation.service.prepare(operation.request)
94
94
  return unless req.is_a? Acfs::Request
95
95
 
96
96
  req = prepare req