acfs 1.5.1 → 1.6.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 55e1388e9df4207138b2a54f1e9d56c349ac407e52364b849887e9682abfee7e
4
- data.tar.gz: ccf1b3550de8f5222988333d14e480ec07742fb0398d3adfb9504be4ca4168b4
3
+ metadata.gz: 46dc13b234cd5b704b67a731292b06ad8b32ee3fafb0a7a0af2a1003824e6df8
4
+ data.tar.gz: a35249f8e2a7a6cc49351b62c75b3fe641b26691132f4fb70b0a183ab041a380
5
5
  SHA512:
6
- metadata.gz: d34c6fd3d4e83e22757633efc72c8d399778b86665f4b5bb6fb46c8d4f93782f996fe307904ac83f9b16701157ecb8418977466cad9d9c5a78c6ea1074e9ddd7
7
- data.tar.gz: 3460436cd3a9d61241155658e4c46ef556b69d00fd389aca73c78ca6484b29bac9b3c45a0fd310b41259aba68f8aad55c7ca95a259e18075c2d88b2515bacd52
6
+ metadata.gz: 07132ad9797084fccd7fdeb31cc9f51572ddda1eb9dc88aaf875cd244000d15823223d3c6c503f0af7ac4cc1f59cb0b748eea75d8592323b807001e82c93d781
7
+ data.tar.gz: 6d6d15b6841820ae2ee672eec742b417113523ce613f1a7c7d493eeed50232b0915d7edcbf3df1b7060c5ced484bb82f59904e34fe6e17f70babe3b5ddf0a4e7
@@ -14,6 +14,14 @@
14
14
  ### Breaks
15
15
 
16
16
 
17
+ ## 1.6.0 - (2021-01-07)
18
+ ---
19
+
20
+ ### New
21
+ * Support Ruby 3.0
22
+ * Use keyword arguments in parameters and when calling methods
23
+
24
+
17
25
  ## 1.5.1 - (2020-12-30)
18
26
  ---
19
27
 
@@ -25,6 +25,8 @@ Gem::Specification.new do |spec|
25
25
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
26
26
  spec.require_paths = %w[lib]
27
27
 
28
+ spec.required_ruby_version = '>= 2.5.0'
29
+
28
30
  spec.add_runtime_dependency 'actionpack', '>= 5.2'
29
31
  spec.add_runtime_dependency 'activemodel', '>= 5.2'
30
32
  spec.add_runtime_dependency 'activesupport', '>= 5.2'
@@ -5,6 +5,8 @@ module Acfs::Adapter
5
5
  # and processing.
6
6
  #
7
7
  class Base
8
+ def initialize(*); end
9
+
8
10
  # Start processing queued requests.
9
11
  #
10
12
  def start; end
@@ -13,8 +13,11 @@ module Acfs
13
13
  # Adapter for Typhoeus.
14
14
  #
15
15
  class Typhoeus < Base
16
- def initialize(opts: {}, **kwargs)
17
- @opts = DEFAULT_OPTIONS.merge(opts)
16
+ def initialize(**kwargs)
17
+ super
18
+
19
+ @opts = DEFAULT_OPTIONS
20
+ @opts = @opts.merge(opts) if (opts = kwargs.delete(:opts))
18
21
  @kwargs = kwargs
19
22
  end
20
23
 
@@ -52,7 +55,7 @@ module Acfs
52
55
  body: req.body
53
56
  }
54
57
 
55
- request = ::Typhoeus::Request.new(req.url, **@opts.merge(opts))
58
+ request = ::Typhoeus::Request.new(req.url, **@opts, **opts)
56
59
 
57
60
  request.on_complete do |response|
58
61
  raise ::Acfs::TimeoutError.new(req) if response.timed_out?
@@ -5,7 +5,7 @@ module Acfs::Collections
5
5
  extend ActiveSupport::Concern
6
6
 
7
7
  included do
8
- def self.operation(_action, opts = {}, &_block)
8
+ def self.operation(_action, **opts, &_block)
9
9
  opts[:url]
10
10
  end
11
11
 
@@ -68,8 +68,8 @@ module Acfs::Collections
68
68
  def setup_params(params)
69
69
  @current_page = begin
70
70
  Integer params.fetch(:page, 1)
71
- rescue ArgumentError
72
- params[:page]
71
+ rescue ArgumentError
72
+ params[:page]
73
73
  end
74
74
  end
75
75
  end
@@ -39,7 +39,7 @@ module Acfs
39
39
  @response = opts[:response]
40
40
 
41
41
  message = if response
42
- (opts[:message] ? opts[:message] + ':' : 'Received') +
42
+ (opts[:message] ? "#{opts[:message]}:" : 'Received') +
43
43
  " #{response.code} for #{response.request.method.upcase}" \
44
44
  " #{response.request.url} #{response.request.format}"
45
45
  else
@@ -87,12 +87,13 @@ module Acfs
87
87
  @errors = opts.delete :errors
88
88
  @resource = opts.delete :resource
89
89
 
90
- if @errors.is_a?(Hash)
91
- opts[:message] ||= @errors.each_pair.map do |k, v|
92
- @errors.is_a?(Array) ? "#{k}: #{v.join(', ')}" : "#{k}: #{v}"
93
- end.join ', '
94
- elsif @errors.is_a?(Array)
95
- opts[:message] ||= @errors.join ', '
90
+ case @errors
91
+ when Hash
92
+ opts[:message] ||= @errors.each_pair.map do |k, v|
93
+ @errors.is_a?(Array) ? "#{k}: #{v.join(', ')}" : "#{k}: #{v}"
94
+ end.join ', '
95
+ when Array
96
+ opts[:message] ||= @errors.join ', '
96
97
  end
97
98
 
98
99
  super
@@ -131,8 +132,7 @@ module Acfs
131
132
  # parent resource. Check if the type is set to the correct
132
133
  # Acfs::Resource Name
133
134
  class ResourceTypeError < Error
134
- attr_reader :base_class
135
- attr_reader :type_name
135
+ attr_reader :base_class, :type_name
136
136
 
137
137
  def initialize(opts = {})
138
138
  @base_class = opts.delete :base_class
@@ -6,36 +6,31 @@ module Acfs
6
6
  # Describes a URL with placeholders.
7
7
  #
8
8
  class Location
9
- attr_reader :arguments, :raw, :struct, :args
9
+ attr_reader :arguments, :raw, :struct, :vars
10
10
 
11
11
  REGEXP = /^:([A-z][A-z0-9_]*)$/.freeze
12
12
 
13
- def initialize(uri, args = {})
13
+ def initialize(uri, vars = {})
14
14
  @raw = URI.parse uri
15
- @args = args
15
+ @vars = vars
16
16
  @struct = raw.path.split('/').reject(&:empty?).map {|s| s =~ REGEXP ? Regexp.last_match[1].to_sym : s }
17
17
  @arguments = struct.select {|s| s.is_a?(Symbol) }
18
18
  end
19
19
 
20
- def build(args = {})
21
- unless args.is_a?(Hash)
22
- raise ArgumentError.new "URI path arguments must be a hash, `#{args.inspect}' given."
23
- end
24
-
25
- self.class.new raw.to_s, args.merge(self.args)
20
+ def build(vars)
21
+ self.class.new raw.to_s, vars.stringify_keys.merge(self.vars)
26
22
  end
27
23
 
28
24
  def extract_from(*args)
29
- args = {}.tap do |collect|
30
- arguments.each {|key| collect[key] = extract_arg key, args }
31
- end
25
+ vars = {}
26
+ arguments.each {|key| vars[key.to_s] = extract_arg(key, args) }
32
27
 
33
- build args
28
+ build(vars)
34
29
  end
35
30
 
36
31
  def str
37
32
  uri = raw.dup
38
- uri.path = '/' + struct.map {|s| lookup_arg(s, args) }.join('/')
33
+ uri.path = "/#{struct.map(&method(:lookup_variable)).join('/')}"
39
34
  uri.to_s
40
35
  end
41
36
 
@@ -56,27 +51,26 @@ module Acfs
56
51
  nil
57
52
  end
58
53
 
59
- def lookup_arg(arg, args)
60
- arg.is_a?(Symbol) ? lookup_replacement(arg, args) : arg
61
- end
54
+ def lookup_variable(name)
55
+ return name unless name.is_a?(Symbol)
62
56
 
63
- def lookup_replacement(sym, args)
64
- value = get_replacement(sym, args).to_s
65
- return ::URI.encode_www_form_component(value) unless value.empty?
57
+ value = vars.fetch(name.to_s) do
58
+ if @raise.nil? || @raise
59
+ raise ArgumentError.new <<~ERROR.strip
60
+ URI path argument `#{name}' missing on `#{self}'. Given: `#{vars}.inspect'
61
+ ERROR
62
+ end
66
63
 
67
- raise ArgumentError.new "Cannot replace path argument `#{sym}' with empty string."
68
- end
64
+ ":#{name}"
65
+ end
69
66
 
70
- def get_replacement(sym, args)
71
- args.fetch(sym.to_s) do
72
- args.fetch(sym) do
73
- if args[:raise].nil? || args[:raise]
74
- raise ArgumentError.new "URI path argument `#{sym}' missing on `#{self}'. Given: `#{args}.inspect'"
75
- end
67
+ value = value.to_s.strip
76
68
 
77
- ":#{sym}"
78
- end
69
+ if value.empty?
70
+ raise ArgumentError.new "Cannot replace path argument `#{name}' with empty string."
79
71
  end
72
+
73
+ ::URI.encode_www_form_component(value)
80
74
  end
81
75
  end
82
76
  end
@@ -8,9 +8,9 @@ module Acfs
8
8
  class Base
9
9
  attr_reader :app, :options
10
10
 
11
- def initialize(app, options = {})
11
+ def initialize(app, **opts)
12
12
  @app = app
13
- @options = options
13
+ @options = opts
14
14
  end
15
15
 
16
16
  def call(request)
@@ -7,19 +7,17 @@ module Acfs
7
7
  # Log requests and responses.
8
8
  #
9
9
  class Logger < Base
10
- def initialize(app, options = {})
10
+ attr_reader :logger
11
+
12
+ def initialize(app, **opts)
11
13
  super
12
- @logger = options[:logger] if options[:logger]
14
+ @logger = options[:logger] || ::Logger.new($stdout)
13
15
  end
14
16
 
15
17
  def response(res, nxt)
16
18
  logger.info "[ACFS] #{res.request.method.to_s.upcase} #{res.request.url} -> #{res.status}"
17
19
  nxt.call res
18
20
  end
19
-
20
- def logger
21
- @logger ||= ::Logger.new STDOUT
22
- end
23
21
  end
24
22
  end
25
23
  end
@@ -29,7 +29,7 @@ module Acfs
29
29
  request.headers['Accept'] = accept.join(',')
30
30
 
31
31
  request.on_complete do |response, nxt|
32
- response.data = decode response.body if mime == response.content_type
32
+ response.data = decode(response.body) if mime == response.content_type
33
33
 
34
34
  nxt.call response
35
35
  end
@@ -12,7 +12,7 @@ module Acfs
12
12
  delegate :service, to: :resource
13
13
  delegate :call, to: :callback
14
14
 
15
- def initialize(resource, action, opts = {}, &block)
15
+ def initialize(resource, action, **opts, &block)
16
16
  @resource = resource
17
17
  @action = action.to_sym
18
18
 
@@ -21,9 +21,7 @@ module Acfs
21
21
  @params = (opts[:params] || {}).dup
22
22
  @data = (opts[:data] || {}).dup
23
23
 
24
- if opts[:url]
25
- @url = opts[:url]
26
- else
24
+ unless (@url = opts[:url])
27
25
  @location = resource.location(action: @action).extract_from(@params, @data)
28
26
  @url = location.str
29
27
  end
@@ -45,11 +43,11 @@ module Acfs
45
43
  end
46
44
 
47
45
  def full_params
48
- (id ? params.merge(id: id) : params).merge location_args
46
+ (id ? params.merge(id: id) : params).merge(location_vars)
49
47
  end
50
48
 
51
- def location_args
52
- location ? location.args : {}
49
+ def location_vars
50
+ location ? location.vars : {}
53
51
  end
54
52
 
55
53
  def method
@@ -11,7 +11,7 @@ module Acfs
11
11
  attr_reader :url, :headers, :params, :data, :method, :operation
12
12
 
13
13
  include Request::Callbacks
14
- def initialize(url, options = {}, &block)
14
+ def initialize(url, **options, &block)
15
15
  @url = URI.parse(url.to_s).tap do |_url|
16
16
  @data = options.delete(:data) || nil
17
17
  @format = options.delete(:format) || :json
@@ -28,13 +28,5 @@ module Acfs
28
28
  def data?
29
29
  !data.nil?
30
30
  end
31
-
32
- class << self
33
- def new(*attrs)
34
- return attrs[0] if attrs[0].is_a? self
35
-
36
- super
37
- end
38
- end
39
31
  end
40
32
  end
@@ -68,7 +68,7 @@ class Acfs::Resource
68
68
  # @see #write_attributes Delegates attributes hash to {#write_attributes}.
69
69
  #
70
70
  def attributes=(attributes)
71
- write_attributes attributes
71
+ write_attributes(attributes)
72
72
  end
73
73
 
74
74
  # @api public
@@ -103,17 +103,16 @@ class Acfs::Resource
103
103
  #
104
104
  # @see #write_attribute Delegates attribute values to `#write_attribute`.
105
105
  #
106
- def write_attributes(attributes, opts = {})
106
+ def write_attributes(attributes, **opts)
107
107
  unless attributes.respond_to?(:each) && attributes.respond_to?(:keys)
108
108
  return false
109
109
  end
110
110
 
111
- if opts.fetch(:unknown, :ignore) == :raise
112
- if (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(', ')}"
116
- 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(', ')}"
117
116
  end
118
117
 
119
118
  procs = {}
@@ -122,12 +121,12 @@ class Acfs::Resource
122
121
  if attributes[key].is_a? Proc
123
122
  procs[key] = attributes[key]
124
123
  else
125
- write_local_attribute key, attributes[key], opts
124
+ write_local_attribute(key, attributes[key], **opts)
126
125
  end
127
126
  end
128
127
 
129
128
  procs.each do |key, proc|
130
- write_local_attribute key, instance_exec(&proc), opts
129
+ write_local_attribute(key, instance_exec(&proc), **opts)
131
130
  end
132
131
 
133
132
  true
@@ -201,12 +200,12 @@ class Acfs::Resource
201
200
  # @param [Symbol, String, Class] type Attribute
202
201
  # type identifier or type class.
203
202
  #
204
- def attribute(name, type, opts = {})
203
+ def attribute(name, type, **opts)
205
204
  if type.is_a?(Symbol) || type.is_a?(String)
206
205
  type = "#{ATTR_CLASS_BASE}::#{type.to_s.classify}".constantize
207
206
  end
208
207
 
209
- define_attribute name.to_sym, type, opts
208
+ define_attribute(name.to_sym, type, **opts)
210
209
  end
211
210
 
212
211
  # @api public
@@ -265,7 +264,7 @@ end
265
264
 
266
265
  # Load attribute type classes.
267
266
  #
268
- Dir[File.dirname(__FILE__) + '/attributes/*.rb'].sort.each do |path|
267
+ Dir[File.join(__dir__, 'attributes/*.rb')].sort.each do |path|
269
268
  filename = File.basename(path)
270
269
  require "acfs/resource/attributes/#{filename}"
271
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,11 +112,11 @@ 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))
119
+ .location(self.class, **opts, action: :read)
117
120
  .build(attributes).str
118
121
  end
119
122
 
@@ -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
@@ -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
@@ -214,7 +214,7 @@ class Acfs::Resource
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
@@ -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
@@ -22,7 +22,7 @@ class Acfs::Resource
22
22
  end
23
23
  end
24
24
 
25
- def save!(*_)
25
+ def save!(**kwargs)
26
26
  unless valid?(new? ? :create : :save)
27
27
  raise ::Acfs::InvalidResource.new resource: self, errors: errors.to_a
28
28
  end
@@ -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
@@ -28,34 +28,26 @@ module Acfs
28
28
 
29
29
  # @api private
30
30
  #
31
- def initialize(options = {})
31
+ def initialize(**options)
32
32
  @options = options
33
33
  end
34
34
 
35
35
  # @api private
36
36
  # @return [Location]
37
37
  #
38
- def location(resource_class, opts = {})
39
- opts.reverse_merge! options
38
+ def location(resource_class, path: nil, action: :list, **)
39
+ path ||= options[:path]
40
40
 
41
- action = opts[:action] || :list
41
+ if path.is_a?(Hash) && path.key?(action)
42
+ path = path.fetch(action)
43
+ else
44
+ path = path.is_a?(Hash) ? path[:all].to_s : path.to_s
42
45
 
43
- path = begin
44
- if opts[:path].is_a?(Hash) && opts[:path].key?(action)
45
- opts[:path].fetch(action)
46
- else
47
- path = if opts[:path].is_a?(Hash)
48
- opts[:path][:all].to_s
49
- else
50
- opts[:path].to_s
51
- end
52
-
53
- if path.blank?
54
- path = (resource_class.name || 'class').pluralize.underscore
55
- end
56
-
57
- resource_class.location_default_path(action, path.strip)
46
+ if path.blank?
47
+ path = (resource_class.name || 'class').pluralize.underscore
58
48
  end
49
+
50
+ path = resource_class.location_default_path(action, path.strip)
59
51
  end
60
52
 
61
53
  if path.nil?
@@ -27,10 +27,10 @@ module Acfs
27
27
  # @return [undefined]
28
28
  # @see #delete
29
29
  #
30
- def delete!(opts = {})
30
+ def delete!(**opts)
31
31
  opts[:params] ||= {}
32
32
 
33
- operation :delete, opts do |data|
33
+ operation(:delete, **opts) do |data|
34
34
  update_with data
35
35
  freeze
36
36
  end
@@ -22,7 +22,7 @@ module Acfs
22
22
  end
23
23
 
24
24
  def accept?(op)
25
- return opts[:with].call op if opts[:with].respond_to? :call
25
+ return opts[:with].call(op) if opts[:with].respond_to?(:call)
26
26
 
27
27
  params = op.full_params.stringify_keys
28
28
  data = op.data.stringify_keys
@@ -84,9 +84,13 @@ module Acfs
84
84
  def raise_error(op, name, data)
85
85
  raise name if name.is_a? Class
86
86
 
87
- data.stringify_keys! if data.respond_to? :stringify_keys!
87
+ data.stringify_keys! if data.respond_to?(:stringify_keys!)
88
88
 
89
- op.handle_failure ::Acfs::Response.new op.request, status: Rack::Utils.status_code(name), data: data
89
+ op.handle_failure ::Acfs::Response.new(
90
+ op.request,
91
+ status: Rack::Utils.status_code(name),
92
+ data: data
93
+ )
90
94
  end
91
95
 
92
96
  class << self
@@ -154,12 +158,14 @@ module Acfs
154
158
  unless stub
155
159
  return false if allow_requests?
156
160
 
157
- raise RealRequestsNotAllowedError.new <<-MSG.strip.gsub(/^[ ]{12}/, '')
158
- No stub found for `#{op.action}' on `#{op.resource.name}' with params `#{op.full_params.inspect}', data `#{op.data.inspect}' and id `#{op.id}'.
161
+ raise RealRequestsNotAllowedError.new <<~ERROR
162
+ No stub found for `#{op.action}' on `#{op.resource.name}' \
163
+ with params `#{op.full_params.inspect}', data `#{op.data.inspect}' \
164
+ and id `#{op.id}'.
159
165
 
160
166
  Available stubs:
161
167
  #{pretty_print}
162
- MSG
168
+ ERROR
163
169
  end
164
170
 
165
171
  stub.call op
@@ -3,8 +3,8 @@
3
3
  module Acfs
4
4
  module VERSION
5
5
  MAJOR = 1
6
- MINOR = 5
7
- PATCH = 1
6
+ MINOR = 6
7
+ PATCH = 0
8
8
  STAGE = nil
9
9
 
10
10
  STRING = [MAJOR, MINOR, PATCH, STAGE].reject(&:nil?).join('.')
@@ -19,7 +19,7 @@ describe Acfs::Adapter::Typhoeus do
19
19
  adapter.queue request1
20
20
  adapter.queue request2
21
21
 
22
- expect { adapter.start }.to raise_error(/404\-[12]/)
22
+ expect { adapter.start }.to raise_error(/404-[12]/)
23
23
  expect { adapter.start }.to_not raise_error
24
24
  end
25
25
 
@@ -5,7 +5,7 @@ require 'spec_helper'
5
5
  describe ::Acfs::Location do
6
6
  let(:location) { described_class.new(uri, args) }
7
7
  let(:uri) { 'http://localhost/users/:id' }
8
- let(:args) { {id: 4} }
8
+ let(:args) { {'id' => 4} }
9
9
 
10
10
  describe '#str' do
11
11
  subject(:str) { location.str }
@@ -15,7 +15,7 @@ describe ::Acfs::Location do
15
15
  end
16
16
 
17
17
  context 'with special characters' do
18
- let(:args) { {id: '4 [@(\/!^$'} }
18
+ let(:args) { {'id' => '4 [@(\/!^$'} }
19
19
 
20
20
  it 'escapes special characters' do
21
21
  expect(str).to eq 'http://localhost/users/4+%5B%40%28%5C%2F%21%5E%24'
@@ -9,7 +9,7 @@ describe Acfs::Request do
9
9
  let(:data) { nil }
10
10
  let(:method) { :get }
11
11
  let(:options) { {method: method, headers: headers, params: params, data: data} }
12
- let(:request) { Acfs::Request.new(url, options) }
12
+ let(:request) { Acfs::Request.new(url, **options) }
13
13
 
14
14
  describe '#url' do
15
15
  it 'should return request URL' do
@@ -48,10 +48,10 @@ describe Acfs::Resource::Attributes do
48
48
  write_attribute :name, "The Great #{name}"
49
49
  end
50
50
  end
51
- let(:args) { [params] }
52
51
  let(:params) { {name: 'James'} }
52
+ let(:opts) { {} }
53
53
  let(:m) { model.new }
54
- let(:action) { -> { m.write_attributes(*args) } }
54
+ let(:action) { -> { m.write_attributes(params, **opts) } }
55
55
  subject { action }
56
56
 
57
57
  it 'should update attributes' do
@@ -79,7 +79,7 @@ describe Acfs::Resource::Attributes do
79
79
  end
80
80
 
81
81
  context 'with unknown: :raise option' do
82
- let(:args) { [params, {unknown: :raise}] }
82
+ let(:opts) { {unknown: :raise} }
83
83
 
84
84
  it { should raise_error(ArgumentError, /unknown attribute/i) }
85
85
 
@@ -101,12 +101,12 @@ describe Acfs::Resource::Persistence do
101
101
  let!(:model) { model_class.find 1 }
102
102
 
103
103
  describe '#update_attributes' do
104
- subject { -> { model.update_attributes name: 'John' } }
104
+ subject { -> { model.update_attributes({name: 'John'}) } }
105
105
  it { expect { subject.call }.to raise_error Acfs::ResourceNotLoaded }
106
106
  end
107
107
 
108
108
  describe '#update_attributes!' do
109
- subject { -> { model.update_attributes! name: 'John' } }
109
+ subject { -> { model.update_attributes!({name: 'John'}) } }
110
110
  it { expect { subject.call }.to raise_error Acfs::ResourceNotLoaded }
111
111
  end
112
112
  end
@@ -179,18 +179,18 @@ describe Acfs::Resource::Persistence do
179
179
  before { model; Acfs.run }
180
180
 
181
181
  it 'should set attributes' do
182
- model.update_attributes name: 'Idefix'
182
+ model.update_attributes({name: 'Idefix'})
183
183
  expect(model.attributes.symbolize_keys).to eq id: 1, name: 'Idefix', age: 12
184
184
  end
185
185
 
186
186
  it 'should save resource' do
187
- expect(model.__getobj__).to receive(:save).with({})
188
- model.update_attributes name: 'Idefix'
187
+ expect(model.__getobj__).to receive(:save)
188
+ model.update_attributes({name: 'Idefix'})
189
189
  end
190
190
 
191
- it 'should pass second hash to save' do
191
+ it 'should kwargs to save' do
192
192
  expect(model.__getobj__).to receive(:save).with(bla: 'blub')
193
- model.update_attributes({name: 'Idefix'}, {bla: 'blub'})
193
+ model.update_attributes({name: 'Idefix'}, bla: 'blub')
194
194
  end
195
195
  end
196
196
 
@@ -199,18 +199,18 @@ describe Acfs::Resource::Persistence do
199
199
  before { model; Acfs.run }
200
200
 
201
201
  it 'should set attributes' do
202
- model.update_attributes! name: 'Idefix'
202
+ model.update_attributes!({name: 'Idefix'})
203
203
  expect(model.attributes.symbolize_keys).to eq id: 1, name: 'Idefix', age: 12
204
204
  end
205
205
 
206
206
  it 'should save resource' do
207
- expect(model.__getobj__).to receive(:save!).with({})
208
- model.update_attributes! name: 'Idefix'
207
+ expect(model.__getobj__).to receive(:save!)
208
+ model.update_attributes!({name: 'Idefix'})
209
209
  end
210
210
 
211
211
  it 'should pass second hash to save' do
212
212
  expect(model.__getobj__).to receive(:save!).with(bla: 'blub')
213
- model.update_attributes!({name: 'Idefix'}, {bla: 'blub'})
213
+ model.update_attributes!({name: 'Idefix'}, bla: 'blub')
214
214
  end
215
215
  end
216
216
  end
@@ -5,7 +5,7 @@ require 'spec_helper'
5
5
  describe Acfs::Service do
6
6
  let(:srv_class) { Class.new(Acfs::Service) { identity :test } }
7
7
  let(:options) { {} }
8
- let(:service) { srv_class.new options }
8
+ let(:service) { srv_class.new(**options) }
9
9
 
10
10
  before do
11
11
  Acfs::Configuration.current.locate :test, ''
@@ -191,7 +191,7 @@ describe 'Acfs' do
191
191
  it 'should load associated resources from different service' do
192
192
  @user = MyUser.find 2 do |user|
193
193
  expect(user.id).to be == 2
194
- @comments = Comment.where user: user.id
194
+ @comments = Comment.where({user: user.id})
195
195
  end
196
196
 
197
197
  Acfs.run
@@ -17,7 +17,6 @@ require 'bundler'
17
17
  Bundler.require(:default, :test)
18
18
 
19
19
  require 'acfs'
20
- require 'webmock/rspec'
21
20
 
22
21
  Dir[File.expand_path('spec/support/**/*.rb')].sort.each {|f| require f }
23
22
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: acfs
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.1
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jan Graichen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-12-31 00:00:00.000000000 Z
11
+ date: 2021-01-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionpack
@@ -221,14 +221,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
221
221
  requirements:
222
222
  - - ">="
223
223
  - !ruby/object:Gem::Version
224
- version: '0'
224
+ version: 2.5.0
225
225
  required_rubygems_version: !ruby/object:Gem::Requirement
226
226
  requirements:
227
227
  - - ">="
228
228
  - !ruby/object:Gem::Version
229
229
  version: '0'
230
230
  requirements: []
231
- rubygems_version: 3.2.3
231
+ rubygems_version: 3.2.4
232
232
  signing_key:
233
233
  specification_version: 4
234
234
  summary: An abstract API base client for service oriented application.