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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +39 -0
- data/README.md +10 -23
- data/acfs.gemspec +19 -20
- data/lib/acfs.rb +2 -0
- data/lib/acfs/adapter/base.rb +6 -8
- data/lib/acfs/adapter/typhoeus.rb +25 -6
- data/lib/acfs/collection.rb +2 -1
- data/lib/acfs/collections/paginatable.rb +4 -3
- data/lib/acfs/configuration.rb +14 -7
- data/lib/acfs/errors.rb +60 -19
- data/lib/acfs/global.rb +2 -0
- data/lib/acfs/location.rb +9 -5
- data/lib/acfs/middleware/base.rb +5 -1
- data/lib/acfs/middleware/json.rb +6 -2
- data/lib/acfs/middleware/logger.rb +2 -0
- data/lib/acfs/middleware/msgpack.rb +2 -0
- data/lib/acfs/middleware/print.rb +2 -0
- data/lib/acfs/middleware/serializer.rb +2 -0
- data/lib/acfs/operation.rb +20 -3
- data/lib/acfs/request.rb +5 -1
- data/lib/acfs/request/callbacks.rb +5 -1
- data/lib/acfs/resource.rb +2 -0
- data/lib/acfs/resource/attributes.rb +7 -4
- data/lib/acfs/resource/attributes/base.rb +2 -1
- data/lib/acfs/resource/attributes/boolean.rb +2 -0
- data/lib/acfs/resource/attributes/date_time.rb +3 -2
- data/lib/acfs/resource/attributes/dict.rb +2 -0
- data/lib/acfs/resource/attributes/float.rb +5 -3
- data/lib/acfs/resource/attributes/integer.rb +2 -0
- data/lib/acfs/resource/attributes/list.rb +2 -0
- data/lib/acfs/resource/attributes/string.rb +2 -0
- data/lib/acfs/resource/attributes/uuid.rb +4 -3
- data/lib/acfs/resource/dirty.rb +2 -0
- data/lib/acfs/resource/initialization.rb +2 -0
- data/lib/acfs/resource/loadable.rb +2 -0
- data/lib/acfs/resource/locatable.rb +10 -6
- data/lib/acfs/resource/operational.rb +2 -1
- data/lib/acfs/resource/persistence.rb +7 -6
- data/lib/acfs/resource/query_methods.rb +6 -4
- data/lib/acfs/resource/service.rb +3 -1
- data/lib/acfs/resource/validation.rb +19 -7
- data/lib/acfs/response.rb +2 -0
- data/lib/acfs/response/formats.rb +2 -0
- data/lib/acfs/response/status.rb +3 -1
- data/lib/acfs/rspec.rb +2 -0
- data/lib/acfs/runner.rb +6 -1
- data/lib/acfs/service.rb +24 -13
- data/lib/acfs/service/middleware.rb +2 -0
- data/lib/acfs/service/middleware/stack.rb +5 -3
- data/lib/acfs/singleton_resource.rb +4 -2
- data/lib/acfs/stub.rb +32 -11
- data/lib/acfs/util.rb +2 -0
- data/lib/acfs/version.rb +4 -2
- data/lib/acfs/yard.rb +1 -0
- data/spec/acfs/adapter/typhoeus_spec.rb +30 -3
- data/spec/acfs/collection_spec.rb +7 -5
- data/spec/acfs/configuration_spec.rb +2 -0
- data/spec/acfs/global_spec.rb +6 -3
- data/spec/acfs/location_spec.rb +2 -0
- data/spec/acfs/middleware/json_spec.rb +17 -1
- data/spec/acfs/middleware/msgpack_spec.rb +2 -0
- data/spec/acfs/operation_spec.rb +2 -0
- data/spec/acfs/request/callbacks_spec.rb +2 -0
- data/spec/acfs/request_spec.rb +3 -1
- data/spec/acfs/resource/attributes/boolean_spec.rb +2 -0
- data/spec/acfs/resource/attributes/date_time_spec.rb +2 -0
- data/spec/acfs/resource/attributes/dict_spec.rb +4 -2
- data/spec/acfs/resource/attributes/float_spec.rb +3 -1
- data/spec/acfs/resource/attributes/integer_spec.rb +2 -0
- data/spec/acfs/resource/attributes/list_spec.rb +5 -3
- data/spec/acfs/resource/attributes/uuid_spec.rb +2 -0
- data/spec/acfs/resource/attributes_spec.rb +8 -8
- data/spec/acfs/resource/dirty_spec.rb +2 -0
- data/spec/acfs/resource/initialization_spec.rb +8 -2
- data/spec/acfs/resource/loadable_spec.rb +2 -0
- data/spec/acfs/resource/locatable_spec.rb +2 -0
- data/spec/acfs/resource/persistance_spec.rb +10 -4
- data/spec/acfs/resource/query_methods_spec.rb +24 -17
- data/spec/acfs/resource/validation_spec.rb +2 -0
- data/spec/acfs/response/formats_spec.rb +3 -1
- data/spec/acfs/response/status_spec.rb +2 -0
- data/spec/acfs/runner_spec.rb +6 -8
- data/spec/acfs/service/middleware_spec.rb +2 -0
- data/spec/acfs/service_spec.rb +3 -1
- data/spec/acfs/singleton_resource_spec.rb +2 -0
- data/spec/acfs/stub_spec.rb +2 -0
- data/spec/acfs_spec.rb +2 -0
- data/spec/spec_helper.rb +3 -1
- data/spec/support/hash.rb +2 -0
- data/spec/support/response.rb +2 -0
- data/spec/support/service.rb +1 -0
- data/spec/support/shared/find_callbacks.rb +2 -0
- metadata +26 -26
data/lib/acfs/util.rb
CHANGED
data/lib/acfs/version.rb
CHANGED
data/lib/acfs/yard.rb
CHANGED
@@ -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
|
-
|
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://
|
13
|
+
request1 = Acfs::Request.new 'http://example.org' do |_rsp|
|
9
14
|
raise '404-1'
|
10
15
|
end
|
11
|
-
request2 = Acfs::Request.new 'http://
|
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) {
|
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'
|
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'
|
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'
|
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'
|
139
|
+
'Link' => '<http://users.example.org/users?page=12>; rel="last"'
|
138
140
|
})
|
139
141
|
end
|
140
142
|
let!(:req) do
|
data/spec/acfs/global_spec.rb
CHANGED
@@ -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 }
|
123
|
-
runner2 = Thread.new { acfs.runner }
|
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
|
data/spec/acfs/location_spec.rb
CHANGED
@@ -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(
|
64
|
+
expect { request.complete! response }.to raise_error(::JSON::ParserError)
|
49
65
|
end
|
50
66
|
end
|
51
67
|
|
data/spec/acfs/operation_spec.rb
CHANGED
data/spec/acfs/request_spec.rb
CHANGED
@@ -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 ==
|
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::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
|
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
|
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
|
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::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
|
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
|
23
|
+
it { expect(subject.call).to eq [] }
|
22
24
|
end
|
23
25
|
|
24
26
|
context 'with array' do
|
25
|
-
let(:value) { %w
|
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 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'
|
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'
|
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
|
-
|
87
|
-
|
88
|
-
|
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
|
174
|
+
expect(submodel.attributes.keys).to match_array %w[age born_at]
|
175
175
|
end
|
176
176
|
end
|
177
177
|
end
|
@@ -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
|
8
|
-
|
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::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
|
-
|
230
|
-
|
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
|
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
|
304
|
+
expect(subject.errors.to_hash).to eq name: %w[required]
|
299
305
|
end
|
300
306
|
end
|
301
307
|
|