schematic 0.0.8 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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