active_record_doctor 1.12.0 → 1.14.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.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +29 -2
  3. data/lib/active_record_doctor/config/loader.rb +1 -1
  4. data/lib/active_record_doctor/detectors/base.rb +11 -7
  5. data/lib/active_record_doctor/detectors/incorrect_boolean_presence_validation.rb +1 -1
  6. data/lib/active_record_doctor/detectors/incorrect_dependent_option.rb +9 -4
  7. data/lib/active_record_doctor/detectors/mismatched_foreign_key_type.rb +1 -1
  8. data/lib/active_record_doctor/detectors/missing_non_null_constraint.rb +2 -2
  9. data/lib/active_record_doctor/detectors/missing_unique_indexes.rb +16 -7
  10. data/lib/active_record_doctor/detectors/unindexed_foreign_keys.rb +1 -0
  11. data/lib/active_record_doctor/logger/hierarchical.rb +1 -1
  12. data/lib/active_record_doctor/railtie.rb +1 -1
  13. data/lib/active_record_doctor/rake/task.rb +35 -3
  14. data/lib/active_record_doctor/runner.rb +1 -1
  15. data/lib/active_record_doctor/utils.rb +2 -2
  16. data/lib/active_record_doctor/version.rb +1 -1
  17. data/lib/tasks/active_record_doctor.rake +1 -2
  18. metadata +12 -49
  19. data/test/active_record_doctor/config/loader_test.rb +0 -120
  20. data/test/active_record_doctor/config_test.rb +0 -116
  21. data/test/active_record_doctor/detectors/disable_test.rb +0 -30
  22. data/test/active_record_doctor/detectors/extraneous_indexes_test.rb +0 -277
  23. data/test/active_record_doctor/detectors/incorrect_boolean_presence_validation_test.rb +0 -79
  24. data/test/active_record_doctor/detectors/incorrect_dependent_option_test.rb +0 -511
  25. data/test/active_record_doctor/detectors/incorrect_length_validation_test.rb +0 -107
  26. data/test/active_record_doctor/detectors/mismatched_foreign_key_type_test.rb +0 -116
  27. data/test/active_record_doctor/detectors/missing_foreign_keys_test.rb +0 -70
  28. data/test/active_record_doctor/detectors/missing_non_null_constraint_test.rb +0 -273
  29. data/test/active_record_doctor/detectors/missing_presence_validation_test.rb +0 -232
  30. data/test/active_record_doctor/detectors/missing_unique_indexes_test.rb +0 -496
  31. data/test/active_record_doctor/detectors/short_primary_key_type_test.rb +0 -77
  32. data/test/active_record_doctor/detectors/undefined_table_references_test.rb +0 -55
  33. data/test/active_record_doctor/detectors/unindexed_deleted_at_test.rb +0 -177
  34. data/test/active_record_doctor/detectors/unindexed_foreign_keys_test.rb +0 -116
  35. data/test/active_record_doctor/runner_test.rb +0 -41
  36. data/test/generators/active_record_doctor/add_indexes/add_indexes_generator_test.rb +0 -141
  37. data/test/setup.rb +0 -124
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d848e296c39f7994781bd645261eb45235450be36058fbdf7368ec6358ebeba5
4
- data.tar.gz: a63cbbfe5b43fb3bf6daeaba24a6298073643d5b5c96696c27c084106fe54594
3
+ metadata.gz: 89e283c2844a768587302646735a080d8db2b3514775083cc6bc74a25e7aff18
4
+ data.tar.gz: 975a75da213c565dba3ee7918ffe64d5b75d812059b8080d6a5134a2fb27028f
5
5
  SHA512:
6
- metadata.gz: 47411eea54d4c21329459dc7490090a535c53e9f3be912268ceed2f6e2588246cb07c9b90e758559d9b0c08de319f3dc6a4735c79511bc30c2ec7b058104c08e
7
- data.tar.gz: 9596cb799a4346b3ec60562876750990b486efc7daebfda0834b028bf2db9075f04bf6b028185df6076ede3a7227cb9755a6ac9e8db609431d063261f3c0732d
6
+ metadata.gz: ca4a89d161ef3a57ee325ea6551417b9e542967d2f932f383eca6e7394ba99f02cf08ac9cd699e98f1f59018669405220fe1175f80d31f60576fc606d2d3f5f6
7
+ data.tar.gz: 70644778b22b9fe2892d12704cdfb3d81337702e8770ca94f8410694e3a8b12ad931bc511bc5188f77726849fca7c87c1ce8fec059d647ea4225adf6ab1363ef
data/README.md CHANGED
@@ -55,7 +55,7 @@ ActiveRecordDoctor::Rake::Task.new do |task|
55
55
  task.deps = []
56
56
 
57
57
  # A path to your active_record_doctor configuration file.
58
- task.config_path = ::Rails.root.join(".active_record_doctor")
58
+ task.config_path = ::Rails.root.join(".active_record_doctor.rb")
59
59
 
60
60
  # A Proc called right before running detectors that should ensure your Active
61
61
  # Record models are preloaded and a database connection is ready.
@@ -111,7 +111,7 @@ If you want to use the default configuration then you don't have to do anything.
111
111
  Just run `active_record_doctor` in your project directory.
112
112
 
113
113
  If you want to customize the tool you should create a file named
114
- `.active_record_doctor` in your project root directory with content like:
114
+ `.active_record_doctor.rb` in your project root directory with content like:
115
115
 
116
116
  ```ruby
117
117
  ActiveRecordDoctor.configure do
@@ -144,6 +144,33 @@ as extraneous.
144
144
  Configuration options for each detector are listed below. They can also be
145
145
  obtained via the help mechanism described in the previous section.
146
146
 
147
+ ### Regexp-Based Ignores
148
+
149
+ Settings like `ignore_tables`, `ignore_indexes`, and so on accept list of
150
+ identifiers to ignore. These can be either:
151
+
152
+ 1. Strings - in which case an exact match is needed.
153
+ 2. Regexps - which are matched against object names, and matching ones are
154
+ excluded from output.
155
+
156
+ For example, to ignore all tables starting with `legacy_` you can write:
157
+
158
+ ```ruby
159
+ ActiveRecordDoctor.configure do
160
+ global :ignore_tables, [
161
+ # Ignore internal Rails-related tables.
162
+ "ar_internal_metadata",
163
+ "schema_migrations",
164
+ "active_storage_blobs",
165
+ "active_storage_attachments",
166
+ "action_text_rich_texts",
167
+
168
+ # Ignore all legacy tables.
169
+ /^legacy_/
170
+ ]
171
+ end
172
+ ```
173
+
147
174
  ### Indexing Unindexed Foreign Keys
148
175
 
149
176
  Foreign keys should be indexed unless it's proven ineffective. However, Rails
@@ -27,7 +27,7 @@ module ActiveRecordDoctor # :nodoc:
27
27
  end
28
28
 
29
29
  # The same global can be used by multiple detectors so we must remove
30
- # duplicates to ensure they aren't reported mutliple times via the user
30
+ # duplicates to ensure they aren't reported multiple times via the user
31
31
  # interface (e.g. in error messages).
32
32
  recognized_globals.uniq!
33
33
 
@@ -170,7 +170,7 @@ module ActiveRecordDoctor
170
170
  case
171
171
  when model.name.start_with?("HABTM_")
172
172
  log("#{model.name} - has-belongs-to-many model; skipping")
173
- when except.include?(model.name)
173
+ when ignored?(model.name, except)
174
174
  log("#{model.name} - ignored via the configuration; skipping")
175
175
  when abstract && !model.abstract_class?
176
176
  log("#{model.name} - non-abstract model; skipping")
@@ -200,7 +200,7 @@ module ActiveRecordDoctor
200
200
  log(message) do
201
201
  indexes.each do |index|
202
202
  case
203
- when except.include?(index.name)
203
+ when ignored?(index.name, except)
204
204
  log("#{index.name} - ignored via the configuration; skipping")
205
205
  when multicolumn_only && !index.columns.is_a?(Array)
206
206
  log("#{index.name} - single-column index; skipping")
@@ -217,7 +217,7 @@ module ActiveRecordDoctor
217
217
  log("Iterating over attributes of #{model.name}") do
218
218
  connection.columns(model.table_name).each do |column|
219
219
  case
220
- when except.include?("#{model.name}.#{column.name}")
220
+ when ignored?("#{model.name}.#{column.name}", except)
221
221
  log("#{model.name}.#{column.name} - ignored via the configuration; skipping")
222
222
  when type && !Array(type).include?(column.type)
223
223
  log("#{model.name}.#{column.name} - ignored due to the #{column.type} type; skipping")
@@ -234,7 +234,7 @@ module ActiveRecordDoctor
234
234
  log("Iterating over columns of #{table_name}") do
235
235
  connection.columns(table_name).each do |column|
236
236
  case
237
- when except.include?("#{table_name}.#{column.name}")
237
+ when ignored?("#{table_name}.#{column.name}", except)
238
238
  log("#{column.name} - ignored via the configuration; skipping")
239
239
  when only.nil? || only.include?(column.name)
240
240
  log(column.name.to_s) do
@@ -266,7 +266,7 @@ module ActiveRecordDoctor
266
266
  log("Iterating over tables") do
267
267
  tables.each do |table|
268
268
  case
269
- when except.include?(table)
269
+ when ignored?(table, except)
270
270
  log("#{table} - ignored via the configuration; skipping")
271
271
  else
272
272
  log(table) do
@@ -280,7 +280,7 @@ module ActiveRecordDoctor
280
280
  def each_data_source(except: [])
281
281
  log("Iterating over data sources") do
282
282
  connection.data_sources.each do |data_source|
283
- if except.include?(data_source)
283
+ if ignored?(data_source, except)
284
284
  log("#{data_source} - ignored via the configuration; skipping")
285
285
  else
286
286
  log(data_source) do
@@ -303,7 +303,7 @@ module ActiveRecordDoctor
303
303
 
304
304
  associations.each do |association|
305
305
  case
306
- when except.include?("#{model.name}.#{association.name}")
306
+ when ignored?("#{model.name}.#{association.name}", except)
307
307
  log("#{model.name}.#{association.name} - ignored via the configuration; skipping")
308
308
  when through && !association.is_a?(ActiveRecord::Reflection::ThroughReflection)
309
309
  log("#{model.name}.#{association.name} - is not a through association; skipping")
@@ -321,6 +321,10 @@ module ActiveRecordDoctor
321
321
  end
322
322
  end
323
323
  end
324
+
325
+ def ignored?(name, patterns)
326
+ patterns.any? { |pattern| pattern === name } # rubocop:disable Style/CaseEquality
327
+ end
324
328
  end
325
329
  end
326
330
  end
@@ -5,7 +5,7 @@ require "active_record_doctor/detectors/base"
5
5
  module ActiveRecordDoctor
6
6
  module Detectors
7
7
  class IncorrectBooleanPresenceValidation < Base # :nodoc:
8
- @description = "detect persence (instead of inclusion) validators on boolean columns"
8
+ @description = "detect presence (instead of inclusion) validators on boolean columns"
9
9
  @config = {
10
10
  ignore_models: {
11
11
  description: "models whose validators should not be checked",
@@ -38,8 +38,8 @@ module ActiveRecordDoctor
38
38
  when :invalid_through
39
39
  "ensure #{model}.#{association} is configured correctly - #{associated_models[0]}.#{association} may be undefined"
40
40
  when :destroy_async
41
- "don't use `dependent: :destroy_async` on #{model}.#{association} or remove the foreign key from #{table_name}.#{column_name} - "\
42
- "associated models will be deleted in the same transaction along with #{model}"
41
+ "don't use `dependent: :destroy_async` on #{model}.#{association} or remove the foreign key from #{table_name}.#{column_name} - " \
42
+ "associated models will be deleted in the same transaction along with #{model}"
43
43
  when :suggest_destroy
44
44
  "use `dependent: :destroy` or similar on #{model}.#{association} - associated #{models_part} callbacks that are currently skipped"
45
45
  when :suggest_delete
@@ -96,8 +96,13 @@ module ActiveRecordDoctor
96
96
  when :destroy_async
97
97
  foreign_key = foreign_key(association.klass.table_name, model.table_name)
98
98
  if foreign_key
99
- problem!(model: model.name, association: association.name,
100
- table_name: foreign_key.from_table, column_name: foreign_key.column, problem: :destroy_async)
99
+ problem!(
100
+ model: model.name,
101
+ association: association.name,
102
+ table_name: foreign_key.from_table,
103
+ column_name: foreign_key.column,
104
+ problem: :destroy_async
105
+ )
101
106
  end
102
107
  when :destroy
103
108
  if destroyable_models.empty? && deletable_models.present?
@@ -29,7 +29,7 @@ module ActiveRecordDoctor
29
29
  each_foreign_key(table) do |foreign_key|
30
30
  from_column = column(table, foreign_key.column)
31
31
 
32
- next if config(:ignore_columns).include?("#{table}.#{from_column.name}")
32
+ next if ignored?("#{table}.#{from_column.name}", config(:ignore_columns))
33
33
 
34
34
  to_table = foreign_key.to_table
35
35
  to_column = column(to_table, foreign_key.primary_key)
@@ -26,14 +26,14 @@ module ActiveRecordDoctor
26
26
  table_models = models.select(&:table_exists?).group_by(&:table_name)
27
27
 
28
28
  table_models.each do |table, models|
29
- next if config(:ignore_tables).include?(table)
29
+ next if ignored?(table, config(:ignore_tables))
30
30
 
31
31
  concrete_models = models.reject do |model|
32
32
  model.abstract_class? || sti_base_model?(model)
33
33
  end
34
34
 
35
35
  connection.columns(table).each do |column|
36
- next if config(:ignore_columns).include?("#{table}.#{column.name}")
36
+ next if ignored?("#{table}.#{column.name}", config(:ignore_columns))
37
37
  next if !column.null
38
38
  next if !concrete_models.all? { |model| non_null_needed?(model, column) }
39
39
  next if not_null_check_constraint_exists?(table, column)
@@ -24,8 +24,8 @@ module ActiveRecordDoctor
24
24
  when :validations
25
25
  "add a unique index on #{table}(#{columns.join(', ')}) - validating uniqueness in #{model.name} without an index can lead to duplicates"
26
26
  when :case_insensitive_validations
27
- "add a unique expression index on #{table}(#{columns.join(', ')}) - validating case-insensitive uniqueness in #{model.name} "\
28
- "without an expression index can lead to duplicates (a regular unique index is not enough)"
27
+ "add a unique expression index on #{table}(#{columns.join(', ')}) - validating case-insensitive uniqueness in #{model.name} " \
28
+ "without an expression index can lead to duplicates (a regular unique index is not enough)"
29
29
  when :has_ones
30
30
  "add a unique index on #{table}(#{columns.join(', ')}) - using `has_one` in #{model.name} without an index can lead to duplicates"
31
31
  end
@@ -70,8 +70,12 @@ module ActiveRecordDoctor
70
70
  if case_sensitive
71
71
  problem!(model: model, table: model.table_name, columns: columns, problem: :validations)
72
72
  else
73
- problem!(model: model, table: model.table_name, columns: columns,
74
- problem: :case_insensitive_validations)
73
+ problem!(
74
+ model: model,
75
+ table: model.table_name,
76
+ columns: columns,
77
+ problem: :case_insensitive_validations
78
+ )
75
79
  end
76
80
  end
77
81
  end
@@ -81,7 +85,7 @@ module ActiveRecordDoctor
81
85
  def has_ones_without_indexes # rubocop:disable Naming/PredicateName
82
86
  each_model do |model|
83
87
  each_association(model, type: :has_one, has_scope: false, through: false) do |has_one|
84
- next if config(:ignore_models).include?(has_one.klass.name)
88
+ next if ignored?(has_one.klass.name, config(:ignore_models))
85
89
 
86
90
  columns =
87
91
  if has_one.options[:as]
@@ -89,10 +93,11 @@ module ActiveRecordDoctor
89
93
  else
90
94
  [has_one.foreign_key.to_s]
91
95
  end
92
- next if ignore_columns.include?("#{model.name}(#{columns.join(',')})")
96
+ next if ignored?("#{has_one.klass.name}(#{columns.join(',')})", ignore_columns)
93
97
 
94
98
  table_name = has_one.klass.table_name
95
99
  next if unique_index?(table_name, columns)
100
+ next if Array(connection.primary_key(table_name)) == columns
96
101
 
97
102
  problem!(model: model, table: table_name, columns: columns, problem: :has_ones)
98
103
  end
@@ -136,7 +141,11 @@ module ActiveRecordDoctor
136
141
 
137
142
  def ignore_columns
138
143
  @ignore_columns ||= config(:ignore_columns).map do |column|
139
- column.gsub(" ", "")
144
+ if column.is_a?(String)
145
+ column.gsub(" ", "")
146
+ else
147
+ column
148
+ end
140
149
  end
141
150
  end
142
151
 
@@ -30,6 +30,7 @@ module ActiveRecordDoctor
30
30
  next unless named_like_foreign_key?(column) || foreign_key?(table, column)
31
31
  next if indexed?(table, column)
32
32
  next if indexed_as_polymorphic?(table, column)
33
+ next if connection.primary_key(table) == column.name
33
34
 
34
35
  type_column_name = type_column_name(column)
35
36
 
@@ -9,7 +9,7 @@ module ActiveRecordDoctor
9
9
  end
10
10
 
11
11
  def log(message)
12
- @io.puts(" " * @nesting + message.to_s)
12
+ @io.puts((" " * @nesting) + message.to_s)
13
13
  return if !block_given?
14
14
 
15
15
  @nesting += 1
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveRecordDoctor
4
- class Railtie < Rails::Railtie
4
+ class Railtie < Rails::Railtie # :nodoc:
5
5
  rake_tasks do
6
6
  load "tasks/active_record_doctor.rake"
7
7
  end
@@ -68,9 +68,41 @@ module ActiveRecordDoctor
68
68
  end
69
69
 
70
70
  def config
71
- @config ||= begin
72
- path = config_path && File.exist?(config_path) ? config_path : nil
73
- ActiveRecordDoctor.load_config_with_defaults(path)
71
+ @config ||=
72
+ ActiveRecordDoctor.load_config_with_defaults(effective_config_path)
73
+ end
74
+
75
+ def effective_config_path
76
+ if config_path.nil?
77
+ # No explicit config_path was set, so we're trying to use defaults.
78
+ legacy_default_path = Rails.root.join(".active_record_doctor")
79
+ new_default_path = Rails.root.join(".active_record_doctor.rb")
80
+
81
+ # First, if the legacy file exists we'll use it but show a warning.
82
+ if legacy_default_path.exist?
83
+ warn(<<~WARN.squish)
84
+ DEPRECATION WARNING: active_record_doctor is using the default
85
+ configuration file located in #{legacy_default_path.basename}. However,
86
+ that default will change to #{new_default_path.basename} in the future.
87
+
88
+ In order to avoid errors, please rename the file from
89
+ #{legacy_default_path.basename} to #{new_default_path.basename}.
90
+ WARN
91
+
92
+ return legacy_default_path
93
+ end
94
+
95
+ # Second, if the legacy file does NOT exist, but the new one does then
96
+ # we'll use that.
97
+ if new_default_path.exist?
98
+ return new_default_path
99
+ end
100
+
101
+ # Otherwise, there's no configuration file in use.
102
+ nil
103
+ else
104
+ # If an explicit configuration file was set then we use it as is.
105
+ config_path
74
106
  end
75
107
  end
76
108
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveRecordDoctor # :nodoc:
4
- # An excecution environment for active_record_doctor that provides a config
4
+ # An execution environment for active_record_doctor that provides a config
5
5
  # and an output device for use by detectors.
6
6
  class Runner
7
7
  # io is injected via constructor parameters to facilitate testing.
@@ -13,8 +13,8 @@ module ActiveRecordDoctor
13
13
 
14
14
  def expression_indexes_unsupported?(connection = ActiveRecord::Base.connection)
15
15
  (ActiveRecord::VERSION::STRING < "5.0") ||
16
- # Active Record < 6 is unable to correctly parse expression indexes for MySQL.
17
- (mysql?(connection) && ActiveRecord::VERSION::STRING < "6.0")
16
+ # Active Record is unable to correctly parse expression indexes for MySQL.
17
+ (mysql?(connection) && ActiveRecord::VERSION::STRING < "7.1")
18
18
  end
19
19
  end
20
20
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveRecordDoctor
4
- VERSION = "1.12.0"
4
+ VERSION = "1.14.0"
5
5
  end
@@ -19,6 +19,5 @@ ActiveRecordDoctor::Rake::Task.new do |task|
19
19
  # This file is imported when active_record_doctor is being used as part of a
20
20
  # Rails app so it's the right place for all Rails-specific settings.
21
21
  task.deps = [:environment]
22
- task.config_path = ::Rails.root.join(".active_record_doctor")
23
- task.setup = -> { ::Rails.application.eager_load! }
22
+ task.setup = -> { Rails.application.eager_load! }
24
23
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_record_doctor
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.12.0
4
+ version: 1.14.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Greg Navis
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-07-27 00:00:00.000000000 Z
11
+ date: 2023-12-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -58,14 +58,14 @@ dependencies:
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 1.3.0
61
+ version: 1.1.4
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 1.3.0
68
+ version: 1.1.4
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: railties
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -100,28 +100,28 @@ dependencies:
100
100
  requirements:
101
101
  - - '='
102
102
  - !ruby/object:Gem::Version
103
- version: 1.0.0.rc1
103
+ version: 2.0.0.rc2
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - '='
109
109
  - !ruby/object:Gem::Version
110
- version: 1.0.0.rc1
110
+ version: 2.0.0.rc2
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: rubocop
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
115
  - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: 1.14.0
117
+ version: 1.57.1
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
- version: 1.14.0
124
+ version: 1.57.1
125
125
  description:
126
126
  email:
127
127
  - contact@gregnavis.com
@@ -164,29 +164,11 @@ files:
164
164
  - lib/generators/active_record_doctor/add_indexes/USAGE
165
165
  - lib/generators/active_record_doctor/add_indexes/add_indexes_generator.rb
166
166
  - lib/tasks/active_record_doctor.rake
167
- - test/active_record_doctor/config/loader_test.rb
168
- - test/active_record_doctor/config_test.rb
169
- - test/active_record_doctor/detectors/disable_test.rb
170
- - test/active_record_doctor/detectors/extraneous_indexes_test.rb
171
- - test/active_record_doctor/detectors/incorrect_boolean_presence_validation_test.rb
172
- - test/active_record_doctor/detectors/incorrect_dependent_option_test.rb
173
- - test/active_record_doctor/detectors/incorrect_length_validation_test.rb
174
- - test/active_record_doctor/detectors/mismatched_foreign_key_type_test.rb
175
- - test/active_record_doctor/detectors/missing_foreign_keys_test.rb
176
- - test/active_record_doctor/detectors/missing_non_null_constraint_test.rb
177
- - test/active_record_doctor/detectors/missing_presence_validation_test.rb
178
- - test/active_record_doctor/detectors/missing_unique_indexes_test.rb
179
- - test/active_record_doctor/detectors/short_primary_key_type_test.rb
180
- - test/active_record_doctor/detectors/undefined_table_references_test.rb
181
- - test/active_record_doctor/detectors/unindexed_deleted_at_test.rb
182
- - test/active_record_doctor/detectors/unindexed_foreign_keys_test.rb
183
- - test/active_record_doctor/runner_test.rb
184
- - test/generators/active_record_doctor/add_indexes/add_indexes_generator_test.rb
185
- - test/setup.rb
186
167
  homepage: https://github.com/gregnavis/active_record_doctor
187
168
  licenses:
188
169
  - MIT
189
- metadata: {}
170
+ metadata:
171
+ rubygems_mfa_required: 'true'
190
172
  post_install_message:
191
173
  rdoc_options: []
192
174
  require_paths:
@@ -202,27 +184,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
202
184
  - !ruby/object:Gem::Version
203
185
  version: '0'
204
186
  requirements: []
205
- rubygems_version: 3.4.10
187
+ rubygems_version: 3.3.26
206
188
  signing_key:
207
189
  specification_version: 4
208
190
  summary: Identify database issues before they hit production.
209
- test_files:
210
- - test/active_record_doctor/config/loader_test.rb
211
- - test/active_record_doctor/config_test.rb
212
- - test/active_record_doctor/detectors/disable_test.rb
213
- - test/active_record_doctor/detectors/extraneous_indexes_test.rb
214
- - test/active_record_doctor/detectors/incorrect_boolean_presence_validation_test.rb
215
- - test/active_record_doctor/detectors/incorrect_dependent_option_test.rb
216
- - test/active_record_doctor/detectors/incorrect_length_validation_test.rb
217
- - test/active_record_doctor/detectors/mismatched_foreign_key_type_test.rb
218
- - test/active_record_doctor/detectors/missing_foreign_keys_test.rb
219
- - test/active_record_doctor/detectors/missing_non_null_constraint_test.rb
220
- - test/active_record_doctor/detectors/missing_presence_validation_test.rb
221
- - test/active_record_doctor/detectors/missing_unique_indexes_test.rb
222
- - test/active_record_doctor/detectors/short_primary_key_type_test.rb
223
- - test/active_record_doctor/detectors/undefined_table_references_test.rb
224
- - test/active_record_doctor/detectors/unindexed_deleted_at_test.rb
225
- - test/active_record_doctor/detectors/unindexed_foreign_keys_test.rb
226
- - test/active_record_doctor/runner_test.rb
227
- - test/generators/active_record_doctor/add_indexes/add_indexes_generator_test.rb
228
- - test/setup.rb
191
+ test_files: []
@@ -1,120 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class ActiveRecordDoctor::LoaderTest < Minitest::Test
4
- def test_load_config
5
- config_path = config_file(<<-CONFIG)
6
- ActiveRecordDoctor.configure do |config|
7
- config.global :ignore_tables, ["schema_migrations"]
8
-
9
- config.detector :extraneous_indexes, ignore_tables: ["users"]
10
- end
11
- CONFIG
12
-
13
- config = ActiveRecordDoctor.load_config(config_path)
14
-
15
- assert_equal(
16
- { ignore_tables: ["schema_migrations"] },
17
- config.globals
18
- )
19
- assert_equal(
20
- { extraneous_indexes: { ignore_tables: ["users"] } },
21
- config.detectors
22
- )
23
- end
24
-
25
- def test_load_config_raises_when_configuration_file_missing
26
- exc = assert_raises(ActiveRecordDoctor::Error::ConfigurationFileMissing) do
27
- ActiveRecordDoctor.load_config("/tmp/config.rb")
28
- end
29
- assert_equal("/tmp/config.rb", exc.config_path)
30
- end
31
-
32
- def test_load_config_raises_when_configuration_file_raises
33
- config_path = config_file("1/0")
34
-
35
- assert_raises(ActiveRecordDoctor::Error::ConfigurationError) do
36
- ActiveRecordDoctor.load_config(config_path)
37
- end
38
- end
39
-
40
- def test_load_config_raises_when_configure_not_called
41
- config_path = config_file("# configure is not called")
42
-
43
- assert_raises(ActiveRecordDoctor::Error::ConfigureNotCalled) do
44
- ActiveRecordDoctor.load_config(config_path)
45
- end
46
- end
47
-
48
- def test_load_config_raises_when_configure_called_twice
49
- config_path = config_file(<<-CONFIG)
50
- ActiveRecordDoctor.configure { |config| }
51
- ActiveRecordDoctor.configure { |config| }
52
- CONFIG
53
-
54
- assert_raises(ActiveRecordDoctor::Error::ConfigureCalledTwice) do
55
- ActiveRecordDoctor.load_config(config_path)
56
- end
57
- end
58
-
59
- def test_load_config_raises_when_unrecognized_global_set
60
- config_path = config_file(<<-CONFIG)
61
- ActiveRecordDoctor.configure do |config|
62
- config.global :user, "acme"
63
- end
64
- CONFIG
65
-
66
- assert_raises(ActiveRecordDoctor::Error::UnrecognizedGlobalSetting) do
67
- ActiveRecordDoctor.load_config(config_path)
68
- end
69
- end
70
-
71
- def test_load_config_raises_when_global_set_twice
72
- config_path = config_file(<<-CONFIG)
73
- ActiveRecordDoctor.configure do |config|
74
- config.global :ignore_tables, ["schema_migrations"]
75
- config.global :ignore_tables, ["schema_migrations"]
76
- end
77
- CONFIG
78
-
79
- assert_raises(ActiveRecordDoctor::Error::DuplicateGlobalSetting) do
80
- ActiveRecordDoctor.load_config(config_path)
81
- end
82
- end
83
-
84
- def test_load_config_raises_when_configured_unrecognized_detector
85
- config_path = config_file(<<-CONFIG)
86
- ActiveRecordDoctor.configure do |config|
87
- config.detector :other_performance_issues, {}
88
- end
89
- CONFIG
90
-
91
- assert_raises(ActiveRecordDoctor::Error::UnrecognizedDetectorName) do
92
- ActiveRecordDoctor.load_config(config_path)
93
- end
94
- end
95
-
96
- def test_load_config_raises_when_detector_configured_twice
97
- config_path = config_file(<<-CONFIG)
98
- ActiveRecordDoctor.configure do |config|
99
- config.detector :extraneous_indexes, ignore_tables: ["users"]
100
- config.detector :extraneous_indexes, ignore_tables: ["users"]
101
- end
102
- CONFIG
103
-
104
- assert_raises(ActiveRecordDoctor::Error::DetectorConfiguredTwice) do
105
- ActiveRecordDoctor.load_config(config_path)
106
- end
107
- end
108
-
109
- def test_load_config_raises_when_provided_unrecognized_detector_setting
110
- config_path = config_file(<<-CONFIG)
111
- ActiveRecordDoctor.configure do |config|
112
- config.detector :extraneous_indexes, { delay: 1 }
113
- end
114
- CONFIG
115
-
116
- assert_raises(ActiveRecordDoctor::Error::UnrecognizedDetectorSettings) do
117
- ActiveRecordDoctor.load_config(config_path)
118
- end
119
- end
120
- end