schematic 0.3.5 → 0.3.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -5,10 +5,17 @@ module Schematic
5
5
  def generate(builder)
6
6
  for_validator ActiveModel::Validations::InclusionValidator do |validator|
7
7
  next if column.type == :boolean
8
+ next if validator.options[:in].respond_to?(:call)
8
9
  validator.options[:in].each do |value|
9
10
  builder.xs(:enumeration, "value" => value)
10
11
  end
11
12
  end
13
+ enumeration_method = "xsd_#{column.name}_enumeration_restrictions".to_sym
14
+ if klass.respond_to? enumeration_method
15
+ klass.send(enumeration_method).each do |enumeration|
16
+ builder.xs(:enumeration, "value" => enumeration)
17
+ end
18
+ end
12
19
  end
13
20
  end
14
21
  end
@@ -88,7 +88,7 @@ module Schematic
88
88
  end
89
89
  end
90
90
 
91
- def generate_sequence_value_restrictions(builder, value)
91
+ def generate_inclusion_value_restrictions(builder, value)
92
92
  enumeration_method = "xsd_#{value}_enumeration_restrictions".to_sym
93
93
  builder.xs :complexType do |complex_type|
94
94
  complex_type.xs :simpleContent do |simple_content|
@@ -114,7 +114,7 @@ module Schematic
114
114
  if values.present?
115
115
  values.each do |value|
116
116
  nested_sequence.xs :element, "name" => value.to_s.dasherize, "minOccurs" => "0", "maxOccurs" => "unbounded" do |sequence_element|
117
- generate_sequence_value_restrictions(sequence_element, value)
117
+ generate_inclusion_value_restrictions(sequence_element, value)
118
118
  end
119
119
  end
120
120
  else
@@ -1,3 +1,3 @@
1
1
  module Schematic
2
- VERSION = "0.3.5"
2
+ VERSION = "0.3.6"
3
3
  end
@@ -1,4 +1,5 @@
1
1
  require "spec_helper"
2
+ require "support/extensions/active_model/validations/inclusion"
2
3
 
3
4
  describe Schematic::Generator::Restrictions::Enumeration do
4
5
  describe ".to_xsd" do
@@ -8,11 +9,13 @@ describe Schematic::Generator::Restrictions::Enumeration do
8
9
  table :id => false do |t|
9
10
  t.string "title"
10
11
  t.boolean "active"
12
+ t.string "options"
11
13
  end
12
14
 
13
15
  model do
14
16
  validates :title, :inclusion => { :in => ["a", "b", "c"] }
15
17
  validates :active, :inclusion => { :in => [true, false] }
18
+ validates :options, :inclusion => { :in => lambda { |f| ["some valid attribute"] } }
16
19
  end
17
20
  end
18
21
 
@@ -22,7 +25,7 @@ describe Schematic::Generator::Restrictions::Enumeration do
22
25
  lambda {
23
26
  validate_xml_against_xsd(xml, subject)
24
27
  }.should raise_error
25
- valid_instance = EnumerationModel.new(:title => "a", :active => true)
28
+ valid_instance = EnumerationModel.new(:title => "a", :active => true, :options => "some valid attribute")
26
29
  xml = [valid_instance].to_xml
27
30
  lambda {
28
31
  validate_xml_against_xsd(xml, subject)
@@ -51,6 +54,14 @@ describe Schematic::Generator::Restrictions::Enumeration do
51
54
  </xs:simpleContent>
52
55
  </xs:complexType>
53
56
  </xs:element>
57
+ <xs:element name="options" minOccurs="0" maxOccurs="1">
58
+ <xs:complexType>
59
+ <xs:simpleContent>
60
+ <xs:restriction base="String">
61
+ </xs:restriction>
62
+ </xs:simpleContent>
63
+ </xs:complexType>
64
+ </xs:element>
54
65
  XML
55
66
  end
56
67
 
@@ -109,6 +109,71 @@ describe Schematic::Serializers::Xsd do
109
109
  end
110
110
  end
111
111
 
112
+ context "given a singular enumeration restriction" do
113
+ with_model :some_model do
114
+ table {}
115
+
116
+ model do
117
+
118
+ attr_accessor :bar
119
+
120
+ def self.xsd_bar_enumeration_restrictions
121
+ ["a", "b", "c"]
122
+ end
123
+
124
+ def self.xsd_methods
125
+ {:bar => nil}
126
+ end
127
+
128
+ def to_xml(options = {})
129
+ super({:methods => [:bar]}.merge(options))
130
+ end
131
+ end
132
+ end
133
+
134
+ it "should include the additional methods" do
135
+ xsd = generate_xsd_for_model(SomeModel) do
136
+ <<-XML
137
+ <xs:element name="id" minOccurs="0" maxOccurs="1">
138
+ <xs:complexType>
139
+ <xs:simpleContent>
140
+ <xs:restriction base="Integer">
141
+ </xs:restriction>
142
+ </xs:simpleContent>
143
+ </xs:complexType>
144
+ </xs:element>
145
+ <xs:element name="bar" minOccurs="0" maxOccurs="1">
146
+ <xs:complexType>
147
+ <xs:simpleContent>
148
+ <xs:restriction base="String">
149
+ <xs:enumeration value="a"/>
150
+ <xs:enumeration value="b"/>
151
+ <xs:enumeration value="c"/>
152
+ </xs:restriction>
153
+ </xs:simpleContent>
154
+ </xs:complexType>
155
+ </xs:element>
156
+ XML
157
+ end
158
+ sanitize_xml(SomeModel.to_xsd).should eq(xsd)
159
+ end
160
+
161
+ it "should validate against the xsd" do
162
+ xsd = SomeModel.to_xsd
163
+
164
+ invalid_instance = SomeModel.new(:bar => "invalid option")
165
+ xml = [invalid_instance].to_xml
166
+ lambda {
167
+ validate_xml_against_xsd(xml, xsd)
168
+ }.should raise_error
169
+ valid_instance = SomeModel.new(:bar => "b")
170
+ xml = [valid_instance].to_xml
171
+ lambda {
172
+ validate_xml_against_xsd(xml, xsd)
173
+ }.should_not raise_error
174
+ end
175
+ end
176
+
112
177
  context "given a an array of methods" do
113
178
  with_model :some_model do
114
179
  table {}
@@ -0,0 +1,70 @@
1
+ #This backports Rails 3.1 lambda inclusion behavior for Rails 3.
2
+ require 'active_support/core_ext/range'
3
+
4
+ module ActiveModel
5
+
6
+ # == Active Model Inclusion Validator
7
+ module Validations
8
+ class InclusionValidator < EachValidator
9
+ ERROR_MESSAGE = "An object with the method #include? or a proc or lambda is required, " <<
10
+ "and must be supplied as the :in option of the configuration hash"
11
+
12
+ def check_validity!
13
+ unless [:include?, :call].any?{ |method| options[:in].respond_to?(method) }
14
+ raise ArgumentError, ERROR_MESSAGE
15
+ end
16
+ end
17
+
18
+ def validate_each(record, attribute, value)
19
+ delimiter = options[:in]
20
+ exclusions = delimiter.respond_to?(:call) ? delimiter.call(record) : delimiter
21
+ unless exclusions.send(inclusion_method(exclusions), value)
22
+ record.errors.add(attribute, :inclusion, options.except(:in).merge!(:value => value))
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ # In Ruby 1.9 <tt>Range#include?</tt> on non-numeric ranges checks all possible values in the
29
+ # range for equality, so it may be slow for large ranges. The new <tt>Range#cover?</tt>
30
+ # uses the previous logic of comparing a value with the range endpoints.
31
+ def inclusion_method(enumerable)
32
+ enumerable.is_a?(Range) ? :cover? : :include?
33
+ end
34
+ end
35
+
36
+ module HelperMethods
37
+ # Validates whether the value of the specified attribute is available in a particular enumerable object.
38
+ #
39
+ # class Person < ActiveRecord::Base
40
+ # validates_inclusion_of :gender, :in => %w( m f )
41
+ # validates_inclusion_of :age, :in => 0..99
42
+ # validates_inclusion_of :format, :in => %w( jpg gif png ), :message => "extension %{value} is not included in the list"
43
+ # validates_inclusion_of :states, :in => lambda{ |person| STATES[person.country] }
44
+ # end
45
+ #
46
+ # Configuration options:
47
+ # * <tt>:in</tt> - An enumerable object of available items. This can be
48
+ # supplied as a proc or lambda which returns an enumerable. If the enumerable
49
+ # is a range the test is performed with <tt>Range#cover?</tt>
50
+ # (backported in Active Support for 1.8), otherwise with <tt>include?</tt>.
51
+ # * <tt>:message</tt> - Specifies a custom error message (default is: "is not included in the list").
52
+ # * <tt>:allow_nil</tt> - If set to true, skips this validation if the attribute is +nil+ (default is +false+).
53
+ # * <tt>:allow_blank</tt> - If set to true, skips this validation if the attribute is blank (default is +false+).
54
+ # * <tt>:on</tt> - Specifies when this validation is active. Runs in all
55
+ # validation contexts by default (+nil+), other options are <tt>:create</tt>
56
+ # and <tt>:update</tt>.
57
+ # * <tt>:if</tt> - Specifies a method, proc or string to call to determine if the validation should
58
+ # occur (e.g. <tt>:if => :allow_validation</tt>, or <tt>:if => Proc.new { |user| user.signup_step > 2 }</tt>). The
59
+ # method, proc or string should return or evaluate to a true or false value.
60
+ # * <tt>:unless</tt> - Specifies a method, proc or string to call to determine if the validation should
61
+ # not occur (e.g. <tt>:unless => :skip_validation</tt>, or <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>). The
62
+ # method, proc or string should return or evaluate to a true or false value.
63
+ def validates_inclusion_of(*attr_names)
64
+ validates_with InclusionValidator, _merge_attributes(attr_names)
65
+ end
66
+ end
67
+ end
68
+ end
69
+
70
+
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: schematic
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.3.5
5
+ version: 0.3.6
6
6
  platform: ruby
7
7
  authors:
8
8
  - Case Commons, LLC
@@ -10,12 +10,11 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-06-30 00:00:00 -04:00
13
+ date: 2011-07-26 00:00:00 -04:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: activerecord
18
- prerelease: false
19
18
  requirement: &id001 !ruby/object:Gem::Requirement
20
19
  none: false
21
20
  requirements:
@@ -23,10 +22,10 @@ dependencies:
23
22
  - !ruby/object:Gem::Version
24
23
  version: 3.0.0
25
24
  type: :runtime
25
+ prerelease: false
26
26
  version_requirements: *id001
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: builder
29
- prerelease: false
30
29
  requirement: &id002 !ruby/object:Gem::Requirement
31
30
  none: false
32
31
  requirements:
@@ -34,10 +33,10 @@ dependencies:
34
33
  - !ruby/object:Gem::Version
35
34
  version: "0"
36
35
  type: :runtime
36
+ prerelease: false
37
37
  version_requirements: *id002
38
38
  - !ruby/object:Gem::Dependency
39
39
  name: rspec-rails
40
- prerelease: false
41
40
  requirement: &id003 !ruby/object:Gem::Requirement
42
41
  none: false
43
42
  requirements:
@@ -45,10 +44,10 @@ dependencies:
45
44
  - !ruby/object:Gem::Version
46
45
  version: "2.1"
47
46
  type: :development
47
+ prerelease: false
48
48
  version_requirements: *id003
49
49
  - !ruby/object:Gem::Dependency
50
50
  name: with_model
51
- prerelease: false
52
51
  requirement: &id004 !ruby/object:Gem::Requirement
53
52
  none: false
54
53
  requirements:
@@ -56,10 +55,10 @@ dependencies:
56
55
  - !ruby/object:Gem::Version
57
56
  version: "0"
58
57
  type: :development
58
+ prerelease: false
59
59
  version_requirements: *id004
60
60
  - !ruby/object:Gem::Dependency
61
61
  name: nokogiri
62
- prerelease: false
63
62
  requirement: &id005 !ruby/object:Gem::Requirement
64
63
  none: false
65
64
  requirements:
@@ -67,10 +66,10 @@ dependencies:
67
66
  - !ruby/object:Gem::Version
68
67
  version: "0"
69
68
  type: :development
69
+ prerelease: false
70
70
  version_requirements: *id005
71
71
  - !ruby/object:Gem::Dependency
72
72
  name: sqlite3
73
- prerelease: false
74
73
  requirement: &id006 !ruby/object:Gem::Requirement
75
74
  none: false
76
75
  requirements:
@@ -78,10 +77,10 @@ dependencies:
78
77
  - !ruby/object:Gem::Version
79
78
  version: "0"
80
79
  type: :development
80
+ prerelease: false
81
81
  version_requirements: *id006
82
82
  - !ruby/object:Gem::Dependency
83
83
  name: autotest
84
- prerelease: false
85
84
  requirement: &id007 !ruby/object:Gem::Requirement
86
85
  none: false
87
86
  requirements:
@@ -89,6 +88,7 @@ dependencies:
89
88
  - !ruby/object:Gem::Version
90
89
  version: "0"
91
90
  type: :development
91
+ prerelease: false
92
92
  version_requirements: *id007
93
93
  description: Automatic XSD generation from ActiveRecord models
94
94
  email:
@@ -139,6 +139,7 @@ files:
139
139
  - spec/schematic/serializers/xsd_xsd_minimum_occurrences_for_spec.rb
140
140
  - spec/schematic_serializers_xsd_spec.rb
141
141
  - spec/spec_helper.rb
142
+ - spec/support/extensions/active_model/validations/inclusion.rb
142
143
  - spec/xsd/XMLSchema.xsd
143
144
  - spec/xsd/xml.xsd
144
145
  has_rdoc: true
@@ -155,12 +156,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
155
156
  requirements:
156
157
  - - ">="
157
158
  - !ruby/object:Gem::Version
159
+ hash: -515081018085257419
160
+ segments:
161
+ - 0
158
162
  version: "0"
159
163
  required_rubygems_version: !ruby/object:Gem::Requirement
160
164
  none: false
161
165
  requirements:
162
166
  - - ">="
163
167
  - !ruby/object:Gem::Version
168
+ hash: -515081018085257419
169
+ segments:
170
+ - 0
164
171
  version: "0"
165
172
  requirements: []
166
173
 
@@ -184,5 +191,6 @@ test_files:
184
191
  - spec/schematic/serializers/xsd_xsd_minimum_occurrences_for_spec.rb
185
192
  - spec/schematic_serializers_xsd_spec.rb
186
193
  - spec/spec_helper.rb
194
+ - spec/support/extensions/active_model/validations/inclusion.rb
187
195
  - spec/xsd/XMLSchema.xsd
188
196
  - spec/xsd/xml.xsd