protip 0.20.7 → 0.30.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/lib/protip.rb +10 -0
- data/lib/protip/{wrapper.rb → decorator.rb} +98 -82
- data/lib/protip/extensions.rb +0 -1
- data/lib/protip/resource.rb +56 -32
- data/lib/protip/resource/extra_methods.rb +5 -3
- data/lib/protip/tasks/compile.rake +2 -2
- data/lib/protip/transformer.rb +14 -0
- data/lib/protip/transformers/abstract_transformer.rb +11 -0
- data/lib/protip/transformers/active_support/time_with_zone_transformer.rb +35 -0
- data/lib/protip/transformers/decorating_transformer.rb +33 -0
- data/lib/protip/transformers/default_transformer.rb +22 -0
- data/lib/protip/transformers/delegating_transformer.rb +44 -0
- data/lib/protip/transformers/deprecated_transformer.rb +90 -0
- data/lib/protip/transformers/enum_transformer.rb +93 -0
- data/lib/protip/transformers/primitives_transformer.rb +78 -0
- data/lib/protip/transformers/timestamp_transformer.rb +31 -0
- data/test/functional/protip/decorator_test.rb +204 -0
- data/test/unit/protip/decorator_test.rb +665 -0
- data/test/unit/protip/resource_test.rb +76 -92
- data/test/unit/protip/transformers/decorating_transformer_test.rb +92 -0
- data/test/unit/protip/transformers/delegating_transformer_test.rb +83 -0
- data/test/unit/protip/transformers/deprecated_transformer_test.rb +139 -0
- data/test/unit/protip/transformers/enum_transformer_test.rb +157 -0
- data/test/unit/protip/transformers/primitives_transformer_test.rb +139 -0
- data/test/unit/protip/transformers/timestamp_transformer_test.rb +46 -0
- metadata +23 -12
- data/definitions/google/protobuf/wrappers.proto +0 -99
- data/lib/google/protobuf/descriptor.rb +0 -1
- data/lib/google/protobuf/wrappers.rb +0 -48
- data/lib/protip/converter.rb +0 -22
- data/lib/protip/standard_converter.rb +0 -185
- data/test/unit/protip/standard_converter_test.rb +0 -502
- data/test/unit/protip/wrapper_test.rb +0 -646
@@ -1,646 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
require 'google/protobuf'
|
4
|
-
require 'protip/wrapper'
|
5
|
-
require 'protip/resource'
|
6
|
-
|
7
|
-
module Protip::WrapperTest # namespace for internal constants
|
8
|
-
describe Protip::Wrapper do
|
9
|
-
let(:converter) do
|
10
|
-
Class.new do
|
11
|
-
include Protip::Converter
|
12
|
-
end.new
|
13
|
-
end
|
14
|
-
let :pool do
|
15
|
-
pool = Google::Protobuf::DescriptorPool.new
|
16
|
-
pool.build do
|
17
|
-
add_enum 'number' do
|
18
|
-
value :ZERO, 0
|
19
|
-
value :ONE, 1
|
20
|
-
value :TWO, 2
|
21
|
-
end
|
22
|
-
add_message 'inner_message' do
|
23
|
-
optional :value, :int64, 1
|
24
|
-
optional :note, :string, 2
|
25
|
-
end
|
26
|
-
add_message 'google.protobuf.BoolValue' do
|
27
|
-
optional :value, :bool, 1
|
28
|
-
end
|
29
|
-
add_message 'protip.messages.EnumValue' do
|
30
|
-
optional :value, :int32, 1
|
31
|
-
end
|
32
|
-
|
33
|
-
add_message 'message' do
|
34
|
-
optional :inner, :message, 1, 'inner_message'
|
35
|
-
optional :string, :string, 2
|
36
|
-
|
37
|
-
repeated :inners, :message, 3, 'inner_message'
|
38
|
-
repeated :strings, :string, 4
|
39
|
-
|
40
|
-
optional :inner_blank, :message, 5, 'inner_message'
|
41
|
-
|
42
|
-
optional :number, :enum, 6, 'number'
|
43
|
-
repeated :numbers, :enum, 7, 'number'
|
44
|
-
optional :number_message, :message, 8, 'protip.messages.EnumValue'
|
45
|
-
|
46
|
-
optional :boolean, :bool, 9
|
47
|
-
repeated :booleans, :bool, 10
|
48
|
-
|
49
|
-
optional :google_bool_value, :message, 11, 'google.protobuf.BoolValue'
|
50
|
-
repeated :google_bool_values, :message, 12, 'google.protobuf.BoolValue'
|
51
|
-
|
52
|
-
oneof :oneof_group do
|
53
|
-
optional :oneof_string1, :string, 13
|
54
|
-
optional :oneof_string2, :string, 14
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
pool
|
59
|
-
end
|
60
|
-
|
61
|
-
%w(inner_message message).each do |name|
|
62
|
-
let(:"#{name}_class") do
|
63
|
-
pool.lookup(name).msgclass
|
64
|
-
end
|
65
|
-
end
|
66
|
-
let(:enum_message_class) do
|
67
|
-
pool.lookup('protip.messages.EnumValue').msgclass
|
68
|
-
end
|
69
|
-
let (:inner_message_field) { message_class.descriptor.lookup('inner') }
|
70
|
-
|
71
|
-
# Stubbed API client
|
72
|
-
let :client do
|
73
|
-
mock.responds_like_instance_of(Class.new { include Protip::Client })
|
74
|
-
end
|
75
|
-
|
76
|
-
# Call `resource_class` to get an empty resource type.
|
77
|
-
let :resource_class do
|
78
|
-
resource_class = Class.new do
|
79
|
-
include Protip::Resource
|
80
|
-
self.base_path = 'base_path'
|
81
|
-
class << self
|
82
|
-
attr_accessor :client
|
83
|
-
end
|
84
|
-
end
|
85
|
-
resource_class.client = client
|
86
|
-
resource_class
|
87
|
-
end
|
88
|
-
|
89
|
-
let(:wrapped_message) do
|
90
|
-
message_class.new(inner: inner_message_class.new(value: 25), string: 'test')
|
91
|
-
end
|
92
|
-
|
93
|
-
let(:wrapper) do
|
94
|
-
Protip::Wrapper.new(wrapped_message, converter)
|
95
|
-
end
|
96
|
-
|
97
|
-
# Stub the wrapped-enum fetcher method - probably rethink this once the
|
98
|
-
# instance variable hack is no longer necessary
|
99
|
-
before do
|
100
|
-
Protip::StandardConverter.stubs(:enum_for_field)
|
101
|
-
.returns(pool.lookup('number') || raise('unexpected - no enum field found'))
|
102
|
-
end
|
103
|
-
|
104
|
-
describe '#respond_to?' do
|
105
|
-
it 'adds setters for message fields' do
|
106
|
-
assert_respond_to wrapper, :string=
|
107
|
-
assert_respond_to wrapper, :inner=
|
108
|
-
assert_respond_to wrapper, :inner_blank=
|
109
|
-
end
|
110
|
-
it 'adds getters for message fields' do
|
111
|
-
assert_respond_to wrapper, :string
|
112
|
-
assert_respond_to wrapper, :inner
|
113
|
-
assert_respond_to wrapper, :inner_blank
|
114
|
-
end
|
115
|
-
it 'adds accessors for oneof groups' do
|
116
|
-
assert_respond_to wrapper, :oneof_group
|
117
|
-
end
|
118
|
-
it 'adds queries for scalar matchable fields' do
|
119
|
-
assert_respond_to wrapper, :number?, 'enum field should respond to query'
|
120
|
-
assert_respond_to wrapper, :number_message?, 'enum message field should respond to query'
|
121
|
-
assert_respond_to wrapper, :boolean?, 'bool field should respond to query'
|
122
|
-
assert_respond_to wrapper, :google_bool_value?, 'google.protobuf.BoolValue field should respond to query'
|
123
|
-
end
|
124
|
-
it 'allows .boolean? to be overwritten to add additional queryable fields' do
|
125
|
-
wrapper.class.stubs(:boolean?).returns(true)
|
126
|
-
assert_respond_to wrapper, :string?
|
127
|
-
wrapper.class.stubs(:boolean?).returns(false)
|
128
|
-
refute_respond_to wrapper, :string?
|
129
|
-
end
|
130
|
-
it 'does not add queries for repeated fields' do
|
131
|
-
refute_respond_to wrapper, :numbers?, 'repeated enum field should not respond to query'
|
132
|
-
refute_respond_to wrapper, :booleans?, 'repeated bool field should not respond to query'
|
133
|
-
refute_respond_to wrapper, :google_bool_values?, 'repeated google.protobuf.BoolValue field should not respond to query'
|
134
|
-
end
|
135
|
-
it 'does not add queries for non-matchable fields' do
|
136
|
-
refute_respond_to wrapper, :inner?
|
137
|
-
end
|
138
|
-
it 'responds to standard defined methods' do
|
139
|
-
assert_respond_to wrapper, :as_json
|
140
|
-
end
|
141
|
-
it 'does not add other setters/getters/queries' do
|
142
|
-
refute_respond_to wrapper, :foo=
|
143
|
-
refute_respond_to wrapper, :foo
|
144
|
-
refute_respond_to wrapper, :foo?
|
145
|
-
end
|
146
|
-
it 'does not add methods which partially match message fields' do
|
147
|
-
refute_respond_to wrapper, :xinner
|
148
|
-
refute_respond_to wrapper, :xinner=
|
149
|
-
refute_respond_to wrapper, :xnumber?
|
150
|
-
refute_respond_to wrapper, :innerx
|
151
|
-
refute_respond_to wrapper, :innerx=
|
152
|
-
refute_respond_to wrapper, :'inner=x'
|
153
|
-
refute_respond_to wrapper, :numberx?
|
154
|
-
refute_respond_to wrapper, :'number?x'
|
155
|
-
end
|
156
|
-
end
|
157
|
-
|
158
|
-
describe '#build' do
|
159
|
-
it 'raises an error when building a primitive field' do
|
160
|
-
assert_raises RuntimeError do
|
161
|
-
wrapper.build(:string)
|
162
|
-
end
|
163
|
-
end
|
164
|
-
|
165
|
-
it 'raises an error when building a repeated primitive field' do
|
166
|
-
assert_raises RuntimeError do
|
167
|
-
wrapper.build(:strings)
|
168
|
-
end
|
169
|
-
end
|
170
|
-
|
171
|
-
# TODO: How to add a new message to a repeated message field?
|
172
|
-
|
173
|
-
it 'raises an error when building a convertible message' do
|
174
|
-
converter.stubs(:convertible?).with(inner_message_class).returns(true)
|
175
|
-
assert_raises RuntimeError do
|
176
|
-
wrapper.build(:inner)
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
describe 'with an inconvertible message field' do
|
181
|
-
let(:wrapped_message) { message_class.new }
|
182
|
-
|
183
|
-
before do
|
184
|
-
converter.stubs(:convertible?).with(inner_message_class).returns(false)
|
185
|
-
end
|
186
|
-
|
187
|
-
it 'builds the message when no attributes are provided' do
|
188
|
-
assert_nil wrapped_message.inner # Sanity check
|
189
|
-
wrapper.build(:inner)
|
190
|
-
assert_equal inner_message_class.new, wrapped_message.inner
|
191
|
-
end
|
192
|
-
|
193
|
-
it 'overwrites the message if it exists' do
|
194
|
-
wrapped_message.inner = inner_message_class.new(value: 4)
|
195
|
-
wrapper.build(:inner)
|
196
|
-
assert_equal inner_message_class.new, wrapped_message.inner
|
197
|
-
end
|
198
|
-
|
199
|
-
it 'delegates to #assign_attributes if attributes are provided' do
|
200
|
-
Protip::Wrapper.any_instance.expects(:assign_attributes).once.with({value: 40})
|
201
|
-
wrapper.build(:inner, value: 40)
|
202
|
-
end
|
203
|
-
|
204
|
-
it 'returns the built message' do
|
205
|
-
built = wrapper.build(:inner)
|
206
|
-
assert_equal wrapper.inner, built
|
207
|
-
end
|
208
|
-
end
|
209
|
-
end
|
210
|
-
|
211
|
-
describe '#assign_attributes' do
|
212
|
-
it 'assigns primitive fields directly' do
|
213
|
-
wrapper.assign_attributes string: 'another thing'
|
214
|
-
assert_equal 'another thing', wrapped_message.string
|
215
|
-
end
|
216
|
-
|
217
|
-
it 'assigns repeated primitive fields from an enumerator' do
|
218
|
-
wrapper.assign_attributes strings: ['one', 'two']
|
219
|
-
assert_equal ['one', 'two'], wrapped_message.strings
|
220
|
-
end
|
221
|
-
|
222
|
-
describe 'when assigning convertible message fields' do
|
223
|
-
before do
|
224
|
-
converter.stubs(:convertible?).with(inner_message_class).returns(true)
|
225
|
-
end
|
226
|
-
|
227
|
-
it 'converts scalar Ruby values to protobuf messages' do
|
228
|
-
converter.expects(:to_message).once.with(45, inner_message_class, inner_message_field).returns(inner_message_class.new(value: 43))
|
229
|
-
wrapper.assign_attributes inner: 45
|
230
|
-
assert_equal inner_message_class.new(value: 43), wrapped_message.inner
|
231
|
-
end
|
232
|
-
|
233
|
-
it 'converts repeated Ruby values to protobuf messages' do
|
234
|
-
invocation = 0
|
235
|
-
converter.expects(:to_message).twice.with do |value|
|
236
|
-
invocation += 1
|
237
|
-
value == invocation
|
238
|
-
end.returns(inner_message_class.new(value: 43), inner_message_class.new(value: 44))
|
239
|
-
wrapper.assign_attributes inners: [1, 2]
|
240
|
-
assert_equal [inner_message_class.new(value: 43), inner_message_class.new(value: 44)], wrapped_message.inners
|
241
|
-
end
|
242
|
-
|
243
|
-
it 'allows messages to be assigned directly' do
|
244
|
-
message = inner_message_class.new
|
245
|
-
wrapper.assign_attributes inner: message
|
246
|
-
assert_same message, wrapper.message.inner
|
247
|
-
end
|
248
|
-
end
|
249
|
-
|
250
|
-
it 'returns nil' do
|
251
|
-
assert_nil wrapper.assign_attributes({})
|
252
|
-
end
|
253
|
-
|
254
|
-
describe 'when assigning inconvertible message fields' do
|
255
|
-
before do
|
256
|
-
converter.stubs(:convertible?).with(inner_message_class).returns(false)
|
257
|
-
end
|
258
|
-
|
259
|
-
it 'sets multiple attributes' do
|
260
|
-
wrapper.assign_attributes string: 'test2', inner: {value: 50}
|
261
|
-
assert_equal 'test2', wrapped_message.string
|
262
|
-
assert_equal inner_message_class.new(value: 50), wrapped_message.inner
|
263
|
-
end
|
264
|
-
|
265
|
-
it 'updates inconvertible message fields which have already been built' do
|
266
|
-
wrapped_message.inner = inner_message_class.new(value: 60)
|
267
|
-
wrapper.assign_attributes inner: {note: 'updated'}
|
268
|
-
assert_equal inner_message_class.new(value: 60, note: 'updated'), wrapped_message.inner
|
269
|
-
end
|
270
|
-
|
271
|
-
it 'delegates to #assign_attributes on a nested wrapper when setting nested attributes on inconvertible message fields' do
|
272
|
-
inner = mock
|
273
|
-
field = wrapped_message.class.descriptor.detect{|f| f.name.to_sym == :inner}
|
274
|
-
raise 'unexpected' if !field
|
275
|
-
wrapper.stubs(:get).with(field).returns(inner)
|
276
|
-
inner.expects(:assign_attributes).once.with(value: 50, note: 'noted')
|
277
|
-
wrapper.assign_attributes inner: {value: 50, note: 'noted'}
|
278
|
-
end
|
279
|
-
|
280
|
-
it 'sets message fields to nil when they\'re assigned nil' do
|
281
|
-
wrapped_message.inner = inner_message_class.new(value: 60)
|
282
|
-
assert wrapped_message.inner
|
283
|
-
wrapper.assign_attributes inner: nil
|
284
|
-
assert_nil wrapped_message.inner
|
285
|
-
end
|
286
|
-
|
287
|
-
it 'allows messages to be assigned directly' do
|
288
|
-
message = inner_message_class.new
|
289
|
-
wrapper.assign_attributes inner: message
|
290
|
-
assert_same message, wrapper.message.inner
|
291
|
-
end
|
292
|
-
end
|
293
|
-
end
|
294
|
-
|
295
|
-
describe '#==' do
|
296
|
-
it 'returns false for non-wrapper objects' do
|
297
|
-
refute_equal 1, wrapper
|
298
|
-
refute_equal wrapper, 1 # Sanity check, make sure we're testing both sides of equality
|
299
|
-
end
|
300
|
-
|
301
|
-
it 'returns false when messages are not equal' do
|
302
|
-
alternate_message = message_class.new
|
303
|
-
refute_equal alternate_message, wrapper.message # Sanity check
|
304
|
-
refute_equal wrapper, Protip::Wrapper.new(alternate_message, wrapper.converter)
|
305
|
-
end
|
306
|
-
|
307
|
-
it 'returns false when converters are not equal' do
|
308
|
-
alternate_converter = Class.new do
|
309
|
-
include Protip::Converter
|
310
|
-
end.new
|
311
|
-
refute_equal alternate_converter, converter # Sanity check
|
312
|
-
refute_equal wrapper, Protip::Wrapper.new(wrapped_message, alternate_converter)
|
313
|
-
end
|
314
|
-
|
315
|
-
it 'returns true when the message and converter are equal' do
|
316
|
-
# Stub converter equality so we aren't relying on actual equality behavior there
|
317
|
-
alternate_converter = converter.clone
|
318
|
-
converter.expects(:==).at_least_once.with(alternate_converter).returns(true)
|
319
|
-
assert_equal wrapper, Protip::Wrapper.new(wrapped_message.clone, converter)
|
320
|
-
end
|
321
|
-
end
|
322
|
-
|
323
|
-
describe '#convert' do
|
324
|
-
let :wrapped_message do
|
325
|
-
m = message_class.new({
|
326
|
-
string: 'test',
|
327
|
-
inner: inner_message_class.new(value: 1),
|
328
|
-
})
|
329
|
-
m.strings += %w(test1 test2)
|
330
|
-
[2, 3].each do |i|
|
331
|
-
m.inners.push inner_message_class.new(value: i)
|
332
|
-
end
|
333
|
-
m
|
334
|
-
end
|
335
|
-
before do
|
336
|
-
converter.stubs(:convertible?).with(message_class).returns false
|
337
|
-
end
|
338
|
-
|
339
|
-
it 'never checks the convertibility of the top-level message' do
|
340
|
-
converter.expects(:convertible?).with(message_class).never
|
341
|
-
converter.stubs(:convertible?).with(inner_message_class).returns false
|
342
|
-
assert_instance_of Hash, wrapper.to_h
|
343
|
-
end
|
344
|
-
|
345
|
-
describe 'with a nested convertible message' do
|
346
|
-
before do
|
347
|
-
converter.stubs(:convertible?).with(inner_message_class).returns true
|
348
|
-
[1, 2, 3].each{|i| converter.stubs(:to_object).with(inner_message_class.new(value: i), anything).returns(i)}
|
349
|
-
end
|
350
|
-
it 'returns a hash with the nested message converted' do
|
351
|
-
assert_equal 1, wrapper.to_h[:inner]
|
352
|
-
end
|
353
|
-
it 'converts a repeated instance of the nested message to an array' do
|
354
|
-
assert_equal [2, 3], wrapper.to_h[:inners]
|
355
|
-
end
|
356
|
-
end
|
357
|
-
|
358
|
-
describe 'with a nested inconvertible message' do
|
359
|
-
before do
|
360
|
-
converter.stubs(:convertible?).with(inner_message_class).returns false
|
361
|
-
end
|
362
|
-
|
363
|
-
it 'contains keys for all fields of the parent message' do
|
364
|
-
keys = %i(string strings inner inners inner_blank number numbers number_message boolean booleans
|
365
|
-
google_bool_value google_bool_values oneof_string1 oneof_string2)
|
366
|
-
assert_equal keys.sort, wrapper.to_h.keys.sort
|
367
|
-
end
|
368
|
-
it 'assigns nil for missing nested messages' do
|
369
|
-
hash = wrapper.to_h
|
370
|
-
assert hash.has_key?(:inner_blank)
|
371
|
-
assert_nil hash[:inner_blank]
|
372
|
-
end
|
373
|
-
it 'assigns a hash for a scalar instance of the inconvertible message' do
|
374
|
-
assert_equal({value: 1, note: ''}, wrapper.to_h[:inner])
|
375
|
-
end
|
376
|
-
it 'assigns an array of hashes for a repeated instance of the inconvertible message' do
|
377
|
-
assert_equal([{value: 2, note: ''}, {value: 3, note: ''}], wrapper.to_h[:inners])
|
378
|
-
end
|
379
|
-
it 'assigns primitive fields directly' do
|
380
|
-
assert_equal 'test', wrapper.to_h[:string]
|
381
|
-
end
|
382
|
-
it 'assigns an array for repeated primitive fields' do
|
383
|
-
assert_equal %w(test1 test2), wrapper.to_h[:strings]
|
384
|
-
end
|
385
|
-
end
|
386
|
-
end
|
387
|
-
|
388
|
-
describe '#get' do
|
389
|
-
before do
|
390
|
-
resource_class.class_exec(converter, inner_message_class) do |converter, message|
|
391
|
-
resource actions: [], message: message
|
392
|
-
self.converter = converter
|
393
|
-
end
|
394
|
-
end
|
395
|
-
|
396
|
-
it 'does not convert simple fields' do
|
397
|
-
converter.expects(:convertible?).never
|
398
|
-
converter.expects(:to_object).never
|
399
|
-
assert_equal 'test', wrapper.string
|
400
|
-
end
|
401
|
-
|
402
|
-
it 'converts convertible messages' do
|
403
|
-
converter.expects(:convertible?).with(inner_message_class).once.returns(true)
|
404
|
-
converter.expects(:to_object).once.with(inner_message_class.new(value: 25), inner_message_field).returns 40
|
405
|
-
assert_equal 40, wrapper.inner
|
406
|
-
end
|
407
|
-
|
408
|
-
it 'wraps inconvertible messages' do
|
409
|
-
converter.expects(:convertible?).with(inner_message_class).once.returns(false)
|
410
|
-
converter.expects(:to_object).never
|
411
|
-
assert_equal Protip::Wrapper.new(inner_message_class.new(value: 25), converter), wrapper.inner
|
412
|
-
end
|
413
|
-
|
414
|
-
it 'wraps nested resource messages in their defined resource' do
|
415
|
-
message = wrapped_message
|
416
|
-
klass = resource_class
|
417
|
-
wrapper = Protip::Wrapper.new(message, Protip::StandardConverter.new, {inner: klass})
|
418
|
-
assert_equal klass, wrapper.inner.class
|
419
|
-
assert_equal message.inner, wrapper.inner.message
|
420
|
-
end
|
421
|
-
|
422
|
-
it 'returns nil for messages that have not been set' do
|
423
|
-
converter.expects(:convertible?).never
|
424
|
-
converter.expects(:to_object).never
|
425
|
-
assert_equal nil, wrapper.inner_blank
|
426
|
-
end
|
427
|
-
end
|
428
|
-
|
429
|
-
describe 'attribute reader' do # generated via method_missing?
|
430
|
-
it 'returns the underlying assigned value for oneof fields' do
|
431
|
-
wrapper.oneof_string1 = 'foo'
|
432
|
-
assert_equal 'foo', wrapper.oneof_group
|
433
|
-
wrapper.oneof_string2 = 'bar'
|
434
|
-
assert_equal 'bar', wrapper.oneof_group
|
435
|
-
wrapper.oneof_string2 = 'bar'
|
436
|
-
wrapper.oneof_string1 = 'foo'
|
437
|
-
assert_equal 'foo', wrapper.oneof_group
|
438
|
-
end
|
439
|
-
|
440
|
-
it 'returns nil for oneof fields that have not been set' do
|
441
|
-
assert_nil wrapper.oneof_group
|
442
|
-
end
|
443
|
-
end
|
444
|
-
|
445
|
-
describe 'attribute writer' do # generated via method_missing?
|
446
|
-
|
447
|
-
before do
|
448
|
-
resource_class.class_exec(converter, inner_message_class) do |converter, message|
|
449
|
-
resource actions: [], message: message
|
450
|
-
self.converter = converter
|
451
|
-
end
|
452
|
-
end
|
453
|
-
|
454
|
-
it 'does not convert simple fields' do
|
455
|
-
converter.expects(:convertible?).never
|
456
|
-
converter.expects(:to_message).never
|
457
|
-
|
458
|
-
wrapper.string = 'test2'
|
459
|
-
assert_equal 'test2', wrapper.message.string
|
460
|
-
end
|
461
|
-
|
462
|
-
it 'converts convertible messages' do
|
463
|
-
converter.expects(:convertible?).at_least_once.with(inner_message_class).returns(true)
|
464
|
-
converter.expects(:to_message).with(40, inner_message_class, inner_message_field).returns(inner_message_class.new(value: 30))
|
465
|
-
|
466
|
-
wrapper.inner = 40
|
467
|
-
assert_equal inner_message_class.new(value: 30), wrapper.message.inner
|
468
|
-
end
|
469
|
-
|
470
|
-
it 'removes message fields when assigning nil, without checking with the converter' do
|
471
|
-
converter.expects(:convertible?).never
|
472
|
-
converter.expects(:to_message).never
|
473
|
-
|
474
|
-
wrapper.inner = nil
|
475
|
-
assert_equal nil, wrapper.message.inner
|
476
|
-
end
|
477
|
-
|
478
|
-
it 'raises an error when setting inconvertible messages' do
|
479
|
-
converter.expects(:convertible?).at_least_once.with(inner_message_class).returns(false)
|
480
|
-
converter.expects(:to_message).never
|
481
|
-
assert_raises ArgumentError do
|
482
|
-
wrapper.inner = 'cannot convert me'
|
483
|
-
end
|
484
|
-
end
|
485
|
-
|
486
|
-
it 'passes through messages without checking whether they are convertible' do
|
487
|
-
message = inner_message_class.new(value: 50)
|
488
|
-
|
489
|
-
converter.expects(:convertible?).never
|
490
|
-
converter.expects(:to_message).never
|
491
|
-
wrapper.inner = message
|
492
|
-
assert_equal inner_message_class.new(value: 50), wrapper.message.inner
|
493
|
-
end
|
494
|
-
|
495
|
-
it 'for nested resources, sets the resource\'s message' do
|
496
|
-
message = wrapped_message
|
497
|
-
klass = resource_class
|
498
|
-
new_inner_message = inner_message_class.new(value: 50)
|
499
|
-
|
500
|
-
resource = klass.new new_inner_message
|
501
|
-
wrapper = Protip::Wrapper.new(message, Protip::StandardConverter.new, {inner: klass})
|
502
|
-
|
503
|
-
resource.expects(:message).once.returns(new_inner_message)
|
504
|
-
wrapper.inner = resource
|
505
|
-
|
506
|
-
assert_equal new_inner_message,
|
507
|
-
wrapper.message.inner,
|
508
|
-
'Wrapper did not set its message\'s inner message value to the value of the '\
|
509
|
-
'given resource\'s message'
|
510
|
-
end
|
511
|
-
|
512
|
-
it 'raises an error when setting an enum field to an undefined value' do
|
513
|
-
assert_raises RangeError do
|
514
|
-
wrapper.number = :NAN
|
515
|
-
end
|
516
|
-
end
|
517
|
-
|
518
|
-
it 'allows strings to be set for enum fields' do
|
519
|
-
wrapper.number = 'ONE'
|
520
|
-
assert_equal :ONE, wrapper.number
|
521
|
-
end
|
522
|
-
|
523
|
-
it 'allows symbols to be set for enum fields' do
|
524
|
-
wrapper.number = :ONE
|
525
|
-
assert_equal :ONE, wrapper.number
|
526
|
-
end
|
527
|
-
|
528
|
-
it 'allows numbers to be set for enum fields' do
|
529
|
-
wrapper.number = 1
|
530
|
-
assert_equal :ONE, wrapper.number
|
531
|
-
end
|
532
|
-
|
533
|
-
it 'allows symbolizable values to be set for enum fields' do
|
534
|
-
m = mock
|
535
|
-
m.stubs(:to_sym).returns(:ONE)
|
536
|
-
|
537
|
-
wrapper.number = m
|
538
|
-
assert_equal :ONE, wrapper.number
|
539
|
-
end
|
540
|
-
|
541
|
-
it 'returns the input value' do
|
542
|
-
input_value = 'str'
|
543
|
-
assert_equal input_value, wrapper.send(:string=, input_value)
|
544
|
-
end
|
545
|
-
end
|
546
|
-
|
547
|
-
describe 'boolean query methods' do
|
548
|
-
it 'returns the boolean-ized version of the field' do
|
549
|
-
wrapper.class.stubs(:boolean?).returns(true)
|
550
|
-
|
551
|
-
# Sanity checks
|
552
|
-
raise 'unexpected string' unless wrapper.string == 'test'
|
553
|
-
raise 'unexpected boolean' unless wrapper.boolean == false
|
554
|
-
raise 'unexpected google_bool_value' unless wrapper.google_bool_value == nil
|
555
|
-
|
556
|
-
assert_equal true, wrapper.string?, 'did not convert string to boolean'
|
557
|
-
assert_equal false, wrapper.boolean?, 'did not pass through boolean value'
|
558
|
-
assert_equal false, wrapper.google_bool_value?, 'did not convert nil to boolean'
|
559
|
-
end
|
560
|
-
end
|
561
|
-
|
562
|
-
describe '#matches?' do
|
563
|
-
it 'is not defined for non-enum fields' do
|
564
|
-
assert_raises NoMethodError do
|
565
|
-
wrapper.inner?(:test)
|
566
|
-
end
|
567
|
-
end
|
568
|
-
|
569
|
-
it 'is not defined for repeated enum fields' do
|
570
|
-
assert_raises NoMethodError do
|
571
|
-
wrapper.numbers?(:test)
|
572
|
-
end
|
573
|
-
end
|
574
|
-
|
575
|
-
describe 'when given a Fixnum' do
|
576
|
-
before do
|
577
|
-
wrapper.number = :ONE
|
578
|
-
end
|
579
|
-
it 'returns true when the number matches the value' do
|
580
|
-
assert wrapper.number?(1)
|
581
|
-
end
|
582
|
-
it 'returns false when the number does not match the value' do
|
583
|
-
refute wrapper.number?(0)
|
584
|
-
end
|
585
|
-
it 'raises an error when the number is not a valid value for the enum' do
|
586
|
-
assert_raises RangeError do
|
587
|
-
wrapper.number?(3)
|
588
|
-
end
|
589
|
-
end
|
590
|
-
end
|
591
|
-
|
592
|
-
describe 'when given a non-Fixnum' do
|
593
|
-
before do
|
594
|
-
wrapper.number = :TWO
|
595
|
-
end
|
596
|
-
it 'returns true when its symbolized argument matches the value' do
|
597
|
-
m = mock
|
598
|
-
m.expects(:to_sym).returns :TWO
|
599
|
-
assert wrapper.number?(m)
|
600
|
-
end
|
601
|
-
it 'returns false when its symbolized argument does not match the value' do
|
602
|
-
m = mock
|
603
|
-
m.expects(:to_sym).returns :ONE
|
604
|
-
refute wrapper.number?(m)
|
605
|
-
end
|
606
|
-
it 'raises an error when its symbolized argument is not a valid value for the enum' do
|
607
|
-
m = mock
|
608
|
-
m.expects(:to_sym).returns :NAN
|
609
|
-
assert_raises RangeError do
|
610
|
-
wrapper.number?(m)
|
611
|
-
end
|
612
|
-
end
|
613
|
-
end
|
614
|
-
|
615
|
-
describe 'for a wrapped enum' do
|
616
|
-
let :enum_message do
|
617
|
-
enum_message_class.new value: 1
|
618
|
-
end
|
619
|
-
|
620
|
-
before do
|
621
|
-
converter.stubs(:convertible?).with(enum_message_class).returns true
|
622
|
-
converter.stubs(:to_object).with(enum_message, anything).returns :ONE
|
623
|
-
wrapper.message.number_message = enum_message
|
624
|
-
end
|
625
|
-
|
626
|
-
it 'returns true when its symbolized argument matches the value' do
|
627
|
-
m = mock
|
628
|
-
m.expects(:to_sym).returns :ONE
|
629
|
-
assert wrapper.number_message?(m)
|
630
|
-
end
|
631
|
-
|
632
|
-
it 'returns false when its symbolized argument does not match the value' do
|
633
|
-
m = mock
|
634
|
-
m.expects(:to_sym).returns :TWO
|
635
|
-
refute wrapper.number_message?(m)
|
636
|
-
end
|
637
|
-
|
638
|
-
it 'returns true when a Fixnum argument matches the value' do
|
639
|
-
assert wrapper.number_message?(1)
|
640
|
-
end
|
641
|
-
|
642
|
-
end
|
643
|
-
|
644
|
-
end
|
645
|
-
end
|
646
|
-
end
|