Empact-sexy_pg_constraints 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.
@@ -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