acfs 1.4.0 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
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