schematic 0.2.1 → 0.2.3
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/lib/schematic.rb +2 -1
- data/lib/schematic/generator/column.rb +9 -5
- data/lib/schematic/generator/column_validator.rb +25 -0
- data/lib/schematic/generator/restrictions/base.rb +3 -18
- data/lib/schematic/generator/uniqueness.rb +25 -0
- data/lib/schematic/generator/xsd.rb +12 -4
- data/lib/schematic/version.rb +1 -1
- data/spec/schematic/generator/restrictions/mixin_spec.rb +65 -0
- data/spec/schematic/generator/{restrictions/uniqueness_spec.rb → uniqueness_spec.rb} +1 -1
- data/spec/schematic_serializers_xsd_spec.rb +39 -0
- metadata +11 -6
- data/lib/schematic/generator/restrictions/uniqueness.rb +0 -26
data/lib/schematic.rb
CHANGED
@@ -9,7 +9,9 @@ module Schematic
|
|
9
9
|
autoload :Names, 'schematic/generator/names'
|
10
10
|
autoload :Namespaces, 'schematic/generator/namespaces'
|
11
11
|
autoload :Column, 'schematic/generator/column'
|
12
|
+
autoload :ColumnValidator, 'schematic/generator/column_validator'
|
12
13
|
autoload :Types, 'schematic/generator/types'
|
14
|
+
autoload :Uniqueness, 'schematic/generator/uniqueness'
|
13
15
|
|
14
16
|
module Restrictions
|
15
17
|
autoload :Base, 'schematic/generator/restrictions/base'
|
@@ -18,7 +20,6 @@ module Schematic
|
|
18
20
|
autoload :Length, 'schematic/generator/restrictions/length'
|
19
21
|
autoload :Pattern, 'schematic/generator/restrictions/pattern'
|
20
22
|
autoload :Numericality, 'schematic/generator/restrictions/numericality'
|
21
|
-
autoload :Uniqueness, 'schematic/generator/restrictions/uniqueness'
|
22
23
|
end
|
23
24
|
end
|
24
25
|
module Serializers
|
@@ -1,6 +1,12 @@
|
|
1
1
|
module Schematic
|
2
2
|
module Generator
|
3
3
|
class Column
|
4
|
+
attr_accessor :restriction_classes
|
5
|
+
class << self
|
6
|
+
def restriction_classes
|
7
|
+
@restriction_classes ||= [Restrictions::Length, Restrictions::Enumeration, Restrictions::Numericality, Restrictions::Pattern, Restrictions::Custom]
|
8
|
+
end
|
9
|
+
end
|
4
10
|
|
5
11
|
def initialize(klass, column, additional_methods = {}, ignored_methods = {})
|
6
12
|
@klass = klass
|
@@ -16,11 +22,9 @@ module Schematic
|
|
16
22
|
field.xs :complexType do |complex_type|
|
17
23
|
complex_type.xs :simpleContent do |simple_content|
|
18
24
|
simple_content.xs :restriction, "base" => map_type(@column) do |restriction|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
Restrictions::Numericality.new(@klass, @column).generate(restriction)
|
23
|
-
Restrictions::Custom.new(@klass, @column).generate(restriction)
|
25
|
+
self.class.restriction_classes.each do |restriction_class|
|
26
|
+
restriction_class.new(@klass, @column).generate(restriction)
|
27
|
+
end
|
24
28
|
end
|
25
29
|
end
|
26
30
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Schematic
|
2
|
+
module Generator
|
3
|
+
class ColumnValidator
|
4
|
+
attr_reader :klass, :column
|
5
|
+
|
6
|
+
def initialize(klass, column)
|
7
|
+
@klass = klass
|
8
|
+
@column = column
|
9
|
+
end
|
10
|
+
|
11
|
+
def for_validator(validator_klass)
|
12
|
+
validators_for_column.each do |column_validation|
|
13
|
+
next unless column_validation.is_a? validator_klass
|
14
|
+
next unless column_validation.options[:if].nil? || column_validation.options[:unless].nil?
|
15
|
+
yield(column_validation)
|
16
|
+
return
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def validators_for_column
|
21
|
+
klass._validators[column.name.to_sym]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -1,25 +1,10 @@
|
|
1
1
|
module Schematic
|
2
2
|
module Generator
|
3
3
|
module Restrictions
|
4
|
-
class Base
|
5
|
-
def
|
6
|
-
|
7
|
-
@column = column
|
4
|
+
class Base < Schematic::Generator::ColumnValidator
|
5
|
+
def self.inherited(klass)
|
6
|
+
Schematic::Generator::Column.restriction_classes << klass unless Schematic::Generator::Column.restriction_classes.include?(klass)
|
8
7
|
end
|
9
|
-
|
10
|
-
def for_validator(validator_klass)
|
11
|
-
validators_for_column.each do |column_validation|
|
12
|
-
next unless column_validation.is_a? validator_klass
|
13
|
-
next unless column_validation.options[:if].nil? || column_validation.options[:unless].nil?
|
14
|
-
yield(column_validation)
|
15
|
-
return
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def validators_for_column
|
20
|
-
@klass._validators[@column.name.to_sym]
|
21
|
-
end
|
22
|
-
|
23
8
|
end
|
24
9
|
end
|
25
10
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Schematic
|
2
|
+
module Generator
|
3
|
+
class Uniqueness < ColumnValidator
|
4
|
+
|
5
|
+
def generate(builder)
|
6
|
+
for_validator ActiveRecord::Validations::UniquenessValidator do |validator|
|
7
|
+
unique_name = validator.attributes.first.to_s.dasherize
|
8
|
+
additional_fields = (validator.options[:scope] || []).map(&:to_s).map(&:dasherize)
|
9
|
+
|
10
|
+
names = Schematic::Generator::Names.new(@klass)
|
11
|
+
builder.xs :unique, "name" => "#{unique_name}-must-be-unique" do |unique|
|
12
|
+
unique.xs :selector, "xpath" => "./#{names.element}"
|
13
|
+
unique.xs :field, "xpath" => unique_name
|
14
|
+
additional_fields.each do |additional_field|
|
15
|
+
unique.xs :field, "xpath" => additional_field
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
|
@@ -7,7 +7,13 @@ module Schematic
|
|
7
7
|
def initialize(klass, options = {})
|
8
8
|
@klass = klass
|
9
9
|
@names = Names.new(klass)
|
10
|
-
|
10
|
+
self.options = options
|
11
|
+
end
|
12
|
+
|
13
|
+
def options=(hash = {})
|
14
|
+
@options = {:generated_types => []}.merge(hash)
|
15
|
+
@options[:generated_types] << @klass unless @options[:generated_types].include?(@klass)
|
16
|
+
@options
|
11
17
|
end
|
12
18
|
|
13
19
|
def header(builder)
|
@@ -30,9 +36,11 @@ module Schematic
|
|
30
36
|
|
31
37
|
def generate(builder, klass)
|
32
38
|
nested_attributes.each do |nested_attribute|
|
33
|
-
next if nested_attribute.klass == klass
|
34
|
-
|
39
|
+
next if nested_attribute.klass == klass
|
40
|
+
next if nested_attribute.klass == klass.superclass
|
41
|
+
next if @options && @options[:generated_types] && @options[:generated_types].include?(klass)
|
35
42
|
nested_attribute.klass.generate_xsd(builder, klass, @options)
|
43
|
+
@options[:generated_types] << klass
|
36
44
|
end
|
37
45
|
|
38
46
|
generate_complex_type_for_collection(builder)
|
@@ -72,7 +80,7 @@ module Schematic
|
|
72
80
|
|
73
81
|
def generate_uniqueness_constraints(builder)
|
74
82
|
@klass.columns.each do |column|
|
75
|
-
|
83
|
+
Uniqueness.new(@klass, column).generate(builder)
|
76
84
|
end
|
77
85
|
end
|
78
86
|
|
data/lib/schematic/version.rb
CHANGED
@@ -0,0 +1,65 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "Schematic::Generator::Restrictions::Mixin" do
|
4
|
+
describe ".to_xsd" do
|
5
|
+
context "with a model with a mixed in restriction" do
|
6
|
+
before do
|
7
|
+
class MixedInRestriction < Schematic::Generator::Restrictions::Base
|
8
|
+
def generate(builder)
|
9
|
+
for_validator ActiveModel::BlockValidator do |validator|
|
10
|
+
builder.xs(:enumeration, "value" => "cheese")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
subject { sanitize_xml(TestModel.to_xsd) }
|
17
|
+
with_model :test_model do
|
18
|
+
table :id => false do |t|
|
19
|
+
t.string "title"
|
20
|
+
end
|
21
|
+
|
22
|
+
model do
|
23
|
+
validates_each :title do |object, attr, value|
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should validate against it's own XSD" do
|
29
|
+
invalid_instance = TestModel.new(:title => "cake")
|
30
|
+
xml = [invalid_instance].to_xml
|
31
|
+
lambda {
|
32
|
+
validate_xml_against_xsd(xml, subject)
|
33
|
+
}.should raise_error
|
34
|
+
valid_instance = TestModel.new(:title => "cheese")
|
35
|
+
xml = [valid_instance].to_xml
|
36
|
+
lambda {
|
37
|
+
validate_xml_against_xsd(xml, subject)
|
38
|
+
}.should_not raise_error
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should mark that the field with the allowed values" do
|
42
|
+
xsd = generate_xsd_for_model(TestModel) do
|
43
|
+
<<-XML
|
44
|
+
<xs:element name="title" minOccurs="0" maxOccurs="1">
|
45
|
+
<xs:complexType>
|
46
|
+
<xs:simpleContent>
|
47
|
+
<xs:restriction base="String">
|
48
|
+
<xs:enumeration value="cheese"/>
|
49
|
+
</xs:restriction>
|
50
|
+
</xs:simpleContent>
|
51
|
+
</xs:complexType>
|
52
|
+
</xs:element>
|
53
|
+
XML
|
54
|
+
end
|
55
|
+
|
56
|
+
subject.should == xsd
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
|
64
|
+
|
65
|
+
|
@@ -154,6 +154,45 @@ describe Schematic::Serializers::Xsd do
|
|
154
154
|
end
|
155
155
|
|
156
156
|
end
|
157
|
+
|
158
|
+
context "when the model has a nested reference that references another nested reference" do
|
159
|
+
with_model :blog do
|
160
|
+
table {}
|
161
|
+
model do
|
162
|
+
has_many :posts
|
163
|
+
has_many :readers
|
164
|
+
accepts_nested_attributes_for :posts
|
165
|
+
accepts_nested_attributes_for :readers
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
with_model :post do
|
170
|
+
table do |t|
|
171
|
+
t.integer :blog_id
|
172
|
+
end
|
173
|
+
|
174
|
+
model do
|
175
|
+
belongs_to :blog
|
176
|
+
has_many :readers
|
177
|
+
accepts_nested_attributes_for :blog
|
178
|
+
accepts_nested_attributes_for :readers
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
with_model :reader do
|
183
|
+
table do |t|
|
184
|
+
t.integer :blog_id
|
185
|
+
t.integer :post_id
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
subject { Post.to_xsd }
|
190
|
+
|
191
|
+
it "should generate a valid XSD" do
|
192
|
+
validate_xsd(subject)
|
193
|
+
end
|
194
|
+
|
195
|
+
end
|
157
196
|
end
|
158
197
|
|
159
198
|
context "for an empty model with no attributes or validations" do
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: schematic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.2.
|
5
|
+
version: 0.2.3
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Case Commons, LLC
|
@@ -10,7 +10,8 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-
|
13
|
+
date: 2011-06-01 00:00:00 -04:00
|
14
|
+
default_executable:
|
14
15
|
dependencies:
|
15
16
|
- !ruby/object:Gem::Dependency
|
16
17
|
name: activerecord
|
@@ -109,6 +110,7 @@ files:
|
|
109
110
|
- TODO
|
110
111
|
- lib/schematic.rb
|
111
112
|
- lib/schematic/generator/column.rb
|
113
|
+
- lib/schematic/generator/column_validator.rb
|
112
114
|
- lib/schematic/generator/names.rb
|
113
115
|
- lib/schematic/generator/namespaces.rb
|
114
116
|
- lib/schematic/generator/restrictions/base.rb
|
@@ -117,8 +119,8 @@ files:
|
|
117
119
|
- lib/schematic/generator/restrictions/length.rb
|
118
120
|
- lib/schematic/generator/restrictions/numericality.rb
|
119
121
|
- lib/schematic/generator/restrictions/pattern.rb
|
120
|
-
- lib/schematic/generator/restrictions/uniqueness.rb
|
121
122
|
- lib/schematic/generator/types.rb
|
123
|
+
- lib/schematic/generator/uniqueness.rb
|
122
124
|
- lib/schematic/generator/xsd.rb
|
123
125
|
- lib/schematic/serializers/xsd.rb
|
124
126
|
- lib/schematic/version.rb
|
@@ -126,9 +128,10 @@ files:
|
|
126
128
|
- spec/schematic/generator/restrictions/custom_spec.rb
|
127
129
|
- spec/schematic/generator/restrictions/enumeration_spec.rb
|
128
130
|
- spec/schematic/generator/restrictions/length_spec.rb
|
131
|
+
- spec/schematic/generator/restrictions/mixin_spec.rb
|
129
132
|
- spec/schematic/generator/restrictions/numericality_spec.rb
|
130
133
|
- spec/schematic/generator/restrictions/pattern_spec.rb
|
131
|
-
- spec/schematic/generator/
|
134
|
+
- spec/schematic/generator/uniqueness_spec.rb
|
132
135
|
- spec/schematic/serializers/xsd_extend_spec.rb
|
133
136
|
- spec/schematic/serializers/xsd_validation_presence_spec.rb
|
134
137
|
- spec/schematic/serializers/xsd_xsd_ignore_methods_spec.rb
|
@@ -138,6 +141,7 @@ files:
|
|
138
141
|
- spec/spec_helper.rb
|
139
142
|
- spec/xsd/XMLSchema.xsd
|
140
143
|
- spec/xsd/xml.xsd
|
144
|
+
has_rdoc: true
|
141
145
|
homepage: https://github.com/Casecommons/schematic
|
142
146
|
licenses: []
|
143
147
|
|
@@ -161,7 +165,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
161
165
|
requirements: []
|
162
166
|
|
163
167
|
rubyforge_project: schematic
|
164
|
-
rubygems_version: 1.
|
168
|
+
rubygems_version: 1.6.2
|
165
169
|
signing_key:
|
166
170
|
specification_version: 3
|
167
171
|
summary: Automatic XSD generation from ActiveRecord models
|
@@ -169,9 +173,10 @@ test_files:
|
|
169
173
|
- spec/schematic/generator/restrictions/custom_spec.rb
|
170
174
|
- spec/schematic/generator/restrictions/enumeration_spec.rb
|
171
175
|
- spec/schematic/generator/restrictions/length_spec.rb
|
176
|
+
- spec/schematic/generator/restrictions/mixin_spec.rb
|
172
177
|
- spec/schematic/generator/restrictions/numericality_spec.rb
|
173
178
|
- spec/schematic/generator/restrictions/pattern_spec.rb
|
174
|
-
- spec/schematic/generator/
|
179
|
+
- spec/schematic/generator/uniqueness_spec.rb
|
175
180
|
- spec/schematic/serializers/xsd_extend_spec.rb
|
176
181
|
- spec/schematic/serializers/xsd_validation_presence_spec.rb
|
177
182
|
- spec/schematic/serializers/xsd_xsd_ignore_methods_spec.rb
|
@@ -1,26 +0,0 @@
|
|
1
|
-
module Schematic
|
2
|
-
module Generator
|
3
|
-
module Restrictions
|
4
|
-
class Uniqueness < Base
|
5
|
-
def generate(builder)
|
6
|
-
for_validator ActiveRecord::Validations::UniquenessValidator do |validator|
|
7
|
-
unique_name = validator.attributes.first.to_s.dasherize
|
8
|
-
additional_fields = (validator.options[:scope] || []).map(&:to_s).map(&:dasherize)
|
9
|
-
|
10
|
-
names = Schematic::Generator::Names.new(@klass)
|
11
|
-
builder.xs :unique, "name" => "#{unique_name}-must-be-unique" do |unique|
|
12
|
-
unique.xs :selector, "xpath" => "./#{names.element}"
|
13
|
-
unique.xs :field, "xpath" => unique_name
|
14
|
-
additional_fields.each do |additional_field|
|
15
|
-
unique.xs :field, "xpath" => additional_field
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
|
26
|
-
|