autoparse 0.1.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.
- data/CHANGELOG +3 -0
- data/LICENSE +202 -0
- data/README.md +25 -0
- data/Rakefile +60 -0
- data/lib/autoparse/inflection.rb +23 -0
- data/lib/autoparse/instance.rb +422 -0
- data/lib/autoparse/version.rb +26 -0
- data/lib/autoparse.rb +203 -0
- data/spec/autoparse/instance_spec.rb +904 -0
- data/spec/data/account.json +8 -0
- data/spec/data/address.json +20 -0
- data/spec/data/adult.json +5 -0
- data/spec/data/calendar.json +49 -0
- data/spec/data/card.json +105 -0
- data/spec/data/geo.json +9 -0
- data/spec/data/hyper-schema.json +60 -0
- data/spec/data/interfaces.json +23 -0
- data/spec/data/json-ref.json +26 -0
- data/spec/data/links.json +35 -0
- data/spec/data/person.json +11 -0
- data/spec/data/positive.json +5 -0
- data/spec/data/schema.json +174 -0
- data/spec/spec.opts +2 -0
- data/spec/spec_helper.rb +7 -0
- data/tasks/clobber.rake +2 -0
- data/tasks/gem.rake +72 -0
- data/tasks/git.rake +40 -0
- data/tasks/metrics.rake +22 -0
- data/tasks/rdoc.rake +26 -0
- data/tasks/rubyforge.rake +103 -0
- data/tasks/spec.rake +71 -0
- data/tasks/yard.rake +26 -0
- data/website/index.html +95 -0
- metadata +212 -0
@@ -0,0 +1,904 @@
|
|
1
|
+
# Copyright 2010 Google Inc
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
|
16
|
+
spec_dir = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
17
|
+
|
18
|
+
require 'spec_helper'
|
19
|
+
|
20
|
+
require 'json'
|
21
|
+
require 'autoparse'
|
22
|
+
require 'addressable/uri'
|
23
|
+
|
24
|
+
describe AutoParse::Instance, 'with an empty schema' do
|
25
|
+
before do
|
26
|
+
@parser = AutoParse::EMPTY_SCHEMA
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should accept all inputs' do
|
30
|
+
instance = @parser.new({
|
31
|
+
"this" => "doesn't",
|
32
|
+
"really" => ["matter", "at", "all"],
|
33
|
+
"!" => 1.2345
|
34
|
+
})
|
35
|
+
instance.should be_valid
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should expose values via index methods' do
|
39
|
+
instance = @parser.new({
|
40
|
+
"this" => "doesn't",
|
41
|
+
"really" => ["matter", "at", "all"],
|
42
|
+
"!" => 1.2345
|
43
|
+
})
|
44
|
+
instance["this"].should == "doesn't"
|
45
|
+
instance["really"].should == ["matter", "at", "all"]
|
46
|
+
instance["!"].should == 1.2345
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'should be coerceable to a Hash value' do
|
50
|
+
instance = @parser.new({
|
51
|
+
"this" => "doesn't",
|
52
|
+
"really" => ["matter", "at", "all"],
|
53
|
+
"!" => 1.2345
|
54
|
+
})
|
55
|
+
instance.to_hash.should == {
|
56
|
+
"this" => "doesn't",
|
57
|
+
"really" => ["matter", "at", "all"],
|
58
|
+
"!" => 1.2345
|
59
|
+
}
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'should convert to a JSON string' do
|
63
|
+
instance = @parser.new({"be" => "brief"})
|
64
|
+
instance.to_json.should == '{"be":"brief"}'
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe AutoParse::Instance, 'with the geo schema' do
|
69
|
+
before do
|
70
|
+
@uri = Addressable::URI.new(
|
71
|
+
:scheme => 'file',
|
72
|
+
:host => '',
|
73
|
+
:path => File.expand_path(File.join(spec_dir, './data/geo.json'))
|
74
|
+
)
|
75
|
+
@schema_data = JSON.parse(File.open(@uri.path, 'r') { |f| f.read })
|
76
|
+
@parser = AutoParse.generate(@schema_data, @uri)
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'should accept a valid geographic coordinate input' do
|
80
|
+
instance = @parser.new({
|
81
|
+
"latitude" => 37.422,
|
82
|
+
"longitude" => -122.084
|
83
|
+
})
|
84
|
+
instance.should be_valid
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'should not accept an invalid geographic coordinate input' do
|
88
|
+
instance = @parser.new({
|
89
|
+
"latitude" => "not",
|
90
|
+
"longitude" => "valid"
|
91
|
+
})
|
92
|
+
instance.should_not be_valid
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'should accept extra fields' do
|
96
|
+
instance = @parser.new({
|
97
|
+
"latitude" => 37.422,
|
98
|
+
"longitude" => -122.084,
|
99
|
+
"extra" => "bonus!"
|
100
|
+
})
|
101
|
+
instance.should be_valid
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'should expose values via generated accessors' do
|
105
|
+
instance = @parser.new({
|
106
|
+
"latitude" => 37.422,
|
107
|
+
"longitude" => -122.084
|
108
|
+
})
|
109
|
+
instance.latitude.should == 37.422
|
110
|
+
instance.longitude.should == -122.084
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'should be coerceable to a Hash value' do
|
114
|
+
instance = @parser.new({
|
115
|
+
"latitude" => 37.422,
|
116
|
+
"longitude" => -122.084
|
117
|
+
})
|
118
|
+
instance.to_hash.should == {
|
119
|
+
"latitude" => 37.422,
|
120
|
+
"longitude" => -122.084
|
121
|
+
}
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'should convert to a JSON string' do
|
125
|
+
instance = @parser.new({
|
126
|
+
"latitude" => 37.422,
|
127
|
+
"longitude" => -122.084
|
128
|
+
})
|
129
|
+
instance.to_json.should == '{"latitude":37.422,"longitude":-122.084}'
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
|
134
|
+
describe AutoParse::Instance, 'with the address schema' do
|
135
|
+
before do
|
136
|
+
@uri = Addressable::URI.new(
|
137
|
+
:scheme => 'file',
|
138
|
+
:host => '',
|
139
|
+
:path => File.expand_path(File.join(spec_dir, './data/address.json'))
|
140
|
+
)
|
141
|
+
@schema_data = JSON.parse(File.open(@uri.path, 'r') { |f| f.read })
|
142
|
+
@parser = AutoParse.generate(@schema_data, @uri)
|
143
|
+
end
|
144
|
+
|
145
|
+
it 'should accept a valid address input' do
|
146
|
+
instance = @parser.new({
|
147
|
+
"post-office-box" => "PO Box 3.14159",
|
148
|
+
"street-address" => "1600 Amphitheatre Parkway",
|
149
|
+
"locality" => "Mountain View",
|
150
|
+
"region" => "CA",
|
151
|
+
"postal-code" => "94043",
|
152
|
+
"country-name" => "United States"
|
153
|
+
})
|
154
|
+
instance.should be_valid
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'should accept extra fields' do
|
158
|
+
instance = @parser.new({
|
159
|
+
"post-office-box" => "PO Box 3.14159",
|
160
|
+
"street-address" => "1600 Amphitheatre Parkway",
|
161
|
+
"locality" => "Mountain View",
|
162
|
+
"region" => "CA",
|
163
|
+
"postal-code" => "94043",
|
164
|
+
"country-name" => "United States",
|
165
|
+
"extra" => "bonus!"
|
166
|
+
})
|
167
|
+
instance.should be_valid
|
168
|
+
end
|
169
|
+
|
170
|
+
it 'should accept a minimally valid address input' do
|
171
|
+
instance = @parser.new({
|
172
|
+
"locality" => "Mountain View",
|
173
|
+
"region" => "CA",
|
174
|
+
"country-name" => "United States"
|
175
|
+
})
|
176
|
+
instance.should be_valid
|
177
|
+
end
|
178
|
+
|
179
|
+
it 'should not accept an address with unmet dependencies' do
|
180
|
+
instance = @parser.new({
|
181
|
+
"post-office-box" => "PO Box 3.14159",
|
182
|
+
"extended-address" => "Apt 2.71828",
|
183
|
+
"locality" => "Mountain View",
|
184
|
+
"region" => "CA",
|
185
|
+
"country-name" => "United States"
|
186
|
+
})
|
187
|
+
instance.should_not be_valid
|
188
|
+
end
|
189
|
+
|
190
|
+
it 'should expose values via generated accessors' do
|
191
|
+
instance = @parser.new({
|
192
|
+
"post-office-box" => "PO Box 3.14159",
|
193
|
+
"street-address" => "1600 Amphitheatre Parkway",
|
194
|
+
"locality" => "Mountain View",
|
195
|
+
"region" => "CA",
|
196
|
+
"postal-code" => "94043",
|
197
|
+
"country-name" => "United States"
|
198
|
+
})
|
199
|
+
instance.post_office_box.should == "PO Box 3.14159"
|
200
|
+
instance.street_address.should == "1600 Amphitheatre Parkway"
|
201
|
+
instance.locality.should == "Mountain View"
|
202
|
+
instance.region.should == "CA"
|
203
|
+
instance.postal_code.should == "94043"
|
204
|
+
instance.country_name.should == "United States"
|
205
|
+
end
|
206
|
+
|
207
|
+
it 'should be coerceable to a Hash value' do
|
208
|
+
instance = @parser.new({
|
209
|
+
"post-office-box" => "PO Box 3.14159",
|
210
|
+
"street-address" => "1600 Amphitheatre Parkway",
|
211
|
+
"locality" => "Mountain View",
|
212
|
+
"region" => "CA",
|
213
|
+
"postal-code" => "94043",
|
214
|
+
"country-name" => "United States"
|
215
|
+
})
|
216
|
+
instance.to_hash.should == {
|
217
|
+
"post-office-box" => "PO Box 3.14159",
|
218
|
+
"street-address" => "1600 Amphitheatre Parkway",
|
219
|
+
"locality" => "Mountain View",
|
220
|
+
"region" => "CA",
|
221
|
+
"postal-code" => "94043",
|
222
|
+
"country-name" => "United States"
|
223
|
+
}
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
describe AutoParse::Instance, 'with the person schema' do
|
228
|
+
before do
|
229
|
+
@uri = Addressable::URI.new(
|
230
|
+
:scheme => 'file',
|
231
|
+
:host => '',
|
232
|
+
:path => File.expand_path(File.join(spec_dir, './data/person.json'))
|
233
|
+
)
|
234
|
+
@schema_data = JSON.parse(File.open(@uri.path, 'r') { |f| f.read })
|
235
|
+
@parser = AutoParse.generate(@schema_data, @uri)
|
236
|
+
end
|
237
|
+
|
238
|
+
it 'should accept a valid person input' do
|
239
|
+
instance = @parser.new({
|
240
|
+
"name" => "Bob Aman",
|
241
|
+
"age" => 29
|
242
|
+
})
|
243
|
+
instance.should be_valid
|
244
|
+
end
|
245
|
+
|
246
|
+
it 'should accept extra fields' do
|
247
|
+
instance = @parser.new({
|
248
|
+
"name" => "Bob Aman",
|
249
|
+
"age" => 29,
|
250
|
+
"extra" => "bonus!"
|
251
|
+
})
|
252
|
+
instance.should be_valid
|
253
|
+
end
|
254
|
+
|
255
|
+
it 'should validate a person whose age is equal to the maximum' do
|
256
|
+
instance = @parser.new({
|
257
|
+
"name" => "Aged Outlier",
|
258
|
+
"age" => 125
|
259
|
+
})
|
260
|
+
instance.should be_valid
|
261
|
+
end
|
262
|
+
|
263
|
+
it 'should validate a young person' do
|
264
|
+
instance = @parser.new({
|
265
|
+
"name" => "Joe Teenager",
|
266
|
+
"age" => 15
|
267
|
+
})
|
268
|
+
instance.should be_valid
|
269
|
+
end
|
270
|
+
|
271
|
+
it 'should not accept an invalid person input' do
|
272
|
+
instance = @parser.new({
|
273
|
+
"name" => "Methuselah",
|
274
|
+
"age" => 969
|
275
|
+
})
|
276
|
+
instance.should_not be_valid
|
277
|
+
end
|
278
|
+
|
279
|
+
it 'should not accept ages which are not integers' do
|
280
|
+
instance = @parser.new({
|
281
|
+
"name" => "Bob Aman",
|
282
|
+
"age" => 29.7
|
283
|
+
})
|
284
|
+
instance.should_not be_valid
|
285
|
+
end
|
286
|
+
|
287
|
+
it 'should expose values via generated accessors' do
|
288
|
+
instance = @parser.new({
|
289
|
+
"name" => "Bob Aman",
|
290
|
+
"age" => 29
|
291
|
+
})
|
292
|
+
instance.name.should == "Bob Aman"
|
293
|
+
instance.age.should == 29
|
294
|
+
end
|
295
|
+
|
296
|
+
it 'should be coerceable to a Hash value' do
|
297
|
+
instance = @parser.new({
|
298
|
+
"name" => "Bob Aman",
|
299
|
+
"age" => 29
|
300
|
+
})
|
301
|
+
instance.to_hash.should == {
|
302
|
+
"name" => "Bob Aman",
|
303
|
+
"age" => 29
|
304
|
+
}
|
305
|
+
end
|
306
|
+
|
307
|
+
it 'should convert to a JSON string' do
|
308
|
+
instance = @parser.new({
|
309
|
+
"name" => "Bob Aman",
|
310
|
+
"age" => 29
|
311
|
+
})
|
312
|
+
instance.to_json.should == '{"name":"Bob Aman","age":29}'
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
describe AutoParse::Instance, 'with the adult schema' do
|
317
|
+
before do
|
318
|
+
@person_uri = Addressable::URI.new(
|
319
|
+
:scheme => 'file',
|
320
|
+
:host => '',
|
321
|
+
:path => File.expand_path(File.join(spec_dir, './data/person.json'))
|
322
|
+
)
|
323
|
+
@person_schema_data =
|
324
|
+
JSON.parse(File.open(@person_uri.path, 'r') { |f| f.read })
|
325
|
+
@person_parser = AutoParse.generate(@person_schema_data, @person_uri)
|
326
|
+
|
327
|
+
@adult_uri = Addressable::URI.new(
|
328
|
+
:scheme => 'file',
|
329
|
+
:host => '',
|
330
|
+
:path => File.expand_path(File.join(spec_dir, './data/adult.json'))
|
331
|
+
)
|
332
|
+
@adult_schema_data =
|
333
|
+
JSON.parse(File.open(@adult_uri.path, 'r') { |f| f.read })
|
334
|
+
@adult_parser = AutoParse.generate(@adult_schema_data, @adult_uri)
|
335
|
+
end
|
336
|
+
|
337
|
+
it 'should accept a valid person input' do
|
338
|
+
instance = @adult_parser.new({
|
339
|
+
"name" => "Bob Aman",
|
340
|
+
"age" => 29
|
341
|
+
})
|
342
|
+
instance.should be_valid
|
343
|
+
end
|
344
|
+
|
345
|
+
it 'should accept extra fields' do
|
346
|
+
instance = @adult_parser.new({
|
347
|
+
"name" => "Bob Aman",
|
348
|
+
"age" => 29,
|
349
|
+
"extra" => "bonus!"
|
350
|
+
})
|
351
|
+
instance.should be_valid
|
352
|
+
end
|
353
|
+
|
354
|
+
it 'should validate a person whose age is equal to the maximum' do
|
355
|
+
instance = @adult_parser.new({
|
356
|
+
"name" => "Aged Outlier",
|
357
|
+
"age" => 125
|
358
|
+
})
|
359
|
+
instance.should be_valid
|
360
|
+
end
|
361
|
+
|
362
|
+
it 'should not validate a young person' do
|
363
|
+
instance = @adult_parser.new({
|
364
|
+
"name" => "Joe Teenager",
|
365
|
+
"age" => 15
|
366
|
+
})
|
367
|
+
instance.should_not be_valid
|
368
|
+
end
|
369
|
+
|
370
|
+
it 'should not accept an invalid person input' do
|
371
|
+
instance = @adult_parser.new({
|
372
|
+
"name" => "Methuselah",
|
373
|
+
"age" => 969
|
374
|
+
})
|
375
|
+
instance.should_not be_valid
|
376
|
+
end
|
377
|
+
|
378
|
+
it 'should not accept ages which are not integers' do
|
379
|
+
instance = @adult_parser.new({
|
380
|
+
"name" => "Bob Aman",
|
381
|
+
"age" => 29.7
|
382
|
+
})
|
383
|
+
instance.should_not be_valid
|
384
|
+
end
|
385
|
+
|
386
|
+
it 'should expose values via generated accessors' do
|
387
|
+
instance = @adult_parser.new({
|
388
|
+
"name" => "Bob Aman",
|
389
|
+
"age" => 29
|
390
|
+
})
|
391
|
+
instance.name.should == "Bob Aman"
|
392
|
+
instance.age.should == 29
|
393
|
+
end
|
394
|
+
|
395
|
+
it 'should be coerceable to a Hash value' do
|
396
|
+
instance = @adult_parser.new({
|
397
|
+
"name" => "Bob Aman",
|
398
|
+
"age" => 29
|
399
|
+
})
|
400
|
+
instance.to_hash.should == {
|
401
|
+
"name" => "Bob Aman",
|
402
|
+
"age" => 29
|
403
|
+
}
|
404
|
+
end
|
405
|
+
|
406
|
+
it 'should convert to a JSON string' do
|
407
|
+
instance = @adult_parser.new({
|
408
|
+
"name" => "Bob Aman",
|
409
|
+
"age" => 29
|
410
|
+
})
|
411
|
+
instance.to_json.should == '{"name":"Bob Aman","age":29}'
|
412
|
+
end
|
413
|
+
end
|
414
|
+
|
415
|
+
describe AutoParse::Instance, 'with the positive schema' do
|
416
|
+
before do
|
417
|
+
@positive_uri = Addressable::URI.new(
|
418
|
+
:scheme => 'file',
|
419
|
+
:host => '',
|
420
|
+
:path => File.expand_path(File.join(spec_dir, './data/positive.json'))
|
421
|
+
)
|
422
|
+
@positive_schema_data =
|
423
|
+
JSON.parse(File.open(@positive_uri.path, 'r') { |f| f.read })
|
424
|
+
@positive_parser = AutoParse.generate(@positive_schema_data, @positive_uri)
|
425
|
+
end
|
426
|
+
|
427
|
+
it 'should not allow instantiation' do
|
428
|
+
(lambda do
|
429
|
+
instance = @positive_parser.new(-1000)
|
430
|
+
end).should raise_error(TypeError)
|
431
|
+
end
|
432
|
+
|
433
|
+
it 'should not allow instantiation, even for a valid positive integer' do
|
434
|
+
(lambda do
|
435
|
+
instance = @positive_parser.new(1000)
|
436
|
+
end).should raise_error(TypeError)
|
437
|
+
end
|
438
|
+
end
|
439
|
+
|
440
|
+
describe AutoParse::Instance, 'with the account schema' do
|
441
|
+
before do
|
442
|
+
@positive_uri = Addressable::URI.new(
|
443
|
+
:scheme => 'file',
|
444
|
+
:host => '',
|
445
|
+
:path => File.expand_path(File.join(spec_dir, './data/positive.json'))
|
446
|
+
)
|
447
|
+
@positive_schema_data =
|
448
|
+
JSON.parse(File.open(@positive_uri.path, 'r') { |f| f.read })
|
449
|
+
@positive_parser = AutoParse.generate(@positive_schema_data, @positive_uri)
|
450
|
+
|
451
|
+
@account_uri = Addressable::URI.new(
|
452
|
+
:scheme => 'file',
|
453
|
+
:host => '',
|
454
|
+
:path => File.expand_path(File.join(spec_dir, './data/account.json'))
|
455
|
+
)
|
456
|
+
@account_schema_data =
|
457
|
+
JSON.parse(File.open(@account_uri.path, 'r') { |f| f.read })
|
458
|
+
@account_parser = AutoParse.generate(@account_schema_data, @account_uri)
|
459
|
+
end
|
460
|
+
|
461
|
+
it 'should accept a valid account input' do
|
462
|
+
instance = @account_parser.new({
|
463
|
+
"accountNumber" => "12345",
|
464
|
+
"balance" => 1000
|
465
|
+
})
|
466
|
+
instance.should be_valid
|
467
|
+
end
|
468
|
+
|
469
|
+
it 'should accept extra fields' do
|
470
|
+
instance = @account_parser.new({
|
471
|
+
"accountNumber" => "12345",
|
472
|
+
"balance" => 1000,
|
473
|
+
"extra" => "bonus!"
|
474
|
+
})
|
475
|
+
instance.should be_valid
|
476
|
+
end
|
477
|
+
|
478
|
+
it 'should validate an account with a zero balance' do
|
479
|
+
instance = @account_parser.new({
|
480
|
+
"accountNumber" => "12345",
|
481
|
+
"balance" => 0
|
482
|
+
})
|
483
|
+
instance.should be_valid
|
484
|
+
end
|
485
|
+
|
486
|
+
it 'should not validate a negative account balance' do
|
487
|
+
instance = @account_parser.new({
|
488
|
+
"accountNumber" => "12345",
|
489
|
+
"balance" => -1000
|
490
|
+
})
|
491
|
+
instance.should_not be_valid
|
492
|
+
end
|
493
|
+
|
494
|
+
it 'should not accept an invalid account input' do
|
495
|
+
instance = @account_parser.new({
|
496
|
+
"accountNumber" => "12345",
|
497
|
+
"balance" => "bogus"
|
498
|
+
})
|
499
|
+
instance.should_not be_valid
|
500
|
+
end
|
501
|
+
|
502
|
+
it 'should expose values via generated accessors' do
|
503
|
+
instance = @account_parser.new({
|
504
|
+
"accountNumber" => "12345",
|
505
|
+
"balance" => 1000
|
506
|
+
})
|
507
|
+
instance.account_number.should == "12345"
|
508
|
+
instance.balance.should == 1000
|
509
|
+
end
|
510
|
+
|
511
|
+
it 'should be coerceable to a Hash value' do
|
512
|
+
instance = @account_parser.new({
|
513
|
+
"accountNumber" => "12345",
|
514
|
+
"balance" => 1000
|
515
|
+
})
|
516
|
+
instance.to_hash.should == {
|
517
|
+
"accountNumber" => "12345",
|
518
|
+
"balance" => 1000
|
519
|
+
}
|
520
|
+
end
|
521
|
+
|
522
|
+
it 'should convert to a JSON string' do
|
523
|
+
instance = @account_parser.new({
|
524
|
+
"accountNumber" => "12345",
|
525
|
+
"balance" => 1000
|
526
|
+
})
|
527
|
+
instance.to_json.should == '{"accountNumber":"12345","balance":1000}'
|
528
|
+
end
|
529
|
+
end
|
530
|
+
|
531
|
+
describe AutoParse::Instance, 'with the card schema' do
|
532
|
+
before do
|
533
|
+
@address_uri = Addressable::URI.new(
|
534
|
+
:scheme => 'file',
|
535
|
+
:host => '',
|
536
|
+
:path => File.expand_path(File.join(spec_dir, './data/address.json'))
|
537
|
+
)
|
538
|
+
@address_schema_data =
|
539
|
+
JSON.parse(File.open(@address_uri.path, 'r') { |f| f.read })
|
540
|
+
@address_parser = AutoParse.generate(@address_schema_data, @address_uri)
|
541
|
+
|
542
|
+
@geo_uri = Addressable::URI.new(
|
543
|
+
:scheme => 'file',
|
544
|
+
:host => '',
|
545
|
+
:path => File.expand_path(File.join(spec_dir, './data/geo.json'))
|
546
|
+
)
|
547
|
+
@geo_schema_data =
|
548
|
+
JSON.parse(File.open(@geo_uri.path, 'r') { |f| f.read })
|
549
|
+
@geo_parser = AutoParse.generate(@geo_schema_data, @geo_uri)
|
550
|
+
|
551
|
+
@card_uri = Addressable::URI.new(
|
552
|
+
:scheme => 'file',
|
553
|
+
:host => '',
|
554
|
+
:path => File.expand_path(File.join(spec_dir, './data/card.json'))
|
555
|
+
)
|
556
|
+
@card_schema_data =
|
557
|
+
JSON.parse(File.open(@card_uri.path, 'r') { |f| f.read })
|
558
|
+
@card_parser = AutoParse.generate(@card_schema_data, @card_uri)
|
559
|
+
end
|
560
|
+
|
561
|
+
it 'should accept a valid card input' do
|
562
|
+
instance = @card_parser.new({
|
563
|
+
"givenName" => "Robert",
|
564
|
+
"familyName" => "Aman"
|
565
|
+
})
|
566
|
+
instance.should be_valid
|
567
|
+
end
|
568
|
+
|
569
|
+
it 'should accept extra fields' do
|
570
|
+
instance = @card_parser.new({
|
571
|
+
"givenName" => "Robert",
|
572
|
+
"familyName" => "Aman",
|
573
|
+
"extra" => "bonus!"
|
574
|
+
})
|
575
|
+
instance.should be_valid
|
576
|
+
end
|
577
|
+
|
578
|
+
it 'should accept a more complete card input' do
|
579
|
+
instance = @card_parser.new({
|
580
|
+
"givenName" => "Robert",
|
581
|
+
"familyName" => "Aman",
|
582
|
+
"additionalName" => ["Danger"],
|
583
|
+
"nickname" => "Bob",
|
584
|
+
"url" => "https://plus.google.com/116452824309856782163",
|
585
|
+
"email" => {
|
586
|
+
"type" => "work",
|
587
|
+
"value" => "bobaman@google.com"
|
588
|
+
},
|
589
|
+
"tel" => {
|
590
|
+
"type" => "fake",
|
591
|
+
"value" => "867-5309"
|
592
|
+
},
|
593
|
+
"tz" => "+03:00",
|
594
|
+
"logo" =>
|
595
|
+
"https://secure.gravatar.com/avatar/56ee28134dd0776825445e3551979b14",
|
596
|
+
"org" => {
|
597
|
+
"organizationName" => "Google, Inc.",
|
598
|
+
"organizationUnit" => "Developer Relations"
|
599
|
+
}
|
600
|
+
})
|
601
|
+
instance.should be_valid
|
602
|
+
end
|
603
|
+
|
604
|
+
it 'should accept a card input with an externally referenced schema' do
|
605
|
+
instance = @card_parser.new({
|
606
|
+
"givenName" => "Robert",
|
607
|
+
"familyName" => "Aman",
|
608
|
+
"adr" => {
|
609
|
+
"locality" => "Lavington",
|
610
|
+
"region" => "Nairobi",
|
611
|
+
"country-name" => "Kenya"
|
612
|
+
},
|
613
|
+
"geo" => {
|
614
|
+
"latitude" => -1.290034,
|
615
|
+
"longitude" => 36.771584
|
616
|
+
}
|
617
|
+
})
|
618
|
+
instance.adr.should be_valid
|
619
|
+
instance.geo.should be_valid
|
620
|
+
instance.should be_valid
|
621
|
+
end
|
622
|
+
|
623
|
+
it 'should not validate a card input with invalid array values' do
|
624
|
+
instance = @card_parser.new({
|
625
|
+
"givenName" => "Robert",
|
626
|
+
"familyName" => "Aman",
|
627
|
+
"additionalName" => [3.14159]
|
628
|
+
})
|
629
|
+
instance.should_not be_valid
|
630
|
+
end
|
631
|
+
|
632
|
+
it 'should not validate a card input when external schema is invalid' do
|
633
|
+
instance = @card_parser.new({
|
634
|
+
"givenName" => "Robert",
|
635
|
+
"familyName" => "Aman",
|
636
|
+
"adr" => {
|
637
|
+
"extended-address" => "Apt 2.71828",
|
638
|
+
"locality" => "Lavington",
|
639
|
+
"region" => "Nairobi",
|
640
|
+
"country-name" => "Kenya"
|
641
|
+
},
|
642
|
+
"geo" => {
|
643
|
+
"latitude" => -1.290034,
|
644
|
+
"longitude" => 36.771584
|
645
|
+
}
|
646
|
+
})
|
647
|
+
instance.adr.should_not be_valid
|
648
|
+
instance.should_not be_valid
|
649
|
+
instance = @card_parser.new({
|
650
|
+
"givenName" => "Robert",
|
651
|
+
"familyName" => "Aman",
|
652
|
+
"adr" => {
|
653
|
+
"locality" => "Lavington",
|
654
|
+
"region" => "Nairobi",
|
655
|
+
"country-name" => "Kenya"
|
656
|
+
},
|
657
|
+
"geo" => {
|
658
|
+
"latitude" => "not",
|
659
|
+
"longitude" => "valid"
|
660
|
+
}
|
661
|
+
})
|
662
|
+
instance.geo.should_not be_valid
|
663
|
+
instance.should_not be_valid
|
664
|
+
end
|
665
|
+
|
666
|
+
it 'should expose values via generated accessors' do
|
667
|
+
instance = @card_parser.new({
|
668
|
+
"givenName" => "Robert",
|
669
|
+
"familyName" => "Aman",
|
670
|
+
"additionalName" => ["Danger"],
|
671
|
+
"nickname" => "Bob",
|
672
|
+
"url" => "https://plus.google.com/116452824309856782163",
|
673
|
+
"email" => {
|
674
|
+
"type" => "work",
|
675
|
+
"value" => "bobaman@google.com"
|
676
|
+
},
|
677
|
+
"tel" => {
|
678
|
+
"type" => "fake",
|
679
|
+
"value" => "867-5309"
|
680
|
+
},
|
681
|
+
"tz" => "+03:00",
|
682
|
+
"logo" =>
|
683
|
+
"https://secure.gravatar.com/avatar/56ee28134dd0776825445e3551979b14",
|
684
|
+
"org" => {
|
685
|
+
"organizationName" => "Google, Inc.",
|
686
|
+
"organizationUnit" => "Developer Relations"
|
687
|
+
}
|
688
|
+
})
|
689
|
+
instance.given_name.should == "Robert"
|
690
|
+
instance.family_name.should == "Aman"
|
691
|
+
instance.additional_name.should == ["Danger"]
|
692
|
+
instance.nickname.should == "Bob"
|
693
|
+
instance.url.should be_kind_of(Addressable::URI)
|
694
|
+
instance.url.should === "https://plus.google.com/116452824309856782163"
|
695
|
+
instance.email.type.should == "work"
|
696
|
+
instance.email.value.should == "bobaman@google.com"
|
697
|
+
instance.tel.type.should == "fake"
|
698
|
+
instance.tel.value.should == "867-5309"
|
699
|
+
instance.tz.should == "+03:00"
|
700
|
+
instance.logo.should ==
|
701
|
+
"https://secure.gravatar.com/avatar/56ee28134dd0776825445e3551979b14"
|
702
|
+
instance.org.organization_name.should == "Google, Inc."
|
703
|
+
instance.org.organization_unit.should == "Developer Relations"
|
704
|
+
end
|
705
|
+
|
706
|
+
it 'should be coerceable to a Hash value' do
|
707
|
+
instance = @card_parser.new({
|
708
|
+
"givenName" => "Robert",
|
709
|
+
"familyName" => "Aman",
|
710
|
+
"additionalName" => ["Danger"],
|
711
|
+
"nickname" => "Bob",
|
712
|
+
"url" => "https://plus.google.com/116452824309856782163",
|
713
|
+
"email" => {
|
714
|
+
"type" => "work",
|
715
|
+
"value" => "bobaman@google.com"
|
716
|
+
},
|
717
|
+
"tel" => {
|
718
|
+
"type" => "fake",
|
719
|
+
"value" => "867-5309"
|
720
|
+
},
|
721
|
+
"tz" => "+03:00",
|
722
|
+
"logo" =>
|
723
|
+
"https://secure.gravatar.com/avatar/56ee28134dd0776825445e3551979b14",
|
724
|
+
"org" => {
|
725
|
+
"organizationName" => "Google, Inc.",
|
726
|
+
"organizationUnit" => "Developer Relations"
|
727
|
+
}
|
728
|
+
})
|
729
|
+
instance.to_hash.should == {
|
730
|
+
"givenName" => "Robert",
|
731
|
+
"familyName" => "Aman",
|
732
|
+
"additionalName" => ["Danger"],
|
733
|
+
"nickname" => "Bob",
|
734
|
+
"url" => "https://plus.google.com/116452824309856782163",
|
735
|
+
"email" => {
|
736
|
+
"type" => "work",
|
737
|
+
"value" => "bobaman@google.com"
|
738
|
+
},
|
739
|
+
"tel" => {
|
740
|
+
"type" => "fake",
|
741
|
+
"value" => "867-5309"
|
742
|
+
},
|
743
|
+
"tz" => "+03:00",
|
744
|
+
"logo" =>
|
745
|
+
"https://secure.gravatar.com/avatar/56ee28134dd0776825445e3551979b14",
|
746
|
+
"org" => {
|
747
|
+
"organizationName" => "Google, Inc.",
|
748
|
+
"organizationUnit" => "Developer Relations"
|
749
|
+
}
|
750
|
+
}
|
751
|
+
end
|
752
|
+
|
753
|
+
it 'should convert to a JSON string' do
|
754
|
+
instance = @card_parser.new({
|
755
|
+
"givenName" => "Robert",
|
756
|
+
"familyName" => "Aman"
|
757
|
+
})
|
758
|
+
instance.to_json.should == '{"givenName":"Robert","familyName":"Aman"}'
|
759
|
+
end
|
760
|
+
end
|
761
|
+
|
762
|
+
describe AutoParse::Instance, 'with the calendar schema' do
|
763
|
+
before do
|
764
|
+
@geo_uri = Addressable::URI.new(
|
765
|
+
:scheme => 'file',
|
766
|
+
:host => '',
|
767
|
+
:path => File.expand_path(File.join(spec_dir, './data/geo.json'))
|
768
|
+
)
|
769
|
+
@geo_schema_data =
|
770
|
+
JSON.parse(File.open(@geo_uri.path, 'r') { |f| f.read })
|
771
|
+
@geo_parser = AutoParse.generate(@geo_schema_data, @geo_uri)
|
772
|
+
|
773
|
+
@calendar_uri = Addressable::URI.new(
|
774
|
+
:scheme => 'file',
|
775
|
+
:host => '',
|
776
|
+
:path => File.expand_path(File.join(spec_dir, './data/calendar.json'))
|
777
|
+
)
|
778
|
+
@calendar_schema_data =
|
779
|
+
JSON.parse(File.open(@calendar_uri.path, 'r') { |f| f.read })
|
780
|
+
@calendar_parser = AutoParse.generate(@calendar_schema_data, @calendar_uri)
|
781
|
+
end
|
782
|
+
|
783
|
+
it 'should accept a valid calendar input' do
|
784
|
+
instance = @calendar_parser.new({
|
785
|
+
"dtstart" => "1592-03-14T00:00:00Z",
|
786
|
+
"dtend" => "1592-03-14T23:59:59Z",
|
787
|
+
"summary" => "Pi Day",
|
788
|
+
"location" => "Googleplex",
|
789
|
+
"url" => "http://www.piday.org/",
|
790
|
+
"rrule" => "FREQ=YEARLY"
|
791
|
+
})
|
792
|
+
instance.should be_valid
|
793
|
+
end
|
794
|
+
|
795
|
+
it 'should accept extra fields' do
|
796
|
+
instance = @calendar_parser.new({
|
797
|
+
"dtstart" => "1592-03-14T00:00:00Z",
|
798
|
+
"dtend" => "1592-03-14T23:59:59Z",
|
799
|
+
"summary" => "Pi Day",
|
800
|
+
"location" => "Googleplex",
|
801
|
+
"url" => "http://www.piday.org/",
|
802
|
+
"rrule" => "FREQ=YEARLY",
|
803
|
+
"extra" => "bonus!"
|
804
|
+
})
|
805
|
+
instance.should be_valid
|
806
|
+
end
|
807
|
+
|
808
|
+
it 'should accept a calendar input with an externally referenced schema' do
|
809
|
+
instance = @calendar_parser.new({
|
810
|
+
"dtstart" => "1592-03-14T00:00:00Z",
|
811
|
+
"dtend" => "1592-03-14T23:59:59Z",
|
812
|
+
"summary" => "Pi Day",
|
813
|
+
"location" => "Googleplex",
|
814
|
+
"url" => "http://www.piday.org/",
|
815
|
+
"rrule" => "FREQ=YEARLY",
|
816
|
+
"geo" => {
|
817
|
+
"latitude" => 37.422,
|
818
|
+
"longitude" => -122.084
|
819
|
+
}
|
820
|
+
})
|
821
|
+
instance.geo.should be_valid
|
822
|
+
instance.should be_valid
|
823
|
+
end
|
824
|
+
|
825
|
+
it 'should not validate a calendar input when external schema is invalid' do
|
826
|
+
instance = @calendar_parser.new({
|
827
|
+
"dtstart" => "1592-03-14T00:00:00Z",
|
828
|
+
"dtend" => "1592-03-14T23:59:59Z",
|
829
|
+
"summary" => "Pi Day",
|
830
|
+
"location" => "Googleplex",
|
831
|
+
"url" => "http://www.piday.org/",
|
832
|
+
"rrule" => "FREQ=YEARLY",
|
833
|
+
"geo" => {
|
834
|
+
"latitude" => "not",
|
835
|
+
"longitude" => "valid"
|
836
|
+
}
|
837
|
+
})
|
838
|
+
instance.geo.should_not be_valid
|
839
|
+
instance.should_not be_valid
|
840
|
+
end
|
841
|
+
|
842
|
+
it 'should expose values via generated accessors' do
|
843
|
+
instance = @calendar_parser.new({
|
844
|
+
"dtstart" => "1592-03-14T00:00:00Z",
|
845
|
+
"dtend" => "1592-03-14T23:59:59Z",
|
846
|
+
"summary" => "Pi Day",
|
847
|
+
"location" => "Googleplex",
|
848
|
+
"url" => "http://www.piday.org/",
|
849
|
+
"rrule" => "FREQ=YEARLY",
|
850
|
+
"geo" => {
|
851
|
+
"latitude" => 37.422,
|
852
|
+
"longitude" => -122.084
|
853
|
+
}
|
854
|
+
})
|
855
|
+
instance.dtstart.should == Time.utc(1592, 3, 14)
|
856
|
+
instance.dtend.should == Time.utc(1592, 3, 14, 23, 59, 59)
|
857
|
+
instance.summary.should == "Pi Day"
|
858
|
+
instance.location.should == "Googleplex"
|
859
|
+
instance.url.should == Addressable::URI.parse("http://www.piday.org/")
|
860
|
+
instance.rrule.should == "FREQ=YEARLY"
|
861
|
+
instance.geo.latitude.should == 37.422
|
862
|
+
instance.geo.longitude.should == -122.084
|
863
|
+
end
|
864
|
+
|
865
|
+
it 'should be coerceable to a Hash value' do
|
866
|
+
instance = @calendar_parser.new({
|
867
|
+
"dtstart" => "1592-03-14T00:00:00Z",
|
868
|
+
"dtend" => "1592-03-14T23:59:59Z",
|
869
|
+
"summary" => "Pi Day",
|
870
|
+
"location" => "Googleplex",
|
871
|
+
"url" => "http://www.piday.org/",
|
872
|
+
"rrule" => "FREQ=YEARLY",
|
873
|
+
"geo" => {
|
874
|
+
"latitude" => 37.422,
|
875
|
+
"longitude" => -122.084
|
876
|
+
}
|
877
|
+
})
|
878
|
+
instance.to_hash.should == {
|
879
|
+
"dtstart" => "1592-03-14T00:00:00Z",
|
880
|
+
"dtend" => "1592-03-14T23:59:59Z",
|
881
|
+
"summary" => "Pi Day",
|
882
|
+
"location" => "Googleplex",
|
883
|
+
"url" => "http://www.piday.org/",
|
884
|
+
"rrule" => "FREQ=YEARLY",
|
885
|
+
"geo" => {
|
886
|
+
"latitude" => 37.422,
|
887
|
+
"longitude" => -122.084
|
888
|
+
}
|
889
|
+
}
|
890
|
+
end
|
891
|
+
|
892
|
+
it 'should convert to a JSON string' do
|
893
|
+
instance = @calendar_parser.new({
|
894
|
+
"dtstart" => "1592-03-14T00:00:00Z",
|
895
|
+
"dtend" => "1592-03-14T23:59:59Z",
|
896
|
+
"summary" => "Pi Day"
|
897
|
+
})
|
898
|
+
instance.to_json.should == (
|
899
|
+
'{"dtend":"1592-03-14T23:59:59Z",' +
|
900
|
+
'"dtstart":"1592-03-14T00:00:00Z",'+
|
901
|
+
'"summary":"Pi Day"}'
|
902
|
+
)
|
903
|
+
end
|
904
|
+
end
|