cistern 2.4.1 → 2.5.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 +8 -1
- data/lib/cistern/attributes.rb +12 -0
- data/lib/cistern/version.rb +1 -1
- data/spec/attributes_spec.rb +177 -83
- data/spec/coverage_spec.rb +19 -15
- data/spec/dirty_spec.rb +10 -8
- data/spec/mock_data_spec.rb +14 -12
- data/spec/singular_spec.rb +15 -13
- data/spec/support/service.rb +7 -0
- data/spec/wait_for_spec.rb +47 -44
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 51b4a1fc74578d0a0a8f89bb9b041501ab850ac9
|
4
|
+
data.tar.gz: 3f24e1b8145497a84d6f6b0fa449aa11b7d5e7f1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2f7a72df05bb6c95d5176a36b8e8d0d17f9c9bd3179cec7424e4fc66e216e24f148bff977e4ba19f1bcee0d5afad60757e193a83bf926401a9d40be70e75a223
|
7
|
+
data.tar.gz: f2221f974e0817e5410e88a8d4586f28881756fcbea1836e52d8440ec97f50dfe689ae3758820e1225c2de006bfcfb0dbc0065ab70cbc0980fc2fda2f8a96b78
|
data/CHANGELOG.md
CHANGED
@@ -2,7 +2,14 @@
|
|
2
2
|
|
3
3
|
## [Unreleased](https://github.com/lanej/cistern/tree/HEAD)
|
4
4
|
|
5
|
-
[Full Changelog](https://github.com/lanej/cistern/compare/v2.4.
|
5
|
+
[Full Changelog](https://github.com/lanej/cistern/compare/v2.4.1...HEAD)
|
6
|
+
|
7
|
+
**Implemented enhancements:**
|
8
|
+
|
9
|
+
- add request\_attributes, dirty\_request\_attributes helpers [\#65](https://github.com/lanej/cistern/pull/65) ([lanej](https://github.com/lanej))
|
10
|
+
|
11
|
+
## [v2.4.1](https://github.com/lanej/cistern/tree/v2.4.1) (2016-07-16)
|
12
|
+
[Full Changelog](https://github.com/lanej/cistern/compare/v2.4.0...v2.4.1)
|
6
13
|
|
7
14
|
**Merged pull requests:**
|
8
15
|
|
data/lib/cistern/attributes.rb
CHANGED
@@ -265,6 +265,18 @@ module Cistern::Attributes
|
|
265
265
|
@changes ||= {}
|
266
266
|
end
|
267
267
|
|
268
|
+
def request_attributes(set = attributes)
|
269
|
+
set.inject({}) do |a,(k,v)|
|
270
|
+
aliases = self.class.attributes[k.to_sym][:aliases]
|
271
|
+
aliases << k if aliases.empty?
|
272
|
+
aliases.each_with_object(a) { |n,r| r[n.to_s] = v }
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
def dirty_request_attributes
|
277
|
+
request_attributes(dirty_attributes)
|
278
|
+
end
|
279
|
+
|
268
280
|
private
|
269
281
|
|
270
282
|
def missing_attributes(keys)
|
data/lib/cistern/version.rb
CHANGED
data/spec/attributes_spec.rb
CHANGED
@@ -1,166 +1,260 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe Cistern::Attributes, '
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
describe Cistern::Attributes, '#request_attributes' do
|
4
|
+
subject { Class.new(Sample::Model) }
|
5
|
+
|
6
|
+
it 'returns a reverse-aliased attributes hash' do
|
7
|
+
subject.class_eval do
|
8
|
+
identity :id
|
9
|
+
attribute :name, alias: 'sample_name'
|
10
|
+
end
|
11
|
+
|
12
|
+
model = subject.new(name: 'steve', id: 1)
|
13
|
+
|
14
|
+
expect(model.request_attributes).to eq(
|
15
|
+
'sample_name' => 'steve',
|
16
|
+
'id' => 1
|
17
|
+
)
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'drops duplicates values for multiple aliases' do
|
21
|
+
subject.class_eval do
|
22
|
+
identity :id
|
23
|
+
attribute :name, aliases: ['sample_name', 'other_name']
|
24
|
+
end
|
25
|
+
|
26
|
+
model = subject.new(name: 'steve', id: 1)
|
27
|
+
|
28
|
+
expect(model.request_attributes).to eq(
|
29
|
+
'sample_name' => 'steve',
|
30
|
+
'other_name' => 'steve',
|
31
|
+
'id' => 1
|
32
|
+
)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe Cistern::Attributes, '#dirty_request_attributes' do
|
37
|
+
subject { Class.new(Sample::Model) }
|
38
|
+
|
39
|
+
it 'returns a reverse-aliased attributes hash of dirty attributes only' do
|
40
|
+
subject.class_eval do
|
41
|
+
identity :id
|
42
|
+
attribute :name, alias: 'sample_name'
|
43
|
+
end
|
44
|
+
|
45
|
+
model = subject.new
|
46
|
+
model.merge_attributes(name: 'steve', id: 1)
|
47
|
+
|
48
|
+
model.name = 'bob'
|
49
|
+
|
50
|
+
expect(model.dirty_request_attributes).to eq(
|
51
|
+
'sample_name' => 'bob',
|
52
|
+
)
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'drops duplicates values for multiple aliases' do
|
56
|
+
subject.class_eval do
|
57
|
+
identity :id
|
58
|
+
attribute :name, aliases: ['sample_name', 'other_name']
|
59
|
+
end
|
60
|
+
|
61
|
+
model = subject.new(name: 'steve', id: 1)
|
62
|
+
|
63
|
+
expect(model.request_attributes).to eq(
|
64
|
+
'sample_name' => 'steve',
|
65
|
+
'other_name' => 'steve',
|
66
|
+
'id' => 1
|
67
|
+
)
|
8
68
|
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe Cistern::Attributes, 'requires' do
|
72
|
+
subject {
|
73
|
+
Class.new(Sample::Model) do
|
74
|
+
identity :id
|
75
|
+
attribute :name, type: :string
|
76
|
+
attribute :type
|
77
|
+
end
|
78
|
+
}
|
9
79
|
|
10
80
|
it 'raises if required attributes are not present' do
|
11
81
|
expect {
|
12
|
-
|
82
|
+
subject.new.requires :name
|
13
83
|
}.to raise_exception(ArgumentError, /name is required/)
|
14
84
|
|
15
85
|
data = { name: '1' }
|
16
|
-
return_value =
|
86
|
+
return_value = subject.new(data).requires :name
|
17
87
|
|
18
88
|
expect(return_value).to eq(data)
|
19
89
|
|
20
90
|
expect {
|
21
|
-
|
91
|
+
subject.new.requires :name, :type
|
22
92
|
}.to raise_exception(ArgumentError, /name and type are required/)
|
23
93
|
|
24
94
|
data = { name: '1', type: 'sample' }
|
25
|
-
return_values =
|
95
|
+
return_values = subject.new(data).requires :name, :type
|
26
96
|
expect(return_values).to eq(data)
|
27
97
|
end
|
28
98
|
|
29
99
|
it 'raises if a required attribute attribute is not present' do
|
30
100
|
expect {
|
31
|
-
|
101
|
+
subject.new.requires_one :name, :type
|
32
102
|
}.to raise_exception(ArgumentError, /name or type are required/)
|
33
103
|
|
34
104
|
data = { name: '1' }
|
35
|
-
return_value =
|
105
|
+
return_value = subject.new(data).requires_one :name, :type
|
36
106
|
|
37
107
|
expect(return_value).to eq(data)
|
38
108
|
|
39
109
|
data = { name: '1', type: 'sample' }
|
40
|
-
return_values =
|
110
|
+
return_values = subject.new(data).requires_one :name, :type
|
41
111
|
expect(return_values).to eq(data)
|
42
112
|
end
|
43
113
|
end
|
44
114
|
|
45
115
|
describe Cistern::Attributes, 'parsing' do
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
attribute :created_at, type: :time
|
50
|
-
attribute :flag, type: :boolean
|
51
|
-
attribute :list, type: :array
|
52
|
-
attribute :number, type: :integer
|
53
|
-
attribute :floater, type: :float
|
54
|
-
attribute :butternut_id, squash: %w(squash id), type: :integer
|
55
|
-
attribute :butternut_type, squash: %w(squash type)
|
56
|
-
attribute :squash
|
57
|
-
attribute :vegetable, aliases: 'squash'
|
58
|
-
attribute :custom, parser: lambda { |v, _| "X!#{v}" }
|
59
|
-
attribute :default, default: 'im a squash'
|
60
|
-
attribute :string_allow_nil, type: :string, allow_nil: true
|
61
|
-
|
62
|
-
attribute :same_alias_1, aliases: 'nested'
|
63
|
-
attribute :same_alias_2, aliases: 'nested'
|
64
|
-
|
65
|
-
attribute :same_alias_squashed_1, squash: %w(nested attr_1)
|
66
|
-
attribute :same_alias_squashed_2, squash: %w(nested attr_2)
|
67
|
-
attribute :same_alias_squashed_3, squash: %w(nested attr_2)
|
68
|
-
attribute :adam_attributes, aliases: 'attributes'
|
69
|
-
|
70
|
-
def save
|
71
|
-
requires :flag
|
72
|
-
end
|
73
|
-
end
|
116
|
+
subject {
|
117
|
+
Class.new(Sample::Model)
|
118
|
+
}
|
74
119
|
|
75
120
|
it 'should parse string' do
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
end
|
121
|
+
subject.class_eval do
|
122
|
+
attribute :name, type: :string
|
123
|
+
end
|
80
124
|
|
81
|
-
|
82
|
-
expect(
|
125
|
+
expect(subject.new(name: 1).name).to eq('1')
|
126
|
+
expect(subject.new(name: "b").name).to eq('b')
|
127
|
+
expect(subject.new(name: nil).name).to eq(nil)
|
83
128
|
end
|
129
|
+
|
84
130
|
it "should handle a 'attributes' aliased attribute" do
|
85
|
-
|
131
|
+
subject.class_eval do
|
132
|
+
attribute :adam_attributes, aliases: 'attributes'
|
133
|
+
end
|
134
|
+
expect(subject.new(attributes: 'x').adam_attributes).to eq('x')
|
86
135
|
end
|
87
136
|
|
88
137
|
it 'should parse time' do
|
138
|
+
subject.class_eval do
|
139
|
+
attribute :created_at, type: :time
|
140
|
+
end
|
141
|
+
|
89
142
|
time = Time.now
|
90
|
-
created_at =
|
143
|
+
created_at = subject.new(created_at: time.to_s).created_at
|
91
144
|
expect(created_at).to be_a(Time)
|
92
145
|
expect(created_at.to_i).to eq(time.to_i)
|
93
146
|
end
|
94
147
|
|
95
148
|
it 'should parse boolean' do
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
149
|
+
subject.class_eval do
|
150
|
+
attribute :flag, type: :boolean
|
151
|
+
end
|
152
|
+
|
153
|
+
['false', false, '0', 0].each do |falsey|
|
154
|
+
expect(subject.new(flag: falsey).flag).to be_falsey
|
155
|
+
end
|
156
|
+
|
157
|
+
['true', true, '1', 1].each do |truthy|
|
158
|
+
expect(subject.new(flag: truthy).flag).to be_truthy
|
159
|
+
end
|
106
160
|
end
|
107
161
|
|
108
162
|
it 'should parse an array' do
|
109
|
-
|
110
|
-
|
163
|
+
subject.class_eval do
|
164
|
+
attribute :list, type: :array
|
165
|
+
end
|
166
|
+
|
167
|
+
expect(subject.new(list: []).list).to eq([])
|
168
|
+
expect(subject.new(list: 'item').list).to eq(['item'])
|
111
169
|
end
|
112
170
|
|
113
171
|
it 'should parse a float' do
|
114
|
-
|
115
|
-
|
172
|
+
subject.class_eval do
|
173
|
+
attribute :floater, type: :float
|
174
|
+
end
|
175
|
+
|
176
|
+
expect(subject.new(floater: '0.01').floater).to eq(0.01)
|
177
|
+
expect(subject.new(floater: 0.01).floater).to eq(0.01)
|
116
178
|
end
|
117
179
|
|
118
180
|
it 'should use custom parser' do
|
119
|
-
|
181
|
+
subject.class_eval do
|
182
|
+
attribute :custom, parser: lambda { |v, _| "X!#{v}" }
|
183
|
+
end
|
184
|
+
|
185
|
+
expect(subject.new(custom: '15').custom).to eq('X!15')
|
120
186
|
end
|
121
187
|
|
122
|
-
it '
|
188
|
+
it 'squashes, casts and aliases an attribute and keeps a vanilla reference' do
|
189
|
+
subject.class_eval do
|
190
|
+
attribute :butternut_id, squash: %w(squash id), type: :integer
|
191
|
+
attribute :butternut_type, squash: %w(squash type)
|
192
|
+
attribute :squash
|
193
|
+
attribute :vegetable, aliases: 'squash'
|
194
|
+
end
|
195
|
+
|
123
196
|
# vanilla squash
|
124
|
-
expect(
|
125
|
-
expect(
|
126
|
-
expect(
|
197
|
+
expect(subject.new({ 'squash' => { 'id' => '12', 'type' => 'fred' } }).butternut_type).to eq('fred')
|
198
|
+
expect(subject.new({ 'squash' => { 'id' => '12', 'type' => nil } }).butternut_type).to be_nil
|
199
|
+
expect(subject.new({ 'squash' => nil }).butternut_type).to be_nil
|
127
200
|
|
128
201
|
# composite processors: squash and cast
|
129
|
-
expect(
|
130
|
-
expect(
|
131
|
-
expect(
|
202
|
+
expect(subject.new({ 'squash' => { 'id' => '12', 'type' => 'fred' } }).butternut_id).to eq(12)
|
203
|
+
expect(subject.new({ 'squash' => { 'id' => nil, 'type' => 'fred' } }).butternut_id).to be_nil
|
204
|
+
expect(subject.new({ 'squash' => { 'type' => 'fred' } }).butternut_id).to be_nil
|
132
205
|
|
133
206
|
# override intermediate processing
|
134
|
-
expect(
|
207
|
+
expect(subject.new({ 'squash' => { 'id' => '12', 'type' => 'fred' } }).squash).to eq({ 'id' => '12', 'type' => 'fred' })
|
135
208
|
|
136
209
|
# alias of override
|
137
|
-
expect(
|
210
|
+
expect(subject.new({ 'squash' => { 'id' => '12', 'type' => 'fred' } }).vegetable).to eq({ 'id' => '12', 'type' => 'fred' })
|
138
211
|
end
|
139
212
|
|
140
|
-
it '
|
141
|
-
|
213
|
+
it 'sets a default value' do
|
214
|
+
subject.class_eval do
|
215
|
+
attribute :default, default: 'im a squash'
|
216
|
+
end
|
217
|
+
|
218
|
+
expect(subject.new.default).to eq('im a squash')
|
142
219
|
end
|
143
220
|
|
144
221
|
it 'should override a default value' do
|
145
|
-
|
222
|
+
subject.class_eval do
|
223
|
+
attribute :default, default: 'im a squash'
|
224
|
+
end
|
225
|
+
|
226
|
+
expect(subject.new(default: 'now im a different squash').default).to eq('now im a different squash')
|
146
227
|
end
|
147
228
|
|
148
229
|
context 'allowing the same alias for multiple attributes' do
|
230
|
+
before {
|
231
|
+
subject.class_eval do
|
232
|
+
attribute :same_alias_1, aliases: 'nested'
|
233
|
+
attribute :same_alias_2, aliases: 'nested'
|
234
|
+
|
235
|
+
attribute :same_alias_squashed_1, squash: %w(nested attr_1)
|
236
|
+
attribute :same_alias_squashed_2, squash: %w(nested attr_2)
|
237
|
+
attribute :same_alias_squashed_3, squash: %w(nested attr_2)
|
238
|
+
end
|
239
|
+
}
|
240
|
+
|
149
241
|
it 'should do so when not squashing' do
|
150
|
-
|
151
|
-
|
152
|
-
expect(
|
242
|
+
model = subject.new('nested' => 'bamboo')
|
243
|
+
|
244
|
+
expect(model.same_alias_1).to eq('bamboo')
|
245
|
+
expect(model.same_alias_2).to eq('bamboo')
|
153
246
|
end
|
154
247
|
|
155
248
|
it 'should do so when squashing' do
|
156
|
-
|
157
|
-
|
158
|
-
expect(
|
159
|
-
expect(
|
249
|
+
model = subject.new('nested' => { 'attr_1' => 'bamboo', 'attr_2' => 'panda' })
|
250
|
+
|
251
|
+
expect(model.same_alias_squashed_1).to eq('bamboo')
|
252
|
+
expect(model.same_alias_squashed_2).to eq('panda')
|
253
|
+
expect(model.same_alias_squashed_3).to eq('panda')
|
160
254
|
end
|
161
255
|
end
|
162
256
|
|
163
257
|
it 'should slice out unaccounted for attributes' do
|
164
|
-
expect(
|
258
|
+
expect(subject.new({ 'something' => { 'id' => '12' } }).attributes.keys).not_to include('something')
|
165
259
|
end
|
166
260
|
end
|
data/spec/coverage_spec.rb
CHANGED
@@ -1,35 +1,39 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe 'coverage', :coverage do
|
4
|
-
|
5
|
-
|
4
|
+
subject {
|
5
|
+
class Sample::Coverage < Sample::Model
|
6
|
+
identity :id
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
|
8
|
+
attribute :used, type: :string
|
9
|
+
attribute :unused, type: :string
|
10
|
+
end
|
11
|
+
|
12
|
+
Sample::Coverage
|
13
|
+
}
|
10
14
|
|
11
|
-
let!(:
|
15
|
+
let!(:model) { subject.new(used: 'foo', unused: 'bar') }
|
12
16
|
|
13
17
|
before(:each) do
|
14
|
-
|
15
|
-
expect(
|
16
|
-
expect(
|
18
|
+
subject.attributes[:used][:coverage_hits] = 0
|
19
|
+
expect(model.used).to eq('foo') # once
|
20
|
+
expect(model.used).to eq('foo') # twice
|
17
21
|
end
|
18
22
|
|
19
23
|
it 'should store the file path where the attribute was defined' do
|
20
|
-
expect(
|
21
|
-
expect(
|
24
|
+
expect(subject.attributes[:used][:coverage_file]).to eq(__FILE__)
|
25
|
+
expect(subject.attributes[:unused][:coverage_file]).to eq(__FILE__)
|
22
26
|
end
|
23
27
|
|
24
28
|
it 'should store the line number where the attribute was defined' do
|
25
29
|
src_lines = File.read(__FILE__).lines
|
26
30
|
|
27
|
-
expect(src_lines[
|
28
|
-
expect(src_lines[
|
31
|
+
expect(src_lines[subject.attributes[:used][:coverage_line] - 1]).to match(/attribute :used/)
|
32
|
+
expect(src_lines[subject.attributes[:unused][:coverage_line] - 1]).to match(/attribute :unused/)
|
29
33
|
end
|
30
34
|
|
31
35
|
it "should store how many times an attribute's reader is called" do
|
32
|
-
expect(
|
33
|
-
expect(
|
36
|
+
expect(subject.attributes[:used][:coverage_hits]).to eq(2)
|
37
|
+
expect(subject.attributes[:unused][:coverage_hits]).to eq(1)
|
34
38
|
end
|
35
39
|
end
|
data/spec/dirty_spec.rb
CHANGED
@@ -1,19 +1,21 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe 'Cistern::Model#dirty' do
|
4
|
-
|
5
|
-
|
4
|
+
subject {
|
5
|
+
Class.new(Sample::Model) do
|
6
|
+
identity :id
|
6
7
|
|
7
|
-
|
8
|
-
|
8
|
+
attribute :name
|
9
|
+
attribute :properties, type: :array
|
9
10
|
|
10
|
-
|
11
|
-
|
11
|
+
def save
|
12
|
+
merge_attributes(attributes)
|
13
|
+
end
|
12
14
|
end
|
13
|
-
|
15
|
+
}
|
14
16
|
|
15
17
|
it 'should mark a existing record as dirty' do
|
16
|
-
model =
|
18
|
+
model = subject.new(id: 1, name: 'steve')
|
17
19
|
expect(model.changed).to be_empty
|
18
20
|
|
19
21
|
expect do
|
data/spec/mock_data_spec.rb
CHANGED
@@ -1,23 +1,25 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe 'mock data' do
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
before {
|
5
|
+
class Sample::Diagnosis < Sample::Request
|
6
|
+
def real(diagnosis)
|
7
|
+
end
|
7
8
|
|
8
|
-
|
9
|
-
|
9
|
+
def mock(diagnosis)
|
10
|
+
cistern.data.store(:diagnosis, cistern.data.fetch(:diagnosis) + [diagnosis])
|
11
|
+
end
|
10
12
|
end
|
11
|
-
end
|
12
13
|
|
13
|
-
|
14
|
-
|
15
|
-
|
14
|
+
class Sample::Treat < Sample::Request
|
15
|
+
def real(treatment)
|
16
|
+
end
|
16
17
|
|
17
|
-
|
18
|
-
|
18
|
+
def mock(treatment)
|
19
|
+
cistern.data[:treatments] += [treatment]
|
20
|
+
end
|
19
21
|
end
|
20
|
-
|
22
|
+
}
|
21
23
|
|
22
24
|
shared_examples 'mock_data#backend' do |backend, options|
|
23
25
|
it 'should store mock data' do
|
data/spec/singular_spec.rb
CHANGED
@@ -1,24 +1,26 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe 'Cistern::Singular' do
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
before {
|
5
|
+
class Sample::Settings < Sample::Singular
|
6
|
+
attribute :name, type: :string
|
7
|
+
attribute :count, type: :number
|
7
8
|
|
8
|
-
|
9
|
-
|
9
|
+
def save
|
10
|
+
result = @@settings = attributes.merge(dirty_attributes)
|
10
11
|
|
11
|
-
|
12
|
-
|
12
|
+
merge_attributes(result)
|
13
|
+
end
|
13
14
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
15
|
+
def get
|
16
|
+
settings = @@settings ||= {}
|
17
|
+
settings[:count] ||= 0
|
18
|
+
settings[:count] += 1
|
18
19
|
|
19
|
-
|
20
|
+
merge_attributes(settings)
|
21
|
+
end
|
20
22
|
end
|
21
|
-
|
23
|
+
}
|
22
24
|
|
23
25
|
let!(:service) { Sample.new }
|
24
26
|
|
data/spec/support/service.rb
CHANGED
data/spec/wait_for_spec.rb
CHANGED
@@ -1,67 +1,70 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
describe 'Cistern::WaitFor' do
|
4
|
+
let(:service) { Sample.new }
|
5
|
+
before {
|
6
|
+
class Sample::Wait < Sample::Model
|
7
|
+
identity :id
|
5
8
|
|
6
|
-
|
7
|
-
end
|
9
|
+
attribute :name
|
10
|
+
end
|
8
11
|
|
9
|
-
class
|
10
|
-
|
12
|
+
class Sample::Waits < Sample::Collection
|
13
|
+
model Sample::Wait
|
11
14
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
end
|
15
|
+
def get(_identity)
|
16
|
+
self
|
17
|
+
end
|
18
|
+
end
|
19
|
+
}
|
16
20
|
|
17
|
-
describe 'Cistern#wait_for' do
|
18
|
-
|
19
|
-
|
21
|
+
describe 'Cistern#wait_for' do
|
22
|
+
it 'should return false if timeout exceeded' do
|
23
|
+
expect(Cistern.wait_for(0, 0) { false }).to be_falsey
|
24
|
+
end
|
20
25
|
end
|
21
|
-
end
|
22
26
|
|
23
|
-
describe 'Cistern#wait_for!' do
|
24
|
-
|
25
|
-
|
27
|
+
describe 'Cistern#wait_for!' do
|
28
|
+
it 'should raise if timeout exceeded' do
|
29
|
+
expect { Cistern.wait_for!(0, 0) { false } }.to raise_exception(Cistern::Timeout)
|
30
|
+
end
|
26
31
|
end
|
27
|
-
end
|
28
32
|
|
29
|
-
describe 'Cistern::Model#wait_for!' do
|
30
|
-
|
31
|
-
let(:model) { service.wait_for_models.new(identity: 1) }
|
33
|
+
describe 'Cistern::Model#wait_for!' do
|
34
|
+
let(:model) { service.waits.new(identity: 1) }
|
32
35
|
|
33
|
-
|
34
|
-
|
36
|
+
it 'should raise if timeout exceeded' do
|
37
|
+
expect { model.wait_for!(0, 0) { false } }.to raise_exception(Sample::Timeout)
|
38
|
+
end
|
35
39
|
end
|
36
|
-
end
|
37
40
|
|
38
|
-
describe 'WaitForModel#timeout' do
|
39
|
-
|
40
|
-
let(:model) { service.wait_for_models.new(identity: 1) }
|
41
|
+
describe 'WaitForModel#timeout' do
|
42
|
+
let(:model) { service.waits.new(identity: 1) }
|
41
43
|
|
42
|
-
|
43
|
-
|
44
|
-
|
44
|
+
it 'should use service-specific timeout in #wait_for' do
|
45
|
+
service.class.timeout = 0.1
|
46
|
+
service.class.poll_interval = 0
|
45
47
|
|
46
|
-
|
48
|
+
elapsed = 0
|
47
49
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
50
|
+
Timeout.timeout(2) do
|
51
|
+
expect do
|
52
|
+
model.wait_for! { sleep(0.2); elapsed += 0.2; elapsed > 0.2 }
|
53
|
+
end.to raise_exception(Sample::Timeout)
|
54
|
+
end
|
52
55
|
end
|
53
|
-
end
|
54
56
|
|
55
|
-
|
56
|
-
|
57
|
-
|
57
|
+
it 'should favor explicit timeout' do
|
58
|
+
service.class.timeout = 1
|
59
|
+
service.class.poll_interval = 0
|
58
60
|
|
59
|
-
|
61
|
+
elapsed = 0
|
60
62
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
63
|
+
Timeout.timeout(2) do
|
64
|
+
expect do
|
65
|
+
model.wait_for!(0.1) { sleep(0.2); elapsed += 0.2; elapsed > 0.2 }
|
66
|
+
end.to raise_exception(Sample::Timeout)
|
67
|
+
end
|
65
68
|
end
|
66
69
|
end
|
67
70
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cistern
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Josh Lane
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-07-
|
11
|
+
date: 2016-07-19 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: API client framework extracted from Fog
|
14
14
|
email:
|