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