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
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
|