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.
- data/.rspec +1 -0
- data/README.rdoc +1 -1
- data/TODO +5 -0
- data/lib/schematic.rb +4 -1
- data/lib/schematic/generator/column.rb +47 -0
- data/lib/schematic/generator/names.rb +27 -0
- data/lib/schematic/generator/namespaces.rb +11 -0
- data/lib/schematic/generator/restrictions/base.rb +24 -0
- data/lib/schematic/generator/restrictions/enumeration.rb +21 -0
- data/lib/schematic/generator/restrictions/length.rb +19 -0
- data/lib/schematic/generator/restrictions/pattern.rb +20 -0
- data/lib/schematic/generator/types.rb +29 -0
- data/lib/schematic/generator/xsd.rb +111 -0
- data/lib/schematic/serializers/xsd.rb +10 -132
- data/lib/schematic/version.rb +1 -1
- data/schematic.gemspec +1 -0
- data/spec/schematic/generator/restrictions/enumeration_spec.rb +53 -0
- data/spec/schematic/generator/restrictions/length_spec.rb +181 -0
- data/spec/schematic/generator/restrictions/pattern_spec.rb +52 -0
- data/spec/schematic/serializers/xsd_extend_spec.rb +37 -0
- data/spec/schematic/serializers/xsd_validation_presence_spec.rb +95 -0
- data/spec/schematic/serializers/xsd_xsd_ignore_methods_spec.rb +25 -0
- data/spec/schematic/serializers/xsd_xsd_methods_spec.rb +116 -0
- data/spec/schematic/serializers/xsd_xsd_minimum_occurrences_for_spec.rb +47 -0
- data/spec/schematic_serializers_xsd_spec.rb +67 -356
- data/spec/spec_helper.rb +100 -0
- metadata +40 -2
@@ -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:
|
205
|
-
|
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:
|
230
|
-
|
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
|