aboutsummaryrefslogtreecommitdiffstats
path: root/railties
diff options
context:
space:
mode:
authorJosé Valim <jose.valim@gmail.com>2010-11-11 19:39:21 +0100
committerJosé Valim <jose.valim@gmail.com>2010-11-11 19:39:21 +0100
commitf912a359aaaffa04fedb2ffd5730284d629b481a (patch)
treeee0163b662d378ba9dfe327cbbe17f3cde07790c /railties
parentde2933e1a062f0752512eb0ec60f7217f4890f8c (diff)
parentcc135e3b6df1785852de2470b4b93559c88c891e (diff)
downloadrails-f912a359aaaffa04fedb2ffd5730284d629b481a.tar.gz
rails-f912a359aaaffa04fedb2ffd5730284d629b481a.tar.bz2
rails-f912a359aaaffa04fedb2ffd5730284d629b481a.zip
Merge remote branch 'drogus/plugin_new'
Conflicts: railties/test/generators/app_generator_test.rb
Diffstat (limited to 'railties')
-rw-r--r--railties/lib/rails/cli.rb7
-rw-r--r--railties/lib/rails/commands/plugin_new.rb16
-rw-r--r--railties/lib/rails/configuration.rb8
-rw-r--r--railties/lib/rails/engine/configuration.rb1
-rw-r--r--railties/lib/rails/generators/app_base.rb176
-rw-r--r--railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb2
-rw-r--r--railties/lib/rails/generators/erb/scaffold/templates/edit.html.erb2
-rw-r--r--railties/lib/rails/generators/erb/scaffold/templates/index.html.erb2
-rw-r--r--railties/lib/rails/generators/erb/scaffold/templates/new.html.erb2
-rw-r--r--railties/lib/rails/generators/erb/scaffold/templates/show.html.erb2
-rw-r--r--railties/lib/rails/generators/named_base.rb8
-rw-r--r--railties/lib/rails/generators/rails/app/app_generator.rb137
-rw-r--r--railties/lib/rails/generators/rails/app/templates/Gemfile21
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/USAGE10
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb246
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/%name%.gemspec9
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/Gemfile11
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/MIT-LICENSE20
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/README.rdoc3
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/Rakefile18
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/app/controllers/%name%/application_controller.rb.tt4
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/app/helpers/%name%/application_helper.rb.tt4
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/config/routes.rb3
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/gitignore6
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/lib/%name%.rb6
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/lib/%name%/engine.rb7
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/lib/tasks/%name%_tasks.rake4
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/rails/application.rb16
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/rails/boot.rb10
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/rails/routes.rb4
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/script/rails.tt5
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/test/%name%_test.rb7
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/test/integration/navigation_test.rb11
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/test/test_helper.rb17
-rw-r--r--railties/lib/rails/generators/rails/resource/resource_generator.rb4
-rw-r--r--railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb2
-rw-r--r--railties/lib/rails/generators/resource_helpers.rb4
-rw-r--r--railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb2
-rw-r--r--railties/test/fixtures/lib/app_builders/empty_builder.rb (renamed from railties/test/fixtures/lib/empty_builder.rb)0
-rw-r--r--railties/test/fixtures/lib/app_builders/simple_builder.rb7
-rw-r--r--railties/test/fixtures/lib/app_builders/tweak_builder.rb7
-rw-r--r--railties/test/fixtures/lib/create_test_dummy_template.rb1
-rw-r--r--railties/test/fixtures/lib/plugin_builders/empty_builder.rb2
-rw-r--r--railties/test/fixtures/lib/plugin_builders/simple_builder.rb7
-rw-r--r--railties/test/fixtures/lib/plugin_builders/spec_builder.rb19
-rw-r--r--railties/test/fixtures/lib/plugin_builders/tweak_builder.rb7
-rw-r--r--railties/test/fixtures/lib/simple_builder.rb7
-rw-r--r--railties/test/fixtures/lib/tweak_builder.rb7
-rw-r--r--railties/test/generators/app_generator_test.rb165
-rw-r--r--railties/test/generators/namespaced_generators_test.rb153
-rw-r--r--railties/test/generators/plugin_new_generator_test.rb192
-rw-r--r--railties/test/generators/shared_generator_tests.rb187
-rw-r--r--railties/test/railties/engine_test.rb20
53 files changed, 1279 insertions, 319 deletions
diff --git a/railties/lib/rails/cli.rb b/railties/lib/rails/cli.rb
index a4b86974c2..2b32f7edf1 100644
--- a/railties/lib/rails/cli.rb
+++ b/railties/lib/rails/cli.rb
@@ -8,4 +8,9 @@ Rails::ScriptRailsLoader.exec_script_rails!
require 'rails/ruby_version_check'
Signal.trap("INT") { puts; exit }
-require 'rails/commands/application'
+if ARGV.first == 'plugin'
+ ARGV.shift
+ require 'rails/commands/plugin_new'
+else
+ require 'rails/commands/application'
+end
diff --git a/railties/lib/rails/commands/plugin_new.rb b/railties/lib/rails/commands/plugin_new.rb
new file mode 100644
index 0000000000..00a7e30902
--- /dev/null
+++ b/railties/lib/rails/commands/plugin_new.rb
@@ -0,0 +1,16 @@
+require 'rails/version'
+if %w(--version -v).include? ARGV.first
+ puts "Rails #{Rails::VERSION::STRING}"
+ exit(0)
+end
+
+if ARGV.first != "new"
+ ARGV[0] = "--help"
+else
+ ARGV.shift
+end
+
+require 'rails/generators'
+require 'rails/generators/rails/plugin_new/plugin_new_generator'
+
+Rails::Generators::PluginNewGenerator.start
diff --git a/railties/lib/rails/configuration.rb b/railties/lib/rails/configuration.rb
index 8369795e71..66fab0a760 100644
--- a/railties/lib/rails/configuration.rb
+++ b/railties/lib/rails/configuration.rb
@@ -1,5 +1,6 @@
require 'active_support/deprecation'
require 'active_support/ordered_options'
+require 'active_support/core_ext/hash/deep_dup'
require 'rails/paths'
require 'rails/rack'
@@ -51,6 +52,13 @@ module Rails
@colorize_logging = true
end
+ def initialize_copy(source)
+ @aliases = @aliases.deep_dup
+ @options = @options.deep_dup
+ @fallbacks = @fallbacks.deep_dup
+ @templates = @templates.dup
+ end
+
def method_missing(method, *args)
method = method.to_s.sub(/=$/, '').to_sym
diff --git a/railties/lib/rails/engine/configuration.rb b/railties/lib/rails/engine/configuration.rb
index 7a07dcad7d..4f458b0aee 100644
--- a/railties/lib/rails/engine/configuration.rb
+++ b/railties/lib/rails/engine/configuration.rb
@@ -10,6 +10,7 @@ module Rails
def initialize(root=nil)
super()
@root = root
+ @generators = app_generators.dup
end
# Returns the middleware stack for the engine.
diff --git a/railties/lib/rails/generators/app_base.rb b/railties/lib/rails/generators/app_base.rb
new file mode 100644
index 0000000000..f5c626553c
--- /dev/null
+++ b/railties/lib/rails/generators/app_base.rb
@@ -0,0 +1,176 @@
+require 'digest/md5'
+require 'active_support/secure_random'
+require 'rails/version' unless defined?(Rails::VERSION)
+require 'rbconfig'
+require 'open-uri'
+require 'uri'
+
+module Rails
+ module Generators
+ class AppBase < Base
+ DATABASES = %w( mysql oracle postgresql sqlite3 frontbase ibm_db )
+ JAVASCRIPTS = %w( prototype jquery )
+
+ attr_accessor :rails_template
+ add_shebang_option!
+
+ argument :app_path, :type => :string
+
+ def self.add_shared_options_for(name)
+ class_option :builder, :type => :string, :aliases => "-b",
+ :desc => "Path to a #{name} builder (can be a filesystem path or URL)"
+
+ class_option :template, :type => :string, :aliases => "-m",
+ :desc => "Path to an #{name} template (can be a filesystem path or URL)"
+
+ class_option :skip_gemfile, :type => :boolean, :default => false,
+ :desc => "Don't create a Gemfile"
+
+ class_option :skip_git, :type => :boolean, :aliases => "-G", :default => false,
+ :desc => "Skip Git ignores and keeps"
+
+ class_option :skip_active_record, :type => :boolean, :aliases => "-O", :default => false,
+ :desc => "Skip Active Record files"
+
+ class_option :database, :type => :string, :aliases => "-d", :default => "sqlite3",
+ :desc => "Preconfigure for selected database (options: #{DATABASES.join('/')})"
+
+ class_option :javascript, :type => :string, :aliases => "-j", :default => "prototype",
+ :desc => "Preconfigure for selected javascript library (options: #{JAVASCRIPTS.join('/')})"
+
+ class_option :skip_javascript, :type => :boolean, :aliases => "-J", :default => false,
+ :desc => "Skip javascript files"
+
+ class_option :dev, :type => :boolean, :default => false,
+ :desc => "Setup the #{name} with Gemfile pointing to your Rails checkout"
+
+ class_option :edge, :type => :boolean, :default => false,
+ :desc => "Setup the #{name} with Gemfile pointing to Rails repository"
+
+ class_option :skip_test_unit, :type => :boolean, :aliases => "-T", :default => false,
+ :desc => "Skip Test::Unit files"
+
+ class_option :help, :type => :boolean, :aliases => "-h", :group => :rails,
+ :desc => "Show this help message and quit"
+ end
+
+ def initialize(*args)
+ @original_wd = Dir.pwd
+
+ super
+ end
+
+ protected
+
+ def builder
+ @builder ||= begin
+ if path = options[:builder]
+ if URI(path).is_a?(URI::HTTP)
+ contents = open(path, "Accept" => "application/x-thor-template") {|io| io.read }
+ else
+ contents = open(File.expand_path(path, @original_wd)) {|io| io.read }
+ end
+
+ prok = eval("proc { #{contents} }", TOPLEVEL_BINDING, path, 1)
+ instance_eval(&prok)
+ end
+
+ builder_class = get_builder_class
+ builder_class.send(:include, ActionMethods)
+ builder_class.new(self)
+ end
+ end
+
+ def build(meth, *args)
+ builder.send(meth, *args) if builder.respond_to?(meth)
+ end
+
+ def create_root
+ self.destination_root = File.expand_path(app_path, destination_root)
+ valid_const?
+
+ empty_directory '.'
+ set_default_accessors!
+ FileUtils.cd(destination_root) unless options[:pretend]
+ end
+
+ def apply_rails_template
+ apply rails_template if rails_template
+ rescue Thor::Error, LoadError, Errno::ENOENT => e
+ raise Error, "The template [#{rails_template}] could not be loaded. Error: #{e}"
+ end
+
+ def set_default_accessors!
+ self.rails_template = case options[:template]
+ when /^http:\/\//
+ options[:template]
+ when String
+ File.expand_path(options[:template], Dir.pwd)
+ else
+ options[:template]
+ end
+ end
+
+ def database_gemfile_entry
+ entry = ""
+ unless options[:skip_active_record]
+ entry = "gem '#{gem_for_database}'"
+ entry << ", :require => '#{require_for_database}'" if require_for_database
+ end
+ entry
+ end
+
+ def rails_gemfile_entry
+ if options.dev?
+ <<-GEMFILE
+gem 'rails', :path => '#{Rails::Generators::RAILS_DEV_PATH}'
+gem 'arel', :git => 'git://github.com/rails/arel.git'
+gem "rack", :git => "git://github.com/rack/rack.git"
+ GEMFILE
+ elsif options.edge?
+ <<-GEMFILE
+gem 'rails', :git => 'git://github.com/rails/rails.git'
+gem 'arel', :git => 'git://github.com/rails/arel.git'
+gem "rack", :git => "git://github.com/rack/rack.git"
+ GEMFILE
+ else
+ <<-GEMFILE
+gem 'rails', '#{Rails::VERSION::STRING}'
+
+# Bundle edge Rails instead:
+# gem 'rails', :git => 'git://github.com/rails/rails.git'
+# gem 'arel', :git => 'git://github.com/rails/arel.git'
+# gem "rack", :git => "git://github.com/rack/rack.git"
+ GEMFILE
+ end
+ end
+
+ def gem_for_database
+ # %w( mysql oracle postgresql sqlite3 frontbase ibm_db )
+ case options[:database]
+ when "oracle" then "ruby-oci8"
+ when "postgresql" then "pg"
+ when "sqlite3" then "sqlite3-ruby"
+ when "frontbase" then "ruby-frontbase"
+ when "mysql" then "mysql2"
+ else options[:database]
+ end
+ end
+
+ def require_for_database
+ case options[:database]
+ when "sqlite3" then "sqlite3"
+ end
+ end
+
+ def bundle_if_dev_or_edge
+ bundle_command = File.basename(Thor::Util.ruby_command).sub(/ruby/, 'bundle')
+ run "#{bundle_command} install" if dev_or_edge?
+ end
+
+ def dev_or_edge?
+ options.dev? || options.edge?
+ end
+ end
+ end
+end
diff --git a/railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb b/railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb
index d12b2ff0e5..c8ee939ad7 100644
--- a/railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb
+++ b/railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb
@@ -1,3 +1,4 @@
+<% without_namespacing do -%>
<%%= form_for(@<%= singular_table_name %>) do |f| %>
<%% if @<%= singular_table_name %>.errors.any? %>
<div id="error_explanation">
@@ -21,3 +22,4 @@
<%%= f.submit %>
</div>
<%% end %>
+<% end -%>
diff --git a/railties/lib/rails/generators/erb/scaffold/templates/edit.html.erb b/railties/lib/rails/generators/erb/scaffold/templates/edit.html.erb
index e58b9fbd08..d1bfcbc429 100644
--- a/railties/lib/rails/generators/erb/scaffold/templates/edit.html.erb
+++ b/railties/lib/rails/generators/erb/scaffold/templates/edit.html.erb
@@ -1,6 +1,8 @@
+<% without_namespacing do -%>
<h1>Editing <%= singular_table_name %></h1>
<%%= render 'form' %>
<%%= link_to 'Show', @<%= singular_table_name %> %> |
<%%= link_to 'Back', <%= index_helper %>_path %>
+<% end -%>
diff --git a/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb b/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb
index 4c46db4d67..435d126ee4 100644
--- a/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb
+++ b/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb
@@ -1,3 +1,4 @@
+<% without_namespacing do -%>
<h1>Listing <%= plural_table_name %></h1>
<table>
@@ -25,3 +26,4 @@
<br />
<%%= link_to 'New <%= human_name %>', new_<%= singular_table_name %>_path %>
+<% end -%>
diff --git a/railties/lib/rails/generators/erb/scaffold/templates/new.html.erb b/railties/lib/rails/generators/erb/scaffold/templates/new.html.erb
index 02ae4d015e..fe4d0971c4 100644
--- a/railties/lib/rails/generators/erb/scaffold/templates/new.html.erb
+++ b/railties/lib/rails/generators/erb/scaffold/templates/new.html.erb
@@ -1,5 +1,7 @@
+<% without_namespacing do -%>
<h1>New <%= singular_table_name %></h1>
<%%= render 'form' %>
<%%= link_to 'Back', <%= index_helper %>_path %>
+<% end -%>
diff --git a/railties/lib/rails/generators/erb/scaffold/templates/show.html.erb b/railties/lib/rails/generators/erb/scaffold/templates/show.html.erb
index c0e5ccff1e..bc3a87b99f 100644
--- a/railties/lib/rails/generators/erb/scaffold/templates/show.html.erb
+++ b/railties/lib/rails/generators/erb/scaffold/templates/show.html.erb
@@ -1,3 +1,4 @@
+<% without_namespacing do -%>
<p id="notice"><%%= notice %></p>
<% for attribute in attributes -%>
@@ -10,3 +11,4 @@
<%%= link_to 'Edit', edit_<%= singular_table_name %>_path(@<%= singular_table_name %>) %> |
<%%= link_to 'Back', <%= index_helper %>_path %>
+<% end -%>
diff --git a/railties/lib/rails/generators/named_base.rb b/railties/lib/rails/generators/named_base.rb
index 9131a19043..badf981d05 100644
--- a/railties/lib/rails/generators/named_base.rb
+++ b/railties/lib/rails/generators/named_base.rb
@@ -30,9 +30,15 @@ module Rails
end
end
+ def without_namespacing(&block)
+ inside_namespace do
+ concat(capture(&block))
+ end
+ end
+
def indent(content, multiplier = 2)
spaces = " " * multiplier
- content.each_line.map {|line| "#{spaces}#{line}" }.join("\n")
+ content = content.each_line.map {|line| "#{spaces}#{line}" }.join
end
def wrap_with_namespace(content)
diff --git a/railties/lib/rails/generators/rails/app/app_generator.rb b/railties/lib/rails/generators/rails/app/app_generator.rb
index 44f9fde0a6..ef1eb8d237 100644
--- a/railties/lib/rails/generators/rails/app/app_generator.rb
+++ b/railties/lib/rails/generators/rails/app/app_generator.rb
@@ -1,9 +1,4 @@
-require 'digest/md5'
-require 'active_support/secure_random'
-require 'rails/version' unless defined?(Rails::VERSION)
-require 'rbconfig'
-require 'open-uri'
-require 'uri'
+require 'rails/generators/app_base'
module Rails
module ActionMethods
@@ -158,60 +153,16 @@ module Rails
RESERVED_NAMES = %w[application destroy benchmarker profiler
plugin runner test]
- class AppGenerator < Base
- DATABASES = %w( mysql oracle postgresql sqlite3 frontbase ibm_db )
- JAVASCRIPTS = %w( prototype jquery )
-
- attr_accessor :rails_template
- add_shebang_option!
-
- argument :app_path, :type => :string
-
- class_option :database, :type => :string, :aliases => "-d", :default => "sqlite3",
- :desc => "Preconfigure for selected database (options: #{DATABASES.join('/')})"
-
- class_option :javascript, :type => :string, :aliases => "-j", :default => "prototype",
- :desc => "Preconfigure for selected javascript library (options: #{JAVASCRIPTS.join('/')})"
-
- class_option :builder, :type => :string, :aliases => "-b",
- :desc => "Path to an application builder (can be a filesystem path or URL)"
-
- class_option :template, :type => :string, :aliases => "-m",
- :desc => "Path to an application template (can be a filesystem path or URL)"
-
- class_option :dev, :type => :boolean, :default => false,
- :desc => "Setup the application with Gemfile pointing to your Rails checkout"
-
- class_option :edge, :type => :boolean, :default => false,
- :desc => "Setup the application with Gemfile pointing to Rails repository"
-
- class_option :skip_gemfile, :type => :boolean, :default => false,
- :desc => "Don't create a Gemfile"
-
- class_option :skip_active_record, :type => :boolean, :aliases => "-O", :default => false,
- :desc => "Skip Active Record files"
-
- class_option :skip_test_unit, :type => :boolean, :aliases => "-T", :default => false,
- :desc => "Skip Test::Unit files"
-
- class_option :skip_javascript, :type => :boolean, :aliases => "-J", :default => false,
- :desc => "Skip javascript files"
-
- class_option :skip_git, :type => :boolean, :aliases => "-G", :default => false,
- :desc => "Skip Git ignores and keeps"
+ class AppGenerator < AppBase
+ add_shared_options_for "application"
# Add bin/rails options
class_option :version, :type => :boolean, :aliases => "-v", :group => :rails,
:desc => "Show Rails version number and quit"
- class_option :help, :type => :boolean, :aliases => "-h", :group => :rails,
- :desc => "Show this help message and quit"
-
def initialize(*args)
raise Error, "Options should be given after the application name. For details run: rails --help" if args[0].blank?
- @original_wd = Dir.pwd
-
super
if !options[:skip_active_record] && !DATABASES.include?(options[:database])
@@ -223,14 +174,7 @@ module Rails
end
end
- def create_root
- self.destination_root = File.expand_path(app_path, destination_root)
- valid_app_const?
-
- empty_directory '.'
- set_default_accessors!
- FileUtils.cd(destination_root) unless options[:pretend]
- end
+ public_task :create_root
def create_root_files
build(:readme)
@@ -309,16 +253,7 @@ module Rails
build(:leftovers)
end
- def apply_rails_template
- apply rails_template if rails_template
- rescue Thor::Error, LoadError, Errno::ENOENT => e
- raise Error, "The template [#{rails_template}] could not be loaded. Error: #{e}"
- end
-
- def bundle_if_dev_or_edge
- bundle_command = File.basename(Thor::Util.ruby_command).sub(/ruby/, 'bundle')
- run "#{bundle_command} install" if dev_or_edge?
- end
+ public_task :apply_rails_template, :bundle_if_dev_or_edge
protected
@@ -326,40 +261,6 @@ module Rails
"rails new #{self.arguments.map(&:usage).join(' ')} [options]"
end
- def builder
- @builder ||= begin
- if path = options[:builder]
- if URI(path).is_a?(URI::HTTP)
- contents = open(path, "Accept" => "application/x-thor-template") {|io| io.read }
- else
- contents = open(File.expand_path(path, @original_wd)) {|io| io.read }
- end
-
- prok = eval("proc { #{contents} }", TOPLEVEL_BINDING, path, 1)
- instance_eval(&prok)
- end
-
- builder_class = defined?(::AppBuilder) ? ::AppBuilder : Rails::AppBuilder
- builder_class.send(:include, ActionMethods)
- builder_class.new(self)
- end
- end
-
- def build(meth, *args)
- builder.send(meth, *args) if builder.respond_to?(meth)
- end
-
- def set_default_accessors!
- self.rails_template = case options[:template]
- when /^http:\/\//
- options[:template]
- when String
- File.expand_path(options[:template], Dir.pwd)
- else
- options[:template]
- end
- end
-
# Define file as an alias to create_file for backwards compatibility.
def file(*args, &block)
create_file(*args, &block)
@@ -388,7 +289,7 @@ module Rails
@app_const ||= "#{app_const_base}::Application"
end
- def valid_app_const?
+ def valid_const?
if app_const =~ /^\d/
raise Error, "Invalid application name #{app_name}. Please give a name which does not start with numbers."
elsif RESERVED_NAMES.include?(app_name)
@@ -402,28 +303,6 @@ module Rails
ActiveSupport::SecureRandom.hex(64)
end
- def dev_or_edge?
- options.dev? || options.edge?
- end
-
- def gem_for_database
- # %w( mysql oracle postgresql sqlite3 frontbase ibm_db )
- case options[:database]
- when "oracle" then "ruby-oci8"
- when "postgresql" then "pg"
- when "sqlite3" then "sqlite3-ruby"
- when "frontbase" then "ruby-frontbase"
- when "mysql" then "mysql2"
- else options[:database]
- end
- end
-
- def require_for_database
- case options[:database]
- when "sqlite3" then "sqlite3"
- end
- end
-
def mysql_socket
@mysql_socket ||= [
"/tmp/mysql.sock", # default
@@ -442,6 +321,10 @@ module Rails
empty_directory(destination, config)
create_file("#{destination}/.gitkeep") unless options[:skip_git]
end
+
+ def get_builder_class
+ defined?(::AppBuilder) ? ::AppBuilder : Rails::AppBuilder
+ end
end
end
end
diff --git a/railties/lib/rails/generators/rails/app/templates/Gemfile b/railties/lib/rails/generators/rails/app/templates/Gemfile
index 40213b1261..86b9e8f40c 100644
--- a/railties/lib/rails/generators/rails/app/templates/Gemfile
+++ b/railties/lib/rails/generators/rails/app/templates/Gemfile
@@ -1,25 +1,8 @@
source 'http://rubygems.org'
-<%- if options.dev? -%>
-gem 'rails', :path => '<%= Rails::Generators::RAILS_DEV_PATH %>'
-gem 'arel', :git => 'git://github.com/rails/arel.git'
-gem "rack", :git => "git://github.com/rack/rack.git"
-<%- elsif options.edge? -%>
-gem 'rails', :git => 'git://github.com/rails/rails.git'
-gem 'arel', :git => 'git://github.com/rails/arel.git'
-gem "rack", :git => "git://github.com/rack/rack.git"
-<%- else -%>
-gem 'rails', '<%= Rails::VERSION::STRING %>'
+<%= rails_gemfile_entry -%>
-# Bundle edge Rails instead:
-# gem 'rails', :git => 'git://github.com/rails/rails.git'
-# gem 'arel', :git => 'git://github.com/rails/arel.git'
-# gem "rack", :git => "git://github.com/rack/rack.git"
-<%- end -%>
-
-<% unless options[:skip_active_record] -%>
-gem '<%= gem_for_database %>'<% if require_for_database %>, :require => '<%= require_for_database %>'<% end %>
-<% end -%>
+<%= database_gemfile_entry -%>
# Use unicorn as the web server
# gem 'unicorn'
diff --git a/railties/lib/rails/generators/rails/plugin_new/USAGE b/railties/lib/rails/generators/rails/plugin_new/USAGE
new file mode 100644
index 0000000000..9a7bf9f396
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/USAGE
@@ -0,0 +1,10 @@
+Description:
+ The 'rails plugin new' command creates a skeleton for developing any
+ kind of Rails extension with ability to run tests using dummy Rails
+ application.
+
+Example:
+ rails plugin new ~/Code/Ruby/blog
+
+ This generates a skeletal Rails plugin in ~/Code/Ruby/blog.
+ See the README in the newly created plugin to get going.
diff --git a/railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb b/railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb
new file mode 100644
index 0000000000..8fac6fc70a
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb
@@ -0,0 +1,246 @@
+require 'active_support/core_ext/hash/slice'
+require "rails/generators/rails/app/app_generator"
+
+module Rails
+ class PluginBuilder
+ def rakefile
+ template "Rakefile"
+ end
+
+ def app
+ directory "app" if options[:mountable]
+ end
+
+ def readme
+ copy_file "README.rdoc"
+ end
+
+ def gemfile
+ template "Gemfile"
+ end
+
+ def license
+ template "MIT-LICENSE"
+ end
+
+ def gemspec
+ template "%name%.gemspec"
+ end
+
+ def gitignore
+ copy_file "gitignore", ".gitignore"
+ end
+
+ def lib
+ template "lib/%name%.rb"
+ template "lib/tasks/%name%_tasks.rake"
+ if full?
+ template "lib/%name%/engine.rb"
+ end
+ end
+
+ def config
+ template "config/routes.rb" if mountable?
+ end
+
+ def test
+ template "test/test_helper.rb"
+ template "test/%name%_test.rb"
+ append_file "Rakefile", <<-EOF
+#{rakefile_test_tasks}
+
+task :default => :test
+ EOF
+ if full?
+ template "test/integration/navigation_test.rb"
+ end
+ end
+
+ def generate_test_dummy(force = false)
+ opts = (options || {}).slice(:skip_active_record, :skip_javascript, :database, :javascript)
+ opts[:force] = force
+
+ invoke Rails::Generators::AppGenerator,
+ [ File.expand_path(dummy_path, destination_root) ], opts
+ end
+
+ def test_dummy_config
+ template "rails/boot.rb", "#{dummy_path}/config/boot.rb", :force => true
+ template "rails/application.rb", "#{dummy_path}/config/application.rb", :force => true
+ if mountable?
+ template "rails/routes.rb", "#{dummy_path}/config/routes.rb", :force => true
+ end
+ end
+
+ def test_dummy_clean
+ inside dummy_path do
+ remove_file ".gitignore"
+ remove_file "db/seeds.rb"
+ remove_file "doc"
+ remove_file "Gemfile"
+ remove_file "lib/tasks"
+ remove_file "public/images/rails.png"
+ remove_file "public/index.html"
+ remove_file "public/robots.txt"
+ remove_file "README"
+ remove_file "test"
+ remove_file "vendor"
+ end
+ end
+
+ def script(force = false)
+ directory "script", :force => force do |content|
+ "#{shebang}\n" + content
+ end
+ chmod "script", 0755, :verbose => false
+ end
+ end
+
+ module Generators
+ class PluginNewGenerator < AppBase
+ add_shared_options_for "plugin"
+
+ alias_method :plugin_path, :app_path
+
+ class_option :dummy_path, :type => :string, :default => "test/dummy",
+ :desc => "Create dummy application at given path"
+
+ class_option :full, :type => :boolean, :default => false,
+ :desc => "Generate rails engine with integration tests"
+
+ class_option :mountable, :type => :boolean, :default => false,
+ :desc => "Generate mountable isolated application"
+
+ def initialize(*args)
+ raise Error, "Options should be given after the plugin name. For details run: rails plugin --help" if args[0].blank?
+
+ super
+ end
+
+ public_task :create_root
+
+ def create_root_files
+ build(:readme)
+ build(:rakefile)
+ build(:gemspec)
+ build(:license)
+ build(:gitignore) unless options[:skip_git]
+ build(:gemfile) unless options[:skip_gemfile]
+ end
+
+ def create_app_files
+ build(:app)
+ end
+
+ def create_config_files
+ build(:config)
+ end
+
+ def create_lib_files
+ build(:lib)
+ end
+
+ def create_script_files
+ build(:script)
+ end
+
+ def create_test_files
+ build(:test) unless options[:skip_test_unit]
+ end
+
+ def create_test_dummy_files
+ return if options[:skip_test_unit]
+ create_dummy_app
+ end
+
+ def finish_template
+ build(:leftovers)
+ end
+
+ public_task :apply_rails_template, :bundle_if_dev_or_edge
+
+ protected
+ def create_dummy_app(path = nil)
+ dummy_path(path) if path
+
+ say_status :vendor_app, dummy_path
+ mute do
+ build(:generate_test_dummy)
+ store_application_definition!
+ build(:test_dummy_config)
+ build(:test_dummy_clean)
+ # ensure that script/rails has proper dummy_path
+ build(:script, true)
+ end
+ end
+
+ def full?
+ options[:full] || options[:mountable]
+ end
+
+ def mountable?
+ options[:mountable]
+ end
+
+ def self.banner
+ "rails plugin new #{self.arguments.map(&:usage).join(' ')} [options]"
+ end
+
+ def name
+ @name ||= File.basename(destination_root)
+ end
+
+ def camelized
+ @camelized ||= name.gsub(/\W/, '_').squeeze('_').camelize
+ end
+
+ def valid_const?
+ if camelized =~ /^\d/
+ raise Error, "Invalid plugin name #{name}. Please give a name which does not start with numbers."
+ elsif RESERVED_NAMES.include?(name)
+ raise Error, "Invalid plugin name #{name}. Please give a name which does not match one of the reserved rails words."
+ elsif Object.const_defined?(camelized)
+ raise Error, "Invalid plugin name #{name}, constant #{camelized} is already in use. Please choose another application name."
+ end
+ end
+
+ def application_definition
+ @application_definition ||= begin
+
+ dummy_application_path = File.expand_path("#{dummy_path}/config/application.rb", destination_root)
+ unless options[:pretend] || !File.exists?(dummy_application_path)
+ contents = File.read(dummy_application_path)
+ contents[(contents.index("module Dummy"))..-1]
+ end
+ end
+ end
+ alias :store_application_definition! :application_definition
+
+ def get_builder_class
+ defined?(::PluginBuilder) ? ::PluginBuilder : Rails::PluginBuilder
+ end
+
+ def rakefile_test_tasks
+ <<-RUBY
+require 'rake/testtask'
+
+Rake::TestTask.new(:test) do |t|
+ t.libs << 'lib'
+ t.libs << 'test'
+ t.pattern = 'test/**/*_test.rb'
+ t.verbose = false
+end
+ RUBY
+ end
+
+ def dummy_path(path = nil)
+ @dummy_path = path if path
+ @dummy_path || options[:dummy_path]
+ end
+
+ def mute(&block)
+ shell.mute(&block)
+ end
+ end
+ end
+end
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/%name%.gemspec b/railties/lib/rails/generators/rails/plugin_new/templates/%name%.gemspec
new file mode 100644
index 0000000000..3d9bfb22c7
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/%name%.gemspec
@@ -0,0 +1,9 @@
+# Provide a simple gemspec so you can easily use your
+# project in your rails apps through git.
+Gem::Specification.new do |s|
+ s.name = "<%= name %>"
+ s.summary = "Insert <%= camelized %> summary."
+ s.description = "Insert <%= camelized %> description."
+ s.files = Dir["lib/**/*"] + ["MIT-LICENSE", "Rakefile", "README.rdoc"]
+ s.version = "0.0.1"
+end
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/Gemfile b/railties/lib/rails/generators/rails/plugin_new/templates/Gemfile
new file mode 100644
index 0000000000..29900c93dc
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/Gemfile
@@ -0,0 +1,11 @@
+source "http://rubygems.org"
+
+<%= rails_gemfile_entry -%>
+
+<% if full? -%>
+<%= database_gemfile_entry -%>
+<% end -%>
+
+if RUBY_VERSION < '1.9'
+ gem "ruby-debug", ">= 0.10.3"
+end
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/MIT-LICENSE b/railties/lib/rails/generators/rails/plugin_new/templates/MIT-LICENSE
new file mode 100644
index 0000000000..d7a9109894
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/MIT-LICENSE
@@ -0,0 +1,20 @@
+Copyright <%= Date.today.year %> YOURNAME
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/README.rdoc b/railties/lib/rails/generators/rails/plugin_new/templates/README.rdoc
new file mode 100644
index 0000000000..301d647731
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/README.rdoc
@@ -0,0 +1,3 @@
+= <%= camelized %>
+
+This project rocks and uses MIT-LICENSE. \ No newline at end of file
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/Rakefile b/railties/lib/rails/generators/rails/plugin_new/templates/Rakefile
new file mode 100644
index 0000000000..88f50f9f04
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/Rakefile
@@ -0,0 +1,18 @@
+# encoding: UTF-8
+require 'rubygems'
+begin
+ require 'bundler/setup'
+rescue LoadError
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
+end
+
+require 'rake'
+require 'rake/rdoctask'
+
+Rake::RDocTask.new(:rdoc) do |rdoc|
+ rdoc.rdoc_dir = 'rdoc'
+ rdoc.title = '<%= camelized %>'
+ rdoc.options << '--line-numbers' << '--inline-source'
+ rdoc.rdoc_files.include('README.rdoc')
+ rdoc.rdoc_files.include('lib/**/*.rb')
+end
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/app/controllers/%name%/application_controller.rb.tt b/railties/lib/rails/generators/rails/plugin_new/templates/app/controllers/%name%/application_controller.rb.tt
new file mode 100644
index 0000000000..f225bc9f7f
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/app/controllers/%name%/application_controller.rb.tt
@@ -0,0 +1,4 @@
+module <%= camelized %>
+ class ApplicationController < ActiveController::Base
+ end
+end
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/app/helpers/%name%/application_helper.rb.tt b/railties/lib/rails/generators/rails/plugin_new/templates/app/helpers/%name%/application_helper.rb.tt
new file mode 100644
index 0000000000..40ae9f52c2
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/app/helpers/%name%/application_helper.rb.tt
@@ -0,0 +1,4 @@
+module <%= camelized %>
+ module ApplicationHelper
+ end
+end
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/config/routes.rb b/railties/lib/rails/generators/rails/plugin_new/templates/config/routes.rb
new file mode 100644
index 0000000000..42ddf380d8
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/config/routes.rb
@@ -0,0 +1,3 @@
+<%= camelized %>::Engine.routes.draw do
+
+end
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/gitignore b/railties/lib/rails/generators/rails/plugin_new/templates/gitignore
new file mode 100644
index 0000000000..1463de6dfb
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/gitignore
@@ -0,0 +1,6 @@
+.bundle/
+log/*.log
+pkg/
+test/dummy/db/*.sqlite3
+test/dummy/log/*.log
+test/dummy/tmp/ \ No newline at end of file
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/lib/%name%.rb b/railties/lib/rails/generators/rails/plugin_new/templates/lib/%name%.rb
new file mode 100644
index 0000000000..2d3bdc510c
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/lib/%name%.rb
@@ -0,0 +1,6 @@
+<% if full? -%>
+require "<%= name %>/engine"
+
+<% end -%>
+module <%= camelized %>
+end
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/lib/%name%/engine.rb b/railties/lib/rails/generators/rails/plugin_new/templates/lib/%name%/engine.rb
new file mode 100644
index 0000000000..9600ee0c3f
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/lib/%name%/engine.rb
@@ -0,0 +1,7 @@
+module <%= camelized %>
+ class Engine < Rails::Engine
+<% if mountable? -%>
+ isolate_namespace <%= camelized %>
+<% end -%>
+ end
+end
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/lib/tasks/%name%_tasks.rake b/railties/lib/rails/generators/rails/plugin_new/templates/lib/tasks/%name%_tasks.rake
new file mode 100644
index 0000000000..7121f5ae23
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/lib/tasks/%name%_tasks.rake
@@ -0,0 +1,4 @@
+# desc "Explaining what the task does"
+# task :<%= name %> do
+# # Task goes here
+# end
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/rails/application.rb b/railties/lib/rails/generators/rails/plugin_new/templates/rails/application.rb
new file mode 100644
index 0000000000..8b68280a5e
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/rails/application.rb
@@ -0,0 +1,16 @@
+require File.expand_path('../boot', __FILE__)
+
+<% unless options[:skip_active_record] -%>
+require 'rails/all'
+<% else -%>
+# require "active_record/railtie"
+require "action_controller/railtie"
+require "action_mailer/railtie"
+require "active_resource/railtie"
+require "rails/test_unit/railtie"
+<% end -%>
+
+Bundler.require
+require "<%= name %>"
+
+<%= application_definition %>
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/rails/boot.rb b/railties/lib/rails/generators/rails/plugin_new/templates/rails/boot.rb
new file mode 100644
index 0000000000..eba0681370
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/rails/boot.rb
@@ -0,0 +1,10 @@
+require 'rubygems'
+gemfile = File.expand_path('../../../../Gemfile', __FILE__)
+
+if File.exist?(gemfile)
+ ENV['BUNDLE_GEMFILE'] = gemfile
+ require 'bundler'
+ Bundler.setup
+end
+
+$:.unshift File.expand_path('../../../../lib', __FILE__) \ No newline at end of file
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/rails/routes.rb b/railties/lib/rails/generators/rails/plugin_new/templates/rails/routes.rb
new file mode 100644
index 0000000000..730ee31c3d
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/rails/routes.rb
@@ -0,0 +1,4 @@
+Rails.application.routes.draw do
+
+ mount <%= camelized %>::Engine => "/<%= name %>"
+end
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/script/rails.tt b/railties/lib/rails/generators/rails/plugin_new/templates/script/rails.tt
new file mode 100644
index 0000000000..ebd5a77dd5
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/script/rails.tt
@@ -0,0 +1,5 @@
+#!/usr/bin/env ruby
+# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
+
+ENGINE_PATH = File.expand_path('../..', __FILE__)
+load File.expand_path('../../<%= dummy_path %>/script/rails', __FILE__)
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/test/%name%_test.rb b/railties/lib/rails/generators/rails/plugin_new/templates/test/%name%_test.rb
new file mode 100644
index 0000000000..0a8bbd4aaf
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/test/%name%_test.rb
@@ -0,0 +1,7 @@
+require 'test_helper'
+
+class <%= camelized %>Test < ActiveSupport::TestCase
+ test "truth" do
+ assert_kind_of Module, <%= camelized %>
+ end
+end
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/test/integration/navigation_test.rb b/railties/lib/rails/generators/rails/plugin_new/templates/test/integration/navigation_test.rb
new file mode 100644
index 0000000000..d06fe7cbd0
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/test/integration/navigation_test.rb
@@ -0,0 +1,11 @@
+require 'test_helper'
+
+class NavigationTest < ActionDispatch::IntegrationTest
+ fixtures :all
+
+ # Replace this with your real tests.
+ test "the truth" do
+ assert true
+ end
+end
+
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/test/test_helper.rb b/railties/lib/rails/generators/rails/plugin_new/templates/test/test_helper.rb
new file mode 100644
index 0000000000..dbcaf6b92f
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/test/test_helper.rb
@@ -0,0 +1,17 @@
+# Configure Rails Envinronment
+ENV["RAILS_ENV"] = "test"
+
+require File.expand_path("../dummy/config/environment.rb", __FILE__)
+require "rails/test_help"
+
+Rails.backtrace_cleaner.remove_silencers!
+
+<% if full? && !options[:skip_active_record] -%>
+# Run any available migration from application
+ActiveRecord::Migrator.migrate File.expand_path("../dummy/db/migrate/", __FILE__)
+# and from engine
+ActiveRecord::Migrator.migrate File.expand_path("../../db/migrate/", __FILE__)
+<% end -%>
+
+# Load support files
+Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
diff --git a/railties/lib/rails/generators/rails/resource/resource_generator.rb b/railties/lib/rails/generators/rails/resource/resource_generator.rb
index 8a943013d3..c7345f3cfb 100644
--- a/railties/lib/rails/generators/rails/resource/resource_generator.rb
+++ b/railties/lib/rails/generators/rails/resource/resource_generator.rb
@@ -16,9 +16,9 @@ module Rails
def add_resource_route
return if options[:actions].present?
- route_config = class_path.collect{|namespace| "namespace :#{namespace} do " }.join(" ")
+ route_config = regular_class_path.collect{|namespace| "namespace :#{namespace} do " }.join(" ")
route_config << "resources :#{file_name.pluralize}"
- route_config << " end" * class_path.size
+ route_config << " end" * regular_class_path.size
route route_config
end
end
diff --git a/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb b/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb
index b21340f755..b5317a055b 100644
--- a/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb
+++ b/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb
@@ -1,3 +1,4 @@
+<% module_namespacing do -%>
class <%= controller_class_name %>Controller < ApplicationController
# GET <%= route_url %>
# GET <%= route_url %>.xml
@@ -81,3 +82,4 @@ class <%= controller_class_name %>Controller < ApplicationController
end
end
end
+<% end -%>
diff --git a/railties/lib/rails/generators/resource_helpers.rb b/railties/lib/rails/generators/resource_helpers.rb
index 8400171aa1..d6ccfc496a 100644
--- a/railties/lib/rails/generators/resource_helpers.rb
+++ b/railties/lib/rails/generators/resource_helpers.rb
@@ -34,7 +34,7 @@ module Rails
attr_reader :controller_name
def controller_class_path
- @class_path
+ class_path
end
def controller_file_name
@@ -46,7 +46,7 @@ module Rails
end
def controller_class_name
- @controller_class_name ||= (controller_class_path + [controller_file_name]).map!{ |m| m.camelize }.join('::')
+ (controller_class_path + [controller_file_name]).map!{ |m| m.camelize }.join('::')
end
def controller_i18n_scope
diff --git a/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb b/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb
index f23e495450..964d59d84c 100644
--- a/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb
+++ b/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb
@@ -1,5 +1,6 @@
require 'test_helper'
+<% module_namespacing do -%>
class <%= controller_class_name %>ControllerTest < ActionController::TestCase
setup do
@<%= singular_table_name %> = <%= table_name %>(:one)
@@ -47,3 +48,4 @@ class <%= controller_class_name %>ControllerTest < ActionController::TestCase
assert_redirected_to <%= index_helper %>_path
end
end
+<% end -%>
diff --git a/railties/test/fixtures/lib/empty_builder.rb b/railties/test/fixtures/lib/app_builders/empty_builder.rb
index babd9c2461..babd9c2461 100644
--- a/railties/test/fixtures/lib/empty_builder.rb
+++ b/railties/test/fixtures/lib/app_builders/empty_builder.rb
diff --git a/railties/test/fixtures/lib/app_builders/simple_builder.rb b/railties/test/fixtures/lib/app_builders/simple_builder.rb
new file mode 100644
index 0000000000..993d3a2aa2
--- /dev/null
+++ b/railties/test/fixtures/lib/app_builders/simple_builder.rb
@@ -0,0 +1,7 @@
+class AppBuilder
+ def gitignore
+ create_file ".gitignore", <<-R.strip
+foobar
+ R
+ end
+end
diff --git a/railties/test/fixtures/lib/app_builders/tweak_builder.rb b/railties/test/fixtures/lib/app_builders/tweak_builder.rb
new file mode 100644
index 0000000000..cb50be01cb
--- /dev/null
+++ b/railties/test/fixtures/lib/app_builders/tweak_builder.rb
@@ -0,0 +1,7 @@
+class AppBuilder < Rails::AppBuilder
+ def gitignore
+ create_file ".gitignore", <<-R.strip
+foobar
+ R
+ end
+end
diff --git a/railties/test/fixtures/lib/create_test_dummy_template.rb b/railties/test/fixtures/lib/create_test_dummy_template.rb
new file mode 100644
index 0000000000..e4378bbd1a
--- /dev/null
+++ b/railties/test/fixtures/lib/create_test_dummy_template.rb
@@ -0,0 +1 @@
+create_dummy_app("spec/dummy")
diff --git a/railties/test/fixtures/lib/plugin_builders/empty_builder.rb b/railties/test/fixtures/lib/plugin_builders/empty_builder.rb
new file mode 100644
index 0000000000..5c5607621c
--- /dev/null
+++ b/railties/test/fixtures/lib/plugin_builders/empty_builder.rb
@@ -0,0 +1,2 @@
+class PluginBuilder
+end
diff --git a/railties/test/fixtures/lib/plugin_builders/simple_builder.rb b/railties/test/fixtures/lib/plugin_builders/simple_builder.rb
new file mode 100644
index 0000000000..08f6c5535d
--- /dev/null
+++ b/railties/test/fixtures/lib/plugin_builders/simple_builder.rb
@@ -0,0 +1,7 @@
+class PluginBuilder
+ def gitignore
+ create_file ".gitignore", <<-R.strip
+foobar
+ R
+ end
+end
diff --git a/railties/test/fixtures/lib/plugin_builders/spec_builder.rb b/railties/test/fixtures/lib/plugin_builders/spec_builder.rb
new file mode 100644
index 0000000000..aa18c7ddaa
--- /dev/null
+++ b/railties/test/fixtures/lib/plugin_builders/spec_builder.rb
@@ -0,0 +1,19 @@
+class PluginBuilder < Rails::PluginBuilder
+ def test
+ create_file "spec/spec_helper.rb"
+ append_file "Rakefile", <<-EOF
+# spec tasks in rakefile
+
+task :default => :spec
+ EOF
+ end
+
+ def generate_test_dummy
+ dummy_path("spec/dummy")
+ super
+ end
+
+ def skip_test_unit?
+ true
+ end
+end
diff --git a/railties/test/fixtures/lib/plugin_builders/tweak_builder.rb b/railties/test/fixtures/lib/plugin_builders/tweak_builder.rb
new file mode 100644
index 0000000000..1e801409a4
--- /dev/null
+++ b/railties/test/fixtures/lib/plugin_builders/tweak_builder.rb
@@ -0,0 +1,7 @@
+class PluginBuilder < Rails::PluginBuilder
+ def gitignore
+ create_file ".gitignore", <<-R.strip
+foobar
+ R
+ end
+end
diff --git a/railties/test/fixtures/lib/simple_builder.rb b/railties/test/fixtures/lib/simple_builder.rb
deleted file mode 100644
index 47dcdc0d96..0000000000
--- a/railties/test/fixtures/lib/simple_builder.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-class AppBuilder
- def configru
- create_file "config.ru", <<-R.strip
-run proc { |env| [200, { "Content-Type" => "text/html" }, ["Hello World"]] }
- R
- end
-end \ No newline at end of file
diff --git a/railties/test/fixtures/lib/tweak_builder.rb b/railties/test/fixtures/lib/tweak_builder.rb
deleted file mode 100644
index eed20ecc9b..0000000000
--- a/railties/test/fixtures/lib/tweak_builder.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-class AppBuilder < Rails::AppBuilder
- def configru
- create_file "config.ru", <<-R.strip
-run proc { |env| [200, { "Content-Type" => "text/html" }, ["Hello World"]] }
- R
- end
-end \ No newline at end of file
diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb
index f4d2027874..6b2026ad0c 100644
--- a/railties/test/generators/app_generator_test.rb
+++ b/railties/test/generators/app_generator_test.rb
@@ -1,6 +1,7 @@
require 'abstract_unit'
require 'generators/generators_test_helper'
require 'rails/generators/rails/app/app_generator'
+require 'generators/shared_generator_tests.rb'
DEFAULT_APP_FILES = %w(
.gitignore
@@ -40,36 +41,10 @@ DEFAULT_APP_FILES = %w(
class AppGeneratorTest < Rails::Generators::TestCase
include GeneratorsTestHelper
arguments [destination_root]
+ include SharedGeneratorTests
- def setup
- Rails.application = TestApp::Application
- super
- Rails::Generators::AppGenerator.instance_variable_set('@desc', nil)
- @bundle_command = File.basename(Thor::Util.ruby_command).sub(/ruby/, 'bundle')
-
- Kernel::silence_warnings do
- Thor::Base.shell.send(:attr_accessor, :always_force)
- @shell = Thor::Base.shell.new
- @shell.send(:always_force=, true)
- end
- end
-
- def teardown
- super
- Rails::Generators::AppGenerator.instance_variable_set('@desc', nil)
- Rails.application = TestApp::Application.instance
- end
-
- def test_application_skeleton_is_created
- run_generator
-
- DEFAULT_APP_FILES.each{ |path| assert_file path }
- end
-
- def test_application_generate_pretend
- run_generator ["testapp", "--pretend"]
-
- DEFAULT_APP_FILES.each{ |path| assert_no_file path }
+ def default_files
+ ::DEFAULT_APP_FILES
end
def test_application_controller_and_layout_files
@@ -78,36 +53,11 @@ class AppGeneratorTest < Rails::Generators::TestCase
assert_no_file "public/stylesheets/application.css"
end
- def test_options_before_application_name_raises_an_error
- content = capture(:stderr){ run_generator(["--skip-active-record", destination_root]) }
- assert_equal "Options should be given after the application name. For details run: rails --help\n", content
- end
-
- def test_name_collision_raises_an_error
- reserved_words = %w[application destroy plugin runner test]
- reserved_words.each do |reserved|
- content = capture(:stderr){ run_generator [File.join(destination_root, reserved)] }
- assert_equal "Invalid application name #{reserved}. Please give a name which does not match one of the reserved rails words.\n", content
- end
- end
-
- def test_invalid_database_option_raises_an_error
- content = capture(:stderr){ run_generator([destination_root, "-d", "unknown"]) }
- assert_match /Invalid value for \-\-database option/, content
- end
-
def test_invalid_application_name_raises_an_error
content = capture(:stderr){ run_generator [File.join(destination_root, "43-things")] }
assert_equal "Invalid application name 43-things. Please give a name which does not start with numbers.\n", content
end
- def test_application_name_raises_an_error_if_name_already_used_constant
- %w{ String Hash Class Module Set Symbol }.each do |ruby_class|
- content = capture(:stderr){ run_generator [File.join(destination_root, ruby_class)] }
- assert_equal "Invalid application name #{ruby_class}, constant #{ruby_class} is already in use. Please choose another application name.\n", content
- end
- end
-
def test_invalid_application_name_is_fixed
run_generator [File.join(destination_root, "things-43")]
assert_file "things-43/config/environment.rb", /Things43::Application\.initialize!/
@@ -188,18 +138,6 @@ class AppGeneratorTest < Rails::Generators::TestCase
assert_file "test"
end
- def test_test_unit_is_removed_from_frameworks_if_skip_test_unit_is_given
- run_generator [destination_root, "--skip-test-unit"]
- assert_file "config/application.rb" do |file|
- assert_match /config.generators.test_framework = false/, file
- end
- end
-
- def test_test_unit_is_skipped_if_required
- run_generator [destination_root, "--skip-test-unit"]
- assert_no_file "test"
- end
-
def test_javascript_is_skipped_if_required
run_generator [destination_root, "--skip-javascript"]
assert_file "config/application.rb", /^\s+config\.action_view\.javascript_expansions\[:defaults\]\s+=\s+%w\(\)/
@@ -224,36 +162,11 @@ class AppGeneratorTest < Rails::Generators::TestCase
assert_file "public/javascripts/rails.js", /jQuery/
end
- def test_shebang_is_added_to_rails_file
- run_generator [destination_root, "--ruby", "foo/bar/baz"]
- assert_file "script/rails", /#!foo\/bar\/baz/
- end
-
- def test_shebang_when_is_the_same_as_default_use_env
- run_generator [destination_root, "--ruby", Thor::Util.ruby_command]
- assert_file "script/rails", /#!\/usr\/bin\/env/
- end
-
def test_template_from_dir_pwd
FileUtils.cd(Rails.root)
assert_match /It works from file!/, run_generator([destination_root, "-m", "lib/template.rb"])
end
- def test_template_raises_an_error_with_invalid_path
- content = capture(:stderr){ run_generator([destination_root, "-m", "non/existant/path"]) }
- assert_match /The template \[.*\] could not be loaded/, content
- assert_match /non\/existant\/path/, content
- end
-
- def test_template_is_executed_when_supplied
- path = "http://gist.github.com/103208.txt"
- template = %{ say "It works!" }
- template.instance_eval "def read; self; end" # Make the string respond to read
-
- generator([destination_root], :template => path).expects(:open).with(path, 'Accept' => 'application/x-thor-template').returns(template)
- assert_match /It works!/, silence(:stdout){ generator.invoke_all }
- end
-
def test_usage_read_from_file
File.expects(:read).returns("USAGE FROM FILE")
assert_equal "USAGE FROM FILE", Rails::Generators::AppGenerator.desc
@@ -273,19 +186,6 @@ class AppGeneratorTest < Rails::Generators::TestCase
assert_file 'lib/test_file.rb', 'heres test data'
end
- def test_dev_option
- generator([destination_root], :dev => true).expects(:run).with("#{@bundle_command} install")
- silence(:stdout){ generator.invoke_all }
- rails_path = File.expand_path('../../..', Rails.root)
- assert_file 'Gemfile', /^gem\s+["']rails["'],\s+:path\s+=>\s+["']#{Regexp.escape(rails_path)}["']$/
- end
-
- def test_edge_option
- generator([destination_root], :edge => true).expects(:run).with("#{@bundle_command} install")
- silence(:stdout){ generator.invoke_all }
- assert_file 'Gemfile', /^gem\s+["']rails["'],\s+:git\s+=>\s+["']#{Regexp.escape("git://github.com/rails/rails.git")}["']$/
- end
-
protected
def action(*args, &block)
@@ -299,62 +199,21 @@ class CustomAppGeneratorTest < Rails::Generators::TestCase
tests Rails::Generators::AppGenerator
arguments [destination_root]
+ include SharedCustomGeneratorTests
- def setup
- Rails.application = TestApp::Application
- super
- Rails::Generators::AppGenerator.instance_variable_set('@desc', nil)
- @bundle_command = File.basename(Thor::Util.ruby_command).sub(/ruby/, 'bundle')
- end
-
- def teardown
- super
- Rails::Generators::AppGenerator.instance_variable_set('@desc', nil)
- Object.class_eval { remove_const :AppBuilder if const_defined?(:AppBuilder) }
- Rails.application = TestApp::Application.instance
- end
-
- def test_builder_option_with_empty_app_builder
- FileUtils.cd(Rails.root)
- run_generator([destination_root, "-b", "#{Rails.root}/lib/empty_builder.rb"])
- DEFAULT_APP_FILES.each{ |path| assert_no_file path }
- end
-
- def test_builder_option_with_simple_app_builder
- FileUtils.cd(Rails.root)
- run_generator([destination_root, "-b", "#{Rails.root}/lib/simple_builder.rb"])
- (DEFAULT_APP_FILES - ['config.ru']).each{ |path| assert_no_file path }
- assert_file "config.ru", %[run proc { |env| [200, { "Content-Type" => "text/html" }, ["Hello World"]] }]
- end
-
- def test_builder_option_with_relative_path
- here = File.expand_path(File.dirname(__FILE__))
- FileUtils.cd(here)
- run_generator([destination_root, "-b", "../fixtures/lib/simple_builder.rb"])
- (DEFAULT_APP_FILES - ['config.ru']).each{ |path| assert_no_file path }
- assert_file "config.ru", %[run proc { |env| [200, { "Content-Type" => "text/html" }, ["Hello World"]] }]
+protected
+ def default_files
+ ::DEFAULT_APP_FILES
end
- def test_builder_option_with_tweak_app_builder
- FileUtils.cd(Rails.root)
- run_generator([destination_root, "-b", "#{Rails.root}/lib/tweak_builder.rb"])
- DEFAULT_APP_FILES.each{ |path| assert_file path }
- assert_file "config.ru", %[run proc { |env| [200, { "Content-Type" => "text/html" }, ["Hello World"]] }]
+ def builders_dir
+ "app_builders"
end
- def test_builder_option_with_http
- path = "http://gist.github.com/103208.txt"
- template = "class AppBuilder; end"
- template.instance_eval "def read; self; end" # Make the string respond to read
-
- generator([destination_root], :builder => path).expects(:open).with(path, 'Accept' => 'application/x-thor-template').returns(template)
- capture(:stdout) { generator.invoke_all }
-
- DEFAULT_APP_FILES.each{ |path| assert_no_file path }
+ def builder_class
+ :AppBuilder
end
-protected
-
def action(*args, &block)
silence(:stdout){ generator.send(*args, &block) }
end
diff --git a/railties/test/generators/namespaced_generators_test.rb b/railties/test/generators/namespaced_generators_test.rb
index d1190fd17d..d61a02d32f 100644
--- a/railties/test/generators/namespaced_generators_test.rb
+++ b/railties/test/generators/namespaced_generators_test.rb
@@ -3,6 +3,7 @@ require 'rails/generators/rails/controller/controller_generator'
require 'rails/generators/rails/model/model_generator'
require 'rails/generators/rails/observer/observer_generator'
require 'rails/generators/mailer/mailer_generator'
+require 'rails/generators/rails/scaffold/scaffold_generator'
class NamespacedGeneratorTestCase < Rails::Generators::TestCase
def setup
@@ -202,3 +203,155 @@ class NamespacedMailerGeneratorTest < NamespacedGeneratorTestCase
assert_file "app/views/test_app/notifier"
end
end
+
+class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase
+ include GeneratorsTestHelper
+ arguments %w(product_line title:string price:integer)
+ tests Rails::Generators::ScaffoldGenerator
+
+ setup :copy_routes
+
+ def test_scaffold_on_invoke
+ run_generator
+
+ # Model
+ assert_file "app/models/test_app/product_line.rb", /module TestApp\n class ProductLine < ActiveRecord::Base/
+ assert_file "test/unit/test_app/product_line_test.rb", /module TestApp\n class ProductLineTest < ActiveSupport::TestCase/
+ assert_file "test/fixtures/test_app/product_lines.yml"
+ assert_migration "db/migrate/create_test_app_product_lines.rb"
+
+ # Route
+ assert_file "config/routes.rb" do |route|
+ assert_match(/resources :product_lines$/, route)
+ end
+
+ # Controller
+ assert_file "app/controllers/test_app/product_lines_controller.rb" do |content|
+ assert_match(/module TestApp\n class ProductLinesController < ApplicationController/, content)
+ end
+
+ assert_file "test/functional/test_app/product_lines_controller_test.rb",
+ /module TestApp\n class ProductLinesControllerTest < ActionController::TestCase/
+
+ # Views
+ %w(
+ index
+ edit
+ new
+ show
+ _form
+ ).each { |view| assert_file "app/views/test_app/product_lines/#{view}.html.erb" }
+ assert_no_file "app/views/layouts/test_app/product_lines.html.erb"
+
+ # Helpers
+ assert_file "app/helpers/test_app/product_lines_helper.rb"
+ assert_file "test/unit/helpers/test_app/product_lines_helper_test.rb"
+
+ # Stylesheets
+ assert_file "public/stylesheets/scaffold.css"
+ end
+
+ def test_scaffold_on_revoke
+ run_generator
+ run_generator ["product_line"], :behavior => :revoke
+
+ # Model
+ assert_no_file "app/models/test_app/product_line.rb"
+ assert_no_file "test/unit/test_app/product_line_test.rb"
+ assert_no_file "test/fixtures/test_app/product_lines.yml"
+ assert_no_migration "db/migrate/create_test_app_product_lines.rb"
+
+ # Route
+ assert_file "config/routes.rb" do |route|
+ assert_no_match(/resources :product_lines$/, route)
+ end
+
+ # Controller
+ assert_no_file "app/controllers/test_app/product_lines_controller.rb"
+ assert_no_file "test/functional/test_app/product_lines_controller_test.rb"
+
+ # Views
+ assert_no_file "app/views/test_app/product_lines"
+ assert_no_file "app/views/test_app/layouts/product_lines.html.erb"
+
+ # Helpers
+ assert_no_file "app/helpers/test_app/product_lines_helper.rb"
+ assert_no_file "test/unit/helpers/test_app/product_lines_helper_test.rb"
+
+ # Stylesheets (should not be removed)
+ assert_file "public/stylesheets/scaffold.css"
+ end
+
+ def test_scaffold_with_namespace_on_invoke
+ run_generator [ "admin/role", "name:string", "description:string" ]
+
+ # Model
+ assert_file "app/models/test_app/admin.rb", /module TestApp\n module Admin/
+ assert_file "app/models/test_app/admin/role.rb", /module TestApp\n class Admin::Role < ActiveRecord::Base/
+ assert_file "test/unit/test_app/admin/role_test.rb", /module TestApp\n class Admin::RoleTest < ActiveSupport::TestCase/
+ assert_file "test/fixtures/test_app/admin/roles.yml"
+ assert_migration "db/migrate/create_test_app_admin_roles.rb"
+
+ # Route
+ assert_file "config/routes.rb" do |route|
+ assert_match(/namespace :admin do resources :roles end$/, route)
+ end
+
+ # Controller
+ assert_file "app/controllers/test_app/admin/roles_controller.rb" do |content|
+ assert_match(/module TestApp\n class Admin::RolesController < ApplicationController/, content)
+ end
+
+ assert_file "test/functional/test_app/admin/roles_controller_test.rb",
+ /module TestApp\n class Admin::RolesControllerTest < ActionController::TestCase/
+
+ # Views
+ %w(
+ index
+ edit
+ new
+ show
+ _form
+ ).each { |view| assert_file "app/views/test_app/admin/roles/#{view}.html.erb" }
+ assert_no_file "app/views/layouts/admin/roles.html.erb"
+
+ # Helpers
+ assert_file "app/helpers/test_app/admin/roles_helper.rb"
+ assert_file "test/unit/helpers/test_app/admin/roles_helper_test.rb"
+
+ # Stylesheets
+ assert_file "public/stylesheets/scaffold.css"
+ end
+
+ def test_scaffold_with_namespace_on_revoke
+ run_generator [ "admin/role", "name:string", "description:string" ]
+ run_generator [ "admin/role" ], :behavior => :revoke
+
+ # Model
+ assert_file "app/models/test_app/admin.rb" # ( should not be remove )
+ assert_no_file "app/models/test_app/admin/role.rb"
+ assert_no_file "test/unit/test_app/admin/role_test.rb"
+ assert_no_file "test/fixtures/test_app/admin/roles.yml"
+ assert_no_migration "db/migrate/create_test_app_admin_roles.rb"
+
+ # Route
+ assert_file "config/routes.rb" do |route|
+ assert_no_match(/namespace :admin do resources :roles end$/, route)
+ end
+
+ # Controller
+ assert_no_file "app/controllers/test_app/admin/roles_controller.rb"
+ assert_no_file "test/functional/test_app/admin/roles_controller_test.rb"
+
+ # Views
+ assert_no_file "app/views/test_app/admin/roles"
+ assert_no_file "app/views/layouts/test_app/admin/roles.html.erb"
+
+ # Helpers
+ assert_no_file "app/helpers/test_app/admin/roles_helper.rb"
+ assert_no_file "test/unit/helpers/test_app/admin/roles_helper_test.rb"
+
+ # Stylesheets (should not be removed)
+ assert_file "public/stylesheets/scaffold.css"
+ end
+end
diff --git a/railties/test/generators/plugin_new_generator_test.rb b/railties/test/generators/plugin_new_generator_test.rb
new file mode 100644
index 0000000000..8dc5ca90ba
--- /dev/null
+++ b/railties/test/generators/plugin_new_generator_test.rb
@@ -0,0 +1,192 @@
+require 'abstract_unit'
+require 'generators/generators_test_helper'
+require 'rails/generators/rails/plugin_new/plugin_new_generator'
+require 'generators/shared_generator_tests.rb'
+
+DEFAULT_PLUGIN_FILES = %w(
+ .gitignore
+ Gemfile
+ Rakefile
+ bukkits.gemspec
+ MIT-LICENSE
+ lib
+ lib/bukkits.rb
+ lib/tasks/bukkits_tasks.rake
+ script/rails
+ test/bukkits_test.rb
+ test/test_helper.rb
+ test/dummy
+)
+
+
+class PluginNewGeneratorTest < Rails::Generators::TestCase
+ include GeneratorsTestHelper
+ destination File.join(Rails.root, "tmp/bukkits")
+ arguments [destination_root]
+ include SharedGeneratorTests
+
+ def default_files
+ ::DEFAULT_PLUGIN_FILES
+ end
+
+ def test_invalid_plugin_name_raises_an_error
+ content = capture(:stderr){ run_generator [File.join(destination_root, "43-things")] }
+ assert_equal "Invalid plugin name 43-things. Please give a name which does not start with numbers.\n", content
+ end
+
+ def test_invalid_plugin_name_is_fixed
+ run_generator [File.join(destination_root, "things-43")]
+ assert_file "things-43/lib/things-43.rb", /module Things43/
+ end
+
+ def test_generating_test_files
+ run_generator
+ assert_file "test/test_helper.rb"
+ assert_file "test/bukkits_test.rb", /assert_kind_of Module, Bukkits/
+ end
+
+ def test_generating_test_files_in_full_mode
+ run_generator [destination_root, "--full"]
+ assert_directory "test/integration/"
+
+ assert_file "test/integration/navigation_test.rb", /ActionDispatch::IntegrationTest/
+ end
+
+ def test_ensure_that_plugin_options_are_not_passed_to_app_generator
+ FileUtils.cd(Rails.root)
+ assert_no_match /It works from file!.*It works_from_file/, run_generator([destination_root, "-m", "lib/template.rb"])
+ end
+
+ def test_ensure_that_test_dummy_can_be_generated_from_a_template
+ FileUtils.cd(Rails.root)
+ run_generator([destination_root, "-m", "lib/create_test_dummy_template.rb", "--skip-test-unit"])
+ assert_file "spec/dummy"
+ assert_no_file "test"
+ end
+
+ def test_database_entry_is_assed_by_default_in_full_mode
+ run_generator([destination_root, "--full"])
+ assert_file "test/dummy/config/database.yml", /sqlite/
+ assert_file "Gemfile", /^gem\s+["']sqlite3-ruby["'],\s+:require\s+=>\s+["']sqlite3["']$/
+ end
+
+ def test_config_another_database
+ run_generator([destination_root, "-d", "mysql", "--full"])
+ assert_file "test/dummy/config/database.yml", /mysql/
+ assert_file "Gemfile", /^gem\s+["']mysql2["']$/
+ end
+
+ def test_active_record_is_removed_from_frameworks_if_skip_active_record_is_given
+ run_generator [destination_root, "--skip-active-record"]
+ assert_file "test/dummy/config/application.rb", /#\s+require\s+["']active_record\/railtie["']/
+ end
+
+ def test_ensure_that_skip_active_record_option_is_passed_to_app_generator
+ run_generator [destination_root, "--skip_active_record"]
+ assert_no_file "test/dummy/config/database.yml"
+ assert_no_match /ActiveRecord/, File.read(File.join(destination_root, "test/test_helper.rb"))
+ end
+
+ def test_ensure_that_database_option_is_passed_to_app_generator
+ run_generator [destination_root, "--database", "postgresql"]
+ assert_file "test/dummy/config/database.yml", /postgres/
+ end
+
+ def test_ensure_that_javascript_option_is_passed_to_app_generator
+ run_generator [destination_root, "--javascript", "jquery"]
+ assert_file "test/dummy/public/javascripts/jquery.js"
+ end
+
+ def test_ensure_that_skip_javascript_option_is_passed_to_app_generator
+ run_generator [destination_root, "--skip_javascript"]
+ assert_no_file "test/dummy/public/javascripts/prototype.js"
+ end
+
+ def test_template_from_dir_pwd
+ FileUtils.cd(Rails.root)
+ assert_match /It works from file!/, run_generator([destination_root, "-m", "lib/template.rb"])
+ end
+
+ def test_ensure_that_tests_works
+ run_generator
+ FileUtils.cd destination_root
+ `bundle install`
+ assert_match /1 tests, 1 assertions, 0 failures, 0 errors/, `bundle exec rake test`
+ end
+
+ def test_ensure_that_tests_works_in_full_mode
+ run_generator [destination_root, "--full"]
+ FileUtils.cd destination_root
+ `bundle install`
+ assert_match /2 tests, 2 assertions, 0 failures, 0 errors/, `bundle exec rake test`
+ end
+
+ def test_creating_engine_in_full_mode
+ run_generator [destination_root, "--full"]
+ assert_file "lib/bukkits/engine.rb", /module Bukkits\n class Engine < Rails::Engine\n end\nend/
+ assert_file "lib/bukkits.rb", /require "bukkits\/engine"/
+ end
+
+ def test_being_quiet_while_creating_dummy_application
+ assert_no_match /create\s+config\/application.rb/, run_generator
+ end
+
+ def test_create_mountable_application_with_mountable_option
+ run_generator [destination_root, "--mountable"]
+ assert_file "config/routes.rb", /Bukkits::Engine.routes.draw do/
+ assert_file "lib/bukkits/engine.rb", /isolate_namespace Bukkits/
+ assert_file "test/dummy/config/routes.rb", /mount Bukkits::Engine => "\/bukkits"/
+ assert_file "app/controllers/bukkits/application_controller.rb", /module Bukkits\n class ApplicationController < ActiveController::Base/
+ assert_file "app/helpers/bukkits/application_helper.rb", /module Bukkits\n module ApplicationHelper/
+ end
+
+ def test_passing_dummy_path_as_a_parameter
+ run_generator [destination_root, "--dummy_path", "spec/dummy"]
+ assert_file "spec/dummy"
+ assert_file "spec/dummy/config/application.rb"
+ assert_no_file "test/dummy"
+ end
+
+protected
+
+ def action(*args, &block)
+ silence(:stdout){ generator.send(*args, &block) }
+ end
+
+end
+
+class CustomPluginGeneratorTest < Rails::Generators::TestCase
+ include GeneratorsTestHelper
+ tests Rails::Generators::PluginNewGenerator
+
+ destination File.join(Rails.root, "tmp/bukkits")
+ arguments [destination_root]
+ include SharedCustomGeneratorTests
+
+ def test_overriding_test_framework
+ FileUtils.cd(destination_root)
+ run_generator([destination_root, "-b", "#{Rails.root}/lib/plugin_builders/spec_builder.rb"])
+ assert_file 'spec/spec_helper.rb'
+ assert_file 'spec/dummy'
+ assert_file 'Rakefile', /task :default => :spec/
+ assert_file 'Rakefile', /# spec tasks in rakefile/
+ assert_file 'script/rails', %r{spec/dummy}
+ end
+
+protected
+ def default_files
+ ::DEFAULT_PLUGIN_FILES
+ end
+
+ def builder_class
+ :PluginBuilder
+ end
+
+ def builders_dir
+ "plugin_builders"
+ end
+
+ def action(*args, &block)
+ silence(:stdout){ generator.send(*args, &block) }
+ end
+end
diff --git a/railties/test/generators/shared_generator_tests.rb b/railties/test/generators/shared_generator_tests.rb
new file mode 100644
index 0000000000..d117656fbd
--- /dev/null
+++ b/railties/test/generators/shared_generator_tests.rb
@@ -0,0 +1,187 @@
+module SharedGeneratorTests
+ def setup
+ Rails.application = TestApp::Application
+ super
+ Rails::Generators::AppGenerator.instance_variable_set('@desc', nil)
+ @bundle_command = File.basename(Thor::Util.ruby_command).sub(/ruby/, 'bundle')
+
+ Kernel::silence_warnings do
+ Thor::Base.shell.send(:attr_accessor, :always_force)
+ @shell = Thor::Base.shell.new
+ @shell.send(:always_force=, true)
+ end
+ end
+
+ def teardown
+ super
+ Rails::Generators::AppGenerator.instance_variable_set('@desc', nil)
+ Rails.application = TestApp::Application.instance
+ end
+
+ def test_skeleton_is_created
+ run_generator
+
+ default_files.each{ |path| assert_file path }
+ end
+
+ def test_plugin_new_generate_pretend
+ run_generator ["testapp", "--pretend"]
+
+ default_files.each{ |path| assert_no_file path }
+ end
+
+ def test_invalid_database_option_raises_an_error
+ content = capture(:stderr){ run_generator([destination_root, "-d", "unknown"]) }
+ assert_match /Invalid value for \-\-database option/, content
+ end
+
+ def test_test_unit_is_skipped_if_required
+ run_generator [destination_root, "--skip-test-unit"]
+ assert_no_file "test"
+ end
+
+ def test_options_before_application_name_raises_an_error
+ content = capture(:stderr){ run_generator(["--pretend", destination_root]) }
+ assert_match /Options should be given after the \w+ name. For details run: rails( plugin)? --help\n/, content
+ end
+
+ def test_name_collision_raises_an_error
+ reserved_words = %w[application destroy plugin runner test]
+ reserved_words.each do |reserved|
+ content = capture(:stderr){ run_generator [File.join(destination_root, reserved)] }
+ assert_match /Invalid \w+ name #{reserved}. Please give a name which does not match one of the reserved rails words.\n/, content
+ end
+ end
+
+ def test_name_raises_an_error_if_name_already_used_constant
+ %w{ String Hash Class Module Set Symbol }.each do |ruby_class|
+ content = capture(:stderr){ run_generator [File.join(destination_root, ruby_class)] }
+ assert_match /Invalid \w+ name #{ruby_class}, constant #{ruby_class} is already in use. Please choose another \w+ name.\n/, content
+ end
+ end
+
+ def test_shebang_is_added_to_rails_file
+ run_generator [destination_root, "--ruby", "foo/bar/baz"]
+ assert_file "script/rails", /#!foo\/bar\/baz/
+ end
+
+ def test_shebang_when_is_the_same_as_default_use_env
+ run_generator [destination_root, "--ruby", Thor::Util.ruby_command]
+ assert_file "script/rails", /#!\/usr\/bin\/env/
+ end
+
+ def test_template_raises_an_error_with_invalid_path
+ content = capture(:stderr){ run_generator([destination_root, "-m", "non/existant/path"]) }
+ assert_match /The template \[.*\] could not be loaded/, content
+ assert_match /non\/existant\/path/, content
+ end
+
+ def test_template_is_executed_when_supplied
+ path = "http://gist.github.com/103208.txt"
+ template = %{ say "It works!" }
+ template.instance_eval "def read; self; end" # Make the string respond to read
+
+ generator([destination_root], :template => path).expects(:open).with(path, 'Accept' => 'application/x-thor-template').returns(template)
+ assert_match /It works!/, silence(:stdout){ generator.invoke_all }
+ end
+
+ def test_dev_option
+ generator([destination_root], :dev => true).expects(:run).with("#{@bundle_command} install")
+ silence(:stdout){ generator.invoke_all }
+ rails_path = File.expand_path('../../..', Rails.root)
+ assert_file 'Gemfile', /^gem\s+["']rails["'],\s+:path\s+=>\s+["']#{Regexp.escape(rails_path)}["']$/
+ end
+
+ def test_edge_option
+ generator([destination_root], :edge => true).expects(:run).with("#{@bundle_command} install")
+ silence(:stdout){ generator.invoke_all }
+ assert_file 'Gemfile', %r{^gem\s+["']rails["'],\s+:git\s+=>\s+["']#{Regexp.escape("git://github.com/rails/rails.git")}["']$}
+ end
+
+ def test_template_raises_an_error_with_invalid_path
+ content = capture(:stderr){ run_generator([destination_root, "-m", "non/existant/path"]) }
+ assert_match /The template \[.*\] could not be loaded/, content
+ assert_match /non\/existant\/path/, content
+ end
+
+ def test_template_is_executed_when_supplied
+ path = "http://gist.github.com/103208.txt"
+ template = %{ say "It works!" }
+ template.instance_eval "def read; self; end" # Make the string respond to read
+
+ generator([destination_root], :template => path).expects(:open).with(path, 'Accept' => 'application/x-thor-template').returns(template)
+ assert_match /It works!/, silence(:stdout){ generator.invoke_all }
+ end
+
+ def test_dev_option
+ generator([destination_root], :dev => true).expects(:run).with("#{@bundle_command} install")
+ silence(:stdout){ generator.invoke_all }
+ rails_path = File.expand_path('../../..', Rails.root)
+ assert_file 'Gemfile', /^gem\s+["']rails["'],\s+:path\s+=>\s+["']#{Regexp.escape(rails_path)}["']$/
+ end
+
+ def test_edge_option
+ generator([destination_root], :edge => true).expects(:run).with("#{@bundle_command} install")
+ silence(:stdout){ generator.invoke_all }
+ assert_file 'Gemfile', %r{^gem\s+["']rails["'],\s+:git\s+=>\s+["']#{Regexp.escape("git://github.com/rails/rails.git")}["']$}
+ end
+end
+
+module SharedCustomGeneratorTests
+ def setup
+ Rails.application = TestApp::Application
+ super
+ Rails::Generators::AppGenerator.instance_variable_set('@desc', nil)
+ @bundle_command = File.basename(Thor::Util.ruby_command).sub(/ruby/, 'bundle')
+ end
+
+ def teardown
+ super
+ Rails::Generators::AppGenerator.instance_variable_set('@desc', nil)
+ Object.class_eval do
+ remove_const :AppBuilder if const_defined?(:AppBuilder)
+ remove_const :PluginBuilder if const_defined?(:PluginBuilder)
+ end
+ Rails.application = TestApp::Application.instance
+ end
+
+ def test_builder_option_with_empty_app_builder
+ FileUtils.cd(destination_root)
+ run_generator([destination_root, "-b", "#{Rails.root}/lib/#{builders_dir}/empty_builder.rb"])
+ default_files.each{ |path| assert_no_file path }
+ end
+
+ def test_builder_option_with_simple_plugin_builder
+ FileUtils.cd(destination_root)
+ run_generator([destination_root, "-b", "#{Rails.root}/lib/#{builders_dir}/simple_builder.rb"])
+ (default_files - ['.gitignore']).each{ |path| assert_no_file path }
+ assert_file ".gitignore", "foobar"
+ end
+
+ def test_builder_option_with_relative_path
+ here = File.expand_path(File.dirname(__FILE__))
+ FileUtils.cd(here)
+ run_generator([destination_root, "-b", "../fixtures/lib/#{builders_dir}/simple_builder.rb"])
+ FileUtils.cd(destination_root)
+ (default_files - ['.gitignore']).each{ |path| assert_no_file path }
+ assert_file ".gitignore", "foobar"
+ end
+
+ def test_builder_option_with_tweak_plugin_builder
+ FileUtils.cd(destination_root)
+ run_generator([destination_root, "-b", "#{Rails.root}/lib/#{builders_dir}/tweak_builder.rb"])
+ default_files.each{ |path| assert_file path }
+ assert_file ".gitignore", "foobar"
+ end
+
+ def test_builder_option_with_http
+ path = "http://gist.github.com/103208.txt"
+ template = "class #{builder_class}; end"
+ template.instance_eval "def read; self; end" # Make the string respond to read
+
+ generator([destination_root], :builder => path).expects(:open).with(path, 'Accept' => 'application/x-thor-template').returns(template)
+ capture(:stdout) { generator.invoke_all }
+
+ default_files.each{ |path| assert_no_file path }
+ end
+end
diff --git a/railties/test/railties/engine_test.rb b/railties/test/railties/engine_test.rb
index 4b52260ecc..822be24ef1 100644
--- a/railties/test/railties/engine_test.rb
+++ b/railties/test/railties/engine_test.rb
@@ -685,5 +685,25 @@ module RailtiesTest
assert_equal :haml , generators[:template_engine]
assert_equal :rspec , generators[:test_framework]
end
+
+ test "engine should get default generators with ability to overwrite them" do
+ @plugin.write "lib/bukkits.rb", <<-RUBY
+ module Bukkits
+ class Engine < ::Rails::Engine
+ config.generators.test_framework :rspec
+ end
+ end
+ RUBY
+
+ boot_rails
+ require "#{rails_root}/config/environment"
+
+ generators = Bukkits::Engine.config.generators.options[:rails]
+ assert_equal :active_record, generators[:orm]
+ assert_equal :rspec , generators[:test_framework]
+
+ app_generators = Rails.application.config.generators.options[:rails]
+ assert_equal :test_unit , app_generators[:test_framework]
+ end
end
end