cistern 2.4.1 → 2.5.0
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 +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:
|