-
-
Notifications
You must be signed in to change notification settings - Fork 268
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
319 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
* [#547](https://github.com/rubocop/rubocop/pull/547): action order cop. ([@mollerhoj][]) |
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 enforces consistent ordering of the standard Rails RESTful | ||
# controller actions. | ||
# | ||
# The cop is configurable and can enforce any ordering of the standard | ||
# actions. All other methods are ignored. | ||
# | ||
# [source,yaml] | ||
# ---- | ||
# Rails/ActionOrder: | ||
# ExpectedOrder: | ||
# - index | ||
# - show | ||
# - new | ||
# - edit | ||
# - create | ||
# - update | ||
# - destroy | ||
# ---- | ||
# | ||
# @example | ||
# # bad | ||
# def index; end | ||
# def destroy; end | ||
# def show; end | ||
# | ||
# # good | ||
# def index; end | ||
# def show; end | ||
# def destroy; end | ||
class ActionOrder < Base | ||
extend AutoCorrector | ||
include VisibilityHelp | ||
include DefNode | ||
|
||
MSG = 'Action `%<current>s` should appear before `%<previous>s`.' | ||
|
||
def_node_search :action_declarations, '(def {%1} ...)' | ||
|
||
def on_class(node) | ||
action_declarations(node, actions).each_cons(2) do |previous, current| | ||
next if node_visibility(current) != :public || non_public?(current) | ||
next if find_index(current) >= find_index(previous) | ||
|
||
register_offense(previous, current) | ||
end | ||
end | ||
|
||
private | ||
|
||
def expected_order | ||
cop_config['ExpectedOrder'].map(&:to_sym) | ||
end | ||
|
||
def actions | ||
@actions ||= Set.new(expected_order) | ||
end | ||
|
||
def find_index(node) | ||
expected_order.find_index(node.method_name) | ||
end | ||
|
||
def register_offense(previous, current) | ||
message = format( | ||
MSG, | ||
expected_order: expected_order.join(', '), | ||
previous: previous.method_name, | ||
current: current.method_name | ||
) | ||
add_offense(current, message: message) do |corrector| | ||
corrector.replace(current, previous.source) | ||
corrector.replace(previous, current.source) | ||
end | ||
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,159 @@ | ||
# frozen_string_literal: true | ||
|
||
RSpec.describe RuboCop::Cop::Rails::ActionOrder, :config do | ||
it 'detects unconventional order of actions' do | ||
expect_offense(<<~RUBY) | ||
class UserController < ApplicationController | ||
def show; end | ||
def index; end | ||
^^^^^^^^^^^^^^ Action `index` should appear before `show`. | ||
end | ||
RUBY | ||
|
||
expect_correction(<<~RUBY) | ||
class UserController < ApplicationController | ||
def index; end | ||
def show; end | ||
end | ||
RUBY | ||
end | ||
|
||
it 'supports methods with content' do | ||
expect_offense(<<~RUBY) | ||
class UserController < ApplicationController | ||
def show | ||
@user = User.find(params[:id]) | ||
end | ||
def index; end | ||
^^^^^^^^^^^^^^ Action `index` should appear before `show`. | ||
end | ||
RUBY | ||
|
||
expect_correction(<<~RUBY) | ||
class UserController < ApplicationController | ||
def index; end | ||
def show | ||
@user = User.find(params[:id]) | ||
end | ||
end | ||
RUBY | ||
end | ||
|
||
it 'respects order of duplicate methods' do | ||
expect_offense(<<~RUBY) | ||
class UserController < ApplicationController | ||
def edit; end | ||
def index # first | ||
^^^^^^^^^^^^^^^^^ Action `index` should appear before `edit`. | ||
end | ||
def show; end | ||
def index # second | ||
^^^^^^^^^^^^^^^^^^ Action `index` should appear before `show`. | ||
end | ||
end | ||
RUBY | ||
|
||
expect_correction(<<~RUBY) | ||
class UserController < ApplicationController | ||
def index # first | ||
end | ||
def index # second | ||
end | ||
def show; end | ||
def edit; end | ||
end | ||
RUBY | ||
end | ||
|
||
it 'ignores non standard controller actions' do | ||
expect_no_offenses(<<~RUBY) | ||
class UserController < ApplicationController | ||
def index; end | ||
def commit; end | ||
def show; end | ||
end | ||
RUBY | ||
end | ||
|
||
it 'does not touch protected actions' do | ||
expect_no_offenses(<<~RUBY) | ||
class UserController < ApplicationController | ||
def show; end | ||
protected | ||
def index; end | ||
end | ||
RUBY | ||
end | ||
|
||
it 'does not touch inline protected actions' do | ||
expect_no_offenses(<<~RUBY) | ||
class UserController < ApplicationController | ||
def show; end | ||
protected def index; end | ||
end | ||
RUBY | ||
end | ||
|
||
it 'does not touch private actions' do | ||
expect_no_offenses(<<~RUBY) | ||
class UserController < ApplicationController | ||
def show; end | ||
private | ||
def index; end | ||
end | ||
RUBY | ||
end | ||
|
||
it 'does not touch inline private actions' do | ||
expect_no_offenses(<<~RUBY) | ||
class UserController < ApplicationController | ||
def show; end | ||
private def index; end | ||
end | ||
RUBY | ||
end | ||
|
||
context 'with custom ordering' do | ||
it 'enforces custom order' do | ||
cop_config['ExpectedOrder'] = %w[show index new edit create update destroy] | ||
|
||
expect_offense(<<~RUBY) | ||
class UserController < ApplicationController | ||
def index; end | ||
def show; end | ||
^^^^^^^^^^^^^ Action `show` should appear before `index`. | ||
end | ||
RUBY | ||
|
||
expect_correction(<<~RUBY) | ||
class UserController < ApplicationController | ||
def show; end | ||
def index; end | ||
end | ||
RUBY | ||
end | ||
|
||
it 'does not require all actions to be specified' do | ||
cop_config['ExpectedOrder'] = %w[show index] | ||
|
||
expect_offense(<<~RUBY) | ||
class UserController < ApplicationController | ||
def index; end | ||
def edit; end | ||
def show; end | ||
^^^^^^^^^^^^^ Action `show` should appear before `index`. | ||
end | ||
RUBY | ||
|
||
expect_correction(<<~RUBY) | ||
class UserController < ApplicationController | ||
def show; end | ||
def edit; end | ||
def index; end | ||
end | ||
RUBY | ||
end | ||
end | ||
end |