acfs 0.50.0 → 1.0.0.dev.1.b297
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +13 -5
- data/CHANGELOG.md +0 -80
- data/README.md +9 -8
- data/acfs.gemspec +7 -7
- data/lib/acfs.rb +5 -7
- data/lib/acfs/adapter/base.rb +2 -0
- data/lib/acfs/adapter/typhoeus.rb +13 -17
- data/lib/acfs/collections/paginatable.rb +10 -10
- data/lib/acfs/configuration.rb +5 -4
- data/lib/acfs/errors.rb +9 -10
- data/lib/acfs/global.rb +7 -16
- data/lib/acfs/location.rb +11 -11
- data/lib/acfs/middleware/base.rb +2 -1
- data/lib/acfs/middleware/json_decoder.rb +16 -0
- data/lib/acfs/middleware/json_encoder.rb +20 -0
- data/lib/acfs/middleware/logger.rb +2 -0
- data/lib/acfs/middleware/msgpack_decoder.rb +26 -0
- data/lib/acfs/middleware/msgpack_encoder.rb +19 -0
- data/lib/acfs/middleware/print.rb +2 -0
- data/lib/acfs/operation.rb +5 -5
- data/lib/acfs/request.rb +4 -4
- data/lib/acfs/request/callbacks.rb +3 -2
- data/lib/acfs/resource.rb +2 -2
- data/lib/acfs/resource/attributes.rb +38 -11
- data/lib/acfs/resource/attributes/base.rb +19 -10
- data/lib/acfs/resource/attributes/boolean.rb +8 -10
- data/lib/acfs/resource/attributes/date_time.rb +9 -6
- data/lib/acfs/resource/attributes/float.rb +5 -11
- data/lib/acfs/resource/attributes/integer.rb +5 -7
- data/lib/acfs/resource/attributes/list.rb +6 -13
- data/lib/acfs/resource/attributes/string.rb +5 -3
- data/lib/acfs/resource/attributes/uuid.rb +17 -8
- data/lib/acfs/resource/dirty.rb +15 -3
- data/lib/acfs/resource/loadable.rb +1 -0
- data/lib/acfs/resource/locatable.rb +4 -0
- data/lib/acfs/resource/operational.rb +2 -0
- data/lib/acfs/resource/persistence.rb +17 -17
- data/lib/acfs/resource/query_methods.rb +7 -8
- data/lib/acfs/resource/service.rb +2 -0
- data/lib/acfs/resource/validation.rb +4 -4
- data/lib/acfs/response.rb +2 -1
- data/lib/acfs/response/formats.rb +3 -2
- data/lib/acfs/response/status.rb +5 -3
- data/lib/acfs/runner.rb +11 -21
- data/lib/acfs/service.rb +6 -4
- data/lib/acfs/service/middleware.rb +30 -20
- data/lib/acfs/singleton_resource.rb +2 -0
- data/lib/acfs/stub.rb +21 -30
- data/lib/acfs/util.rb +1 -1
- data/lib/acfs/version.rb +4 -6
- data/spec/acfs/adapter/typhoeus_spec.rb +4 -12
- data/spec/acfs/collection_spec.rb +33 -45
- data/spec/acfs/configuration_spec.rb +1 -9
- data/spec/acfs/global_spec.rb +3 -21
- data/spec/acfs/middleware/json_decoder_spec.rb +45 -0
- data/spec/acfs/middleware/msgpack_decoder_spec.rb +36 -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 +9 -40
- data/spec/acfs/resource/attributes/date_time_spec.rb +35 -29
- data/spec/acfs/resource/attributes/float_spec.rb +9 -48
- data/spec/acfs/resource/attributes/list_spec.rb +19 -43
- data/spec/acfs/resource/attributes/uuid_spec.rb +54 -31
- data/spec/acfs/resource/attributes_spec.rb +31 -17
- data/spec/acfs/resource/locatable_spec.rb +2 -2
- data/spec/acfs/resource/persistance_spec.rb +34 -65
- data/spec/acfs/resource/query_methods_spec.rb +90 -97
- data/spec/acfs/resource/validation_spec.rb +5 -4
- data/spec/acfs/response/formats_spec.rb +4 -4
- data/spec/acfs/response/status_spec.rb +1 -1
- data/spec/acfs/runner_spec.rb +3 -28
- data/spec/acfs/service/middleware_spec.rb +20 -4
- data/spec/acfs/service_spec.rb +5 -3
- data/spec/acfs/singleton_resource_spec.rb +2 -1
- data/spec/acfs/stub_spec.rb +22 -137
- data/spec/acfs_spec.rb +19 -22
- data/spec/spec_helper.rb +2 -3
- data/spec/support/service.rb +6 -10
- data/spec/support/shared/find_callbacks.rb +7 -7
- metadata +36 -43
- data/lib/acfs/middleware/json.rb +0 -27
- data/lib/acfs/middleware/msgpack.rb +0 -30
- data/lib/acfs/middleware/serializer.rb +0 -39
- data/lib/acfs/resource/attributes/dict.rb +0 -37
- data/lib/acfs/service/middleware/stack.rb +0 -63
- data/spec/acfs/middleware/json_spec.rb +0 -63
- data/spec/acfs/middleware/msgpack_spec.rb +0 -60
- data/spec/acfs/operation_spec.rb +0 -10
- data/spec/acfs/resource/attributes/dict_spec.rb +0 -75
- data/spec/acfs/resource/attributes/integer_spec.rb +0 -34
@@ -1,4 +1,5 @@
|
|
1
1
|
module Acfs::Resource::Attributes
|
2
|
+
|
2
3
|
# @api public
|
3
4
|
#
|
4
5
|
# DateTime attribute type. Use it in your model as
|
@@ -15,16 +16,18 @@ module Acfs::Resource::Attributes
|
|
15
16
|
#
|
16
17
|
# Cast given object to DateTime.
|
17
18
|
#
|
18
|
-
# @param [Object]
|
19
|
+
# @param [Object] obj Object to cast.
|
19
20
|
# @return [DateTime] Casted object as DateTime.
|
20
21
|
#
|
21
|
-
def
|
22
|
-
if
|
22
|
+
def cast_type(obj)
|
23
|
+
if nil_allowed? && obj.blank?
|
23
24
|
nil
|
24
|
-
elsif
|
25
|
-
|
25
|
+
elsif obj.is_a? ::DateTime
|
26
|
+
obj
|
27
|
+
elsif obj.is_a?(Time) || obj.is_a?(Date)
|
28
|
+
::DateTime.iso8601 obj.iso8601
|
26
29
|
else
|
27
|
-
::DateTime.iso8601
|
30
|
+
::DateTime.iso8601 obj
|
28
31
|
end
|
29
32
|
end
|
30
33
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
module Acfs::Resource::Attributes
|
2
|
+
|
2
3
|
# @api public
|
3
4
|
#
|
4
5
|
# Float attribute type. Use it in your model as an attribute type:
|
@@ -9,23 +10,16 @@ module Acfs::Resource::Attributes
|
|
9
10
|
# end
|
10
11
|
#
|
11
12
|
class Float < Base
|
13
|
+
|
12
14
|
# @api public
|
13
15
|
#
|
14
16
|
# Cast given object to float.
|
15
17
|
#
|
16
|
-
# @param [Object]
|
18
|
+
# @param [Object] obj Object to cast.
|
17
19
|
# @return [Float] Casted object as float.
|
18
20
|
#
|
19
|
-
def
|
20
|
-
|
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
|
21
|
+
def cast_type(obj)
|
22
|
+
Float obj
|
29
23
|
end
|
30
24
|
end
|
31
25
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
module Acfs::Resource::Attributes
|
2
|
+
|
2
3
|
# @api public
|
3
4
|
#
|
4
5
|
# Integer attribute type. Use it in your model as an attribute type:
|
@@ -9,19 +10,16 @@ module Acfs::Resource::Attributes
|
|
9
10
|
# end
|
10
11
|
#
|
11
12
|
class Integer < Base
|
13
|
+
|
12
14
|
# @api public
|
13
15
|
#
|
14
16
|
# Cast given object to integer.
|
15
17
|
#
|
16
|
-
# @param [Object]
|
18
|
+
# @param [Object] obj Object to cast.
|
17
19
|
# @return [Fixnum] Casted object as fixnum.
|
18
20
|
#
|
19
|
-
def
|
20
|
-
|
21
|
-
0
|
22
|
-
else
|
23
|
-
Integer(value)
|
24
|
-
end
|
21
|
+
def cast_type(obj)
|
22
|
+
Integer obj
|
25
23
|
end
|
26
24
|
end
|
27
25
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
module Acfs::Resource::Attributes
|
2
|
+
|
2
3
|
# @api public
|
3
4
|
#
|
4
5
|
# List attribute type. Use it in your model as an attribute type:
|
@@ -9,26 +10,18 @@ module Acfs::Resource::Attributes
|
|
9
10
|
# end
|
10
11
|
#
|
11
12
|
class List < Base
|
13
|
+
|
12
14
|
# @api public
|
13
15
|
#
|
14
16
|
# Cast given object to a list.
|
15
17
|
#
|
16
|
-
# @param [Object]
|
18
|
+
# @param [Object] obj Object to cast.
|
17
19
|
# @return [Fixnum] Casted object as list.
|
18
20
|
# @raise [TypeError] If object cannot be casted to a list.
|
19
21
|
#
|
20
|
-
def
|
21
|
-
return
|
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
|
22
|
+
def cast_type(obj)
|
23
|
+
return obj.to_a if obj.respond_to? :to_a
|
24
|
+
raise TypeError.new "Cannot cast #{obj.inspect} to array."
|
32
25
|
end
|
33
26
|
end
|
34
27
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
module Acfs::Resource::Attributes
|
2
|
+
|
2
3
|
# @api public
|
3
4
|
#
|
4
5
|
# String attribute type. Use it in your model as
|
@@ -10,15 +11,16 @@ module Acfs::Resource::Attributes
|
|
10
11
|
# end
|
11
12
|
#
|
12
13
|
class String < Base
|
14
|
+
|
13
15
|
# @api public
|
14
16
|
#
|
15
17
|
# Cast given object to string.
|
16
18
|
#
|
17
|
-
# @param [Object]
|
19
|
+
# @param [Object] obj Object to cast.
|
18
20
|
# @return [String] Casted string.
|
19
21
|
#
|
20
|
-
def
|
21
|
-
|
22
|
+
def cast_type(obj)
|
23
|
+
obj.to_s
|
22
24
|
end
|
23
25
|
end
|
24
26
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
module Acfs::Resource::Attributes
|
2
|
+
|
2
3
|
# @api public
|
3
4
|
#
|
4
5
|
# UUID attribute type. Use it in your model as an attribute type:
|
@@ -9,8 +10,9 @@ module Acfs::Resource::Attributes
|
|
9
10
|
# end
|
10
11
|
#
|
11
12
|
class UUID < Base
|
13
|
+
|
12
14
|
#
|
13
|
-
|
15
|
+
REGEXP = /[0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}/i
|
14
16
|
|
15
17
|
# @api public
|
16
18
|
#
|
@@ -28,16 +30,23 @@ module Acfs::Resource::Attributes
|
|
28
30
|
# | 4 | 4 |
|
29
31
|
# | 5 | 12 |
|
30
32
|
#
|
31
|
-
# @param [Object]
|
33
|
+
# @param [Object] obj Object to cast.
|
32
34
|
# @return [String] Casted object as UUID.
|
33
35
|
#
|
34
|
-
def
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
36
|
+
def cast_type(obj)
|
37
|
+
cast_string obj.to_s
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def cast_string(str)
|
43
|
+
if nil_allowed? && str.blank?
|
44
|
+
return nil
|
45
|
+
elsif str =~ REGEXP
|
46
|
+
str
|
39
47
|
else
|
40
|
-
raise
|
48
|
+
raise ArgumentError.new "given String `#{str}` " \
|
49
|
+
"does not look like a UUID"
|
41
50
|
end
|
42
51
|
end
|
43
52
|
end
|
data/lib/acfs/resource/dirty.rb
CHANGED
@@ -8,14 +8,26 @@ class Acfs::Resource
|
|
8
8
|
|
9
9
|
# @api private
|
10
10
|
#
|
11
|
+
# Resets all changes. Does not touch previous changes.
|
12
|
+
#
|
11
13
|
def reset_changes
|
12
|
-
|
14
|
+
changed_attributes.clear
|
15
|
+
end
|
16
|
+
|
17
|
+
# @api private
|
18
|
+
#
|
19
|
+
# Save current changes as previous changes and reset
|
20
|
+
# current one.
|
21
|
+
#
|
22
|
+
def swap_changes
|
23
|
+
@previously_changed = changes
|
24
|
+
reset_changes
|
13
25
|
end
|
14
26
|
|
15
27
|
# @api private
|
16
28
|
#
|
17
29
|
def save!(*)
|
18
|
-
super.tap {|_|
|
30
|
+
super.tap {|_| swap_changes }
|
19
31
|
end
|
20
32
|
|
21
33
|
# @api private
|
@@ -28,7 +40,7 @@ class Acfs::Resource
|
|
28
40
|
# @api private
|
29
41
|
#
|
30
42
|
def write_raw_attribute(name, value, opts = {})
|
31
|
-
attribute_will_change!
|
43
|
+
attribute_will_change! name if opts[:change].nil? || opts[:change]
|
32
44
|
super
|
33
45
|
end
|
34
46
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
class Acfs::Resource
|
2
|
+
|
2
3
|
# Provide methods for generation URLs for resources.
|
3
4
|
#
|
4
5
|
# @example
|
@@ -13,6 +14,7 @@ class Acfs::Resource
|
|
13
14
|
|
14
15
|
#
|
15
16
|
module ClassMethods
|
17
|
+
|
16
18
|
# @overload url(suffix)
|
17
19
|
# @deprecated
|
18
20
|
# Return URL for this class of resource. Given suffix
|
@@ -88,6 +90,8 @@ class Acfs::Resource
|
|
88
90
|
return path
|
89
91
|
when :read, :update, :delete
|
90
92
|
return "#{path}/:id"
|
93
|
+
else
|
94
|
+
nil
|
91
95
|
end
|
92
96
|
end
|
93
97
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
class Acfs::Resource
|
2
|
+
|
2
3
|
# @api private
|
3
4
|
#
|
4
5
|
# Provide methods for creating and processing CRUD operations and
|
@@ -13,6 +14,7 @@ class Acfs::Resource
|
|
13
14
|
|
14
15
|
#
|
15
16
|
module ClassMethods
|
17
|
+
|
16
18
|
# Invoke CRUD operation.
|
17
19
|
def operation(action, opts = {}, &block)
|
18
20
|
Acfs.runner.process ::Acfs::Operation.new self, action, opts, &block
|
@@ -8,7 +8,8 @@ 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
|
11
|
+
# it is saved after being created or when it was not changed
|
12
|
+
# since it was loaded.
|
12
13
|
#
|
13
14
|
# @example Newly created resource:
|
14
15
|
# user = User.new name: "John"
|
@@ -20,14 +21,15 @@ class Acfs::Resource
|
|
20
21
|
# user2 = User.find 5
|
21
22
|
# user2.persisted? # => true
|
22
23
|
# user2.name = 'Amy'
|
23
|
-
# user2.persisted? # =>
|
24
|
+
# user2.persisted? # => false
|
24
25
|
# user2.save
|
25
26
|
# user2.persisted? # => true
|
26
27
|
#
|
27
|
-
# @return [Boolean] True if resource has
|
28
|
+
# @return [Boolean] True if resource has no changes and
|
29
|
+
# is not newly created, false otherwise.
|
28
30
|
#
|
29
31
|
def persisted?
|
30
|
-
!new?
|
32
|
+
!new? && !changed?
|
31
33
|
end
|
32
34
|
|
33
35
|
# @api public
|
@@ -172,7 +174,7 @@ class Acfs::Resource
|
|
172
174
|
#
|
173
175
|
def delete!(opts = {})
|
174
176
|
opts[:params] ||= {}
|
175
|
-
opts[:params]
|
177
|
+
opts[:params].merge! id: id
|
176
178
|
|
177
179
|
operation :delete, opts do |data|
|
178
180
|
update_with data
|
@@ -180,14 +182,9 @@ class Acfs::Resource
|
|
180
182
|
end
|
181
183
|
end
|
182
184
|
|
183
|
-
|
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
|
-
|
185
|
+
#
|
190
186
|
module ClassMethods
|
187
|
+
|
191
188
|
# @api public
|
192
189
|
#
|
193
190
|
# Create a new resource sending given data. If resource cannot be
|
@@ -211,8 +208,10 @@ class Acfs::Resource
|
|
211
208
|
# will be overridden with provided data hash.
|
212
209
|
# @see #create
|
213
210
|
#
|
214
|
-
def create!(data,
|
215
|
-
new(data).tap
|
211
|
+
def create!(data, opts = {})
|
212
|
+
new(data).tap do |model|
|
213
|
+
model.save!
|
214
|
+
end
|
216
215
|
end
|
217
216
|
|
218
217
|
# @api public
|
@@ -235,7 +234,7 @@ class Acfs::Resource
|
|
235
234
|
# will be overridden with provided data hash.
|
236
235
|
# @see #create!
|
237
236
|
#
|
238
|
-
def create(data,
|
237
|
+
def create(data, opts = {})
|
239
238
|
model = new data
|
240
239
|
model.save
|
241
240
|
model
|
@@ -250,8 +249,9 @@ class Acfs::Resource
|
|
250
249
|
end
|
251
250
|
|
252
251
|
def check_loaded!(opts = {})
|
253
|
-
|
254
|
-
|
252
|
+
unless loaded? || opts[:force]
|
253
|
+
raise ::Acfs::ResourceNotLoaded.new resource: self
|
254
|
+
end
|
255
255
|
end
|
256
256
|
end
|
257
257
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
class Acfs::Resource
|
2
|
+
|
2
3
|
# Methods providing the query interface for finding resouces.
|
3
4
|
#
|
4
5
|
# @example
|
@@ -16,6 +17,7 @@ class Acfs::Resource
|
|
16
17
|
|
17
18
|
#
|
18
19
|
module ClassMethods
|
20
|
+
|
19
21
|
# @api public
|
20
22
|
#
|
21
23
|
# @overload find(id, opts = {})
|
@@ -137,7 +139,7 @@ class Acfs::Resource
|
|
137
139
|
def find_by!(params, &block)
|
138
140
|
find_by params do |m|
|
139
141
|
if m.nil?
|
140
|
-
raise Acfs::ResourceNotFound.new message:
|
142
|
+
raise Acfs::ResourceNotFound.new message: "Recieved erronious " \
|
141
143
|
"response: no `#{name}` with params #{params} found"
|
142
144
|
end
|
143
145
|
block.call m unless block.nil?
|
@@ -193,13 +195,10 @@ class Acfs::Resource
|
|
193
195
|
#
|
194
196
|
# @yield [item] Callback that will be invoked for each item.
|
195
197
|
# @yieldparam item [self] Resource.
|
196
|
-
# @yieldparam collection [Acfs::Collection] Collection.
|
197
198
|
#
|
198
|
-
def each_item(opts = {})
|
199
|
+
def each_item(opts = {}, &block)
|
199
200
|
each_page(opts) do |collection|
|
200
|
-
collection.each
|
201
|
-
yield item, collection
|
202
|
-
end
|
201
|
+
collection.each(&block)
|
203
202
|
end
|
204
203
|
end
|
205
204
|
|
@@ -226,9 +225,9 @@ class Acfs::Resource
|
|
226
225
|
collection.__callbacks__ << block unless block.nil?
|
227
226
|
|
228
227
|
counter = 0
|
229
|
-
ids.
|
228
|
+
ids.each do |id|
|
230
229
|
find_single id, opts do |resource|
|
231
|
-
collection
|
230
|
+
collection << resource
|
232
231
|
if (counter += 1) == ids.size
|
233
232
|
collection.loaded!
|
234
233
|
collection.__invoke__
|
@@ -1,6 +1,8 @@
|
|
1
1
|
class Acfs::Resource
|
2
|
+
|
2
3
|
#
|
3
4
|
module Validation
|
5
|
+
|
4
6
|
def valid?(*args)
|
5
7
|
super
|
6
8
|
remote_errors.each {|f, e| errors.add f, e }
|
@@ -13,10 +15,8 @@ class Acfs::Resource
|
|
13
15
|
|
14
16
|
def remote_errors=(errors)
|
15
17
|
(errors || []).each do |field, errs|
|
16
|
-
|
17
|
-
|
18
|
-
remote_errors.add field.to_sym, err
|
19
|
-
end
|
18
|
+
self.errors.set field.to_sym, errs
|
19
|
+
remote_errors.set field.to_sym, errs
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|