mv-postgresql 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Valeriy Prokopchuk
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,162 @@
1
+ = Introduction
2
+
3
+ mv-postgresql is the PostgreSQL driver for Migration Validators project (details here: https://github.com/vprokopchuk256/mv-core)
4
+
5
+ = Validators
6
+
7
+ === uniqueness
8
+
9
+ Value uniqueness validation
10
+
11
+ Usage:
12
+
13
+ validate_column :table_name, :column_name, :uniqueness => true
14
+ validate_column :table_name, :column_name, :uniqueness => {:message => 'Error message', :as => :trigger}
15
+ validate_column :table_name, :column_name, :uniqueness => {:as => :index}
16
+
17
+ create_table :table_name do |t|
18
+ t.string :column_name, :validates => {uniqueness => true}
19
+ end
20
+
21
+ Options:
22
+
23
+ message: text of the error message that will be shown if constraint violated. Ignored unless :as == :trigger
24
+ index_name: name of the index that will be created for validator. Ignored unless :as == :index
25
+ on: validation event. Possible values [:save, :update, :create]. Ignored unless :as == :trigger. Default value :save
26
+ create_tigger_name: Name of the 'before insert' trigger that will be created if :as == :trigger && :on in [:save, :create]
27
+ update_tigger_name: Name of the 'before update' trigger that will be created if :as == :trigger && :on in [:save, :update]
28
+ allow_nil: ignore validation for nil values. Ignored unless :as == :trigger. Default value: false
29
+ allow_blank: ignore validation for blank values. Ignored unless :as == :trigger. Default value: false
30
+ as: defines the way how constraint will be implemented. Possible values: [:index, :trigger]. Default value: :index
31
+
32
+ === length
33
+
34
+ Value length validation
35
+
36
+ Usage:
37
+
38
+ validate_column :table_name, :column_name, :length => {:in => 5..8, :message => "Wrong length message"}
39
+ validate_column :table_name, :column_name, :length => {:is => 3, :allow_nil => true}
40
+ validate_column :table_name, :column_name, :length => {:maximum => 3, :too_long => "Value is longer than 3 symbols"}
41
+
42
+ Options:
43
+
44
+ in: range or array that length of the value should be contained in.
45
+ within: synonym of :in
46
+ is: exact length of the value
47
+ maximum: maximum allowed length
48
+ minimum: minimum allowed length
49
+ message: message that should be shown if validation failed and specific message is not defined
50
+ too_long: message that will be shown if value longer than allowed. Ignored unless maximum value is defined
51
+ too_short: message that will be shown if value shorter than allowed. Ignored unless minimum value is defined
52
+ on: validation event. Possible values [:save, :update, :create]. Ignored unless :as == :trigger. Default value: :save
53
+ create_tigger_name: Name of the 'before insert' trigger that will be created if :as == :trigger && :on in [:save, :create]
54
+ update_tigger_name: Name of the 'before update' trigger that will be created if :as == :trigger && :on in [:save, :update]
55
+ allow_nil: ignore validation for nil values. Default value: false
56
+ allow_blank: ignore validation for blank values. Default value: false
57
+ as: defines the way how constraint will be implemented. Possible values: [:trigger, :check] Default value: :check
58
+
59
+ === inclusion
60
+
61
+ Value inclusion validation
62
+
63
+ Usage:
64
+
65
+ validate_column :table_name, :column_name, :inclusion => {:in => [1, 2, 3]}
66
+ validate_column :table_name, :column_name, :inclusion => {:in => [1, 2, 3], :message => "Column 'column_name' should be equal to 1 or 2 or 3"}
67
+ validate_column :table_name, :column_name, :inclusion => {:in => [1, 2, 3], :on => :update, :as => :check}
68
+ validate_column :table_name, :column_name, :inclusion => {:in => 1..3, :on => :create, :as => :trigger}
69
+
70
+ Options:
71
+
72
+ in: range or array that column value should be contained in.
73
+ message: message that should be shown if validation failed
74
+ on: validation event. Possible values [:save, :update, :create]. Ignored unless :as == :trigger. Default value: :save
75
+ create_tigger_name: Name of the 'before insert' trigger that will be created if :as == :trigger && :on in [:save, :create]
76
+ update_tigger_name: Name of the 'before update' trigger that will be created if :as == :trigger && :on in [:save, :update]
77
+ allow_nil: ignore validation for nil values. Default value: false
78
+ allow_blank: ignore validation for blank values. Default value: false
79
+ as: defines the way how constraint will be implemented. Possible values: [:trigger, :check] Default value: :check
80
+
81
+
82
+ === exclusion
83
+
84
+ Value exclusion validation
85
+
86
+ Usage:
87
+
88
+ validate_column :table_name, :column_name, :exclusion => {:in => [1, 2, 3]}
89
+ validate_column :table_name, :column_name, :exclusion => {:in => [1, 2, 3], :message => "Column 'column_name' should not be equal to 1 or 2 or 3"}
90
+ validate_column :table_name, :column_name, :exclusion => {:in => [1, 2, 3], :on => :update, :as => :check}
91
+ validate_column :table_name, :column_name, :exclusion => {:in => 1..3, :on => :create, :as => :trigger}
92
+
93
+ Options:
94
+
95
+ in: range or array that column value should NOT be contained in.
96
+ message: message that should be shown if validation failed
97
+ on: validation event. Possible values [:save, :update, :create]. Ignored unless :as == :trigger. Default value: :save
98
+ create_tigger_name: Name of the 'before insert' trigger that will be created if :as == :trigger && :on in [:save, :create]
99
+ update_tigger_name: Name of the 'before update' trigger that will be created if :as == :trigger && :on in [:save, :update]
100
+ allow_nil: ignore validation for nil values. Default value: false
101
+ allow_blank: ignore validation for blank values. Default value: false
102
+ as: defines the way how constraint will be implemented. Possible values: [:trigger, :check] Default value: :check
103
+
104
+ === presense
105
+
106
+ Value presense validation
107
+
108
+ Usage:
109
+
110
+ validate_column :table_name, :column_name, :presense => true
111
+ validate_column :table_name, :column_name, :presense => {:message => "value should not be empty"}
112
+ validate_column :table_name, :column_name, :presense => {:message => "value should not be empty", :as=> :trigger}
113
+ validate_column :table_name, :column_name, :presense => {:message => "value should not be empty", :as=> :trigger, :on => :create}
114
+
115
+
116
+ Options:
117
+
118
+ message: message that should be shown if validation failed
119
+ on: validation event. Possible values [:save, :update, :create]. Ignored unless :as == :trigger. Default value: :save
120
+ create_tigger_name: Name of the 'before insert' trigger that will be created if :as == :trigger && :on in [:save, :create]
121
+ update_tigger_name: Name of the 'before update' trigger that will be created if :as == :trigger && :on in [:save, :update]
122
+ allow_nil: ignore validation for nil values. Default value: false
123
+ allow_blank: ignore validation for blank values. Default value: false
124
+ as: defines the way how constraint will be implemented. Possible values: [:trigger, :check] Default value: :check
125
+
126
+ === format
127
+
128
+ Allows to define regular expression that column value will be mathed with
129
+
130
+ Usage:
131
+
132
+ validate_column :table_name, :column_name, :format => {:with => /word/}
133
+ validate_column :table_name, :column_name, :format => {:with => /word/, :messsage => "Column_name value should contain start word"}
134
+ validate_column :table_name, :column_name, :format => {:with => /word/, :messsage => "Column_name value should contain start word", :as => :trigger}
135
+
136
+
137
+ Options:
138
+
139
+ with: regular expression that column value should be matched to
140
+ message: message that should be shown if validation failed
141
+ on: validation event. Possible values [:save, :update, :create]. Ignored unless :as == :trigger. Default value: :save
142
+ create_tigger_name: Name of the 'before insert' trigger that will be created if :as == :trigger && :on in [:save, :create]
143
+ update_tigger_name: Name of the 'before update' trigger that will be created if :as == :trigger && :on in [:save, :update]
144
+ allow_nil: ignore validation for nil values. Default value: false
145
+ allow_blank: ignore validation for blank values. Default value: false
146
+ as: defines the way how constraint will be implemented. Possible values: [:trigger, :check] Default value: :check
147
+
148
+ == Contributing to mv-postgresql
149
+
150
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
151
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
152
+ * Fork the project
153
+ * Start a feature/bugfix branch
154
+ * Commit and push until you are happy with your contribution
155
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
156
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
157
+
158
+ == Copyright
159
+
160
+ Copyright (c) 2011 Valeriy Prokopchuk. See LICENSE.txt for
161
+ further details.
162
+
@@ -0,0 +1,146 @@
1
+ module MigrationValidators
2
+ module Adapters
3
+ class Postgresql < MigrationValidators::Adapters::Base
4
+ def name
5
+ "PostgreSQL Migration Validators Adapter"
6
+ end
7
+
8
+ define_base_syntax
9
+ syntax do
10
+ operation(:regexp) {|stmt, value| "#{stmt} ~ #{value}"}
11
+ operation :db_value do |value|
12
+ case value.class.name
13
+ when "String" then "'#{value}'"
14
+ when "Date" then "'#{value.strftime('%Y-%m-%d')}' "
15
+ when "DateTime" then "'#{value.strftime('%Y-%m-%d %H:%M:%S')}'"
16
+ when "Time" then "'#{value.strftime('%Y-%m-%d %H:%M:%S')}' "
17
+ when "Regexp" then "'#{value.source}'"
18
+ else value.to_s
19
+ end
20
+ end
21
+ end
22
+
23
+ define_base_validators
24
+
25
+ define_base_containers
26
+ container :insert_trigger do
27
+ operation :create do |stmt, trigger_name, group_name|
28
+ func_name = "#{trigger_name}_func"
29
+
30
+ "CREATE OR REPLACE FUNCTION #{func_name}() RETURNS TRIGGER AS $#{func_name}$
31
+ BEGIN
32
+ #{stmt};
33
+
34
+ RETURN NEW;
35
+ END;
36
+ $#{func_name}$ LANGUAGE plpgsql;
37
+
38
+ CREATE TRIGGER #{trigger_name} BEFORE INSERT ON #{group_name.first}
39
+ FOR EACH ROW EXECUTE PROCEDURE #{func_name}();"
40
+ end
41
+
42
+ operation :drop do |stmt, trigger_name, group_name|
43
+ "DROP TRIGGER IF EXISTS #{trigger_name} ON #{group_name.first};"
44
+ end
45
+
46
+
47
+ operation :bind_to_error do |stmt, error_message|
48
+ "IF NOT(#{stmt}) THEN
49
+ RAISE EXCEPTION '#{error_message}';
50
+ END IF"
51
+ end
52
+ end
53
+
54
+ container :update_trigger do
55
+ operation :create do |stmt, trigger_name, group_name|
56
+ func_name = "#{trigger_name}_func"
57
+
58
+ "CREATE OR REPLACE FUNCTION #{func_name}() RETURNS TRIGGER AS $#{func_name}$
59
+ BEGIN
60
+ #{stmt};
61
+
62
+ RETURN NEW;
63
+ END;
64
+ $#{func_name}$ LANGUAGE plpgsql;
65
+
66
+ CREATE TRIGGER #{trigger_name} BEFORE UPDATE ON #{group_name.first}
67
+ FOR EACH ROW EXECUTE PROCEDURE #{func_name}();"
68
+ end
69
+
70
+ operation :drop do |stmt, trigger_name, group_name|
71
+ func_name = "#{trigger_name}_func"
72
+
73
+ "DROP TRIGGER IF EXISTS #{trigger_name} ON #{group_name.first};
74
+ DROP FUNCTION IF EXISTS #{func_name}();"
75
+ end
76
+
77
+ operation :bind_to_error do |stmt, error_message|
78
+ "IF NOT(#{stmt}) THEN
79
+ RAISE EXCEPTION '#{error_message}';
80
+ END IF"
81
+ end
82
+ end
83
+
84
+ container :check do
85
+ operation :drop do |stmt, check_name, group_name|
86
+ "CREATE OR REPLACE FUNCTION __temporary_constraint_drop_function__() RETURNS INTEGER AS $$
87
+ DECLARE
88
+ constraint_rec RECORD;
89
+ BEGIN
90
+ SELECT INTO constraint_rec * FROM pg_constraint WHERE conname='#{check_name}' AND contype='c';
91
+
92
+ IF FOUND THEN
93
+ ALTER TABLE #{group_name.first} DROP CONSTRAINT #{check_name};
94
+ END IF;
95
+
96
+ RETURN 1;
97
+ END;
98
+ $$ LANGUAGE plpgsql;
99
+
100
+ SELECT __temporary_constraint_drop_function__();
101
+
102
+ DROP FUNCTION __temporary_constraint_drop_function__();
103
+ "
104
+ end
105
+ end
106
+
107
+
108
+ route :presense, :trigger do
109
+ to :insert_trigger, :if => {:on => [:save, :create, nil]}
110
+ to :update_trigger, :if => {:on => [:save, :update, nil]}
111
+ end
112
+ route :presense, :check, :to => :check, :default => true
113
+
114
+ route :inclusion, :trigger do
115
+ to :insert_trigger, :if => {:on => [:save, :create, nil]}
116
+ to :update_trigger, :if => {:on => [:save, :update, nil]}
117
+ end
118
+ route :inclusion, :check, :to => :check, :default => true
119
+
120
+ route :exclusion, :trigger do
121
+ to :insert_trigger, :if => {:on => [:save, :create, nil]}
122
+ to :update_trigger, :if => {:on => [:save, :update, nil]}
123
+ end
124
+ route :exclusion, :check, :to => :check, :default => true
125
+
126
+ route :length, :trigger do
127
+ to :insert_trigger, :if => {:on => [:save, :create, nil]}
128
+ to :update_trigger, :if => {:on => [:save, :update, nil]}
129
+ end
130
+ route :length, :check, :to => :check, :default => true
131
+
132
+ route :format, :trigger do
133
+ to :insert_trigger, :if => {:on => [:save, :create, nil]}
134
+ to :update_trigger, :if => {:on => [:save, :update, nil]}
135
+ end
136
+ route :format, :check, :to => :check, :default => true
137
+
138
+ route :uniqueness, :trigger do
139
+ to :insert_trigger, :if => {:on => [:save, :create, nil]}
140
+ to :update_trigger, :if => {:on => [:save, :update, nil]}
141
+ end
142
+ end
143
+
144
+ MigrationValidators.register_adapter! "postgresql", Postgresql
145
+ end
146
+ end
@@ -0,0 +1,4 @@
1
+ require 'mv-core'
2
+
3
+ require File.expand_path(File.dirname(__FILE__)) + '/migration_validators/adapters/postgresql'
4
+
@@ -0,0 +1,1518 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ describe MigrationValidators::Adapters::Postgresql, :type => :mv_test do
4
+ before :all do
5
+ Driver = Class.new(MigrationValidators::Adapters::Base)
6
+ use_db :adapter => "postgresql",
7
+ :port => 5432,
8
+ :host => "localhost",
9
+ :database => "root",
10
+ :username => "root",
11
+ :password => "root"
12
+
13
+ db.initialize_schema_migrations_table
14
+ ::ActiveRecord::Migration.verbose = false
15
+ end
16
+
17
+ before :each do
18
+ MigrationValidators::Core::DbValidator.clear_all
19
+ end
20
+
21
+ for_test_table do
22
+
23
+ #integer
24
+ for_integer_column do
25
+ with_validator :inclusion do
26
+ with_option :as => :trigger do
27
+ #closed integer interval
28
+ with_options :in => 1..9 do
29
+ it { should allow(1,4,9) }
30
+ it { should deny(0, 10).with_initial(1) }
31
+ end
32
+
33
+ #open integer interval
34
+ with_options :in => 1...9 do
35
+ it { should allow(1,4) }
36
+ it { should deny(0, 9, 10).with_initial(1) }
37
+ end
38
+
39
+ #single value
40
+ with_options :in => 9 do
41
+ it { should allow(9) }
42
+ it { should deny(8, 10).with_initial(9) }
43
+ end
44
+
45
+ #array
46
+ with_options :in => [1, 9] do
47
+ it { should allow(1, 9) }
48
+ it { should deny(0, 3, 10).with_initial(1) }
49
+ end
50
+
51
+ with_options :in => 9, :message => "Some error message" do
52
+ it { should deny(8, 10).with_initial(9).and_message(/Some error message/) }
53
+
54
+ with_option :on => :update do
55
+ it { should allow.insert(8, 10) }
56
+ end
57
+
58
+ with_option :on => :create do
59
+ it { should allow.update(8, 10).with_initial(9) }
60
+ end
61
+ end
62
+ end
63
+
64
+ with_option :as => :check do
65
+ #closed integer interval
66
+ with_options :in => 1..9 do
67
+ it { should allow(1,4,9) }
68
+ it { should deny(0, 10).with_initial(1) }
69
+ end
70
+
71
+ #open integer interval
72
+ with_options :in => 1...9 do
73
+ it { should allow(1,4) }
74
+ it { should deny(0, 9, 10).with_initial(1) }
75
+ end
76
+
77
+ #single value
78
+ with_options :in => 9 do
79
+ it { should allow(9) }
80
+ it { should deny(8, 10).with_initial(9) }
81
+ end
82
+
83
+ #array
84
+ with_options :in => [1, 9] do
85
+ it { should allow(1, 9) }
86
+ it { should deny(0, 3, 10).with_initial(1) }
87
+ end
88
+ end
89
+ end
90
+
91
+ with_validator :exclusion do
92
+ with_option :as => :trigger do
93
+ #closed integer interval
94
+ with_options :in => 1..9 do
95
+ it { should allow(0, 10) }
96
+ it { should deny(1,4,9).with_initial(0) }
97
+ end
98
+
99
+ #open integer intervalw
100
+ with_options :in => 1...9 do
101
+ it { should allow(0, 9, 10) }
102
+ it { should deny(1,4).with_initial(0) }
103
+ end
104
+
105
+ #single value
106
+ with_options :in => 9 do
107
+ it { should allow(8, 10) }
108
+ it { should deny(9).with_initial(0) }
109
+ end
110
+
111
+ #array
112
+ with_options :in => [1, 9] do
113
+ it { should allow(0, 3, 10) }
114
+ it { should deny(1, 9).with_initial(0) }
115
+ end
116
+
117
+ with_options :in => 9, :message => "Some error message" do
118
+ it { should deny(9).with_initial(8).and_message(/Some error message/) }
119
+
120
+ with_option :on => :update do
121
+ it { should allow.insert(9) }
122
+ end
123
+
124
+ with_option :on => :create do
125
+ it { should allow.update(9).with_initial(8) }
126
+ end
127
+ end
128
+ end
129
+
130
+ with_option :as => :check do
131
+ #closed integer interval
132
+ with_options :in => 1..9 do
133
+ it { should allow(0, 10) }
134
+ it { should deny(1,4,9).with_initial(0) }
135
+ end
136
+
137
+ #open integer intervalw
138
+ with_options :in => 1...9 do
139
+ it { should allow(0, 9, 10) }
140
+ it { should deny(1,4).with_initial(0) }
141
+ end
142
+
143
+ #single value
144
+ with_options :in => 9 do
145
+ it { should allow(8, 10) }
146
+ it { should deny(9).with_initial(0) }
147
+ end
148
+
149
+ #array
150
+ with_options :in => [1, 9] do
151
+ it { should allow(0, 3, 10) }
152
+ it { should deny(1, 9).with_initial(0) }
153
+ end
154
+ end
155
+ end
156
+
157
+ with_validator :uniqueness do
158
+ with_option :as => :trigger do
159
+ it { should deny.insert.at_least_one(1,1)}
160
+ it { should deny.update(1).with_initial(1,2)}
161
+ it { should allow.insert(1,2,3) }
162
+
163
+ with_option :message => "Some error message" do
164
+ it { should deny.at_least_one(1,1).with_initial(1).and_message(/Some error message/) }
165
+ end
166
+ end
167
+
168
+ with_option :as => :index do
169
+ it { should deny.insert.at_least_one(1,1).with_message(/duplicate key value violates unique constraint/) }
170
+ it { should deny.update(1).with_initial(1,2).and_message(/duplicate key value violates unique constraint/) }
171
+ it { should allow.insert(1,2,3) }
172
+ it { should allow.update(1).with_initial(2) }
173
+ end
174
+ end
175
+ end
176
+
177
+ for_integer_column :validates => {:uniqueness => {:as => :index, :message => "Some error message"}, :inclusion => {:in => 1..9, :as => :trigger, :message => "Some error message"}} do
178
+ it { should deny.at_least_one(1,1).with_initial(1, 2).and_message(/duplicate key value violates unique constraint/) }
179
+ it { should deny(10).with_initial(8).and_message(/Some error message/) }
180
+
181
+ with_change :inclusion => false do
182
+ it { should deny.at_least_one(1,1).with_initial(1, 2).and_message(/duplicate key value violates unique constraint/) }
183
+ it { should allow(10) }
184
+ end
185
+
186
+ with_change :inclusion => {:in => 1..9} do
187
+ with_change :inclusion => false do
188
+ it { should allow(10) }
189
+ end
190
+ end
191
+ end
192
+
193
+ for_integer_column :validates => {:uniqueness => {:as => :index, :message => "Some error message"}, :inclusion => {:in => 1..9, :as => :check}} do
194
+ it { should deny.at_least_one(1,1).with_initial(1, 2).and_message(/duplicate key value violates unique constraint/) }
195
+ it { should deny(10).with_initial(8) }
196
+
197
+ with_change :inclusion => false do
198
+ it { should deny.at_least_one(1,1).with_initial(1, 2).and_message(/duplicate key value violates unique constraint/) }
199
+ it { should allow(10) }
200
+ end
201
+
202
+ with_change :inclusion => {:in => 1..9} do
203
+ with_change :inclusion => false do
204
+ it { should allow(10) }
205
+ end
206
+ end
207
+ end
208
+
209
+ for_integer_column :validates => {:uniqueness => {:as => :index, :message => "Some error message"}, :exclusion => {:in => 4..9, :as => :trigger, :message => "Some error message"}} do
210
+ it { should deny.at_least_one(1,1).with_initial(1, 2).and_message(/duplicate key value violates unique constraint/) }
211
+ it { should deny(9).with_initial(10).and_message(/Some error message/) }
212
+
213
+ with_change :exclusion => false do
214
+ it { should deny.at_least_one(1,1).with_initial(1, 2).and_message(/duplicate key value violates unique constraint/) }
215
+ it { should allow(9) }
216
+ end
217
+
218
+ with_change :exclusion => {:in => 4..9} do
219
+ with_change :exclusion => false do
220
+ it { should allow(9) }
221
+ end
222
+ end
223
+ end
224
+
225
+ for_integer_column :validates => {:uniqueness => {:as => :index, :message => "Some error message"}, :exclusion => {:in => 4..9, :as => :check}} do
226
+ it { should deny.at_least_one(1,1).with_initial(1, 2).and_message(/duplicate key value violates unique constraint/) }
227
+ it { should deny(9).with_initial(10) }
228
+
229
+ with_change :exclusion => false do
230
+ it { should deny.at_least_one(1,1).with_initial(1, 2).and_message(/duplicate key value violates unique constraint/) }
231
+ it { should allow(9) }
232
+ end
233
+
234
+ with_change :exclusion => {:in => 4..9} do
235
+ with_change :exclusion => false do
236
+ it { should allow(9) }
237
+ end
238
+ end
239
+ end
240
+
241
+ #float
242
+ for_float_column do
243
+ with_validator :inclusion do
244
+ with_option :as => :trigger do
245
+ #closed integer interval
246
+ with_options :in => 1.1..9.1 do
247
+ it { should allow(1.1, 9.1) }
248
+ it { should deny(1.0, 9.2).with_initial(1.1) }
249
+ end
250
+
251
+ #open integer interval
252
+ with_options :in => 1.1...9.1 do
253
+ it { should allow(1.1, 9) }
254
+ it { should deny(1.0, 9.1, 9.2).with_initial(1.1) }
255
+ end
256
+
257
+ #single value
258
+ with_options :in => 9.1 do
259
+ it { should allow(9.1) }
260
+ it { should deny(8.1, 10.1).with_initial(9.1) }
261
+ end
262
+
263
+ #array
264
+ with_options :in => [1.1, 9.1] do
265
+ it { should allow(1.1, 9.1) }
266
+ it { should deny(0.1, 3.1, 10.1).with_initial(1.1) }
267
+ end
268
+
269
+ with_options :in => 9.1, :message => "Some error message" do
270
+ it { should deny(8.1, 10.1).with_initial(9.1).and_message(/Some error message/) }
271
+ end
272
+ end
273
+
274
+ with_option :as => :check do
275
+ #closed integer interval
276
+ with_options :in => 1.1..9.1 do
277
+ it { should allow(1.1, 9.1) }
278
+ it { should deny(1.0, 9.2).with_initial(1.1) }
279
+ end
280
+
281
+ #open integer interval
282
+ with_options :in => 1.1...9.1 do
283
+ it { should allow(1.1, 9) }
284
+ it { should deny(1.0, 9.1, 9.2).with_initial(1.1) }
285
+ end
286
+
287
+ #single value
288
+ with_options :in => 9.1 do
289
+ it { should allow(9.1) }
290
+ it { should deny(8.1, 10.1).with_initial(9.1) }
291
+ end
292
+
293
+ #array
294
+ with_options :in => [1.1, 9.1] do
295
+ it { should allow(1.1, 9.1) }
296
+ it { should deny(0.1, 3.1, 10.1).with_initial(1.1) }
297
+ end
298
+ end
299
+ end
300
+
301
+ with_validator :exclusion do
302
+ with_option :as => :trigger do
303
+ #closed integer interval
304
+ with_options :in => 1.1..9.1 do
305
+ it { should allow(1.0, 9.2) }
306
+ it { should deny(1.1, 9.1).with_initial(1.0) }
307
+ end
308
+
309
+ #open integer interval
310
+ with_options :in => 1.1...9.1 do
311
+ it { should allow(1.0, 9.1, 9.2) }
312
+ it { should deny(1.1, 9).with_initial(1.0) }
313
+ end
314
+
315
+ #single value
316
+ with_options :in => 9.1 do
317
+ it { should deny(9.1).with_initial(9.0) }
318
+ it { should allow(8.1, 10.1) }
319
+ end
320
+
321
+ #array
322
+ with_options :in => [1.1, 9.1] do
323
+ it { should deny(1.1, 9.1).with_initial(1.0) }
324
+ it { should allow(0.1, 3.1, 10.1) }
325
+ end
326
+
327
+ with_options :in => 9.1, :message => "Some error message" do
328
+ it { should deny(9.1).with_initial(9.0).and_message(/Some error message/) }
329
+ end
330
+ end
331
+
332
+ with_option :as => :check do
333
+ #closed integer interval
334
+ with_options :in => 1.1..9.1 do
335
+ it { should allow(1.0, 9.2) }
336
+ it { should deny(1.1, 9.1).with_initial(1.0) }
337
+ end
338
+
339
+ #open integer interval
340
+ with_options :in => 1.1...9.1 do
341
+ it { should allow(1.0, 9.1, 9.2) }
342
+ it { should deny(1.1, 9).with_initial(1.0) }
343
+ end
344
+
345
+ #single value
346
+ with_options :in => 9.1 do
347
+ it { should deny(9.1).with_initial(9.0) }
348
+ it { should allow(8.1, 10.1) }
349
+ end
350
+
351
+ #array
352
+ with_options :in => [1.1, 9.1] do
353
+ it { should deny(1.1, 9.1).with_initial(1.0) }
354
+ it { should allow(0.1, 3.1, 10.1) }
355
+ end
356
+ end
357
+ end
358
+ end
359
+
360
+ #string
361
+ for_string_column do
362
+
363
+ with_validator :format do
364
+ with_option :as => :trigger do
365
+ with_option :with => /^start/ do
366
+ it { should allow('start stop') }
367
+ it { should deny('stop start').with_initial('start') }
368
+ it { should deny('stop').with_initial('start') }
369
+
370
+ with_option :on => :update do
371
+ it { should allow.insert('stop')}
372
+ end
373
+
374
+ with_option :on => :create do
375
+ it { should allow.update('stop').with_initial('start')}
376
+ end
377
+
378
+ with_option :message => "Some error message" do
379
+ it { should deny('stop').with_initial('start').and_message(/Some error message/) }
380
+ end
381
+ end
382
+ end
383
+
384
+ with_option :as => :check do
385
+ with_option :with => /^start/ do
386
+ it { should allow('start stop') }
387
+ it { should deny('stop start').with_initial('start') }
388
+ it { should deny('stop').with_initial('start') }
389
+ end
390
+ end
391
+ end
392
+
393
+ with_validator :presense do
394
+ with_option :as => :trigger do
395
+ it { should allow('b') }
396
+ it { should deny(nil).with_initial('b') }
397
+
398
+ with_option :allow_blank => true do
399
+ it { should allow(nil) }
400
+ end
401
+
402
+ with_option :allow_nil => true do
403
+ it { should allow(nil) }
404
+ end
405
+
406
+ with_option :on => :update do
407
+ it { should allow.insert(nil) }
408
+ end
409
+
410
+ with_option :on => :create do
411
+ it { should allow.update(nil).with_initial('b') }
412
+ end
413
+ end
414
+
415
+ with_option :as => :check do
416
+ it { should allow('b') }
417
+ it { should deny(nil).with_initial('b') }
418
+
419
+ with_option :allow_blank => true do
420
+ it { should allow(nil) }
421
+ end
422
+
423
+ with_option :allow_nil => true do
424
+ it { should allow(nil) }
425
+ end
426
+ end
427
+ end
428
+
429
+ with_validator :uniqueness do
430
+ with_option :as => :trigger do
431
+ it { should deny.at_least_one(' ', ' ').with_initial(' ', 'a') }
432
+
433
+ with_option :allow_blank => true do
434
+ it { should allow(' ', ' ') }
435
+ end
436
+ end
437
+ end
438
+
439
+ with_validator :inclusion do
440
+ with_option :as => :trigger do
441
+ #closed string interval
442
+ with_options :in => 'b'..'e' do
443
+ it { should allow('b', 'd', 'e') }
444
+ it { should deny('a', 'f').with_initial('b') }
445
+ it { should deny(' ').with_initial('b') }
446
+ it { should deny(nil).with_initial('b') }
447
+
448
+ with_option :allow_blank => true do
449
+ it { should allow(' ') }
450
+ end
451
+
452
+ with_option :allow_nil => true do
453
+ it { should allow(nil) }
454
+ end
455
+ end
456
+
457
+ #open string interval
458
+ with_options :in => 'b'...'e' do
459
+ it { should allow('b', 'd') }
460
+ it { should deny('a', 'e', 'f').with_initial('b') }
461
+ it { should deny(' ').with_initial('b') }
462
+ it { should deny(nil).with_initial('b') }
463
+
464
+ with_option :allow_blank => true do
465
+ it { should allow(' ') }
466
+ end
467
+
468
+ with_option :allow_nil => true do
469
+ it { should allow(nil) }
470
+ end
471
+ end
472
+
473
+ #single string value
474
+ with_options :in => 'b' do
475
+ it { should allow('b') }
476
+ it { should deny('a', 'c').with_initial('b') }
477
+ it { should deny(' ').with_initial('b') }
478
+ it { should deny(nil).with_initial('b') }
479
+
480
+ with_option :allow_blank => true do
481
+ it { should allow(' ') }
482
+ end
483
+
484
+ with_option :allow_nil => true do
485
+ it { should allow(nil) }
486
+ end
487
+ end
488
+
489
+ #array
490
+ with_options :in => ['b', 'e'] do
491
+ it { should allow('b', 'e') }
492
+ it { should deny('a', 'c', 'f').with_initial('b') }
493
+ it { should deny(' ').with_initial('b') }
494
+ it { should deny(nil).with_initial('b') }
495
+
496
+ with_option :allow_blank => true do
497
+ it { should allow(' ') }
498
+ end
499
+
500
+ with_option :allow_nil => true do
501
+ it { should allow(nil) }
502
+ end
503
+ end
504
+
505
+ with_options :in => 'b' do
506
+ it { should allow('b') }
507
+
508
+ with_option :message => "Some error message" do
509
+ it { should deny('c').with_initial('b').with_message(/Some error message/) }
510
+ end
511
+
512
+ it { should deny(' ').with_initial('b') }
513
+
514
+ with_option :allow_blank => true do
515
+ it { should allow(' ') }
516
+ end
517
+ end
518
+ end
519
+
520
+ with_option :as => :check do
521
+ #closed string interval
522
+ with_options :in => 'b'..'e' do
523
+ it { should allow('b', 'd', 'e') }
524
+ it { should deny('a', 'f').with_initial('b') }
525
+ it { should deny(' ').with_initial('b') }
526
+ it { should deny(nil).with_initial('b') }
527
+
528
+ with_option :allow_blank => true do
529
+ it { should allow(' ') }
530
+ end
531
+
532
+ with_option :allow_nil => true do
533
+ it { should allow(nil) }
534
+ end
535
+ end
536
+
537
+ #open string interval
538
+ with_options :in => 'b'...'e' do
539
+ it { should allow('b', 'd') }
540
+ it { should deny('a', 'e', 'f').with_initial('b') }
541
+ it { should deny(' ').with_initial('b') }
542
+ it { should deny(nil).with_initial('b') }
543
+
544
+ with_option :allow_blank => true do
545
+ it { should allow(' ') }
546
+ end
547
+
548
+ with_option :allow_nil => true do
549
+ it { should allow(nil) }
550
+ end
551
+ end
552
+
553
+ #single string value
554
+ with_options :in => 'b' do
555
+ it { should allow('b') }
556
+ it { should deny('a', 'c').with_initial('b') }
557
+ it { should deny(' ').with_initial('b') }
558
+ it { should deny(nil).with_initial('b') }
559
+
560
+ with_option :allow_blank => true do
561
+ it { should allow(' ') }
562
+ end
563
+
564
+ with_option :allow_nil => true do
565
+ it { should allow(nil) }
566
+ end
567
+ end
568
+
569
+ #array
570
+ with_options :in => ['b', 'e'] do
571
+ it { should allow('b', 'e') }
572
+ it { should deny('a', 'c', 'f').with_initial('b') }
573
+ it { should deny(' ').with_initial('b') }
574
+ it { should deny(nil).with_initial('b') }
575
+
576
+ with_option :allow_blank => true do
577
+ it { should allow(' ') }
578
+ end
579
+
580
+ with_option :allow_nil => true do
581
+ it { should allow(nil) }
582
+ end
583
+ end
584
+
585
+ with_options :in => 'b' do
586
+ it { should allow('b') }
587
+ it { should deny(' ').with_initial('b') }
588
+
589
+ with_option :allow_blank => true do
590
+ it { should allow(' ') }
591
+ end
592
+ end
593
+ end
594
+ end
595
+
596
+ with_validator :exclusion do
597
+ with_option :as => :trigger do
598
+ #closed string interval
599
+ with_options :in => 'b'..'e' do
600
+ it { should allow('a', 'f') }
601
+ it { should deny('b', 'd', 'e').with_initial('a') }
602
+ it { should allow(nil) }
603
+ end
604
+
605
+ #open string interval
606
+ with_options :in => 'b'...'e' do
607
+ it { should deny('b', 'd').with_initial('a') }
608
+ it { should allow('a', 'e', 'f') }
609
+ it { should allow(nil) }
610
+ end
611
+
612
+ #single string value
613
+ with_options :in => 'b' do
614
+ it { should deny('b').with_initial('a') }
615
+ it { should allow('a', 'c') }
616
+ it { should allow(nil) }
617
+ end
618
+
619
+ #array
620
+ with_options :in => ['b', 'e', ' '] do
621
+ it { should deny('b', 'e').with_initial('a') }
622
+ it { should allow('a', 'c', 'f') }
623
+ it { should deny(' ').with_initial('a') }
624
+ it { should allow(nil) }
625
+
626
+ with_option :allow_blank => true do
627
+ it { should allow(' ') }
628
+ end
629
+ end
630
+
631
+ with_options :in => 'b', :message => "Some error message" do
632
+ it { should deny('b').with_initial('a').with_message(/Some error message/) }
633
+ end
634
+ end
635
+
636
+ with_option :as => :check do
637
+ #closed string interval
638
+ with_options :in => 'b'..'e' do
639
+ it { should allow('a', 'f') }
640
+ it { should deny('b', 'd', 'e').with_initial('a') }
641
+ it { should allow(nil) }
642
+ end
643
+
644
+ #open string interval
645
+ with_options :in => 'b'...'e' do
646
+ it { should deny('b', 'd').with_initial('a') }
647
+ it { should allow('a', 'e', 'f') }
648
+ it { should allow(nil) }
649
+ end
650
+
651
+ #single string value
652
+ with_options :in => 'b' do
653
+ it { should deny('b').with_initial('a') }
654
+ it { should allow('a', 'c') }
655
+ it { should allow(nil) }
656
+ end
657
+
658
+ #array
659
+ with_options :in => ['b', 'e', ' '] do
660
+ it { should deny('b', 'e').with_initial('a') }
661
+ it { should allow('a', 'c', 'f') }
662
+ it { should deny(' ').with_initial('a') }
663
+ it { should allow(nil) }
664
+
665
+ with_option :allow_blank => true do
666
+ it { should allow(' ') }
667
+ end
668
+ end
669
+ end
670
+ end
671
+
672
+ with_validator :length do
673
+ with_option :as => :trigger do
674
+ with_option :is => 5 do
675
+ it {should allow('12345') }
676
+ it {should deny('1234', '123456').with_initial('12345') }
677
+
678
+ with_option :message => "Some error message" do
679
+ it {should deny('123456').with_initial('12345').with_message("Some error message") }
680
+
681
+ with_option :wrong_length => "Some specific error message" do
682
+ it {should deny('123456').with_initial('12345').with_message("Some specific error message") }
683
+ end
684
+ end
685
+
686
+ with_option :on => :create do
687
+ it {should deny.insert('1234', '123456') }
688
+ it {should allow.update('1234', '123456').with_initial('12345') }
689
+ end
690
+
691
+ with_option :on => :update do
692
+ it {should allow.insert('1234', '123456') }
693
+ it {should deny.update('1234', '123456').with_initial('12345') }
694
+ end
695
+
696
+ it {should deny(' ', nil).with_initial('12345') }
697
+
698
+ with_option :allow_blank => true do
699
+ it { should allow.insert(' ') }
700
+ end
701
+
702
+ with_option :allow_nil => true do
703
+ it { should allow.insert(nil) }
704
+ end
705
+ end
706
+
707
+ with_option :is => 0 do
708
+ it { should allow(nil) }
709
+ end
710
+
711
+
712
+ with_option :maximum => 5 do
713
+ it {should allow('1234', '12345') }
714
+ it {should deny('123456').with_initial('12345') }
715
+
716
+ with_option :message => "Some error message" do
717
+ it {should deny('123456').with_initial('12345').with_message("Some error message") }
718
+
719
+ with_option :too_long => "Some specific error message" do
720
+ it {should deny('123456').with_initial('12345').with_message("Some specific error message") }
721
+ end
722
+ end
723
+
724
+ it { should allow(' ', nil) }
725
+ end
726
+
727
+ with_option :minimum => 5 do
728
+ it {should allow('12345', '123456') }
729
+ it {should deny('1234').with_initial('12345') }
730
+
731
+ with_option :message => "Some error message" do
732
+ it {should deny('1234').with_initial('12345').with_message("Some error message") }
733
+
734
+ with_option :too_short => "Some specific error message" do
735
+ it {should deny('1234').with_initial('12345').with_message("Some specific error message") }
736
+ end
737
+ end
738
+
739
+ it {should deny(' ', nil).with_initial('12345') }
740
+
741
+ with_option :allow_blank => true do
742
+ it { should allow.insert(' ') }
743
+ end
744
+
745
+ with_option :allow_nil => true do
746
+ it { should allow.insert(nil) }
747
+ end
748
+ end
749
+
750
+ with_option :minimum => 0 do
751
+ it { should allow(' ', nil) }
752
+ end
753
+
754
+ with_option :in => 2..5 do
755
+ it {should allow('12', '123', '12345') }
756
+ it {should deny('1', '123456').with_initial('12') }
757
+
758
+ with_option :message => "Some error message" do
759
+ it {should deny('1').with_initial('12').with_message("Some error message") }
760
+ end
761
+
762
+ it {should deny(' ', nil).with_initial('12') }
763
+
764
+ with_option :allow_blank => true do
765
+ it { should allow.insert(' ') }
766
+ end
767
+
768
+ with_option :allow_nil => true do
769
+ it { should allow.insert(nil) }
770
+ end
771
+ end
772
+
773
+ with_option :in => 0..1 do
774
+ it { should allow(' ', nil) }
775
+ end
776
+
777
+ with_option :in => 2...5 do
778
+ it {should allow('12', '123') }
779
+ it {should deny('1', '12345', '123456').with_initial('12') }
780
+
781
+ with_option :message => "Some error message" do
782
+ it {should deny('1').with_initial('12').with_message("Some error message") }
783
+ end
784
+
785
+ it {should deny(' ', nil).with_initial('12') }
786
+
787
+ with_option :allow_blank => true do
788
+ it { should allow.insert(' ') }
789
+ end
790
+
791
+ with_option :allow_nil => true do
792
+ it { should allow.insert(nil) }
793
+ end
794
+ end
795
+
796
+ with_option :in => 0...2 do
797
+ it { should allow(' ', nil) }
798
+ end
799
+
800
+ with_option :in => [2, 3, 5] do
801
+ it {should allow('12', '123', '12345') }
802
+ it {should deny('1', '1234', '123456').with_initial('12') }
803
+
804
+ with_option :message => "Some error message" do
805
+ it {should deny('1').with_initial('12').with_message("Some error message") }
806
+ end
807
+
808
+ it {should deny(' ', nil).with_initial('12') }
809
+
810
+ with_option :allow_blank => true do
811
+ it { should allow.insert(' ') }
812
+ end
813
+
814
+ with_option :allow_nil => true do
815
+ it { should allow.insert(nil) }
816
+ end
817
+ end
818
+
819
+ with_option :in => [0, 1] do
820
+ it { should allow(' ', nil) }
821
+ end
822
+
823
+ with_option :in => 5 do
824
+ it {should allow('12345') }
825
+ it {should deny('1234', '123456').with_initial('12345') }
826
+ end
827
+
828
+ with_option :within => 2..5 do
829
+ it {should allow('12', '123', '12345') }
830
+ it {should deny('1', '123456').with_initial('12') }
831
+
832
+ with_option :message => "Some error message" do
833
+ it {should deny('1').with_initial('12').with_message("Some error message") }
834
+ end
835
+
836
+ it {should deny(' ', nil).with_initial('12') }
837
+
838
+ with_option :allow_blank => true do
839
+ it { should allow.insert(' ') }
840
+ end
841
+
842
+ with_option :allow_nil => true do
843
+ it { should allow.insert(nil) }
844
+ end
845
+ end
846
+
847
+ with_option :within => 0..1 do
848
+ it { should allow(' ', nil) }
849
+ end
850
+
851
+ with_option :within => 2...5 do
852
+ it {should allow('12', '123') }
853
+ it {should deny('1', '12345', '123456').with_initial('12') }
854
+
855
+ with_option :message => "Some error message" do
856
+ it {should deny('1').with_initial('12').with_message("Some error message") }
857
+ end
858
+
859
+ it {should deny(' ', nil).with_initial('12') }
860
+
861
+ with_option :allow_blank => true do
862
+ it { should allow.insert(' ') }
863
+ end
864
+
865
+ with_option :allow_nil => true do
866
+ it { should allow.insert(nil) }
867
+ end
868
+ end
869
+
870
+ with_option :within => 0...2 do
871
+ it { should allow(' ', nil) }
872
+ end
873
+
874
+ with_option :within => [2, 3, 5] do
875
+ it {should allow('12', '123', '12345') }
876
+ it {should deny('1', '1234', '123456').with_initial('12') }
877
+
878
+ with_option :message => "Some error message" do
879
+ it {should deny('1').with_initial('12').with_message("Some error message") }
880
+ end
881
+
882
+ it {should deny(' ', nil).with_initial('12') }
883
+
884
+ with_option :allow_blank => true do
885
+ it { should allow.insert(' ') }
886
+ end
887
+
888
+ with_option :allow_nil => true do
889
+ it { should allow.insert(nil) }
890
+ end
891
+ end
892
+
893
+ with_option :within => [0, 1] do
894
+ it { should allow(' ', nil) }
895
+ end
896
+
897
+ with_option :within => 5 do
898
+ it {should allow('12345') }
899
+ it {should deny('1234', '123456').with_initial('12345') }
900
+ end
901
+ end
902
+
903
+ with_option :as => :check do
904
+ with_option :is => 5 do
905
+ it {should allow('12345') }
906
+ it {should deny('1234', '123456').with_initial('12345') }
907
+
908
+ it {should deny(' ', nil).with_initial('12345') }
909
+
910
+ with_option :allow_blank => true do
911
+ it { should allow.insert(' ') }
912
+ end
913
+
914
+ with_option :allow_nil => true do
915
+ it { should allow.insert(nil) }
916
+ end
917
+ end
918
+
919
+ with_option :is => 0 do
920
+ it { should allow(nil) }
921
+ end
922
+
923
+
924
+ with_option :maximum => 5 do
925
+ it {should allow('1234', '12345') }
926
+ it {should deny('123456').with_initial('12345') }
927
+ it { should allow(' ', nil) }
928
+ end
929
+
930
+ with_option :minimum => 5 do
931
+ it {should allow('12345', '123456') }
932
+ it {should deny('1234').with_initial('12345') }
933
+
934
+ it {should deny(' ', nil).with_initial('12345') }
935
+
936
+ with_option :allow_blank => true do
937
+ it { should allow.insert(' ') }
938
+ end
939
+
940
+ with_option :allow_nil => true do
941
+ it { should allow.insert(nil) }
942
+ end
943
+ end
944
+
945
+ with_option :minimum => 0 do
946
+ it { should allow(' ', nil) }
947
+ end
948
+
949
+ with_option :in => 2..5 do
950
+ it {should allow('12', '123', '12345') }
951
+ it {should deny('1', '123456').with_initial('12') }
952
+
953
+ it {should deny(' ', nil).with_initial('12') }
954
+
955
+ with_option :allow_blank => true do
956
+ it { should allow.insert(' ') }
957
+ end
958
+
959
+ with_option :allow_nil => true do
960
+ it { should allow.insert(nil) }
961
+ end
962
+ end
963
+
964
+ with_option :in => 0..1 do
965
+ it { should allow(' ', nil) }
966
+ end
967
+
968
+ with_option :in => 2...5 do
969
+ it {should allow('12', '123') }
970
+ it {should deny('1', '12345', '123456').with_initial('12') }
971
+
972
+ it {should deny(' ', nil).with_initial('12') }
973
+
974
+ with_option :allow_blank => true do
975
+ it { should allow.insert(' ') }
976
+ end
977
+
978
+ with_option :allow_nil => true do
979
+ it { should allow.insert(nil) }
980
+ end
981
+ end
982
+
983
+ with_option :in => 0...2 do
984
+ it { should allow(' ', nil) }
985
+ end
986
+
987
+ with_option :in => [2, 3, 5] do
988
+ it {should allow('12', '123', '12345') }
989
+ it {should deny('1', '1234', '123456').with_initial('12') }
990
+
991
+ it {should deny(' ', nil).with_initial('12') }
992
+
993
+ with_option :allow_blank => true do
994
+ it { should allow.insert(' ') }
995
+ end
996
+
997
+ with_option :allow_nil => true do
998
+ it { should allow.insert(nil) }
999
+ end
1000
+ end
1001
+
1002
+ with_option :in => [0, 1] do
1003
+ it { should allow(' ', nil) }
1004
+ end
1005
+
1006
+ with_option :in => 5 do
1007
+ it {should allow('12345') }
1008
+ it {should deny('1234', '123456').with_initial('12345') }
1009
+ end
1010
+
1011
+ with_option :within => 2..5 do
1012
+ it {should allow('12', '123', '12345') }
1013
+ it {should deny('1', '123456').with_initial('12') }
1014
+
1015
+ it {should deny(' ', nil).with_initial('12') }
1016
+
1017
+ with_option :allow_blank => true do
1018
+ it { should allow.insert(' ') }
1019
+ end
1020
+
1021
+ with_option :allow_nil => true do
1022
+ it { should allow.insert(nil) }
1023
+ end
1024
+ end
1025
+
1026
+ with_option :within => 0..1 do
1027
+ it { should allow(' ', nil) }
1028
+ end
1029
+
1030
+ with_option :within => 2...5 do
1031
+ it {should allow('12', '123') }
1032
+ it {should deny('1', '12345', '123456').with_initial('12') }
1033
+
1034
+ it {should deny(' ', nil).with_initial('12') }
1035
+
1036
+ with_option :allow_blank => true do
1037
+ it { should allow.insert(' ') }
1038
+ end
1039
+
1040
+ with_option :allow_nil => true do
1041
+ it { should allow.insert(nil) }
1042
+ end
1043
+ end
1044
+
1045
+ with_option :within => 0...2 do
1046
+ it { should allow(' ', nil) }
1047
+ end
1048
+
1049
+ with_option :within => [2, 3, 5] do
1050
+ it {should allow('12', '123', '12345') }
1051
+ it {should deny('1', '1234', '123456').with_initial('12') }
1052
+
1053
+ it {should deny(' ', nil).with_initial('12') }
1054
+
1055
+ with_option :allow_blank => true do
1056
+ it { should allow.insert(' ') }
1057
+ end
1058
+
1059
+ with_option :allow_nil => true do
1060
+ it { should allow.insert(nil) }
1061
+ end
1062
+ end
1063
+
1064
+ with_option :within => [0, 1] do
1065
+ it { should allow(' ', nil) }
1066
+ end
1067
+
1068
+ with_option :within => 5 do
1069
+ it {should allow('12345') }
1070
+ it {should deny('1234', '123456').with_initial('12345') }
1071
+ end
1072
+ end
1073
+ end
1074
+ end
1075
+
1076
+ for_string_column :validates => {:uniqueness => {:as => :index}, :length => {:in => 4..9, :as => :trigger, :message => "Some error message"}} do
1077
+ it { should deny.at_least_one('1234','1234').with_initial('1234', '12345').and_message(/duplicate key value violates unique constraint/) }
1078
+ it { should deny('123').with_initial('1234').and_message(/Some error message/) }
1079
+
1080
+ with_change :length => false do
1081
+ it { should deny.at_least_one('1234','1234').with_initial('1234', '12345').and_message(/duplicate key value violates unique constraint/) }
1082
+ it { should allow('123') }
1083
+ end
1084
+
1085
+ with_change :length => {:in => 4..9} do
1086
+ with_change :length => false do
1087
+ it { should allow('123') }
1088
+ end
1089
+ end
1090
+ end
1091
+
1092
+ for_string_column :validates => {:uniqueness => {:as => :index}, :length => {:in => 4..9, :as => :check}} do
1093
+ it { should deny.at_least_one('1234','1234').with_initial('1234', '12345').and_message(/duplicate key value violates unique constraint/) }
1094
+ it { should deny('123').with_initial('1234') }
1095
+
1096
+ with_change :length => false do
1097
+ it { should deny.at_least_one('1234','1234').with_initial('1234', '12345').and_message(/duplicate key value violates unique constraint/) }
1098
+ it { should allow('123') }
1099
+ end
1100
+
1101
+ with_change :length => {:in => 4..9} do
1102
+ with_change :length => false do
1103
+ it { should allow('123') }
1104
+ end
1105
+ end
1106
+ end
1107
+
1108
+ for_string_column :validates => {:uniqueness => {:as => :index, :message => "Some error message"}, :format => {:with => /^start/, :as => :trigger, :message => "Some error message"}} do
1109
+ it { should deny.at_least_one('start','start').with_initial('start', 'start1').and_message(/duplicate key value violates unique constraint/) }
1110
+ it { should deny('stop').with_initial('start').and_message(/Some error message/) }
1111
+
1112
+ with_change :format => false do
1113
+ it { should deny.at_least_one('start','start').with_initial('start', 'start1').and_message(/duplicate key value violates unique constraint/) }
1114
+ it { should allow('stop') }
1115
+ end
1116
+
1117
+ with_change :format => {:with => /^start/} do
1118
+ with_change :format => false do
1119
+ it { should allow('stop') }
1120
+ end
1121
+ end
1122
+ end
1123
+
1124
+ for_string_column :validates => {:uniqueness => {:as => :index, :message => "Some error message"}, :format => {:with => /^start/, :as => :check}} do
1125
+ it { should deny.at_least_one('start','start').with_initial('start', 'start1').and_message(/duplicate key value violates unique constraint/) }
1126
+ it { should deny('stop').with_initial('start')}
1127
+
1128
+ with_change :format => false do
1129
+ it { should deny.at_least_one('start','start').with_initial('start', 'start1').and_message(/duplicate key value violates unique constraint/) }
1130
+ it { should allow('stop') }
1131
+ end
1132
+
1133
+ with_change :format => {:with => /^start/} do
1134
+ with_change :format => false do
1135
+ it { should allow('stop') }
1136
+ end
1137
+ end
1138
+ end
1139
+
1140
+ #date
1141
+ for_date_column do
1142
+ startDate = Date.today - 5
1143
+ endDate = Date.today
1144
+
1145
+ with_validator :inclusion do
1146
+ with_option :as => :trigger do
1147
+
1148
+ #closed date interval
1149
+ with_options :in => startDate..endDate do
1150
+ it { should allow(startDate, endDate - 3, endDate) }
1151
+ it { should deny(startDate - 1, endDate + 1).with_initial(endDate - 1) }
1152
+ end
1153
+
1154
+ #open date interval
1155
+ with_options :in => startDate...endDate do
1156
+ it { should allow(startDate, endDate - 3) }
1157
+ it { should deny(startDate - 1, endDate, endDate + 1).with_initial(endDate - 1) }
1158
+ end
1159
+
1160
+ #single date value
1161
+ with_options :in => endDate do
1162
+ it { should allow(endDate) }
1163
+ it { should deny(endDate - 1, endDate + 1).with_initial(endDate) }
1164
+ end
1165
+
1166
+ #array
1167
+ with_options :in => [startDate, endDate] do
1168
+ it { should allow(startDate, endDate) }
1169
+ it { should deny(startDate - 1, endDate - 1, endDate + 1).with_initial(endDate) }
1170
+ end
1171
+
1172
+ with_options :in => endDate, :message => "Some error message" do
1173
+ it { should deny(endDate + 1).with_initial(endDate).with_message(/Some error message/) }
1174
+ end
1175
+ end
1176
+
1177
+ with_option :as => :check do
1178
+
1179
+ #closed date interval
1180
+ with_options :in => startDate..endDate do
1181
+ it { should allow(startDate, endDate - 3, endDate) }
1182
+ it { should deny(startDate - 1, endDate + 1).with_initial(endDate - 1) }
1183
+ end
1184
+
1185
+ #open date interval
1186
+ with_options :in => startDate...endDate do
1187
+ it { should allow(startDate, endDate - 3) }
1188
+ it { should deny(startDate - 1, endDate, endDate + 1).with_initial(endDate - 1) }
1189
+ end
1190
+
1191
+ #single date value
1192
+ with_options :in => endDate do
1193
+ it { should allow(endDate) }
1194
+ it { should deny(endDate - 1, endDate + 1).with_initial(endDate) }
1195
+ end
1196
+
1197
+ #array
1198
+ with_options :in => [startDate, endDate] do
1199
+ it { should allow(startDate, endDate) }
1200
+ it { should deny(startDate - 1, endDate - 1, endDate + 1).with_initial(endDate) }
1201
+ end
1202
+ end
1203
+ end
1204
+
1205
+ with_validator :exclusion do
1206
+ with_option :as => :trigger do
1207
+
1208
+ #closed date interval
1209
+ with_options :in => startDate..endDate do
1210
+ it { should deny(startDate, endDate - 3, endDate).with_initial(startDate - 1) }
1211
+ it { should allow(startDate - 1, endDate + 1) }
1212
+ end
1213
+
1214
+ #open date interval
1215
+ with_options :in => startDate...endDate do
1216
+ it { should deny(startDate, endDate - 3).with_initial(startDate - 1) }
1217
+ it { should allow(startDate - 1, endDate, endDate + 1) }
1218
+ end
1219
+
1220
+ #single date value
1221
+ with_options :in => endDate do
1222
+ it { should deny(endDate).with_initial(endDate - 1) }
1223
+ it { should allow(endDate - 1, endDate + 1) }
1224
+ end
1225
+
1226
+ #array
1227
+ with_options :in => [startDate, endDate] do
1228
+ it { should deny(startDate, endDate).with_initial(startDate - 1) }
1229
+ it { should allow(startDate - 1, endDate - 1, endDate + 1) }
1230
+ end
1231
+
1232
+ with_options :in => endDate, :message => "Some error message" do
1233
+ it { should deny(endDate).with_initial(endDate - 1).with_message(/Some error message/) }
1234
+ end
1235
+ end
1236
+
1237
+ with_option :as => :check do
1238
+
1239
+ #closed date interval
1240
+ with_options :in => startDate..endDate do
1241
+ it { should deny(startDate, endDate - 3, endDate).with_initial(startDate - 1) }
1242
+ it { should allow(startDate - 1, endDate + 1) }
1243
+ end
1244
+
1245
+ #open date interval
1246
+ with_options :in => startDate...endDate do
1247
+ it { should deny(startDate, endDate - 3).with_initial(startDate - 1) }
1248
+ it { should allow(startDate - 1, endDate, endDate + 1) }
1249
+ end
1250
+
1251
+ #single date value
1252
+ with_options :in => endDate do
1253
+ it { should deny(endDate).with_initial(endDate - 1) }
1254
+ it { should allow(endDate - 1, endDate + 1) }
1255
+ end
1256
+
1257
+ #array
1258
+ with_options :in => [startDate, endDate] do
1259
+ it { should deny(startDate, endDate).with_initial(startDate - 1) }
1260
+ it { should allow(startDate - 1, endDate - 1, endDate + 1) }
1261
+ end
1262
+ end
1263
+ end
1264
+ end
1265
+
1266
+ #time
1267
+ for_time_column do
1268
+ startTime = Time.now - 10
1269
+ endTime = Time.now
1270
+
1271
+ with_validator :inclusion do
1272
+ with_option :as => :trigger do
1273
+
1274
+ #closed time interval
1275
+ with_options :in => startTime..endTime do
1276
+ it { should allow(startTime, startTime + 1, endTime) }
1277
+ it { should deny(startTime - 1, endTime + 1).with_initial(startTime) }
1278
+ end
1279
+
1280
+ #open time interval
1281
+ with_options :in => startTime...endTime do
1282
+ it { should allow(startTime, startTime + 1, endTime - 1) }
1283
+ it { should deny(startTime - 1, endTime).with_initial(startTime) }
1284
+ end
1285
+
1286
+ #single time value
1287
+ with_options :in => startTime do
1288
+ it { should allow(startTime) }
1289
+ it { should deny(startTime - 1, endTime).with_initial(startTime) }
1290
+ end
1291
+
1292
+ #array
1293
+ with_options :in => [startTime, endTime] do
1294
+ it { should allow(startTime, endTime) }
1295
+ it { should deny(startTime - 1, startTime + 1, endTime + 1).with_initial(startTime) }
1296
+ end
1297
+
1298
+ with_options :in => startTime, :message => "Some error message" do
1299
+ it { should deny(startTime + 1).with_initial(startTime).with_message(/Some error message/) }
1300
+ end
1301
+ end
1302
+
1303
+ with_option :as => :check do
1304
+
1305
+ #closed time interval
1306
+ with_options :in => startTime..endTime do
1307
+ it { should allow(startTime, startTime + 1, endTime) }
1308
+ it { should deny(startTime - 1, endTime + 1).with_initial(startTime) }
1309
+ end
1310
+
1311
+ #open time interval
1312
+ with_options :in => startTime...endTime do
1313
+ it { should allow(startTime, startTime + 1, endTime - 1) }
1314
+ it { should deny(startTime - 1, endTime).with_initial(startTime) }
1315
+ end
1316
+
1317
+ #single time value
1318
+ with_options :in => startTime do
1319
+ it { should allow(startTime) }
1320
+ it { should deny(startTime - 1, endTime).with_initial(startTime) }
1321
+ end
1322
+
1323
+ #array
1324
+ with_options :in => [startTime, endTime] do
1325
+ it { should allow(startTime, endTime) }
1326
+ it { should deny(startTime - 1, startTime + 1, endTime + 1).with_initial(startTime) }
1327
+ end
1328
+ end
1329
+ end
1330
+
1331
+ with_validator :exclusion do
1332
+ with_option :as => :trigger do
1333
+
1334
+ #closed time interval
1335
+ with_options :in => startTime..endTime do
1336
+ it { should deny(startTime, startTime + 1, endTime).with_initial(startTime - 1) }
1337
+ it { should allow(startTime - 1, endTime + 1) }
1338
+ end
1339
+
1340
+ #open time interval
1341
+ with_options :in => startTime...endTime do
1342
+ it { should deny(startTime, startTime + 1, endTime - 1).with_initial(startTime - 1) }
1343
+ it { should allow(startTime - 1, endTime) }
1344
+ end
1345
+
1346
+ #single time value
1347
+ with_options :in => startTime do
1348
+ it { should deny(startTime).with_initial(startTime - 1) }
1349
+ it { should allow(startTime - 1, endTime) }
1350
+ end
1351
+
1352
+ #array
1353
+ with_options :in => [startTime, endTime] do
1354
+ it { should deny(startTime, endTime).with_initial(startTime - 1) }
1355
+ it { should allow(startTime - 1, startTime + 1, endTime + 1)}
1356
+ end
1357
+
1358
+ with_options :in => startTime, :message => "Some error message" do
1359
+ it { should deny(startTime).with_initial(startTime - 1).with_message(/Some error message/) }
1360
+ end
1361
+ end
1362
+
1363
+ with_option :as => :check do
1364
+
1365
+ #closed time interval
1366
+ with_options :in => startTime..endTime do
1367
+ it { should deny(startTime, startTime + 1, endTime).with_initial(startTime - 1) }
1368
+ it { should allow(startTime - 1, endTime + 1) }
1369
+ end
1370
+
1371
+ #open time interval
1372
+ with_options :in => startTime...endTime do
1373
+ it { should deny(startTime, startTime + 1, endTime - 1).with_initial(startTime - 1) }
1374
+ it { should allow(startTime - 1, endTime) }
1375
+ end
1376
+
1377
+ #single time value
1378
+ with_options :in => startTime do
1379
+ it { should deny(startTime).with_initial(startTime - 1) }
1380
+ it { should allow(startTime - 1, endTime) }
1381
+ end
1382
+
1383
+ #array
1384
+ with_options :in => [startTime, endTime] do
1385
+ it { should deny(startTime, endTime).with_initial(startTime - 1) }
1386
+ it { should allow(startTime - 1, startTime + 1, endTime + 1)}
1387
+ end
1388
+ end
1389
+ end
1390
+ end
1391
+
1392
+ #datetime
1393
+ for_datetime_column do
1394
+ startDateTime = DateTime.now - 10
1395
+ endDateTime = DateTime.now
1396
+
1397
+ with_validator :inclusion do
1398
+ with_option :as => :trigger do
1399
+
1400
+ #closed time interval
1401
+ with_options :in => startDateTime..endDateTime do
1402
+ it { should allow(startDateTime, startDateTime + 1, endDateTime) }
1403
+ it { should deny(startDateTime - 1, endDateTime + 1).with_initial(startDateTime) }
1404
+ end
1405
+
1406
+ #open time interval
1407
+ with_options :in => startDateTime...endDateTime do
1408
+ it { should allow(startDateTime, startDateTime + 1, endDateTime - 1) }
1409
+ it { should deny(startDateTime - 1, endDateTime).with_initial(startDateTime) }
1410
+ end
1411
+
1412
+ #single time value
1413
+ with_options :in => startDateTime do
1414
+ it { should allow(startDateTime) }
1415
+ it { should deny(startDateTime - 1, endDateTime).with_initial(startDateTime) }
1416
+ end
1417
+
1418
+ #array
1419
+ with_options :in => [startDateTime, endDateTime] do
1420
+ it { should allow(startDateTime, endDateTime) }
1421
+ it { should deny(startDateTime - 1, startDateTime + 1, endDateTime + 1).with_initial(startDateTime) }
1422
+ end
1423
+
1424
+ with_options :in => startDateTime, :message => "Some error message" do
1425
+ it { should deny(startDateTime + 1).with_initial(startDateTime).with_message(/Some error message/) }
1426
+ end
1427
+ end
1428
+
1429
+ with_option :as => :check do
1430
+
1431
+ #closed time interval
1432
+ with_options :in => startDateTime..endDateTime do
1433
+ it { should allow(startDateTime, startDateTime + 1, endDateTime) }
1434
+ it { should deny(startDateTime - 1, endDateTime + 1).with_initial(startDateTime) }
1435
+ end
1436
+
1437
+ #open time interval
1438
+ with_options :in => startDateTime...endDateTime do
1439
+ it { should allow(startDateTime, startDateTime + 1, endDateTime - 1) }
1440
+ it { should deny(startDateTime - 1, endDateTime).with_initial(startDateTime) }
1441
+ end
1442
+
1443
+ #single time value
1444
+ with_options :in => startDateTime do
1445
+ it { should allow(startDateTime) }
1446
+ it { should deny(startDateTime - 1, endDateTime).with_initial(startDateTime) }
1447
+ end
1448
+
1449
+ #array
1450
+ with_options :in => [startDateTime, endDateTime] do
1451
+ it { should allow(startDateTime, endDateTime) }
1452
+ it { should deny(startDateTime - 1, startDateTime + 1, endDateTime + 1).with_initial(startDateTime) }
1453
+ end
1454
+ end
1455
+ end
1456
+
1457
+ with_validator :exclusion do
1458
+ with_option :as => :trigger do
1459
+
1460
+ #closed time interval
1461
+ with_options :in => startDateTime..endDateTime do
1462
+ it { should deny(startDateTime, startDateTime + 1, endDateTime).with_initial(startDateTime - 1) }
1463
+ it { should allow(startDateTime - 1, endDateTime + 1) }
1464
+ end
1465
+
1466
+ #open time interval
1467
+ with_options :in => startDateTime...endDateTime do
1468
+ it { should deny(startDateTime, startDateTime + 1, endDateTime - 1).with_initial(startDateTime - 1) }
1469
+ it { should allow(startDateTime - 1, endDateTime) }
1470
+ end
1471
+
1472
+ #single time value
1473
+ with_options :in => startDateTime do
1474
+ it { should deny(startDateTime).with_initial(startDateTime - 1) }
1475
+ it { should allow(startDateTime - 1, endDateTime) }
1476
+ end
1477
+
1478
+ #array
1479
+ with_options :in => [startDateTime, endDateTime] do
1480
+ it { should deny(startDateTime, endDateTime).with_initial(startDateTime - 1) }
1481
+ it { should allow(startDateTime - 1, startDateTime + 1, endDateTime + 1) }
1482
+ end
1483
+
1484
+ with_options :in => startDateTime, :message => "Some error message" do
1485
+ it { should deny(startDateTime).with_initial(startDateTime - 1).with_message(/Some error message/) }
1486
+ end
1487
+ end
1488
+
1489
+ with_option :as => :check do
1490
+
1491
+ #closed time interval
1492
+ with_options :in => startDateTime..endDateTime do
1493
+ it { should deny(startDateTime, startDateTime + 1, endDateTime).with_initial(startDateTime - 1) }
1494
+ it { should allow(startDateTime - 1, endDateTime + 1) }
1495
+ end
1496
+
1497
+ #open time interval
1498
+ with_options :in => startDateTime...endDateTime do
1499
+ it { should deny(startDateTime, startDateTime + 1, endDateTime - 1).with_initial(startDateTime - 1) }
1500
+ it { should allow(startDateTime - 1, endDateTime) }
1501
+ end
1502
+
1503
+ #single time value
1504
+ with_options :in => startDateTime do
1505
+ it { should deny(startDateTime).with_initial(startDateTime - 1) }
1506
+ it { should allow(startDateTime - 1, endDateTime) }
1507
+ end
1508
+
1509
+ #array
1510
+ with_options :in => [startDateTime, endDateTime] do
1511
+ it { should deny(startDateTime, endDateTime).with_initial(startDateTime - 1) }
1512
+ it { should allow(startDateTime - 1, startDateTime + 1, endDateTime + 1) }
1513
+ end
1514
+ end
1515
+ end
1516
+ end
1517
+ end
1518
+ end