acfs 1.3.2 → 1.5.1

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 (94) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +39 -0
  3. data/README.md +10 -23
  4. data/acfs.gemspec +19 -20
  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 +2 -0
  13. data/lib/acfs/location.rb +9 -5
  14. data/lib/acfs/middleware/base.rb +5 -1
  15. data/lib/acfs/middleware/json.rb +6 -2
  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 +7 -4
  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 +3 -2
  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 +19 -7
  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 +6 -3
  60. data/spec/acfs/location_spec.rb +2 -0
  61. data/spec/acfs/middleware/json_spec.rb +17 -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 +26 -26
@@ -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 = 2
6
+ MINOR = 5
7
+ PATCH = 1
6
8
  STAGE = nil
7
9
 
8
10
  STRING = [MAJOR, MINOR, PATCH, STAGE].reject(&:nil?).join('.')
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  # YARD macros
2
3
 
3
4
  # @!macro [new] experimental
@@ -1,14 +1,19 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Acfs::Adapter::Typhoeus do
4
6
  let(:adapter) { described_class.new }
5
- before { WebMock.allow_net_connect! }
7
+
8
+ before do
9
+ stub_request(:any, 'http://example.org').to_return status: 200
10
+ end
6
11
 
7
12
  it 'raises an error' do
8
- request1 = Acfs::Request.new 'http://altimos.de/404.1' do |_rsp|
13
+ request1 = Acfs::Request.new 'http://example.org' do |_rsp|
9
14
  raise '404-1'
10
15
  end
11
- request2 = Acfs::Request.new 'http://altimos.de/404.2' do |_rsp|
16
+ request2 = Acfs::Request.new 'http://example.org' do |_rsp|
12
17
  raise '404-2'
13
18
  end
14
19
  adapter.queue request1
@@ -18,6 +23,28 @@ describe Acfs::Adapter::Typhoeus do
18
23
  expect { adapter.start }.to_not raise_error
19
24
  end
20
25
 
26
+ it 'raises timeout' do
27
+ stub_request(:any, 'http://example.org').to_timeout
28
+
29
+ request = Acfs::Request.new 'http://example.org'
30
+ adapter.queue request
31
+
32
+ expect { adapter.run(request) }.to raise_error(::Acfs::TimeoutError) do |err|
33
+ expect(err.message).to eq 'Timeout reached: GET http://example.org'
34
+ end
35
+ end
36
+
37
+ it 'raises connection errors' do
38
+ WebMock.allow_net_connect!
39
+
40
+ request = Acfs::Request.new 'http://should-never-exists.example.org'
41
+ adapter.queue request
42
+
43
+ expect { adapter.run(request) }.to raise_error(::Acfs::RequestError) do |err|
44
+ expect(err.message).to eq 'Couldn\'t resolve host name: GET http://should-never-exists.example.org'
45
+ end
46
+ end
47
+
21
48
  it 'passes arguments to typhoeus hydra' do
22
49
  value = {key: 1, key2: 2}
23
50
 
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Acfs::Collection do
4
6
  let(:model) { MyUser }
5
7
 
6
8
  describe 'Pagination' do
7
- let(:params) { Hash.new }
9
+ let(:params) { {} }
8
10
  let!(:collection) { model.all params }
9
11
 
10
12
  subject { Acfs.run; collection }
@@ -62,7 +64,7 @@ describe Acfs::Collection do
62
64
  .to_return response([{id: 1, name: 'Anon', age: 12, born_at: 'Berlin'}],
63
65
  headers: {
64
66
  'X-Total-Pages' => '2',
65
- 'Link' => '<http://users.example.org/users?page=2>; rel="next"'
67
+ 'Link' => '<http://users.example.org/users?page=2>; rel="next"'
66
68
  })
67
69
  end
68
70
  let!(:req) do
@@ -86,7 +88,7 @@ describe Acfs::Collection do
86
88
  .to_return response([{id: 2, name: 'Anno', age: 1604, born_at: 'Santa Maria'}],
87
89
  headers: {
88
90
  'X-Total-Pages' => '2',
89
- 'Link' => '<http://users.example.org/users>; rel="prev"'
91
+ 'Link' => '<http://users.example.org/users>; rel="prev"'
90
92
  })
91
93
  end
92
94
  let!(:req) do
@@ -110,7 +112,7 @@ describe Acfs::Collection do
110
112
  .to_return response([{id: 2, name: 'Anno', age: 1604, born_at: 'Santa Maria'}],
111
113
  headers: {
112
114
  'X-Total-Pages' => '2',
113
- 'Link' => '<http://users.example.org/users>; rel="first"'
115
+ 'Link' => '<http://users.example.org/users>; rel="first"'
114
116
  })
115
117
  end
116
118
  let!(:req) do
@@ -134,7 +136,7 @@ describe Acfs::Collection do
134
136
  .to_return response([{id: 2, name: 'Anno', age: 1604, born_at: 'Santa Maria'}],
135
137
  headers: {
136
138
  'X-Total-Pages' => '2',
137
- 'Link' => '<http://users.example.org/users?page=12>; rel="last"'
139
+ 'Link' => '<http://users.example.org/users?page=12>; rel="last"'
138
140
  })
139
141
  end
140
142
  let!(:req) do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Acfs::Configuration do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  class NotificationCollector
@@ -48,7 +50,8 @@ describe ::Acfs::Global do
48
50
  stub_request(:get, %r{http://users.example.org/users/\d+}).to_return(
49
51
  status: 200,
50
52
  body: '{}',
51
- headers: {'Content-Type' => 'application/json'})
53
+ headers: {'Content-Type' => 'application/json'}
54
+ )
52
55
  end
53
56
 
54
57
  it 'should invoke when both resources' do
@@ -119,8 +122,8 @@ describe ::Acfs::Global do
119
122
 
120
123
  describe '#runner' do
121
124
  it 'returns per-thread runner' do
122
- runner1 = Thread.new { acfs.runner } .value
123
- runner2 = Thread.new { acfs.runner } .value
125
+ runner1 = Thread.new { acfs.runner }.value
126
+ runner2 = Thread.new { acfs.runner }.value
124
127
 
125
128
  expect(runner1).to_not equal runner2
126
129
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe ::Acfs::Location do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Acfs::Middleware::JSON do
@@ -26,6 +28,20 @@ describe Acfs::Middleware::JSON do
26
28
  expect(JSON.parse(request.body)).to eq data.map(&:stringify_keys)
27
29
  end
28
30
  end
31
+
32
+ context 'with #to_json objects' do
33
+ let(:data) do
34
+ Class.new do
35
+ def to_json(*)
36
+ '{"a": 1, "b": 2}'
37
+ end
38
+ end.new
39
+ end
40
+
41
+ it 'should serialize data with #to_json' do
42
+ expect(JSON.parse(request.body)).to eq 'a' => 1, 'b' => 2
43
+ end
44
+ end
29
45
  end
30
46
 
31
47
  describe 'decode' do
@@ -45,7 +61,7 @@ describe Acfs::Middleware::JSON do
45
61
  let(:body) { data.to_json[4..-4] }
46
62
 
47
63
  it 'should raise an error' do
48
- expect { request.complete! response }.to raise_error(MultiJson::LoadError)
64
+ expect { request.complete! response }.to raise_error(::JSON::ParserError)
49
65
  end
50
66
  end
51
67
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Acfs::Middleware::MessagePack do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe ::Acfs::Operation do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Acfs::Request::Callbacks do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Acfs::Request do
@@ -18,7 +20,7 @@ describe Acfs::Request do
18
20
  let(:params) { {id: 10} }
19
21
 
20
22
  it 'should return URL without query' do
21
- expect(request.url).to be == "#{url}"
23
+ expect(request.url).to be == url.to_s
22
24
  end
23
25
  end
24
26
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Acfs::Resource::Attributes::Boolean do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Acfs::Resource::Attributes::DateTime do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Acfs::Resource::Attributes::Dict do
@@ -13,12 +15,12 @@ describe Acfs::Resource::Attributes::Dict do
13
15
 
14
16
  context 'with blank string (I)' do
15
17
  let(:value) { '' }
16
- it { expect(subject.call).to eq Hash.new }
18
+ it { expect(subject.call).to eq({}) }
17
19
  end
18
20
 
19
21
  context 'with blank string (II)' do
20
22
  let(:value) { " \t" }
21
- it { expect(subject.call).to eq Hash.new }
23
+ it { expect(subject.call).to eq({}) }
22
24
  end
23
25
 
24
26
  context 'with hash' do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Acfs::Resource::Attributes::Float do
@@ -33,7 +35,7 @@ describe Acfs::Resource::Attributes::Float do
33
35
 
34
36
  context 'with -Infinity' do
35
37
  let(:value) { '-Infinity' }
36
- it { expect(subject.call).to eq -::Float::INFINITY }
38
+ it { expect(subject.call).to eq(-::Float::INFINITY) }
37
39
  end
38
40
 
39
41
  context 'with NaN' do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Acfs::Resource::Attributes::Integer do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Acfs::Resource::Attributes::List do
@@ -13,16 +15,16 @@ describe Acfs::Resource::Attributes::List do
13
15
 
14
16
  context 'with blank string (I)' do
15
17
  let(:value) { '' }
16
- it { expect(subject.call).to eq Array.new }
18
+ it { expect(subject.call).to eq [] }
17
19
  end
18
20
 
19
21
  context 'with blank string (II)' do
20
22
  let(:value) { " \t" }
21
- it { expect(subject.call).to eq Array.new }
23
+ it { expect(subject.call).to eq [] }
22
24
  end
23
25
 
24
26
  context 'with array' do
25
- let(:value) { %w(abc cde efg) }
27
+ let(:value) { %w[abc cde efg] }
26
28
  it { expect(subject.call).to eq value }
27
29
  end
28
30
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Acfs::Resource::Attributes::UUID do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Acfs::Resource::Attributes do
@@ -52,7 +54,7 @@ describe Acfs::Resource::Attributes do
52
54
  let(:action) { -> { m.write_attributes(*args) } }
53
55
  subject { action }
54
56
 
55
- it 'should update attributes' do
57
+ it 'should update attributes' do
56
58
  should change(m, :attributes)
57
59
  .from(name: 'The Great John', age: 25)
58
60
  .to(name: 'The Great James', age: 25)
@@ -70,7 +72,7 @@ describe Acfs::Resource::Attributes do
70
72
 
71
73
  it { should_not raise_error }
72
74
 
73
- it 'should update known attributes and store unknown' do
75
+ it 'should update known attributes and store unknown' do
74
76
  should change(m, :attributes)
75
77
  .from(name: 'The Great John', age: 25)
76
78
  .to(name: 'The Great James', age: 25, born_at: 'today')
@@ -83,11 +85,9 @@ describe Acfs::Resource::Attributes do
83
85
 
84
86
  it do
85
87
  expect do
86
- begin
87
- subject.call
88
- rescue
89
- true
90
- end
88
+ subject.call
89
+ rescue StandardError
90
+ true
91
91
  end.to_not change(m, :attributes)
92
92
  end
93
93
  end
@@ -171,7 +171,7 @@ describe Acfs::Resource::Attributes do
171
171
  end
172
172
 
173
173
  it 'includes superclass attributes' do
174
- expect(submodel.attributes.keys).to match_array %w(age born_at)
174
+ expect(submodel.attributes.keys).to match_array %w[age born_at]
175
175
  end
176
176
  end
177
177
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Acfs::Resource::Dirty do
@@ -1,11 +1,17 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe 'Acfs::Resource::Initialization' do
4
6
  let(:model) do
5
7
  Class.new(Acfs::Resource).tap do |c|
6
8
  c.class_eval do
7
- attr_accessor :name, :age
8
- private :age=
9
+ attr_accessor :name
10
+ attr_reader :age
11
+
12
+ private
13
+
14
+ attr_writer :age
9
15
  end
10
16
  end
11
17
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Acfs::Resource::Loadable do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Acfs::Resource::Locatable do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Acfs::Resource::Persistence do
@@ -226,8 +228,12 @@ describe Acfs::Resource::Persistence do
226
228
 
227
229
  it 'should set local errors hash' do
228
230
  model.name = ''
229
- model.save! rescue nil
230
- expect(model.errors.to_hash).to be == {name: %w(required)}
231
+ begin
232
+ model.save!
233
+ rescue StandardError
234
+ nil
235
+ end
236
+ expect(model.errors.to_hash).to be == {name: %w[required]}
231
237
  end
232
238
  end
233
239
 
@@ -265,7 +271,7 @@ describe Acfs::Resource::Persistence do
265
271
  it 'should raise an error' do
266
272
  expect { model_class.create! data }.to \
267
273
  raise_error(::Acfs::InvalidResource) do |error|
268
- expect(error.errors).to be == {'name' => %w(required)}
274
+ expect(error.errors).to be == {'name' => %w[required]}
269
275
  end
270
276
  end
271
277
  end
@@ -295,7 +301,7 @@ describe Acfs::Resource::Persistence do
295
301
  end
296
302
 
297
303
  it 'should contain error hash' do
298
- expect(subject.errors.to_hash).to eq name: %w(required)
304
+ expect(subject.errors.to_hash).to eq name: %w[required]
299
305
  end
300
306
  end
301
307