schematic 0.2.1 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
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
- Restrictions::Length.new(@klass, @column).generate(restriction)
20
- Restrictions::Enumeration.new(@klass, @column).generate(restriction)
21
- Restrictions::Pattern.new(@klass, @column).generate(restriction)
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 initialize(klass, column)
6
- @klass = klass
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
- @options = options
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 || nested_attribute.klass == klass.superclass
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
- Restrictions::Uniqueness.new(@klass, column).generate(builder)
83
+ Uniqueness.new(@klass, column).generate(builder)
76
84
  end
77
85
  end
78
86
 
@@ -1,3 +1,3 @@
1
1
  module Schematic
2
- VERSION = "0.2.1"
2
+ VERSION = "0.2.3"
3
3
  end
@@ -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
+
@@ -1,6 +1,6 @@
1
1
  require "spec_helper"
2
2
 
3
- describe Schematic::Generator::Restrictions::Uniqueness do
3
+ describe Schematic::Generator::Uniqueness do
4
4
  describe ".to_xsd" do
5
5
  context "with a model with a uniqueness validation" do
6
6
  subject { sanitize_xml(TestModel.to_xsd) }
@@ -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.1
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-05-25 00:00:00 Z
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/restrictions/uniqueness_spec.rb
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.7.2
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/restrictions/uniqueness_spec.rb
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
-