acfs 0.50.0 → 1.0.0.dev.1.b297

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.
Files changed (90) hide show
  1. checksums.yaml +13 -5
  2. data/CHANGELOG.md +0 -80
  3. data/README.md +9 -8
  4. data/acfs.gemspec +7 -7
  5. data/lib/acfs.rb +5 -7
  6. data/lib/acfs/adapter/base.rb +2 -0
  7. data/lib/acfs/adapter/typhoeus.rb +13 -17
  8. data/lib/acfs/collections/paginatable.rb +10 -10
  9. data/lib/acfs/configuration.rb +5 -4
  10. data/lib/acfs/errors.rb +9 -10
  11. data/lib/acfs/global.rb +7 -16
  12. data/lib/acfs/location.rb +11 -11
  13. data/lib/acfs/middleware/base.rb +2 -1
  14. data/lib/acfs/middleware/json_decoder.rb +16 -0
  15. data/lib/acfs/middleware/json_encoder.rb +20 -0
  16. data/lib/acfs/middleware/logger.rb +2 -0
  17. data/lib/acfs/middleware/msgpack_decoder.rb +26 -0
  18. data/lib/acfs/middleware/msgpack_encoder.rb +19 -0
  19. data/lib/acfs/middleware/print.rb +2 -0
  20. data/lib/acfs/operation.rb +5 -5
  21. data/lib/acfs/request.rb +4 -4
  22. data/lib/acfs/request/callbacks.rb +3 -2
  23. data/lib/acfs/resource.rb +2 -2
  24. data/lib/acfs/resource/attributes.rb +38 -11
  25. data/lib/acfs/resource/attributes/base.rb +19 -10
  26. data/lib/acfs/resource/attributes/boolean.rb +8 -10
  27. data/lib/acfs/resource/attributes/date_time.rb +9 -6
  28. data/lib/acfs/resource/attributes/float.rb +5 -11
  29. data/lib/acfs/resource/attributes/integer.rb +5 -7
  30. data/lib/acfs/resource/attributes/list.rb +6 -13
  31. data/lib/acfs/resource/attributes/string.rb +5 -3
  32. data/lib/acfs/resource/attributes/uuid.rb +17 -8
  33. data/lib/acfs/resource/dirty.rb +15 -3
  34. data/lib/acfs/resource/loadable.rb +1 -0
  35. data/lib/acfs/resource/locatable.rb +4 -0
  36. data/lib/acfs/resource/operational.rb +2 -0
  37. data/lib/acfs/resource/persistence.rb +17 -17
  38. data/lib/acfs/resource/query_methods.rb +7 -8
  39. data/lib/acfs/resource/service.rb +2 -0
  40. data/lib/acfs/resource/validation.rb +4 -4
  41. data/lib/acfs/response.rb +2 -1
  42. data/lib/acfs/response/formats.rb +3 -2
  43. data/lib/acfs/response/status.rb +5 -3
  44. data/lib/acfs/runner.rb +11 -21
  45. data/lib/acfs/service.rb +6 -4
  46. data/lib/acfs/service/middleware.rb +30 -20
  47. data/lib/acfs/singleton_resource.rb +2 -0
  48. data/lib/acfs/stub.rb +21 -30
  49. data/lib/acfs/util.rb +1 -1
  50. data/lib/acfs/version.rb +4 -6
  51. data/spec/acfs/adapter/typhoeus_spec.rb +4 -12
  52. data/spec/acfs/collection_spec.rb +33 -45
  53. data/spec/acfs/configuration_spec.rb +1 -9
  54. data/spec/acfs/global_spec.rb +3 -21
  55. data/spec/acfs/middleware/json_decoder_spec.rb +45 -0
  56. data/spec/acfs/middleware/msgpack_decoder_spec.rb +36 -0
  57. data/spec/acfs/request/callbacks_spec.rb +8 -8
  58. data/spec/acfs/request_spec.rb +5 -5
  59. data/spec/acfs/resource/attributes/boolean_spec.rb +9 -40
  60. data/spec/acfs/resource/attributes/date_time_spec.rb +35 -29
  61. data/spec/acfs/resource/attributes/float_spec.rb +9 -48
  62. data/spec/acfs/resource/attributes/list_spec.rb +19 -43
  63. data/spec/acfs/resource/attributes/uuid_spec.rb +54 -31
  64. data/spec/acfs/resource/attributes_spec.rb +31 -17
  65. data/spec/acfs/resource/locatable_spec.rb +2 -2
  66. data/spec/acfs/resource/persistance_spec.rb +34 -65
  67. data/spec/acfs/resource/query_methods_spec.rb +90 -97
  68. data/spec/acfs/resource/validation_spec.rb +5 -4
  69. data/spec/acfs/response/formats_spec.rb +4 -4
  70. data/spec/acfs/response/status_spec.rb +1 -1
  71. data/spec/acfs/runner_spec.rb +3 -28
  72. data/spec/acfs/service/middleware_spec.rb +20 -4
  73. data/spec/acfs/service_spec.rb +5 -3
  74. data/spec/acfs/singleton_resource_spec.rb +2 -1
  75. data/spec/acfs/stub_spec.rb +22 -137
  76. data/spec/acfs_spec.rb +19 -22
  77. data/spec/spec_helper.rb +2 -3
  78. data/spec/support/service.rb +6 -10
  79. data/spec/support/shared/find_callbacks.rb +7 -7
  80. metadata +36 -43
  81. data/lib/acfs/middleware/json.rb +0 -27
  82. data/lib/acfs/middleware/msgpack.rb +0 -30
  83. data/lib/acfs/middleware/serializer.rb +0 -39
  84. data/lib/acfs/resource/attributes/dict.rb +0 -37
  85. data/lib/acfs/service/middleware/stack.rb +0 -63
  86. data/spec/acfs/middleware/json_spec.rb +0 -63
  87. data/spec/acfs/middleware/msgpack_spec.rb +0 -60
  88. data/spec/acfs/operation_spec.rb +0 -10
  89. data/spec/acfs/resource/attributes/dict_spec.rb +0 -75
  90. data/spec/acfs/resource/attributes/integer_spec.rb +0 -34
@@ -3,6 +3,7 @@ require 'acfs/response/status'
3
3
  require 'active_support/core_ext/module/delegation'
4
4
 
5
5
  module Acfs
6
+
6
7
  # This represents a response. In addition to an standard HTTP
7
8
  # it has a field `data` for storing the encoded body.
8
9
  #
@@ -13,7 +14,7 @@ module Acfs
13
14
  include Response::Formats
14
15
  include Response::Status
15
16
 
16
- # delegate :status, :status_message, :success?, :modified?, :timed_out?,
17
+ #delegate :status, :status_message, :success?, :modified?, :timed_out?,
17
18
  # :response_body, :response_headers, :response_code, :headers,
18
19
  # to: :response
19
20
 
@@ -2,18 +2,19 @@ require 'action_dispatch'
2
2
 
3
3
  module Acfs
4
4
  class Response
5
+
5
6
  # Quick accessors for format handling.
6
7
  module Formats
8
+
7
9
  def content_type
8
10
  @content_type ||= read_content_type
9
11
  end
10
12
 
11
13
  def json?
12
- content_type == Mime[:json]
14
+ content_type == Mime::JSON
13
15
  end
14
16
 
15
17
  private
16
-
17
18
  def read_content_type
18
19
  return 'text/plain' unless headers && headers['Content-Type']
19
20
 
@@ -1,17 +1,19 @@
1
1
  module Acfs
2
2
  class Response
3
+
3
4
  # Method to fetch information about response status.
4
5
  #
5
6
  module Status
7
+
6
8
  # Return response status code. Will return zero if
7
9
  # request was not executed or failed on client side.
8
10
  #
9
11
  def status_code
10
12
  return @status.to_i if defined? :@status
11
- # return response.response_code unless response.nil?
12
- # 0
13
+ #return response.response_code unless response.nil?
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,6 +1,7 @@
1
1
  require 'acfs/service/middleware'
2
2
 
3
3
  module Acfs
4
+
4
5
  # @api private
5
6
  #
6
7
  class Runner
@@ -16,7 +17,6 @@ module Acfs
16
17
  # and parallel operations will be queued.
17
18
  #
18
19
  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) {|req| adapter.run req }
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) {|req| adapter.queue req }
42
+ op_request(op) { |req| adapter.queue req }
43
43
  else
44
44
  queue << op
45
45
  end
@@ -55,13 +55,15 @@ module Acfs
55
55
  # Start processing queued operations.
56
56
  #
57
57
  def start
58
- return if running?
59
-
60
58
  enqueue_operations
61
- start_all
59
+
60
+ @running = true
61
+ adapter.start
62
62
  rescue
63
63
  queue.clear
64
64
  raise
65
+ ensure
66
+ @running = false
65
67
  end
66
68
 
67
69
  def clear
@@ -71,27 +73,15 @@ module Acfs
71
73
  end
72
74
 
73
75
  private
74
-
75
- def start_all
76
- @running = true
77
- adapter.start
78
- ensure
79
- @running = false
80
- end
81
-
82
76
  def enqueue_operations
83
77
  while (op = queue.shift)
84
- op_request(op) {|req| adapter.queue req }
78
+ op_request(op) { |req| adapter.queue req }
85
79
  end
86
80
  end
87
81
 
88
82
  def op_request(op)
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
83
+ return if Acfs::Stub.enabled? and Acfs::Stub.stubbed(op)
84
+ yield prepare op.service.prepare op.request
95
85
  end
96
86
  end
97
87
  end
@@ -1,6 +1,7 @@
1
1
  require 'acfs/service/middleware'
2
2
 
3
3
  module Acfs
4
+
4
5
  # User {Acfs::Service} to define your services. That includes
5
6
  # an identity used to identify the service in configuration files
6
7
  # and middlewares the service uses.
@@ -34,14 +35,14 @@ module Acfs
34
35
  # @return [Location]
35
36
  #
36
37
  def location(resource_class, opts = {})
37
- opts.reverse_merge! options
38
+ opts.reverse_merge! self.options
38
39
 
39
40
  action = opts[:action] || :list
40
41
 
41
- path = if opts[:path].is_a?(Hash) && opts[:path].key?(action)
42
+ path = if Hash === opts[:path] && opts[:path].has_key?(action)
42
43
  opts[:path].fetch(action)
43
44
  else
44
- path = if opts[:path].is_a?(Hash)
45
+ path = if Hash === opts[:path]
45
46
  opts[:path][:all].to_s
46
47
  else
47
48
  opts[:path].to_s
@@ -58,6 +59,7 @@ module Acfs
58
59
  end
59
60
 
60
61
  class << self
62
+
61
63
  # @api public
62
64
  #
63
65
  # @overload identity()
@@ -81,7 +83,7 @@ module Acfs
81
83
  #
82
84
  def base_url
83
85
  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."
86
+ raise ArgumentError, "#{identity} not configured. Add `locate '#{identity.to_s.underscore}', 'http://service.url/'` to your configuration."
85
87
  end
86
88
 
87
89
  base.to_s
@@ -1,7 +1,6 @@
1
- require 'acfs/service/middleware/stack'
2
-
3
1
  module Acfs
4
2
  class Service
3
+
5
4
  # Module providing all function to register middlewares
6
5
  # on services and process queued request through the
7
6
  # middleware stack.
@@ -17,25 +16,28 @@ module Acfs
17
16
  end
18
17
 
19
18
  module ClassMethods
20
- # @!method use(klass, *args, &block)
21
- # @api public
19
+
20
+ # @api public
22
21
  #
23
- # Register a new middleware to be used for this service.
22
+ # Register a new middleware to be used for this service.
24
23
  #
25
- # @example
26
- # class MyService < Acfs::Service
27
- # self.base_url = 'http://my.srv'
28
- # use Acfs::Middleware::JSON
29
- # end
24
+ # @example
25
+ # class MyService < Acfs::Service
26
+ # self.base_url = 'http://my.srv'
27
+ # use Acfs::Middleware::JsonDecoder
28
+ # end
30
29
  #
31
- # @param [Class] klass Middleware class to append
32
- # @param [Array<Object>] args Arguments passed to klass initialize
33
- # @param [Proc] block Block passed to klass initialize
34
- # @return [undefined]
30
+ # @param [Class] klass Middleware class to instantiate and append to middleware stack.
31
+ # @param [Hash, Object] options Options to delegate to middleware class initializer.
32
+ # @return [undefined]
35
33
  #
36
- def use(klass, *args, &block)
37
- # Backward compatible behavior
38
- middleware.insert(0, klass, *args, &block)
34
+ def use(klass, options = {})
35
+ @middlewares ||= []
36
+
37
+ return false if @middlewares.include? klass
38
+
39
+ @middlewares << klass
40
+ @middleware = klass.new(middleware, options)
39
41
  end
40
42
 
41
43
  # @api private
@@ -45,11 +47,19 @@ module Acfs
45
47
  # @return [#call]
46
48
  #
47
49
  def middleware
48
- @middleware ||= Stack.new
50
+ @middleware ||= proc { |request| request}
49
51
  end
50
52
 
51
- # @deprecated
52
- delegate :clear, to: :middleware
53
+ # @api public
54
+ #
55
+ # Clear all registered middlewares.
56
+ #
57
+ # @return [undefined]
58
+ #
59
+ def clear
60
+ @middleware = nil
61
+ @middlewares = []
62
+ end
53
63
  end
54
64
  end
55
65
  end
@@ -1,4 +1,5 @@
1
1
  module Acfs
2
+
2
3
  # Acfs SingletonResources
3
4
  #
4
5
  # Usage explanation:
@@ -13,6 +14,7 @@ module Acfs
13
14
  # always only a single instance of the resource is being returned
14
15
  #
15
16
  class SingletonResource < Acfs::Resource
17
+
16
18
  # @api public
17
19
  #
18
20
  # Destroy resource by sending a DELETE request.
@@ -1,6 +1,7 @@
1
1
  require 'rack/utils'
2
2
 
3
3
  module Acfs
4
+
4
5
  # Global handler for stubbing resources.
5
6
  #
6
7
  class Stub
@@ -13,7 +14,7 @@ module Acfs
13
14
 
14
15
  @opts[:with].stringify_keys! if @opts[:with].is_a? Hash
15
16
  @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
17
+ @opts[:return].map! { |h| h.stringify_keys! if h.is_a? Hash } if @opts[:return].is_a? Array
17
18
  end
18
19
 
19
20
  def accept?(op)
@@ -21,21 +22,14 @@ module Acfs
21
22
 
22
23
  params = op.full_params.stringify_keys
23
24
  data = op.data.stringify_keys
24
- with = opts[:with]
25
-
26
- return true if with.nil?
27
-
28
- case opts.fetch(:match, :inclusion)
29
- when :legacy
30
- 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? }
33
- false
34
- when :inclusion
35
- with.each_pair.all? do |k, v|
36
- (params.key?(k) && params[k] == v) || (data.key?(k) && data[k] == v)
37
- end
38
- end
25
+
26
+ return true if opts[:with] == params || data == opts[:with]
27
+ return true if (opts[:with].nil? && params.empty? && data.empty?)
28
+
29
+ return true if opts[:with].reject { |k, v| v.nil? } == params.reject { |k, v| v.nil? }
30
+ return true if opts[:with].reject { |k, v| v.nil? } == data.reject { |k, v| v.nil? }
31
+
32
+ false
39
33
  end
40
34
 
41
35
  def calls
@@ -56,20 +50,17 @@ module Acfs
56
50
  if err
57
51
  raise_error op, err, opts[:return]
58
52
  elsif data
59
- data = data.call(op) if data.respond_to?(:call)
60
-
61
53
  response = Acfs::Response.new op.request,
62
- headers: opts[:headers] || {},
63
- status: opts[:status] || 200,
64
- data: data || {}
54
+ headers: opts[:headers] || {},
55
+ status: opts[:status] || 200,
56
+ data: data || {}
65
57
  op.call data, response
66
58
  else
67
- raise ArgumentError.new 'Unsupported stub.'
59
+ raise ArgumentError, 'Unsupported stub.'
68
60
  end
69
61
  end
70
62
 
71
63
  private
72
-
73
64
  def raise_error(op, name, data)
74
65
  raise name if name.is_a? Class
75
66
  data.stringify_keys! if data.respond_to? :stringify_keys!
@@ -78,12 +69,13 @@ module Acfs
78
69
  end
79
70
 
80
71
  class << self
72
+
81
73
  # Stub a resource with given handler block. An already created handler
82
74
  # for same resource class will be overridden.
83
75
  #
84
- def resource(klass, action, opts = {}, &_block)
76
+ def resource(klass, action, opts = {}, &block)
85
77
  action = action.to_sym
86
- raise ArgumentError.new "Unknown action `#{action}`." unless ACTIONS.include? action
78
+ raise ArgumentError, "Unknown action `#{action}`." unless ACTIONS.include? action
87
79
 
88
80
  Stub.new(opts).tap do |stub|
89
81
  stubs[klass] ||= {}
@@ -104,11 +96,11 @@ module Acfs
104
96
  @enabled ||= false
105
97
  end
106
98
 
107
- def enable
99
+ def enable;
108
100
  @enabled = true
109
101
  end
110
102
 
111
- def disable
103
+ def disable;
112
104
  @enabled = false
113
105
  end
114
106
 
@@ -126,7 +118,7 @@ module Acfs
126
118
  return false unless (classes = stubs[op.resource])
127
119
  return false unless (stubs = classes[op.action])
128
120
 
129
- accepted_stubs = stubs.select {|stub| stub.accept? op }
121
+ accepted_stubs = stubs.select { |stub| stub.accept? op }
130
122
 
131
123
  raise AmbiguousStubError.new stubs: accepted_stubs, operation: op if accepted_stubs.size > 1
132
124
 
@@ -150,9 +142,8 @@ module Acfs
150
142
  end
151
143
 
152
144
  private
153
-
154
145
  def pretty_print
155
- out = ''
146
+ out = String.new
156
147
  stubs.each do |klass, actions|
157
148
  out << ' ' << klass.name << ":\n"
158
149
  actions.each do |action, stubs|
@@ -7,7 +7,7 @@ module Acfs
7
7
  end
8
8
 
9
9
  def __invoke__
10
- __callbacks__.each {|c| c.call self }
10
+ __callbacks__.each{|c| c.call self}
11
11
  end
12
12
  end
13
13
 
@@ -1,14 +1,12 @@
1
1
  module Acfs
2
2
  module VERSION
3
- MAJOR = 0
4
- MINOR = 50
3
+ MAJOR = 1
4
+ MINOR = 0
5
5
  PATCH = 0
6
- STAGE = nil
6
+ STAGE = 'dev'
7
7
 
8
8
  STRING = [MAJOR, MINOR, PATCH, STAGE].reject(&:nil?).join('.')
9
9
 
10
- def self.to_s
11
- STRING
12
- end
10
+ def self.to_s; STRING end
13
11
  end
14
12
  end
@@ -5,24 +5,16 @@ describe Acfs::Adapter::Typhoeus do
5
5
  before { WebMock.allow_net_connect! }
6
6
 
7
7
  it 'raises an error' do
8
- request1 = Acfs::Request.new 'http://altimos.de/404.1' do |_rsp|
8
+ request1 = Acfs::Request.new 'http://altimos.de/404.1' do |rsp|
9
9
  raise '404-1'
10
10
  end
11
- request2 = Acfs::Request.new 'http://altimos.de/404.2' do |_rsp|
11
+ request2 = Acfs::Request.new 'http://altimos.de/404.2' do |rsp|
12
12
  raise '404-2'
13
13
  end
14
14
  adapter.queue request1
15
15
  adapter.queue request2
16
16
 
17
- expect { adapter.start }.to raise_error(/404\-[12]/)
18
- expect { adapter.start }.to_not raise_error
19
- end
20
-
21
- it 'passes arguments to typhoeus hydra' do
22
- value = {key: 1, key2: 2}
23
-
24
- expect(::Typhoeus::Hydra).to receive(:new).with(value)
25
-
26
- described_class.new(**value).send :hydra
17
+ expect{ adapter.start }.to raise_error /404\-[12]/
18
+ expect{ adapter.start }.to_not raise_error
27
19
  end
28
20
  end