autoparse 0.3.1 → 0.3.2
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.md +6 -0
- data/Gemfile +17 -0
- data/Gemfile.lock +32 -0
- data/lib/autoparse.rb +7 -20
- data/lib/autoparse/instance.rb +26 -23
- data/lib/autoparse/version.rb +1 -1
- data/spec/autoparse/instance_spec.rb +147 -10
- data/spec/data/booleans.json +25 -0
- data/spec/data/file.json +173 -0
- data/spec/data/filelist.json +35 -0
- data/spec/data/parentref.json +28 -0
- data/spec/spec_helper.rb +23 -0
- data/tasks/gem.rake +5 -6
- data/tasks/git.rake +6 -1
- metadata +17 -69
- data/spec/data/chaos.json +0 -22
data/CHANGELOG.md
CHANGED
data/Gemfile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
source :rubygems
|
2
|
+
|
3
|
+
gem 'addressable', '>= 2.3.1'
|
4
|
+
gem 'multi_json', '>= 1.0.0'
|
5
|
+
gem 'extlib', '>= 0.9.15'
|
6
|
+
|
7
|
+
group :development do
|
8
|
+
gem 'launchy', '>= 2.1.1'
|
9
|
+
gem 'yard'
|
10
|
+
gem 'redcarpet'
|
11
|
+
end
|
12
|
+
|
13
|
+
group :test, :development do
|
14
|
+
gem 'rake', '>= 0.9.0'
|
15
|
+
gem 'rspec', '>= 2.11.0'
|
16
|
+
gem 'rcov', '>= 0.9.9', :platform => :mri_18
|
17
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
addressable (2.3.1)
|
5
|
+
diff-lcs (1.1.3)
|
6
|
+
extlib (0.9.15)
|
7
|
+
multi_json (1.3.6)
|
8
|
+
rake (0.9.2.2)
|
9
|
+
rcov (1.0.0)
|
10
|
+
redcarpet (2.1.1)
|
11
|
+
rspec (2.11.0)
|
12
|
+
rspec-core (~> 2.11.0)
|
13
|
+
rspec-expectations (~> 2.11.0)
|
14
|
+
rspec-mocks (~> 2.11.0)
|
15
|
+
rspec-core (2.11.1)
|
16
|
+
rspec-expectations (2.11.1)
|
17
|
+
diff-lcs (~> 1.1.3)
|
18
|
+
rspec-mocks (2.11.1)
|
19
|
+
yard (0.8.2.1)
|
20
|
+
|
21
|
+
PLATFORMS
|
22
|
+
ruby
|
23
|
+
|
24
|
+
DEPENDENCIES
|
25
|
+
addressable (>= 2.3.1)
|
26
|
+
extlib (>= 0.9.15)
|
27
|
+
multi_json (>= 1.0.0)
|
28
|
+
rake (>= 0.9.0)
|
29
|
+
rcov (>= 0.9.9)
|
30
|
+
redcarpet
|
31
|
+
rspec (>= 2.11.0)
|
32
|
+
yard
|
data/lib/autoparse.rb
CHANGED
@@ -231,8 +231,7 @@ module AutoParse
|
|
231
231
|
elsif value.kind_of?(Symbol)
|
232
232
|
value.to_s
|
233
233
|
else
|
234
|
-
raise TypeError,
|
235
|
-
"Expected String or Symbol, got #{value.class}."
|
234
|
+
raise TypeError, "Expected String or Symbol, got #{value.class}."
|
236
235
|
end
|
237
236
|
end
|
238
237
|
|
@@ -242,11 +241,10 @@ module AutoParse
|
|
242
241
|
true
|
243
242
|
when 'false', 'no', 'n', 'off', '0'
|
244
243
|
false
|
245
|
-
when 'nil', 'null', 'undefined'
|
244
|
+
when 'nil', 'null', 'undefined', ''
|
246
245
|
nil
|
247
246
|
else
|
248
|
-
raise TypeError,
|
249
|
-
"Expected boolean, got #{value.class}."
|
247
|
+
raise TypeError, "Expected boolean, got #{value.class}."
|
250
248
|
end
|
251
249
|
end
|
252
250
|
|
@@ -256,7 +254,7 @@ module AutoParse
|
|
256
254
|
true
|
257
255
|
when 'false', 'no', 'n', 'off', '0'
|
258
256
|
false
|
259
|
-
when 'nil', 'null', 'undefined'
|
257
|
+
when 'nil', 'null', 'undefined', ''
|
260
258
|
nil
|
261
259
|
else
|
262
260
|
raise TypeError, "Expected boolean, got #{value.class}."
|
@@ -302,29 +300,18 @@ module AutoParse
|
|
302
300
|
else
|
303
301
|
(value || []).to_ary.dup
|
304
302
|
end)
|
305
|
-
|
306
|
-
items_schema = AutoParse.generate(items_data, :parent => schema_class)
|
307
|
-
if items_schema.data['$ref']
|
308
|
-
# Dereference the schema if necessary.
|
309
|
-
items_schema = items_schema.dereference
|
310
|
-
end
|
303
|
+
items_schema = schema_class.property('items')
|
311
304
|
value.map! do |item|
|
312
305
|
AutoParse.import(item, items_schema)
|
313
306
|
end
|
314
|
-
value
|
315
|
-
end
|
307
|
+
value end
|
316
308
|
|
317
309
|
def self.export_array(value, schema_class)
|
318
310
|
if value == nil
|
319
311
|
value
|
320
312
|
elsif value.respond_to?(:to_ary)
|
321
313
|
value = value.to_ary.dup
|
322
|
-
|
323
|
-
items_schema = AutoParse.generate(items_data, :parent => schema_class)
|
324
|
-
if items_schema.data['$ref']
|
325
|
-
# Dereference the schema if necessary.
|
326
|
-
items_schema = items_schema.dereference
|
327
|
-
end
|
314
|
+
items_schema = schema_class.property('items')
|
328
315
|
value.map! do |item|
|
329
316
|
AutoParse.export(item, items_schema)
|
330
317
|
end
|
data/lib/autoparse/instance.rb
CHANGED
@@ -65,6 +65,25 @@ module AutoParse
|
|
65
65
|
)
|
66
66
|
end
|
67
67
|
|
68
|
+
def self.property(property_name)
|
69
|
+
property_key = self.keys[property_name] || property_name
|
70
|
+
schema_class = self.properties[property_key]
|
71
|
+
if !schema_class
|
72
|
+
if self.data[property_name]
|
73
|
+
schema_class = AutoParse.generate(self.data[property_name], :parent => self)
|
74
|
+
else
|
75
|
+
schema_class = self.additional_properties_schema
|
76
|
+
end
|
77
|
+
end
|
78
|
+
if schema_class.data['$ref']
|
79
|
+
# Dereference the schema if necessary.
|
80
|
+
schema_class = schema_class.dereference
|
81
|
+
# Avoid this dereference in the future.
|
82
|
+
self.properties[property_key] = schema_class
|
83
|
+
end
|
84
|
+
return schema_class
|
85
|
+
end
|
86
|
+
|
68
87
|
def self.keys
|
69
88
|
return @keys ||= (
|
70
89
|
if self.superclass.ancestors.include?(::AutoParse::Instance)
|
@@ -324,41 +343,25 @@ module AutoParse
|
|
324
343
|
|
325
344
|
def __get__(property_name)
|
326
345
|
property_key = self.class.keys[property_name] || property_name
|
327
|
-
|
328
|
-
schema_class = self.class.properties[property_key]
|
329
|
-
schema_class = self.class.additional_properties_schema if !schema_class
|
346
|
+
schema_class = self.class.property(property_name)
|
330
347
|
if !schema_class
|
331
348
|
@data[property_key]
|
332
349
|
else
|
333
|
-
if
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
self.class.properties[property_key] = schema_class
|
350
|
+
if @data.has_key?(property_key)
|
351
|
+
value = @data[property_key]
|
352
|
+
else
|
353
|
+
value = schema_class.data['default']
|
338
354
|
end
|
339
|
-
|
340
|
-
value = @data[property_key] || schema_class.data['default']
|
341
|
-
|
342
355
|
AutoParse.import(value, schema_class)
|
343
|
-
end
|
344
|
-
end
|
356
|
+
end end
|
345
357
|
protected :__get__
|
346
358
|
|
347
359
|
def __set__(property_name, value)
|
348
360
|
property_key = self.class.keys[property_name] || property_name
|
349
|
-
|
350
|
-
schema_class = self.class.properties[property_key]
|
351
|
-
schema_class = self.class.additional_properties_schema if !schema_class
|
361
|
+
schema_class = self.class.property(property_name)
|
352
362
|
if !schema_class
|
353
363
|
@data[property_key] = value
|
354
364
|
else
|
355
|
-
if schema_class.data['$ref']
|
356
|
-
# Dereference the schema if necessary.
|
357
|
-
schema_class = schema_class.dereference
|
358
|
-
# Avoid this dereference in the future.
|
359
|
-
self.class.properties[property_key] = schema_class
|
360
|
-
end
|
361
|
-
|
362
365
|
@data[property_key] = AutoParse.export(value, schema_class)
|
363
366
|
end
|
364
367
|
end
|
data/lib/autoparse/version.rb
CHANGED
@@ -22,6 +22,7 @@ require 'autoparse'
|
|
22
22
|
require 'addressable/uri'
|
23
23
|
|
24
24
|
describe AutoParse::Instance, 'with an empty schema' do
|
25
|
+
include JSONMatchers
|
25
26
|
before do
|
26
27
|
@parser = AutoParse::EMPTY_SCHEMA
|
27
28
|
end
|
@@ -65,11 +66,12 @@ describe AutoParse::Instance, 'with an empty schema' do
|
|
65
66
|
|
66
67
|
it 'should convert to a JSON string' do
|
67
68
|
instance = @parser.new({"be" => "brief"})
|
68
|
-
instance.to_json.should
|
69
|
+
instance.to_json.should be_json '{"be":"brief"}'
|
69
70
|
end
|
70
71
|
end
|
71
72
|
|
72
73
|
describe AutoParse::Instance, 'with the geo schema' do
|
74
|
+
include JSONMatchers
|
73
75
|
before do
|
74
76
|
@uri = Addressable::URI.new(
|
75
77
|
:scheme => 'file',
|
@@ -144,11 +146,12 @@ describe AutoParse::Instance, 'with the geo schema' do
|
|
144
146
|
"latitude" => 37.422,
|
145
147
|
"longitude" => -122.084
|
146
148
|
})
|
147
|
-
instance.to_json.should
|
149
|
+
instance.to_json.should be_json '{"latitude":37.422,"longitude":-122.084}'
|
148
150
|
end
|
149
151
|
end
|
150
152
|
|
151
153
|
describe AutoParse::Instance, 'with the address schema' do
|
154
|
+
include JSONMatchers
|
152
155
|
before do
|
153
156
|
@uri = Addressable::URI.new(
|
154
157
|
:scheme => 'file',
|
@@ -264,6 +267,7 @@ describe AutoParse::Instance, 'with the address schema' do
|
|
264
267
|
end
|
265
268
|
|
266
269
|
describe AutoParse::Instance, 'with the person schema' do
|
270
|
+
include JSONMatchers
|
267
271
|
before do
|
268
272
|
@uri = Addressable::URI.new(
|
269
273
|
:scheme => 'file',
|
@@ -362,11 +366,12 @@ describe AutoParse::Instance, 'with the person schema' do
|
|
362
366
|
"name" => "Bob Aman",
|
363
367
|
"age" => 29
|
364
368
|
})
|
365
|
-
instance.to_json.should
|
369
|
+
instance.to_json.should be_json '{"name":"Bob Aman","age":29}'
|
366
370
|
end
|
367
371
|
end
|
368
372
|
|
369
373
|
describe AutoParse::Instance, 'with the adult schema' do
|
374
|
+
include JSONMatchers
|
370
375
|
before do
|
371
376
|
@person_uri = Addressable::URI.new(
|
372
377
|
:scheme => 'file',
|
@@ -478,11 +483,12 @@ describe AutoParse::Instance, 'with the adult schema' do
|
|
478
483
|
"name" => "Bob Aman",
|
479
484
|
"age" => 29
|
480
485
|
})
|
481
|
-
instance.to_json.should
|
486
|
+
instance.to_json.should be_json '{"name":"Bob Aman","age":29}'
|
482
487
|
end
|
483
488
|
end
|
484
489
|
|
485
490
|
describe AutoParse::Instance, 'with the user list schema' do
|
491
|
+
include JSONMatchers
|
486
492
|
before do
|
487
493
|
@person_uri = Addressable::URI.new(
|
488
494
|
:scheme => 'file',
|
@@ -654,13 +660,14 @@ describe AutoParse::Instance, 'with the user list schema' do
|
|
654
660
|
}
|
655
661
|
}
|
656
662
|
})
|
657
|
-
instance.to_json.should
|
663
|
+
instance.to_json.should be_json (
|
658
664
|
'{"users":{"bobaman@google.com":{"name":"Bob Aman","age":29}}}'
|
659
665
|
)
|
660
666
|
end
|
661
667
|
end
|
662
668
|
|
663
669
|
describe AutoParse::Instance, 'with the positive schema' do
|
670
|
+
include JSONMatchers
|
664
671
|
before do
|
665
672
|
@positive_uri = Addressable::URI.new(
|
666
673
|
:scheme => 'file',
|
@@ -692,6 +699,7 @@ describe AutoParse::Instance, 'with the positive schema' do
|
|
692
699
|
end
|
693
700
|
|
694
701
|
describe AutoParse::Instance, 'with the account schema' do
|
702
|
+
include JSONMatchers
|
695
703
|
before do
|
696
704
|
@positive_uri = Addressable::URI.new(
|
697
705
|
:scheme => 'file',
|
@@ -797,11 +805,12 @@ describe AutoParse::Instance, 'with the account schema' do
|
|
797
805
|
"accountNumber" => "12345",
|
798
806
|
"balance" => 1000
|
799
807
|
})
|
800
|
-
instance.to_json.should
|
808
|
+
instance.to_json.should be_json '{"accountNumber":"12345","balance":1000}'
|
801
809
|
end
|
802
810
|
end
|
803
811
|
|
804
812
|
describe AutoParse::Instance, 'with the card schema' do
|
813
|
+
include JSONMatchers
|
805
814
|
before do
|
806
815
|
@address_uri = Addressable::URI.new(
|
807
816
|
:scheme => 'file',
|
@@ -1130,11 +1139,12 @@ describe AutoParse::Instance, 'with the card schema' do
|
|
1130
1139
|
"givenName" => "Robert",
|
1131
1140
|
"familyName" => "Aman"
|
1132
1141
|
})
|
1133
|
-
instance.to_json.should
|
1142
|
+
instance.to_json.should be_json '{"givenName":"Robert","familyName":"Aman"}'
|
1134
1143
|
end
|
1135
1144
|
end
|
1136
1145
|
|
1137
1146
|
describe AutoParse::Instance, 'with the calendar schema' do
|
1147
|
+
include JSONMatchers
|
1138
1148
|
before do
|
1139
1149
|
@geo_uri = Addressable::URI.new(
|
1140
1150
|
:scheme => 'file',
|
@@ -1303,11 +1313,11 @@ describe AutoParse::Instance, 'with the calendar schema' do
|
|
1303
1313
|
|
1304
1314
|
it 'should convert to a JSON string' do
|
1305
1315
|
instance = @calendar_parser.new({
|
1306
|
-
"dtstart" => "1592-03-14T00:00:00Z",
|
1307
1316
|
"dtend" => "1592-03-14T23:59:59Z",
|
1317
|
+
"dtstart" => "1592-03-14T00:00:00Z",
|
1308
1318
|
"summary" => "Pi Day"
|
1309
1319
|
})
|
1310
|
-
instance.to_json.should
|
1320
|
+
instance.to_json.should be_json (
|
1311
1321
|
'{"dtend":"1592-03-14T23:59:59Z",' +
|
1312
1322
|
'"dtstart":"1592-03-14T00:00:00Z",'+
|
1313
1323
|
'"summary":"Pi Day"}'
|
@@ -1316,6 +1326,7 @@ describe AutoParse::Instance, 'with the calendar schema' do
|
|
1316
1326
|
end
|
1317
1327
|
|
1318
1328
|
describe AutoParse::Instance, 'with the node schema' do
|
1329
|
+
include JSONMatchers
|
1319
1330
|
before do
|
1320
1331
|
@uri = Addressable::URI.new(
|
1321
1332
|
:scheme => 'file',
|
@@ -1446,10 +1457,136 @@ describe AutoParse::Instance, 'with the node schema' do
|
|
1446
1457
|
|
1447
1458
|
it 'should convert to a JSON string' do
|
1448
1459
|
instance = @parser.new({
|
1460
|
+
"left" => nil,
|
1449
1461
|
"value" => 42,
|
1462
|
+
"right" => nil
|
1463
|
+
})
|
1464
|
+
instance.to_json.should be_json '{"left":null,"value":42,"right":null}'
|
1465
|
+
end
|
1466
|
+
end
|
1467
|
+
|
1468
|
+
describe AutoParse::Instance, 'with the booleans schema' do
|
1469
|
+
include JSONMatchers
|
1470
|
+
before do
|
1471
|
+
@uri = Addressable::URI.new(
|
1472
|
+
:scheme => 'file',
|
1473
|
+
:host => '',
|
1474
|
+
:path => File.expand_path(File.join(spec_dir, './data/booleans.json'))
|
1475
|
+
)
|
1476
|
+
@schema_data = JSON.parse(File.open(@uri.path, 'r') { |f| f.read })
|
1477
|
+
@parser = AutoParse.generate(@schema_data, :uri => @uri)
|
1478
|
+
end
|
1479
|
+
|
1480
|
+
it 'should have the correct URI' do
|
1481
|
+
@parser.uri.should === @uri
|
1482
|
+
end
|
1483
|
+
|
1484
|
+
it 'should accept a valid booleans input' do
|
1485
|
+
instance = @parser.new({
|
1486
|
+
"guaranteed" => false,
|
1487
|
+
"truthy" => true,
|
1488
|
+
"accurate" => false
|
1489
|
+
})
|
1490
|
+
instance.should be_valid
|
1491
|
+
end
|
1492
|
+
|
1493
|
+
it 'should expose values via generated accessors' do
|
1494
|
+
instance = @parser.new({
|
1495
|
+
"guaranteed" => false,
|
1496
|
+
"truthy" => true,
|
1497
|
+
"accurate" => false
|
1498
|
+
})
|
1499
|
+
instance.truthy.should == true
|
1500
|
+
instance.untrue.should == false
|
1501
|
+
instance.accurate.should == false
|
1502
|
+
instance.maybe.should == nil
|
1503
|
+
instance.guaranteed.should == false
|
1504
|
+
end
|
1505
|
+
|
1506
|
+
it 'should alter output structure via generated mutators' do
|
1507
|
+
instance = @parser.new
|
1508
|
+
instance.truthy = true
|
1509
|
+
instance.untrue = false
|
1510
|
+
instance.accurate = false
|
1511
|
+
instance.guaranteed = false
|
1512
|
+
instance.to_hash.should == {
|
1513
|
+
"truthy" => true,
|
1514
|
+
"untrue" => false,
|
1515
|
+
"accurate" => false,
|
1516
|
+
"guaranteed" => false
|
1517
|
+
}
|
1518
|
+
end
|
1519
|
+
|
1520
|
+
it 'should be coerceable to a Hash value' do
|
1521
|
+
instance = @parser.new({
|
1522
|
+
"guaranteed" => false,
|
1523
|
+
"truthy" => true,
|
1524
|
+
"accurate" => false
|
1525
|
+
})
|
1526
|
+
instance.to_hash.should == {
|
1527
|
+
"guaranteed" => false,
|
1528
|
+
"truthy" => true,
|
1529
|
+
"accurate" => false
|
1530
|
+
}
|
1531
|
+
end
|
1532
|
+
|
1533
|
+
it 'should convert to a JSON string' do
|
1534
|
+
instance = @parser.new({
|
1450
1535
|
"left" => nil,
|
1536
|
+
"value" => 42,
|
1451
1537
|
"right" => nil
|
1452
1538
|
})
|
1453
|
-
instance.to_json.should
|
1539
|
+
instance.to_json.should be_json '{"left":null,"value":42,"right":null}'
|
1540
|
+
end
|
1541
|
+
end
|
1542
|
+
|
1543
|
+
describe AutoParse::Instance, 'with the file schema' do
|
1544
|
+
def load_schema(file, uri)
|
1545
|
+
json = JSON.parse(File.read(file))
|
1546
|
+
return AutoParse.generate(json, :uri => Addressable::URI.parse(uri))
|
1547
|
+
end
|
1548
|
+
|
1549
|
+
before do
|
1550
|
+
@data = {
|
1551
|
+
"kind" => "drive#fileList",
|
1552
|
+
"items" => [
|
1553
|
+
{
|
1554
|
+
"kind" => "drive#file",
|
1555
|
+
"id" => "0Bz2X2-r-Ou9fYTJFLVFYZENzMjA",
|
1556
|
+
"editable" => "false",
|
1557
|
+
"parents" => [
|
1558
|
+
{
|
1559
|
+
"kind" => "drive#parentReference",
|
1560
|
+
"id" => "0AD2X2-r-Ou9fUk9PVA",
|
1561
|
+
"isRoot" => "true"
|
1562
|
+
}
|
1563
|
+
]
|
1564
|
+
}
|
1565
|
+
]
|
1566
|
+
}
|
1567
|
+
@filelist_parser = load_schema('spec/data/filelist.json', 'https://www.googleapis.com/drive/v2/#FileList')
|
1568
|
+
@file_parser = load_schema('spec/data/file.json', 'https://www.googleapis.com/drive/v2/#File')
|
1569
|
+
@parentref_parser = load_schema('spec/data/parentref.json', 'https://www.googleapis.com/drive/v2/#ParentReference')
|
1570
|
+
end
|
1571
|
+
|
1572
|
+
it 'should not redefine parent schemas' do
|
1573
|
+
file = @filelist_parser.new(@data)
|
1574
|
+
file.should be_an_instance_of @filelist_parser
|
1575
|
+
file.items.first.should be_an_instance_of @file_parser
|
1576
|
+
file.items.first.parents.first.should be_an_instance_of @parentref_parser
|
1577
|
+
|
1578
|
+
file = @filelist_parser.new(@data)
|
1579
|
+
file.should be_an_instance_of @filelist_parser
|
1580
|
+
file.items.first.should be_an_instance_of @file_parser
|
1581
|
+
file.items.first.parents.first.should be_an_instance_of @parentref_parser
|
1582
|
+
end
|
1583
|
+
|
1584
|
+
it 'should handle booleans correctly' do
|
1585
|
+
file = @filelist_parser.new(@data)
|
1586
|
+
file.should be_an_instance_of @filelist_parser
|
1587
|
+
file.items.first.should be_an_instance_of @file_parser
|
1588
|
+
file.items.first.editable.should == false
|
1589
|
+
file.items.first.parents.first.should be_an_instance_of @parentref_parser
|
1590
|
+
file.items.first.parents.first.is_root.should == true
|
1454
1591
|
end
|
1455
1592
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
{
|
2
|
+
"description":"A bunch of booleans",
|
3
|
+
"type":"object",
|
4
|
+
"properties": {
|
5
|
+
"truthy": {
|
6
|
+
"type": "boolean",
|
7
|
+
"default": null
|
8
|
+
},
|
9
|
+
"untrue": {
|
10
|
+
"type": "boolean",
|
11
|
+
"default": false
|
12
|
+
},
|
13
|
+
"accurate": {
|
14
|
+
"type": "boolean",
|
15
|
+
"default": true
|
16
|
+
},
|
17
|
+
"maybe": {
|
18
|
+
"type": "boolean"
|
19
|
+
},
|
20
|
+
"guaranteed": {
|
21
|
+
"type": "boolean",
|
22
|
+
"required": true
|
23
|
+
}
|
24
|
+
}
|
25
|
+
}
|
data/spec/data/file.json
ADDED
@@ -0,0 +1,173 @@
|
|
1
|
+
{
|
2
|
+
"id": "File",
|
3
|
+
"type": "object",
|
4
|
+
"description": "The metadata for a file.",
|
5
|
+
"properties": {
|
6
|
+
"alternateLink": {
|
7
|
+
"type": "string",
|
8
|
+
"description": "A link for opening the file in a browser."
|
9
|
+
},
|
10
|
+
"createdDate": {
|
11
|
+
"type": "string",
|
12
|
+
"description": "Create time for this file (formatted ISO8601 timestamp).",
|
13
|
+
"format": "date-time"
|
14
|
+
},
|
15
|
+
"description": {
|
16
|
+
"type": "string",
|
17
|
+
"description": "A short description of the file."
|
18
|
+
},
|
19
|
+
"downloadUrl": {
|
20
|
+
"type": "string",
|
21
|
+
"description": "Short term download URL for the file. This will only be populated on files with content stored in Drive."
|
22
|
+
},
|
23
|
+
"editable": {
|
24
|
+
"type": "boolean",
|
25
|
+
"description": "Whether the file can be edited by the current user."
|
26
|
+
},
|
27
|
+
"embedLink": {
|
28
|
+
"type": "string",
|
29
|
+
"description": "A link for embedding the file."
|
30
|
+
},
|
31
|
+
"etag": {
|
32
|
+
"type": "string",
|
33
|
+
"description": "ETag of the file."
|
34
|
+
},
|
35
|
+
"exportLinks": {
|
36
|
+
"type": "object",
|
37
|
+
"description": "Links for exporting Google Docs to specific formats.",
|
38
|
+
"additionalProperties": {
|
39
|
+
"type": "string",
|
40
|
+
"description": "A mapping from export format to URL"
|
41
|
+
}
|
42
|
+
},
|
43
|
+
"fileExtension": {
|
44
|
+
"type": "string",
|
45
|
+
"description": "The file extension used when downloading this file. This field is read only. To set the extension, include it on title when creating the file. This will only be populated on files with content stored in Drive."
|
46
|
+
},
|
47
|
+
"fileSize": {
|
48
|
+
"type": "string",
|
49
|
+
"description": "The size of the file in bytes. This will only be populated on files with content stored in Drive.",
|
50
|
+
"format": "int64"
|
51
|
+
},
|
52
|
+
"id": {
|
53
|
+
"type": "string",
|
54
|
+
"description": "The id of the file."
|
55
|
+
},
|
56
|
+
"indexableText": {
|
57
|
+
"type": "object",
|
58
|
+
"description": "Indexable text attributes for the file (can only be written)",
|
59
|
+
"properties": {
|
60
|
+
"text": {
|
61
|
+
"type": "string",
|
62
|
+
"description": "The text to be indexed for this file"
|
63
|
+
}
|
64
|
+
}
|
65
|
+
},
|
66
|
+
"kind": {
|
67
|
+
"type": "string",
|
68
|
+
"description": "The type of file. This is always drive#file.",
|
69
|
+
"default": "drive#file"
|
70
|
+
},
|
71
|
+
"labels": {
|
72
|
+
"type": "object",
|
73
|
+
"description": "A group of labels for the file.",
|
74
|
+
"properties": {
|
75
|
+
"hidden": {
|
76
|
+
"type": "boolean",
|
77
|
+
"description": "Whether this file is hidden from the user."
|
78
|
+
},
|
79
|
+
"restricted": {
|
80
|
+
"type": "boolean",
|
81
|
+
"description": "Whether viewers are prevented from downloading this file."
|
82
|
+
},
|
83
|
+
"starred": {
|
84
|
+
"type": "boolean",
|
85
|
+
"description": "Whether this file is starred by the user."
|
86
|
+
},
|
87
|
+
"trashed": {
|
88
|
+
"type": "boolean",
|
89
|
+
"description": "Whether this file has been trashed."
|
90
|
+
},
|
91
|
+
"viewed": {
|
92
|
+
"type": "boolean",
|
93
|
+
"description": "Whether this file has been viewed by this user."
|
94
|
+
}
|
95
|
+
}
|
96
|
+
},
|
97
|
+
"lastModifyingUserName": {
|
98
|
+
"type": "string",
|
99
|
+
"description": "Name of the last user to modify this file. This will only be populated if a user has edited this file."
|
100
|
+
},
|
101
|
+
"lastViewedByMeDate": {
|
102
|
+
"type": "string",
|
103
|
+
"description": "Last time this file was viewed by the user (formatted RFC 3339 timestamp).",
|
104
|
+
"format": "date-time"
|
105
|
+
},
|
106
|
+
"md5Checksum": {
|
107
|
+
"type": "string",
|
108
|
+
"description": "An MD5 checksum for the content of this file. This will only be populated on files with content stored in Drive."
|
109
|
+
},
|
110
|
+
"mimeType": {
|
111
|
+
"type": "string",
|
112
|
+
"description": "The MIME type of the file."
|
113
|
+
},
|
114
|
+
"modifiedByMeDate": {
|
115
|
+
"type": "string",
|
116
|
+
"description": "Last time this file was modified by the user (formatted RFC 3339 timestamp).",
|
117
|
+
"format": "date-time"
|
118
|
+
},
|
119
|
+
"modifiedDate": {
|
120
|
+
"type": "string",
|
121
|
+
"description": "Last time this file was modified by anyone (formatted RFC 3339 timestamp).",
|
122
|
+
"format": "date-time"
|
123
|
+
},
|
124
|
+
"originalFilename": {
|
125
|
+
"type": "string",
|
126
|
+
"description": "The filename when uploading this file. This will only be populated on files with content stored in Drive."
|
127
|
+
},
|
128
|
+
"ownerNames": {
|
129
|
+
"type": "array",
|
130
|
+
"description": "Name(s) of the owner(s) of this file.",
|
131
|
+
"items": {
|
132
|
+
"type": "string"
|
133
|
+
}
|
134
|
+
},
|
135
|
+
"parents": {
|
136
|
+
"type": "array",
|
137
|
+
"description": "Collection of parent folders which contain this file.\nSetting this field will put the file in all of the provided folders. On insert, if no folders are provided, the file will be placed in the default root folder.",
|
138
|
+
"items": {
|
139
|
+
"$ref": "#ParentReference"
|
140
|
+
}
|
141
|
+
},
|
142
|
+
"permissionsLink": {
|
143
|
+
"type": "string",
|
144
|
+
"description": "A link to the permissions collection."
|
145
|
+
},
|
146
|
+
"quotaBytesUsed": {
|
147
|
+
"type": "string",
|
148
|
+
"description": "The number of quota bytes used by this file.",
|
149
|
+
"format": "int64"
|
150
|
+
},
|
151
|
+
"selfLink": {
|
152
|
+
"type": "string",
|
153
|
+
"description": "A link back to this file."
|
154
|
+
},
|
155
|
+
"sharedWithMeDate": {
|
156
|
+
"type": "string",
|
157
|
+
"description": "Time at which this file was shared with the user (formatted RFC 3339 timestamp).",
|
158
|
+
"format": "date-time"
|
159
|
+
},
|
160
|
+
"thumbnailLink": {
|
161
|
+
"type": "string",
|
162
|
+
"description": "A link to the file's thumbnail."
|
163
|
+
},
|
164
|
+
"title": {
|
165
|
+
"type": "string",
|
166
|
+
"description": "The title of this file."
|
167
|
+
},
|
168
|
+
"writersCanShare": {
|
169
|
+
"type": "boolean",
|
170
|
+
"description": "Whether writers can share the document with other users."
|
171
|
+
}
|
172
|
+
}
|
173
|
+
}
|
@@ -0,0 +1,35 @@
|
|
1
|
+
{
|
2
|
+
"id": "FileList",
|
3
|
+
"type": "object",
|
4
|
+
"description": "A list of files.",
|
5
|
+
"properties": {
|
6
|
+
"etag": {
|
7
|
+
"type": "string",
|
8
|
+
"description": "The ETag of the list."
|
9
|
+
},
|
10
|
+
"items": {
|
11
|
+
"type": "array",
|
12
|
+
"description": "The actual list of files.",
|
13
|
+
"items": {
|
14
|
+
"$ref": "#File"
|
15
|
+
}
|
16
|
+
},
|
17
|
+
"kind": {
|
18
|
+
"type": "string",
|
19
|
+
"description": "This is always drive#fileList.",
|
20
|
+
"default": "drive#fileList"
|
21
|
+
},
|
22
|
+
"nextLink": {
|
23
|
+
"type": "string",
|
24
|
+
"description": "A link to the next page of files."
|
25
|
+
},
|
26
|
+
"nextPageToken": {
|
27
|
+
"type": "string",
|
28
|
+
"description": "The page token for the next page of files."
|
29
|
+
},
|
30
|
+
"selfLink": {
|
31
|
+
"type": "string",
|
32
|
+
"description": "A link back to this list."
|
33
|
+
}
|
34
|
+
}
|
35
|
+
}
|
@@ -0,0 +1,28 @@
|
|
1
|
+
{
|
2
|
+
"id": "ParentReference",
|
3
|
+
"type": "object",
|
4
|
+
"description": "A reference to a file's parent.",
|
5
|
+
"properties": {
|
6
|
+
"id": {
|
7
|
+
"type": "string",
|
8
|
+
"description": "The ID of the parent."
|
9
|
+
},
|
10
|
+
"isRoot": {
|
11
|
+
"type": "boolean",
|
12
|
+
"description": "Whether or not the parent is the root folder."
|
13
|
+
},
|
14
|
+
"kind": {
|
15
|
+
"type": "string",
|
16
|
+
"description": "This is always drive#parentReference.",
|
17
|
+
"default": "drive#parentReference"
|
18
|
+
},
|
19
|
+
"parentLink": {
|
20
|
+
"type": "string",
|
21
|
+
"description": "A link to the parent."
|
22
|
+
},
|
23
|
+
"selfLink": {
|
24
|
+
"type": "string",
|
25
|
+
"description": "A link back to this reference."
|
26
|
+
}
|
27
|
+
}
|
28
|
+
}
|
data/spec/spec_helper.rb
CHANGED
@@ -5,3 +5,26 @@ $:.unshift(lib_dir)
|
|
5
5
|
$:.uniq!
|
6
6
|
|
7
7
|
require 'autoparse'
|
8
|
+
require 'json'
|
9
|
+
|
10
|
+
module JSONMatchers
|
11
|
+
class EqualsJson
|
12
|
+
def initialize(expected)
|
13
|
+
@expected = JSON.parse(expected)
|
14
|
+
end
|
15
|
+
def matches?(target)
|
16
|
+
@target = JSON.parse(target)
|
17
|
+
@target.eql?(@expected)
|
18
|
+
end
|
19
|
+
def failure_message
|
20
|
+
"expected #{@target.inspect} to be #{@expected}"
|
21
|
+
end
|
22
|
+
def negative_failure_message
|
23
|
+
"expected #{@target.inspect} not to be #{@expected}"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def be_json(expected)
|
28
|
+
EqualsJson.new(expected)
|
29
|
+
end
|
30
|
+
end
|
data/tasks/gem.rake
CHANGED
@@ -25,14 +25,13 @@ namespace :gem do
|
|
25
25
|
s.extra_rdoc_files = %w( README.md )
|
26
26
|
s.rdoc_options.concat ['--main', 'README.md']
|
27
27
|
|
28
|
-
s.add_runtime_dependency('addressable', '
|
28
|
+
s.add_runtime_dependency('addressable', '>= 2.3.1')
|
29
29
|
s.add_runtime_dependency('multi_json', '>= 1.0.0')
|
30
30
|
s.add_runtime_dependency('extlib', '>= 0.9.15')
|
31
31
|
|
32
|
-
s.add_development_dependency('rake', '
|
33
|
-
s.add_development_dependency('rspec', '
|
34
|
-
s.add_development_dependency('launchy', '
|
35
|
-
s.add_development_dependency('diff-lcs', '~> 1.1.2')
|
32
|
+
s.add_development_dependency('rake', '>= 0.9.0')
|
33
|
+
s.add_development_dependency('rspec', '>= 2.11.0')
|
34
|
+
s.add_development_dependency('launchy', '>= 2.1.1')
|
36
35
|
|
37
36
|
s.require_path = 'lib'
|
38
37
|
end
|
@@ -87,4 +86,4 @@ end
|
|
87
86
|
desc 'Alias to gem:package'
|
88
87
|
task 'gem' => 'gem:package'
|
89
88
|
|
90
|
-
task '
|
89
|
+
task 'gem:release' => 'gem:gemspec'
|
data/tasks/git.rake
CHANGED
@@ -19,10 +19,15 @@ namespace :git do
|
|
19
19
|
v = ENV['VERSION'] or abort 'Must supply VERSION=x.y.z'
|
20
20
|
abort "Versions don't match #{v} vs #{PKG_VERSION}" if v != PKG_VERSION
|
21
21
|
|
22
|
+
git_status = `git status`
|
23
|
+
if git_status !~ /nothing to commit \(working directory clean\)/
|
24
|
+
abort "Working directory isn't clean."
|
25
|
+
end
|
26
|
+
|
22
27
|
tag = "#{PKG_NAME}-#{PKG_VERSION}"
|
23
28
|
msg = "Release #{PKG_NAME}-#{PKG_VERSION}"
|
24
29
|
|
25
|
-
existing_tags = `git tag -l #{PKG_NAME}-*`.split(
|
30
|
+
existing_tags = `git tag -l #{PKG_NAME}-*`.split('\n')
|
26
31
|
if existing_tags.include?(tag)
|
27
32
|
warn('Tag already exists, deleting...')
|
28
33
|
unless system "git tag -d #{tag}"
|
metadata
CHANGED
@@ -1,13 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: autoparse
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash: 17
|
5
4
|
prerelease:
|
6
|
-
|
7
|
-
- 0
|
8
|
-
- 3
|
9
|
-
- 1
|
10
|
-
version: 0.3.1
|
5
|
+
version: 0.3.2
|
11
6
|
platform: ruby
|
12
7
|
authors:
|
13
8
|
- Bob Aman
|
@@ -15,7 +10,7 @@ autorequire:
|
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
12
|
|
18
|
-
date: 2012-
|
13
|
+
date: 2012-07-31 00:00:00 Z
|
19
14
|
dependencies:
|
20
15
|
- !ruby/object:Gem::Dependency
|
21
16
|
name: addressable
|
@@ -23,14 +18,9 @@ dependencies:
|
|
23
18
|
requirement: &id001 !ruby/object:Gem::Requirement
|
24
19
|
none: false
|
25
20
|
requirements:
|
26
|
-
- -
|
21
|
+
- - ">="
|
27
22
|
- !ruby/object:Gem::Version
|
28
|
-
|
29
|
-
segments:
|
30
|
-
- 2
|
31
|
-
- 2
|
32
|
-
- 3
|
33
|
-
version: 2.2.3
|
23
|
+
version: 2.3.1
|
34
24
|
type: :runtime
|
35
25
|
version_requirements: *id001
|
36
26
|
- !ruby/object:Gem::Dependency
|
@@ -41,11 +31,6 @@ dependencies:
|
|
41
31
|
requirements:
|
42
32
|
- - ">="
|
43
33
|
- !ruby/object:Gem::Version
|
44
|
-
hash: 23
|
45
|
-
segments:
|
46
|
-
- 1
|
47
|
-
- 0
|
48
|
-
- 0
|
49
34
|
version: 1.0.0
|
50
35
|
type: :runtime
|
51
36
|
version_requirements: *id002
|
@@ -57,11 +42,6 @@ dependencies:
|
|
57
42
|
requirements:
|
58
43
|
- - ">="
|
59
44
|
- !ruby/object:Gem::Version
|
60
|
-
hash: 37
|
61
|
-
segments:
|
62
|
-
- 0
|
63
|
-
- 9
|
64
|
-
- 15
|
65
45
|
version: 0.9.15
|
66
46
|
type: :runtime
|
67
47
|
version_requirements: *id003
|
@@ -71,14 +51,9 @@ dependencies:
|
|
71
51
|
requirement: &id004 !ruby/object:Gem::Requirement
|
72
52
|
none: false
|
73
53
|
requirements:
|
74
|
-
- -
|
54
|
+
- - ">="
|
75
55
|
- !ruby/object:Gem::Version
|
76
|
-
|
77
|
-
segments:
|
78
|
-
- 0
|
79
|
-
- 8
|
80
|
-
- 3
|
81
|
-
version: 0.8.3
|
56
|
+
version: 0.9.0
|
82
57
|
type: :development
|
83
58
|
version_requirements: *id004
|
84
59
|
- !ruby/object:Gem::Dependency
|
@@ -87,14 +62,9 @@ dependencies:
|
|
87
62
|
requirement: &id005 !ruby/object:Gem::Requirement
|
88
63
|
none: false
|
89
64
|
requirements:
|
90
|
-
- -
|
65
|
+
- - ">="
|
91
66
|
- !ruby/object:Gem::Version
|
92
|
-
|
93
|
-
segments:
|
94
|
-
- 2
|
95
|
-
- 6
|
96
|
-
- 0
|
97
|
-
version: 2.6.0
|
67
|
+
version: 2.11.0
|
98
68
|
type: :development
|
99
69
|
version_requirements: *id005
|
100
70
|
- !ruby/object:Gem::Dependency
|
@@ -103,32 +73,11 @@ dependencies:
|
|
103
73
|
requirement: &id006 !ruby/object:Gem::Requirement
|
104
74
|
none: false
|
105
75
|
requirements:
|
106
|
-
- -
|
76
|
+
- - ">="
|
107
77
|
- !ruby/object:Gem::Version
|
108
|
-
|
109
|
-
segments:
|
110
|
-
- 0
|
111
|
-
- 3
|
112
|
-
- 2
|
113
|
-
version: 0.3.2
|
78
|
+
version: 2.1.1
|
114
79
|
type: :development
|
115
80
|
version_requirements: *id006
|
116
|
-
- !ruby/object:Gem::Dependency
|
117
|
-
name: diff-lcs
|
118
|
-
prerelease: false
|
119
|
-
requirement: &id007 !ruby/object:Gem::Requirement
|
120
|
-
none: false
|
121
|
-
requirements:
|
122
|
-
- - ~>
|
123
|
-
- !ruby/object:Gem::Version
|
124
|
-
hash: 23
|
125
|
-
segments:
|
126
|
-
- 1
|
127
|
-
- 1
|
128
|
-
- 2
|
129
|
-
version: 1.1.2
|
130
|
-
type: :development
|
131
|
-
version_requirements: *id007
|
132
81
|
description: |
|
133
82
|
An implementation of the JSON Schema specification. Provides automatic parsing
|
134
83
|
for any given JSON Schema.
|
@@ -149,15 +98,18 @@ files:
|
|
149
98
|
- spec/data/account.json
|
150
99
|
- spec/data/address.json
|
151
100
|
- spec/data/adult.json
|
101
|
+
- spec/data/booleans.json
|
152
102
|
- spec/data/calendar.json
|
153
103
|
- spec/data/card.json
|
154
|
-
- spec/data/
|
104
|
+
- spec/data/file.json
|
105
|
+
- spec/data/filelist.json
|
155
106
|
- spec/data/geo.json
|
156
107
|
- spec/data/hyper-schema.json
|
157
108
|
- spec/data/interfaces.json
|
158
109
|
- spec/data/json-ref.json
|
159
110
|
- spec/data/links.json
|
160
111
|
- spec/data/node.json
|
112
|
+
- spec/data/parentref.json
|
161
113
|
- spec/data/person.json
|
162
114
|
- spec/data/positive.json
|
163
115
|
- spec/data/schema.json
|
@@ -173,6 +125,8 @@ files:
|
|
173
125
|
- tasks/yard.rake
|
174
126
|
- website/index.html
|
175
127
|
- CHANGELOG.md
|
128
|
+
- Gemfile
|
129
|
+
- Gemfile.lock
|
176
130
|
- LICENSE
|
177
131
|
- Rakefile
|
178
132
|
- README.md
|
@@ -190,23 +144,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
190
144
|
requirements:
|
191
145
|
- - ">="
|
192
146
|
- !ruby/object:Gem::Version
|
193
|
-
hash: 3
|
194
|
-
segments:
|
195
|
-
- 0
|
196
147
|
version: "0"
|
197
148
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
198
149
|
none: false
|
199
150
|
requirements:
|
200
151
|
- - ">="
|
201
152
|
- !ruby/object:Gem::Version
|
202
|
-
hash: 3
|
203
|
-
segments:
|
204
|
-
- 0
|
205
153
|
version: "0"
|
206
154
|
requirements: []
|
207
155
|
|
208
156
|
rubyforge_project: autoparse
|
209
|
-
rubygems_version: 1.8.
|
157
|
+
rubygems_version: 1.8.24
|
210
158
|
signing_key:
|
211
159
|
specification_version: 3
|
212
160
|
summary: A parsing system based on JSON Schema.
|
data/spec/data/chaos.json
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
{
|
2
|
-
"description" : "A union type",
|
3
|
-
"type" : ["null", {
|
4
|
-
"properties" : {
|
5
|
-
"chaos": {
|
6
|
-
"type":"string",
|
7
|
-
"format": "url"
|
8
|
-
}
|
9
|
-
}
|
10
|
-
}, {
|
11
|
-
"properties" : {
|
12
|
-
"chaos": {
|
13
|
-
"type":"string",
|
14
|
-
"format": "date-time"
|
15
|
-
}
|
16
|
-
}
|
17
|
-
}, {
|
18
|
-
"properties" : {
|
19
|
-
"chaos": {"type":["boolean", "number"]}
|
20
|
-
}
|
21
|
-
}]
|
22
|
-
}
|