acfs 1.0.0.dev.1.b305 → 1.0.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 +5 -13
- data/CHANGELOG.md +64 -0
- data/README.md +2 -2
- data/acfs.gemspec +4 -4
- data/lib/acfs.rb +7 -5
- data/lib/acfs/adapter/base.rb +0 -2
- data/lib/acfs/adapter/typhoeus.rb +17 -13
- data/lib/acfs/collections/paginatable.rb +10 -10
- data/lib/acfs/configuration.rb +4 -5
- data/lib/acfs/errors.rb +10 -9
- data/lib/acfs/global.rb +16 -7
- data/lib/acfs/location.rb +11 -11
- data/lib/acfs/middleware/base.rb +1 -2
- data/lib/acfs/middleware/json.rb +27 -0
- data/lib/acfs/middleware/logger.rb +0 -2
- data/lib/acfs/middleware/msgpack.rb +30 -0
- data/lib/acfs/middleware/print.rb +0 -2
- data/lib/acfs/middleware/serializer.rb +39 -0
- data/lib/acfs/operation.rb +5 -5
- data/lib/acfs/request.rb +4 -4
- data/lib/acfs/request/callbacks.rb +2 -3
- data/lib/acfs/resource.rb +2 -2
- data/lib/acfs/resource/attributes.rb +10 -37
- data/lib/acfs/resource/attributes/base.rb +10 -19
- data/lib/acfs/resource/attributes/boolean.rb +10 -8
- data/lib/acfs/resource/attributes/date_time.rb +6 -9
- data/lib/acfs/resource/attributes/dict.rb +37 -0
- data/lib/acfs/resource/attributes/float.rb +11 -5
- data/lib/acfs/resource/attributes/integer.rb +7 -5
- data/lib/acfs/resource/attributes/list.rb +13 -6
- data/lib/acfs/resource/attributes/string.rb +3 -5
- data/lib/acfs/resource/attributes/uuid.rb +8 -17
- data/lib/acfs/resource/loadable.rb +0 -1
- data/lib/acfs/resource/locatable.rb +0 -4
- data/lib/acfs/resource/operational.rb +0 -2
- data/lib/acfs/resource/persistence.rb +17 -17
- data/lib/acfs/resource/query_methods.rb +3 -5
- data/lib/acfs/resource/service.rb +0 -2
- data/lib/acfs/resource/validation.rb +0 -2
- data/lib/acfs/response.rb +1 -2
- data/lib/acfs/response/formats.rb +1 -2
- data/lib/acfs/response/status.rb +3 -5
- data/lib/acfs/runner.rb +21 -11
- data/lib/acfs/service.rb +4 -6
- data/lib/acfs/service/middleware.rb +20 -30
- data/lib/acfs/service/middleware/stack.rb +63 -0
- data/lib/acfs/singleton_resource.rb +0 -2
- data/lib/acfs/stub.rb +30 -21
- data/lib/acfs/util.rb +1 -1
- data/lib/acfs/version.rb +4 -2
- data/spec/acfs/adapter/typhoeus_spec.rb +12 -4
- data/spec/acfs/collection_spec.rb +45 -33
- data/spec/acfs/configuration_spec.rb +9 -1
- data/spec/acfs/global_spec.rb +21 -3
- data/spec/acfs/middleware/json_spec.rb +63 -0
- data/spec/acfs/middleware/msgpack_spec.rb +60 -0
- data/spec/acfs/operation_spec.rb +10 -0
- data/spec/acfs/request/callbacks_spec.rb +8 -8
- data/spec/acfs/request_spec.rb +5 -5
- data/spec/acfs/resource/attributes/boolean_spec.rb +40 -9
- data/spec/acfs/resource/attributes/date_time_spec.rb +29 -35
- data/spec/acfs/resource/attributes/dict_spec.rb +75 -0
- data/spec/acfs/resource/attributes/float_spec.rb +48 -9
- data/spec/acfs/resource/attributes/integer_spec.rb +34 -0
- data/spec/acfs/resource/attributes/list_spec.rb +43 -19
- data/spec/acfs/resource/attributes/uuid_spec.rb +31 -54
- data/spec/acfs/resource/attributes_spec.rb +17 -31
- data/spec/acfs/resource/locatable_spec.rb +2 -2
- data/spec/acfs/resource/persistance_spec.rb +65 -34
- data/spec/acfs/resource/query_methods_spec.rb +87 -87
- data/spec/acfs/resource/validation_spec.rb +4 -5
- data/spec/acfs/response/formats_spec.rb +1 -1
- data/spec/acfs/response/status_spec.rb +1 -1
- data/spec/acfs/runner_spec.rb +28 -3
- data/spec/acfs/service/middleware_spec.rb +4 -20
- data/spec/acfs/service_spec.rb +3 -5
- data/spec/acfs/singleton_resource_spec.rb +1 -2
- data/spec/acfs/stub_spec.rb +137 -22
- data/spec/acfs_spec.rb +22 -19
- data/spec/spec_helper.rb +2 -1
- data/spec/support/service.rb +10 -6
- data/spec/support/shared/find_callbacks.rb +7 -7
- metadata +37 -30
- data/lib/acfs/middleware/json_decoder.rb +0 -16
- data/lib/acfs/middleware/json_encoder.rb +0 -20
- data/lib/acfs/middleware/msgpack_decoder.rb +0 -26
- data/lib/acfs/middleware/msgpack_encoder.rb +0 -19
- data/spec/acfs/middleware/json_decoder_spec.rb +0 -45
- data/spec/acfs/middleware/msgpack_decoder_spec.rb +0 -36
@@ -1,5 +1,4 @@
|
|
1
1
|
module Acfs::Resource::Attributes
|
2
|
-
|
3
2
|
# @api public
|
4
3
|
#
|
5
4
|
# Float attribute type. Use it in your model as an attribute type:
|
@@ -10,16 +9,23 @@ module Acfs::Resource::Attributes
|
|
10
9
|
# end
|
11
10
|
#
|
12
11
|
class Float < Base
|
13
|
-
|
14
12
|
# @api public
|
15
13
|
#
|
16
14
|
# Cast given object to float.
|
17
15
|
#
|
18
|
-
# @param [Object]
|
16
|
+
# @param [Object] value Object to cast.
|
19
17
|
# @return [Float] Casted object as float.
|
20
18
|
#
|
21
|
-
def
|
22
|
-
|
19
|
+
def cast_value(value)
|
20
|
+
return 0.0 if value.blank?
|
21
|
+
|
22
|
+
case value
|
23
|
+
when ::Float then value
|
24
|
+
when "Infinity" then ::Float::INFINITY
|
25
|
+
when "-Infinity" then -::Float::INFINITY
|
26
|
+
when "NaN" then ::Float::NAN
|
27
|
+
else Float(value)
|
28
|
+
end
|
23
29
|
end
|
24
30
|
end
|
25
31
|
end
|
@@ -1,5 +1,4 @@
|
|
1
1
|
module Acfs::Resource::Attributes
|
2
|
-
|
3
2
|
# @api public
|
4
3
|
#
|
5
4
|
# Integer attribute type. Use it in your model as an attribute type:
|
@@ -10,16 +9,19 @@ module Acfs::Resource::Attributes
|
|
10
9
|
# end
|
11
10
|
#
|
12
11
|
class Integer < Base
|
13
|
-
|
14
12
|
# @api public
|
15
13
|
#
|
16
14
|
# Cast given object to integer.
|
17
15
|
#
|
18
|
-
# @param [Object]
|
16
|
+
# @param [Object] value Object to cast.
|
19
17
|
# @return [Fixnum] Casted object as fixnum.
|
20
18
|
#
|
21
|
-
def
|
22
|
-
|
19
|
+
def cast_value(value)
|
20
|
+
if value.blank?
|
21
|
+
0
|
22
|
+
else
|
23
|
+
Integer(value)
|
24
|
+
end
|
23
25
|
end
|
24
26
|
end
|
25
27
|
end
|
@@ -1,5 +1,4 @@
|
|
1
1
|
module Acfs::Resource::Attributes
|
2
|
-
|
3
2
|
# @api public
|
4
3
|
#
|
5
4
|
# List attribute type. Use it in your model as an attribute type:
|
@@ -10,18 +9,26 @@ module Acfs::Resource::Attributes
|
|
10
9
|
# end
|
11
10
|
#
|
12
11
|
class List < Base
|
13
|
-
|
14
12
|
# @api public
|
15
13
|
#
|
16
14
|
# Cast given object to a list.
|
17
15
|
#
|
18
|
-
# @param [Object]
|
16
|
+
# @param [Object] value Object to cast.
|
19
17
|
# @return [Fixnum] Casted object as list.
|
20
18
|
# @raise [TypeError] If object cannot be casted to a list.
|
21
19
|
#
|
22
|
-
def
|
23
|
-
return
|
24
|
-
|
20
|
+
def cast_value(value)
|
21
|
+
return [] if value.blank?
|
22
|
+
|
23
|
+
if value.is_a?(::Array)
|
24
|
+
value
|
25
|
+
elsif value.respond_to?(:to_ary)
|
26
|
+
value.to_ary
|
27
|
+
elsif value.respond_to?(:to_a)
|
28
|
+
value.to_a
|
29
|
+
else
|
30
|
+
Array(value)
|
31
|
+
end
|
25
32
|
end
|
26
33
|
end
|
27
34
|
end
|
@@ -1,5 +1,4 @@
|
|
1
1
|
module Acfs::Resource::Attributes
|
2
|
-
|
3
2
|
# @api public
|
4
3
|
#
|
5
4
|
# String attribute type. Use it in your model as
|
@@ -11,16 +10,15 @@ module Acfs::Resource::Attributes
|
|
11
10
|
# end
|
12
11
|
#
|
13
12
|
class String < Base
|
14
|
-
|
15
13
|
# @api public
|
16
14
|
#
|
17
15
|
# Cast given object to string.
|
18
16
|
#
|
19
|
-
# @param [Object]
|
17
|
+
# @param [Object] value Object to cast.
|
20
18
|
# @return [String] Casted string.
|
21
19
|
#
|
22
|
-
def
|
23
|
-
|
20
|
+
def cast_value(value)
|
21
|
+
value.to_s
|
24
22
|
end
|
25
23
|
end
|
26
24
|
end
|
@@ -1,5 +1,4 @@
|
|
1
1
|
module Acfs::Resource::Attributes
|
2
|
-
|
3
2
|
# @api public
|
4
3
|
#
|
5
4
|
# UUID attribute type. Use it in your model as an attribute type:
|
@@ -10,9 +9,8 @@ module Acfs::Resource::Attributes
|
|
10
9
|
# end
|
11
10
|
#
|
12
11
|
class UUID < Base
|
13
|
-
|
14
12
|
#
|
15
|
-
|
13
|
+
UUID_REGEXP = /[0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}/i
|
16
14
|
|
17
15
|
# @api public
|
18
16
|
#
|
@@ -30,23 +28,16 @@ module Acfs::Resource::Attributes
|
|
30
28
|
# | 4 | 4 |
|
31
29
|
# | 5 | 12 |
|
32
30
|
#
|
33
|
-
# @param [Object]
|
31
|
+
# @param [Object] value Object to cast.
|
34
32
|
# @return [String] Casted object as UUID.
|
35
33
|
#
|
36
|
-
def
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
def cast_string(str)
|
43
|
-
if nil_allowed? && str.blank?
|
44
|
-
return nil
|
45
|
-
elsif str =~ REGEXP
|
46
|
-
str
|
34
|
+
def cast_value(value)
|
35
|
+
if value.blank?
|
36
|
+
nil
|
37
|
+
elsif value.to_s =~ UUID_REGEXP
|
38
|
+
value
|
47
39
|
else
|
48
|
-
raise
|
49
|
-
"does not look like a UUID"
|
40
|
+
raise TypeError.new "Invalid UUID: `#{value.to_s}'"
|
50
41
|
end
|
51
42
|
end
|
52
43
|
end
|
@@ -1,5 +1,4 @@
|
|
1
1
|
class Acfs::Resource
|
2
|
-
|
3
2
|
# Provide methods for generation URLs for resources.
|
4
3
|
#
|
5
4
|
# @example
|
@@ -14,7 +13,6 @@ class Acfs::Resource
|
|
14
13
|
|
15
14
|
#
|
16
15
|
module ClassMethods
|
17
|
-
|
18
16
|
# @overload url(suffix)
|
19
17
|
# @deprecated
|
20
18
|
# Return URL for this class of resource. Given suffix
|
@@ -90,8 +88,6 @@ class Acfs::Resource
|
|
90
88
|
return path
|
91
89
|
when :read, :update, :delete
|
92
90
|
return "#{path}/:id"
|
93
|
-
else
|
94
|
-
nil
|
95
91
|
end
|
96
92
|
end
|
97
93
|
end
|
@@ -1,5 +1,4 @@
|
|
1
1
|
class Acfs::Resource
|
2
|
-
|
3
2
|
# @api private
|
4
3
|
#
|
5
4
|
# Provide methods for creating and processing CRUD operations and
|
@@ -14,7 +13,6 @@ class Acfs::Resource
|
|
14
13
|
|
15
14
|
#
|
16
15
|
module ClassMethods
|
17
|
-
|
18
16
|
# Invoke CRUD operation.
|
19
17
|
def operation(action, opts = {}, &block)
|
20
18
|
Acfs.runner.process ::Acfs::Operation.new self, action, opts, &block
|
@@ -8,8 +8,7 @@ class Acfs::Resource
|
|
8
8
|
# @api public
|
9
9
|
#
|
10
10
|
# Check if the model is persisted. A model is persisted if
|
11
|
-
# it is saved after being created
|
12
|
-
# since it was loaded.
|
11
|
+
# it is saved after being created
|
13
12
|
#
|
14
13
|
# @example Newly created resource:
|
15
14
|
# user = User.new name: "John"
|
@@ -21,15 +20,14 @@ class Acfs::Resource
|
|
21
20
|
# user2 = User.find 5
|
22
21
|
# user2.persisted? # => true
|
23
22
|
# user2.name = 'Amy'
|
24
|
-
# user2.persisted? # =>
|
23
|
+
# user2.persisted? # => true
|
25
24
|
# user2.save
|
26
25
|
# user2.persisted? # => true
|
27
26
|
#
|
28
|
-
# @return [Boolean] True if resource has
|
29
|
-
# is not newly created, false otherwise.
|
27
|
+
# @return [Boolean] True if resource has been saved
|
30
28
|
#
|
31
29
|
def persisted?
|
32
|
-
!new?
|
30
|
+
!new?
|
33
31
|
end
|
34
32
|
|
35
33
|
# @api public
|
@@ -174,7 +172,7 @@ class Acfs::Resource
|
|
174
172
|
#
|
175
173
|
def delete!(opts = {})
|
176
174
|
opts[:params] ||= {}
|
177
|
-
opts[:params].merge
|
175
|
+
opts[:params] = attributes_for_url(:delete).merge opts[:params]
|
178
176
|
|
179
177
|
operation :delete, opts do |data|
|
180
178
|
update_with data
|
@@ -182,9 +180,14 @@ class Acfs::Resource
|
|
182
180
|
end
|
183
181
|
end
|
184
182
|
|
185
|
-
|
186
|
-
module ClassMethods
|
183
|
+
private
|
187
184
|
|
185
|
+
def attributes_for_url(action)
|
186
|
+
arguments_for_url = self.class.location(action: action).arguments
|
187
|
+
attributes.slice(*arguments_for_url)
|
188
|
+
end
|
189
|
+
|
190
|
+
module ClassMethods
|
188
191
|
# @api public
|
189
192
|
#
|
190
193
|
# Create a new resource sending given data. If resource cannot be
|
@@ -208,10 +211,8 @@ class Acfs::Resource
|
|
208
211
|
# will be overridden with provided data hash.
|
209
212
|
# @see #create
|
210
213
|
#
|
211
|
-
def create!(data,
|
212
|
-
new(data).tap
|
213
|
-
model.save!
|
214
|
-
end
|
214
|
+
def create!(data, _opts = {})
|
215
|
+
new(data).tap(&:save!)
|
215
216
|
end
|
216
217
|
|
217
218
|
# @api public
|
@@ -234,7 +235,7 @@ class Acfs::Resource
|
|
234
235
|
# will be overridden with provided data hash.
|
235
236
|
# @see #create!
|
236
237
|
#
|
237
|
-
def create(data,
|
238
|
+
def create(data, _opts = {})
|
238
239
|
model = new data
|
239
240
|
model.save
|
240
241
|
model
|
@@ -249,9 +250,8 @@ class Acfs::Resource
|
|
249
250
|
end
|
250
251
|
|
251
252
|
def check_loaded!(opts = {})
|
252
|
-
|
253
|
-
|
254
|
-
end
|
253
|
+
return if loaded? || opts[:force]
|
254
|
+
raise ::Acfs::ResourceNotLoaded.new resource: self
|
255
255
|
end
|
256
256
|
end
|
257
257
|
end
|
@@ -1,5 +1,4 @@
|
|
1
1
|
class Acfs::Resource
|
2
|
-
|
3
2
|
# Methods providing the query interface for finding resouces.
|
4
3
|
#
|
5
4
|
# @example
|
@@ -17,7 +16,6 @@ class Acfs::Resource
|
|
17
16
|
|
18
17
|
#
|
19
18
|
module ClassMethods
|
20
|
-
|
21
19
|
# @api public
|
22
20
|
#
|
23
21
|
# @overload find(id, opts = {})
|
@@ -139,7 +137,7 @@ class Acfs::Resource
|
|
139
137
|
def find_by!(params, &block)
|
140
138
|
find_by params do |m|
|
141
139
|
if m.nil?
|
142
|
-
raise Acfs::ResourceNotFound.new message:
|
140
|
+
raise Acfs::ResourceNotFound.new message: 'Received erroneous ' \
|
143
141
|
"response: no `#{name}` with params #{params} found"
|
144
142
|
end
|
145
143
|
block.call m unless block.nil?
|
@@ -225,9 +223,9 @@ class Acfs::Resource
|
|
225
223
|
collection.__callbacks__ << block unless block.nil?
|
226
224
|
|
227
225
|
counter = 0
|
228
|
-
ids.
|
226
|
+
ids.each_with_index do |id, index|
|
229
227
|
find_single id, opts do |resource|
|
230
|
-
collection
|
228
|
+
collection[index] = resource
|
231
229
|
if (counter += 1) == ids.size
|
232
230
|
collection.loaded!
|
233
231
|
collection.__invoke__
|
data/lib/acfs/response.rb
CHANGED
@@ -3,7 +3,6 @@ require 'acfs/response/status'
|
|
3
3
|
require 'active_support/core_ext/module/delegation'
|
4
4
|
|
5
5
|
module Acfs
|
6
|
-
|
7
6
|
# This represents a response. In addition to an standard HTTP
|
8
7
|
# it has a field `data` for storing the encoded body.
|
9
8
|
#
|
@@ -14,7 +13,7 @@ module Acfs
|
|
14
13
|
include Response::Formats
|
15
14
|
include Response::Status
|
16
15
|
|
17
|
-
#delegate :status, :status_message, :success?, :modified?, :timed_out?,
|
16
|
+
# delegate :status, :status_message, :success?, :modified?, :timed_out?,
|
18
17
|
# :response_body, :response_headers, :response_code, :headers,
|
19
18
|
# to: :response
|
20
19
|
|
@@ -2,10 +2,8 @@ require 'action_dispatch'
|
|
2
2
|
|
3
3
|
module Acfs
|
4
4
|
class Response
|
5
|
-
|
6
5
|
# Quick accessors for format handling.
|
7
6
|
module Formats
|
8
|
-
|
9
7
|
def content_type
|
10
8
|
@content_type ||= read_content_type
|
11
9
|
end
|
@@ -15,6 +13,7 @@ module Acfs
|
|
15
13
|
end
|
16
14
|
|
17
15
|
private
|
16
|
+
|
18
17
|
def read_content_type
|
19
18
|
return 'text/plain' unless headers && headers['Content-Type']
|
20
19
|
|
data/lib/acfs/response/status.rb
CHANGED
@@ -1,19 +1,17 @@
|
|
1
1
|
module Acfs
|
2
2
|
class Response
|
3
|
-
|
4
3
|
# Method to fetch information about response status.
|
5
4
|
#
|
6
5
|
module Status
|
7
|
-
|
8
6
|
# Return response status code. Will return zero if
|
9
7
|
# request was not executed or failed on client side.
|
10
8
|
#
|
11
9
|
def status_code
|
12
10
|
return @status.to_i if defined? :@status
|
13
|
-
#return response.response_code unless response.nil?
|
14
|
-
#0
|
11
|
+
# return response.response_code unless response.nil?
|
12
|
+
# 0
|
15
13
|
end
|
16
|
-
|
14
|
+
alias_method :code, :status_code
|
17
15
|
|
18
16
|
# Return true if response was successful indicated by
|
19
17
|
# response status code.
|
data/lib/acfs/runner.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'acfs/service/middleware'
|
2
2
|
|
3
3
|
module Acfs
|
4
|
-
|
5
4
|
# @api private
|
6
5
|
#
|
7
6
|
class Runner
|
@@ -17,6 +16,7 @@ module Acfs
|
|
17
16
|
# and parallel operations will be queued.
|
18
17
|
#
|
19
18
|
def process(op)
|
19
|
+
::ActiveSupport::Notifications.instrument 'acfs.operation.before_process', operation: op
|
20
20
|
op.synchronous? ? run(op) : enqueue(op)
|
21
21
|
end
|
22
22
|
|
@@ -24,7 +24,7 @@ module Acfs
|
|
24
24
|
#
|
25
25
|
def run(op)
|
26
26
|
::ActiveSupport::Notifications.instrument 'acfs.runner.sync_run', operation: op do
|
27
|
-
op_request(op) {
|
27
|
+
op_request(op) {|req| adapter.run req }
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
@@ -39,7 +39,7 @@ module Acfs
|
|
39
39
|
def enqueue(op)
|
40
40
|
::ActiveSupport::Notifications.instrument 'acfs.runner.enqueue', operation: op do
|
41
41
|
if running?
|
42
|
-
op_request(op) {
|
42
|
+
op_request(op) {|req| adapter.queue req }
|
43
43
|
else
|
44
44
|
queue << op
|
45
45
|
end
|
@@ -55,15 +55,13 @@ module Acfs
|
|
55
55
|
# Start processing queued operations.
|
56
56
|
#
|
57
57
|
def start
|
58
|
-
|
58
|
+
return if running?
|
59
59
|
|
60
|
-
|
61
|
-
|
60
|
+
enqueue_operations
|
61
|
+
start_all
|
62
62
|
rescue
|
63
63
|
queue.clear
|
64
64
|
raise
|
65
|
-
ensure
|
66
|
-
@running = false
|
67
65
|
end
|
68
66
|
|
69
67
|
def clear
|
@@ -73,15 +71,27 @@ module Acfs
|
|
73
71
|
end
|
74
72
|
|
75
73
|
private
|
74
|
+
|
75
|
+
def start_all
|
76
|
+
@running = true
|
77
|
+
adapter.start
|
78
|
+
ensure
|
79
|
+
@running = false
|
80
|
+
end
|
81
|
+
|
76
82
|
def enqueue_operations
|
77
83
|
while (op = queue.shift)
|
78
|
-
op_request(op) {
|
84
|
+
op_request(op) {|req| adapter.queue req }
|
79
85
|
end
|
80
86
|
end
|
81
87
|
|
82
88
|
def op_request(op)
|
83
|
-
return if Acfs::Stub.enabled?
|
84
|
-
|
89
|
+
return if Acfs::Stub.enabled? && Acfs::Stub.stubbed(op)
|
90
|
+
req = op.service.prepare op.request
|
91
|
+
return unless req.is_a? Acfs::Request
|
92
|
+
req = prepare req
|
93
|
+
return unless req.is_a? Acfs::Request
|
94
|
+
yield req
|
85
95
|
end
|
86
96
|
end
|
87
97
|
end
|