acfs 1.3.1 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +41 -1
  3. data/README.md +10 -25
  4. data/acfs.gemspec +20 -15
  5. data/lib/acfs.rb +2 -0
  6. data/lib/acfs/adapter/base.rb +6 -8
  7. data/lib/acfs/adapter/typhoeus.rb +25 -6
  8. data/lib/acfs/collection.rb +2 -1
  9. data/lib/acfs/collections/paginatable.rb +4 -3
  10. data/lib/acfs/configuration.rb +14 -7
  11. data/lib/acfs/errors.rb +60 -19
  12. data/lib/acfs/global.rb +12 -2
  13. data/lib/acfs/location.rb +9 -5
  14. data/lib/acfs/middleware/base.rb +5 -1
  15. data/lib/acfs/middleware/json.rb +5 -3
  16. data/lib/acfs/middleware/logger.rb +2 -0
  17. data/lib/acfs/middleware/msgpack.rb +2 -0
  18. data/lib/acfs/middleware/print.rb +2 -0
  19. data/lib/acfs/middleware/serializer.rb +2 -0
  20. data/lib/acfs/operation.rb +20 -3
  21. data/lib/acfs/request.rb +5 -1
  22. data/lib/acfs/request/callbacks.rb +5 -1
  23. data/lib/acfs/resource.rb +2 -0
  24. data/lib/acfs/resource/attributes.rb +5 -2
  25. data/lib/acfs/resource/attributes/base.rb +2 -1
  26. data/lib/acfs/resource/attributes/boolean.rb +2 -0
  27. data/lib/acfs/resource/attributes/date_time.rb +2 -1
  28. data/lib/acfs/resource/attributes/dict.rb +2 -0
  29. data/lib/acfs/resource/attributes/float.rb +5 -3
  30. data/lib/acfs/resource/attributes/integer.rb +2 -0
  31. data/lib/acfs/resource/attributes/list.rb +2 -0
  32. data/lib/acfs/resource/attributes/string.rb +2 -0
  33. data/lib/acfs/resource/attributes/uuid.rb +4 -3
  34. data/lib/acfs/resource/dirty.rb +2 -0
  35. data/lib/acfs/resource/initialization.rb +2 -0
  36. data/lib/acfs/resource/loadable.rb +2 -0
  37. data/lib/acfs/resource/locatable.rb +10 -6
  38. data/lib/acfs/resource/operational.rb +2 -1
  39. data/lib/acfs/resource/persistence.rb +7 -6
  40. data/lib/acfs/resource/query_methods.rb +6 -4
  41. data/lib/acfs/resource/service.rb +3 -1
  42. data/lib/acfs/resource/validation.rb +3 -1
  43. data/lib/acfs/response.rb +2 -0
  44. data/lib/acfs/response/formats.rb +2 -0
  45. data/lib/acfs/response/status.rb +3 -1
  46. data/lib/acfs/rspec.rb +2 -0
  47. data/lib/acfs/runner.rb +6 -1
  48. data/lib/acfs/service.rb +24 -13
  49. data/lib/acfs/service/middleware.rb +2 -0
  50. data/lib/acfs/service/middleware/stack.rb +5 -3
  51. data/lib/acfs/singleton_resource.rb +4 -2
  52. data/lib/acfs/stub.rb +32 -11
  53. data/lib/acfs/util.rb +2 -0
  54. data/lib/acfs/version.rb +4 -2
  55. data/lib/acfs/yard.rb +1 -0
  56. data/spec/acfs/adapter/typhoeus_spec.rb +30 -3
  57. data/spec/acfs/collection_spec.rb +7 -5
  58. data/spec/acfs/configuration_spec.rb +2 -0
  59. data/spec/acfs/global_spec.rb +50 -3
  60. data/spec/acfs/location_spec.rb +2 -0
  61. data/spec/acfs/middleware/json_spec.rb +3 -1
  62. data/spec/acfs/middleware/msgpack_spec.rb +2 -0
  63. data/spec/acfs/operation_spec.rb +2 -0
  64. data/spec/acfs/request/callbacks_spec.rb +2 -0
  65. data/spec/acfs/request_spec.rb +3 -1
  66. data/spec/acfs/resource/attributes/boolean_spec.rb +2 -0
  67. data/spec/acfs/resource/attributes/date_time_spec.rb +2 -0
  68. data/spec/acfs/resource/attributes/dict_spec.rb +4 -2
  69. data/spec/acfs/resource/attributes/float_spec.rb +3 -1
  70. data/spec/acfs/resource/attributes/integer_spec.rb +2 -0
  71. data/spec/acfs/resource/attributes/list_spec.rb +5 -3
  72. data/spec/acfs/resource/attributes/uuid_spec.rb +2 -0
  73. data/spec/acfs/resource/attributes_spec.rb +8 -8
  74. data/spec/acfs/resource/dirty_spec.rb +2 -0
  75. data/spec/acfs/resource/initialization_spec.rb +8 -2
  76. data/spec/acfs/resource/loadable_spec.rb +2 -0
  77. data/spec/acfs/resource/locatable_spec.rb +2 -0
  78. data/spec/acfs/resource/persistance_spec.rb +10 -4
  79. data/spec/acfs/resource/query_methods_spec.rb +24 -17
  80. data/spec/acfs/resource/validation_spec.rb +2 -0
  81. data/spec/acfs/response/formats_spec.rb +3 -1
  82. data/spec/acfs/response/status_spec.rb +2 -0
  83. data/spec/acfs/runner_spec.rb +6 -8
  84. data/spec/acfs/service/middleware_spec.rb +2 -0
  85. data/spec/acfs/service_spec.rb +3 -1
  86. data/spec/acfs/singleton_resource_spec.rb +2 -0
  87. data/spec/acfs/stub_spec.rb +2 -0
  88. data/spec/acfs_spec.rb +2 -0
  89. data/spec/spec_helper.rb +3 -1
  90. data/spec/support/hash.rb +2 -0
  91. data/spec/support/response.rb +2 -0
  92. data/spec/support/service.rb +1 -0
  93. data/spec/support/shared/find_callbacks.rb +2 -0
  94. metadata +13 -28
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Acfs::Resource
2
4
  # @api private
3
5
  #
@@ -11,7 +13,6 @@ class Acfs::Resource
11
13
  extend ActiveSupport::Concern
12
14
  delegate :operation, to: :'self.class'
13
15
 
14
- #
15
16
  module ClassMethods
16
17
  # Invoke CRUD operation.
17
18
  def operation(action, opts = {}, &block)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Acfs::Resource
2
4
  #
3
5
  # Allow to track the persistence state of a model.
@@ -40,7 +42,7 @@ class Acfs::Resource
40
42
  def new?
41
43
  !loaded?
42
44
  end
43
- alias_method :new_record?, :new?
45
+ alias new_record? new?
44
46
 
45
47
  # @api public
46
48
  #
@@ -86,9 +88,9 @@ class Acfs::Resource
86
88
  operation((new? ? :create : :update), opts) do |data|
87
89
  update_with data
88
90
  end
89
- rescue ::Acfs::InvalidResource => err
90
- self.remote_errors = err.errors
91
- raise err
91
+ rescue ::Acfs::InvalidResource => e
92
+ self.remote_errors = e.errors
93
+ raise e
92
94
  end
93
95
 
94
96
  # @api public
@@ -242,8 +244,6 @@ class Acfs::Resource
242
244
  end
243
245
  end
244
246
 
245
- private
246
-
247
247
  def update_with(data)
248
248
  self.attributes = data
249
249
  loaded!
@@ -251,6 +251,7 @@ class Acfs::Resource
251
251
 
252
252
  def check_loaded!(opts = {})
253
253
  return if loaded? || opts[:force]
254
+
254
255
  raise ::Acfs::ResourceNotLoaded.new resource: self
255
256
  end
256
257
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Acfs::Resource
2
4
  # Methods providing the query interface for finding resouces.
3
5
  #
@@ -14,7 +16,6 @@ class Acfs::Resource
14
16
  module QueryMethods
15
17
  extend ActiveSupport::Concern
16
18
 
17
- #
18
19
  module ClassMethods
19
20
  # @api public
20
21
  #
@@ -89,7 +90,7 @@ class Acfs::Resource
89
90
 
90
91
  collection
91
92
  end
92
- alias_method :where, :all
93
+ alias where all
93
94
 
94
95
  # @api public
95
96
  #
@@ -140,7 +141,7 @@ class Acfs::Resource
140
141
  raise Acfs::ResourceNotFound.new message: 'Received erroneous ' \
141
142
  "response: no `#{name}` with params #{params} found"
142
143
  end
143
- block.call m unless block.nil?
144
+ block&.call m
144
145
  end
145
146
  end
146
147
 
@@ -249,6 +250,7 @@ class Acfs::Resource
249
250
 
250
251
  def resource_class_lookup(type)
251
252
  return self if type.nil?
253
+
252
254
  klass = type.camelize.constantize
253
255
 
254
256
  unless klass <= self
@@ -256,7 +258,7 @@ class Acfs::Resource
256
258
  end
257
259
 
258
260
  klass
259
- rescue NameError, NoMethodError
261
+ rescue NameError
260
262
  raise Acfs::ResourceTypeError.new type_name: type, base_class: self
261
263
  end
262
264
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Acfs::Resource
2
4
  # Included by Acfs::Model. Allows to configure the service
3
5
  # a resource belongs to.
@@ -5,7 +7,6 @@ class Acfs::Resource
5
7
  module Service
6
8
  extend ActiveSupport::Concern
7
9
 
8
- #
9
10
  module ClassMethods
10
11
  # @api public
11
12
  #
@@ -35,6 +36,7 @@ class Acfs::Resource
35
36
  #
36
37
  def service(klass = nil, options = {})
37
38
  return (@service = klass.new options) if klass
39
+
38
40
  @service || superclass.service
39
41
  end
40
42
  end
@@ -1,5 +1,6 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Acfs::Resource
2
- #
3
4
  module Validation
4
5
  def valid?(*args)
5
6
  super
@@ -31,6 +32,7 @@ class Acfs::Resource
31
32
  unless valid?(new? ? :create : :save)
32
33
  raise ::Acfs::InvalidResource.new resource: self, errors: errors.to_a
33
34
  end
35
+
34
36
  super
35
37
  end
36
38
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'acfs/response/formats'
2
4
  require 'acfs/response/status'
3
5
  require 'active_support/core_ext/module/delegation'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'action_dispatch'
2
4
 
3
5
  module Acfs
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Acfs
2
4
  class Response
3
5
  # Method to fetch information about response status.
@@ -11,7 +13,7 @@ module Acfs
11
13
  # return response.response_code unless response.nil?
12
14
  # 0
13
15
  end
14
- alias_method :code, :status_code
16
+ alias code status_code
15
17
 
16
18
  # Return true if response was successful indicated by
17
19
  # response status code.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'acfs'
2
4
 
3
5
  RSpec.configure do |config|
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'acfs/service/middleware'
2
4
 
3
5
  module Acfs
@@ -59,7 +61,7 @@ module Acfs
59
61
 
60
62
  enqueue_operations
61
63
  start_all
62
- rescue
64
+ rescue StandardError
63
65
  queue.clear
64
66
  raise
65
67
  end
@@ -87,10 +89,13 @@ module Acfs
87
89
 
88
90
  def op_request(op)
89
91
  return if Acfs::Stub.enabled? && Acfs::Stub.stubbed(op)
92
+
90
93
  req = op.service.prepare op.request
91
94
  return unless req.is_a? Acfs::Request
95
+
92
96
  req = prepare req
93
97
  return unless req.is_a? Acfs::Request
98
+
94
99
  yield req
95
100
  end
96
101
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'acfs/service/middleware'
2
4
 
3
5
  module Acfs
@@ -38,21 +40,27 @@ module Acfs
38
40
 
39
41
  action = opts[:action] || :list
40
42
 
41
- path = if opts[:path].is_a?(Hash) && opts[:path].key?(action)
42
- opts[:path].fetch(action)
43
- else
44
- path = if opts[:path].is_a?(Hash)
45
- opts[:path][:all].to_s
46
- else
47
- opts[:path].to_s
48
- end
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
49
52
 
50
- path = (resource_class.name || 'class').pluralize.underscore if path.blank?
53
+ if path.blank?
54
+ path = (resource_class.name || 'class').pluralize.underscore
55
+ end
51
56
 
52
- resource_class.location_default_path(action, path.strip)
53
- end
57
+ resource_class.location_default_path(action, path.strip)
58
+ end
59
+ end
54
60
 
55
- raise ArgumentError.new "Location for `#{action}' explicit disabled by set to nil." if path.nil?
61
+ if path.nil?
62
+ raise ArgumentError.new "Location for `#{action}' explicit disabled by set to nil."
63
+ end
56
64
 
57
65
  Location.new [self.class.base_url.to_s, path.to_s].join('/')
58
66
  end
@@ -81,7 +89,10 @@ module Acfs
81
89
  #
82
90
  def base_url
83
91
  unless (base = Acfs::Configuration.current.locate identity)
84
- raise ArgumentError.new "#{identity} not configured. Add `locate '#{identity.to_s.underscore}', 'http://service.url/'` to your configuration."
92
+ raise ArgumentError.new \
93
+ "#{identity} not configured. Add `locate '" \
94
+ "#{identity.to_s.underscore}', 'http://service.url/'` " \
95
+ 'to your configuration.'
85
96
  end
86
97
 
87
98
  base.to_s
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'acfs/service/middleware/stack'
2
4
 
3
5
  module Acfs
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Acfs
2
4
  class Service
3
5
  module Middleware
@@ -5,7 +7,7 @@ module Acfs
5
7
  include Enumerable
6
8
 
7
9
  MUTEX = Mutex.new
8
- IDENTITY = -> (i) { i }
10
+ IDENTITY = ->(i) { i }
9
11
 
10
12
  attr_reader :middlewares
11
13
 
@@ -41,7 +43,7 @@ module Acfs
41
43
  next_middleware.call(klass.call(env, *args))
42
44
  end
43
45
  else
44
- fail "Invalid middleware, doesn't respond to `call`: #{klass.inspect}"
46
+ raise "Invalid middleware, doesn't respond to `call`: #{klass.inspect}"
45
47
  end
46
48
  end
47
49
  end
@@ -51,7 +53,7 @@ module Acfs
51
53
  end
52
54
 
53
55
  def each
54
- middlewares.each { |x| yield x.first }
56
+ middlewares.each {|x| yield x.first }
55
57
  end
56
58
 
57
59
  def clear
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Acfs
2
4
  # Acfs SingletonResources
3
5
  #
@@ -71,8 +73,8 @@ module Acfs
71
73
  def all
72
74
  raise ::Acfs::UnsupportedOperation.new
73
75
  end
74
- alias_method :find_by, :all
75
- alias_method :find_by!, :all
76
+ alias find_by all
77
+ alias find_by! all
76
78
 
77
79
  # @api private
78
80
  def location_default_path(_, path)
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rack/utils'
2
4
 
3
5
  module Acfs
4
6
  # Global handler for stubbing resources.
5
7
  #
6
8
  class Stub
7
- ACTIONS = [:read, :create, :update, :delete, :list]
9
+ ACTIONS = %i[read create update delete list].freeze
8
10
 
9
11
  attr_reader :opts
10
12
 
@@ -13,7 +15,10 @@ module Acfs
13
15
 
14
16
  @opts[:with].stringify_keys! if @opts[:with].is_a? Hash
15
17
  @opts[:return].stringify_keys! if @opts[:return].is_a? Hash
16
- @opts[:return].map! {|h| h.stringify_keys! if h.is_a? Hash } if @opts[:return].is_a? Array
18
+
19
+ if @opts[:return].is_a?(Array) # rubocop:disable Style/GuardClause
20
+ @opts[:return].map! {|h| h.stringify_keys! if h.is_a? Hash }
21
+ end
17
22
  end
18
23
 
19
24
  def accept?(op)
@@ -28,8 +33,13 @@ module Acfs
28
33
  case opts.fetch(:match, :inclusion)
29
34
  when :legacy
30
35
  return true if with.empty? && params.empty? && data.empty?
31
- return true if with.reject {|_, v| v.nil? } == params.reject {|_, v| v.nil? }
32
- return true if with.reject {|_, v| v.nil? } == data.reject {|_, v| v.nil? }
36
+ if with.reject {|_, v| v.nil? } == params.reject {|_, v| v.nil? }
37
+ return true
38
+ end
39
+ if with.reject {|_, v| v.nil? } == data.reject {|_, v| v.nil? }
40
+ return true
41
+ end
42
+
33
43
  false
34
44
  when :inclusion
35
45
  with.each_pair.all? do |k, v|
@@ -43,7 +53,8 @@ module Acfs
43
53
  end
44
54
 
45
55
  def called?(count = nil)
46
- count = count.count if count.respond_to? :count # For `5.times` Enumerators
56
+ count = count.count if count.respond_to?(:count)
57
+
47
58
  count.nil? ? calls.any? : calls.size == count
48
59
  end
49
60
 
@@ -60,8 +71,8 @@ module Acfs
60
71
 
61
72
  response = Acfs::Response.new op.request,
62
73
  headers: opts[:headers] || {},
63
- status: opts[:status] || 200,
64
- data: data || {}
74
+ status: opts[:status] || 200,
75
+ data: data || {}
65
76
  op.call data, response
66
77
  else
67
78
  raise ArgumentError.new 'Unsupported stub.'
@@ -72,6 +83,7 @@ module Acfs
72
83
 
73
84
  def raise_error(op, name, data)
74
85
  raise name if name.is_a? Class
86
+
75
87
  data.stringify_keys! if data.respond_to? :stringify_keys!
76
88
 
77
89
  op.handle_failure ::Acfs::Response.new op.request, status: Rack::Utils.status_code(name), data: data
@@ -83,7 +95,9 @@ module Acfs
83
95
  #
84
96
  def resource(klass, action, opts = {}, &_block)
85
97
  action = action.to_sym
86
- raise ArgumentError.new "Unknown action `#{action}`." unless ACTIONS.include? action
98
+ unless ACTIONS.include? action
99
+ raise ArgumentError.new "Unknown action `#{action}`."
100
+ end
87
101
 
88
102
  Stub.new(opts).tap do |stub|
89
103
  stubs[klass] ||= {}
@@ -128,7 +142,9 @@ module Acfs
128
142
 
129
143
  accepted_stubs = stubs.select {|stub| stub.accept? op }
130
144
 
131
- raise AmbiguousStubError.new stubs: accepted_stubs, operation: op if accepted_stubs.size > 1
145
+ if accepted_stubs.size > 1
146
+ raise AmbiguousStubError.new stubs: accepted_stubs, operation: op
147
+ end
132
148
 
133
149
  accepted_stubs.first
134
150
  end
@@ -137,6 +153,7 @@ module Acfs
137
153
  stub = stub_for op
138
154
  unless stub
139
155
  return false if allow_requests?
156
+
140
157
  raise RealRequestsNotAllowedError.new <<-MSG.strip.gsub(/^[ ]{12}/, '')
141
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}'.
142
159
 
@@ -159,8 +176,12 @@ module Acfs
159
176
  stubs.each do |stub|
160
177
  out << " #{action}"
161
178
  out << " with #{stub.opts[:with].inspect}" if stub.opts[:with]
162
- out << " and return #{stub.opts[:return].inspect}" if stub.opts[:return]
163
- out << " and raise #{stub.opts[:raise].inspect}" if stub.opts[:raise]
179
+ if stub.opts[:return]
180
+ out << " and return #{stub.opts[:return].inspect}"
181
+ end
182
+ if stub.opts[:raise]
183
+ out << " and raise #{stub.opts[:raise].inspect}"
184
+ end
164
185
  out << "\n"
165
186
  end
166
187
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Acfs
2
4
  module Util
3
5
  # TODO: Merge wit features in v1.0
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Acfs
2
4
  module VERSION
3
5
  MAJOR = 1
4
- MINOR = 3
5
- PATCH = 1
6
+ MINOR = 5
7
+ PATCH = 0
6
8
  STAGE = nil
7
9
 
8
10
  STRING = [MAJOR, MINOR, PATCH, STAGE].reject(&:nil?).join('.')