schematic 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -1,3 +1,41 @@
1
1
  = Schematic
2
2
 
3
- Automatic schema generation.
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" => "0", "maxOccurs" => "1" do |field|
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
@@ -1,3 +1,3 @@
1
1
  module Schematic
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -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
- xsd = generate_xsd_for_model(SomeModel) do
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
- <xs:element name="#{model.xsd_element_collection_name}" type="#{model.xsd_type_collection_name}"/>
158
- <xs:complexType name="#{model.xsd_type_collection_name}">
159
- <xs:sequence>
160
- <xs:element name="#{model.xsd_element_name}" type="#{model.xsd_type_name}" minOccurs="0" maxOccurs="unbounded"/>
161
- </xs:sequence>
162
- <xs:attribute name="type" type="xs:string" fixed="array"/>
163
- </xs:complexType>
164
- <xs:complexType name="#{model.xsd_type_name}">
165
- <xs:all>
166
- #{yield}
167
- </xs:all>
168
- </xs:complexType>
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
data/spec/spec_helper.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require "active_record"
2
2
  require "with_model"
3
+ require "nokogiri"
3
4
  require "schematic"
4
5
 
5
6
  RSpec.configure do |config|