schematic 0.0.8 → 0.1.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.
@@ -0,0 +1,116 @@
1
+ require "spec_helper"
2
+
3
+ describe Schematic::Serializers::Xsd do
4
+ describe ".xsd_methods" do
5
+ context "given a method" do
6
+ with_model :some_model do
7
+ table {}
8
+
9
+ model do
10
+ def self.xsd_methods
11
+ {:foo_bar => nil}
12
+ end
13
+ end
14
+ end
15
+
16
+ it "should include the additional method" do
17
+ xsd = generate_xsd_for_model(SomeModel) do
18
+ <<-XML
19
+ <xs:element name="id" minOccurs="0" maxOccurs="1">
20
+ <xs:complexType>
21
+ <xs:simpleContent>
22
+ <xs:restriction base="Integer">
23
+ </xs:restriction>
24
+ </xs:simpleContent>
25
+ </xs:complexType>
26
+ </xs:element>
27
+ <xs:element name="foo-bar" minOccurs="0" maxOccurs="1"/>
28
+ XML
29
+ end
30
+
31
+ sanitize_xml(SomeModel.to_xsd).should eq(xsd)
32
+ end
33
+ end
34
+
35
+ context "given a an array of methods" do
36
+ with_model :some_model do
37
+ table {}
38
+
39
+ model do
40
+ def self.xsd_methods
41
+ {:foo => [:bar]}
42
+ end
43
+ end
44
+ end
45
+
46
+ it "should include the additional methods" do
47
+ xsd = generate_xsd_for_model(SomeModel) do
48
+ <<-XML
49
+ <xs:element name="id" minOccurs="0" maxOccurs="1">
50
+ <xs:complexType>
51
+ <xs:simpleContent>
52
+ <xs:restriction base="Integer">
53
+ </xs:restriction>
54
+ </xs:simpleContent>
55
+ </xs:complexType>
56
+ </xs:element>
57
+ <xs:element name="foo" minOccurs="0" maxOccurs="1">
58
+ <xs:complexType>
59
+ <xs:sequence>
60
+ <xs:element name="bar" minOccurs="0" maxOccurs="unbounded"/>
61
+ </xs:sequence>
62
+ <xs:attribute name="type" type="xs:string" fixed="array" use="optional"/>
63
+ </xs:complexType>
64
+ </xs:element>
65
+ XML
66
+ end
67
+ sanitize_xml(SomeModel.to_xsd).should eq(xsd)
68
+ end
69
+ end
70
+
71
+ context "given nested methods" do
72
+ with_model :some_model do
73
+ table {}
74
+
75
+ model do
76
+ def self.xsd_methods
77
+ { :foo => { :bar => {:baz => nil } } }
78
+ end
79
+ end
80
+ end
81
+
82
+ it "should nested the additional methods" do
83
+ xsd = generate_xsd_for_model(SomeModel) do
84
+ <<-XML
85
+ <xs:element name="id" minOccurs="0" maxOccurs="1">
86
+ <xs:complexType>
87
+ <xs:simpleContent>
88
+ <xs:restriction base="Integer">
89
+ </xs:restriction>
90
+ </xs:simpleContent>
91
+ </xs:complexType>
92
+ </xs:element>
93
+ <xs:element name="foo" minOccurs="0" maxOccurs="1">
94
+ <xs:complexType>
95
+ <xs:all>
96
+ <xs:element name="bar" minOccurs="0" maxOccurs="1">
97
+ <xs:complexType>
98
+ <xs:all>
99
+ <xs:element name="baz" minOccurs="0" maxOccurs="1"/>
100
+ </xs:all>
101
+ <xs:attribute name="type" type="xs:string" fixed="array" use="optional"/>
102
+ </xs:complexType>
103
+ </xs:element>
104
+ </xs:all>
105
+ <xs:attribute name="type" type="xs:string" fixed="array" use="optional"/>
106
+ </xs:complexType>
107
+ </xs:element>
108
+ XML
109
+ end
110
+
111
+ sanitize_xml(SomeModel.to_xsd).should eq(xsd)
112
+ end
113
+ end
114
+ end
115
+ end
116
+
@@ -0,0 +1,47 @@
1
+ require "spec_helper"
2
+
3
+ describe Schematic::Serializers::Xsd do
4
+
5
+ describe ".minimum_occurrences_for_column" do
6
+ subject { Schematic::Generator::Column.new(SomeModel, column).minimum_occurrences_for_column }
7
+ let(:column) { SomeModel.columns.first }
8
+
9
+ context "given a column with no validations" do
10
+ with_model :some_model do
11
+ table :id => false do |t|
12
+ t.string "title"
13
+ end
14
+ model {}
15
+ end
16
+
17
+ it { should == "0" }
18
+ end
19
+
20
+ context "given a column with presence of but allow blank" do
21
+ with_model :some_model do
22
+ table :id => false do |t|
23
+ t.string "title"
24
+ end
25
+ model do
26
+ validates :title, :presence => true, :allow_blank => true
27
+ end
28
+ end
29
+
30
+ it { should == "0" }
31
+ end
32
+
33
+ context "given a column with presence of and no allow blank" do
34
+ with_model :some_model do
35
+ table :id => false do |t|
36
+ t.string "title"
37
+ end
38
+ model do
39
+ validates :title, :presence => true
40
+ end
41
+ end
42
+
43
+ it { should == "1" }
44
+ end
45
+ end
46
+
47
+ end
@@ -10,32 +10,6 @@ describe Schematic::Serializers::Xsd do
10
10
  end
11
11
  end
12
12
 
13
- describe ".extend" do
14
- context "when the model inherits ActiveRecord::Base" do
15
- subject { EmptyModel }
16
-
17
- it "should allow the model to be extended" do
18
- lambda {
19
- subject.class_eval do
20
- extend Schematic::Serializers::Xsd
21
- end
22
- }.should_not raise_error
23
- end
24
- end
25
-
26
- context "when the model does not inherit ActiveRecord::Base" do
27
- subject { Object }
28
-
29
- it "should raise an exception" do
30
- lambda {
31
- subject.class_eval do
32
- extend Schematic::Serializers::Xsd
33
- end
34
- }.should raise_error(Schematic::InvalidClass)
35
- end
36
- end
37
- end
38
-
39
13
  describe ".to_xsd" do
40
14
 
41
15
  context "XSD validation" do
@@ -46,13 +20,14 @@ describe Schematic::Serializers::Xsd do
46
20
  table do |t|
47
21
  t.string "some_string"
48
22
  t.float "some_float"
23
+ t.integer "some_integer"
49
24
  t.datetime "some_datetime"
50
25
  t.date "some_date"
51
26
  t.boolean "some_boolean"
52
27
  end
53
28
 
54
29
  model do
55
- validates :some_string, :presence => true
30
+ validates :some_string, :presence => true, :length => { :maximum => 100 }
56
31
  validates :some_date, :presence => true, :allow_blank => true
57
32
  validates :some_datetime, :presence => true, :allow_blank => false
58
33
 
@@ -64,9 +39,21 @@ describe Schematic::Serializers::Xsd do
64
39
  end
65
40
 
66
41
  end
42
+
67
43
  it "should generate a valid XSD" do
68
44
  validate_xsd(subject)
69
45
  end
46
+
47
+ it "should validate against it's own XSD" do
48
+ instance = SomeModel.new(:some_string => "ExampleString",
49
+ :some_date => Date.today,
50
+ :some_datetime => DateTime.new,
51
+ :some_boolean => true,
52
+ :some_float => 1.5,
53
+ :some_integer => 2)
54
+ xml = [instance].to_xml
55
+ validate_xml_against_xsd(xml, subject)
56
+ end
70
57
  end
71
58
 
72
59
  context "when the model is namespaced" do
@@ -166,6 +153,55 @@ describe Schematic::Serializers::Xsd do
166
153
  xsd = <<-XML
167
154
  <?xml version="1.0" encoding="UTF-8"?>
168
155
  <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
156
+ <xs:complexType name="Integer">
157
+ <xs:simpleContent>
158
+ <xs:extension base="xs:integer">
159
+ <xs:attribute name="type" type="xs:string" use="optional"/>
160
+ </xs:extension>
161
+ </xs:simpleContent>
162
+ </xs:complexType>
163
+ <xs:complexType name="Float">
164
+ <xs:simpleContent>
165
+ <xs:extension base="xs:float">
166
+ <xs:attribute name="type" type="xs:string" use="optional"/>
167
+ </xs:extension>
168
+ </xs:simpleContent>
169
+ </xs:complexType>
170
+ <xs:complexType name="String">
171
+ <xs:simpleContent>
172
+ <xs:extension base="xs:string">
173
+ <xs:attribute name="type" type="xs:string" use="optional"/>
174
+ </xs:extension>
175
+ </xs:simpleContent>
176
+ </xs:complexType>
177
+ <xs:complexType name="Text">
178
+ <xs:simpleContent>
179
+ <xs:extension base="xs:string">
180
+ <xs:attribute name="type" type="xs:string" use="optional"/>
181
+ </xs:extension>
182
+ </xs:simpleContent>
183
+ </xs:complexType>
184
+ <xs:complexType name="DateTime">
185
+ <xs:simpleContent>
186
+ <xs:extension base="xs:dateTime">
187
+ <xs:attribute name="type" type="xs:string" use="optional"/>
188
+ </xs:extension>
189
+ </xs:simpleContent>
190
+ </xs:complexType>
191
+ <xs:complexType name="Date">
192
+ <xs:simpleContent>
193
+ <xs:extension base="xs:date">
194
+ <xs:attribute name="type" type="xs:string" use="optional"/>
195
+ </xs:extension>
196
+ </xs:simpleContent>
197
+ </xs:complexType>
198
+ <xs:complexType name="Boolean">
199
+ <xs:simpleContent>
200
+ <xs:extension base="xs:boolean">
201
+ <xs:attribute name="type" type="xs:string" use="optional"/>
202
+ </xs:extension>
203
+ </xs:simpleContent>
204
+ </xs:complexType>
169
205
  <xs:element name="empty-models" type="EmptyModels"/>
170
206
  <xs:complexType name="EmptyModels">
171
207
  <xs:sequence>
@@ -201,9 +237,8 @@ describe Schematic::Serializers::Xsd do
201
237
  <xs:element name="some-float" minOccurs="0" maxOccurs="1">
202
238
  <xs:complexType>
203
239
  <xs:simpleContent>
204
- <xs:extension base="xs:float">
205
- <xs:attribute name="type" type="xs:string" use="optional"/>
206
- </xs:extension>
240
+ <xs:restriction base="Float">
241
+ </xs:restriction>
207
242
  </xs:simpleContent>
208
243
  </xs:complexType>
209
244
  </xs:element>
@@ -226,9 +261,8 @@ describe Schematic::Serializers::Xsd do
226
261
  <xs:element name="id" minOccurs="0" maxOccurs="1">
227
262
  <xs:complexType>
228
263
  <xs:simpleContent>
229
- <xs:extension base="xs:integer">
230
- <xs:attribute name="type" type="xs:string" use="optional"/>
231
- </xs:extension>
264
+ <xs:restriction base="Integer">
265
+ </xs:restriction>
232
266
  </xs:simpleContent>
233
267
  </xs:complexType>
234
268
  </xs:element>
@@ -242,329 +276,6 @@ describe Schematic::Serializers::Xsd do
242
276
 
243
277
  end
244
278
 
245
- context "with a model with validations" do
246
- subject { sanitize_xml(SomeModel.to_xsd) }
247
-
248
- context "presence of validation" do
249
-
250
- context "when allow blank is true" do
251
- with_model :some_model do
252
- table :id => false do |t|
253
- t.string "title"
254
- end
255
-
256
- model do
257
- validate :title, :presence => true, :allow_blank => true
258
- end
259
- end
260
-
261
- it "should mark that the field minimum occurrences is 0" do
262
- xsd = generate_xsd_for_model(SomeModel) do
263
- <<-XML
264
- <xs:element name="title" minOccurs="0" maxOccurs="1">
265
- <xs:complexType>
266
- <xs:simpleContent>
267
- <xs:extension base="xs:string">
268
- <xs:attribute name="type" type="xs:string" use="optional"/>
269
- </xs:extension>
270
- </xs:simpleContent>
271
- </xs:complexType>
272
- </xs:element>
273
- XML
274
- end
275
-
276
- subject.should == xsd
277
- end
278
- end
279
-
280
- context "when allow blank is false" do
281
- with_model :some_model do
282
- table :id => false do |t|
283
- t.string "title"
284
- end
285
-
286
- model do
287
- validates :title, :presence => true
288
- end
289
- end
290
-
291
- it "should mark that the field minimum occurrences is 1" do
292
- xsd = generate_xsd_for_model(SomeModel) do
293
- <<-XML
294
- <xs:element name="title" minOccurs="1" maxOccurs="1">
295
- <xs:complexType>
296
- <xs:simpleContent>
297
- <xs:extension base="xs:string">
298
- <xs:attribute name="type" type="xs:string" use="optional"/>
299
- </xs:extension>
300
- </xs:simpleContent>
301
- </xs:complexType>
302
- </xs:element>
303
- XML
304
- end
305
-
306
- subject.should == xsd
307
- end
308
- end
309
-
310
- context "when there is a condition" do
311
- with_model :some_model do
312
- table :id => false do |t|
313
- t.string "title"
314
- end
315
-
316
- model do
317
- validates :title, :presence => true, :if => lambda { |model| false }
318
- end
319
- end
320
-
321
- it "should mark that the field minimum occurrences is 0" do
322
- xsd = generate_xsd_for_model(SomeModel) do
323
- <<-XML
324
- <xs:element name="title" minOccurs="0" maxOccurs="1">
325
- <xs:complexType>
326
- <xs:simpleContent>
327
- <xs:extension base="xs:string">
328
- <xs:attribute name="type" type="xs:string" use="optional"/>
329
- </xs:extension>
330
- </xs:simpleContent>
331
- </xs:complexType>
332
- </xs:element>
333
- XML
334
- end
335
-
336
- subject.should == xsd
337
- end
338
- end
339
- end
340
-
341
- describe "length validation" do
342
-
343
- end
344
-
345
- describe "inclusion validation" do
346
-
347
- end
348
- end
349
- end
350
-
351
- describe ".xsd_methods" do
352
- context "given a method" do
353
- with_model :some_model do
354
- table {}
355
-
356
- model do
357
- def self.xsd_methods
358
- {:foo_bar => nil}
359
- end
360
- end
361
- end
362
-
363
- it "should include the additional method" do
364
- xsd = generate_xsd_for_model(SomeModel) do
365
- <<-XML
366
- <xs:element name="id" minOccurs="0" maxOccurs="1">
367
- <xs:complexType>
368
- <xs:simpleContent>
369
- <xs:extension base="xs:integer">
370
- <xs:attribute name="type" type="xs:string" use="optional"/>
371
- </xs:extension>
372
- </xs:simpleContent>
373
- </xs:complexType>
374
- </xs:element>
375
- <xs:element name="foo-bar" minOccurs="0" maxOccurs="1"/>
376
- XML
377
- end
378
-
379
- sanitize_xml(SomeModel.to_xsd).should eq(xsd)
380
- end
381
- end
382
-
383
- context "given a an array of methods" do
384
- with_model :some_model do
385
- table {}
386
-
387
- model do
388
- def self.xsd_methods
389
- {:foo => [:bar]}
390
- end
391
- end
392
- end
393
-
394
- it "should include the additional methods" do
395
- xsd = generate_xsd_for_model(SomeModel) do
396
- <<-XML
397
- <xs:element name="id" minOccurs="0" maxOccurs="1">
398
- <xs:complexType>
399
- <xs:simpleContent>
400
- <xs:extension base="xs:integer">
401
- <xs:attribute name="type" type="xs:string" use="optional"/>
402
- </xs:extension>
403
- </xs:simpleContent>
404
- </xs:complexType>
405
- </xs:element>
406
- <xs:element name="foo" minOccurs="0" maxOccurs="1">
407
- <xs:complexType>
408
- <xs:sequence>
409
- <xs:element name="bar" minOccurs="0" maxOccurs="unbounded"/>
410
- </xs:sequence>
411
- <xs:attribute name="type" type="xs:string" fixed="array" use="optional"/>
412
- </xs:complexType>
413
- </xs:element>
414
- XML
415
- end
416
- sanitize_xml(SomeModel.to_xsd).should eq(xsd)
417
- end
418
- end
419
-
420
- context "given nested methods" do
421
- with_model :some_model do
422
- table {}
423
-
424
- model do
425
- def self.xsd_methods
426
- { :foo => { :bar => {:baz => nil } } }
427
- end
428
- end
429
- end
430
-
431
- it "should nested the additional methods" do
432
- xsd = generate_xsd_for_model(SomeModel) do
433
- <<-XML
434
- <xs:element name="id" minOccurs="0" maxOccurs="1">
435
- <xs:complexType>
436
- <xs:simpleContent>
437
- <xs:extension base="xs:integer">
438
- <xs:attribute name="type" type="xs:string" use="optional"/>
439
- </xs:extension>
440
- </xs:simpleContent>
441
- </xs:complexType>
442
- </xs:element>
443
- <xs:element name="foo" minOccurs="0" maxOccurs="1">
444
- <xs:complexType>
445
- <xs:all>
446
- <xs:element name="bar" minOccurs="0" maxOccurs="1">
447
- <xs:complexType>
448
- <xs:all>
449
- <xs:element name="baz" minOccurs="0" maxOccurs="1"/>
450
- </xs:all>
451
- <xs:attribute name="type" type="xs:string" fixed="array" use="optional"/>
452
- </xs:complexType>
453
- </xs:element>
454
- </xs:all>
455
- <xs:attribute name="type" type="xs:string" fixed="array" use="optional"/>
456
- </xs:complexType>
457
- </xs:element>
458
- XML
459
- end
460
-
461
- sanitize_xml(SomeModel.to_xsd).should eq(xsd)
462
- end
463
- end
464
279
  end
465
280
 
466
-
467
- describe ".xsd_ignore_methods" do
468
- with_model :some_model do
469
- table :id => false do |t|
470
- t.string :title
471
- end
472
-
473
- model do
474
- def self.xsd_ignore_methods
475
- [:title]
476
- end
477
- end
478
- end
479
-
480
- it "should exclude the methods" do
481
- xsd = generate_xsd_for_model(SomeModel) do
482
- end
483
-
484
- sanitize_xml(SomeModel.to_xsd).should eq(xsd)
485
- end
486
- end
487
-
488
- describe ".xsd_minimum_occurrences_for" do
489
-
490
- context "given a column with no validations" do
491
- with_model :some_model do
492
- table :id => false do |t|
493
- t.string "title"
494
- end
495
- model {}
496
- end
497
-
498
- it "should return 0" do
499
- SomeModel.xsd_minimum_occurrences_for_column(SomeModel.columns.first).should == "0"
500
- end
501
- end
502
-
503
- context "given a column with presence of but allow blank" do
504
- with_model :some_model do
505
- table :id => false do |t|
506
- t.string "title"
507
- end
508
- model do
509
- validates :title, :presence => true, :allow_blank => true
510
- end
511
- end
512
-
513
- it "should return 0" do
514
- SomeModel.xsd_minimum_occurrences_for_column(SomeModel.columns.first).should == "0"
515
- end
516
- end
517
-
518
- context "given a column with presence of and no allow blank" do
519
- with_model :some_model do
520
- table :id => false do |t|
521
- t.string "title"
522
- end
523
- model do
524
- validates :title, :presence => true
525
- end
526
- end
527
-
528
- it "should return 1" do
529
- SomeModel.xsd_minimum_occurrences_for_column(SomeModel.columns.first).should == "1"
530
- end
531
- end
532
- end
533
-
534
- private
535
-
536
- def validate_xsd(xml)
537
- xsd_schema_file = File.join(File.dirname(__FILE__), "xsd", "XMLSchema.xsd")
538
- meta_xsd = Nokogiri::XML::Schema(File.open(xsd_schema_file))
539
-
540
- doc = Nokogiri::XML.parse(xml)
541
- meta_xsd.validate(doc).each do |error|
542
- error.message.should be_nil
543
- end
544
- end
545
-
546
- def sanitize_xml(xml)
547
- xml.split("\n").reject(&:blank?).map(&:strip).join("\n")
548
- end
549
-
550
- def generate_xsd_for_model(model)
551
- output = <<-XML
552
- <?xml version="1.0" encoding="UTF-8"?>
553
- <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
554
- <xs:element name="#{model.xsd_element_collection_name}" type="#{model.xsd_type_collection_name}"/>
555
- <xs:complexType name="#{model.xsd_type_collection_name}">
556
- <xs:sequence>
557
- <xs:element name="#{model.xsd_element_name}" type="#{model.xsd_type_name}" minOccurs="0" maxOccurs="unbounded"/>
558
- </xs:sequence>
559
- <xs:attribute name="type" type="xs:string" fixed="array"/>
560
- </xs:complexType>
561
- <xs:complexType name="#{model.xsd_type_name}">
562
- <xs:all>
563
- #{yield}
564
- </xs:all>
565
- </xs:complexType>
566
- </xs:schema>
567
- XML
568
- sanitize_xml(output)
569
- end
570
281
  end