sexy_pg_constraints 0.1.2 → 0.2.0
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/Manifest +4 -0
- data/README.rdoc +6 -0
- data/Rakefile +1 -1
- data/lib/constrainer.rb +1 -1
- data/lib/constraints.rb +80 -55
- data/sexy_pg_constraints.gemspec +3 -3
- data/test/sexy_pg_constraints_test.rb +597 -270
- data/test/support/assert_prohibits_allows.rb +28 -0
- data/test/support/database.yml +6 -0
- data/test/support/database.yml.example +6 -0
- data/test/support/models.rb +36 -0
- data/test/test_helper.rb +6 -1
- metadata +6 -2
data/Manifest
CHANGED
@@ -11,4 +11,8 @@ lib/sexy_pg_constraints.rb
|
|
11
11
|
sexy_pg_constraints.gemspec
|
12
12
|
test/postgresql_adapter.rb
|
13
13
|
test/sexy_pg_constraints_test.rb
|
14
|
+
test/support/assert_prohibits_allows.rb
|
15
|
+
test/support/database.yml
|
16
|
+
test/support/database.yml.example
|
17
|
+
test/support/models.rb
|
14
18
|
test/test_helper.rb
|
data/README.rdoc
CHANGED
@@ -106,6 +106,8 @@ Below is the list of constraints available and tested so far.
|
|
106
106
|
* even
|
107
107
|
* odd
|
108
108
|
* format
|
109
|
+
* lowercase
|
110
|
+
* xor
|
109
111
|
|
110
112
|
== Extensibility
|
111
113
|
|
@@ -113,8 +115,12 @@ All constraints are located in the lib/constraints.rb. Extending this module wit
|
|
113
115
|
|
114
116
|
== TODO
|
115
117
|
|
118
|
+
* Add support for Rails schema.rb
|
116
119
|
* Create better API for adding constraints
|
117
120
|
|
121
|
+
== Contributors
|
122
|
+
* Empact[http://github.com/Empact] (Big thanks for lots of work. Better flexibility, more tests, organizing code, bug fixes.)
|
123
|
+
|
118
124
|
== License
|
119
125
|
|
120
126
|
Copyright (c) 2008 Maxim Chernyak
|
data/Rakefile
CHANGED
@@ -2,7 +2,7 @@ require 'rubygems'
|
|
2
2
|
require 'rake'
|
3
3
|
require 'echoe'
|
4
4
|
|
5
|
-
Echoe.new('sexy_pg_constraints', '0.
|
5
|
+
Echoe.new('sexy_pg_constraints', '0.2.0') do |p|
|
6
6
|
p.description = "Use migrations and simple syntax to manage constraints in PostgreSQL DB."
|
7
7
|
p.summary = "If you're on PostgreSQL and see the importance of data-layer constraints - this gem/plugin is for you. It integrates constraints into PostgreSQL adapter so you can add/remove them in your migrations. You get two simple methods for adding/removing constraints, as well as a pack of pre-made constraints."
|
8
8
|
p.url = "http://github.com/maxim/sexy_pg_constraints"
|
data/lib/constrainer.rb
CHANGED
@@ -24,7 +24,7 @@ module SexyPgConstraints
|
|
24
24
|
def add_constraints(table, column, constraints)
|
25
25
|
constraints.each_pair do |type, options|
|
26
26
|
sql = "alter table #{table} add constraint #{make_title(table, column, type)} " +
|
27
|
-
SexyPgConstraints::Constraints.send(type, column, options) + ';'
|
27
|
+
SexyPgConstraints::Constraints.send(type, table, column, options) + ';'
|
28
28
|
|
29
29
|
execute sql
|
30
30
|
end
|
data/lib/constraints.rb
CHANGED
@@ -1,38 +1,38 @@
|
|
1
1
|
module SexyPgConstraints
|
2
2
|
module Constraints
|
3
3
|
module_function
|
4
|
-
|
4
|
+
|
5
5
|
##
|
6
6
|
# Only allow listed values.
|
7
7
|
#
|
8
|
-
# Example:
|
8
|
+
# Example:
|
9
9
|
# constrain :books, :variation, :whitelist => %w(hardcover softcover)
|
10
10
|
#
|
11
|
-
def whitelist(column, options)
|
12
|
-
"check (#{column} in (#{ options.collect{|v| "'#{v}'"}.join(',') }))"
|
11
|
+
def whitelist(table, column, options)
|
12
|
+
"check (#{table}.#{column} in (#{ options.collect{|v| "'#{v}'"}.join(',') }))"
|
13
13
|
end
|
14
|
-
|
15
|
-
##
|
14
|
+
|
15
|
+
##
|
16
16
|
# Prohibit listed values.
|
17
17
|
#
|
18
|
-
# Example:
|
18
|
+
# Example:
|
19
19
|
# constrain :books, :isbn, :blacklist => %w(invalid_isbn1 invalid_isbn2)
|
20
20
|
#
|
21
|
-
def blacklist(column, options)
|
22
|
-
"check (#{column} not in (#{ options.collect{|v| "'#{v}'"}.join(',') }))"
|
21
|
+
def blacklist(table, column, options)
|
22
|
+
"check (#{table}.#{column} not in (#{ options.collect{|v| "'#{v}'"}.join(',') }))"
|
23
23
|
end
|
24
|
-
|
25
|
-
##
|
24
|
+
|
25
|
+
##
|
26
26
|
# The value must have at least 1 non-space character.
|
27
27
|
#
|
28
28
|
# Example:
|
29
29
|
# constrain :books, :title, :not_blank => true
|
30
30
|
#
|
31
|
-
def not_blank(column, options)
|
32
|
-
"check ( length(trim(both from #{column})) > 0 )"
|
31
|
+
def not_blank(table, column, options)
|
32
|
+
"check ( length(trim(both from #{table}.#{column})) > 0 )"
|
33
33
|
end
|
34
34
|
|
35
|
-
##
|
35
|
+
##
|
36
36
|
# The numeric value must be within given range.
|
37
37
|
#
|
38
38
|
# Example:
|
@@ -40,115 +40,140 @@ module SexyPgConstraints
|
|
40
40
|
# constrain :books, :year, :within => 1980...2009
|
41
41
|
# (the two lines above do the same thing)
|
42
42
|
#
|
43
|
-
def within(column, options)
|
44
|
-
|
43
|
+
def within(table, column, options)
|
44
|
+
column_ref = column.to_s.include?('.') ? column : "#{table}.#{column}"
|
45
|
+
"check (#{column_ref} >= #{options.begin} and #{column_ref} #{options.exclude_end? ? ' < ' : ' <= '} #{options.end})"
|
45
46
|
end
|
46
47
|
|
47
|
-
##
|
48
|
+
##
|
48
49
|
# Check the length of strings/text to be within the range.
|
49
50
|
#
|
50
51
|
# Example:
|
51
52
|
# constrain :books, :author, :length_within => 4..50
|
52
53
|
#
|
53
|
-
def length_within(column, options)
|
54
|
-
within("length(#{column})", options)
|
54
|
+
def length_within(table, column, options)
|
55
|
+
within(table, "length(#{table}.#{column})", options)
|
55
56
|
end
|
56
|
-
|
57
|
-
##
|
57
|
+
|
58
|
+
##
|
58
59
|
# Allow only valid email format.
|
59
60
|
#
|
60
61
|
# Example:
|
61
62
|
# constrain :books, :author, :email => true
|
62
63
|
#
|
63
|
-
def email(column, options)
|
64
|
-
"check (((#{column})::text ~ E'^([-a-z0-9]+)@([-a-z0-9]+[.]+[a-z]{2,4})$'::text))"
|
64
|
+
def email(table, column, options)
|
65
|
+
"check (((#{table}.#{column})::text ~ E'^([-a-z0-9]+)@([-a-z0-9]+[.]+[a-z]{2,4})$'::text))"
|
65
66
|
end
|
66
67
|
|
67
|
-
##
|
68
|
+
##
|
68
69
|
# Allow only alphanumeric values.
|
69
70
|
#
|
70
71
|
# Example:
|
71
72
|
# constrain :books, :author, :alphanumeric => true
|
72
73
|
#
|
73
|
-
def alphanumeric(column, options)
|
74
|
-
"check (((#{column})::text ~* '^[a-z0-9]+$'::text))"
|
74
|
+
def alphanumeric(table, column, options)
|
75
|
+
"check (((#{table}.#{column})::text ~* '^[a-z0-9]+$'::text))"
|
76
|
+
end
|
77
|
+
|
78
|
+
##
|
79
|
+
# Allow only lower case values.
|
80
|
+
#
|
81
|
+
# Example:
|
82
|
+
# constrain :books, :author, :lowercase => true
|
83
|
+
#
|
84
|
+
def lowercase(table, column, options)
|
85
|
+
"check (#{table}.#{column} = lower(#{table}.#{column}))"
|
75
86
|
end
|
76
|
-
|
77
|
-
##
|
87
|
+
|
88
|
+
##
|
78
89
|
# Allow only positive values.
|
79
90
|
#
|
80
91
|
# Example:
|
81
92
|
# constrain :books, :quantity, :positive => true
|
82
93
|
#
|
83
|
-
def positive(column, options)
|
84
|
-
"check (#{column} >= 0)"
|
94
|
+
def positive(table, column, options)
|
95
|
+
"check (#{table}.#{column} >= 0)"
|
85
96
|
end
|
86
|
-
|
87
|
-
##
|
97
|
+
|
98
|
+
##
|
88
99
|
# Allow only odd values.
|
89
100
|
#
|
90
101
|
# Example:
|
91
102
|
# constrain :books, :quantity, :odd => true
|
92
103
|
#
|
93
|
-
def odd(column, options)
|
94
|
-
"check (mod(#{column}, 2) != 0)"
|
104
|
+
def odd(table, column, options)
|
105
|
+
"check (mod(#{table}.#{column}, 2) != 0)"
|
95
106
|
end
|
96
107
|
|
97
|
-
##
|
108
|
+
##
|
98
109
|
# Allow only even values.
|
99
110
|
#
|
100
111
|
# Example:
|
101
112
|
# constrain :books, :quantity, :even => true
|
102
113
|
#
|
103
|
-
def even(column, options)
|
104
|
-
"check (mod(#{column}, 2) = 0)"
|
114
|
+
def even(table, column, options)
|
115
|
+
"check (mod(#{table}.#{column}, 2) = 0)"
|
105
116
|
end
|
106
117
|
|
107
|
-
##
|
118
|
+
##
|
108
119
|
# Make sure every entry in the column is unique.
|
109
120
|
#
|
110
121
|
# Example:
|
111
122
|
# constrain :books, :isbn, :unique => true
|
112
123
|
#
|
113
|
-
def unique(column, options)
|
114
|
-
column = column.join(', ')
|
124
|
+
def unique(table, column, options)
|
125
|
+
column = Array(column).map {|c| %{"#{c}"} }.join(', ')
|
115
126
|
"unique (#{column})"
|
116
127
|
end
|
117
|
-
|
118
|
-
##
|
128
|
+
|
129
|
+
##
|
130
|
+
# Allow only one of the values in the given columns to be true.
|
131
|
+
# Only reasonable with more than one column.
|
132
|
+
# See Enterprise Rails, Chapter 10 for details.
|
133
|
+
#
|
134
|
+
# Example:
|
135
|
+
# constrain :books, [], :xor => true
|
136
|
+
#
|
137
|
+
def xor(table, column, options)
|
138
|
+
addition = Array(column).map {|c| %{("#{c}" is not null)::integer} }.join(' + ')
|
139
|
+
|
140
|
+
"check (#{addition} = 1)"
|
141
|
+
end
|
142
|
+
|
143
|
+
##
|
119
144
|
# Allow only text/strings of the exact length specified, no more, no less.
|
120
145
|
#
|
121
146
|
# Example:
|
122
147
|
# constrain :books, :hash, :exact_length => 32
|
123
148
|
#
|
124
|
-
def exact_length(column, options)
|
125
|
-
"check ( length(trim(both from #{column})) = #{options} )"
|
149
|
+
def exact_length(table, column, options)
|
150
|
+
"check ( length(trim(both from #{table}.#{column})) = #{options} )"
|
126
151
|
end
|
127
|
-
|
128
|
-
##
|
152
|
+
|
153
|
+
##
|
129
154
|
# Allow only values that match the regular expression.
|
130
155
|
#
|
131
156
|
# Example:
|
132
157
|
# constrain :orders, :visa, :format => /^([4]{1})([0-9]{12,15})$/
|
133
158
|
#
|
134
|
-
def format(column, options)
|
135
|
-
"check (((#{column})::text #{options.casefold? ? '~*' : '~'} E'#{options.source}'::text ))"
|
159
|
+
def format(table, column, options)
|
160
|
+
"check (((#{table}.#{column})::text #{options.casefold? ? '~*' : '~'} E'#{options.source}'::text ))"
|
136
161
|
end
|
137
|
-
|
138
|
-
##
|
162
|
+
|
163
|
+
##
|
139
164
|
# Add foreign key constraint.
|
140
165
|
#
|
141
166
|
# Example:
|
142
167
|
# constrain :books, :author_id, :reference => {:authors => :id, :on_delete => :cascade}
|
143
168
|
#
|
144
|
-
def reference(column, options)
|
169
|
+
def reference(table, column, options)
|
145
170
|
on_delete = options.delete(:on_delete)
|
146
171
|
fk_table = options.keys.first
|
147
172
|
fk_column = options[fk_table]
|
148
|
-
|
173
|
+
|
149
174
|
on_delete = "on delete #{on_delete}" if on_delete
|
150
|
-
|
151
|
-
|
175
|
+
|
176
|
+
%{foreign key ("#{column}") references #{fk_table} (#{fk_column}) #{on_delete}}
|
152
177
|
end
|
153
178
|
end
|
154
|
-
end
|
179
|
+
end
|
data/sexy_pg_constraints.gemspec
CHANGED
@@ -2,15 +2,15 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{sexy_pg_constraints}
|
5
|
-
s.version = "0.
|
5
|
+
s.version = "0.2.0"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Maxim Chernyak"]
|
9
|
-
s.date = %q{
|
9
|
+
s.date = %q{2010-02-01}
|
10
10
|
s.description = %q{Use migrations and simple syntax to manage constraints in PostgreSQL DB.}
|
11
11
|
s.email = %q{max@bitsonnet.com}
|
12
12
|
s.extra_rdoc_files = ["CHANGELOG.rdoc", "README.rdoc", "lib/constrainer.rb", "lib/constraints.rb", "lib/deconstrainer.rb", "lib/helpers.rb", "lib/sexy_pg_constraints.rb"]
|
13
|
-
s.files = ["CHANGELOG.rdoc", "Manifest", "README.rdoc", "Rakefile", "init.rb", "lib/constrainer.rb", "lib/constraints.rb", "lib/deconstrainer.rb", "lib/helpers.rb", "lib/sexy_pg_constraints.rb", "sexy_pg_constraints.gemspec", "test/postgresql_adapter.rb", "test/sexy_pg_constraints_test.rb", "test/test_helper.rb"]
|
13
|
+
s.files = ["CHANGELOG.rdoc", "Manifest", "README.rdoc", "Rakefile", "init.rb", "lib/constrainer.rb", "lib/constraints.rb", "lib/deconstrainer.rb", "lib/helpers.rb", "lib/sexy_pg_constraints.rb", "sexy_pg_constraints.gemspec", "test/postgresql_adapter.rb", "test/sexy_pg_constraints_test.rb", "test/support/assert_prohibits_allows.rb", "test/support/database.yml", "test/support/database.yml.example", "test/support/models.rb", "test/test_helper.rb"]
|
14
14
|
s.homepage = %q{http://github.com/maxim/sexy_pg_constraints}
|
15
15
|
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Sexy_pg_constraints", "--main", "README.rdoc"]
|
16
16
|
s.require_paths = ["lib"]
|
@@ -1,572 +1,899 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/test_helper.rb'
|
2
2
|
|
3
|
-
# Database spc_test should be created manually.
|
4
|
-
ActiveRecord::Base.establish_connection(:adapter => "postgresql", :database => "spc_test")
|
5
|
-
|
6
|
-
# Setting up sample migrations
|
7
|
-
class CreateBooks < ActiveRecord::Migration
|
8
|
-
def self.up
|
9
|
-
create_table :books do |t|
|
10
|
-
t.string :title
|
11
|
-
t.string :author
|
12
|
-
t.integer :author_id
|
13
|
-
t.integer :quantity
|
14
|
-
t.string :isbn
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
def self.down
|
19
|
-
drop_table :books
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
class CreateAuthors < ActiveRecord::Migration
|
24
|
-
def self.up
|
25
|
-
create_table :authors do |t|
|
26
|
-
t.string :name
|
27
|
-
t.string :bio
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def self.down
|
32
|
-
drop_table :authors
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
class Book < ActiveRecord::Base; end
|
37
|
-
class Author < ActiveRecord::Base; end
|
38
|
-
|
39
3
|
class SexyPgConstraintsTest < Test::Unit::TestCase
|
40
4
|
def setup
|
41
5
|
CreateBooks.up
|
42
6
|
CreateAuthors.up
|
43
7
|
end
|
44
|
-
|
8
|
+
|
45
9
|
def teardown
|
46
10
|
CreateBooks.down
|
47
11
|
CreateAuthors.down
|
48
12
|
end
|
49
|
-
|
13
|
+
|
50
14
|
def test_should_create_book
|
51
15
|
Book.create
|
52
16
|
assert_equal 1, Book.count
|
53
17
|
end
|
54
|
-
|
18
|
+
|
55
19
|
def test_whitelist
|
56
20
|
ActiveRecord::Migration.constrain :books, :author, :whitelist => %w(whitelisted1 whitelisted2 whitelisted3)
|
57
|
-
|
58
|
-
assert_prohibits :author, :whitelist do |book|
|
21
|
+
|
22
|
+
assert_prohibits Book, :author, :whitelist do |book|
|
59
23
|
book.author = 'not_whitelisted'
|
60
24
|
end
|
61
|
-
|
62
|
-
assert_allows do |book|
|
25
|
+
|
26
|
+
assert_allows Book do |book|
|
63
27
|
book.author = 'whitelisted2'
|
64
28
|
end
|
65
|
-
|
29
|
+
|
66
30
|
ActiveRecord::Migration.deconstrain :books, :author, :whitelist
|
67
|
-
|
68
|
-
assert_allows do |book|
|
31
|
+
|
32
|
+
assert_allows Book do |book|
|
69
33
|
book.author = 'not_whitelisted'
|
70
34
|
end
|
71
35
|
end
|
72
|
-
|
36
|
+
|
37
|
+
def test_whitelist_on_a_column_whose_name_is_a_sql_keyword
|
38
|
+
ActiveRecord::Migration.constrain :books, :as, :whitelist => %w(whitelisted1 whitelisted2 whitelisted3)
|
39
|
+
|
40
|
+
assert_prohibits Book, :as, :whitelist do |book|
|
41
|
+
book.as = 'not_whitelisted'
|
42
|
+
end
|
43
|
+
|
44
|
+
assert_allows Book do |book|
|
45
|
+
book.as = 'whitelisted2'
|
46
|
+
end
|
47
|
+
|
48
|
+
ActiveRecord::Migration.deconstrain :books, :as, :whitelist
|
49
|
+
|
50
|
+
assert_allows Book do |book|
|
51
|
+
book.as = 'not_whitelisted'
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
73
55
|
def test_blacklist
|
74
56
|
ActiveRecord::Migration.constrain :books, :author, :blacklist => %w(blacklisted1 blacklisted2 blacklisted3)
|
75
|
-
|
76
|
-
assert_prohibits :author, :blacklist do |book|
|
57
|
+
|
58
|
+
assert_prohibits Book, :author, :blacklist do |book|
|
77
59
|
book.author = 'blacklisted2'
|
78
60
|
end
|
79
|
-
|
80
|
-
assert_allows do |book|
|
61
|
+
|
62
|
+
assert_allows Book do |book|
|
81
63
|
book.author = 'not_blacklisted'
|
82
64
|
end
|
83
|
-
|
65
|
+
|
84
66
|
ActiveRecord::Migration.deconstrain :books, :author, :blacklist
|
85
|
-
|
86
|
-
assert_allows do |book|
|
67
|
+
|
68
|
+
assert_allows Book do |book|
|
87
69
|
book.author = 'blacklisted2'
|
88
70
|
end
|
89
71
|
end
|
90
|
-
|
72
|
+
|
73
|
+
def test_blacklist_on_a_column_whose_name_is_a_sql_keyword
|
74
|
+
ActiveRecord::Migration.constrain :books, :as, :blacklist => %w(blacklisted1 blacklisted2 blacklisted3)
|
75
|
+
|
76
|
+
assert_prohibits Book, :as, :blacklist do |book|
|
77
|
+
book.as = 'blacklisted2'
|
78
|
+
end
|
79
|
+
|
80
|
+
assert_allows Book do |book|
|
81
|
+
book.as = 'not_blacklisted'
|
82
|
+
end
|
83
|
+
|
84
|
+
ActiveRecord::Migration.deconstrain :books, :as, :blacklist
|
85
|
+
|
86
|
+
assert_allows Book do |book|
|
87
|
+
book.as = 'blacklisted2'
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
91
|
def test_not_blank
|
92
92
|
ActiveRecord::Migration.constrain :books, :author, :not_blank => true
|
93
|
-
|
94
|
-
assert_prohibits :author, :not_blank do |book|
|
93
|
+
|
94
|
+
assert_prohibits Book, :author, :not_blank do |book|
|
95
95
|
book.author = ' '
|
96
96
|
end
|
97
|
-
|
98
|
-
assert_allows do |book|
|
97
|
+
|
98
|
+
assert_allows Book do |book|
|
99
99
|
book.author = 'foo'
|
100
100
|
end
|
101
|
-
|
101
|
+
|
102
102
|
ActiveRecord::Migration.deconstrain :books, :author, :not_blank
|
103
|
-
|
104
|
-
assert_allows do |book|
|
103
|
+
|
104
|
+
assert_allows Book do |book|
|
105
105
|
book.author = ' '
|
106
106
|
end
|
107
107
|
end
|
108
|
-
|
108
|
+
|
109
|
+
def test_not_blank_on_a_column_whose_name_is_a_sql_keyword
|
110
|
+
ActiveRecord::Migration.constrain :books, :as, :not_blank => true
|
111
|
+
|
112
|
+
assert_prohibits Book, :as, :not_blank do |book|
|
113
|
+
book.as = ' '
|
114
|
+
end
|
115
|
+
|
116
|
+
assert_allows Book do |book|
|
117
|
+
book.as = 'foo'
|
118
|
+
end
|
119
|
+
|
120
|
+
ActiveRecord::Migration.deconstrain :books, :as, :not_blank
|
121
|
+
|
122
|
+
assert_allows Book do |book|
|
123
|
+
book.as = ' '
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
109
127
|
def test_within_inclusive
|
110
128
|
ActiveRecord::Migration.constrain :books, :quantity, :within => 5..11
|
111
|
-
|
112
|
-
assert_prohibits :quantity, :within do |book|
|
129
|
+
|
130
|
+
assert_prohibits Book, :quantity, :within do |book|
|
113
131
|
book.quantity = 12
|
114
132
|
end
|
115
|
-
|
116
|
-
assert_prohibits :quantity, :within do |book|
|
133
|
+
|
134
|
+
assert_prohibits Book, :quantity, :within do |book|
|
117
135
|
book.quantity = 4
|
118
136
|
end
|
119
|
-
|
120
|
-
assert_allows do |book|
|
137
|
+
|
138
|
+
assert_allows Book do |book|
|
121
139
|
book.quantity = 7
|
122
140
|
end
|
123
|
-
|
141
|
+
|
124
142
|
ActiveRecord::Migration.deconstrain :books, :quantity, :within
|
125
|
-
|
126
|
-
assert_allows do |book|
|
143
|
+
|
144
|
+
assert_allows Book do |book|
|
127
145
|
book.quantity = 12
|
128
146
|
end
|
129
147
|
end
|
130
|
-
|
148
|
+
|
149
|
+
def test_within_inclusive_on_a_column_whose_name_is_a_sql_keyword
|
150
|
+
ActiveRecord::Migration.constrain :books, :from, :within => 5..11
|
151
|
+
|
152
|
+
assert_prohibits Book, :from, :within do |book|
|
153
|
+
book.from = 12
|
154
|
+
end
|
155
|
+
|
156
|
+
assert_prohibits Book, :from, :within do |book|
|
157
|
+
book.from = 4
|
158
|
+
end
|
159
|
+
|
160
|
+
assert_allows Book do |book|
|
161
|
+
book.from = 7
|
162
|
+
end
|
163
|
+
|
164
|
+
ActiveRecord::Migration.deconstrain :books, :from, :within
|
165
|
+
|
166
|
+
assert_allows Book do |book|
|
167
|
+
book.from = 12
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
131
171
|
def test_within_non_inclusive
|
132
172
|
ActiveRecord::Migration.constrain :books, :quantity, :within => 5...11
|
133
|
-
|
134
|
-
assert_prohibits :quantity, :within do |book|
|
173
|
+
|
174
|
+
assert_prohibits Book, :quantity, :within do |book|
|
135
175
|
book.quantity = 11
|
136
176
|
end
|
137
|
-
|
138
|
-
assert_prohibits :quantity, :within do |book|
|
177
|
+
|
178
|
+
assert_prohibits Book, :quantity, :within do |book|
|
139
179
|
book.quantity = 4
|
140
180
|
end
|
141
|
-
|
142
|
-
assert_allows do |book|
|
181
|
+
|
182
|
+
assert_allows Book do |book|
|
143
183
|
book.quantity = 10
|
144
184
|
end
|
145
|
-
|
185
|
+
|
146
186
|
ActiveRecord::Migration.deconstrain :books, :quantity, :within
|
147
|
-
|
148
|
-
assert_allows do |book|
|
187
|
+
|
188
|
+
assert_allows Book do |book|
|
149
189
|
book.quantity = 11
|
150
190
|
end
|
151
191
|
end
|
152
|
-
|
192
|
+
|
193
|
+
def test_within_non_inclusive_on_a_column_whose_name_is_a_sql_keyword
|
194
|
+
ActiveRecord::Migration.constrain :books, :from, :within => 5...11
|
195
|
+
|
196
|
+
assert_prohibits Book, :from, :within do |book|
|
197
|
+
book.from = 11
|
198
|
+
end
|
199
|
+
|
200
|
+
assert_prohibits Book, :from, :within do |book|
|
201
|
+
book.from = 4
|
202
|
+
end
|
203
|
+
|
204
|
+
assert_allows Book do |book|
|
205
|
+
book.from = 10
|
206
|
+
end
|
207
|
+
|
208
|
+
ActiveRecord::Migration.deconstrain :books, :from, :within
|
209
|
+
|
210
|
+
assert_allows Book do |book|
|
211
|
+
book.from = 11
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
153
215
|
def test_length_within_inclusive
|
154
216
|
ActiveRecord::Migration.constrain :books, :title, :length_within => 5..11
|
155
|
-
|
156
|
-
assert_prohibits :title, :length_within do |book|
|
217
|
+
|
218
|
+
assert_prohibits Book, :title, :length_within do |book|
|
157
219
|
book.title = 'abcdefghijkl'
|
158
220
|
end
|
159
|
-
|
160
|
-
assert_prohibits :title, :length_within do |book|
|
221
|
+
|
222
|
+
assert_prohibits Book, :title, :length_within do |book|
|
161
223
|
book.title = 'abcd'
|
162
224
|
end
|
163
|
-
|
164
|
-
assert_allows do |book|
|
225
|
+
|
226
|
+
assert_allows Book do |book|
|
165
227
|
book.title = 'abcdefg'
|
166
228
|
end
|
167
|
-
|
229
|
+
|
168
230
|
ActiveRecord::Migration.deconstrain :books, :title, :length_within
|
169
|
-
|
170
|
-
assert_allows do |book|
|
231
|
+
|
232
|
+
assert_allows Book do |book|
|
171
233
|
book.title = 'abcdefghijkl'
|
172
234
|
end
|
173
235
|
end
|
174
|
-
|
236
|
+
|
237
|
+
def test_length_within_inclusive_on_a_column_whose_name_is_a_sql_keyword
|
238
|
+
ActiveRecord::Migration.constrain :books, :as, :length_within => 5..11
|
239
|
+
|
240
|
+
assert_prohibits Book, :as, :length_within do |book|
|
241
|
+
book.as = 'abcdefghijkl'
|
242
|
+
end
|
243
|
+
|
244
|
+
assert_prohibits Book, :as, :length_within do |book|
|
245
|
+
book.as = 'abcd'
|
246
|
+
end
|
247
|
+
|
248
|
+
assert_allows Book do |book|
|
249
|
+
book.as = 'abcdefg'
|
250
|
+
end
|
251
|
+
|
252
|
+
ActiveRecord::Migration.deconstrain :books, :as, :length_within
|
253
|
+
|
254
|
+
assert_allows Book do |book|
|
255
|
+
book.as = 'abcdefghijkl'
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
175
259
|
def test_length_within_non_inclusive
|
176
260
|
ActiveRecord::Migration.constrain :books, :title, :length_within => 5...11
|
177
|
-
|
178
|
-
assert_prohibits :title, :length_within do |book|
|
261
|
+
|
262
|
+
assert_prohibits Book, :title, :length_within do |book|
|
179
263
|
book.title = 'abcdefghijk'
|
180
264
|
end
|
181
|
-
|
182
|
-
assert_prohibits :title, :length_within do |book|
|
265
|
+
|
266
|
+
assert_prohibits Book, :title, :length_within do |book|
|
183
267
|
book.title = 'abcd'
|
184
268
|
end
|
185
|
-
|
186
|
-
assert_allows do |book|
|
269
|
+
|
270
|
+
assert_allows Book do |book|
|
187
271
|
book.title = 'abcdefg'
|
188
272
|
end
|
189
|
-
|
273
|
+
|
190
274
|
ActiveRecord::Migration.deconstrain :books, :title, :length_within
|
191
|
-
|
192
|
-
assert_allows do |book|
|
275
|
+
|
276
|
+
assert_allows Book do |book|
|
193
277
|
book.title = 'abcdefghijk'
|
194
278
|
end
|
195
279
|
end
|
196
|
-
|
280
|
+
|
281
|
+
def test_length_within_non_inclusive_on_a_column_whose_name_is_a_sql_keyword
|
282
|
+
ActiveRecord::Migration.constrain :books, :as, :length_within => 5...11
|
283
|
+
|
284
|
+
assert_prohibits Book, :as, :length_within do |book|
|
285
|
+
book.as = 'abcdefghijk'
|
286
|
+
end
|
287
|
+
|
288
|
+
assert_prohibits Book, :as, :length_within do |book|
|
289
|
+
book.as = 'abcd'
|
290
|
+
end
|
291
|
+
|
292
|
+
assert_allows Book do |book|
|
293
|
+
book.as = 'abcdefg'
|
294
|
+
end
|
295
|
+
|
296
|
+
ActiveRecord::Migration.deconstrain :books, :as, :length_within
|
297
|
+
|
298
|
+
assert_allows Book do |book|
|
299
|
+
book.as = 'abcdefghijk'
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
197
303
|
def test_email
|
198
304
|
ActiveRecord::Migration.constrain :books, :author, :email => true
|
199
|
-
|
200
|
-
assert_prohibits :author, :email do |book|
|
305
|
+
|
306
|
+
assert_prohibits Book, :author, :email do |book|
|
201
307
|
book.author = 'blah@example'
|
202
308
|
end
|
203
|
-
|
204
|
-
assert_allows do |book|
|
309
|
+
|
310
|
+
assert_allows Book do |book|
|
205
311
|
book.author = 'blah@example.com'
|
206
312
|
end
|
207
|
-
|
313
|
+
|
208
314
|
ActiveRecord::Migration.deconstrain :books, :author, :email
|
209
|
-
|
210
|
-
assert_allows do |book|
|
315
|
+
|
316
|
+
assert_allows Book do |book|
|
211
317
|
book.author = 'blah@example'
|
212
318
|
end
|
213
|
-
end
|
214
|
-
|
319
|
+
end
|
320
|
+
|
321
|
+
def test_email_on_a_column_whose_name_is_a_sql_keyword
|
322
|
+
ActiveRecord::Migration.constrain :books, :as, :email => true
|
323
|
+
|
324
|
+
assert_prohibits Book, :as, :email do |book|
|
325
|
+
book.as = 'blah@example'
|
326
|
+
end
|
327
|
+
|
328
|
+
assert_allows Book do |book|
|
329
|
+
book.as = 'blah@example.com'
|
330
|
+
end
|
331
|
+
|
332
|
+
ActiveRecord::Migration.deconstrain :books, :as, :email
|
333
|
+
|
334
|
+
assert_allows Book do |book|
|
335
|
+
book.as = 'blah@example'
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
215
339
|
def test_alphanumeric
|
216
340
|
ActiveRecord::Migration.constrain :books, :title, :alphanumeric => true
|
217
|
-
|
218
|
-
assert_prohibits :title, :alphanumeric do |book|
|
341
|
+
|
342
|
+
assert_prohibits Book, :title, :alphanumeric do |book|
|
219
343
|
book.title = 'asdf@asdf'
|
220
344
|
end
|
221
|
-
|
222
|
-
assert_allows do |book|
|
345
|
+
|
346
|
+
assert_allows Book do |book|
|
223
347
|
book.title = 'asdf'
|
224
348
|
end
|
225
|
-
|
349
|
+
|
226
350
|
ActiveRecord::Migration.deconstrain :books, :title, :alphanumeric
|
227
|
-
|
228
|
-
assert_allows do |book|
|
351
|
+
|
352
|
+
assert_allows Book do |book|
|
229
353
|
book.title = 'asdf@asdf'
|
230
354
|
end
|
231
355
|
end
|
232
|
-
|
356
|
+
|
357
|
+
def test_alphanumeric_on_a_column_whose_name_is_a_sql_keyword
|
358
|
+
ActiveRecord::Migration.constrain :books, :as, :alphanumeric => true
|
359
|
+
|
360
|
+
assert_prohibits Book, :as, :alphanumeric do |book|
|
361
|
+
book.as = 'asdf@asdf'
|
362
|
+
end
|
363
|
+
|
364
|
+
assert_allows Book do |book|
|
365
|
+
book.as = 'asdf'
|
366
|
+
end
|
367
|
+
|
368
|
+
ActiveRecord::Migration.deconstrain :books, :as, :alphanumeric
|
369
|
+
|
370
|
+
assert_allows Book do |book|
|
371
|
+
book.as = 'asdf@asdf'
|
372
|
+
end
|
373
|
+
end
|
374
|
+
|
233
375
|
def test_positive
|
234
376
|
ActiveRecord::Migration.constrain :books, :quantity, :positive => true
|
235
|
-
|
236
|
-
assert_prohibits :quantity, :positive do |book|
|
377
|
+
|
378
|
+
assert_prohibits Book, :quantity, :positive do |book|
|
237
379
|
book.quantity = -1
|
238
380
|
end
|
239
|
-
|
240
|
-
assert_allows do |book|
|
381
|
+
|
382
|
+
assert_allows Book do |book|
|
241
383
|
book.quantity = 0
|
242
384
|
end
|
243
|
-
|
244
|
-
assert_allows do |book|
|
385
|
+
|
386
|
+
assert_allows Book do |book|
|
245
387
|
book.quantity = 1
|
246
388
|
end
|
247
|
-
|
389
|
+
|
248
390
|
ActiveRecord::Migration.deconstrain :books, :quantity, :positive
|
249
|
-
|
250
|
-
assert_allows do |book|
|
391
|
+
|
392
|
+
assert_allows Book do |book|
|
251
393
|
book.quantity = -1
|
252
394
|
end
|
253
395
|
end
|
254
|
-
|
396
|
+
|
397
|
+
def test_positive_on_a_column_whose_name_is_a_sql_keyword
|
398
|
+
ActiveRecord::Migration.constrain :books, :from, :positive => true
|
399
|
+
|
400
|
+
assert_prohibits Book, :from, :positive do |book|
|
401
|
+
book.from = -1
|
402
|
+
end
|
403
|
+
|
404
|
+
assert_allows Book do |book|
|
405
|
+
book.from = 0
|
406
|
+
end
|
407
|
+
|
408
|
+
assert_allows Book do |book|
|
409
|
+
book.from = 1
|
410
|
+
end
|
411
|
+
|
412
|
+
ActiveRecord::Migration.deconstrain :books, :from, :positive
|
413
|
+
|
414
|
+
assert_allows Book do |book|
|
415
|
+
book.from = -1
|
416
|
+
end
|
417
|
+
end
|
418
|
+
|
255
419
|
def test_odd
|
256
420
|
ActiveRecord::Migration.constrain :books, :quantity, :odd => true
|
257
|
-
|
258
|
-
assert_prohibits :quantity, :odd do |book|
|
421
|
+
|
422
|
+
assert_prohibits Book, :quantity, :odd do |book|
|
259
423
|
book.quantity = 2
|
260
424
|
end
|
261
|
-
|
262
|
-
assert_allows do |book|
|
425
|
+
|
426
|
+
assert_allows Book do |book|
|
263
427
|
book.quantity = 1
|
264
428
|
end
|
265
|
-
|
429
|
+
|
266
430
|
ActiveRecord::Migration.deconstrain :books, :quantity, :odd
|
267
|
-
|
268
|
-
assert_allows do |book|
|
431
|
+
|
432
|
+
assert_allows Book do |book|
|
269
433
|
book.quantity = 2
|
270
434
|
end
|
271
435
|
end
|
272
|
-
|
436
|
+
|
437
|
+
def test_odd_on_a_column_whose_name_is_a_sql_keyword
|
438
|
+
ActiveRecord::Migration.constrain :books, :from, :odd => true
|
439
|
+
|
440
|
+
assert_prohibits Book, :from, :odd do |book|
|
441
|
+
book.from = 2
|
442
|
+
end
|
443
|
+
|
444
|
+
assert_allows Book do |book|
|
445
|
+
book.from = 1
|
446
|
+
end
|
447
|
+
|
448
|
+
ActiveRecord::Migration.deconstrain :books, :from, :odd
|
449
|
+
|
450
|
+
assert_allows Book do |book|
|
451
|
+
book.from = 2
|
452
|
+
end
|
453
|
+
end
|
454
|
+
|
273
455
|
def test_even
|
274
456
|
ActiveRecord::Migration.constrain :books, :quantity, :even => true
|
275
|
-
|
276
|
-
assert_prohibits :quantity, :even do |book|
|
457
|
+
|
458
|
+
assert_prohibits Book, :quantity, :even do |book|
|
277
459
|
book.quantity = 1
|
278
460
|
end
|
279
|
-
|
280
|
-
assert_allows do |book|
|
461
|
+
|
462
|
+
assert_allows Book do |book|
|
281
463
|
book.quantity = 2
|
282
464
|
end
|
283
|
-
|
465
|
+
|
284
466
|
ActiveRecord::Migration.deconstrain :books, :quantity, :even
|
285
|
-
|
286
|
-
assert_allows do |book|
|
467
|
+
|
468
|
+
assert_allows Book do |book|
|
287
469
|
book.quantity = 1
|
288
470
|
end
|
289
471
|
end
|
290
|
-
|
472
|
+
|
473
|
+
def test_even_on_a_column_whose_name_is_a_sql_keyword
|
474
|
+
ActiveRecord::Migration.constrain :books, :from, :even => true
|
475
|
+
|
476
|
+
assert_prohibits Book, :from, :even do |book|
|
477
|
+
book.from = 1
|
478
|
+
end
|
479
|
+
|
480
|
+
assert_allows Book do |book|
|
481
|
+
book.from = 2
|
482
|
+
end
|
483
|
+
|
484
|
+
ActiveRecord::Migration.deconstrain :books, :from, :even
|
485
|
+
|
486
|
+
assert_allows Book do |book|
|
487
|
+
book.from = 1
|
488
|
+
end
|
489
|
+
end
|
490
|
+
|
291
491
|
def test_unique
|
292
492
|
ActiveRecord::Migration.constrain :books, :isbn, :unique => true
|
293
|
-
|
294
|
-
assert_allows do |book|
|
493
|
+
|
494
|
+
assert_allows Book do |book|
|
295
495
|
book.isbn = 'foo'
|
296
496
|
end
|
297
|
-
|
298
|
-
assert_prohibits :isbn, :unique, 'unique' do |book|
|
497
|
+
|
498
|
+
assert_prohibits Book, :isbn, :unique, 'unique' do |book|
|
299
499
|
book.isbn = 'foo'
|
300
500
|
end
|
301
|
-
|
501
|
+
|
302
502
|
ActiveRecord::Migration.deconstrain :books, :isbn, :unique
|
303
|
-
|
304
|
-
assert_allows do |book|
|
503
|
+
|
504
|
+
assert_allows Book do |book|
|
305
505
|
book.isbn = 'foo'
|
306
506
|
end
|
307
507
|
end
|
308
|
-
|
508
|
+
|
509
|
+
def test_unique_on_a_column_whose_name_is_a_sql_keyword
|
510
|
+
ActiveRecord::Migration.constrain :books, :as, :unique => true
|
511
|
+
|
512
|
+
assert_allows Book do |book|
|
513
|
+
book.as = 'foo'
|
514
|
+
end
|
515
|
+
|
516
|
+
assert_prohibits Book, :as, :unique, 'unique' do |book|
|
517
|
+
book.as = 'foo'
|
518
|
+
end
|
519
|
+
|
520
|
+
ActiveRecord::Migration.deconstrain :books, :as, :unique
|
521
|
+
|
522
|
+
assert_allows Book do |book|
|
523
|
+
book.as = 'foo'
|
524
|
+
end
|
525
|
+
end
|
526
|
+
|
309
527
|
def test_exact_length
|
310
528
|
ActiveRecord::Migration.constrain :books, :isbn, :exact_length => 5
|
311
|
-
|
312
|
-
assert_prohibits :isbn, :exact_length do |book|
|
529
|
+
|
530
|
+
assert_prohibits Book, :isbn, :exact_length do |book|
|
313
531
|
book.isbn = '123456'
|
314
532
|
end
|
315
|
-
|
316
|
-
assert_prohibits :isbn, :exact_length do |book|
|
533
|
+
|
534
|
+
assert_prohibits Book, :isbn, :exact_length do |book|
|
317
535
|
book.isbn = '1234'
|
318
536
|
end
|
319
|
-
|
320
|
-
assert_allows do |book|
|
537
|
+
|
538
|
+
assert_allows Book do |book|
|
321
539
|
book.isbn = '12345'
|
322
540
|
end
|
323
|
-
|
541
|
+
|
324
542
|
ActiveRecord::Migration.deconstrain :books, :isbn, :exact_length
|
325
|
-
|
326
|
-
assert_allows do |book|
|
543
|
+
|
544
|
+
assert_allows Book do |book|
|
327
545
|
book.isbn = '123456'
|
328
546
|
end
|
329
547
|
end
|
330
|
-
|
548
|
+
|
549
|
+
def test_exact_length_on_a_column_whose_name_is_a_sql_keyword
|
550
|
+
ActiveRecord::Migration.constrain :books, :as, :exact_length => 5
|
551
|
+
|
552
|
+
assert_prohibits Book, :as, :exact_length do |book|
|
553
|
+
book.as = '123456'
|
554
|
+
end
|
555
|
+
|
556
|
+
assert_prohibits Book, :as, :exact_length do |book|
|
557
|
+
book.as = '1234'
|
558
|
+
end
|
559
|
+
|
560
|
+
assert_allows Book do |book|
|
561
|
+
book.as = '12345'
|
562
|
+
end
|
563
|
+
|
564
|
+
ActiveRecord::Migration.deconstrain :books, :as, :exact_length
|
565
|
+
|
566
|
+
assert_allows Book do |book|
|
567
|
+
book.as = '123456'
|
568
|
+
end
|
569
|
+
end
|
570
|
+
|
331
571
|
def test_format_case_insensitive
|
332
572
|
ActiveRecord::Migration.constrain :books, :title, :format => /^[a-z]+$/i
|
333
|
-
|
334
|
-
assert_prohibits :title, :format do |book|
|
573
|
+
|
574
|
+
assert_prohibits Book, :title, :format do |book|
|
335
575
|
book.title = 'abc3'
|
336
576
|
end
|
337
|
-
|
338
|
-
assert_prohibits :title, :format do |book|
|
577
|
+
|
578
|
+
assert_prohibits Book, :title, :format do |book|
|
339
579
|
book.title = ''
|
340
580
|
end
|
341
|
-
|
342
|
-
assert_allows do |book|
|
581
|
+
|
582
|
+
assert_allows Book do |book|
|
343
583
|
book.title = 'abc'
|
344
584
|
end
|
345
|
-
|
346
|
-
assert_allows do |book|
|
585
|
+
|
586
|
+
assert_allows Book do |book|
|
347
587
|
book.title = 'ABc'
|
348
588
|
end
|
349
|
-
|
589
|
+
|
350
590
|
ActiveRecord::Migration.deconstrain :books, :title, :format
|
351
|
-
|
352
|
-
assert_allows do |book|
|
591
|
+
|
592
|
+
assert_allows Book do |book|
|
353
593
|
book.title = 'abc3'
|
354
594
|
end
|
355
595
|
end
|
356
|
-
|
596
|
+
|
597
|
+
def test_format_case_insensitive_on_a_column_whose_name_is_a_sql_keyword
|
598
|
+
ActiveRecord::Migration.constrain :books, :as, :format => /^[a-z]+$/i
|
599
|
+
|
600
|
+
assert_prohibits Book, :as, :format do |book|
|
601
|
+
book.as = 'abc3'
|
602
|
+
end
|
603
|
+
|
604
|
+
assert_prohibits Book, :as, :format do |book|
|
605
|
+
book.as = ''
|
606
|
+
end
|
607
|
+
|
608
|
+
assert_allows Book do |book|
|
609
|
+
book.as = 'abc'
|
610
|
+
end
|
611
|
+
|
612
|
+
assert_allows Book do |book|
|
613
|
+
book.as = 'ABc'
|
614
|
+
end
|
615
|
+
|
616
|
+
ActiveRecord::Migration.deconstrain :books, :as, :format
|
617
|
+
|
618
|
+
assert_allows Book do |book|
|
619
|
+
book.as = 'abc3'
|
620
|
+
end
|
621
|
+
end
|
622
|
+
|
357
623
|
def test_format_case_sensitive
|
358
624
|
ActiveRecord::Migration.constrain :books, :title, :format => /^[a-z]+$/
|
359
|
-
|
360
|
-
assert_prohibits :title, :format do |book|
|
625
|
+
|
626
|
+
assert_prohibits Book, :title, :format do |book|
|
361
627
|
book.title = 'aBc'
|
362
628
|
end
|
363
|
-
|
364
|
-
assert_allows do |book|
|
629
|
+
|
630
|
+
assert_allows Book do |book|
|
365
631
|
book.title = 'abc'
|
366
632
|
end
|
367
|
-
|
633
|
+
|
368
634
|
ActiveRecord::Migration.deconstrain :books, :title, :format
|
369
|
-
|
370
|
-
assert_allows do |book|
|
635
|
+
|
636
|
+
assert_allows Book do |book|
|
371
637
|
book.title = 'aBc'
|
372
638
|
end
|
373
639
|
end
|
374
|
-
|
640
|
+
|
641
|
+
def test_format_case_sensitive_on_a_column_whose_name_is_a_sql_keyword
|
642
|
+
ActiveRecord::Migration.constrain :books, :as, :format => /^[a-z]+$/
|
643
|
+
|
644
|
+
assert_prohibits Book, :as, :format do |book|
|
645
|
+
book.as = 'aBc'
|
646
|
+
end
|
647
|
+
|
648
|
+
assert_allows Book do |book|
|
649
|
+
book.as = 'abc'
|
650
|
+
end
|
651
|
+
|
652
|
+
ActiveRecord::Migration.deconstrain :books, :as, :format
|
653
|
+
|
654
|
+
assert_allows Book do |book|
|
655
|
+
book.as = 'aBc'
|
656
|
+
end
|
657
|
+
end
|
658
|
+
|
375
659
|
def test_reference
|
376
660
|
ActiveRecord::Migration.constrain :books, :author_id, :reference => {:authors => :id}
|
377
|
-
|
378
|
-
assert_prohibits :author_id, :reference, 'foreign key' do |book|
|
661
|
+
|
662
|
+
assert_prohibits Book, :author_id, :reference, 'foreign key' do |book|
|
379
663
|
book.author_id = 1
|
380
664
|
end
|
381
|
-
|
665
|
+
|
382
666
|
author = Author.new
|
383
667
|
author.name = "Mark Twain"
|
384
668
|
author.bio = "American writer"
|
385
669
|
assert author.save
|
386
|
-
|
670
|
+
|
387
671
|
assert_equal 1, author.id
|
388
|
-
|
389
|
-
assert_allows do |book|
|
672
|
+
|
673
|
+
assert_allows Book do |book|
|
390
674
|
book.author_id = 1
|
391
675
|
end
|
392
|
-
|
676
|
+
|
393
677
|
ActiveRecord::Migration.deconstrain :books, :author_id, :reference
|
394
|
-
|
395
|
-
assert_allows do |book|
|
678
|
+
|
679
|
+
assert_allows Book do |book|
|
396
680
|
book.author_id = 2
|
397
681
|
end
|
398
682
|
end
|
399
|
-
|
683
|
+
|
684
|
+
def test_reference_on_a_column_whose_name_is_a_sql_keyword
|
685
|
+
ActiveRecord::Migration.constrain :books, :from, :reference => {:authors => :id}
|
686
|
+
|
687
|
+
assert_prohibits Book, :from, :reference, 'foreign key' do |book|
|
688
|
+
book.from = 1
|
689
|
+
end
|
690
|
+
|
691
|
+
author = Author.new
|
692
|
+
author.name = "Mark Twain"
|
693
|
+
author.bio = "American writer"
|
694
|
+
assert author.save
|
695
|
+
|
696
|
+
assert_equal 1, author.id
|
697
|
+
|
698
|
+
assert_allows Book do |book|
|
699
|
+
book.from = 1
|
700
|
+
end
|
701
|
+
|
702
|
+
ActiveRecord::Migration.deconstrain :books, :from, :reference
|
703
|
+
|
704
|
+
assert_allows Book do |book|
|
705
|
+
book.from = 2
|
706
|
+
end
|
707
|
+
end
|
708
|
+
|
400
709
|
def test_reference_with_on_delete
|
401
710
|
ActiveRecord::Migration.constrain :books, :author_id, :reference => {:authors => :id, :on_delete => :cascade}
|
402
|
-
|
711
|
+
|
403
712
|
author = Author.new
|
404
713
|
author.name = "Mark Twain"
|
405
714
|
author.bio = "American writer"
|
406
715
|
assert author.save
|
407
|
-
|
716
|
+
|
408
717
|
assert_equal 1, Author.count
|
409
|
-
|
410
|
-
assert_allows do |book|
|
718
|
+
|
719
|
+
assert_allows Book do |book|
|
411
720
|
book.title = "The Adventures of Tom Sawyer"
|
412
721
|
book.author_id = 1
|
413
722
|
end
|
414
|
-
|
415
|
-
assert_allows do |book|
|
723
|
+
|
724
|
+
assert_allows Book do |book|
|
416
725
|
book.title = "The Adventures of Huckleberry Finn"
|
417
726
|
book.author_id = 1
|
418
727
|
end
|
419
|
-
|
728
|
+
|
420
729
|
author.destroy
|
421
|
-
|
730
|
+
|
422
731
|
assert_equal 0, Author.count
|
423
732
|
assert_equal 0, Book.count
|
424
733
|
end
|
425
|
-
|
734
|
+
|
426
735
|
def test_block_syntax
|
427
736
|
ActiveRecord::Migration.constrain :books do |t|
|
428
737
|
t.title :not_blank => true
|
429
738
|
t.isbn :exact_length => 15
|
430
739
|
t.author :alphanumeric => true
|
431
740
|
end
|
432
|
-
|
433
|
-
assert_prohibits :title, :not_blank do |book|
|
741
|
+
|
742
|
+
assert_prohibits Book, :title, :not_blank do |book|
|
434
743
|
book.title = ' '
|
435
744
|
end
|
436
|
-
|
437
|
-
assert_prohibits :isbn, :exact_length do |book|
|
745
|
+
|
746
|
+
assert_prohibits Book, :isbn, :exact_length do |book|
|
438
747
|
book.isbn = 'asdf'
|
439
748
|
end
|
440
|
-
|
441
|
-
assert_prohibits :author, :alphanumeric do |book|
|
749
|
+
|
750
|
+
assert_prohibits Book, :author, :alphanumeric do |book|
|
442
751
|
book.author = 'foo#bar'
|
443
752
|
end
|
444
|
-
|
753
|
+
|
445
754
|
ActiveRecord::Migration.deconstrain :books do |t|
|
446
755
|
t.title :not_blank
|
447
756
|
t.isbn :exact_length
|
448
757
|
t.author :alphanumeric
|
449
758
|
end
|
450
|
-
|
451
|
-
assert_allows do |book|
|
759
|
+
|
760
|
+
assert_allows Book do |book|
|
452
761
|
book.title = ' '
|
453
762
|
book.isbn = 'asdf'
|
454
763
|
book.author = 'foo#bar'
|
455
764
|
end
|
456
765
|
end
|
457
|
-
|
766
|
+
|
458
767
|
def test_multiple_constraints_per_line
|
459
768
|
ActiveRecord::Migration.constrain :books do |t|
|
460
769
|
t.title :not_blank => true, :alphanumeric => true, :blacklist => %w(foo bar)
|
461
770
|
end
|
462
|
-
|
463
|
-
assert_prohibits :title, :not_blank do |book|
|
771
|
+
|
772
|
+
assert_prohibits Book, :title, [:not_blank, :alphanumeric] do |book|
|
464
773
|
book.title = ' '
|
465
774
|
end
|
466
|
-
|
467
|
-
assert_prohibits :title, :alphanumeric do |book|
|
775
|
+
|
776
|
+
assert_prohibits Book, :title, :alphanumeric do |book|
|
468
777
|
book.title = 'asdf@asdf'
|
469
778
|
end
|
470
|
-
|
471
|
-
assert_prohibits :title, :blacklist do |book|
|
779
|
+
|
780
|
+
assert_prohibits Book, :title, :blacklist do |book|
|
472
781
|
book.title = 'foo'
|
473
782
|
end
|
474
|
-
|
783
|
+
|
475
784
|
ActiveRecord::Migration.deconstrain :books do |t|
|
476
785
|
t.title :not_blank, :alphanumeric, :blacklist
|
477
786
|
end
|
478
|
-
|
479
|
-
assert_allows do |book|
|
787
|
+
|
788
|
+
assert_allows Book do |book|
|
480
789
|
book.title = ' '
|
481
790
|
end
|
482
|
-
|
483
|
-
assert_allows do |book|
|
791
|
+
|
792
|
+
assert_allows Book do |book|
|
484
793
|
book.title = 'asdf@asdf'
|
485
794
|
end
|
486
|
-
|
487
|
-
assert_allows do |book|
|
795
|
+
|
796
|
+
assert_allows Book do |book|
|
488
797
|
book.title = 'foo'
|
489
798
|
end
|
490
799
|
end
|
491
|
-
|
800
|
+
|
492
801
|
def test_multicolumn_constraint
|
493
802
|
ActiveRecord::Migration.constrain :books, [:title, :isbn], :unique => true
|
494
|
-
|
495
|
-
assert_allows do |book|
|
803
|
+
|
804
|
+
assert_allows Book do |book|
|
496
805
|
book.title = 'foo'
|
497
806
|
book.isbn = 'bar'
|
498
807
|
end
|
499
|
-
|
500
|
-
assert_allows do |book|
|
808
|
+
|
809
|
+
assert_allows Book do |book|
|
501
810
|
book.title = 'foo'
|
502
811
|
book.isbn = 'foo'
|
503
812
|
end
|
504
|
-
|
505
|
-
assert_prohibits [:title, :isbn], :unique, 'unique' do |book|
|
813
|
+
|
814
|
+
assert_prohibits Book, [:title, :isbn], :unique, 'unique' do |book|
|
506
815
|
book.title = 'foo'
|
507
816
|
book.isbn = 'bar'
|
508
817
|
end
|
509
|
-
|
818
|
+
|
510
819
|
ActiveRecord::Migration.deconstrain :books, [:title, :isbn], :unique
|
511
|
-
|
512
|
-
assert_allows do |book|
|
820
|
+
|
821
|
+
assert_allows Book do |book|
|
513
822
|
book.title = 'foo'
|
514
823
|
book.isbn = 'bar'
|
515
824
|
end
|
516
825
|
end
|
517
|
-
|
826
|
+
|
518
827
|
def test_multicolumn_constraint_block_syntax
|
519
828
|
ActiveRecord::Migration.constrain :books do |t|
|
520
829
|
t[:title, :isbn].all :unique => true
|
521
830
|
end
|
522
|
-
|
523
|
-
assert_allows do |book|
|
831
|
+
|
832
|
+
assert_allows Book do |book|
|
524
833
|
book.title = 'foo'
|
525
834
|
book.isbn = 'bar'
|
526
835
|
end
|
527
|
-
|
528
|
-
assert_allows do |book|
|
836
|
+
|
837
|
+
assert_allows Book do |book|
|
529
838
|
book.title = 'foo'
|
530
839
|
book.isbn = 'foo'
|
531
840
|
end
|
532
|
-
|
533
|
-
assert_prohibits [:title, :isbn], :unique, 'unique' do |book|
|
841
|
+
|
842
|
+
assert_prohibits Book, [:title, :isbn], :unique, 'unique' do |book|
|
534
843
|
book.title = 'foo'
|
535
844
|
book.isbn = 'bar'
|
536
845
|
end
|
537
|
-
|
846
|
+
|
538
847
|
ActiveRecord::Migration.deconstrain :books do |t|
|
539
848
|
t[:title, :isbn].all :unique
|
540
849
|
end
|
541
|
-
|
542
|
-
assert_allows do |book|
|
850
|
+
|
851
|
+
assert_allows Book do |book|
|
543
852
|
book.title = 'foo'
|
544
853
|
book.isbn = 'bar'
|
545
854
|
end
|
546
855
|
end
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
book.
|
557
|
-
end
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
856
|
+
|
857
|
+
def test_lowercase
|
858
|
+
ActiveRecord::Migration.constrain :books, :author, :lowercase => true
|
859
|
+
|
860
|
+
assert_prohibits Book, :author, :lowercase do |book|
|
861
|
+
book.author = 'UPPER'
|
862
|
+
end
|
863
|
+
|
864
|
+
assert_allows Book do |book|
|
865
|
+
book.author = 'lower with 1337'
|
866
|
+
end
|
867
|
+
|
868
|
+
ActiveRecord::Migration.deconstrain :books, :author, :lowercase
|
869
|
+
|
870
|
+
assert_allows Book do |book|
|
871
|
+
book.author = 'UPPER'
|
872
|
+
end
|
873
|
+
|
874
|
+
end
|
875
|
+
|
876
|
+
def test_xor
|
877
|
+
ActiveRecord::Migration.constrain :books, [:xor_col_1, :xor_col_2], :xor => true
|
878
|
+
|
879
|
+
assert_prohibits Book, [:xor_col_1, :xor_col_2], :xor do |book|
|
880
|
+
book.xor_col_1 = 123
|
881
|
+
book.xor_col_2 = 321
|
882
|
+
end
|
883
|
+
|
884
|
+
assert_allows Book do |book|
|
885
|
+
book.xor_col_1 = 123
|
886
|
+
end
|
887
|
+
|
888
|
+
assert_allows Book do |book|
|
889
|
+
book.xor_col_2 = 123
|
890
|
+
end
|
891
|
+
|
892
|
+
ActiveRecord::Migration.deconstrain :books, [:xor_col_1, :xor_col_2], :xor
|
893
|
+
|
894
|
+
assert_allows Book do |book|
|
895
|
+
book.xor_col_1 = 123
|
896
|
+
book.xor_col_2 = 123
|
897
|
+
end
|
571
898
|
end
|
572
899
|
end
|