requisite 0.2.0 → 0.2.1

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 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: