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
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
N2QwNTZiNDBiZDc4NjJhNjc3NjU3M2YxOTI4MzY2YWM4ZGZjMzE0MA==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6d20f4360733b38c6a3fde5716cf43ff586e7579
|
4
|
+
data.tar.gz: b3f8ba827e8813e21182d1b48d3e17ab4b8e1f89
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
OTBiMjY4ZDE4ZTJjNDk4YjEwZjVjYjEzMGJiNzNkZDY3Y2IxMWM3Y2VhN2Q1
|
11
|
-
M2I1OWI0NTVlODIxMjFiYzJhYTYwZTZjMTI3M2ZmMTQxYjBkYzI=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
Zjk4MzhhNGM0YzNjNmY4ZDAzOWFiYTE2MzViYTdhM2QxMTc0ZTI3MzJkMmI3
|
14
|
-
MThkZDNlYWFiM2FjYmE4MWVkY2I5N2RlZTMwYjA4OGE5ZTZmMmUzM2MxZjUz
|
15
|
-
ZTZkZTNhNmUwNmEyYTIzZGJhZDk0ZjgyN2Q2ZjAzMjkzMzdkMzA=
|
6
|
+
metadata.gz: 0841dd869d9e38ae2cc009c80fa7c9a327f970ee35ec3011f535a5f1f0f43bf6fd086efd1d16256793f8c80abeb6db6962ab7459d3c123f405f62b457639effc
|
7
|
+
data.tar.gz: bd81043d09374bbd5984120563c3425441fda4939fcd3154182aed6e28bd78fb0b6118025c17003ff642c274657ab575bf420045d8bbfd468b0eadaaa79a9cab
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,69 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 1.0.0
|
4
|
+
|
5
|
+
* Switch to first non-development major as it's long time used in production.
|
6
|
+
* Fix NewRelic RPM inference with middleware stack inherited from `ActionDispatch::MiddlewareStack`.
|
7
|
+
|
8
|
+
## 0.48.0
|
9
|
+
|
10
|
+
* Remove #attribute_types broke since f7e4109 (Sep 2013, v0.23)
|
11
|
+
* Fix attribute inheritance on subclassing broken since commit 7cf1d11 (Apr 2014, v0.43)
|
12
|
+
|
13
|
+
## 0.47.0
|
14
|
+
|
15
|
+
* Change blank value handling of dict and list type (0a12ef1)
|
16
|
+
|
17
|
+
## 0.46.0
|
18
|
+
|
19
|
+
* Rework types system (#39)
|
20
|
+
|
21
|
+
## 0.45.0
|
22
|
+
|
23
|
+
* Fetching multiple records (`find(ary)`) is stable now, but untested (#38)
|
24
|
+
* Middleware stack is build on ActionDispatch::MiddlewareStack now
|
25
|
+
* Deprecate legacy middleware names (xyEncoder, xyDecoder)
|
26
|
+
|
27
|
+
## 0.44.0
|
28
|
+
|
29
|
+
* Add option to configure adapter creation and pass option to typhoeus adapter e.g.
|
30
|
+
limiting concurrency.
|
31
|
+
|
32
|
+
## 0.43.2
|
33
|
+
|
34
|
+
* add `total_count` for paginated collections
|
35
|
+
|
36
|
+
## 0.43.1
|
37
|
+
|
38
|
+
* Fix `:with` condition matching on stubs
|
39
|
+
|
40
|
+
## 0.43.0
|
41
|
+
|
42
|
+
* Remove `Acfs::Model` (inherit from `Acfs::Resource`)
|
43
|
+
* Stub does only a partial match of `:with` attributes now
|
44
|
+
* Allow blocks as stub `:return`s
|
45
|
+
|
46
|
+
## 0.42.0
|
47
|
+
|
48
|
+
* Add simple dict attribute type
|
49
|
+
|
50
|
+
## 0.40.0
|
51
|
+
|
52
|
+
* Change `Resource#persisted?` to return true if it is not new
|
53
|
+
|
54
|
+
## 0.39.1
|
55
|
+
|
56
|
+
* Fix automatic path parameter handling for #destroy
|
57
|
+
|
58
|
+
## 0.39.0
|
59
|
+
|
60
|
+
* Add new event acfs.operation.before_process
|
61
|
+
|
62
|
+
## 0.38.0
|
63
|
+
|
64
|
+
* Allow middlewares to abort request processing
|
65
|
+
* Allow middlewares to receive the request operation object (via the request)
|
66
|
+
|
3
67
|
## 0.37.0
|
4
68
|
|
5
69
|
* Add Acfs.on
|
data/README.md
CHANGED
@@ -250,8 +250,8 @@ it 'should find user number one' do
|
|
250
250
|
expect(user.name).to be == 'John Smith'
|
251
251
|
expect(user.age).to be == 32
|
252
252
|
|
253
|
-
expect(@stub).to
|
254
|
-
expect(@stub).to_not
|
253
|
+
expect(@stub).to be_called
|
254
|
+
expect(@stub).to_not be_called 5.times
|
255
255
|
end
|
256
256
|
|
257
257
|
it 'should not find user number two' do
|
data/acfs.gemspec
CHANGED
@@ -8,13 +8,13 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.version = Acfs::VERSION
|
9
9
|
spec.authors = ['Jan Graichen']
|
10
10
|
spec.email = %w(jg@altimos.de)
|
11
|
-
spec.description =
|
12
|
-
spec.summary =
|
11
|
+
spec.description = 'API Client For Services'
|
12
|
+
spec.summary = 'An abstract API base client for service oriented application.'
|
13
13
|
spec.homepage = 'https://github.com/jgraichen/acfs'
|
14
14
|
spec.license = 'MIT'
|
15
15
|
|
16
16
|
spec.files = Dir['**/*'].grep(%r{^((bin|lib|test|spec|features)/|.*\.gemspec|.*LICENSE.*|.*README.*|.*CHANGELOG.*)})
|
17
|
-
spec.executables = spec.files.grep(%r{^bin/}) {
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) {|f| File.basename(f) }
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = %w(lib)
|
20
20
|
|
@@ -24,7 +24,7 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.add_runtime_dependency 'multi_json'
|
25
25
|
|
26
26
|
# Bundle update w/o version resolves to 0.3.3 ...
|
27
|
-
spec.add_runtime_dependency 'typhoeus', '
|
27
|
+
spec.add_runtime_dependency 'typhoeus', '~> 1.0'
|
28
28
|
|
29
29
|
spec.add_runtime_dependency 'rack'
|
30
30
|
|
data/lib/acfs.rb
CHANGED
@@ -30,13 +30,16 @@ module Acfs
|
|
30
30
|
module Middleware
|
31
31
|
extend ActiveSupport::Autoload
|
32
32
|
require 'acfs/middleware/base'
|
33
|
+
require 'acfs/middleware/serializer'
|
33
34
|
|
34
35
|
autoload :Print
|
35
36
|
autoload :Logger
|
36
|
-
autoload :
|
37
|
-
autoload :
|
38
|
-
autoload :JsonEncoder
|
39
|
-
autoload :
|
37
|
+
autoload :JSON
|
38
|
+
autoload :JsonDecoder, 'acfs/middleware/json'
|
39
|
+
autoload :JsonEncoder, 'acfs/middleware/json'
|
40
|
+
autoload :MessagePack, 'acfs/middleware/msgpack'
|
41
|
+
autoload :MessagePackDecoder, 'acfs/middleware/msgpack'
|
42
|
+
autoload :MessagePackEncoder, 'acfs/middleware/msgpack'
|
40
43
|
end
|
41
44
|
|
42
45
|
module Adapter
|
@@ -44,4 +47,3 @@ module Acfs
|
|
44
47
|
require 'acfs/adapter/typhoeus'
|
45
48
|
end
|
46
49
|
end
|
47
|
-
|
data/lib/acfs/adapter/base.rb
CHANGED
@@ -2,10 +2,12 @@ require 'typhoeus'
|
|
2
2
|
|
3
3
|
module Acfs
|
4
4
|
module Adapter
|
5
|
-
|
6
5
|
# Adapter for Typhoeus.
|
7
6
|
#
|
8
7
|
class Typhoeus < Base
|
8
|
+
def initialize(**kwargs)
|
9
|
+
@options = kwargs
|
10
|
+
end
|
9
11
|
|
10
12
|
def start
|
11
13
|
hydra.run
|
@@ -14,9 +16,7 @@ module Acfs
|
|
14
16
|
raise
|
15
17
|
end
|
16
18
|
|
17
|
-
|
18
|
-
hydra.abort
|
19
|
-
end
|
19
|
+
delegate :abort, to: :hydra
|
20
20
|
|
21
21
|
def run(request)
|
22
22
|
convert_request(request).run
|
@@ -26,17 +26,21 @@ module Acfs
|
|
26
26
|
hydra.queue convert_request request
|
27
27
|
end
|
28
28
|
|
29
|
-
|
29
|
+
protected
|
30
|
+
|
30
31
|
def hydra
|
31
|
-
@hydra ||= ::Typhoeus::Hydra.new
|
32
|
+
@hydra ||= ::Typhoeus::Hydra.new(**@options)
|
32
33
|
end
|
33
34
|
|
34
35
|
def convert_request(req)
|
35
36
|
request = ::Typhoeus::Request.new req.url,
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
37
|
+
method: req.method,
|
38
|
+
params: req.params,
|
39
|
+
headers: req.headers.merge(
|
40
|
+
'Expect' => '',
|
41
|
+
'Transfer-Encoding' => ''
|
42
|
+
),
|
43
|
+
body: req.body
|
40
44
|
|
41
45
|
request.on_complete do |response|
|
42
46
|
req.complete! convert_response(req, response)
|
@@ -47,9 +51,9 @@ module Acfs
|
|
47
51
|
|
48
52
|
def convert_response(request, response)
|
49
53
|
Acfs::Response.new request,
|
50
|
-
|
51
|
-
|
52
|
-
|
54
|
+
status: response.code,
|
55
|
+
headers: response.headers,
|
56
|
+
body: response.body
|
53
57
|
end
|
54
58
|
end
|
55
59
|
end
|
@@ -1,15 +1,14 @@
|
|
1
1
|
module Acfs::Collections
|
2
|
-
|
3
2
|
#
|
4
3
|
module Paginatable
|
5
4
|
extend ActiveSupport::Concern
|
6
5
|
|
7
6
|
included do
|
8
|
-
def self.operation(
|
7
|
+
def self.operation(_action, opts = {}, &_block)
|
9
8
|
opts[:url]
|
10
9
|
end
|
11
10
|
|
12
|
-
attr_reader :total_pages, :current_page
|
11
|
+
attr_reader :total_pages, :current_page, :total_count
|
13
12
|
end
|
14
13
|
|
15
14
|
def process_response(response)
|
@@ -34,12 +33,9 @@ module Acfs::Collections
|
|
34
33
|
end
|
35
34
|
|
36
35
|
def page(rel, &block)
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
# raise ArgumentError.new "No relative page `#{rel}'."
|
41
|
-
nil
|
42
|
-
end
|
36
|
+
return unless relations[rel]
|
37
|
+
|
38
|
+
@resource_class.all nil, url: relations[rel], &block
|
43
39
|
end
|
44
40
|
|
45
41
|
private
|
@@ -53,13 +49,17 @@ module Acfs::Collections
|
|
53
49
|
@total_pages = Integer(headers['X-Total-Pages'])
|
54
50
|
end
|
55
51
|
|
52
|
+
if headers['X-Total-Count']
|
53
|
+
@total_count = Integer(headers['X-Total-Count'])
|
54
|
+
end
|
55
|
+
|
56
56
|
setup_links headers['Link'] if headers['Link']
|
57
57
|
end
|
58
58
|
|
59
59
|
def setup_links(links)
|
60
60
|
links.split(/,\s+/).each do |link|
|
61
61
|
if link =~ /^\s*<([^>]+)>.*\s+rel="([\w_-]+)".*$/
|
62
|
-
relations[
|
62
|
+
relations[Regexp.last_match[2]] = Regexp.last_match[1]
|
63
63
|
end
|
64
64
|
end
|
65
65
|
end
|
data/lib/acfs/configuration.rb
CHANGED
@@ -2,11 +2,11 @@ require 'uri'
|
|
2
2
|
require 'yaml'
|
3
3
|
|
4
4
|
module Acfs
|
5
|
-
|
6
5
|
# Acfs configuration is used to locate services and get their base URLs.
|
7
6
|
#
|
8
7
|
class Configuration
|
9
8
|
attr_reader :locations
|
9
|
+
attr_accessor :adapter
|
10
10
|
|
11
11
|
# @api private
|
12
12
|
def initialize
|
@@ -28,7 +28,7 @@ module Acfs
|
|
28
28
|
if block.arity > 0
|
29
29
|
block.call self
|
30
30
|
else
|
31
|
-
instance_eval
|
31
|
+
instance_eval(&block)
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
@@ -64,10 +64,10 @@ module Acfs
|
|
64
64
|
# @return [undefined]
|
65
65
|
#
|
66
66
|
def load(filename)
|
67
|
-
config = YAML
|
67
|
+
config = YAML.load File.read filename
|
68
68
|
env = ENV['RACK_ENV'] || ENV['RAILS_ENV'] || 'development'
|
69
69
|
|
70
|
-
config = config[env] if config.
|
70
|
+
config = config[env] if config.key? env
|
71
71
|
config.each do |key, value|
|
72
72
|
case key
|
73
73
|
when 'services' then load_services value
|
@@ -88,7 +88,6 @@ module Acfs
|
|
88
88
|
end
|
89
89
|
|
90
90
|
class << self
|
91
|
-
|
92
91
|
# @api private
|
93
92
|
#
|
94
93
|
# Return current configuration object.
|
data/lib/acfs/errors.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
module Acfs
|
2
|
-
|
3
2
|
# Acfs base error.
|
4
3
|
#
|
5
4
|
class Error < StandardError
|
@@ -23,20 +22,20 @@ module Acfs
|
|
23
22
|
message << ": #{response.code}"
|
24
23
|
if response.data
|
25
24
|
message << "\n with content:\n "
|
26
|
-
message << response.data.map{|k,v| "#{k.inspect}: #{v.inspect}"}.join("\n ")
|
25
|
+
message << response.data.map {|k, v| "#{k.inspect}: #{v.inspect}" }.join("\n ")
|
27
26
|
end
|
28
27
|
if response.headers.any?
|
29
28
|
message << "\n with headers:\n "
|
30
|
-
message << response.headers.map{|k,v| "#{k}: #{v}"}.join("\n ")
|
29
|
+
message << response.headers.map {|k, v| "#{k}: #{v}" }.join("\n ")
|
31
30
|
end
|
32
31
|
message << "\nbased on request: #{response.request.method.upcase} #{response.request.url} #{response.request.format}"
|
33
32
|
if response.request.data
|
34
33
|
message << "\n with content:\n "
|
35
|
-
message << response.request.data.map{|k,v| "#{k.inspect}: #{v.inspect}"}.join("\n ")
|
34
|
+
message << response.request.data.map {|k, v| "#{k.inspect}: #{v.inspect}" }.join("\n ")
|
36
35
|
end
|
37
36
|
if response.request.headers.any?
|
38
37
|
message << "\n with headers:\n "
|
39
|
-
message << response.request.headers.map{|k,v| "#{k}: #{v}"}.join("\n ")
|
38
|
+
message << response.request.headers.map {|k, v| "#{k}: #{v}" }.join("\n ")
|
40
39
|
end
|
41
40
|
end
|
42
41
|
super opts, message
|
@@ -47,12 +46,14 @@ module Acfs
|
|
47
46
|
attr_reader :stubs, :operation
|
48
47
|
|
49
48
|
def initialize(opts = {})
|
49
|
+
require 'pp'
|
50
|
+
|
50
51
|
@stubs = opts.delete :stubs
|
51
52
|
@operation = opts.delete :operation
|
52
53
|
|
53
|
-
super opts,
|
54
|
+
super opts, "Ambiguous stubs for #{operation.action} on #{operation.resource}.\n" +
|
55
|
+
stubs.map {|s| " #{s.opts.pretty_inspect}" }.join
|
54
56
|
end
|
55
|
-
|
56
57
|
end
|
57
58
|
|
58
59
|
# Resource not found error raised on a 404 response
|
@@ -67,7 +68,7 @@ module Acfs
|
|
67
68
|
def initialize(opts = {})
|
68
69
|
@errors = opts.delete :errors
|
69
70
|
@resource = opts.delete :resource
|
70
|
-
opts[:message] ||= @errors.map{
|
71
|
+
opts[:message] ||= @errors.map {|k, v| "#{k}: #{v.join ', '}" }.join ', ' if @errors.is_a? Hash
|
71
72
|
opts[:message] ||= @errors.join ', ' if @errors.is_a? Array
|
72
73
|
super
|
73
74
|
end
|
@@ -99,7 +100,7 @@ module Acfs
|
|
99
100
|
def initialize(opts = {})
|
100
101
|
@base_class = opts.delete :base_class
|
101
102
|
@type_name = opts.delete :type_name
|
102
|
-
opts[:message] = "
|
103
|
+
opts[:message] = "Received resource type `#{type_name}` is no subclass of #{base_class}"
|
103
104
|
super
|
104
105
|
end
|
105
106
|
end
|
data/lib/acfs/global.rb
CHANGED
@@ -1,14 +1,22 @@
|
|
1
1
|
module Acfs
|
2
|
-
|
2
|
+
#
|
3
3
|
# Global Acfs module methods.
|
4
4
|
#
|
5
5
|
module Global
|
6
|
-
|
6
|
+
#
|
7
7
|
# @api private
|
8
8
|
# @return [Runner]
|
9
9
|
#
|
10
10
|
def runner
|
11
|
-
|
11
|
+
Thread.current[:acfs_runner] ||= begin
|
12
|
+
adapter = Configuration.current.adapter
|
13
|
+
|
14
|
+
if adapter
|
15
|
+
Runner.new adapter.call
|
16
|
+
else
|
17
|
+
Runner.new Adapter::Typhoeus.new
|
18
|
+
end
|
19
|
+
end
|
12
20
|
end
|
13
21
|
|
14
22
|
# @api public
|
@@ -59,9 +67,10 @@ module Acfs
|
|
59
67
|
# Acfs.add_callback(user, &callback_two)
|
60
68
|
#
|
61
69
|
def add_callback(resource, &block)
|
62
|
-
|
63
|
-
|
64
|
-
|
70
|
+
unless resource.respond_to?(:__callbacks__)
|
71
|
+
raise ArgumentError.new 'Given resource is not an Acfs resource ' \
|
72
|
+
"delegator but a: #{resource.class.name}"
|
73
|
+
end
|
65
74
|
return false if block.nil?
|
66
75
|
|
67
76
|
if resource.loaded?
|
@@ -73,7 +82,7 @@ module Acfs
|
|
73
82
|
|
74
83
|
def on(*resources)
|
75
84
|
resources.each do |resource|
|
76
|
-
add_callback resource do |
|
85
|
+
add_callback resource do |_|
|
77
86
|
yield(*resources) unless resources.any? {|res| !res.loaded? }
|
78
87
|
end
|
79
88
|
end
|
data/lib/acfs/location.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
module Acfs
|
2
|
-
|
3
2
|
# @api private
|
4
3
|
#
|
5
4
|
# Describes a URL with placeholders.
|
@@ -7,17 +6,17 @@ module Acfs
|
|
7
6
|
class Location
|
8
7
|
attr_reader :arguments, :raw, :struct, :args
|
9
8
|
|
10
|
-
REGEXP= /^:([A-z][A-z0-9_]*)$/
|
9
|
+
REGEXP = /^:([A-z][A-z0-9_]*)$/
|
11
10
|
|
12
11
|
def initialize(uri, args = {})
|
13
12
|
@raw = URI.parse uri
|
14
13
|
@args = args
|
15
|
-
@struct = raw.path.split('/').reject(&:empty?).map{|s| s =~ REGEXP ?
|
16
|
-
@arguments = struct.select{|s| Symbol
|
14
|
+
@struct = raw.path.split('/').reject(&:empty?).map {|s| s =~ REGEXP ? Regexp.last_match[1].to_sym : s }
|
15
|
+
@arguments = struct.select {|s| s.is_a?(Symbol) }
|
17
16
|
end
|
18
17
|
|
19
18
|
def build(args = {})
|
20
|
-
unless Hash
|
19
|
+
unless args.is_a?(Hash)
|
21
20
|
raise ArgumentError.new "URI path arguments must be a hash, `#{args.inspect}' given."
|
22
21
|
end
|
23
22
|
|
@@ -25,8 +24,8 @@ module Acfs
|
|
25
24
|
end
|
26
25
|
|
27
26
|
def extract_from(*args)
|
28
|
-
args =
|
29
|
-
arguments.each{|key| collect[key] = extract_arg key, args }
|
27
|
+
args = {}.tap do |collect|
|
28
|
+
arguments.each {|key| collect[key] = extract_arg key, args }
|
30
29
|
end
|
31
30
|
|
32
31
|
build args
|
@@ -34,7 +33,7 @@ module Acfs
|
|
34
33
|
|
35
34
|
def str
|
36
35
|
uri = raw.dup
|
37
|
-
uri.path = URI.escape '/' + struct.map{|s| lookup_arg(s, args) }.join('/')
|
36
|
+
uri.path = URI.escape '/' + struct.map {|s| lookup_arg(s, args) }.join('/')
|
38
37
|
uri.to_s
|
39
38
|
end
|
40
39
|
|
@@ -44,16 +43,17 @@ module Acfs
|
|
44
43
|
alias_method :to_s, :raw_uri
|
45
44
|
|
46
45
|
private
|
46
|
+
|
47
47
|
def extract_arg(key, hashes)
|
48
48
|
hashes.each_with_index do |hash, index|
|
49
|
-
return (index == 0 ? hash.delete(key) : hash.fetch(key)) if hash.
|
49
|
+
return (index == 0 ? hash.delete(key) : hash.fetch(key)) if hash.key?(key)
|
50
50
|
end
|
51
51
|
|
52
52
|
nil
|
53
53
|
end
|
54
54
|
|
55
55
|
def lookup_arg(arg, args)
|
56
|
-
Symbol
|
56
|
+
arg.is_a?(Symbol) ? lookup_replacement(arg, args) : arg
|
57
57
|
end
|
58
58
|
|
59
59
|
def lookup_replacement(sym, args)
|
@@ -67,7 +67,7 @@ module Acfs
|
|
67
67
|
args.fetch(sym.to_s) do
|
68
68
|
args.fetch(sym) do
|
69
69
|
if args[:raise].nil? || args[:raise]
|
70
|
-
raise ArgumentError.new "URI path argument `#{sym}' missing on `#{
|
70
|
+
raise ArgumentError.new "URI path argument `#{sym}' missing on `#{self}'. Given: `#{args}.inspect'"
|
71
71
|
else
|
72
72
|
":#{sym}"
|
73
73
|
end
|