aboutsummaryrefslogtreecommitdiffstats
path: root/railties
diff options
context:
space:
mode:
Diffstat (limited to 'railties')
-rw-r--r--railties/lib/rails/generators/named_base.rb60
-rw-r--r--railties/lib/rails/generators/rails/controller/controller_generator.rb2
-rw-r--r--railties/lib/rails/generators/rails/helper/helper_generator.rb2
-rw-r--r--railties/test/abstract_unit.rb9
-rw-r--r--railties/test/generators/generators_test_helper.rb2
-rw-r--r--railties/test/generators/namespaced_generators_test.rb125
6 files changed, 192 insertions, 8 deletions
diff --git a/railties/lib/rails/generators/named_base.rb b/railties/lib/rails/generators/named_base.rb
index 44f831e6f3..7fae505883 100644
--- a/railties/lib/rails/generators/named_base.rb
+++ b/railties/lib/rails/generators/named_base.rb
@@ -5,6 +5,8 @@ module Rails
module Generators
class NamedBase < Base
argument :name, :type => :string
+ class_option :skip_namespace, :type => :boolean, :default => false,
+ :desc => "Skip namespace (affects only isolated applications)"
def initialize(args, *options) #:nodoc:
# Unfreeze name in case it's given as a frozen string
@@ -16,15 +18,69 @@ module Rails
protected
- attr_reader :class_path, :file_name
+ def indent(content, multiplier = 2)
+ spaces = " " * multiplier
+ content.each_line.map {|line| "#{spaces}#{line}" }.join("\n")
+ end
+
+ def wrap_with_namespace(content)
+ "module #{namespace.name}\n#{content}\nend\n"
+ end
+
+ def namespaced_template(source, *args, &block)
+ inside_namespace do
+ template(source, *args) do |content|
+ content = block.call(content) if block_given?
+ if namespace
+ content = indent(content)
+ content = wrap_with_namespace(content)
+ end
+ content
+ end
+ end
+ end
+
+ def inside_namespace
+ @inside_namespace = true if namespaced?
+ result = yield
+ @inside_namespace = false
+ result
+ end
+
+ def namespace
+ @namespace ||= if defined?(Rails) && Rails.application
+ Rails.application.parents.detect { |n| n.respond_to?(:_railtie) }
+ end
+ end
+
+ def namespaced?
+ !options[:skip_namespace] && !!namespace
+ end
+
+ def inside_namespace?
+ @inside_namespace
+ end
+
+ attr_reader :file_name
alias :singular_name :file_name
def file_path
@file_path ||= (class_path + [file_name]).join('/')
end
+ def class_path
+ inside_namespace? || !namespaced? ? @class_path : namespaced_class_path
+ end
+
+ def namespaced_class_path
+ @namespaced_class_path ||= begin
+ namespace_path = namespace.name.split("::").map {|m| m.underscore }
+ namespace_path + @class_path
+ end
+ end
+
def class_name
- @class_name ||= (class_path + [file_name]).map!{ |m| m.camelize }.join('::')
+ (class_path + [file_name]).map!{ |m| m.camelize }.join('::')
end
def human_name
diff --git a/railties/lib/rails/generators/rails/controller/controller_generator.rb b/railties/lib/rails/generators/rails/controller/controller_generator.rb
index 9788c0d0bc..981ce88474 100644
--- a/railties/lib/rails/generators/rails/controller/controller_generator.rb
+++ b/railties/lib/rails/generators/rails/controller/controller_generator.rb
@@ -5,7 +5,7 @@ module Rails
check_class_collision :suffix => "Controller"
def create_controller_files
- template 'controller.rb', File.join('app/controllers', class_path, "#{file_name}_controller.rb")
+ namespaced_template 'controller.rb', File.join('app/controllers', class_path, "#{file_name}_controller.rb")
end
def add_routes
diff --git a/railties/lib/rails/generators/rails/helper/helper_generator.rb b/railties/lib/rails/generators/rails/helper/helper_generator.rb
index ad66388591..50d3b46b56 100644
--- a/railties/lib/rails/generators/rails/helper/helper_generator.rb
+++ b/railties/lib/rails/generators/rails/helper/helper_generator.rb
@@ -4,7 +4,7 @@ module Rails
check_class_collision :suffix => "Helper"
def create_helper_files
- template 'helper.rb', File.join('app/helpers', class_path, "#{file_name}_helper.rb")
+ namespaced_template 'helper.rb', File.join('app/helpers', class_path, "#{file_name}_helper.rb")
end
hook_for :test_framework
diff --git a/railties/test/abstract_unit.rb b/railties/test/abstract_unit.rb
index a05bae5dcc..45cf565e86 100644
--- a/railties/test/abstract_unit.rb
+++ b/railties/test/abstract_unit.rb
@@ -11,7 +11,10 @@ require 'action_controller'
require 'rails/all'
# TODO: Remove these hacks
-class TestApp < Rails::Application
- config.root = File.dirname(__FILE__)
+module TestApp
+ class Application < Rails::Application
+ config.root = File.dirname(__FILE__)
+ end
end
-Rails.application = TestApp
+
+Rails.application = TestApp::Application
diff --git a/railties/test/generators/generators_test_helper.rb b/railties/test/generators/generators_test_helper.rb
index 4a5a9b2932..46a6da3568 100644
--- a/railties/test/generators/generators_test_helper.rb
+++ b/railties/test/generators/generators_test_helper.rb
@@ -36,4 +36,4 @@ module GeneratorsTestHelper
FileUtils.mkdir_p(destination)
FileUtils.cp File.expand_path(routes), destination
end
-end \ No newline at end of file
+end
diff --git a/railties/test/generators/namespaced_generators_test.rb b/railties/test/generators/namespaced_generators_test.rb
new file mode 100644
index 0000000000..2be5bea117
--- /dev/null
+++ b/railties/test/generators/namespaced_generators_test.rb
@@ -0,0 +1,125 @@
+require 'generators/generators_test_helper'
+require 'rails/generators/rails/controller/controller_generator'
+require 'rails/generators/rails/model/model_generator'
+
+class NamespacedGeneratorTestCase < Rails::Generators::TestCase
+ def setup
+ TestApp::Application.namespace(TestApp)
+ end
+
+ def teardown
+ if TestApp.respond_to?(:_railtie)
+ TestApp.singleton_class.send(:undef_method, :_railtie)
+ TestApp.singleton_class.send(:undef_method, :table_name_prefix)
+ TestApp::Application.namespaced = false
+ end
+ end
+end
+
+class NamespacedControllerGeneratorTest < NamespacedGeneratorTestCase
+ include GeneratorsTestHelper
+ arguments %w(Account foo bar)
+ tests Rails::Generators::ControllerGenerator
+
+ setup :copy_routes
+
+ def test_namespaced_controller_skeleton_is_created
+ run_generator
+ assert_file "app/controllers/test_app/account_controller.rb", /module TestApp/, / class AccountController < ApplicationController/
+ assert_file "test/functional/test_app/account_controller_test.rb", /TestApp::AccountController/
+ end
+
+ def test_skipping_namespace
+ run_generator ["Account", "--skip-namespace"]
+ assert_file "app/controllers/account_controller.rb", /class AccountController < ApplicationController/
+ assert_file "app/helpers/account_helper.rb", /module AccountHelper/
+ end
+
+ def test_namespaced_controller_with_additional_namespace
+ run_generator ["admin/account"]
+ assert_file "app/controllers/test_app/admin/account_controller.rb", /module TestApp/, / class Admin::AccountController < ApplicationController/
+ end
+
+ def test_helpr_is_also_namespaced
+ run_generator
+ assert_file "app/helpers/test_app/account_helper.rb", /module TestApp/, / module AccountHelper/
+ assert_file "test/unit/helpers/test_app/account_helper_test.rb", /TestApp::AccountHelper/
+ end
+
+ def test_invokes_default_test_framework
+ run_generator
+ assert_file "test/functional/test_app/account_controller_test.rb"
+ end
+
+ def test_invokes_default_template_engine
+ run_generator
+ assert_file "app/views/test_app/account/foo.html.erb", %r(app/views/test_app/account/foo\.html\.erb)
+ assert_file "app/views/test_app/account/bar.html.erb", %r(app/views/test_app/account/bar\.html\.erb)
+ end
+
+ def test_routes_should_not_be_namespaced
+ run_generator
+ assert_file "config/routes.rb", /get "account\/foo"/, /get "account\/bar"/
+ end
+#
+ def test_invokes_default_template_engine_even_with_no_action
+ run_generator ["account"]
+ assert_file "app/views/test_app/account"
+ end
+end
+
+class NamespacedModelGeneratorTest < NamespacedGeneratorTestCase
+ include GeneratorsTestHelper
+ arguments %w(Account name:string age:integer)
+ tests Rails::Generators::ModelGenerator
+
+ def test_adds_namespace_to_model
+ run_generator
+ assert_file "app/models/test_app/account.rb", /module TestApp/, / class Account < ActiveRecord::Base/
+ end
+
+ def test_model_with_namespace
+ run_generator ["admin/account"]
+ assert_file "app/models/test_app/admin.rb", /module TestApp/, /module Admin/
+ assert_file "app/models/test_app/admin.rb", /def self\.table_name_prefix/
+ assert_file "app/models/test_app/admin.rb", /'admin_'/
+ assert_file "app/models/test_app/admin/account.rb", /module TestApp/, /class Admin::Account < ActiveRecord::Base/
+ end
+
+ def test_migration
+ run_generator
+ assert_migration "db/migrate/create_test_app_accounts.rb", /create_table :test_app_accounts/, /class CreateTestAppAccounts < ActiveRecord::Migration/
+ end
+
+ def test_migration_with_namespace
+ run_generator ["Gallery::Image"]
+ assert_migration "db/migrate/create_test_app_gallery_images", /class CreateTestAppGalleryImages < ActiveRecord::Migration/
+ assert_no_migration "db/migrate/create_test_app_images"
+ end
+
+ def test_migration_with_nested_namespace
+ run_generator ["Admin::Gallery::Image"]
+ assert_no_migration "db/migrate/create_images"
+ assert_no_migration "db/migrate/create_gallery_images"
+ assert_migration "db/migrate/create_test_app_admin_gallery_images", /class CreateTestAppAdminGalleryImages < ActiveRecord::Migration/
+ assert_migration "db/migrate/create_test_app_admin_gallery_images", /create_table :test_app_admin_gallery_images/
+ end
+
+ def test_migration_with_nested_namespace_without_pluralization
+ ActiveRecord::Base.pluralize_table_names = false
+ run_generator ["Admin::Gallery::Image"]
+ assert_no_migration "db/migrate/create_images"
+ assert_no_migration "db/migrate/create_gallery_images"
+ assert_no_migration "db/migrate/create_test_app_admin_gallery_images"
+ assert_migration "db/migrate/create_test_app_admin_gallery_image", /class CreateTestAppAdminGalleryImage < ActiveRecord::Migration/
+ assert_migration "db/migrate/create_test_app_admin_gallery_image", /create_table :test_app_admin_gallery_image/
+ ensure
+ ActiveRecord::Base.pluralize_table_names = true
+ end
+
+ def test_invokes_default_test_framework
+ run_generator
+ assert_file "test/unit/test_app/account_test.rb", /class TestApp::AccountTest < ActiveSupport::TestCase/
+ assert_file "test/fixtures/test_app/accounts.yml", /name: MyString/, /age: 1/
+ end
+end