schematic 0.0.1 → 0.0.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/README.rdoc +39 -1
- data/lib/schematic/serializers/xsd.rb +9 -1
- data/lib/schematic/version.rb +1 -1
- data/spec/schematic_serializers_xsd_spec.rb +146 -13
- data/spec/spec_helper.rb +1 -0
- data/spec/xsd/XMLSchema.xsd +2534 -0
- metadata +4 -2
data/README.rdoc
CHANGED
@@ -1,3 +1,41 @@
|
|
1
1
|
= Schematic
|
2
2
|
|
3
|
-
|
3
|
+
* http://github.com/casecommons/schematic/
|
4
|
+
|
5
|
+
== DESCRIPTION
|
6
|
+
|
7
|
+
Automatic XSD generation for your ActiveRecord models
|
8
|
+
|
9
|
+
== INSTALL
|
10
|
+
|
11
|
+
Add schematic to your Gemfile
|
12
|
+
|
13
|
+
gem 'schematic'
|
14
|
+
|
15
|
+
Then run:
|
16
|
+
|
17
|
+
$ bundle install
|
18
|
+
|
19
|
+
== USAGE
|
20
|
+
|
21
|
+
class Post < ActiveRecord::Base
|
22
|
+
end
|
23
|
+
|
24
|
+
Post.to_xsd => (a bunch of xml)
|
25
|
+
|
26
|
+
You can include additional elements by defining a ".xsd_methods" on your class:
|
27
|
+
|
28
|
+
class Post < ActiveRecord::Base
|
29
|
+
def self.xsd_methods
|
30
|
+
{:title => nil, :author => [:name, :email, :url]}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
== REQUIREMENTS
|
35
|
+
|
36
|
+
* ActiveRecord 3.x
|
37
|
+
|
38
|
+
== LICENSE
|
39
|
+
|
40
|
+
MIT
|
41
|
+
|
@@ -33,7 +33,7 @@ module Schematic
|
|
33
33
|
xsd_columns.each do |column|
|
34
34
|
next if additional_methods.keys.map(&:to_s).include?(column.name)
|
35
35
|
|
36
|
-
all.xs :element, "name" => column.name.dasherize, "minOccurs" =>
|
36
|
+
all.xs :element, "name" => column.name.dasherize, "minOccurs" => xsd_minimum_occurrences_for_column(column), "maxOccurs" => "1" do |field|
|
37
37
|
field.xs :complexType do |complex_type|
|
38
38
|
complex_type.xs :simpleContent do |simple_content|
|
39
39
|
simple_content.xs :extension, "base" => map_column_type_to_xsd_type(column) do |extension|
|
@@ -69,6 +69,14 @@ module Schematic
|
|
69
69
|
end
|
70
70
|
end
|
71
71
|
|
72
|
+
def xsd_minimum_occurrences_for_column(column)
|
73
|
+
self._validators[column.name.to_sym].each do |column_validation|
|
74
|
+
next unless column_validation.is_a? ActiveModel::Validations::PresenceValidator
|
75
|
+
return "1" if column_validation.options[:allow_blank] != true
|
76
|
+
end
|
77
|
+
"0"
|
78
|
+
end
|
79
|
+
|
72
80
|
def xsd_methods
|
73
81
|
{}
|
74
82
|
end
|
data/lib/schematic/version.rb
CHANGED
@@ -37,6 +37,37 @@ describe Schematic::Serializers::Xsd do
|
|
37
37
|
end
|
38
38
|
|
39
39
|
describe ".to_xsd" do
|
40
|
+
|
41
|
+
context "XSD validation" do
|
42
|
+
subject { SomeModel.to_xsd }
|
43
|
+
|
44
|
+
with_model :some_model do
|
45
|
+
table do |t|
|
46
|
+
t.string "some_string"
|
47
|
+
t.float "some_float"
|
48
|
+
t.datetime "some_datetime"
|
49
|
+
t.date "some_date"
|
50
|
+
t.boolean "some_boolean"
|
51
|
+
end
|
52
|
+
|
53
|
+
model do
|
54
|
+
validates :some_string, :presence => true
|
55
|
+
validates :some_date, :presence => true, :allow_blank => true
|
56
|
+
validates :some_datetime, :presence => true, :allow_blank => false
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
it "should generate a valid XSD" do
|
61
|
+
xsd_schema_file = File.join(File.dirname(__FILE__), "xsd", "XMLSchema.xsd")
|
62
|
+
meta_xsd = Nokogiri::XML::Schema(File.open(xsd_schema_file))
|
63
|
+
|
64
|
+
doc = Nokogiri::XML.parse(subject)
|
65
|
+
meta_xsd.validate(doc).each do |error|
|
66
|
+
error.message.should be_nil
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
40
71
|
context "for an empty model with no attributes or validations" do
|
41
72
|
subject { EmptyModel.to_xsd }
|
42
73
|
|
@@ -99,7 +130,7 @@ describe Schematic::Serializers::Xsd do
|
|
99
130
|
end
|
100
131
|
|
101
132
|
it "should include the additional method" do
|
102
|
-
|
133
|
+
xsd = generate_xsd_for_model(SomeModel) do
|
103
134
|
<<-XML
|
104
135
|
<xs:element name="id" minOccurs="0" maxOccurs="1">
|
105
136
|
<xs:complexType>
|
@@ -125,12 +156,68 @@ describe Schematic::Serializers::Xsd do
|
|
125
156
|
end
|
126
157
|
|
127
158
|
context "with a model with validations" do
|
159
|
+
subject { SomeModel.to_xsd }
|
160
|
+
|
128
161
|
context "presence of validation" do
|
162
|
+
|
129
163
|
context "when allow blank is true" do
|
164
|
+
with_model :some_model do
|
165
|
+
table :id => false do |t|
|
166
|
+
t.string "title"
|
167
|
+
end
|
130
168
|
|
169
|
+
model do
|
170
|
+
validate :title, :presence => true, :allow_blank => true
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
it "should mark that the field minimum occurrences is 0" do
|
175
|
+
xsd = generate_xsd_for_model(SomeModel) do
|
176
|
+
<<-XML
|
177
|
+
<xs:element name="title" minOccurs="0" maxOccurs="1">
|
178
|
+
<xs:complexType>
|
179
|
+
<xs:simpleContent>
|
180
|
+
<xs:extension base="xs:string">
|
181
|
+
<xs:attribute name="type" type="xs:string" use="optional"/>
|
182
|
+
</xs:extension>
|
183
|
+
</xs:simpleContent>
|
184
|
+
</xs:complexType>
|
185
|
+
</xs:element>
|
186
|
+
XML
|
187
|
+
end
|
188
|
+
|
189
|
+
subject.should == sanitize_xml(xsd)
|
190
|
+
end
|
131
191
|
end
|
132
192
|
|
133
193
|
context "when allow blank is false" do
|
194
|
+
with_model :some_model do
|
195
|
+
table :id => false do |t|
|
196
|
+
t.string "title"
|
197
|
+
end
|
198
|
+
|
199
|
+
model do
|
200
|
+
validates :title, :presence => true
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
it "should mark that the field minimum occurrences is 1" do
|
205
|
+
xsd = generate_xsd_for_model(SomeModel) do
|
206
|
+
<<-XML
|
207
|
+
<xs:element name="title" minOccurs="1" maxOccurs="1">
|
208
|
+
<xs:complexType>
|
209
|
+
<xs:simpleContent>
|
210
|
+
<xs:extension base="xs:string">
|
211
|
+
<xs:attribute name="type" type="xs:string" use="optional"/>
|
212
|
+
</xs:extension>
|
213
|
+
</xs:simpleContent>
|
214
|
+
</xs:complexType>
|
215
|
+
</xs:element>
|
216
|
+
XML
|
217
|
+
end
|
218
|
+
|
219
|
+
subject.should == sanitize_xml(xsd)
|
220
|
+
end
|
134
221
|
end
|
135
222
|
end
|
136
223
|
|
@@ -144,6 +231,52 @@ describe Schematic::Serializers::Xsd do
|
|
144
231
|
end
|
145
232
|
end
|
146
233
|
|
234
|
+
describe ".xsd_minimum_occurrences_for" do
|
235
|
+
|
236
|
+
context "given a column with no validations" do
|
237
|
+
with_model :some_model do
|
238
|
+
table :id => false do |t|
|
239
|
+
t.string "title"
|
240
|
+
end
|
241
|
+
model {}
|
242
|
+
end
|
243
|
+
|
244
|
+
it "should return 0" do
|
245
|
+
SomeModel.xsd_minimum_occurrences_for_column(SomeModel.columns.first).should == "0"
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
context "given a column with presence of but allow blank" do
|
250
|
+
with_model :some_model do
|
251
|
+
table :id => false do |t|
|
252
|
+
t.string "title"
|
253
|
+
end
|
254
|
+
model do
|
255
|
+
validates :title, :presence => true, :allow_blank => true
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
it "should return 0" do
|
260
|
+
SomeModel.xsd_minimum_occurrences_for_column(SomeModel.columns.first).should == "0"
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
context "given a column with presence of and no allow blank" do
|
265
|
+
with_model :some_model do
|
266
|
+
table :id => false do |t|
|
267
|
+
t.string "title"
|
268
|
+
end
|
269
|
+
model do
|
270
|
+
validates :title, :presence => true
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
it "should return 1" do
|
275
|
+
SomeModel.xsd_minimum_occurrences_for_column(SomeModel.columns.first).should == "1"
|
276
|
+
end
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
147
280
|
private
|
148
281
|
|
149
282
|
def sanitize_xml(xml)
|
@@ -154,18 +287,18 @@ describe Schematic::Serializers::Xsd do
|
|
154
287
|
<<-XML
|
155
288
|
<?xml version="1.0" encoding="UTF-8"?>
|
156
289
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
290
|
+
<xs:element name="#{model.xsd_element_collection_name}" type="#{model.xsd_type_collection_name}"/>
|
291
|
+
<xs:complexType name="#{model.xsd_type_collection_name}">
|
292
|
+
<xs:sequence>
|
293
|
+
<xs:element name="#{model.xsd_element_name}" type="#{model.xsd_type_name}" minOccurs="0" maxOccurs="unbounded"/>
|
294
|
+
</xs:sequence>
|
295
|
+
<xs:attribute name="type" type="xs:string" fixed="array"/>
|
296
|
+
</xs:complexType>
|
297
|
+
<xs:complexType name="#{model.xsd_type_name}">
|
298
|
+
<xs:all>
|
299
|
+
#{yield}
|
300
|
+
</xs:all>
|
301
|
+
</xs:complexType>
|
169
302
|
</xs:schema>
|
170
303
|
XML
|
171
304
|
end
|