Empact-sexy_pg_constraints 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,31 @@
1
+ module SexyPgConstraints
2
+ class DeConstrainer
3
+ include SexyPgConstraints::Helpers
4
+
5
+ def initialize(table, columns = [])
6
+ @table = table.to_s
7
+ @columns = columns
8
+ end
9
+
10
+ def method_missing(column, *constraints)
11
+ self.class.drop_constraints(@table, column.to_s, *constraints)
12
+ end
13
+
14
+ def [](*columns)
15
+ @columns = columns.map{|c| c.to_s}
16
+ self
17
+ end
18
+
19
+ def all(*constraints)
20
+ self.class.drop_constraints(@table, @columns, *constraints)
21
+ end
22
+
23
+ class << self
24
+ def drop_constraints(table, column, *constraints)
25
+ constraints.each do |type|
26
+ execute "alter table #{table} drop constraint #{make_title(table, column, type)};"
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,19 @@
1
+ module SexyPgConstraints
2
+ module Helpers
3
+ def self.included(base)
4
+ base.extend ClassMethods
5
+ end
6
+
7
+ module ClassMethods
8
+ def make_title(table, column, type)
9
+ column = column.join('_') if column.respond_to?(:join)
10
+
11
+ "#{table}_#{column}_#{type}"
12
+ end
13
+
14
+ def execute(*args)
15
+ ActiveRecord::Base.connection.execute(*args)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,7 @@
1
+ if defined?(Rails)
2
+ class SexyPgConstraintsRailtie < Rails::Railtie
3
+ config.after_initialize do
4
+ ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.send(:include, SexyPgConstraints)
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,32 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{sexy_pg_constraints}
5
+ s.version = "0.1.3"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Maxim Chernyak"]
9
+ s.date = %q{2009-01-19}
10
+ s.description = %q{Use migrations and simple syntax to manage constraints in PostgreSQL DB.}
11
+ s.email = %q{max@bitsonnet.com}
12
+ s.extra_rdoc_files = ["CHANGELOG.rdoc", "lib/constrainer.rb", "lib/constraints.rb", "lib/deconstrainer.rb", "lib/helpers.rb", "lib/sexy_pg_constraints.rb", "README.rdoc"]
13
+ s.files = ["CHANGELOG.rdoc", "init.rb", "lib/constrainer.rb", "lib/constraints.rb", "lib/deconstrainer.rb", "lib/helpers.rb", "lib/sexy_pg_constraints.rb", "Manifest", "Rakefile", "README.rdoc", "sexy_pg_constraints.gemspec", "test/postgresql_adapter.rb", "test/sexy_pg_constraints_test.rb", "test/test_helper.rb"]
14
+ s.has_rdoc = true
15
+ s.homepage = %q{http://github.com/maxim/sexy_pg_constraints}
16
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Sexy_pg_constraints", "--main", "README.rdoc"]
17
+ s.require_paths = ["lib"]
18
+ s.rubyforge_project = %q{sexy_pg_constraints}
19
+ s.rubygems_version = %q{1.3.1}
20
+ s.summary = %q{Use migrations and simple syntax to manage constraints in PostgreSQL DB.}
21
+ s.test_files = ["test/sexy_pg_constraints_test.rb", "test/test_helper.rb"]
22
+
23
+ if s.respond_to? :specification_version then
24
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
25
+ s.specification_version = 2
26
+
27
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
28
+ else
29
+ end
30
+ else
31
+ end
32
+ end
@@ -0,0 +1,899 @@
1
+ require 'test_helper'
2
+
3
+ class SexyPgConstraintsTest < Test::Unit::TestCase
4
+ def setup
5
+ CreateBooks.up
6
+ CreateAuthors.up
7
+ end
8
+
9
+ def teardown
10
+ CreateBooks.down
11
+ CreateAuthors.down
12
+ end
13
+
14
+ def test_should_create_book
15
+ Book.create
16
+ assert_equal 1, Book.count
17
+ end
18
+
19
+ def test_whitelist
20
+ ActiveRecord::Migration.constrain :books, :author, :whitelist => %w(whitelisted1 whitelisted2 whitelisted3)
21
+
22
+ assert_prohibits Book, :author, :whitelist do |book|
23
+ book.author = 'not_whitelisted'
24
+ end
25
+
26
+ assert_allows Book do |book|
27
+ book.author = 'whitelisted2'
28
+ end
29
+
30
+ ActiveRecord::Migration.deconstrain :books, :author, :whitelist
31
+
32
+ assert_allows Book do |book|
33
+ book.author = 'not_whitelisted'
34
+ end
35
+ end
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
+
55
+ def test_blacklist
56
+ ActiveRecord::Migration.constrain :books, :author, :blacklist => %w(blacklisted1 blacklisted2 blacklisted3)
57
+
58
+ assert_prohibits Book, :author, :blacklist do |book|
59
+ book.author = 'blacklisted2'
60
+ end
61
+
62
+ assert_allows Book do |book|
63
+ book.author = 'not_blacklisted'
64
+ end
65
+
66
+ ActiveRecord::Migration.deconstrain :books, :author, :blacklist
67
+
68
+ assert_allows Book do |book|
69
+ book.author = 'blacklisted2'
70
+ end
71
+ end
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
+ def test_not_blank
92
+ ActiveRecord::Migration.constrain :books, :author, :not_blank => true
93
+
94
+ assert_prohibits Book, :author, :not_blank do |book|
95
+ book.author = ' '
96
+ end
97
+
98
+ assert_allows Book do |book|
99
+ book.author = 'foo'
100
+ end
101
+
102
+ ActiveRecord::Migration.deconstrain :books, :author, :not_blank
103
+
104
+ assert_allows Book do |book|
105
+ book.author = ' '
106
+ end
107
+ end
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
+
127
+ def test_within_inclusive
128
+ ActiveRecord::Migration.constrain :books, :quantity, :within => 5..11
129
+
130
+ assert_prohibits Book, :quantity, :within do |book|
131
+ book.quantity = 12
132
+ end
133
+
134
+ assert_prohibits Book, :quantity, :within do |book|
135
+ book.quantity = 4
136
+ end
137
+
138
+ assert_allows Book do |book|
139
+ book.quantity = 7
140
+ end
141
+
142
+ ActiveRecord::Migration.deconstrain :books, :quantity, :within
143
+
144
+ assert_allows Book do |book|
145
+ book.quantity = 12
146
+ end
147
+ end
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
+
171
+ def test_within_non_inclusive
172
+ ActiveRecord::Migration.constrain :books, :quantity, :within => 5...11
173
+
174
+ assert_prohibits Book, :quantity, :within do |book|
175
+ book.quantity = 11
176
+ end
177
+
178
+ assert_prohibits Book, :quantity, :within do |book|
179
+ book.quantity = 4
180
+ end
181
+
182
+ assert_allows Book do |book|
183
+ book.quantity = 10
184
+ end
185
+
186
+ ActiveRecord::Migration.deconstrain :books, :quantity, :within
187
+
188
+ assert_allows Book do |book|
189
+ book.quantity = 11
190
+ end
191
+ end
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
+
215
+ def test_length_within_inclusive
216
+ ActiveRecord::Migration.constrain :books, :title, :length_within => 5..11
217
+
218
+ assert_prohibits Book, :title, :length_within do |book|
219
+ book.title = 'abcdefghijkl'
220
+ end
221
+
222
+ assert_prohibits Book, :title, :length_within do |book|
223
+ book.title = 'abcd'
224
+ end
225
+
226
+ assert_allows Book do |book|
227
+ book.title = 'abcdefg'
228
+ end
229
+
230
+ ActiveRecord::Migration.deconstrain :books, :title, :length_within
231
+
232
+ assert_allows Book do |book|
233
+ book.title = 'abcdefghijkl'
234
+ end
235
+ end
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
+
259
+ def test_length_within_non_inclusive
260
+ ActiveRecord::Migration.constrain :books, :title, :length_within => 5...11
261
+
262
+ assert_prohibits Book, :title, :length_within do |book|
263
+ book.title = 'abcdefghijk'
264
+ end
265
+
266
+ assert_prohibits Book, :title, :length_within do |book|
267
+ book.title = 'abcd'
268
+ end
269
+
270
+ assert_allows Book do |book|
271
+ book.title = 'abcdefg'
272
+ end
273
+
274
+ ActiveRecord::Migration.deconstrain :books, :title, :length_within
275
+
276
+ assert_allows Book do |book|
277
+ book.title = 'abcdefghijk'
278
+ end
279
+ end
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
+
303
+ def test_email
304
+ ActiveRecord::Migration.constrain :books, :author, :email => true
305
+
306
+ assert_prohibits Book, :author, :email do |book|
307
+ book.author = 'blah@example'
308
+ end
309
+
310
+ assert_allows Book do |book|
311
+ book.author = 'blah@example.com'
312
+ end
313
+
314
+ ActiveRecord::Migration.deconstrain :books, :author, :email
315
+
316
+ assert_allows Book do |book|
317
+ book.author = 'blah@example'
318
+ end
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
+
339
+ def test_alphanumeric
340
+ ActiveRecord::Migration.constrain :books, :title, :alphanumeric => true
341
+
342
+ assert_prohibits Book, :title, :alphanumeric do |book|
343
+ book.title = 'asdf@asdf'
344
+ end
345
+
346
+ assert_allows Book do |book|
347
+ book.title = 'asdf'
348
+ end
349
+
350
+ ActiveRecord::Migration.deconstrain :books, :title, :alphanumeric
351
+
352
+ assert_allows Book do |book|
353
+ book.title = 'asdf@asdf'
354
+ end
355
+ end
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
+
375
+ def test_positive
376
+ ActiveRecord::Migration.constrain :books, :quantity, :positive => true
377
+
378
+ assert_prohibits Book, :quantity, :positive do |book|
379
+ book.quantity = -1
380
+ end
381
+
382
+ assert_allows Book do |book|
383
+ book.quantity = 0
384
+ end
385
+
386
+ assert_allows Book do |book|
387
+ book.quantity = 1
388
+ end
389
+
390
+ ActiveRecord::Migration.deconstrain :books, :quantity, :positive
391
+
392
+ assert_allows Book do |book|
393
+ book.quantity = -1
394
+ end
395
+ end
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
+
419
+ def test_odd
420
+ ActiveRecord::Migration.constrain :books, :quantity, :odd => true
421
+
422
+ assert_prohibits Book, :quantity, :odd do |book|
423
+ book.quantity = 2
424
+ end
425
+
426
+ assert_allows Book do |book|
427
+ book.quantity = 1
428
+ end
429
+
430
+ ActiveRecord::Migration.deconstrain :books, :quantity, :odd
431
+
432
+ assert_allows Book do |book|
433
+ book.quantity = 2
434
+ end
435
+ end
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
+
455
+ def test_even
456
+ ActiveRecord::Migration.constrain :books, :quantity, :even => true
457
+
458
+ assert_prohibits Book, :quantity, :even do |book|
459
+ book.quantity = 1
460
+ end
461
+
462
+ assert_allows Book do |book|
463
+ book.quantity = 2
464
+ end
465
+
466
+ ActiveRecord::Migration.deconstrain :books, :quantity, :even
467
+
468
+ assert_allows Book do |book|
469
+ book.quantity = 1
470
+ end
471
+ end
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
+
491
+ def test_unique
492
+ ActiveRecord::Migration.constrain :books, :isbn, :unique => true
493
+
494
+ assert_allows Book do |book|
495
+ book.isbn = 'foo'
496
+ end
497
+
498
+ assert_prohibits Book, :isbn, :unique, 'unique', ActiveRecord::RecordNotUnique do |book|
499
+ book.isbn = 'foo'
500
+ end
501
+
502
+ ActiveRecord::Migration.deconstrain :books, :isbn, :unique
503
+
504
+ assert_allows Book do |book|
505
+ book.isbn = 'foo'
506
+ end
507
+ end
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', ActiveRecord::RecordNotUnique 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
+
527
+ def test_exact_length
528
+ ActiveRecord::Migration.constrain :books, :isbn, :exact_length => 5
529
+
530
+ assert_prohibits Book, :isbn, :exact_length do |book|
531
+ book.isbn = '123456'
532
+ end
533
+
534
+ assert_prohibits Book, :isbn, :exact_length do |book|
535
+ book.isbn = '1234'
536
+ end
537
+
538
+ assert_allows Book do |book|
539
+ book.isbn = '12345'
540
+ end
541
+
542
+ ActiveRecord::Migration.deconstrain :books, :isbn, :exact_length
543
+
544
+ assert_allows Book do |book|
545
+ book.isbn = '123456'
546
+ end
547
+ end
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
+
571
+ def test_format_case_insensitive
572
+ ActiveRecord::Migration.constrain :books, :title, :format => /^[a-z]+$/i
573
+
574
+ assert_prohibits Book, :title, :format do |book|
575
+ book.title = 'abc3'
576
+ end
577
+
578
+ assert_prohibits Book, :title, :format do |book|
579
+ book.title = ''
580
+ end
581
+
582
+ assert_allows Book do |book|
583
+ book.title = 'abc'
584
+ end
585
+
586
+ assert_allows Book do |book|
587
+ book.title = 'ABc'
588
+ end
589
+
590
+ ActiveRecord::Migration.deconstrain :books, :title, :format
591
+
592
+ assert_allows Book do |book|
593
+ book.title = 'abc3'
594
+ end
595
+ end
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
+
623
+ def test_format_case_sensitive
624
+ ActiveRecord::Migration.constrain :books, :title, :format => /^[a-z]+$/
625
+
626
+ assert_prohibits Book, :title, :format do |book|
627
+ book.title = 'aBc'
628
+ end
629
+
630
+ assert_allows Book do |book|
631
+ book.title = 'abc'
632
+ end
633
+
634
+ ActiveRecord::Migration.deconstrain :books, :title, :format
635
+
636
+ assert_allows Book do |book|
637
+ book.title = 'aBc'
638
+ end
639
+ end
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
+
659
+ def test_reference
660
+ ActiveRecord::Migration.constrain :books, :author_id, :reference => {:authors => :id}
661
+
662
+ assert_prohibits Book, :author_id, :reference, 'foreign key', ActiveRecord::InvalidForeignKey do |book|
663
+ book.author_id = 1
664
+ end
665
+
666
+ author = Author.new
667
+ author.name = "Mark Twain"
668
+ author.bio = "American writer"
669
+ assert author.save
670
+
671
+ assert_equal 1, author.id
672
+
673
+ assert_allows Book do |book|
674
+ book.author_id = 1
675
+ end
676
+
677
+ ActiveRecord::Migration.deconstrain :books, :author_id, :reference
678
+
679
+ assert_allows Book do |book|
680
+ book.author_id = 2
681
+ end
682
+ end
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', ActiveRecord::InvalidForeignKey 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
+
709
+ def test_reference_with_on_delete
710
+ ActiveRecord::Migration.constrain :books, :author_id, :reference => {:authors => :id, :on_delete => :cascade}
711
+
712
+ author = Author.new
713
+ author.name = "Mark Twain"
714
+ author.bio = "American writer"
715
+ assert author.save
716
+
717
+ assert_equal 1, Author.count
718
+
719
+ assert_allows Book do |book|
720
+ book.title = "The Adventures of Tom Sawyer"
721
+ book.author_id = 1
722
+ end
723
+
724
+ assert_allows Book do |book|
725
+ book.title = "The Adventures of Huckleberry Finn"
726
+ book.author_id = 1
727
+ end
728
+
729
+ author.destroy
730
+
731
+ assert_equal 0, Author.count
732
+ assert_equal 0, Book.count
733
+ end
734
+
735
+ def test_block_syntax
736
+ ActiveRecord::Migration.constrain :books do |t|
737
+ t.title :not_blank => true
738
+ t.isbn :exact_length => 15
739
+ t.author :alphanumeric => true
740
+ end
741
+
742
+ assert_prohibits Book, :title, :not_blank do |book|
743
+ book.title = ' '
744
+ end
745
+
746
+ assert_prohibits Book, :isbn, :exact_length do |book|
747
+ book.isbn = 'asdf'
748
+ end
749
+
750
+ assert_prohibits Book, :author, :alphanumeric do |book|
751
+ book.author = 'foo#bar'
752
+ end
753
+
754
+ ActiveRecord::Migration.deconstrain :books do |t|
755
+ t.title :not_blank
756
+ t.isbn :exact_length
757
+ t.author :alphanumeric
758
+ end
759
+
760
+ assert_allows Book do |book|
761
+ book.title = ' '
762
+ book.isbn = 'asdf'
763
+ book.author = 'foo#bar'
764
+ end
765
+ end
766
+
767
+ def test_multiple_constraints_per_line
768
+ ActiveRecord::Migration.constrain :books do |t|
769
+ t.title :not_blank => true, :alphanumeric => true, :blacklist => %w(foo bar)
770
+ end
771
+
772
+ assert_prohibits Book, :title, [:not_blank, :alphanumeric] do |book|
773
+ book.title = ' '
774
+ end
775
+
776
+ assert_prohibits Book, :title, :alphanumeric do |book|
777
+ book.title = 'asdf@asdf'
778
+ end
779
+
780
+ assert_prohibits Book, :title, :blacklist do |book|
781
+ book.title = 'foo'
782
+ end
783
+
784
+ ActiveRecord::Migration.deconstrain :books do |t|
785
+ t.title :not_blank, :alphanumeric, :blacklist
786
+ end
787
+
788
+ assert_allows Book do |book|
789
+ book.title = ' '
790
+ end
791
+
792
+ assert_allows Book do |book|
793
+ book.title = 'asdf@asdf'
794
+ end
795
+
796
+ assert_allows Book do |book|
797
+ book.title = 'foo'
798
+ end
799
+ end
800
+
801
+ def test_multicolumn_constraint
802
+ ActiveRecord::Migration.constrain :books, [:title, :isbn], :unique => true
803
+
804
+ assert_allows Book do |book|
805
+ book.title = 'foo'
806
+ book.isbn = 'bar'
807
+ end
808
+
809
+ assert_allows Book do |book|
810
+ book.title = 'foo'
811
+ book.isbn = 'foo'
812
+ end
813
+
814
+ assert_prohibits Book, [:title, :isbn], :unique, 'unique', ActiveRecord::RecordNotUnique do |book|
815
+ book.title = 'foo'
816
+ book.isbn = 'bar'
817
+ end
818
+
819
+ ActiveRecord::Migration.deconstrain :books, [:title, :isbn], :unique
820
+
821
+ assert_allows Book do |book|
822
+ book.title = 'foo'
823
+ book.isbn = 'bar'
824
+ end
825
+ end
826
+
827
+ def test_multicolumn_constraint_block_syntax
828
+ ActiveRecord::Migration.constrain :books do |t|
829
+ t[:title, :isbn].all :unique => true
830
+ end
831
+
832
+ assert_allows Book do |book|
833
+ book.title = 'foo'
834
+ book.isbn = 'bar'
835
+ end
836
+
837
+ assert_allows Book do |book|
838
+ book.title = 'foo'
839
+ book.isbn = 'foo'
840
+ end
841
+
842
+ assert_prohibits Book, [:title, :isbn], :unique, 'unique', ActiveRecord::RecordNotUnique do |book|
843
+ book.title = 'foo'
844
+ book.isbn = 'bar'
845
+ end
846
+
847
+ ActiveRecord::Migration.deconstrain :books do |t|
848
+ t[:title, :isbn].all :unique
849
+ end
850
+
851
+ assert_allows Book do |book|
852
+ book.title = 'foo'
853
+ book.isbn = 'bar'
854
+ end
855
+ end
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
898
+ end
899
+ end