From e83634081a9222446df608106c8df5a6831d64db Mon Sep 17 00:00:00 2001 From: Piotr Sarnacki Date: Thu, 23 Sep 2010 19:13:07 +0200 Subject: Generators are not aware of namespace of isolated engines and applications MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: José Valim --- railties/lib/rails/generators/named_base.rb | 60 +++++++++- .../rails/controller/controller_generator.rb | 2 +- .../generators/rails/helper/helper_generator.rb | 2 +- railties/test/abstract_unit.rb | 9 +- railties/test/generators/generators_test_helper.rb | 2 +- .../test/generators/namespaced_generators_test.rb | 125 +++++++++++++++++++++ 6 files changed, 192 insertions(+), 8 deletions(-) create mode 100644 railties/test/generators/namespaced_generators_test.rb (limited to 'railties') 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 -- cgit v1.2.3