Skip to content

Commit 7b71247

Browse files
committed
Add Rails/HttpUrl cop to enforce passing a string literal as a URL to http method calls
For the test cases; to make the actual URL obvious and to facilitate tracking endpoint path changes. Original discussion: rubocop/rails-style-guide#328 Signed-off-by: moznion <[email protected]>
1 parent 75be327 commit 7b71247

File tree

4 files changed

+62
-0
lines changed

4 files changed

+62
-0
lines changed

config/default.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,14 @@ Rails/HttpStatus:
565565
- numeric
566566
- symbolic
567567

568+
Rails/HttpUrl:
569+
Description: 'Enforces passing a string literal as a URL to http method calls.'
570+
Enabled: true
571+
VersionAdded: '2.26'
572+
Include:
573+
- 'spec/**/*'
574+
- 'test/**/*'
575+
568576
Rails/I18nLazyLookup:
569577
Description: 'Checks for places where I18n "lazy" lookup can be used.'
570578
StyleGuide: 'https://rails.rubystyle.guide/#lazy-lookup'

lib/rubocop/cop/rails/http_url.rb

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# frozen_string_literal: true
2+
3+
module RuboCop
4+
module Cop
5+
module Rails
6+
# Enforces passing a string literal as a URL to http method calls.
7+
#
8+
# @example
9+
# # bad
10+
# get photos_path
11+
# put photo_path(id)
12+
# post edit_photo_path(id)
13+
#
14+
# # good
15+
# get "/photos"
16+
# put "/photos/#{id}"
17+
# post "/photos/#{id}/edit"
18+
class HttpUrl < Base
19+
MSG = 'The first argument to `%<method>s` should be a string.'
20+
RESTRICT_ON_SEND = %i[get post put patch delete head].freeze
21+
22+
def_node_matcher :request_method?, <<-PATTERN
23+
(send nil? {#{RESTRICT_ON_SEND.map(&:inspect).join(' ')}} $!str ...)
24+
PATTERN
25+
26+
def on_send(node)
27+
request_method?(node) do |arg|
28+
add_offense(arg, message: format(MSG, method: node.method_name))
29+
end
30+
end
31+
end
32+
end
33+
end
34+
end

lib/rubocop/cop/rails_cops.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
require_relative 'rails/has_many_or_has_one_dependent'
6262
require_relative 'rails/helper_instance_variable'
6363
require_relative 'rails/http_positional_arguments'
64+
require_relative 'rails/http_url'
6465
require_relative 'rails/http_status'
6566
require_relative 'rails/i18n_lazy_lookup'
6667
require_relative 'rails/i18n_locale_assignment'
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# frozen_string_literal: true
2+
3+
RSpec.describe RuboCop::Cop::Rails::HttpUrl, :config do
4+
%i[get post put delete patch head].each do |http_method|
5+
it "registers an offense when first argument to `#{http_method}` is not a string" do
6+
padding = " #{' ' * http_method.length}"
7+
expect_offense(<<~RUBY, http_method: http_method)
8+
#{http_method} :resource
9+
#{padding}^^^^^^^^^ The first argument to `#{http_method}` should be a string.
10+
RUBY
11+
end
12+
13+
it "does not register an offense when the first argument to #{http_method} is a string" do
14+
expect_no_offenses(<<~RUBY)
15+
#{http_method} '/resource'
16+
RUBY
17+
end
18+
end
19+
end

0 commit comments

Comments
 (0)