1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Add :namespace option to generator route action (#37746)

* Refactor generator `route` action tests

Add `assert_routes` helper, which verifies that routes are always added
to the `Rails.application.routes.draw` block, are always indented, and
are always terminated with a newline.  This "fixes" one test that was
not testing something it claimed to, and obsoletes another test.

Also, add a test case for indentation of multi-line routing code.

* Add :namespace option to generator `route` action
This commit is contained in:
Jonathan Hefner 2019-11-22 20:16:41 -06:00 committed by y-yagi
parent 4fe767535d
commit 91adecaa9c
4 changed files with 66 additions and 113 deletions

View file

@ -254,7 +254,12 @@ module Rails
# Make an entry in Rails routing file <tt>config/routes.rb</tt>
#
# route "root 'welcome#index'"
def route(routing_code)
# route "root 'admin#index'", namespace: :admin
def route(routing_code, namespace: nil)
routing_code = Array(namespace).reverse.reduce(routing_code) do |code, ns|
"namespace :#{ns} do\n#{indent(code, 2)}\nend"
end
log :route, routing_code
sentinel = /\.routes\.draw do\s*\n/m
@ -327,12 +332,7 @@ module Rails
# Returns optimized string with indentation
def optimize_indentation(value, amount = 0) # :doc:
return "#{value}\n" unless value.is_a?(String)
if value.lines.size > 1
value.strip_heredoc.indent(amount)
else
"#{value.strip.indent(amount)}\n"
end
"#{value.strip_heredoc.indent(amount).chomp}\n"
end
# Indent the +Gemfile+ to the depth of @indentation

View file

@ -17,7 +17,8 @@ module Rails
def add_routes
return if options[:skip_routes]
return if actions.empty?
route generate_routing_code
routing_code = actions.map { |action| "get '#{file_name}/#{action}'" }.join("\n")
route routing_code, namespace: regular_class_path
end
hook_for :template_engine, :test_framework, :helper, :assets do |generator|
@ -32,45 +33,6 @@ module Rails
def remove_possible_suffix(name)
name.sub(/_?controller$/i, "")
end
# This method creates nested route entry for namespaced resources.
# For e.g. rails g controller foo/bar/baz index show
# Will generate -
# namespace :foo do
# namespace :bar do
# get 'baz/index'
# get 'baz/show'
# end
# end
def generate_routing_code
depth = 0
lines = []
# Create 'namespace' ladder
# namespace :foo do
# namespace :bar do
regular_class_path.each do |ns|
lines << indent("namespace :#{ns} do\n", depth * 2)
depth += 1
end
# Create route
# get 'baz/index'
# get 'baz/show'
actions.each do |action|
lines << indent(%{get '#{file_name}/#{action}'\n}, depth * 2)
end
# Create `end` ladder
# end
# end
until depth.zero?
depth -= 1
lines << indent("end\n", depth * 2)
end
lines.join
end
end
end
end

View file

@ -16,32 +16,7 @@ module Rails
# end
def add_resource_route
return if options[:actions].present?
depth = 0
lines = []
# Create 'namespace' ladder
# namespace :foo do
# namespace :bar do
regular_class_path.each do |ns|
lines << indent("namespace :#{ns} do\n", depth * 2)
depth += 1
end
# inserts the primary resource
# Create route
# resources 'products'
lines << indent(%{resources :#{file_name.pluralize}\n}, depth * 2)
# Create `end` ladder
# end
# end
until depth.zero?
depth -= 1
lines << indent("end\n", depth * 2)
end
route lines.join
route "resources :#{file_name.pluralize}", namespace: regular_class_path
end
end
end

View file

@ -494,57 +494,59 @@ class ActionsTest < Rails::Generators::TestCase
end
end
def test_route_should_add_data_to_the_routes_block_in_config_routes
test "route should add route" do
run_generator
route_command = "route '/login', controller: 'sessions', action: 'new'"
action :route, route_command
assert_file "config/routes.rb", /#{Regexp.escape(route_command)}/
route_commands = ["get 'foo'", "get 'bar'", "get 'baz'"]
route_commands.each do |route_command|
action :route, route_command
end
assert_routes route_commands
end
def test_route_should_be_idempotent
test "route should indent routing code" do
run_generator
route_path = File.expand_path("config/routes.rb", destination_root)
route_commands = ["get 'foo'", "get 'bar'", "get 'baz'"]
action :route, route_commands.join("\n")
assert_routes route_commands
end
# runs first time, not asserting
action :route, "root 'welcome#index'"
content_1 = File.read(route_path)
test "route should be idempotent" do
run_generator
route_command = "root 'welcome#index'"
# runs first time
action :route, route_command
assert_routes route_command
content = File.read(File.expand_path("config/routes.rb", destination_root))
# runs second time
action :route, "root 'welcome#index'"
content_2 = File.read(route_path)
assert_equal content_1, content_2
action :route, route_command
assert_file "config/routes.rb", content
end
def test_route_should_add_data_with_an_new_line
test "route with namespace option should nest route" do
run_generator
action :route, "root 'welcome#index'"
route_path = File.expand_path("config/routes.rb", destination_root)
content = File.read(route_path)
action :route, "get 'foo'\nget 'bar'", namespace: :baz
assert_routes <<~ROUTING_CODE.chomp
namespace :baz do
get 'foo'
get 'bar'
end
ROUTING_CODE
end
# Remove all of the comments and blank lines from the routes file
content.gsub!(/^ \#.*\n/, "")
content.gsub!(/^\n/, "")
File.write(route_path, content)
routes = <<-F
Rails.application.routes.draw do
root 'welcome#index'
end
F
assert_file "config/routes.rb", routes
action :route, "resources :product_lines"
routes = <<-F
Rails.application.routes.draw do
resources :product_lines
root 'welcome#index'
end
F
assert_file "config/routes.rb", routes
test "route with namespace option array should deeply nest route" do
run_generator
action :route, "get 'foo'\nget 'bar'", namespace: %w[baz qux]
assert_routes <<~ROUTING_CODE.chomp
namespace :baz do
namespace :qux do
get 'foo'
get 'bar'
end
end
ROUTING_CODE
end
def test_readme
@ -584,4 +586,18 @@ F
def action(*args, &block)
capture(:stdout) { generator.send(*args, &block) }
end
def assert_routes(*route_commands)
route_regexps = route_commands.flatten.map do |route_command|
%r{
^#{Regexp.escape("Rails.application.routes.draw do")}\n
(?:[ ]{2}.+\n|\n)*
#{Regexp.escape(route_command.indent(2))}\n
(?:[ ]{2}.+\n|\n)*
end\n
}x
end
assert_file "config/routes.rb", *route_regexps
end
end