requisite 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fdf15247190df240348bbf154bac1485d5e93b6a
4
- data.tar.gz: 32d1748aff1b074f8b5f9b9639249697176c7c58
3
+ metadata.gz: 0900379bbe4e112f2e983138cba06a3f4c399d8b
4
+ data.tar.gz: 30ee7ec731114380f827676e2e881510b860d38e
5
5
  SHA512:
6
- metadata.gz: 569dae2fbad28fae97b4c5013f34290f24702494eddbfb560f3279f07387e3df679d74bd1a8ee3c52c5531e193d240008a12454c8f70d20304fe58f064de8a5d
7
- data.tar.gz: c66308ee9e74ec995613b5c7d35202c76e645725d77d72bbbc406e0380cc43c78d34b3519adbec9da9c82d45e7662d558671c2676a03058ce2d627a34a1a6786
6
+ metadata.gz: 3d979fd487435e6ef9b025db1d4ed6f7d09a6c897a1bf2f440bd19e4328f8b0e5ca663a2582cba8827a4bc5fcc0cfbebb959f18e3a6621ba2339228ac378bcbd
7
+ data.tar.gz: b4b83bf22163cc36b6dbd144cafbacf9f803e52076b9a969e001c167f608d387a394e8d124260379de44c5c27b55c5992a0acb0fe73e7d7151170a9f7d7e72e5
data/CHANGES.md CHANGED
@@ -1,3 +1,6 @@
1
+ ### 0.2.1 (5th March 2015):
2
+ - Fix false in hash inputs
3
+
1
4
  ### 0.2.0 (17th November 2014):
2
5
  - Add inheritance of serialized attributes
3
6
 
@@ -3,22 +3,31 @@ require 'json'
3
3
  module Requisite
4
4
  class ApiModel < BoundaryObject
5
5
  attr_reader :model
6
-
6
+
7
7
  def initialize(model={})
8
8
  @model = model.kind_of?(Hash) ? Hash[model.map{ |k, v| [k.to_sym, v] }] : model
9
9
  end
10
-
10
+
11
11
  def convert(name)
12
12
  attribute_from_model(name)
13
13
  end
14
-
14
+
15
15
  def convert!(name)
16
- attribute_from_model(name) || (raise NotImplementedError.new("'#{name}' not found on model"))
16
+ raise NotImplementedError.new("'#{name}' not found on model") unless model_responds_to_attribute_query?(name)
17
+ attribute_from_model(name)
17
18
  end
18
19
 
19
20
  def attribute_from_model(name)
20
21
  if @model.kind_of?(Hash)
21
22
  @model[name]
23
+ else
24
+ @model.send(name)
25
+ end
26
+ end
27
+
28
+ def model_responds_to_attribute_query?(name)
29
+ if @model.kind_of?(Hash)
30
+ @model[name] != nil
22
31
  else
23
32
  @model.send(name) if @model.respond_to?(name)
24
33
  end
@@ -37,11 +46,11 @@ module Requisite
37
46
  end
38
47
  end
39
48
  end
40
-
49
+
41
50
  def to_json
42
51
  to_hash.to_json
43
52
  end
44
-
53
+
45
54
  def parse_typed_hash(name, hash)
46
55
  {}.tap do |result|
47
56
  passed_hash = attribute_from_model(name)
@@ -52,7 +61,7 @@ module Requisite
52
61
  end
53
62
  end
54
63
  end
55
-
64
+
56
65
  def parse_scalar_hash(name)
57
66
  {}.tap do |result|
58
67
  passed_hash = attribute_from_model(name) || {}
@@ -62,7 +71,7 @@ module Requisite
62
71
  end
63
72
  end
64
73
  end
65
-
74
+
66
75
  def parse_typed_array(name, type)
67
76
  [].tap do |result|
68
77
  passed_array = attribute_from_model(name) || []
@@ -72,13 +81,13 @@ module Requisite
72
81
  end
73
82
  end
74
83
  end
75
-
84
+
76
85
  def with_type!(desired_type)
77
86
  yield.tap do |value|
78
87
  raise_bad_type_if_type_mismatch(value, desired_type) if value
79
88
  end
80
89
  end
81
-
90
+
82
91
  def first_attribute_from_model(*attributes)
83
92
  attributes.each do |attribute|
84
93
  value = attribute_from_model(attribute)
@@ -88,7 +97,7 @@ module Requisite
88
97
  end
89
98
  nil
90
99
  end
91
-
100
+
92
101
  private
93
102
 
94
103
  def preprocess_model
@@ -1,3 +1,3 @@
1
1
  module Requisite
2
- VERSION = '0.2.0'
2
+ VERSION = '0.2.1'
3
3
  end
@@ -4,7 +4,7 @@ require 'test_helper'
4
4
  module Requisite
5
5
  class DummyApiModel < Requisite::ApiModel
6
6
  end
7
-
7
+
8
8
  describe ApiModel do
9
9
  it 'creates methods from serialized_attributes block' do
10
10
  DummyApiModel.serialized_attributes { attribute :a; attribute :b }
@@ -15,7 +15,7 @@ module Requisite
15
15
  response.must_respond_to :a
16
16
  response.must_respond_to :b
17
17
  end
18
-
18
+
19
19
  it 'attribute provides a default implementation of calling a hash model' do
20
20
  DummyApiModel.serialized_attributes { attribute :c }
21
21
  mock = {:c => 'C'}
@@ -24,7 +24,7 @@ module Requisite
24
24
  end
25
25
 
26
26
  let(:params_hash) { {:c => 'C', :num => 12} }
27
-
27
+
28
28
  it 'attribute provides a default implementation of calling a model' do
29
29
  DummyApiModel.serialized_attributes { attribute :c }
30
30
  response = DummyApiModel.new(params_hash)
@@ -36,77 +36,77 @@ module Requisite
36
36
  response = DummyApiModel.new
37
37
  response.to_hash.must_equal(:c => 'see')
38
38
  end
39
-
39
+
40
40
  it 'ignores default if value given' do
41
41
  DummyApiModel.serialized_attributes { attribute :num, default: 0 }
42
42
  response = DummyApiModel.new(params_hash)
43
43
  response.to_hash.must_equal(:num => 12)
44
44
  end
45
-
45
+
46
46
  it 'attribute can be set to stringify fields' do
47
47
  DummyApiModel.serialized_attributes { attribute :num, stringify: true }
48
48
  response = DummyApiModel.new(params_hash)
49
49
  response.to_hash.must_equal(:num => '12')
50
50
  end
51
-
51
+
52
52
  it 'attribute can be set to rename fields' do
53
53
  DummyApiModel.serialized_attributes { attribute :my_num, rename: :num }
54
54
  response = DummyApiModel.new(params_hash)
55
55
  response.to_hash.must_equal(:my_num => 12)
56
56
  end
57
-
57
+
58
58
  it 'attribute can assert type of a field' do
59
59
  DummyApiModel.serialized_attributes { attribute :num, type: String }
60
60
  response = DummyApiModel.new(params_hash)
61
61
  proc { response.to_hash }.must_raise(BadTypeError)
62
62
  end
63
-
63
+
64
64
  it 'with_type! helper raises on mismatched type' do
65
65
  model = DummyApiModel.new()
66
66
  proc { model.with_type!(String) { 1 + 2 }}.must_raise(Requisite::BadTypeError)
67
67
  end
68
-
68
+
69
69
  it 'first_attribute_from_model helper finds first matching attriubute' do
70
70
  model = DummyApiModel.new(:oh => 12, :a => nil, :b => 'B', :c => 'C')
71
71
  model.first_attribute_from_model(:a, :b, :c).must_equal('B')
72
72
  end
73
-
73
+
74
74
  it 'attribute can assert type of a boolean field' do
75
75
  DummyApiModel.serialized_attributes { attribute :truthy_val, type: Requisite::Boolean }
76
76
  response = DummyApiModel.new(:truthy_val => false)
77
77
  response.to_hash.must_equal(:truthy_val => false)
78
78
  end
79
-
79
+
80
80
  it 'attribute does not include values of nil' do
81
81
  DummyApiModel.serialized_attributes { attribute :num, type: String }
82
82
  response = DummyApiModel.new({:num => nil})
83
83
  response.to_hash.must_equal({})
84
84
  end
85
-
85
+
86
86
  it 'attribute can be stringified and renamed with default fields' do
87
87
  DummyApiModel.serialized_attributes { attribute :my_num, rename: :num, stringify: true, default: 22 }
88
88
  response = DummyApiModel.new
89
89
  response.to_hash.must_equal(:my_num => '22')
90
90
  end
91
-
91
+
92
92
  it 'attribute can be stringified after type check' do
93
93
  DummyApiModel.serialized_attributes { attribute :num, stringify: true, type: Fixnum }
94
94
  response = DummyApiModel.new(params_hash)
95
95
  response.to_hash.must_equal(:num => '12')
96
96
  end
97
-
97
+
98
98
  it 'attribute type checks after rename' do
99
99
  DummyApiModel.serialized_attributes { attribute :my_num, rename: :num, type: String }
100
100
  response = DummyApiModel.new(params_hash)
101
101
  proc { response.to_hash }.must_raise(BadTypeError)
102
102
  end
103
-
103
+
104
104
  it 'attribute can be stringified, renamed, defaulted and have type checking on a field' do
105
105
  DummyApiModel.serialized_attributes { attribute :my_num, rename: :num, stringify: true, default: 22, type: String }
106
106
  response = DummyApiModel.new
107
107
  proc { response.to_hash }.must_raise(BadTypeError)
108
108
  end
109
-
109
+
110
110
  let(:invalid_params_hash) { {:d => nil} }
111
111
 
112
112
  it "attribute! raises an error if not found on model" do
@@ -114,13 +114,20 @@ module Requisite
114
114
  response = DummyApiModel.new(invalid_params_hash)
115
115
  proc { response.to_hash }.must_raise(NotImplementedError, "'d' not found on model")
116
116
  end
117
-
117
+
118
+ it 'attribute! does not raise an error if value on model is false' do
119
+ params_hash = {:d => false}
120
+ DummyApiModel.serialized_attributes { attribute! :d }
121
+ response = DummyApiModel.new(params_hash)
122
+ response.to_hash.must_equal({d: false})
123
+ end
124
+
118
125
  it 'attribute! can be set to stringify fields' do
119
126
  DummyApiModel.serialized_attributes { attribute! :num, stringify: true }
120
127
  response = DummyApiModel.new(params_hash)
121
128
  response.to_hash.must_equal(:num => '12')
122
129
  end
123
-
130
+
124
131
  it 'attribute! can be set to rename fields' do
125
132
  DummyApiModel.serialized_attributes { attribute! :my_num, rename: :num }
126
133
  response = DummyApiModel.new(params_hash)
@@ -132,7 +139,7 @@ module Requisite
132
139
  response = DummyApiModel.new(params_hash)
133
140
  response.model.must_equal(params_hash)
134
141
  end
135
-
142
+
136
143
  it 'sets the model from an object' do
137
144
  mc = MockClass.new
138
145
  mc.a = 'a'
@@ -142,109 +149,109 @@ module Requisite
142
149
  response.model.must_equal(mc)
143
150
  response.to_hash.must_equal(:a => 'a')
144
151
  end
145
-
152
+
146
153
  it 'has alias a for attribute' do
147
154
  DummyApiModel.serialized_attributes { a :num }
148
155
  response = DummyApiModel.new(params_hash)
149
156
  response.to_hash.must_equal(:num => 12)
150
157
  end
151
-
158
+
152
159
  it 'has alias a! for attribute!' do
153
160
  DummyApiModel.serialized_attributes { a! :num }
154
161
  response = DummyApiModel.new(params_hash)
155
162
  response.to_hash.must_equal(:num => 12)
156
163
  end
157
-
164
+
158
165
  it 'can convert to json' do
159
166
  DummyApiModel.serialized_attributes { a! :num }
160
167
  response = DummyApiModel.new(params_hash)
161
168
  response.to_json.must_equal("{\"num\":12}")
162
169
  end
163
-
170
+
164
171
  it 'drops non-listed parameters' do
165
172
  DummyApiModel.serialized_attributes { attribute :num }
166
173
  response = DummyApiModel.new({num: 12, other: 'value'})
167
174
  response.to_hash.must_equal(:num => 12)
168
175
  end
169
-
176
+
170
177
  describe 'with nested structures' do
171
-
178
+
172
179
  describe 'with typed arrays' do
173
180
  it 'allows arrays of one type' do
174
181
  DummyApiModel.serialized_attributes { attribute :ids, typed_array: Fixnum }
175
182
  response = DummyApiModel.new({ids: [1, 2, 3]})
176
183
  response.to_hash.must_equal(:ids => [1, 2, 3])
177
184
  end
178
-
185
+
179
186
  it 'raises errors when array has a wrongly typed value' do
180
187
  DummyApiModel.serialized_attributes { attribute :ids, typed_array: Requisite::Boolean }
181
188
  response = DummyApiModel.new({ids: [true, 'value', false]})
182
189
  Proc.new {response.to_hash}.must_raise(BadTypeError)
183
190
  end
184
191
  end
185
-
192
+
186
193
  describe 'with typed nested hashes' do
187
194
  it 'drops non listed parameters in nested hashes' do
188
195
  DummyApiModel.serialized_attributes { attribute :data, typed_hash: { num: Numeric, bool: Requisite::Boolean } }
189
196
  response = DummyApiModel.new({data: { num: 12, value: 'x', bool: true }})
190
197
  response.to_hash.must_equal(:data => { :num => 12, :bool => true })
191
198
  end
192
-
199
+
193
200
  it 'can stringify nested hashes' do
194
201
  DummyApiModel.serialized_attributes { attribute :data, typed_hash: { num: Numeric }, stringify: true }
195
202
  response = DummyApiModel.new({data: { num: 12, value: 'x' }})
196
203
  response.to_hash.must_equal(:data => "{:num=>12}")
197
204
  end
198
-
205
+
199
206
  it 'raises an error when nested hash values of the wrong type' do
200
207
  DummyApiModel.serialized_attributes { attribute :data, typed_hash: { num: Numeric } }
201
208
  Proc.new {DummyApiModel.new({data: { num: '12'}}).to_hash}.must_raise(BadTypeError)
202
209
  end
203
-
210
+
204
211
  it 'can rename param and work with nested hashes' do
205
212
  DummyApiModel.serialized_attributes { attribute :my_data, typed_hash: { num: Numeric }, rename: :data }
206
213
  response = DummyApiModel.new({data: { num: 12, value: 'x' }})
207
214
  response.to_hash.must_equal(:my_data => { :num => 12 })
208
215
  end
209
-
216
+
210
217
  it 'can set a default value for a nested hash' do
211
218
  DummyApiModel.serialized_attributes { attribute :data, typed_hash: { num: Numeric }, default: { num: 4 } }
212
219
  response = DummyApiModel.new({data: { value: 'x' }})
213
220
  response.to_hash.must_equal(:data => { :num => 4 })
214
221
  end
215
-
222
+
216
223
  it 'drops non listed fields with attribute!' do
217
224
  DummyApiModel.serialized_attributes { attribute! :data, typed_hash: { num: Numeric } }
218
225
  response = DummyApiModel.new({data: { num: 12, value: 'x' }})
219
226
  response.to_hash.must_equal(:data => { :num => 12 })
220
227
  end
221
-
228
+
222
229
  it 'attribute! does not raise an error with missing values in hash' do
223
230
  DummyApiModel.serialized_attributes { attribute! :data, typed_hash: { num: Numeric } }
224
231
  response = DummyApiModel.new({data: { value: 'x' }})
225
232
  response.to_hash.must_equal(:data => { })
226
233
  end
227
234
  end
228
-
235
+
229
236
  describe 'with scalar only nested hashes' do
230
237
  it 'should parse scalar hashes permitting anything scalar' do
231
238
  DummyApiModel.serialized_attributes { attribute :data, scalar_hash: true }
232
239
  response = DummyApiModel.new({data: { num: 12, value: 'x', :truthy => false }})
233
240
  response.to_hash.must_equal(:data => { :num => 12, :value => 'x', :truthy => false })
234
241
  end
235
-
242
+
236
243
  it 'should parse a renamed scalar hash' do
237
244
  DummyApiModel.serialized_attributes { attribute :my_data, scalar_hash: true, rename: :data }
238
245
  response = DummyApiModel.new({data: { num: 12, value: 'x' }})
239
246
  response.to_hash.must_equal(:my_data => { :num => 12, :value => 'x' })
240
247
  end
241
-
248
+
242
249
  it 'should stringify a scalar hash' do
243
250
  DummyApiModel.serialized_attributes { attribute :data, scalar_hash: true, stringify: true }
244
251
  response = DummyApiModel.new({data: { num: 12, value: 'x' }})
245
252
  response.to_hash.must_equal(:data => "{:num=>12, :value=>\"x\"}")
246
253
  end
247
-
254
+
248
255
  it 'should parse scalar hashes permitting anything scalar with object' do
249
256
  mc = MockClass.new
250
257
  mc.a = 'a'
@@ -253,13 +260,13 @@ module Requisite
253
260
  response = DummyApiModel.new(mc)
254
261
  response.to_hash.must_equal(:b => { :num => 12, :value => 'x' })
255
262
  end
256
-
263
+
257
264
  it 'should fail to parse scalar hashes when non scalar values present' do
258
265
  DummyApiModel.serialized_attributes { attribute :data, scalar_hash: true }
259
266
  Proc.new { DummyApiModel.new({data: { num: 12, value: { nested: 'value' } }}).to_hash}.must_raise(BadTypeError)
260
267
  Proc.new { DummyApiModel.new({data: { num: 12, value: ['array value'] }}).to_hash}.must_raise(BadTypeError)
261
268
  end
262
-
269
+
263
270
  it 'should fail to parse scalar hashes permitting anything scalar with object' do
264
271
  mc = MockClass.new
265
272
  mc.a = 'a'
@@ -268,19 +275,19 @@ module Requisite
268
275
  response = DummyApiModel.new(mc)
269
276
  Proc.new { response.to_hash }.must_raise(BadTypeError)
270
277
  end
271
-
278
+
272
279
  it 'can set a default value for a scalar hash' do
273
280
  DummyApiModel.serialized_attributes { attribute :data, scalar_hash: true, default: { num: 9, value: 'y' } }
274
281
  response = DummyApiModel.new({data: { }})
275
282
  response.to_hash.must_equal(:data => { :num => 9, :value => 'y' })
276
283
  end
277
-
284
+
278
285
  it 'doesnt raise with attribute! when an empty hash passed' do
279
286
  DummyApiModel.serialized_attributes { attribute! :data, scalar_hash: true }
280
287
  response = DummyApiModel.new({data: {}})
281
288
  response.to_hash.must_equal(:data => {})
282
289
  end
283
-
290
+
284
291
  it 'raises with attribute! when nil is passed' do
285
292
  DummyApiModel.serialized_attributes { attribute! :data, scalar_hash: true }
286
293
  response = DummyApiModel.new({data: nil})
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: requisite
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Osler
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-11-17 00:00:00.000000000 Z
11
+ date: 2015-03-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -79,4 +79,3 @@ test_files:
79
79
  - test/requisite/api_model_test.rb
80
80
  - test/requisite/api_user_test.rb
81
81
  - test/test_helper.rb
82
- has_rdoc: