acfs 1.4.0 → 1.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +26 -0
- data/README.md +22 -39
- data/acfs.gemspec +8 -14
- data/lib/acfs/adapter/base.rb +2 -0
- data/lib/acfs/adapter/typhoeus.rb +16 -11
- data/lib/acfs/collections/paginatable.rb +1 -1
- data/lib/acfs/configuration.rb +13 -3
- data/lib/acfs/errors.rb +41 -21
- data/lib/acfs/global.rb +2 -2
- data/lib/acfs/location.rb +26 -32
- data/lib/acfs/middleware/base.rb +2 -2
- data/lib/acfs/middleware/json.rb +4 -2
- data/lib/acfs/middleware/logger.rb +4 -6
- data/lib/acfs/middleware/serializer.rb +1 -1
- data/lib/acfs/operation.rb +21 -8
- data/lib/acfs/request/callbacks.rb +4 -4
- data/lib/acfs/request.rb +4 -11
- data/lib/acfs/resource/attributes/date_time.rb +1 -1
- data/lib/acfs/resource/attributes/uuid.rb +1 -1
- data/lib/acfs/resource/attributes.rb +16 -15
- data/lib/acfs/resource/dirty.rb +2 -2
- data/lib/acfs/resource/initialization.rb +5 -5
- data/lib/acfs/resource/locatable.rb +11 -8
- data/lib/acfs/resource/operational.rb +6 -3
- data/lib/acfs/resource/persistence.rb +13 -15
- data/lib/acfs/resource/query_methods.rb +10 -10
- data/lib/acfs/resource/service.rb +2 -2
- data/lib/acfs/resource/validation.rb +17 -7
- data/lib/acfs/response.rb +5 -5
- data/lib/acfs/runner.rb +15 -15
- data/lib/acfs/service.rb +16 -19
- data/lib/acfs/singleton_resource.rb +2 -2
- data/lib/acfs/stub.rb +41 -31
- data/lib/acfs/version.rb +2 -2
- data/spec/acfs/adapter/typhoeus_spec.rb +2 -2
- data/spec/acfs/collection_spec.rb +66 -41
- data/spec/acfs/configuration_spec.rb +22 -12
- data/spec/acfs/global_spec.rb +11 -9
- data/spec/acfs/location_spec.rb +2 -2
- data/spec/acfs/middleware/json_spec.rb +22 -8
- data/spec/acfs/middleware/{msgpack_spec.rb → message_pack_spec.rb} +6 -6
- data/spec/acfs/operation_spec.rb +3 -2
- data/spec/acfs/request/callbacks_spec.rb +19 -10
- data/spec/acfs/request_spec.rb +16 -20
- data/spec/acfs/resource/attributes/boolean_spec.rb +32 -32
- data/spec/acfs/resource/attributes/date_time_spec.rb +16 -8
- data/spec/acfs/resource/attributes/dict_spec.rb +15 -9
- data/spec/acfs/resource/attributes/float_spec.rb +20 -10
- data/spec/acfs/resource/attributes/integer_spec.rb +10 -5
- data/spec/acfs/resource/attributes/list_spec.rb +13 -8
- data/spec/acfs/resource/attributes/uuid_spec.rb +12 -6
- data/spec/acfs/resource/attributes_spec.rb +37 -38
- data/spec/acfs/resource/dirty_spec.rb +6 -3
- data/spec/acfs/resource/initialization_spec.rb +4 -5
- data/spec/acfs/resource/loadable_spec.rb +3 -1
- data/spec/acfs/resource/locatable_spec.rb +24 -18
- data/spec/acfs/resource/{persistance_spec.rb → persistence_spec.rb} +122 -90
- data/spec/acfs/resource/query_methods_spec.rb +143 -110
- data/spec/acfs/resource/validation_spec.rb +34 -27
- data/spec/acfs/response/formats_spec.rb +8 -8
- data/spec/acfs/response/status_spec.rb +16 -9
- data/spec/acfs/runner_spec.rb +10 -8
- data/spec/acfs/service/middleware_spec.rb +3 -3
- data/spec/acfs/service_spec.rb +6 -5
- data/spec/acfs/singleton_resource_spec.rb +2 -1
- data/spec/acfs/stub_spec.rb +57 -53
- data/spec/acfs_spec.rb +111 -93
- data/spec/spec_helper.rb +1 -2
- data/spec/support/response.rb +2 -2
- data/spec/support/service.rb +1 -1
- data/spec/support/shared/find_callbacks.rb +14 -10
- metadata +30 -29
@@ -9,12 +9,12 @@ describe Acfs::Resource::Attributes do
|
|
9
9
|
describe '#initialize' do
|
10
10
|
before { model.attribute :name, :string, default: 'John' }
|
11
11
|
|
12
|
-
it '
|
12
|
+
it 'has attribute list' do
|
13
13
|
expect(model.new.attributes).to include(:name)
|
14
14
|
end
|
15
15
|
|
16
|
-
it '
|
17
|
-
expect(model.new.name).to
|
16
|
+
it 'sets default attributes' do
|
17
|
+
expect(model.new.name).to eq 'John'
|
18
18
|
end
|
19
19
|
|
20
20
|
context 'with dynamic default value' do
|
@@ -23,8 +23,8 @@ describe Acfs::Resource::Attributes do
|
|
23
23
|
model.attribute :mail, :string, default: -> { "#{name}@srv.tld" }
|
24
24
|
end
|
25
25
|
|
26
|
-
it '
|
27
|
-
expect(model.new.mail).to
|
26
|
+
it 'sets dynamic default attributes' do
|
27
|
+
expect(model.new.mail).to eq 'John@srv.tld'
|
28
28
|
end
|
29
29
|
end
|
30
30
|
end
|
@@ -35,12 +35,14 @@ describe Acfs::Resource::Attributes do
|
|
35
35
|
model.attribute :age, :integer, default: 25
|
36
36
|
end
|
37
37
|
|
38
|
-
it '
|
38
|
+
it 'returns hash of all attributes' do
|
39
39
|
expect(model.new.attributes).to eq(name: 'John', age: 25)
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
43
|
describe '#write_attributes' do
|
44
|
+
subject(:action) { -> { m.write_attributes(params, **opts) } }
|
45
|
+
|
44
46
|
before do
|
45
47
|
model.attribute :name, :string, default: 'John'
|
46
48
|
model.attribute :age, :integer, default: 25
|
@@ -48,14 +50,13 @@ describe Acfs::Resource::Attributes do
|
|
48
50
|
write_attribute :name, "The Great #{name}"
|
49
51
|
end
|
50
52
|
end
|
51
|
-
|
53
|
+
|
52
54
|
let(:params) { {name: 'James'} }
|
55
|
+
let(:opts) { {} }
|
53
56
|
let(:m) { model.new }
|
54
|
-
let(:action) { -> { m.write_attributes(*args) } }
|
55
|
-
subject { action }
|
56
57
|
|
57
|
-
it '
|
58
|
-
|
58
|
+
it 'updates attributes' do
|
59
|
+
expect(action).to change(m, :attributes)
|
59
60
|
.from(name: 'The Great John', age: 25)
|
60
61
|
.to(name: 'The Great James', age: 25)
|
61
62
|
end
|
@@ -63,34 +64,32 @@ describe Acfs::Resource::Attributes do
|
|
63
64
|
context 'without non-hash params' do
|
64
65
|
let(:params) { 'James' }
|
65
66
|
|
66
|
-
it {
|
67
|
-
|
67
|
+
it { expect(action).not_to change(m, :attributes) }
|
68
|
+
it { expect(action.call).to eq false }
|
68
69
|
end
|
69
70
|
|
70
71
|
context 'with unknown attributes' do
|
71
72
|
let(:params) { {name: 'James', born_at: 'today'} }
|
72
73
|
|
73
|
-
it {
|
74
|
+
it { expect(action).not_to raise_error }
|
74
75
|
|
75
|
-
it '
|
76
|
-
|
76
|
+
it 'updates known attributes and store unknown' do
|
77
|
+
expect(action).to change(m, :attributes)
|
77
78
|
.from(name: 'The Great John', age: 25)
|
78
79
|
.to(name: 'The Great James', age: 25, born_at: 'today')
|
79
80
|
end
|
80
81
|
|
81
82
|
context 'with unknown: :raise option' do
|
82
|
-
let(:
|
83
|
+
let(:opts) { {unknown: :raise} }
|
83
84
|
|
84
|
-
it {
|
85
|
+
it { expect(action).to raise_error(ArgumentError, /unknown attribute/i) }
|
85
86
|
|
86
87
|
it do
|
87
88
|
expect do
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
end
|
93
|
-
end.to_not change(m, :attributes)
|
89
|
+
action.call
|
90
|
+
rescue StandardError
|
91
|
+
true
|
92
|
+
end.not_to change(m, :attributes)
|
94
93
|
end
|
95
94
|
end
|
96
95
|
end
|
@@ -99,15 +98,15 @@ describe Acfs::Resource::Attributes do
|
|
99
98
|
describe '#_getter_' do
|
100
99
|
before { model.attribute :name, :string, default: 'John' }
|
101
100
|
|
102
|
-
it '
|
101
|
+
it 'returns value' do
|
103
102
|
mo = model.new
|
104
103
|
mo.name = 'Paul'
|
105
104
|
|
106
|
-
expect(mo.name).to
|
105
|
+
expect(mo.name).to eq 'Paul'
|
107
106
|
end
|
108
107
|
|
109
|
-
it '
|
110
|
-
expect(model.new.name).to
|
108
|
+
it 'returns default value' do
|
109
|
+
expect(model.new.name).to eq 'John'
|
111
110
|
end
|
112
111
|
end
|
113
112
|
|
@@ -117,49 +116,49 @@ describe Acfs::Resource::Attributes do
|
|
117
116
|
model.attribute :age, :integer, default: '25'
|
118
117
|
end
|
119
118
|
|
120
|
-
it '
|
119
|
+
it 'sets value' do
|
121
120
|
o = model.new
|
122
121
|
o.name = 'Paul'
|
123
122
|
|
124
|
-
expect(o.name).to
|
123
|
+
expect(o.name).to eq 'Paul'
|
125
124
|
end
|
126
125
|
|
127
|
-
it '
|
126
|
+
it 'updates attributes hash' do
|
128
127
|
o = model.new
|
129
128
|
o.name = 'Johannes'
|
130
129
|
|
131
|
-
expect(o.attributes['name']).to
|
130
|
+
expect(o.attributes['name']).to eq 'Johannes'
|
132
131
|
end
|
133
132
|
|
134
|
-
it '
|
133
|
+
it 'casts values' do
|
135
134
|
o = model.new
|
136
135
|
o.age = '28'
|
137
136
|
|
138
|
-
expect(o.age).to
|
137
|
+
expect(o.age).to eq 28
|
139
138
|
end
|
140
139
|
end
|
141
140
|
|
142
141
|
describe 'class' do
|
143
142
|
describe '#attributes' do
|
144
|
-
it '
|
143
|
+
it 'adds an attribute to model attribute list' do
|
145
144
|
model.send :attribute, :name, :string
|
146
145
|
|
147
146
|
expect(model.attributes.symbolize_keys).to eq name: nil
|
148
147
|
end
|
149
148
|
|
150
|
-
it '
|
149
|
+
it 'accepts a default value' do
|
151
150
|
model.send :attribute, :name, :string, default: 'John'
|
152
151
|
|
153
152
|
expect(model.attributes.symbolize_keys).to eq name: 'John'
|
154
153
|
end
|
155
154
|
|
156
|
-
it '
|
155
|
+
it 'accepts a symbolic type' do
|
157
156
|
model.send :attribute, :age, :integer, default: '12'
|
158
157
|
|
159
158
|
expect(model.attributes.symbolize_keys).to eq age: 12
|
160
159
|
end
|
161
160
|
|
162
|
-
it '
|
161
|
+
it 'accepts a class type' do
|
163
162
|
model.send :attribute, :age, Acfs::Resource::Attributes::Integer,
|
164
163
|
default: '12'
|
165
164
|
|
@@ -4,6 +4,7 @@ require 'spec_helper'
|
|
4
4
|
|
5
5
|
describe Acfs::Resource::Dirty do
|
6
6
|
let(:model) { MyUser.new }
|
7
|
+
|
7
8
|
before do
|
8
9
|
stub_request(:get, 'http://users.example.org/users/1')
|
9
10
|
.to_return response id: 1, name: 'Anon', age: 12
|
@@ -23,21 +24,23 @@ describe Acfs::Resource::Dirty do
|
|
23
24
|
|
24
25
|
context 'and saving' do
|
25
26
|
before { user.save }
|
26
|
-
|
27
|
+
|
28
|
+
it { expect(user).not_to be_changed }
|
27
29
|
end
|
28
30
|
end
|
29
31
|
|
30
32
|
context 'after model load' do
|
31
33
|
let(:user) { MyUser.find 1 }
|
34
|
+
|
32
35
|
before { user && Acfs.run }
|
33
36
|
|
34
|
-
it { expect(user).
|
37
|
+
it { expect(user).not_to be_changed }
|
35
38
|
end
|
36
39
|
|
37
40
|
context 'after model new without attrs' do
|
38
41
|
let(:user) { MyUser.new }
|
39
42
|
|
40
|
-
it { expect(user).
|
43
|
+
it { expect(user).not_to be_changed }
|
41
44
|
end
|
42
45
|
|
43
46
|
context 'after model new with attrs' do
|
@@ -17,20 +17,19 @@ describe 'Acfs::Resource::Initialization' do
|
|
17
17
|
end
|
18
18
|
|
19
19
|
describe '#initialize' do
|
20
|
-
it '
|
20
|
+
it 'allows to set attributes with initializer' do
|
21
21
|
m = model.new name: 'John'
|
22
22
|
expect(m.name).to eq 'John'
|
23
23
|
end
|
24
24
|
|
25
|
-
it '
|
25
|
+
it 'raises error when attributes with private setters are given' do
|
26
26
|
expect { model.new age: 25 }.to raise_error(NoMethodError)
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
30
|
describe '#persisted?' do
|
31
|
-
|
32
|
-
|
33
|
-
should be false
|
31
|
+
it 'is false' do
|
32
|
+
expect(model.new.persisted?).to be false
|
34
33
|
end
|
35
34
|
end
|
36
35
|
end
|
@@ -4,6 +4,7 @@ require 'spec_helper'
|
|
4
4
|
|
5
5
|
describe Acfs::Resource::Loadable do
|
6
6
|
let(:model) { MyUser.find 1 }
|
7
|
+
|
7
8
|
before do
|
8
9
|
stub_request(:get, 'http://users.example.org/users/1')
|
9
10
|
.to_return response id: 1, name: 'Anon', age: 12
|
@@ -11,11 +12,12 @@ describe Acfs::Resource::Loadable do
|
|
11
12
|
|
12
13
|
describe '#loaded?' do
|
13
14
|
context 'before Acfs#run' do
|
14
|
-
it { expect(model).
|
15
|
+
it { expect(model).not_to be_loaded }
|
15
16
|
end
|
16
17
|
|
17
18
|
context 'afer Acfs#run' do
|
18
19
|
before { model && Acfs.run }
|
20
|
+
|
19
21
|
it { expect(model).to be_loaded }
|
20
22
|
end
|
21
23
|
end
|
@@ -4,6 +4,7 @@ require 'spec_helper'
|
|
4
4
|
|
5
5
|
describe Acfs::Resource::Locatable do
|
6
6
|
let(:model) { MyUser }
|
7
|
+
|
7
8
|
before do
|
8
9
|
stub_request(:get, 'http://users.example.org/users/1')
|
9
10
|
.to_return response id: 1, name: 'Anon', age: 12
|
@@ -12,63 +13,67 @@ describe Acfs::Resource::Locatable do
|
|
12
13
|
end
|
13
14
|
|
14
15
|
describe '.url' do
|
15
|
-
it '
|
16
|
-
expect(model.url).to
|
16
|
+
it 'returns URL' do
|
17
|
+
expect(model.url).to eq 'http://users.example.org/users'
|
17
18
|
end
|
18
19
|
|
19
|
-
it '
|
20
|
-
expect(model.url(5)).to
|
20
|
+
it 'returns URL with id path part if specified' do
|
21
|
+
expect(model.url(5)).to eq 'http://users.example.org/users/5'
|
21
22
|
end
|
22
23
|
|
23
24
|
context 'with attribute in path' do
|
24
25
|
let(:model) { Profile }
|
25
26
|
|
26
|
-
it '
|
27
|
+
it 'replaces placeholder' do
|
27
28
|
expect(model.url(user_id: 1))
|
28
29
|
.to eq 'http://users.example.org/users/1/profile'
|
29
30
|
end
|
30
31
|
|
31
32
|
context 'without attributes' do
|
32
|
-
it '
|
33
|
+
it 'raises an error if attribute is missing' do
|
33
34
|
expect { model.url }.to raise_error ArgumentError
|
34
35
|
end
|
35
36
|
end
|
36
37
|
end
|
37
38
|
|
38
39
|
describe 'custom paths' do
|
40
|
+
subject(:location) { Session.location(action: action) }
|
41
|
+
|
39
42
|
let(:model) { Session }
|
40
|
-
let(:location) { Session.location action: action }
|
41
|
-
subject { location }
|
42
43
|
|
43
44
|
context ':list location' do
|
44
45
|
let(:action) { :list }
|
45
46
|
|
46
47
|
its(:raw_uri) do
|
47
|
-
|
48
|
+
is_expected.to eq 'http://users.example.org/users/:user_id/sessions'
|
48
49
|
end
|
49
50
|
end
|
50
51
|
|
51
52
|
context ':create location' do
|
52
53
|
let(:action) { :create }
|
53
|
-
|
54
|
+
|
55
|
+
its(:raw_uri) { is_expected.to eq 'http://users.example.org/sessions' }
|
54
56
|
end
|
55
57
|
|
56
58
|
context ':read location' do
|
57
59
|
let(:action) { :read }
|
58
|
-
|
60
|
+
|
61
|
+
its(:raw_uri) { is_expected.to eq 'http://users.example.org/sessions/:id' }
|
59
62
|
end
|
60
63
|
|
61
64
|
context ':update location' do
|
62
65
|
let(:action) { :update }
|
66
|
+
|
63
67
|
its(:raw_uri) do
|
64
|
-
expect {
|
68
|
+
expect { location }.to raise_error ArgumentError, /update.*disabled/
|
65
69
|
end
|
66
70
|
end
|
67
71
|
|
68
72
|
context ':delete location' do
|
69
73
|
let(:action) { :delete }
|
74
|
+
|
70
75
|
its(:raw_uri) do
|
71
|
-
|
76
|
+
is_expected.to eq 'http://users.example.org/users/:user_id/sessions/del/:id'
|
72
77
|
end
|
73
78
|
end
|
74
79
|
end
|
@@ -78,20 +83,20 @@ describe Acfs::Resource::Locatable do
|
|
78
83
|
context 'new resource' do
|
79
84
|
let(:m) { model.new }
|
80
85
|
|
81
|
-
it '
|
86
|
+
it 'returns nil' do
|
82
87
|
expect(m.url).to be_nil
|
83
88
|
end
|
84
89
|
|
85
90
|
context 'new resource with id' do
|
86
91
|
let(:m) { model.new id: 475 }
|
87
92
|
|
88
|
-
it '
|
93
|
+
it 'returns resource URL' do
|
89
94
|
expect(m.url).to eq 'http://users.example.org/users/475'
|
90
95
|
end
|
91
96
|
end
|
92
97
|
|
93
98
|
context 'with attribute in path' do
|
94
|
-
it '
|
99
|
+
it 'returns nil' do
|
95
100
|
expect(m.url).to be_nil
|
96
101
|
end
|
97
102
|
end
|
@@ -99,9 +104,10 @@ describe Acfs::Resource::Locatable do
|
|
99
104
|
|
100
105
|
context 'loaded resource' do
|
101
106
|
let(:m) { model.find 1 }
|
107
|
+
|
102
108
|
before { m && Acfs.run }
|
103
109
|
|
104
|
-
it "
|
110
|
+
it "returns resource's URL" do
|
105
111
|
expect(m.url).to eq 'http://users.example.org/users/1'
|
106
112
|
end
|
107
113
|
|
@@ -109,7 +115,7 @@ describe Acfs::Resource::Locatable do
|
|
109
115
|
let(:model) { Profile }
|
110
116
|
let(:m) { model.find user_id: 1 }
|
111
117
|
|
112
|
-
it "
|
118
|
+
it "returns resource's URL" do
|
113
119
|
expect(m.url).to eq 'http://users.example.org/users/2/profile'
|
114
120
|
end
|
115
121
|
end
|