-
-
Notifications
You must be signed in to change notification settings - Fork 266
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add new Rails/ImplementedMigration cop
- Loading branch information
Showing
7 changed files
with
272 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
# frozen_string_literal: true | ||
|
||
module RuboCop | ||
module Cop | ||
module Rails | ||
# This cop checks whether the migration implements | ||
# either a `change` method or both an `up` and a `down` | ||
# method. | ||
# | ||
# @example | ||
# # bad | ||
# class SomeMigration < ActiveRecord::Migration[6.0] | ||
# def chance # <----- typo | ||
# # migration | ||
# end | ||
# end | ||
# | ||
# class SomeMigration < ActiveRecord::Migration[6.0] | ||
# def up | ||
# # up migration | ||
# end | ||
# | ||
# # <----- missing down method | ||
# end | ||
# | ||
# class SomeMigration < ActiveRecord::Migration[6.0] | ||
# # <----- missing up method | ||
# | ||
# def down | ||
# # down migration | ||
# end | ||
# end | ||
# | ||
# # good | ||
# class SomeMigration < ActiveRecord::Migration[6.0] | ||
# def change | ||
# # migration | ||
# end | ||
# end | ||
# | ||
# # good | ||
# class SomeMigration < ActiveRecord::Migration[6.0] | ||
# def up | ||
# # up migration | ||
# end | ||
# | ||
# def down | ||
# # down migration | ||
# end | ||
# end | ||
class ImplementedMigration < Base | ||
MSG = 'Migrations must contain either a change method, or ' \ | ||
'both an up and a down method.' | ||
|
||
def_node_matcher :migration_class?, <<~PATTERN | ||
(class | ||
(const nil? _) | ||
(send | ||
(const (const nil? :ActiveRecord) :Migration) | ||
:[] | ||
(float _)) | ||
_) | ||
PATTERN | ||
|
||
def_node_matcher :change_method?, <<~PATTERN | ||
[ #migration_class? `(def :change (args) _) ] | ||
PATTERN | ||
|
||
def_node_matcher :up_and_down_methods?, <<~PATTERN | ||
[ #migration_class? `(def :up (args) _) `(def :down (args) _) ] | ||
PATTERN | ||
|
||
def on_class(node) | ||
return if change_method?(node) | ||
return if up_and_down_methods?(node) | ||
|
||
add_offense(node) | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
# frozen_string_literal: true | ||
|
||
RSpec.describe RuboCop::Cop::Rails::ImplementedMigration, :config do | ||
it 'does not register an offense with a change method' do | ||
expect_no_offenses(<<~RUBY) | ||
class SomeMigration < ActiveRecord::Migration[6.0] | ||
def change | ||
add_column :users, :email, :text, null: false | ||
end | ||
end | ||
RUBY | ||
end | ||
|
||
it 'registers an offense with only an up method' do | ||
expect_offense(<<~RUBY) | ||
class SomeMigration < ActiveRecord::Migration[6.0] | ||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Migrations must contain either a change method, or both an up and a down method. | ||
def up | ||
add_column :users, :email, :text, null: false | ||
end | ||
end | ||
RUBY | ||
end | ||
|
||
it 'registers an offense with only a down method' do | ||
expect_offense(<<~RUBY) | ||
class SomeMigration < ActiveRecord::Migration[6.0] | ||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Migrations must contain either a change method, or both an up and a down method. | ||
def down | ||
remove_column :users, :email | ||
end | ||
end | ||
RUBY | ||
end | ||
|
||
it 'does not register an offense with an up and a down method' do | ||
expect_no_offenses(<<~RUBY) | ||
class SomeMigration < ActiveRecord::Migration[6.0] | ||
def up | ||
add_column :users, :email, :text, null: false | ||
end | ||
def down | ||
remove_column :users, :email | ||
end | ||
end | ||
RUBY | ||
end | ||
|
||
it 'registers an offense with a typo\'d change method' do | ||
expect_offense(<<~RUBY) | ||
class SomeMigration < ActiveRecord::Migration[6.0] | ||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Migrations must contain either a change method, or both an up and a down method. | ||
def chance | ||
add_column :users, :email, :text, null: false | ||
end | ||
end | ||
RUBY | ||
end | ||
|
||
it 'does not register an offense with helper methods' do | ||
expect_no_offenses(<<~RUBY) | ||
class SomeMigration < ActiveRecord::Migration[6.0] | ||
def change | ||
add_users_column :email, :text, null: false | ||
end | ||
private | ||
def add_users_column(column_name, null: false) | ||
add_column :users, column_name, type, null: null | ||
end | ||
end | ||
RUBY | ||
end | ||
|
||
it 'registers offenses correctly with any migration class' do | ||
expect_offense(<<~RUBY) | ||
class SomeMigration < ActiveRecord::Migration[5.1] | ||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Migrations must contain either a change method, or both an up and a down method. | ||
def chance | ||
add_column :users, :email, :text, null: false | ||
end | ||
end | ||
RUBY | ||
|
||
expect_offense(<<~RUBY) | ||
class SomeMigration < ActiveRecord::Migration[7.1] | ||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Migrations must contain either a change method, or both an up and a down method. | ||
def chance | ||
add_column :users, :email, :text, null: false | ||
end | ||
end | ||
RUBY | ||
end | ||
|
||
it 'does not register offenses correctly with any migration class' do | ||
expect_no_offenses(<<~RUBY) | ||
class SomeMigration < ActiveRecord::Migration[5.2] | ||
def change | ||
add_column :users, :email, :text, null: false | ||
end | ||
end | ||
RUBY | ||
|
||
expect_no_offenses(<<~RUBY) | ||
class SomeMigration < ActiveRecord::Migration[7.1] | ||
def change | ||
add_column :users, :email, :text, null: false | ||
end | ||
end | ||
RUBY | ||
end | ||
end |