schematic 0.0.8 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
data/lib/schematic/version.rb
CHANGED
data/schematic.gemspec
CHANGED
@@ -20,6 +20,7 @@ Gem::Specification.new do |s|
|
|
20
20
|
s.add_development_dependency('with_model')
|
21
21
|
s.add_development_dependency('nokogiri')
|
22
22
|
s.add_development_dependency('sqlite3')
|
23
|
+
s.add_development_dependency('autotest')
|
23
24
|
|
24
25
|
s.files = `git ls-files`.split("\n")
|
25
26
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Schematic::Generator::Restrictions::Enumeration do
|
4
|
+
describe ".to_xsd" do
|
5
|
+
context "with a model with inclusion validations" do
|
6
|
+
subject { sanitize_xml(EnumerationModel.to_xsd) }
|
7
|
+
with_model :enumeration_model do
|
8
|
+
table :id => false do |t|
|
9
|
+
t.string "title"
|
10
|
+
end
|
11
|
+
|
12
|
+
model do
|
13
|
+
validates :title, :inclusion => { :in => ["a", "b", "c"] }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should validate against it's own XSD" do
|
18
|
+
invalid_instance = EnumerationModel.new(:title => "d")
|
19
|
+
xml = [invalid_instance].to_xml
|
20
|
+
lambda {
|
21
|
+
validate_xml_against_xsd(xml, subject)
|
22
|
+
}.should raise_error
|
23
|
+
valid_instance = EnumerationModel.new(:title => "a")
|
24
|
+
xml = [valid_instance].to_xml
|
25
|
+
lambda {
|
26
|
+
validate_xml_against_xsd(xml, subject)
|
27
|
+
}.should_not raise_error
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should mark that the field with the allowed values" do
|
31
|
+
xsd = generate_xsd_for_model(EnumerationModel) do
|
32
|
+
<<-XML
|
33
|
+
<xs:element name="title" minOccurs="0" maxOccurs="1">
|
34
|
+
<xs:complexType>
|
35
|
+
<xs:simpleContent>
|
36
|
+
<xs:restriction base="String">
|
37
|
+
<xs:enumeration value="a"/>
|
38
|
+
<xs:enumeration value="b"/>
|
39
|
+
<xs:enumeration value="c"/>
|
40
|
+
</xs:restriction>
|
41
|
+
</xs:simpleContent>
|
42
|
+
</xs:complexType>
|
43
|
+
</xs:element>
|
44
|
+
XML
|
45
|
+
end
|
46
|
+
|
47
|
+
subject.should == xsd
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
|
@@ -0,0 +1,181 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Schematic::Generator::Restrictions::Length do
|
4
|
+
describe ".to_xsd" do
|
5
|
+
context "with a model with range length validations" do
|
6
|
+
subject { sanitize_xml(LengthModelRange.to_xsd) }
|
7
|
+
with_model :length_model_range do
|
8
|
+
table :id => false do |t|
|
9
|
+
t.string "title"
|
10
|
+
end
|
11
|
+
|
12
|
+
model do
|
13
|
+
validates :title, :length => { :within => 10..20 }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should validate against it's own XSD" do
|
18
|
+
invalid_instance = LengthModelRange.new(:title => "A" * 9)
|
19
|
+
xml = [invalid_instance].to_xml
|
20
|
+
lambda {
|
21
|
+
validate_xml_against_xsd(xml, subject)
|
22
|
+
}.should raise_error
|
23
|
+
invalid_instance = LengthModelRange.new(:title => "A" * 21)
|
24
|
+
xml = [invalid_instance].to_xml
|
25
|
+
lambda {
|
26
|
+
validate_xml_against_xsd(xml, subject)
|
27
|
+
}.should raise_error
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context "with a model with using the range alias length validations" do
|
32
|
+
subject { sanitize_xml(LengthModelRange.to_xsd) }
|
33
|
+
with_model :length_model_range do
|
34
|
+
table :id => false do |t|
|
35
|
+
t.string "title"
|
36
|
+
end
|
37
|
+
|
38
|
+
model do
|
39
|
+
validates :title, :length => { :in => 10..20 }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should validate against it's own XSD" do
|
44
|
+
invalid_instance = LengthModelRange.new(:title => "A" * 9)
|
45
|
+
xml = [invalid_instance].to_xml
|
46
|
+
lambda {
|
47
|
+
validate_xml_against_xsd(xml, subject)
|
48
|
+
}.should raise_error
|
49
|
+
invalid_instance = LengthModelRange.new(:title => "A" * 21)
|
50
|
+
xml = [invalid_instance].to_xml
|
51
|
+
lambda {
|
52
|
+
validate_xml_against_xsd(xml, subject)
|
53
|
+
}.should raise_error
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context "with a model with minimum length validations" do
|
58
|
+
subject { sanitize_xml(LengthModelMinimum.to_xsd) }
|
59
|
+
with_model :length_model_minimum do
|
60
|
+
table :id => false do |t|
|
61
|
+
t.string "title"
|
62
|
+
end
|
63
|
+
|
64
|
+
model do
|
65
|
+
validates :title, :length => { :minimum => 10 }
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should validate against it's own XSD" do
|
70
|
+
invalid_instance = LengthModelMinimum.new(:title => "A" * 9)
|
71
|
+
xml = [invalid_instance].to_xml
|
72
|
+
lambda {
|
73
|
+
validate_xml_against_xsd(xml, subject)
|
74
|
+
}.should raise_error
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context "with a model with maximum length validations" do
|
79
|
+
subject { sanitize_xml(LengthModelOne.to_xsd) }
|
80
|
+
context "when allow blank is true" do
|
81
|
+
with_model :length_model_one do
|
82
|
+
table :id => false do |t|
|
83
|
+
t.string "title"
|
84
|
+
end
|
85
|
+
|
86
|
+
model do
|
87
|
+
validates :title, :length => { :maximum => 100 }, :allow_blank => true
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should validate against it's own XSD" do
|
92
|
+
invalid_instance = LengthModelOne.new(:title => "A" * 201)
|
93
|
+
xml = [invalid_instance].to_xml
|
94
|
+
lambda {
|
95
|
+
validate_xml_against_xsd(xml, subject)
|
96
|
+
}.should raise_error
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should mark that the field minimum occurrences is 0 but still list the length" do
|
100
|
+
xsd = generate_xsd_for_model(LengthModelOne) do
|
101
|
+
<<-XML
|
102
|
+
<xs:element name="title" minOccurs="0" maxOccurs="1">
|
103
|
+
<xs:complexType>
|
104
|
+
<xs:simpleContent>
|
105
|
+
<xs:restriction base="String">
|
106
|
+
<xs:maxLength value="100"/>
|
107
|
+
</xs:restriction>
|
108
|
+
</xs:simpleContent>
|
109
|
+
</xs:complexType>
|
110
|
+
</xs:element>
|
111
|
+
XML
|
112
|
+
end
|
113
|
+
|
114
|
+
subject.should == xsd
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
context "when allow blank is false" do
|
119
|
+
subject { sanitize_xml(LengthModelTwo.to_xsd) }
|
120
|
+
with_model :length_model_two do
|
121
|
+
table :id => false do |t|
|
122
|
+
t.string "title"
|
123
|
+
end
|
124
|
+
|
125
|
+
model do
|
126
|
+
validates :title, :length => { :maximum => 100 }, :allow_blank => false
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
it "should mark that the field maximum length to 100" do
|
131
|
+
xsd = generate_xsd_for_model(LengthModelTwo) do
|
132
|
+
<<-XML
|
133
|
+
<xs:element name="title" minOccurs="0" maxOccurs="1">
|
134
|
+
<xs:complexType>
|
135
|
+
<xs:simpleContent>
|
136
|
+
<xs:restriction base="String">
|
137
|
+
<xs:maxLength value="100"/>
|
138
|
+
</xs:restriction>
|
139
|
+
</xs:simpleContent>
|
140
|
+
</xs:complexType>
|
141
|
+
</xs:element>
|
142
|
+
XML
|
143
|
+
end
|
144
|
+
|
145
|
+
subject.should == xsd
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
context "when there is a condition" do
|
150
|
+
subject { sanitize_xml(LengthModelThree.to_xsd) }
|
151
|
+
with_model :length_model_three do
|
152
|
+
table :id => false do |t|
|
153
|
+
t.string "title"
|
154
|
+
end
|
155
|
+
|
156
|
+
model do
|
157
|
+
validates :title, :length => { :maximum => 100 }, :if => lambda { |model| false }
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
it "should not record the max length" do
|
162
|
+
xsd = generate_xsd_for_model(LengthModelThree) do
|
163
|
+
<<-XML
|
164
|
+
<xs:element name="title" minOccurs="0" maxOccurs="1">
|
165
|
+
<xs:complexType>
|
166
|
+
<xs:simpleContent>
|
167
|
+
<xs:restriction base="String">
|
168
|
+
</xs:restriction>
|
169
|
+
</xs:simpleContent>
|
170
|
+
</xs:complexType>
|
171
|
+
</xs:element>
|
172
|
+
XML
|
173
|
+
end
|
174
|
+
|
175
|
+
subject.should == xsd
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Schematic::Generator::Restrictions::Enumeration do
|
4
|
+
describe ".to_xsd" do
|
5
|
+
context "with a model with format validations" do
|
6
|
+
subject { sanitize_xml(PatternModel.to_xsd) }
|
7
|
+
with_model :pattern_model do
|
8
|
+
table :id => false do |t|
|
9
|
+
t.string "title"
|
10
|
+
end
|
11
|
+
|
12
|
+
model do
|
13
|
+
validates :title, :format => { :with => /[a-z]#[0-9]/ }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should validate against it's own XSD" do
|
18
|
+
invalid_instance = PatternModel.new(:title => "1-2")
|
19
|
+
xml = [invalid_instance].to_xml
|
20
|
+
lambda {
|
21
|
+
validate_xml_against_xsd(xml, subject)
|
22
|
+
}.should raise_error
|
23
|
+
valid_instance = PatternModel.new(:title => "a#5")
|
24
|
+
xml = [valid_instance].to_xml
|
25
|
+
lambda {
|
26
|
+
validate_xml_against_xsd(xml, subject)
|
27
|
+
}.should_not raise_error
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should mark that the field with the allowed values" do
|
31
|
+
xsd = generate_xsd_for_model(PatternModel) do
|
32
|
+
<<-XML
|
33
|
+
<xs:element name="title" minOccurs="0" maxOccurs="1">
|
34
|
+
<xs:complexType>
|
35
|
+
<xs:simpleContent>
|
36
|
+
<xs:restriction base="String">
|
37
|
+
<xs:pattern value="[a-z]#[0-9]"/>
|
38
|
+
</xs:restriction>
|
39
|
+
</xs:simpleContent>
|
40
|
+
</xs:complexType>
|
41
|
+
</xs:element>
|
42
|
+
XML
|
43
|
+
end
|
44
|
+
|
45
|
+
subject.should == xsd
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Schematic::Serializers::Xsd do
|
4
|
+
before do
|
5
|
+
class EmptyModel < ActiveRecord::Base
|
6
|
+
def self.columns
|
7
|
+
[]
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe ".extend" do
|
13
|
+
context "when the model inherits ActiveRecord::Base" do
|
14
|
+
subject { EmptyModel }
|
15
|
+
|
16
|
+
it "should allow the model to be extended" do
|
17
|
+
lambda {
|
18
|
+
subject.class_eval do
|
19
|
+
extend Schematic::Serializers::Xsd
|
20
|
+
end
|
21
|
+
}.should_not raise_error
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context "when the model does not inherit ActiveRecord::Base" do
|
26
|
+
subject { Object }
|
27
|
+
|
28
|
+
it "should raise an exception" do
|
29
|
+
lambda {
|
30
|
+
subject.class_eval do
|
31
|
+
extend Schematic::Serializers::Xsd
|
32
|
+
end
|
33
|
+
}.should raise_error(Schematic::InvalidClass)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Schematic::Serializers::Xsd do
|
4
|
+
describe ".to_xsd" do
|
5
|
+
context "with a model with presence of validations" do
|
6
|
+
subject { sanitize_xml(SomeModel.to_xsd) }
|
7
|
+
context "when allow blank is true" do
|
8
|
+
with_model :some_model do
|
9
|
+
table :id => false do |t|
|
10
|
+
t.string "title"
|
11
|
+
end
|
12
|
+
|
13
|
+
model do
|
14
|
+
validate :title, :presence => true, :allow_blank => true
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should mark that the field minimum occurrences is 0" do
|
19
|
+
xsd = generate_xsd_for_model(SomeModel) do
|
20
|
+
<<-XML
|
21
|
+
<xs:element name="title" minOccurs="0" maxOccurs="1">
|
22
|
+
<xs:complexType>
|
23
|
+
<xs:simpleContent>
|
24
|
+
<xs:restriction base="String">
|
25
|
+
</xs:restriction>
|
26
|
+
</xs:simpleContent>
|
27
|
+
</xs:complexType>
|
28
|
+
</xs:element>
|
29
|
+
XML
|
30
|
+
end
|
31
|
+
|
32
|
+
subject.should == xsd
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context "when allow blank is false" do
|
37
|
+
with_model :some_model do
|
38
|
+
table :id => false do |t|
|
39
|
+
t.string "title"
|
40
|
+
end
|
41
|
+
|
42
|
+
model do
|
43
|
+
validates :title, :presence => true
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should mark that the field minimum occurrences is 1" do
|
48
|
+
xsd = generate_xsd_for_model(SomeModel) do
|
49
|
+
<<-XML
|
50
|
+
<xs:element name="title" minOccurs="1" maxOccurs="1">
|
51
|
+
<xs:complexType>
|
52
|
+
<xs:simpleContent>
|
53
|
+
<xs:restriction base="String">
|
54
|
+
</xs:restriction>
|
55
|
+
</xs:simpleContent>
|
56
|
+
</xs:complexType>
|
57
|
+
</xs:element>
|
58
|
+
XML
|
59
|
+
end
|
60
|
+
|
61
|
+
subject.should == xsd
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context "when there is a condition" do
|
66
|
+
with_model :some_model do
|
67
|
+
table :id => false do |t|
|
68
|
+
t.string "title"
|
69
|
+
end
|
70
|
+
|
71
|
+
model do
|
72
|
+
validates :title, :presence => true, :if => lambda { |model| false }
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should mark that the field minimum occurrences is 0" do
|
77
|
+
xsd = generate_xsd_for_model(SomeModel) do
|
78
|
+
<<-XML
|
79
|
+
<xs:element name="title" minOccurs="0" maxOccurs="1">
|
80
|
+
<xs:complexType>
|
81
|
+
<xs:simpleContent>
|
82
|
+
<xs:restriction base="String">
|
83
|
+
</xs:restriction>
|
84
|
+
</xs:simpleContent>
|
85
|
+
</xs:complexType>
|
86
|
+
</xs:element>
|
87
|
+
XML
|
88
|
+
end
|
89
|
+
|
90
|
+
subject.should == xsd
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Schematic::Serializers::Xsd do
|
4
|
+
describe ".xsd_ignore_methods" do
|
5
|
+
with_model :some_model do
|
6
|
+
table :id => false do |t|
|
7
|
+
t.string :title
|
8
|
+
end
|
9
|
+
|
10
|
+
model do
|
11
|
+
def self.xsd_ignore_methods
|
12
|
+
[:title]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should exclude the methods" do
|
18
|
+
xsd = generate_xsd_for_model(SomeModel) do
|
19
|
+
end
|
20
|
+
|
21
|
+
sanitize_xml(SomeModel.to_xsd).should eq(xsd)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|