active_record_doctor 1.10.0 → 1.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/active_record_doctor/detectors/base.rb +180 -50
- data/lib/active_record_doctor/detectors/extraneous_indexes.rb +24 -27
- data/lib/active_record_doctor/detectors/incorrect_boolean_presence_validation.rb +2 -5
- data/lib/active_record_doctor/detectors/incorrect_dependent_option.rb +63 -21
- data/lib/active_record_doctor/detectors/incorrect_length_validation.rb +7 -10
- data/lib/active_record_doctor/detectors/mismatched_foreign_key_type.rb +16 -9
- data/lib/active_record_doctor/detectors/missing_foreign_keys.rb +2 -4
- data/lib/active_record_doctor/detectors/missing_non_null_constraint.rb +13 -11
- data/lib/active_record_doctor/detectors/missing_presence_validation.rb +14 -7
- data/lib/active_record_doctor/detectors/missing_unique_indexes.rb +5 -11
- data/lib/active_record_doctor/detectors/short_primary_key_type.rb +1 -1
- data/lib/active_record_doctor/detectors/undefined_table_references.rb +2 -2
- data/lib/active_record_doctor/detectors/unindexed_deleted_at.rb +5 -13
- data/lib/active_record_doctor/detectors/unindexed_foreign_keys.rb +2 -4
- data/lib/active_record_doctor/logger/dummy.rb +11 -0
- data/lib/active_record_doctor/logger/hierarchical.rb +22 -0
- data/lib/active_record_doctor/logger.rb +6 -0
- data/lib/active_record_doctor/rake/task.rb +10 -1
- data/lib/active_record_doctor/runner.rb +8 -3
- data/lib/active_record_doctor/version.rb +1 -1
- data/lib/active_record_doctor.rb +3 -0
- data/test/active_record_doctor/detectors/disable_test.rb +1 -1
- data/test/active_record_doctor/detectors/incorrect_boolean_presence_validation_test.rb +7 -7
- data/test/active_record_doctor/detectors/incorrect_dependent_option_test.rb +136 -57
- data/test/active_record_doctor/detectors/incorrect_length_validation_test.rb +16 -14
- data/test/active_record_doctor/detectors/mismatched_foreign_key_type_test.rb +35 -1
- data/test/active_record_doctor/detectors/missing_non_null_constraint_test.rb +46 -23
- data/test/active_record_doctor/detectors/missing_presence_validation_test.rb +55 -27
- data/test/active_record_doctor/detectors/missing_unique_indexes_test.rb +36 -36
- data/test/active_record_doctor/detectors/undefined_table_references_test.rb +11 -13
- data/test/active_record_doctor/runner_test.rb +18 -19
- data/test/setup.rb +10 -6
- metadata +19 -4
- data/test/model_factory.rb +0 -128
@@ -3,30 +3,30 @@
|
|
3
3
|
class ActiveRecordDoctor::Detectors::IncorrectDependentOptionTest < Minitest::Test
|
4
4
|
def test_invoking_no_callbacks_suggests_delete_all
|
5
5
|
create_table(:companies) do
|
6
|
-
end.
|
6
|
+
end.define_model do
|
7
7
|
has_many :users, dependent: :destroy
|
8
8
|
end
|
9
9
|
|
10
10
|
create_table(:users) do |t|
|
11
11
|
t.references :companies
|
12
|
-
end.
|
12
|
+
end.define_model do
|
13
13
|
belongs_to :company
|
14
14
|
end
|
15
15
|
|
16
16
|
assert_problems(<<~OUTPUT)
|
17
|
-
use `dependent: :delete_all` or similar on
|
17
|
+
use `dependent: :delete_all` or similar on TransientRecord::Models::Company.users - associated model TransientRecord::Models::User has no callbacks and can be deleted in bulk
|
18
18
|
OUTPUT
|
19
19
|
end
|
20
20
|
|
21
21
|
def test_invoking_callbacks_does_not_suggest_delete_all
|
22
22
|
create_table(:companies) do
|
23
|
-
end.
|
23
|
+
end.define_model do
|
24
24
|
has_many :users, dependent: :destroy
|
25
25
|
end
|
26
26
|
|
27
27
|
create_table(:users) do |t|
|
28
28
|
t.references :companies
|
29
|
-
end.
|
29
|
+
end.define_model do
|
30
30
|
belongs_to :company
|
31
31
|
|
32
32
|
before_destroy :log
|
@@ -40,13 +40,13 @@ class ActiveRecordDoctor::Detectors::IncorrectDependentOptionTest < Minitest::Te
|
|
40
40
|
|
41
41
|
def test_skipping_callbacks_suggests_destroy
|
42
42
|
create_table(:companies) do
|
43
|
-
end.
|
43
|
+
end.define_model do
|
44
44
|
has_many :users, dependent: :delete_all
|
45
45
|
end
|
46
46
|
|
47
47
|
create_table(:users) do |t|
|
48
48
|
t.references :companies
|
49
|
-
end.
|
49
|
+
end.define_model do
|
50
50
|
belongs_to :company
|
51
51
|
|
52
52
|
before_destroy :log
|
@@ -56,19 +56,19 @@ class ActiveRecordDoctor::Detectors::IncorrectDependentOptionTest < Minitest::Te
|
|
56
56
|
end
|
57
57
|
|
58
58
|
assert_problems(<<~OUTPUT)
|
59
|
-
use `dependent: :destroy` or similar on
|
59
|
+
use `dependent: :destroy` or similar on TransientRecord::Models::Company.users - associated model TransientRecord::Models::User has callbacks that are currently skipped
|
60
60
|
OUTPUT
|
61
61
|
end
|
62
62
|
|
63
63
|
def test_invoking_callbacks_does_not_suggest_destroy
|
64
64
|
create_table(:companies) do
|
65
|
-
end.
|
65
|
+
end.define_model do
|
66
66
|
has_many :users, dependent: :destroy
|
67
67
|
end
|
68
68
|
|
69
69
|
create_table(:users) do |t|
|
70
70
|
t.references :companies
|
71
|
-
end.
|
71
|
+
end.define_model do
|
72
72
|
belongs_to :company
|
73
73
|
|
74
74
|
before_destroy :log
|
@@ -82,102 +82,102 @@ class ActiveRecordDoctor::Detectors::IncorrectDependentOptionTest < Minitest::Te
|
|
82
82
|
|
83
83
|
def test_works_on_has_one
|
84
84
|
create_table(:companies) do
|
85
|
-
end.
|
86
|
-
has_one :owner, class_name: "
|
85
|
+
end.define_model do
|
86
|
+
has_one :owner, class_name: "TransientRecord::Models::User", dependent: :destroy
|
87
87
|
end
|
88
88
|
|
89
89
|
create_table(:users) do |t|
|
90
90
|
t.references :companies
|
91
|
-
end.
|
91
|
+
end.define_model do
|
92
92
|
belongs_to :company
|
93
93
|
end
|
94
94
|
|
95
95
|
assert_problems(<<~OUTPUT)
|
96
|
-
use `dependent: :delete` or similar on
|
96
|
+
use `dependent: :delete` or similar on TransientRecord::Models::Company.owner - associated model TransientRecord::Models::User has no callbacks and can be deleted without loading
|
97
97
|
OUTPUT
|
98
98
|
end
|
99
99
|
|
100
100
|
def test_works_on_belongs_to
|
101
101
|
create_table(:companies) do
|
102
|
-
end.
|
102
|
+
end.define_model do
|
103
103
|
has_many :users
|
104
104
|
end
|
105
105
|
|
106
106
|
create_table(:users) do |t|
|
107
107
|
t.references :company
|
108
|
-
end.
|
108
|
+
end.define_model do
|
109
109
|
belongs_to :company, dependent: :destroy
|
110
110
|
end
|
111
111
|
|
112
112
|
assert_problems(<<~OUTPUT)
|
113
|
-
use `dependent: :delete` or similar on
|
113
|
+
use `dependent: :delete` or similar on TransientRecord::Models::User.company - associated model TransientRecord::Models::Company has no callbacks and can be deleted without loading
|
114
114
|
OUTPUT
|
115
115
|
end
|
116
116
|
|
117
117
|
def test_no_foreign_key_on_second_level_association
|
118
118
|
create_table(:companies) do
|
119
|
-
end.
|
119
|
+
end.define_model do
|
120
120
|
has_many :users
|
121
121
|
has_many :projects
|
122
122
|
end
|
123
123
|
|
124
124
|
create_table(:users) do |t|
|
125
125
|
t.references :company
|
126
|
-
end.
|
126
|
+
end.define_model do
|
127
127
|
belongs_to :company, dependent: :destroy
|
128
128
|
end
|
129
129
|
|
130
130
|
create_table(:projects) do |t|
|
131
131
|
t.references :company
|
132
|
-
end.
|
132
|
+
end.define_model do
|
133
133
|
belongs_to :company
|
134
134
|
end
|
135
135
|
|
136
136
|
assert_problems(<<~OUTPUT)
|
137
|
-
use `dependent: :delete` or similar on
|
137
|
+
use `dependent: :delete` or similar on TransientRecord::Models::User.company - associated model TransientRecord::Models::Company has no callbacks and can be deleted without loading
|
138
138
|
OUTPUT
|
139
139
|
end
|
140
140
|
|
141
141
|
def test_nullify_foreign_key_on_second_level_association
|
142
142
|
create_table(:companies) do
|
143
|
-
end.
|
143
|
+
end.define_model do
|
144
144
|
has_many :users
|
145
145
|
has_many :projects
|
146
146
|
end
|
147
147
|
|
148
148
|
create_table(:users) do |t|
|
149
149
|
t.references :company
|
150
|
-
end.
|
150
|
+
end.define_model do
|
151
151
|
belongs_to :company, dependent: :destroy
|
152
152
|
end
|
153
153
|
|
154
154
|
create_table(:projects) do |t|
|
155
155
|
t.references :company, foreign_key: { on_delete: :nullify }
|
156
|
-
end.
|
156
|
+
end.define_model do
|
157
157
|
belongs_to :company
|
158
158
|
end
|
159
159
|
|
160
160
|
assert_problems(<<~OUTPUT)
|
161
|
-
use `dependent: :delete` or similar on
|
161
|
+
use `dependent: :delete` or similar on TransientRecord::Models::User.company - associated model TransientRecord::Models::Company has no callbacks and can be deleted without loading
|
162
162
|
OUTPUT
|
163
163
|
end
|
164
164
|
|
165
165
|
def test_cascade_foreign_key_and_callbacks_on_second_level_association
|
166
166
|
create_table(:companies) do
|
167
|
-
end.
|
167
|
+
end.define_model do
|
168
168
|
has_many :users
|
169
169
|
has_many :projects
|
170
170
|
end
|
171
171
|
|
172
172
|
create_table(:users) do |t|
|
173
173
|
t.references :company
|
174
|
-
end.
|
174
|
+
end.define_model do
|
175
175
|
belongs_to :company, dependent: :delete
|
176
176
|
end
|
177
177
|
|
178
178
|
create_table(:projects) do |t|
|
179
179
|
t.references :company, foreign_key: { on_delete: :cascade }
|
180
|
-
end.
|
180
|
+
end.define_model do
|
181
181
|
belongs_to :company
|
182
182
|
|
183
183
|
before_destroy :log
|
@@ -187,26 +187,26 @@ class ActiveRecordDoctor::Detectors::IncorrectDependentOptionTest < Minitest::Te
|
|
187
187
|
end
|
188
188
|
|
189
189
|
assert_problems(<<~OUTPUT)
|
190
|
-
use `dependent: :destroy` or similar on
|
190
|
+
use `dependent: :destroy` or similar on TransientRecord::Models::User.company - associated model TransientRecord::Models::Company has callbacks that are currently skipped
|
191
191
|
OUTPUT
|
192
192
|
end
|
193
193
|
|
194
194
|
def test_cascade_foreign_key_and_no_callbacks_on_second_level_association
|
195
195
|
create_table(:companies) do
|
196
|
-
end.
|
196
|
+
end.define_model do
|
197
197
|
has_many :users
|
198
198
|
has_many :projects
|
199
199
|
end
|
200
200
|
|
201
201
|
create_table(:users) do |t|
|
202
202
|
t.references :company
|
203
|
-
end.
|
203
|
+
end.define_model do
|
204
204
|
belongs_to :company, dependent: :delete
|
205
205
|
end
|
206
206
|
|
207
207
|
create_table(:projects) do |t|
|
208
208
|
t.references :company, foreign_key: { on_delete: :cascade }
|
209
|
-
end.
|
209
|
+
end.define_model do
|
210
210
|
belongs_to :company
|
211
211
|
end
|
212
212
|
|
@@ -215,13 +215,13 @@ class ActiveRecordDoctor::Detectors::IncorrectDependentOptionTest < Minitest::Te
|
|
215
215
|
|
216
216
|
def test_no_dependent_suggests_nothing
|
217
217
|
create_table(:companies) do
|
218
|
-
end.
|
218
|
+
end.define_model do
|
219
219
|
has_many :users
|
220
220
|
end
|
221
221
|
|
222
222
|
create_table(:users) do |t|
|
223
223
|
t.references :companies
|
224
|
-
end.
|
224
|
+
end.define_model do
|
225
225
|
belongs_to :company
|
226
226
|
end
|
227
227
|
|
@@ -232,22 +232,22 @@ class ActiveRecordDoctor::Detectors::IncorrectDependentOptionTest < Minitest::Te
|
|
232
232
|
create_table(:images) do |t|
|
233
233
|
t.bigint :imageable_id, null: false
|
234
234
|
t.string :imageable_type, null: true
|
235
|
-
end.
|
235
|
+
end.define_model do
|
236
236
|
belongs_to :imageable, polymorphic: true, dependent: :destroy
|
237
237
|
end
|
238
238
|
|
239
239
|
create_table(:users) do
|
240
|
-
end.
|
240
|
+
end.define_model do
|
241
241
|
has_one :image, as: :imageable
|
242
242
|
end
|
243
243
|
|
244
244
|
create_table(:companies) do
|
245
|
-
end.
|
245
|
+
end.define_model do
|
246
246
|
has_one :image, as: :imageable
|
247
247
|
end
|
248
248
|
|
249
249
|
assert_problems(<<~OUTPUT)
|
250
|
-
use `dependent: :delete` or similar on
|
250
|
+
use `dependent: :delete` or similar on TransientRecord::Models::Image.imageable - associated models TransientRecord::Models::Company, TransientRecord::Models::User have no callbacks and can be deleted without loading
|
251
251
|
OUTPUT
|
252
252
|
end
|
253
253
|
|
@@ -255,12 +255,12 @@ class ActiveRecordDoctor::Detectors::IncorrectDependentOptionTest < Minitest::Te
|
|
255
255
|
create_table(:images) do |t|
|
256
256
|
t.bigint :imageable_id, null: false
|
257
257
|
t.string :imageable_type, null: true
|
258
|
-
end.
|
258
|
+
end.define_model do
|
259
259
|
belongs_to :imageable, polymorphic: true, dependent: :destroy
|
260
260
|
end
|
261
261
|
|
262
262
|
create_table(:users) do
|
263
|
-
end.
|
263
|
+
end.define_model do
|
264
264
|
has_one :image, as: :imageable
|
265
265
|
|
266
266
|
before_destroy :log
|
@@ -270,7 +270,7 @@ class ActiveRecordDoctor::Detectors::IncorrectDependentOptionTest < Minitest::Te
|
|
270
270
|
end
|
271
271
|
|
272
272
|
create_table(:companies) do
|
273
|
-
end.
|
273
|
+
end.define_model do
|
274
274
|
has_one :image, as: :imageable
|
275
275
|
end
|
276
276
|
|
@@ -281,12 +281,12 @@ class ActiveRecordDoctor::Detectors::IncorrectDependentOptionTest < Minitest::Te
|
|
281
281
|
create_table(:images) do |t|
|
282
282
|
t.bigint :imageable_id, null: false
|
283
283
|
t.string :imageable_type, null: true
|
284
|
-
end.
|
284
|
+
end.define_model do
|
285
285
|
belongs_to :imageable, polymorphic: true, dependent: :delete
|
286
286
|
end
|
287
287
|
|
288
288
|
create_table(:users) do
|
289
|
-
end.
|
289
|
+
end.define_model do
|
290
290
|
has_one :image, as: :imageable
|
291
291
|
|
292
292
|
before_destroy :log
|
@@ -296,12 +296,12 @@ class ActiveRecordDoctor::Detectors::IncorrectDependentOptionTest < Minitest::Te
|
|
296
296
|
end
|
297
297
|
|
298
298
|
create_table(:companies) do
|
299
|
-
end.
|
299
|
+
end.define_model do
|
300
300
|
has_one :image, as: :imageable
|
301
301
|
end
|
302
302
|
|
303
303
|
assert_problems(<<~OUTPUT)
|
304
|
-
use `dependent: :destroy` or similar on
|
304
|
+
use `dependent: :destroy` or similar on TransientRecord::Models::Image.imageable - associated model TransientRecord::Models::User has callbacks that are currently skipped
|
305
305
|
OUTPUT
|
306
306
|
end
|
307
307
|
|
@@ -309,39 +309,118 @@ class ActiveRecordDoctor::Detectors::IncorrectDependentOptionTest < Minitest::Te
|
|
309
309
|
create_table(:images) do |t|
|
310
310
|
t.bigint :imageable_id, null: false
|
311
311
|
t.string :imageable_type, null: true
|
312
|
-
end.
|
312
|
+
end.define_model do
|
313
313
|
belongs_to :imageable, polymorphic: true, dependent: :delete
|
314
314
|
end
|
315
315
|
|
316
316
|
create_table(:users) do
|
317
|
-
end.
|
317
|
+
end.define_model do
|
318
318
|
has_one :image, as: :imageable
|
319
319
|
end
|
320
320
|
|
321
321
|
create_table(:companies) do
|
322
|
-
end.
|
322
|
+
end.define_model do
|
323
323
|
has_one :image, as: :imageable
|
324
324
|
end
|
325
325
|
|
326
326
|
refute_problems
|
327
327
|
end
|
328
328
|
|
329
|
+
def test_works_on_has_through_associations_with_destroy
|
330
|
+
create_table(:users) do
|
331
|
+
end.define_model do
|
332
|
+
has_many :posts
|
333
|
+
has_many :comments, through: :posts, dependent: :destroy
|
334
|
+
end
|
335
|
+
|
336
|
+
create_table(:posts) do |t|
|
337
|
+
t.references :users
|
338
|
+
end.define_model do
|
339
|
+
belongs_to :user
|
340
|
+
has_many :comments
|
341
|
+
end
|
342
|
+
|
343
|
+
create_table(:comments) do |t|
|
344
|
+
t.references :posts
|
345
|
+
end.define_model do
|
346
|
+
belongs_to :post
|
347
|
+
end
|
348
|
+
|
349
|
+
assert_problems(<<~OUTPUT)
|
350
|
+
use `dependent: :delete_all` or similar on TransientRecord::Models::User.comments - associated join model TransientRecord::Models::Post has no callbacks and can be deleted in bulk
|
351
|
+
OUTPUT
|
352
|
+
end
|
353
|
+
|
354
|
+
def test_works_on_has_through_associations_with_delete_all
|
355
|
+
create_table(:users) do
|
356
|
+
end.define_model do
|
357
|
+
has_many :posts
|
358
|
+
has_many :comments, through: :posts, dependent: :delete_all
|
359
|
+
end
|
360
|
+
|
361
|
+
create_table(:posts) do |t|
|
362
|
+
t.references :users
|
363
|
+
end.define_model do
|
364
|
+
belongs_to :user
|
365
|
+
has_many :comments
|
366
|
+
|
367
|
+
before_destroy :log
|
368
|
+
|
369
|
+
def log
|
370
|
+
end
|
371
|
+
end
|
372
|
+
|
373
|
+
create_table(:comments) do |t|
|
374
|
+
t.references :posts
|
375
|
+
end.define_model do
|
376
|
+
belongs_to :post
|
377
|
+
end
|
378
|
+
|
379
|
+
assert_problems(<<~OUTPUT)
|
380
|
+
use `dependent: :destroy` or similar on TransientRecord::Models::User.comments - associated join model TransientRecord::Models::Post has callbacks that are currently skipped
|
381
|
+
OUTPUT
|
382
|
+
end
|
383
|
+
|
384
|
+
def test_has_through_associations_when_join_model_incomplete
|
385
|
+
create_table(:users) do
|
386
|
+
end.define_model do
|
387
|
+
has_many :posts
|
388
|
+
has_many :comments, through: :posts
|
389
|
+
end
|
390
|
+
|
391
|
+
create_table(:posts) do |t|
|
392
|
+
t.references :users
|
393
|
+
end.define_model do
|
394
|
+
# The join model should define has_many :comments, but intentionally skips
|
395
|
+
# it for this test case's purpose.
|
396
|
+
end
|
397
|
+
|
398
|
+
create_table(:comments) do |t|
|
399
|
+
t.references :posts
|
400
|
+
end.define_model do
|
401
|
+
end
|
402
|
+
|
403
|
+
assert_problems(<<~OUTPUT)
|
404
|
+
ensure TransientRecord::Models::User.comments is configured correctly - TransientRecord::Models::Post.comments may be undefined
|
405
|
+
OUTPUT
|
406
|
+
end
|
407
|
+
|
329
408
|
def test_config_ignore_models
|
330
409
|
create_table(:companies) do
|
331
|
-
end.
|
410
|
+
end.define_model do
|
332
411
|
has_many :users, dependent: :destroy
|
333
412
|
end
|
334
413
|
|
335
414
|
create_table(:users) do |t|
|
336
415
|
t.references :companies
|
337
|
-
end.
|
416
|
+
end.define_model do
|
338
417
|
belongs_to :company
|
339
418
|
end
|
340
419
|
|
341
420
|
config_file(<<-CONFIG)
|
342
421
|
ActiveRecordDoctor.configure do |config|
|
343
422
|
config.detector :incorrect_dependent_option,
|
344
|
-
ignore_models: ["
|
423
|
+
ignore_models: ["TransientRecord::Models::Company"]
|
345
424
|
end
|
346
425
|
CONFIG
|
347
426
|
|
@@ -350,19 +429,19 @@ class ActiveRecordDoctor::Detectors::IncorrectDependentOptionTest < Minitest::Te
|
|
350
429
|
|
351
430
|
def test_global_ignore_models
|
352
431
|
create_table(:companies) do
|
353
|
-
end.
|
432
|
+
end.define_model do
|
354
433
|
has_many :users, dependent: :destroy
|
355
434
|
end
|
356
435
|
|
357
436
|
create_table(:users) do |t|
|
358
437
|
t.references :companies
|
359
|
-
end.
|
438
|
+
end.define_model do
|
360
439
|
belongs_to :company
|
361
440
|
end
|
362
441
|
|
363
442
|
config_file(<<-CONFIG)
|
364
443
|
ActiveRecordDoctor.configure do |config|
|
365
|
-
config.global :ignore_models, ["
|
444
|
+
config.global :ignore_models, ["TransientRecord::Models::Company"]
|
366
445
|
end
|
367
446
|
CONFIG
|
368
447
|
|
@@ -371,20 +450,20 @@ class ActiveRecordDoctor::Detectors::IncorrectDependentOptionTest < Minitest::Te
|
|
371
450
|
|
372
451
|
def test_config_ignore_associations
|
373
452
|
create_table(:companies) do
|
374
|
-
end.
|
453
|
+
end.define_model do
|
375
454
|
has_many :users, dependent: :destroy
|
376
455
|
end
|
377
456
|
|
378
457
|
create_table(:users) do |t|
|
379
458
|
t.references :companies
|
380
|
-
end.
|
459
|
+
end.define_model do
|
381
460
|
belongs_to :company
|
382
461
|
end
|
383
462
|
|
384
463
|
config_file(<<-CONFIG)
|
385
464
|
ActiveRecordDoctor.configure do |config|
|
386
465
|
config.detector :incorrect_dependent_option,
|
387
|
-
ignore_associations: ["
|
466
|
+
ignore_associations: ["TransientRecord::Models::Company.users"]
|
388
467
|
end
|
389
468
|
CONFIG
|
390
469
|
|
@@ -4,8 +4,10 @@ class ActiveRecordDoctor::Detectors::IncorrectLengthValidationTest < Minitest::T
|
|
4
4
|
def test_validation_and_limit_equal_is_ok
|
5
5
|
create_table(:users) do |t|
|
6
6
|
t.string :email, limit: 64
|
7
|
-
|
7
|
+
t.string :name, limit: 32
|
8
|
+
end.define_model do
|
8
9
|
validates :email, length: { maximum: 64 }
|
10
|
+
validates :name, length: { maximum: 32 }
|
9
11
|
end
|
10
12
|
|
11
13
|
refute_problems
|
@@ -14,12 +16,12 @@ class ActiveRecordDoctor::Detectors::IncorrectLengthValidationTest < Minitest::T
|
|
14
16
|
def test_validation_and_limit_different_is_error
|
15
17
|
create_table(:users) do |t|
|
16
18
|
t.string :email, limit: 64
|
17
|
-
end.
|
19
|
+
end.define_model do
|
18
20
|
validates :email, length: { maximum: 32 }
|
19
21
|
end
|
20
22
|
|
21
23
|
assert_problems(<<~OUTPUT)
|
22
|
-
the schema limits users.email to 64 characters but the length validator on
|
24
|
+
the schema limits users.email to 64 characters but the length validator on TransientRecord::Models::User.email enforces a maximum of 32 characters - set both limits to the same value or remove both
|
23
25
|
OUTPUT
|
24
26
|
end
|
25
27
|
|
@@ -28,23 +30,23 @@ class ActiveRecordDoctor::Detectors::IncorrectLengthValidationTest < Minitest::T
|
|
28
30
|
|
29
31
|
create_table(:users) do |t|
|
30
32
|
t.string :email
|
31
|
-
end.
|
33
|
+
end.define_model do
|
32
34
|
validates :email, length: { maximum: 32 }
|
33
35
|
end
|
34
36
|
|
35
37
|
assert_problems(<<~OUTPUT)
|
36
|
-
the length validator on
|
38
|
+
the length validator on TransientRecord::Models::User.email enforces a maximum of 32 characters but there's no schema limit on users.email - remove the validator or the schema length limit
|
37
39
|
OUTPUT
|
38
40
|
end
|
39
41
|
|
40
42
|
def test_no_validation_and_limit_is_error
|
41
43
|
create_table(:users) do |t|
|
42
44
|
t.string :email, limit: 64
|
43
|
-
end.
|
45
|
+
end.define_model do
|
44
46
|
end
|
45
47
|
|
46
48
|
assert_problems(<<~OUTPUT)
|
47
|
-
the schema limits users.email to 64 characters but there's no length validator on
|
49
|
+
the schema limits users.email to 64 characters but there's no length validator on TransientRecord::Models::User.email - remove the database limit or add the validator
|
48
50
|
OUTPUT
|
49
51
|
end
|
50
52
|
|
@@ -53,7 +55,7 @@ class ActiveRecordDoctor::Detectors::IncorrectLengthValidationTest < Minitest::T
|
|
53
55
|
|
54
56
|
create_table(:users) do |t|
|
55
57
|
t.string :email
|
56
|
-
end.
|
58
|
+
end.define_model do
|
57
59
|
end
|
58
60
|
|
59
61
|
refute_problems
|
@@ -62,12 +64,12 @@ class ActiveRecordDoctor::Detectors::IncorrectLengthValidationTest < Minitest::T
|
|
62
64
|
def test_config_ignore_models
|
63
65
|
create_table(:users) do |t|
|
64
66
|
t.string :email, limit: 64
|
65
|
-
end.
|
67
|
+
end.define_model
|
66
68
|
|
67
69
|
config_file(<<-CONFIG)
|
68
70
|
ActiveRecordDoctor.configure do |config|
|
69
71
|
config.detector :incorrect_length_validation,
|
70
|
-
ignore_models: ["
|
72
|
+
ignore_models: ["TransientRecord::Models::User"]
|
71
73
|
end
|
72
74
|
CONFIG
|
73
75
|
|
@@ -77,11 +79,11 @@ class ActiveRecordDoctor::Detectors::IncorrectLengthValidationTest < Minitest::T
|
|
77
79
|
def test_global_ignore_models
|
78
80
|
create_table(:users) do |t|
|
79
81
|
t.string :email, limit: 64
|
80
|
-
end.
|
82
|
+
end.define_model
|
81
83
|
|
82
84
|
config_file(<<-CONFIG)
|
83
85
|
ActiveRecordDoctor.configure do |config|
|
84
|
-
config.global :ignore_models, ["
|
86
|
+
config.global :ignore_models, ["TransientRecord::Models::User"]
|
85
87
|
end
|
86
88
|
CONFIG
|
87
89
|
|
@@ -91,12 +93,12 @@ class ActiveRecordDoctor::Detectors::IncorrectLengthValidationTest < Minitest::T
|
|
91
93
|
def test_config_ignore_attributes
|
92
94
|
create_table(:users) do |t|
|
93
95
|
t.string :email, limit: 64
|
94
|
-
end.
|
96
|
+
end.define_model
|
95
97
|
|
96
98
|
config_file(<<-CONFIG)
|
97
99
|
ActiveRecordDoctor.configure do |config|
|
98
100
|
config.detector :incorrect_length_validation,
|
99
|
-
ignore_attributes: ["
|
101
|
+
ignore_attributes: ["TransientRecord::Models::User.email"]
|
100
102
|
end
|
101
103
|
CONFIG
|
102
104
|
|
@@ -11,7 +11,7 @@ class ActiveRecordDoctor::Detectors::MismatchedForeignKeyTypeTest < Minitest::Te
|
|
11
11
|
end
|
12
12
|
|
13
13
|
assert_problems(<<~OUTPUT)
|
14
|
-
users.company_id
|
14
|
+
users.company_id is a foreign key of type integer and references companies.id of type bigint - foreign keys should be of the same type as the referenced column
|
15
15
|
OUTPUT
|
16
16
|
end
|
17
17
|
|
@@ -24,6 +24,40 @@ class ActiveRecordDoctor::Detectors::MismatchedForeignKeyTypeTest < Minitest::Te
|
|
24
24
|
refute_problems
|
25
25
|
end
|
26
26
|
|
27
|
+
def test_mismatched_foreign_key_with_non_primary_key_type_is_reported
|
28
|
+
# MySQL does not allow foreign keys to have different type than paired primary keys
|
29
|
+
return if mysql?
|
30
|
+
|
31
|
+
create_table(:companies, id: :bigint) do |t|
|
32
|
+
t.string :code
|
33
|
+
t.index :code, unique: true
|
34
|
+
end
|
35
|
+
create_table(:users) do |t|
|
36
|
+
t.text :code
|
37
|
+
t.foreign_key :companies, table: :companies, column: :code, primary_key: :code
|
38
|
+
end
|
39
|
+
|
40
|
+
assert_problems(<<~OUTPUT)
|
41
|
+
users.code is a foreign key of type text and references companies.code of type character varying - foreign keys should be of the same type as the referenced column
|
42
|
+
OUTPUT
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_matched_foreign_key_with_non_primary_key_type_is_not_reported
|
46
|
+
# MySQL does not allow foreign keys to have different type than paired primary keys
|
47
|
+
return if mysql?
|
48
|
+
|
49
|
+
create_table(:companies, id: :bigint) do |t|
|
50
|
+
t.string :code
|
51
|
+
t.index :code, unique: true
|
52
|
+
end
|
53
|
+
create_table(:users) do |t|
|
54
|
+
t.string :code
|
55
|
+
t.foreign_key :companies, table: :companies, column: :code, primary_key: :code
|
56
|
+
end
|
57
|
+
|
58
|
+
refute_problems
|
59
|
+
end
|
60
|
+
|
27
61
|
def test_config_ignore_tables
|
28
62
|
# MySQL does not allow foreign keys to have different type than paired primary keys
|
29
63
|
return if mysql?
|