cistern 2.2.3 → 2.2.4
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/.travis.yml +4 -4
- data/lib/cistern/attributes.rb +62 -61
- data/lib/cistern/client.rb +30 -24
- data/lib/cistern/collection.rb +15 -16
- data/lib/cistern/coverage.rb +7 -5
- data/lib/cistern/data/hash.rb +5 -7
- data/lib/cistern/data/redis.rb +7 -9
- data/lib/cistern/data.rb +2 -2
- data/lib/cistern/formatter/awesome_print.rb +1 -1
- data/lib/cistern/formatter/default.rb +2 -2
- data/lib/cistern/formatter/formatador.rb +3 -3
- data/lib/cistern/hash.rb +3 -3
- data/lib/cistern/mock.rb +2 -2
- data/lib/cistern/model.rb +10 -10
- data/lib/cistern/request.rb +2 -2
- data/lib/cistern/service.rb +2 -2
- data/lib/cistern/singular.rb +2 -5
- data/lib/cistern/string.rb +6 -6
- data/lib/cistern/timeout.rb +3 -3
- data/lib/cistern/version.rb +1 -1
- data/lib/cistern/wait_for.rb +4 -4
- data/lib/cistern.rb +5 -6
- data/spec/client_spec.rb +8 -9
- data/spec/collection_spec.rb +18 -18
- data/spec/dirty_spec.rb +9 -9
- data/spec/formatter_spec.rb +14 -14
- data/spec/hash_spec.rb +17 -17
- data/spec/mock_data_spec.rb +21 -22
- data/spec/model_spec.rb +76 -76
- data/spec/request_spec.rb +8 -8
- data/spec/singular_spec.rb +7 -8
- data/spec/spec_helper.rb +3 -3
- data/spec/wait_for_spec.rb +7 -8
- metadata +2 -2
data/spec/model_spec.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe
|
4
|
-
describe
|
3
|
+
describe 'Cistern::Model' do
|
4
|
+
describe '#update' do
|
5
5
|
class UpdateSpec < Sample::Model
|
6
6
|
identity :id
|
7
7
|
attribute :name
|
@@ -12,22 +12,22 @@ describe "Cistern::Model" do
|
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
|
-
it
|
16
|
-
model = UpdateSpec.new(name:
|
15
|
+
it 'should merge and save attributes' do
|
16
|
+
model = UpdateSpec.new(name: 'steve')
|
17
17
|
model.save
|
18
18
|
|
19
|
-
expect(model.update(name:
|
19
|
+
expect(model.update(name: 'karen')).to eq(name: 'karen')
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
-
context
|
24
|
-
it
|
23
|
+
context '#new_record?' do
|
24
|
+
it 'does not require identity' do
|
25
25
|
identity_less = Class.new(Sample::Model)
|
26
26
|
|
27
27
|
expect(identity_less.new.new_record?).to eq(true)
|
28
28
|
end
|
29
29
|
|
30
|
-
it
|
30
|
+
it 'is false if identity is set' do
|
31
31
|
identity_full = Class.new(Sample::Model) {
|
32
32
|
identity :id
|
33
33
|
}
|
@@ -37,7 +37,7 @@ describe "Cistern::Model" do
|
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
40
|
-
it
|
40
|
+
it 'should set singular resource service method' do
|
41
41
|
class ModelService
|
42
42
|
include Cistern::Client
|
43
43
|
end
|
@@ -49,7 +49,7 @@ describe "Cistern::Model" do
|
|
49
49
|
expect(ModelService.new.jimbob).to be_a(ModelService::Jimbob)
|
50
50
|
end
|
51
51
|
|
52
|
-
it
|
52
|
+
it 'should set specific singular resource service method' do
|
53
53
|
class SpecificModelService
|
54
54
|
include Cistern::Client
|
55
55
|
end
|
@@ -63,24 +63,24 @@ describe "Cistern::Model" do
|
|
63
63
|
expect(SpecificModelService.new.john_boy).to be_a(SpecificModelService::Jimbob)
|
64
64
|
end
|
65
65
|
|
66
|
-
it
|
66
|
+
it 'should duplicate a model' do
|
67
67
|
class DupSpec < Sample::Model
|
68
68
|
identity :id
|
69
69
|
attribute :name
|
70
70
|
attribute :properties
|
71
71
|
end
|
72
72
|
|
73
|
-
model = DupSpec.new(id: 1, name:
|
73
|
+
model = DupSpec.new(id: 1, name: 'string', properties: { value: 'something', else: 'what' })
|
74
74
|
duplicate = model.dup
|
75
75
|
|
76
76
|
expect(duplicate).to eq(model)
|
77
77
|
expect(duplicate).to eql(model)
|
78
78
|
|
79
|
-
model.name =
|
80
|
-
expect(duplicate.name).to eq(
|
79
|
+
model.name = 'anotherstring'
|
80
|
+
expect(duplicate.name).to eq('string')
|
81
81
|
end
|
82
82
|
|
83
|
-
context
|
83
|
+
context 'attribute parsing' do
|
84
84
|
class TypeSpec < Sample::Model
|
85
85
|
identity :id
|
86
86
|
attribute :name, type: :string
|
@@ -89,125 +89,125 @@ describe "Cistern::Model" do
|
|
89
89
|
attribute :list, type: :array
|
90
90
|
attribute :number, type: :integer
|
91
91
|
attribute :floater, type: :float
|
92
|
-
attribute :butternut_id, squash:
|
93
|
-
attribute :butternut_type, squash:
|
92
|
+
attribute :butternut_id, squash: %w(squash id), type: :integer
|
93
|
+
attribute :butternut_type, squash: %w(squash type)
|
94
94
|
attribute :squash
|
95
|
-
attribute :vegetable, aliases:
|
95
|
+
attribute :vegetable, aliases: 'squash'
|
96
96
|
attribute :custom, parser: lambda { |v, _| "X!#{v}" }
|
97
|
-
attribute :default, default:
|
97
|
+
attribute :default, default: 'im a squash'
|
98
98
|
|
99
|
-
attribute :same_alias_1, aliases:
|
100
|
-
attribute :same_alias_2, aliases:
|
99
|
+
attribute :same_alias_1, aliases: 'nested'
|
100
|
+
attribute :same_alias_2, aliases: 'nested'
|
101
101
|
|
102
|
-
attribute :same_alias_squashed_1, squash:
|
103
|
-
attribute :same_alias_squashed_2, squash:
|
104
|
-
attribute :same_alias_squashed_3, squash:
|
105
|
-
attribute :adam_attributes, aliases:
|
102
|
+
attribute :same_alias_squashed_1, squash: %w(nested attr_1)
|
103
|
+
attribute :same_alias_squashed_2, squash: %w(nested attr_2)
|
104
|
+
attribute :same_alias_squashed_3, squash: %w(nested attr_2)
|
105
|
+
attribute :adam_attributes, aliases: 'attributes'
|
106
106
|
|
107
107
|
def save
|
108
108
|
requires :flag
|
109
109
|
end
|
110
110
|
end
|
111
111
|
|
112
|
-
it
|
113
|
-
expect(TypeSpec.new(name: 1).name).to eq(
|
112
|
+
it 'should parse string' do
|
113
|
+
expect(TypeSpec.new(name: 1).name).to eq('1')
|
114
114
|
end
|
115
115
|
|
116
116
|
it "should handle a 'attributes' aliased attribute" do
|
117
|
-
expect(TypeSpec.new(attributes:
|
117
|
+
expect(TypeSpec.new(attributes: 'x').adam_attributes).to eq('x')
|
118
118
|
end
|
119
119
|
|
120
|
-
it
|
120
|
+
it 'should parse time' do
|
121
121
|
time = Time.now
|
122
122
|
created_at = TypeSpec.new(created_at: time.to_s).created_at
|
123
123
|
expect(created_at).to be_a(Time)
|
124
124
|
expect(created_at.to_i).to eq(time.to_i)
|
125
125
|
end
|
126
126
|
|
127
|
-
it
|
128
|
-
expect(TypeSpec.new(flag:
|
129
|
-
expect(TypeSpec.new(flag:
|
127
|
+
it 'should parse boolean' do
|
128
|
+
expect(TypeSpec.new(flag: 'false').flag).to be_falsey
|
129
|
+
expect(TypeSpec.new(flag: 'true').flag).to be_truthy
|
130
130
|
expect(TypeSpec.new(flag: false).flag).to be_falsey
|
131
131
|
expect(TypeSpec.new(flag: true).flag).to be_truthy
|
132
|
-
expect(TypeSpec.new(flag:
|
133
|
-
expect(TypeSpec.new(flag:
|
132
|
+
expect(TypeSpec.new(flag: '0').flag).to be_falsey
|
133
|
+
expect(TypeSpec.new(flag: '1').flag).to be_truthy
|
134
134
|
expect(TypeSpec.new(flag: 0).flag).to be_falsey
|
135
135
|
expect(TypeSpec.new(flag: 1).flag).to be_truthy
|
136
136
|
expect(TypeSpec.new(flag: false)).not_to be_flag
|
137
137
|
expect(TypeSpec.new(flag: true)).to be_flag
|
138
138
|
end
|
139
139
|
|
140
|
-
it
|
140
|
+
it 'should parse an array' do
|
141
141
|
expect(TypeSpec.new(list: []).list).to eq([])
|
142
|
-
expect(TypeSpec.new(list:
|
142
|
+
expect(TypeSpec.new(list: 'item').list).to eq(['item'])
|
143
143
|
end
|
144
144
|
|
145
|
-
it
|
146
|
-
expect(TypeSpec.new(floater:
|
145
|
+
it 'should parse a float' do
|
146
|
+
expect(TypeSpec.new(floater: '0.01').floater).to eq(0.01)
|
147
147
|
expect(TypeSpec.new(floater: 0.01).floater).to eq(0.01)
|
148
148
|
end
|
149
149
|
|
150
|
-
it
|
151
|
-
expect(TypeSpec.new(custom:
|
150
|
+
it 'should use custom parser' do
|
151
|
+
expect(TypeSpec.new(custom: '15').custom).to eq('X!15')
|
152
152
|
end
|
153
153
|
|
154
|
-
it
|
154
|
+
it 'should squash, cast, alias an attribute and keep a vanilla reference' do
|
155
155
|
# vanilla squash
|
156
|
-
expect(TypeSpec.new({
|
157
|
-
expect(TypeSpec.new({
|
158
|
-
expect(TypeSpec.new({
|
156
|
+
expect(TypeSpec.new({ 'squash' => { 'id' => '12', 'type' => 'fred' } }).butternut_type).to eq('fred')
|
157
|
+
expect(TypeSpec.new({ 'squash' => { 'id' => '12', 'type' => nil } }).butternut_type).to be_nil
|
158
|
+
expect(TypeSpec.new({ 'squash' => nil }).butternut_type).to be_nil
|
159
159
|
|
160
160
|
# composite processors: squash and cast
|
161
|
-
expect(TypeSpec.new({
|
162
|
-
expect(TypeSpec.new({
|
163
|
-
expect(TypeSpec.new({
|
161
|
+
expect(TypeSpec.new({ 'squash' => { 'id' => '12', 'type' => 'fred' } }).butternut_id).to eq(12)
|
162
|
+
expect(TypeSpec.new({ 'squash' => { 'id' => nil, 'type' => 'fred' } }).butternut_id).to be_nil
|
163
|
+
expect(TypeSpec.new({ 'squash' => { 'type' => 'fred' } }).butternut_id).to be_nil
|
164
164
|
|
165
165
|
# override intermediate processing
|
166
|
-
expect(TypeSpec.new({
|
166
|
+
expect(TypeSpec.new({ 'squash' => { 'id' => '12', 'type' => 'fred' } }).squash).to eq({ 'id' => '12', 'type' => 'fred' })
|
167
167
|
|
168
168
|
# alias of override
|
169
|
-
expect(TypeSpec.new({
|
169
|
+
expect(TypeSpec.new({ 'squash' => { 'id' => '12', 'type' => 'fred' } }).vegetable).to eq({ 'id' => '12', 'type' => 'fred' })
|
170
170
|
end
|
171
171
|
|
172
|
-
it
|
173
|
-
expect(TypeSpec.new.default).to eq(
|
172
|
+
it 'should set a default value' do
|
173
|
+
expect(TypeSpec.new.default).to eq('im a squash')
|
174
174
|
end
|
175
175
|
|
176
|
-
it
|
177
|
-
expect(TypeSpec.new(default:
|
176
|
+
it 'should override a default value' do
|
177
|
+
expect(TypeSpec.new(default: 'now im a different squash').default).to eq('now im a different squash')
|
178
178
|
end
|
179
179
|
|
180
|
-
context
|
181
|
-
it
|
182
|
-
type_spec = TypeSpec.new({
|
183
|
-
expect(type_spec.same_alias_1).to eq(
|
184
|
-
expect(type_spec.same_alias_2).to eq(
|
180
|
+
context 'allowing the same alias for multiple attributes' do
|
181
|
+
it 'should do so when not squashing' do
|
182
|
+
type_spec = TypeSpec.new({ 'nested' => 'bamboo' })
|
183
|
+
expect(type_spec.same_alias_1).to eq('bamboo')
|
184
|
+
expect(type_spec.same_alias_2).to eq('bamboo')
|
185
185
|
end
|
186
186
|
|
187
|
-
it
|
188
|
-
type_spec = TypeSpec.new({
|
189
|
-
expect(type_spec.same_alias_squashed_1).to eq(
|
190
|
-
expect(type_spec.same_alias_squashed_2).to eq(
|
191
|
-
expect(type_spec.same_alias_squashed_3).to eq(
|
187
|
+
it 'should do so when squashing' do
|
188
|
+
type_spec = TypeSpec.new({ 'nested' => { 'attr_1' => 'bamboo', 'attr_2' => 'panda' } })
|
189
|
+
expect(type_spec.same_alias_squashed_1).to eq('bamboo')
|
190
|
+
expect(type_spec.same_alias_squashed_2).to eq('panda')
|
191
|
+
expect(type_spec.same_alias_squashed_3).to eq('panda')
|
192
192
|
end
|
193
193
|
end
|
194
194
|
|
195
|
-
it
|
196
|
-
expect(TypeSpec.new({
|
195
|
+
it 'should slice out unaccounted for attributes' do
|
196
|
+
expect(TypeSpec.new({ 'something' => { 'id' => '12' } }).attributes.keys).not_to include('something')
|
197
197
|
end
|
198
198
|
|
199
|
-
describe
|
200
|
-
it
|
201
|
-
expect { TypeSpec.new({
|
199
|
+
describe '#requires' do
|
200
|
+
it 'should raise if attribute not provided' do
|
201
|
+
expect { TypeSpec.new({ 'service' => 'fake', 'something' => { 'id' => '12' } }).save }.to raise_exception(ArgumentError)
|
202
202
|
end
|
203
203
|
|
204
|
-
it
|
205
|
-
expect { TypeSpec.new({
|
204
|
+
it 'should raise if attribute is provided and is nil' do
|
205
|
+
expect { TypeSpec.new({ 'service' => 'fake', 'custom' => nil }).save }.to raise_exception(ArgumentError)
|
206
206
|
end
|
207
207
|
end
|
208
208
|
end
|
209
209
|
|
210
|
-
context
|
210
|
+
context 'attribute coverage info collecting', :coverage do
|
211
211
|
class CoverageSpec < Sample::Model
|
212
212
|
identity :id
|
213
213
|
|
@@ -215,20 +215,20 @@ describe "Cistern::Model" do
|
|
215
215
|
attribute :unused, type: :string
|
216
216
|
end
|
217
217
|
|
218
|
-
let!(:obj) { CoverageSpec.new(used:
|
218
|
+
let!(:obj) { CoverageSpec.new(used: 'foo', unused: 'bar') }
|
219
219
|
|
220
220
|
before(:each) do
|
221
221
|
CoverageSpec.attributes[:used][:coverage_hits] = 0
|
222
|
-
expect(obj.used).to eq(
|
223
|
-
expect(obj.used).to eq(
|
222
|
+
expect(obj.used).to eq('foo') # once
|
223
|
+
expect(obj.used).to eq('foo') # twice
|
224
224
|
end
|
225
225
|
|
226
|
-
it
|
226
|
+
it 'should store the file path where the attribute was defined' do
|
227
227
|
expect(CoverageSpec.attributes[:used][:coverage_file]).to eq(__FILE__)
|
228
228
|
expect(CoverageSpec.attributes[:unused][:coverage_file]).to eq(__FILE__)
|
229
229
|
end
|
230
230
|
|
231
|
-
it
|
231
|
+
it 'should store the line number where the attribute was defined' do
|
232
232
|
src_lines = File.read(__FILE__).lines
|
233
233
|
|
234
234
|
expect(src_lines[CoverageSpec.attributes[:used][:coverage_line] - 1]).to match(/attribute :used/)
|
data/spec/request_spec.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe
|
3
|
+
describe 'Cistern::Request' do
|
4
4
|
class SampleService < Cistern::Service
|
5
5
|
recognizes :key
|
6
6
|
|
@@ -18,20 +18,20 @@ describe "Cistern::Request" do
|
|
18
18
|
service_method :list_all_samples
|
19
19
|
|
20
20
|
def real(*args)
|
21
|
-
service.service_args + args + [
|
21
|
+
service.service_args + args + ['real']
|
22
22
|
end
|
23
23
|
|
24
24
|
def mock(*args)
|
25
|
-
args + [
|
25
|
+
args + ['mock']
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
|
-
it
|
30
|
-
expect(SampleService.new.list_all_samples(
|
31
|
-
expect(SampleService::Real.new.list_all_samples(
|
32
|
-
expect(SampleService::Mock.new.list_all_samples(
|
29
|
+
it 'should execute a new-style request' do
|
30
|
+
expect(SampleService.new.list_all_samples('sample1')).to eq([{}, 'sample1', 'real'])
|
31
|
+
expect(SampleService::Real.new.list_all_samples('sample2')).to eq(%w(sample2 real))
|
32
|
+
expect(SampleService::Mock.new.list_all_samples('sample3')).to eq(%w(sample3 mock))
|
33
33
|
|
34
34
|
# service access
|
35
|
-
expect(SampleService.new(:
|
35
|
+
expect(SampleService.new(key: 'value').list_all_samples('stat')).to eq([{ key: 'value' }, 'stat', 'real'])
|
36
36
|
end
|
37
37
|
end
|
data/spec/singular_spec.rb
CHANGED
@@ -1,26 +1,25 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe
|
3
|
+
describe 'Cistern::Singular' do
|
4
4
|
class SampleSingular < Sample::Singular
|
5
|
-
|
6
5
|
attribute :name
|
7
6
|
attribute :count, type: :number
|
8
7
|
|
9
8
|
def fetch_attributes
|
10
|
-
#test that initialize waits for service to be defined
|
11
|
-
|
9
|
+
# test that initialize waits for service to be defined
|
10
|
+
fail 'missing service' unless service
|
12
11
|
|
13
12
|
@counter ||= 0
|
14
13
|
@counter += 1
|
15
|
-
{name:
|
14
|
+
{ name: 'amazing', count: @counter }
|
16
15
|
end
|
17
16
|
end
|
18
17
|
|
19
|
-
it
|
20
|
-
expect(Sample.new.sample_singular.name).to eq(
|
18
|
+
it 'should work' do
|
19
|
+
expect(Sample.new.sample_singular.name).to eq('amazing')
|
21
20
|
end
|
22
21
|
|
23
|
-
it
|
22
|
+
it 'should reload' do
|
24
23
|
singular = Sample.new.sample_singular
|
25
24
|
old_count = singular.count
|
26
25
|
expect(singular.count).to eq(old_count)
|
data/spec/spec_helper.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
if ENV[
|
2
|
-
require
|
1
|
+
if ENV['TRAVIS']
|
2
|
+
require 'codeclimate-test-reporter'
|
3
3
|
CodeClimate::TestReporter.start
|
4
4
|
end
|
5
5
|
|
6
6
|
require File.expand_path('../../lib/cistern', __FILE__)
|
7
|
-
Dir[File.expand_path(
|
7
|
+
Dir[File.expand_path('../{support,shared,matchers,fixtures}/*.rb', __FILE__)].each { |f| require(f) }
|
8
8
|
|
9
9
|
Bundler.require(:test)
|
10
10
|
|
data/spec/wait_for_spec.rb
CHANGED
@@ -9,19 +9,19 @@ end
|
|
9
9
|
class WaitForModels < Sample::Collection
|
10
10
|
model WaitForModel
|
11
11
|
|
12
|
-
def get(
|
12
|
+
def get(_identity)
|
13
13
|
self
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
17
|
describe 'Cistern#wait_for' do
|
18
|
-
it
|
18
|
+
it 'should return false if timeout exceeded' do
|
19
19
|
expect(Cistern.wait_for(0, 0) { false }).to be_falsey
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
23
|
describe 'Cistern#wait_for!' do
|
24
|
-
it
|
24
|
+
it 'should raise if timeout exceeded' do
|
25
25
|
expect { Cistern.wait_for!(0, 0) { false } }.to raise_exception(Cistern::Timeout)
|
26
26
|
end
|
27
27
|
end
|
@@ -30,17 +30,16 @@ describe 'Cistern::Model#wait_for!' do
|
|
30
30
|
let(:service) { Sample.new }
|
31
31
|
let(:model) { service.wait_for_models.new(identity: 1) }
|
32
32
|
|
33
|
-
it
|
33
|
+
it 'should raise if timeout exceeded' do
|
34
34
|
expect { model.wait_for!(0, 0) { false } }.to raise_exception(Sample::Timeout)
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
-
|
39
|
-
describe "WaitForModel#timeout" do
|
38
|
+
describe 'WaitForModel#timeout' do
|
40
39
|
let(:service) { Sample.new }
|
41
40
|
let(:model) { service.wait_for_models.new(identity: 1) }
|
42
41
|
|
43
|
-
it
|
42
|
+
it 'should use service-specific timeout in #wait_for' do
|
44
43
|
service.class.timeout = 0.1
|
45
44
|
service.class.poll_interval = 0
|
46
45
|
|
@@ -53,7 +52,7 @@ describe "WaitForModel#timeout" do
|
|
53
52
|
end
|
54
53
|
end
|
55
54
|
|
56
|
-
it
|
55
|
+
it 'should favor explicit timeout' do
|
57
56
|
service.class.timeout = 1
|
58
57
|
service.class.poll_interval = 0
|
59
58
|
|
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.2.
|
4
|
+
version: 2.2.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Josh Lane
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-11-27 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: API client framework extracted from Fog
|
14
14
|
email:
|