sequel 2.12.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. data/CHANGELOG +62 -0
  2. data/README.rdoc +3 -3
  3. data/Rakefile +7 -0
  4. data/doc/advanced_associations.rdoc +44 -0
  5. data/doc/release_notes/3.0.0.txt +221 -0
  6. data/lib/sequel/adapters/amalgalite.rb +208 -0
  7. data/lib/sequel/adapters/db2.rb +3 -0
  8. data/lib/sequel/adapters/dbi.rb +9 -0
  9. data/lib/sequel/adapters/do.rb +0 -4
  10. data/lib/sequel/adapters/firebird.rb +16 -18
  11. data/lib/sequel/adapters/informix.rb +5 -3
  12. data/lib/sequel/adapters/jdbc.rb +24 -20
  13. data/lib/sequel/adapters/jdbc/h2.rb +15 -4
  14. data/lib/sequel/adapters/mysql.rb +4 -8
  15. data/lib/sequel/adapters/odbc.rb +0 -4
  16. data/lib/sequel/adapters/oracle.rb +0 -4
  17. data/lib/sequel/adapters/shared/mssql.rb +16 -5
  18. data/lib/sequel/adapters/shared/mysql.rb +87 -86
  19. data/lib/sequel/adapters/shared/oracle.rb +92 -3
  20. data/lib/sequel/adapters/shared/postgres.rb +85 -29
  21. data/lib/sequel/adapters/shared/progress.rb +8 -3
  22. data/lib/sequel/adapters/shared/sqlite.rb +53 -23
  23. data/lib/sequel/adapters/sqlite.rb +4 -7
  24. data/lib/sequel/adapters/utils/unsupported.rb +3 -3
  25. data/lib/sequel/connection_pool.rb +18 -25
  26. data/lib/sequel/core.rb +2 -21
  27. data/lib/sequel/database.rb +60 -44
  28. data/lib/sequel/database/schema_generator.rb +26 -31
  29. data/lib/sequel/database/schema_methods.rb +8 -3
  30. data/lib/sequel/database/schema_sql.rb +114 -28
  31. data/lib/sequel/dataset.rb +14 -41
  32. data/lib/sequel/dataset/convenience.rb +31 -54
  33. data/lib/sequel/dataset/graph.rb +7 -13
  34. data/lib/sequel/dataset/sql.rb +43 -54
  35. data/lib/sequel/extensions/inflector.rb +0 -5
  36. data/lib/sequel/extensions/schema_dumper.rb +238 -0
  37. data/lib/sequel/metaprogramming.rb +0 -20
  38. data/lib/sequel/model.rb +1 -2
  39. data/lib/sequel/model/base.rb +18 -16
  40. data/lib/sequel/model/inflections.rb +6 -9
  41. data/lib/sequel/plugins/caching.rb +0 -6
  42. data/lib/sequel/plugins/hook_class_methods.rb +1 -1
  43. data/lib/sequel/sql.rb +2 -0
  44. data/lib/sequel/version.rb +2 -2
  45. data/spec/adapters/firebird_spec.rb +35 -8
  46. data/spec/adapters/mysql_spec.rb +173 -266
  47. data/spec/adapters/oracle_spec.rb +13 -0
  48. data/spec/adapters/postgres_spec.rb +127 -227
  49. data/spec/adapters/sqlite_spec.rb +13 -171
  50. data/spec/core/connection_pool_spec.rb +15 -4
  51. data/spec/core/core_sql_spec.rb +14 -170
  52. data/spec/core/database_spec.rb +50 -132
  53. data/spec/core/dataset_spec.rb +47 -930
  54. data/spec/core/expression_filters_spec.rb +12 -0
  55. data/spec/core/schema_generator_spec.rb +37 -45
  56. data/spec/core/schema_spec.rb +26 -16
  57. data/spec/core/spec_helper.rb +0 -25
  58. data/spec/extensions/inflector_spec.rb +0 -3
  59. data/spec/extensions/schema_dumper_spec.rb +292 -0
  60. data/spec/extensions/serialization_spec.rb +9 -0
  61. data/spec/extensions/single_table_inheritance_spec.rb +6 -1
  62. data/spec/extensions/spec_helper.rb +1 -3
  63. data/spec/extensions/validation_helpers_spec.rb +4 -4
  64. data/spec/integration/database_test.rb +18 -0
  65. data/spec/integration/dataset_test.rb +112 -1
  66. data/spec/integration/eager_loader_test.rb +70 -9
  67. data/spec/integration/prepared_statement_test.rb +2 -2
  68. data/spec/integration/schema_test.rb +76 -27
  69. data/spec/integration/spec_helper.rb +0 -14
  70. data/spec/integration/transaction_test.rb +27 -0
  71. data/spec/model/associations_spec.rb +0 -36
  72. data/spec/model/base_spec.rb +18 -123
  73. data/spec/model/hooks_spec.rb +2 -235
  74. data/spec/model/inflector_spec.rb +15 -115
  75. data/spec/model/model_spec.rb +0 -120
  76. data/spec/model/plugins_spec.rb +0 -70
  77. data/spec/model/record_spec.rb +35 -93
  78. data/spec/model/spec_helper.rb +0 -27
  79. data/spec/model/validations_spec.rb +0 -931
  80. metadata +9 -14
  81. data/lib/sequel/deprecated.rb +0 -593
  82. data/lib/sequel/deprecated_migration.rb +0 -91
  83. data/lib/sequel/model/deprecated.rb +0 -204
  84. data/lib/sequel/model/deprecated_hooks.rb +0 -103
  85. data/lib/sequel/model/deprecated_inflector.rb +0 -335
  86. data/lib/sequel/model/deprecated_validations.rb +0 -388
  87. data/spec/core/core_ext_spec.rb +0 -156
  88. data/spec/core/migration_spec.rb +0 -263
  89. data/spec/core/pretty_table_spec.rb +0 -58
  90. data/spec/model/caching_spec.rb +0 -217
  91. data/spec/model/schema_spec.rb +0 -92
@@ -10,31 +10,6 @@ end
10
10
 
11
11
  Sequel.virtual_row_instance_eval = true
12
12
 
13
- module Spec::Example::ExampleMethods
14
- def deprec
15
- output = Sequel::Deprecation.output = nil
16
- begin
17
- yield
18
- ensure
19
- Sequel::Deprecation.output = output
20
- end
21
- end
22
- end
23
-
24
- module Spec::Example::ExampleGroupMethods
25
- def deprec_specify(*args, &block)
26
- specify(*args) do
27
- output = Sequel::Deprecation.output
28
- Sequel::Deprecation.output = nil
29
- begin
30
- instance_eval(&block)
31
- ensure
32
- Sequel::Deprecation.output = output
33
- end
34
- end
35
- end
36
- end
37
-
38
13
  class MockDataset < Sequel::Dataset
39
14
  def insert(*args)
40
15
  @db.execute insert_sql(*args)
@@ -104,12 +79,10 @@ end
104
79
 
105
80
  class << Sequel::Model
106
81
  alias orig_columns columns
107
- alias orig_str_columns str_columns
108
82
  def columns(*cols)
109
83
  return if cols.empty?
110
84
  define_method(:columns){cols}
111
85
  @dataset.instance_variable_set(:@columns, cols) if @dataset
112
- define_method(:str_columns){cols.map{|x|x.to_s.freeze}}
113
86
  def_column_accessor(*cols)
114
87
  @columns = cols
115
88
  @db_schema = {}
@@ -75,122 +75,6 @@ describe Sequel::Model::Errors do
75
75
  end
76
76
  end
77
77
 
78
- describe Sequel::Model do
79
- before do
80
- deprec do
81
- @c = Class.new(Sequel::Model) do
82
- def self.validates_coolness_of(attr)
83
- validates_each(attr) {|o, a, v| o.errors[a] << 'is not cool' if v != :cool}
84
- end
85
- end
86
- end
87
- end
88
-
89
- deprec_specify "should respond to validates, validations, has_validations?" do
90
- @c.should respond_to(:validations)
91
- @c.should respond_to(:has_validations?)
92
- end
93
-
94
- deprec_specify "should acccept validation definitions using validates_each" do
95
- @c.validates_each(:xx, :yy) {|o, a, v| o.errors[a] << 'too low' if v < 50}
96
- o = @c.new
97
- o.should_receive(:xx).once.and_return(40)
98
- o.should_receive(:yy).once.and_return(60)
99
- o.valid?.should == false
100
- o.errors.full_messages.should == ['xx too low']
101
- end
102
-
103
- deprec_specify "should return true/false for has_validations?" do
104
- @c.has_validations?.should == false
105
- @c.validates_each(:xx) {1}
106
- @c.has_validations?.should == true
107
- end
108
-
109
- deprec_specify "should validate multiple attributes at once" do
110
- o = @c.new
111
- def o.xx
112
- 1
113
- end
114
- def o.yy
115
- 2
116
- end
117
- vals = nil
118
- atts = nil
119
- @c.validates_each([:xx, :yy]){|obj,a,v| atts=a; vals=v}
120
- o.valid?
121
- vals.should == [1,2]
122
- atts.should == [:xx, :yy]
123
- end
124
-
125
- deprec_specify "should respect allow_missing option when using multiple attributes" do
126
- o = @c.new
127
- def o.xx
128
- self[:xx]
129
- end
130
- def o.yy
131
- self[:yy]
132
- end
133
- vals = nil
134
- atts = nil
135
- @c.validates_each([:xx, :yy], :allow_missing=>true){|obj,a,v| atts=a; vals=v}
136
-
137
- o.values[:xx] = 1
138
- o.valid?
139
- vals.should == [1,nil]
140
- atts.should == [:xx, :yy]
141
-
142
- vals = nil
143
- atts = nil
144
- o.values.clear
145
- o.values[:yy] = 2
146
- o.valid?
147
- vals.should == [nil, 2]
148
- atts.should == [:xx, :yy]
149
-
150
- vals = nil
151
- atts = nil
152
- o.values.clear
153
- o.valid?.should == true
154
- vals.should == nil
155
- atts.should == nil
156
- end
157
-
158
- deprec_specify "should overwrite existing validation with the same tag and attribute" do
159
- @c.validates_each(:xx, :xx, :tag=>:low) {|o, a, v| o.xxx; o.errors[a] << 'too low' if v < 50}
160
- @c.validates_each(:yy, :yy) {|o, a, v| o.yyy; o.errors[a] << 'too low' if v < 50}
161
- @c.validates_presence_of(:zz, :zz)
162
- @c.validates_length_of(:aa, :aa, :tag=>:blah)
163
- o = @c.new
164
- def o.zz
165
- @a ||= 0
166
- @a += 1
167
- end
168
- def o.aa
169
- @b ||= 0
170
- @b += 1
171
- end
172
- o.should_receive(:xx).once.and_return(40)
173
- o.should_receive(:yy).once.and_return(60)
174
- o.should_receive(:xxx).once
175
- o.should_receive(:yyy).twice
176
- o.valid?.should == false
177
- o.zz.should == 2
178
- o.aa.should == 2
179
- o.errors.full_messages.should == ['xx too low']
180
- end
181
-
182
- deprec_specify "should provide a validates method that takes block with validation definitions" do
183
- @c.validates do
184
- coolness_of :blah
185
- end
186
- @c.validations[:blah].should_not be_empty
187
- o = @c.new
188
- o.should_receive(:blah).once.and_return(nil)
189
- o.valid?.should == false
190
- o.errors.full_messages.should == ['blah is not cool']
191
- end
192
- end
193
-
194
78
  describe Sequel::Model do
195
79
  before do
196
80
  @c = Class.new(Sequel::Model) do
@@ -222,821 +106,6 @@ describe Sequel::Model do
222
106
  end
223
107
  end
224
108
 
225
- describe 'Sequel::Model::Validation::Generator' do
226
- before do
227
- $testit = nil
228
-
229
- @c = Class.new(Sequel::Model) do
230
- def self.validates_blah
231
- $testit = 1324
232
- end
233
- end
234
- end
235
-
236
- deprec_specify "should instance_eval the block, sending everything to its receiver" do
237
- @c.class_eval do
238
- validates do
239
- blah
240
- end
241
- end
242
- $testit.should == 1324
243
- end
244
- end
245
-
246
- describe Sequel::Model do
247
- before do
248
- @c = Class.new(Sequel::Model) do
249
- columns :value
250
-
251
- def self.filter(*args)
252
- o = Object.new
253
- def o.count; 2; end
254
- o
255
- end
256
-
257
- def skip; false; end
258
- def dont_skip; true; end
259
- end
260
- @m = @c.new
261
- end
262
-
263
- deprec_specify "should validate acceptance_of" do
264
- @c.validates_acceptance_of :value
265
- @m.should be_valid
266
- @m.value = '1'
267
- @m.should be_valid
268
- end
269
-
270
- deprec_specify "should validate acceptance_of with accept" do
271
- @c.validates_acceptance_of :value, :accept => 'true'
272
- @m.value = '1'
273
- @m.should_not be_valid
274
- @m.value = 'true'
275
- @m.should be_valid
276
- end
277
-
278
- deprec_specify "should validate acceptance_of with allow_nil => false" do
279
- @c.validates_acceptance_of :value, :allow_nil => false
280
- @m.should_not be_valid
281
- end
282
-
283
- deprec_specify "should validate acceptance_of with allow_missing => true" do
284
- @c.validates_acceptance_of :value, :allow_missing => true
285
- @m.should be_valid
286
- end
287
-
288
- deprec_specify "should validate acceptance_of with allow_missing => true and allow_nil => false" do
289
- @c.validates_acceptance_of :value, :allow_missing => true, :allow_nil => false
290
- @m.should be_valid
291
- @m.value = nil
292
- @m.should_not be_valid
293
- end
294
-
295
- deprec_specify "should validate acceptance_of with if => true" do
296
- @c.validates_acceptance_of :value, :if => :dont_skip
297
- @m.value = '0'
298
- @m.should_not be_valid
299
- end
300
-
301
- deprec_specify "should validate acceptance_of with if => false" do
302
- @c.validates_acceptance_of :value, :if => :skip
303
- @m.value = '0'
304
- @m.should be_valid
305
- end
306
-
307
- deprec_specify "should validate acceptance_of with if proc that evaluates to true" do
308
- @c.validates_acceptance_of :value, :if => proc{true}
309
- @m.value = '0'
310
- @m.should_not be_valid
311
- end
312
-
313
- deprec_specify "should validate acceptance_of with if proc that evaluates to false" do
314
- @c.validates_acceptance_of :value, :if => proc{false}
315
- @m.value = '0'
316
- @m.should be_valid
317
- end
318
-
319
- deprec_specify "should raise an error if :if option is not a Symbol, Proc, or nil" do
320
- @c.validates_acceptance_of :value, :if => 1
321
- @m.value = '0'
322
- proc{@m.valid?}.should raise_error(Sequel::Error)
323
- end
324
-
325
- deprec_specify "should validate confirmation_of" do
326
- @c.send(:attr_accessor, :value_confirmation)
327
- @c.validates_confirmation_of :value
328
-
329
- @m.value = 'blah'
330
- @m.should_not be_valid
331
-
332
- @m.value_confirmation = 'blah'
333
- @m.should be_valid
334
- end
335
-
336
- deprec_specify "should validate confirmation_of with if => true" do
337
- @c.send(:attr_accessor, :value_confirmation)
338
- @c.validates_confirmation_of :value, :if => :dont_skip
339
-
340
- @m.value = 'blah'
341
- @m.should_not be_valid
342
- end
343
-
344
- deprec_specify "should validate confirmation_of with if => false" do
345
- @c.send(:attr_accessor, :value_confirmation)
346
- @c.validates_confirmation_of :value, :if => :skip
347
-
348
- @m.value = 'blah'
349
- @m.should be_valid
350
- end
351
-
352
- deprec_specify "should validate confirmation_of with allow_missing => true" do
353
- @c.send(:attr_accessor, :value_confirmation)
354
- @c.validates_acceptance_of :value, :allow_missing => true
355
- @m.should be_valid
356
- @m.value_confirmation = 'blah'
357
- @m.should be_valid
358
- @m.value = nil
359
- @m.should_not be_valid
360
- end
361
-
362
- deprec_specify "should validate format_of" do
363
- @c.validates_format_of :value, :with => /.+_.+/
364
- @m.value = 'abc_'
365
- @m.should_not be_valid
366
- @m.value = 'abc_def'
367
- @m.should be_valid
368
- end
369
-
370
- deprec_specify "should raise for validate_format_of without regexp" do
371
- proc {@c.validates_format_of :value}.should raise_error(ArgumentError)
372
- proc {@c.validates_format_of :value, :with => :blah}.should raise_error(ArgumentError)
373
- end
374
-
375
- deprec_specify "should validate format_of with if => true" do
376
- @c.validates_format_of :value, :with => /_/, :if => :dont_skip
377
-
378
- @m.value = 'a'
379
- @m.should_not be_valid
380
- end
381
-
382
- deprec_specify "should validate format_of with if => false" do
383
- @c.validates_format_of :value, :with => /_/, :if => :skip
384
-
385
- @m.value = 'a'
386
- @m.should be_valid
387
- end
388
-
389
- deprec_specify "should validate format_of with allow_missing => true" do
390
- @c.validates_format_of :value, :allow_missing => true, :with=>/./
391
- @m.should be_valid
392
- @m.value = nil
393
- @m.should_not be_valid
394
- end
395
-
396
- deprec_specify "should validate length_of with maximum" do
397
- @c.validates_length_of :value, :maximum => 5
398
- @m.should_not be_valid
399
- @m.value = '12345'
400
- @m.should be_valid
401
- @m.value = '123456'
402
- @m.should_not be_valid
403
- end
404
-
405
- deprec_specify "should validate length_of with minimum" do
406
- @c.validates_length_of :value, :minimum => 5
407
- @m.should_not be_valid
408
- @m.value = '12345'
409
- @m.should be_valid
410
- @m.value = '1234'
411
- @m.should_not be_valid
412
- end
413
-
414
- deprec_specify "should validate length_of with within" do
415
- @c.validates_length_of :value, :within => 2..5
416
- @m.should_not be_valid
417
- @m.value = '12345'
418
- @m.should be_valid
419
- @m.value = '1'
420
- @m.should_not be_valid
421
- @m.value = '123456'
422
- @m.should_not be_valid
423
- end
424
-
425
- deprec_specify "should validate length_of with is" do
426
- @c.validates_length_of :value, :is => 3
427
- @m.should_not be_valid
428
- @m.value = '123'
429
- @m.should be_valid
430
- @m.value = '12'
431
- @m.should_not be_valid
432
- @m.value = '1234'
433
- @m.should_not be_valid
434
- end
435
-
436
- deprec_specify "should validate length_of with allow_nil" do
437
- @c.validates_length_of :value, :is => 3, :allow_nil => true
438
- @m.should be_valid
439
- end
440
-
441
- deprec_specify "should validate length_of with if => true" do
442
- @c.validates_length_of :value, :is => 3, :if => :dont_skip
443
-
444
- @m.value = 'a'
445
- @m.should_not be_valid
446
- end
447
-
448
- deprec_specify "should validate length_of with if => false" do
449
- @c.validates_length_of :value, :is => 3, :if => :skip
450
-
451
- @m.value = 'a'
452
- @m.should be_valid
453
- end
454
-
455
- deprec_specify "should validate length_of with allow_missing => true" do
456
- @c.validates_length_of :value, :allow_missing => true, :minimum => 5
457
- @m.should be_valid
458
- @m.value = nil
459
- @m.should_not be_valid
460
- end
461
-
462
- deprec_specify "should allow multiple calls to validates_length_of with different options without overwriting" do
463
- @c.validates_length_of :value, :maximum => 5
464
- @c.validates_length_of :value, :minimum => 5
465
- @m.should_not be_valid
466
- @m.value = '12345'
467
- @m.should be_valid
468
- @m.value = '123456'
469
- @m.should_not be_valid
470
- @m.value = '12345'
471
- @m.should be_valid
472
- @m.value = '1234'
473
- @m.should_not be_valid
474
- end
475
-
476
- deprec_specify "should validate numericality_of" do
477
- @c.validates_numericality_of :value
478
- @m.value = 'blah'
479
- @m.should_not be_valid
480
- @m.value = '123'
481
- @m.should be_valid
482
- @m.value = '123.1231'
483
- @m.should be_valid
484
- @m.value = '+1'
485
- @m.should be_valid
486
- @m.value = '-1'
487
- @m.should be_valid
488
- @m.value = '+1.123'
489
- @m.should be_valid
490
- @m.value = '-0.123'
491
- @m.should be_valid
492
- @m.value = '-0.123E10'
493
- @m.should be_valid
494
- @m.value = '32.123e10'
495
- @m.should be_valid
496
- @m.value = '+32.123E10'
497
- @m.should be_valid
498
- @m.should be_valid
499
- @m.value = '.0123'
500
- end
501
-
502
- deprec_specify "should validate numericality_of with only_integer" do
503
- @c.validates_numericality_of :value, :only_integer => true
504
- @m.value = 'blah'
505
- @m.should_not be_valid
506
- @m.value = '123'
507
- @m.should be_valid
508
- @m.value = '123.1231'
509
- @m.should_not be_valid
510
- end
511
-
512
- deprec_specify "should validate numericality_of with if => true" do
513
- @c.validates_numericality_of :value, :if => :dont_skip
514
-
515
- @m.value = 'a'
516
- @m.should_not be_valid
517
- end
518
-
519
- deprec_specify "should validate numericality_of with if => false" do
520
- @c.validates_numericality_of :value, :if => :skip
521
-
522
- @m.value = 'a'
523
- @m.should be_valid
524
- end
525
-
526
- deprec_specify "should validate numericality_of with allow_missing => true" do
527
- @c.validates_numericality_of :value, :allow_missing => true
528
- @m.should be_valid
529
- @m.value = nil
530
- @m.should_not be_valid
531
- end
532
-
533
- deprec_specify "should validate presence_of" do
534
- @c.validates_presence_of :value
535
- @m.should_not be_valid
536
- @m.value = ''
537
- @m.should_not be_valid
538
- @m.value = 1234
539
- @m.should be_valid
540
- @m.value = nil
541
- @m.should_not be_valid
542
- @m.value = true
543
- @m.should be_valid
544
- @m.value = false
545
- @m.should be_valid
546
- end
547
-
548
- deprec_specify "should validate inclusion_of with an array" do
549
- @c.validates_inclusion_of :value, :in => [1,2]
550
- @m.should_not be_valid
551
- @m.value = 1
552
- @m.should be_valid
553
- @m.value = 1.5
554
- @m.should_not be_valid
555
- @m.value = 2
556
- @m.should be_valid
557
- @m.value = 3
558
- @m.should_not be_valid
559
- end
560
-
561
- deprec_specify "should validate inclusion_of with a range" do
562
- @c.validates_inclusion_of :value, :in => 1..4
563
- @m.should_not be_valid
564
- @m.value = 1
565
- @m.should be_valid
566
- @m.value = 1.5
567
- @m.should be_valid
568
- @m.value = 0
569
- @m.should_not be_valid
570
- @m.value = 5
571
- @m.should_not be_valid
572
- end
573
-
574
- deprec_specify "should raise an error if inclusion_of doesn't receive a valid :in option" do
575
- lambda {
576
- @c.validates_inclusion_of :value
577
- }.should raise_error(ArgumentError)
578
-
579
- lambda {
580
- @c.validates_inclusion_of :value, :in => 1
581
- }.should raise_error(ArgumentError)
582
- end
583
-
584
- deprec_specify "should raise an error if inclusion_of handles :allow_nil too" do
585
- @c.validates_inclusion_of :value, :in => 1..4, :allow_nil => true
586
- @m.value = nil
587
- @m.should be_valid
588
- @m.value = 0
589
- @m.should_not be_valid
590
- end
591
-
592
- deprec_specify "should validate presence_of with if => true" do
593
- @c.validates_presence_of :value, :if => :dont_skip
594
- @m.should_not be_valid
595
- end
596
-
597
- deprec_specify "should validate presence_of with if => false" do
598
- @c.validates_presence_of :value, :if => :skip
599
- @m.should be_valid
600
- end
601
-
602
- deprec_specify "should validate presence_of with allow_missing => true" do
603
- @c.validates_presence_of :value, :allow_missing => true
604
- @m.should be_valid
605
- @m.value = nil
606
- @m.should_not be_valid
607
- end
608
-
609
- deprec_specify "should validate uniqueness_of with if => true" do
610
- @c.validates_uniqueness_of :value, :if => :dont_skip
611
-
612
- @m.value = 'a'
613
- @m.should_not be_valid
614
- end
615
-
616
- deprec_specify "should validate uniqueness_of with if => false" do
617
- @c.validates_uniqueness_of :value, :if => :skip
618
-
619
- @m.value = 'a'
620
- @m.should be_valid
621
- end
622
-
623
- deprec_specify "should validate uniqueness_of with allow_missing => true" do
624
- @c.validates_uniqueness_of :value, :allow_missing => true
625
- @m.should be_valid
626
- @m.value = nil
627
- @m.should_not be_valid
628
- end
629
- end
630
-
631
- context "Superclass validations" do
632
- before do
633
- deprec do
634
- @c1 = Class.new(Sequel::Model) do
635
- columns :value
636
- validates_length_of :value, :minimum => 5
637
- end
638
-
639
- @c2 = Class.new(@c1) do
640
- columns :value
641
- validates_format_of :value, :with => /^[a-z]+$/
642
- end
643
- end
644
- end
645
-
646
- deprec_specify "should be checked when validating" do
647
- o = @c2.new
648
- o.value = 'ab'
649
- o.valid?.should == false
650
- o.errors.full_messages.should == [
651
- 'value is too short'
652
- ]
653
-
654
- o.value = '12'
655
- o.valid?.should == false
656
- o.errors.full_messages.should == [
657
- 'value is too short',
658
- 'value is invalid'
659
- ]
660
-
661
- o.value = 'abcde'
662
- o.valid?.should be_true
663
- end
664
-
665
- deprec_specify "should be skipped if skip_superclass_validations is called" do
666
- @c2.skip_superclass_validations
667
-
668
- o = @c2.new
669
- o.value = 'ab'
670
- o.valid?.should be_true
671
-
672
- o.value = '12'
673
- o.valid?.should == false
674
- o.errors.full_messages.should == [
675
- 'value is invalid'
676
- ]
677
-
678
- o.value = 'abcde'
679
- o.valid?.should be_true
680
- end
681
- end
682
-
683
- context ".validates with block" do
684
- deprec_specify "should support calling .each" do
685
- @c = Class.new(Sequel::Model) do
686
- columns :vvv
687
- validates do
688
- each :vvv do |o, a, v|
689
- o.errors[a] << "is less than zero" if v.to_i < 0
690
- end
691
- end
692
- end
693
-
694
- o = @c.new
695
- o.vvv = 1
696
- o.should be_valid
697
- o.vvv = -1
698
- o.should_not be_valid
699
- end
700
- end
701
-
702
- describe Sequel::Model, "Validations" do
703
-
704
- before(:all) do
705
- class ::Person < Sequel::Model
706
- columns :id,:name,:first_name,:last_name,:middle_name,:initials,:age, :terms
707
- end
708
-
709
- class ::Smurf < Person
710
- end
711
-
712
- class ::Cow < Sequel::Model
713
- columns :id, :name, :got_milk
714
- end
715
-
716
- class ::User < Sequel::Model
717
- columns :id, :username, :password
718
- end
719
-
720
- class ::Address < Sequel::Model
721
- columns :id, :zip_code
722
- end
723
- end
724
-
725
- deprec_specify "should validate the acceptance of a column" do
726
- class ::Cow < Sequel::Model
727
- validations.clear
728
- validates_acceptance_of :got_milk, :accept => 'blah', :allow_nil => false
729
- end
730
-
731
- @cow = Cow.new
732
- @cow.should_not be_valid
733
- @cow.errors.full_messages.should == ["got_milk is not accepted"]
734
-
735
- @cow.got_milk = "blah"
736
- @cow.should be_valid
737
- end
738
-
739
- deprec_specify "should validate the confirmation of a column" do
740
- class ::User < Sequel::Model
741
- def password_confirmation
742
- "test"
743
- end
744
-
745
- validations.clear
746
- validates_confirmation_of :password
747
- end
748
-
749
- @user = User.new
750
- @user.should_not be_valid
751
- @user.errors.full_messages.should == ["password is not confirmed"]
752
-
753
- @user.password = "test"
754
- @user.should be_valid
755
- end
756
-
757
- deprec_specify "should validate format of column" do
758
- class ::Person < Sequel::Model
759
- validates_format_of :first_name, :with => /^[a-zA-Z]+$/
760
- end
761
-
762
- @person = Person.new :first_name => "Lancelot99"
763
- @person.valid?.should be_false
764
- @person = Person.new :first_name => "Anita"
765
- @person.valid?.should be_true
766
- end
767
-
768
- deprec_specify "should validate length of column" do
769
- class ::Person < Sequel::Model
770
- validations.clear
771
- validates_length_of :first_name, :maximum => 30
772
- validates_length_of :last_name, :minimum => 30
773
- validates_length_of :middle_name, :within => 1..5
774
- validates_length_of :initials, :is => 2
775
- end
776
-
777
- @person = Person.new(
778
- :first_name => "Anamethatiswaytofreakinglongandwayoverthirtycharacters",
779
- :last_name => "Alastnameunderthirtychars",
780
- :initials => "LGC",
781
- :middle_name => "danger"
782
- )
783
-
784
- @person.should_not be_valid
785
- @person.errors.full_messages.size.should == 4
786
- @person.errors.full_messages.should include(
787
- 'first_name is too long',
788
- 'last_name is too short',
789
- 'middle_name is the wrong length',
790
- 'initials is the wrong length'
791
- )
792
-
793
- @person.first_name = "Lancelot"
794
- @person.last_name = "1234567890123456789012345678901"
795
- @person.initials = "LC"
796
- @person.middle_name = "Will"
797
- @person.should be_valid
798
- end
799
-
800
- deprec_specify "should validate that a column doesn't have a string value" do
801
- p = Class.new(Sequel::Model)
802
- p.class_eval do
803
- columns :age, :price, :confirmed
804
- self.raise_on_typecast_failure = false
805
- validates_not_string :age
806
- validates_not_string :confirmed
807
- validates_not_string :price, :message=>'is not valid'
808
- @db_schema = {:age=>{:type=>:integer}}
809
- end
810
-
811
- @person = p.new
812
- @person.should be_valid
813
-
814
- @person.confirmed = 't'
815
- @person.should_not be_valid
816
- @person.errors.full_messages.should == ['confirmed is a string']
817
- @person.confirmed = true
818
- @person.should be_valid
819
-
820
- @person.age = 'a'
821
- @person.should_not be_valid
822
- @person.errors.full_messages.should == ['age is not a valid integer']
823
- @person.db_schema[:age][:type] = :datetime
824
- @person.should_not be_valid
825
- @person.errors.full_messages.should == ['age is not a valid datetime']
826
- @person.age = 20
827
- @person.should be_valid
828
-
829
- @person.price = 'a'
830
- @person.should_not be_valid
831
- @person.errors.full_messages.should == ['price is not valid']
832
- @person.price = 20
833
- @person.should be_valid
834
- end
835
-
836
- deprec_specify "should validate numericality of column" do
837
- class ::Person < Sequel::Model
838
- validations.clear
839
- validates_numericality_of :age
840
- end
841
-
842
- @person = Person.new :age => "Twenty"
843
- @person.should_not be_valid
844
- @person.errors.full_messages.should == ['age is not a number']
845
-
846
- @person.age = 20
847
- @person.should be_valid
848
- end
849
-
850
- deprec_specify "should validate the presence of a column" do
851
- class ::Cow < Sequel::Model
852
- validations.clear
853
- validates_presence_of :name
854
- end
855
-
856
- @cow = Cow.new
857
- @cow.should_not be_valid
858
- @cow.errors.full_messages.should == ['name is not present']
859
-
860
- @cow.name = "Betsy"
861
- @cow.should be_valid
862
- end
863
-
864
- deprec_specify "should validate the uniqueness of a column" do
865
- class ::User < Sequel::Model
866
- validations.clear
867
- validates do
868
- uniqueness_of :username
869
- end
870
- end
871
- User.dataset.extend(Module.new {
872
- def fetch_rows(sql)
873
- @db << sql
874
-
875
- case sql
876
- when /COUNT.*username = '0records'/
877
- yield({:v => 0})
878
- when /COUNT.*username = '2records'/
879
- yield({:v => 2})
880
- when /COUNT.*username = '1record'/
881
- yield({:v => 1})
882
- when /username = '1record'/
883
- yield({:id => 3, :username => "1record", :password => "test"})
884
- end
885
- end
886
- })
887
-
888
- @user = User.new(:username => "2records", :password => "anothertest")
889
- @user.should_not be_valid
890
- @user.errors.full_messages.should == ['username is already taken']
891
-
892
- @user = User.new(:username => "1record", :password => "anothertest")
893
- @user.should_not be_valid
894
- @user.errors.full_messages.should == ['username is already taken']
895
-
896
- @user = User.load(:id=>4, :username => "1record", :password => "anothertest")
897
- @user.should_not be_valid
898
- @user.errors.full_messages.should == ['username is already taken']
899
-
900
- @user = User.load(:id=>3, :username => "1record", :password => "anothertest")
901
- @user.should be_valid
902
- @user.errors.full_messages.should == []
903
-
904
- @user = User.new(:username => "0records", :password => "anothertest")
905
- @user.should be_valid
906
- @user.errors.full_messages.should == []
907
- end
908
-
909
- deprec_specify "should validate the uniqueness of multiple columns" do
910
- class ::User < Sequel::Model
911
- validations.clear
912
- validates do
913
- uniqueness_of [:username, :password]
914
- end
915
- end
916
- User.dataset.extend(Module.new {
917
- def fetch_rows(sql)
918
- @db << sql
919
-
920
- case sql
921
- when /COUNT.*username = '0records'/
922
- yield({:v => 0})
923
- when /COUNT.*username = '2records'/
924
- yield({:v => 2})
925
- when /COUNT.*username = '1record'/
926
- yield({:v => 1})
927
- when /username = '1record'/
928
- if sql =~ /password = 'anothertest'/
929
- yield({:id => 3, :username => "1record", :password => "anothertest"})
930
- else
931
- yield({:id => 4, :username => "1record", :password => "test"})
932
- end
933
- end
934
- end
935
- })
936
-
937
- @user = User.new(:username => "2records", :password => "anothertest")
938
- @user.should_not be_valid
939
- @user.errors.full_messages.should == ['username and password is already taken']
940
-
941
- @user = User.new(:username => "1record", :password => "anothertest")
942
- @user.should_not be_valid
943
- @user.errors.full_messages.should == ['username and password is already taken']
944
-
945
- @user = User.load(:id=>4, :username => "1record", :password => "anothertest")
946
- @user.should_not be_valid
947
- @user.errors.full_messages.should == ['username and password is already taken']
948
-
949
- @user = User.load(:id=>3, :username => "1record", :password => "test")
950
- @user.should_not be_valid
951
- @user.errors.full_messages.should == ['username and password is already taken']
952
-
953
- @user = User.load(:id=>3, :username => "1record", :password => "anothertest")
954
- @user.should be_valid
955
- @user.errors.full_messages.should == []
956
-
957
- @user = User.new(:username => "0records", :password => "anothertest")
958
- @user.should be_valid
959
- @user.errors.full_messages.should == []
960
- end
961
-
962
- deprec_specify "should have a validates block that contains multiple validations" do
963
- class ::Person < Sequel::Model
964
- validations.clear
965
- validates do
966
- format_of :first_name, :with => /^[a-zA-Z]+$/
967
- length_of :first_name, :maximum => 30
968
- end
969
- end
970
-
971
- Person.validations[:first_name].size.should == 2
972
-
973
- @person = Person.new :first_name => "Lancelot99"
974
- @person.valid?.should be_false
975
-
976
- @person2 = Person.new :first_name => "Wayne"
977
- @person2.valid?.should be_true
978
- end
979
-
980
- deprec_specify "should allow 'longhand' validations direcly within the model." do
981
- lambda {
982
- class ::Person < Sequel::Model
983
- validations.clear
984
- validates_length_of :first_name, :maximum => 30
985
- end
986
- }.should_not raise_error
987
- Person.validations.length.should eql(1)
988
- end
989
-
990
- deprec_specify "should define a has_validations? method which returns true if the model has validations, false otherwise" do
991
- class ::Person < Sequel::Model
992
- validations.clear
993
- validates do
994
- format_of :first_name, :with => /\w+/
995
- length_of :first_name, :maximum => 30
996
- end
997
- end
998
-
999
- class ::Smurf < Person
1000
- validations.clear
1001
- end
1002
-
1003
- Person.should have_validations
1004
- Smurf.should_not have_validations
1005
- end
1006
-
1007
- deprec_specify "should validate correctly instances initialized with string keys" do
1008
- class ::Can < Sequel::Model
1009
- columns :id, :name
1010
-
1011
- validates_length_of :name, :minimum => 4
1012
- end
1013
-
1014
- Can.new('name' => 'ab').should_not be_valid
1015
- Can.new('name' => 'abcd').should be_valid
1016
- end
1017
-
1018
- end
1019
-
1020
- describe "Model#save!" do
1021
- before do
1022
- @c = Class.new(Sequel::Model(:people)) do
1023
- def columns; [:id]; end
1024
-
1025
- validates_each :id do |o, a, v|
1026
- o.errors[a] << 'blah' unless v == 5
1027
- end
1028
- end
1029
- @m = @c.load(:id => 4)
1030
- MODEL_DB.reset
1031
- end
1032
-
1033
- deprec_specify "should save regardless of validations" do
1034
- @m.should_not be_valid
1035
- @m.save!
1036
- MODEL_DB.sqls.should == ['UPDATE people SET id = 4 WHERE (id = 4)']
1037
- end
1038
- end
1039
-
1040
109
  describe "Model#save" do
1041
110
  before do
1042
111
  @c = Class.new(Sequel::Model(:people)) do