aboutsummaryrefslogtreecommitdiffstats
path: root/railties
diff options
context:
space:
mode:
Diffstat (limited to 'railties')
-rw-r--r--railties/Rakefile3
-rwxr-xr-xrailties/bin/gen42
-rwxr-xr-xrailties/bin/rails13
-rw-r--r--railties/lib/generators.rb62
-rw-r--r--railties/lib/generators/actions.rb274
-rw-r--r--railties/lib/generators/active_record.rb58
-rw-r--r--railties/lib/generators/active_record/migration/migration_generator.rb25
-rw-r--r--railties/lib/generators/active_record/migration/templates/migration.rb11
-rw-r--r--railties/lib/generators/active_record/model/model_generator.rb34
-rw-r--r--railties/lib/generators/active_record/model/templates/migration.rb16
-rw-r--r--railties/lib/generators/active_record/model/templates/model.rb5
-rw-r--r--railties/lib/generators/active_record/observer/observer_generator.rb13
-rw-r--r--railties/lib/generators/active_record/observer/templates/observer.rb2
-rw-r--r--railties/lib/generators/active_record/session_migration/session_migration_generator.rb20
-rw-r--r--railties/lib/generators/active_record/session_migration/templates/migration.rb16
-rw-r--r--railties/lib/generators/base.rb349
-rw-r--r--railties/lib/generators/erb.rb8
-rw-r--r--railties/lib/generators/erb/controller/controller_generator.rb21
-rw-r--r--railties/lib/generators/erb/controller/templates/view.html.erb2
-rw-r--r--railties/lib/generators/erb/mailer/mailer_generator.rb20
-rw-r--r--railties/lib/generators/erb/mailer/templates/view.erb3
-rw-r--r--railties/lib/generators/generated_attribute.rb43
-rw-r--r--railties/lib/generators/named_base.rb108
-rw-r--r--railties/lib/generators/rails/app/USAGE (renamed from railties/lib/rails_generator/generators/applications/app/USAGE)0
-rw-r--r--railties/lib/generators/rails/app/app_generator.rb207
-rw-r--r--railties/lib/generators/rails/app/templates/README (renamed from railties/README)0
-rwxr-xr-xrailties/lib/generators/rails/app/templates/Rakefile (renamed from railties/fresh_rakefile)0
-rw-r--r--railties/lib/generators/rails/app/templates/app/controllers/application_controller.rb (renamed from railties/helpers/application_controller.rb)0
-rw-r--r--railties/lib/generators/rails/app/templates/app/helpers/application_helper.rb (renamed from railties/helpers/application_helper.rb)0
-rw-r--r--railties/lib/generators/rails/app/templates/app/models/.empty_directory (renamed from railties/configs/empty.log)0
-rw-r--r--railties/lib/generators/rails/app/templates/app/views/layouts/.empty_directory (renamed from railties/html/favicon.ico)0
-rw-r--r--railties/lib/generators/rails/app/templates/config/boot.rb (renamed from railties/environments/boot.rb)0
-rw-r--r--railties/lib/generators/rails/app/templates/config/databases/frontbase.yml (renamed from railties/configs/databases/frontbase.yml)0
-rw-r--r--railties/lib/generators/rails/app/templates/config/databases/ibm_db.yml (renamed from railties/configs/databases/ibm_db.yml)0
-rw-r--r--railties/lib/generators/rails/app/templates/config/databases/mysql.yml (renamed from railties/configs/databases/mysql.yml)12
-rw-r--r--railties/lib/generators/rails/app/templates/config/databases/oracle.yml (renamed from railties/configs/databases/oracle.yml)0
-rw-r--r--railties/lib/generators/rails/app/templates/config/databases/postgresql.yml (renamed from railties/configs/databases/postgresql.yml)0
-rw-r--r--railties/lib/generators/rails/app/templates/config/databases/sqlite2.yml (renamed from railties/configs/databases/sqlite2.yml)0
-rw-r--r--railties/lib/generators/rails/app/templates/config/databases/sqlite3.yml (renamed from railties/configs/databases/sqlite3.yml)0
-rw-r--r--railties/lib/generators/rails/app/templates/config/environment.rb (renamed from railties/environments/environment.rb)8
-rw-r--r--railties/lib/generators/rails/app/templates/config/environments/development.rb (renamed from railties/environments/development.rb)0
-rw-r--r--railties/lib/generators/rails/app/templates/config/environments/production.rb (renamed from railties/environments/production.rb)0
-rw-r--r--railties/lib/generators/rails/app/templates/config/environments/test.rb (renamed from railties/environments/test.rb)0
-rw-r--r--railties/lib/generators/rails/app/templates/config/initializers/backtrace_silencers.rb (renamed from railties/configs/initializers/backtrace_silencers.rb)0
-rw-r--r--railties/lib/generators/rails/app/templates/config/initializers/inflections.rb (renamed from railties/configs/initializers/inflections.rb)0
-rw-r--r--railties/lib/generators/rails/app/templates/config/initializers/mime_types.rb (renamed from railties/configs/initializers/mime_types.rb)0
-rw-r--r--railties/lib/generators/rails/app/templates/config/initializers/new_rails_defaults.rb (renamed from railties/configs/initializers/new_rails_defaults.rb)0
-rw-r--r--railties/lib/generators/rails/app/templates/config/initializers/session_store.rb.tt (renamed from railties/configs/initializers/session_store.rb)0
-rw-r--r--railties/lib/generators/rails/app/templates/config/locales/en.yml (renamed from railties/configs/locales/en.yml)0
-rw-r--r--railties/lib/generators/rails/app/templates/config/routes.rb (renamed from railties/configs/routes.rb)0
-rw-r--r--railties/lib/generators/rails/app/templates/db/seeds.rb (renamed from railties/configs/seeds.rb)0
-rw-r--r--railties/lib/generators/rails/app/templates/dispatchers/config.ru (renamed from railties/dispatches/config.ru)0
-rwxr-xr-xrailties/lib/generators/rails/app/templates/dispatchers/dispatch.fcgi (renamed from railties/dispatches/dispatch.fcgi)2
-rwxr-xr-xrailties/lib/generators/rails/app/templates/dispatchers/dispatch.rb (renamed from railties/dispatches/dispatch.rb)2
-rwxr-xr-xrailties/lib/generators/rails/app/templates/dispatchers/gateway.cgi (renamed from railties/dispatches/gateway.cgi)2
-rw-r--r--railties/lib/generators/rails/app/templates/doc/README_FOR_APP (renamed from railties/doc/README_FOR_APP)0
-rw-r--r--railties/lib/generators/rails/app/templates/public/404.html (renamed from railties/html/404.html)0
-rw-r--r--railties/lib/generators/rails/app/templates/public/422.html (renamed from railties/html/422.html)0
-rw-r--r--railties/lib/generators/rails/app/templates/public/500.html (renamed from railties/html/500.html)0
-rw-r--r--railties/lib/generators/rails/app/templates/public/favicon.ico0
-rw-r--r--railties/lib/generators/rails/app/templates/public/images/rails.png (renamed from railties/html/images/rails.png)bin6646 -> 6646 bytes
-rw-r--r--railties/lib/generators/rails/app/templates/public/index.html (renamed from railties/html/index.html)0
-rw-r--r--railties/lib/generators/rails/app/templates/public/javascripts/application.js (renamed from railties/html/javascripts/application.js)0
-rw-r--r--railties/lib/generators/rails/app/templates/public/javascripts/controls.js (renamed from railties/html/javascripts/controls.js)0
-rw-r--r--railties/lib/generators/rails/app/templates/public/javascripts/dragdrop.js (renamed from railties/html/javascripts/dragdrop.js)0
-rw-r--r--railties/lib/generators/rails/app/templates/public/javascripts/effects.js (renamed from railties/html/javascripts/effects.js)0
-rw-r--r--railties/lib/generators/rails/app/templates/public/javascripts/prototype.js (renamed from railties/html/javascripts/prototype.js)0
-rw-r--r--railties/lib/generators/rails/app/templates/public/robots.txt (renamed from railties/html/robots.txt)0
-rw-r--r--railties/lib/generators/rails/app/templates/public/stylesheets/.empty_directory0
-rwxr-xr-xrailties/lib/generators/rails/app/templates/script/about.tt (renamed from railties/bin/about)4
-rwxr-xr-xrailties/lib/generators/rails/app/templates/script/console.tt (renamed from railties/bin/console)2
-rwxr-xr-xrailties/lib/generators/rails/app/templates/script/dbconsole.tt (renamed from railties/bin/dbconsole)2
-rwxr-xr-xrailties/lib/generators/rails/app/templates/script/destroy.tt (renamed from railties/bin/destroy)2
-rwxr-xr-xrailties/lib/generators/rails/app/templates/script/generate.tt (renamed from railties/bin/generate)2
-rwxr-xr-xrailties/lib/generators/rails/app/templates/script/performance/benchmarker.tt (renamed from railties/bin/performance/benchmarker)2
-rwxr-xr-xrailties/lib/generators/rails/app/templates/script/performance/profiler.tt (renamed from railties/bin/performance/profiler)2
-rwxr-xr-xrailties/lib/generators/rails/app/templates/script/plugin.tt (renamed from railties/bin/plugin)2
-rwxr-xr-xrailties/lib/generators/rails/app/templates/script/runner.tt (renamed from railties/bin/runner)2
-rwxr-xr-xrailties/lib/generators/rails/app/templates/script/server.tt (renamed from railties/bin/server)2
-rw-r--r--railties/lib/generators/rails/app/templates/test/fixtures/.empty_directory0
-rw-r--r--railties/lib/generators/rails/app/templates/test/functional/.empty_directory0
-rw-r--r--railties/lib/generators/rails/app/templates/test/integration/.empty_directory0
-rw-r--r--railties/lib/generators/rails/app/templates/test/performance/performance_test.rb (renamed from railties/helpers/performance_test.rb)0
-rw-r--r--railties/lib/generators/rails/app/templates/test/test_helper.rb (renamed from railties/helpers/test_helper.rb)0
-rw-r--r--railties/lib/generators/rails/app/templates/test/unit/.empty_directory0
-rw-r--r--railties/lib/generators/rails/controller/USAGE18
-rw-r--r--railties/lib/generators/rails/controller/controller_generator.rb15
-rw-r--r--railties/lib/generators/rails/controller/templates/controller.rb7
-rw-r--r--railties/lib/generators/rails/helper/USAGE17
-rw-r--r--railties/lib/generators/rails/helper/helper_generator.rb13
-rw-r--r--railties/lib/generators/rails/helper/templates/helper.rb2
-rw-r--r--railties/lib/generators/rails/integration_test/USAGE10
-rw-r--r--railties/lib/generators/rails/integration_test/integration_test_generator.rb11
-rw-r--r--railties/lib/generators/rails/integration_test/templates/integration_test.rb10
-rw-r--r--railties/lib/generators/rails/mailer/USAGE15
-rw-r--r--railties/lib/generators/rails/mailer/mailer_generator.rb14
-rw-r--r--railties/lib/generators/rails/mailer/templates/mailer.rb15
-rw-r--r--railties/lib/generators/rails/metal/USAGE8
-rw-r--r--railties/lib/generators/rails/metal/metal_generator.rb11
-rw-r--r--railties/lib/generators/rails/metal/templates/metal.rb12
-rw-r--r--railties/lib/generators/rails/migration/USAGE29
-rw-r--r--railties/lib/generators/rails/migration/migration_generator.rb8
-rw-r--r--railties/lib/generators/rails/model/USAGE30
-rw-r--r--railties/lib/generators/rails/model/model_generator.rb8
-rw-r--r--railties/lib/generators/rails/model_subclass/model_subclass_generator.rb11
-rw-r--r--railties/lib/generators/rails/observer/USAGE12
-rw-r--r--railties/lib/generators/rails/observer/observer_generator.rb7
-rw-r--r--railties/lib/generators/rails/performance_test/USAGE10
-rw-r--r--railties/lib/generators/rails/performance_test/performance_test_generator.rb11
-rw-r--r--railties/lib/generators/rails/performance_test/templates/performance_test.rb9
-rw-r--r--railties/lib/generators/rails/plugin/USAGE13
-rw-r--r--railties/lib/generators/rails/plugin/plugin_generator.rb41
-rw-r--r--railties/lib/generators/rails/plugin/templates/MIT-LICENSE20
-rw-r--r--railties/lib/generators/rails/plugin/templates/README13
-rw-r--r--railties/lib/generators/rails/plugin/templates/Rakefile23
-rw-r--r--railties/lib/generators/rails/plugin/templates/generators/%file_name%/%file_name%_generator.rb.tt2
-rw-r--r--railties/lib/generators/rails/plugin/templates/generators/%file_name%/USAGE.tt8
-rw-r--r--railties/lib/generators/rails/plugin/templates/generators/%file_name%/templates/.empty_directory0
-rw-r--r--railties/lib/generators/rails/plugin/templates/init.rb1
-rw-r--r--railties/lib/generators/rails/plugin/templates/install.rb1
-rw-r--r--railties/lib/generators/rails/plugin/templates/lib/%file_name%.rb.tt1
-rw-r--r--railties/lib/generators/rails/plugin/templates/tasks/%file_name%_tasks.rake.tt4
-rw-r--r--railties/lib/generators/rails/plugin/templates/uninstall.rb1
-rw-r--r--railties/lib/generators/rails/resource/USAGE23
-rw-r--r--railties/lib/generators/rails/resource/resource_generator.rb32
-rw-r--r--railties/lib/generators/rails/session_migration/USAGE8
-rw-r--r--railties/lib/generators/rails/session_migration/session_migration_generator.rb8
-rw-r--r--railties/lib/generators/test_unit.rb9
-rw-r--r--railties/lib/generators/test_unit/controller/controller_generator.rb13
-rw-r--r--railties/lib/generators/test_unit/controller/templates/functional_test.rb8
-rw-r--r--railties/lib/generators/test_unit/helper/helper_generator.rb13
-rw-r--r--railties/lib/generators/test_unit/helper/templates/helper_test.rb4
-rw-r--r--railties/lib/generators/test_unit/mailer/mailer_generator.rb20
-rw-r--r--railties/lib/generators/test_unit/mailer/templates/fixture3
-rw-r--r--railties/lib/generators/test_unit/mailer/templates/unit_test.rb20
-rw-r--r--railties/lib/generators/test_unit/model/model_generator.rb24
-rw-r--r--railties/lib/generators/test_unit/model/templates/fixtures.yml19
-rw-r--r--railties/lib/generators/test_unit/model/templates/unit_test.rb8
-rw-r--r--railties/lib/generators/test_unit/observer/observer_generator.rb11
-rw-r--r--railties/lib/generators/test_unit/observer/templates/unit_test.rb8
-rw-r--r--railties/lib/generators/test_unit/plugin/plugin_generator.rb11
-rw-r--r--railties/lib/generators/test_unit/plugin/templates/test/%file_name%_test.rb.tt8
-rw-r--r--railties/lib/generators/test_unit/plugin/templates/test/test_helper.rb3
-rw-r--r--railties/lib/rails_generator/generators/applications/app/app_generator.rb263
-rw-r--r--railties/lib/rails_generator/generators/applications/app/scm/git.rb16
-rw-r--r--railties/lib/rails_generator/generators/applications/app/scm/scm.rb8
-rw-r--r--railties/lib/rails_generator/generators/applications/app/scm/svn.rb7
-rw-r--r--railties/lib/rails_generator/generators/applications/app/template_runner.rb401
-rw-r--r--railties/lib/rails_generator/secret_key_generator.rb24
-rw-r--r--railties/test/boot_test.rb2
-rw-r--r--railties/test/generators/actions_test.rb185
-rw-r--r--railties/test/generators/app_generator_test.rb166
-rw-r--r--railties/test/generators/controller_generator_test.rb83
-rw-r--r--railties/test/generators/generators_test_helper.rb88
-rw-r--r--railties/test/generators/helper_generator_test.rb61
-rw-r--r--railties/test/generators/integration_test_generator_test.rb18
-rw-r--r--railties/test/generators/mailer_generator_test.rb54
-rw-r--r--railties/test/generators/metal_generator_test.rb23
-rw-r--r--railties/test/generators/migration_generator_test.rb60
-rw-r--r--railties/test/generators/model_generator_test.rb110
-rw-r--r--railties/test/generators/observer_generator_test.rb35
-rw-r--r--railties/test/generators/performance_test_generator_test.rb18
-rw-r--r--railties/test/generators/plugin_generator_test.rb53
-rw-r--r--railties/test/generators/rails_template_runner_test.rb216
-rw-r--r--railties/test/generators/resource_generator_test.rb95
-rw-r--r--railties/test/generators/session_migration_generator_test.rb24
-rw-r--r--railties/test/rails_generator/generator_test_helper.rb (renamed from railties/test/generators/generator_test_helper.rb)0
-rw-r--r--railties/test/rails_generator/rails_controller_generator_test.rb (renamed from railties/test/generators/rails_controller_generator_test.rb)2
-rw-r--r--railties/test/rails_generator/rails_helper_generator_test.rb (renamed from railties/test/generators/rails_helper_generator_test.rb)0
-rw-r--r--railties/test/rails_generator/rails_mailer_generator_test.rb (renamed from railties/test/generators/rails_mailer_generator_test.rb)2
-rw-r--r--railties/test/rails_generator/rails_model_generator_test.rb (renamed from railties/test/generators/rails_model_generator_test.rb)2
-rw-r--r--railties/test/rails_generator/rails_model_subclass_generator_test.rb (renamed from railties/test/generators/rails_model_subclass_generator_test.rb)4
-rw-r--r--railties/test/rails_generator/rails_resource_generator_test.rb (renamed from railties/test/generators/rails_resource_generator_test.rb)2
-rw-r--r--railties/test/rails_generator/rails_scaffold_generator_test.rb (renamed from railties/test/generators/rails_scaffold_generator_test.rb)2
-rw-r--r--railties/test/secret_key_generation_test.rb38
175 files changed, 3146 insertions, 1013 deletions
diff --git a/railties/Rakefile b/railties/Rakefile
index 61c094150a..35ae15ff0f 100644
--- a/railties/Rakefile
+++ b/railties/Rakefile
@@ -26,7 +26,8 @@ task :default => :test
## below passes. It's not ideal, but at least
## we can see the failures
task :test do
- Dir['test/**/*_test.rb'].all? do |file|
+ dir = ENV["TEST_DIR"] || "**"
+ Dir["test/#{dir}/*_test.rb"].all? do |file|
ruby = File.join(*RbConfig::CONFIG.values_at('bindir', 'RUBY_INSTALL_NAME'))
system(ruby, '-Itest', "-I#{File.dirname(__FILE__)}/../activesupport/lib", file)
end or raise "Failures"
diff --git a/railties/bin/gen b/railties/bin/gen
new file mode 100755
index 0000000000..9f105d2e19
--- /dev/null
+++ b/railties/bin/gen
@@ -0,0 +1,42 @@
+require File.dirname(__FILE__) + '/../lib/ruby_version_check'
+Signal.trap("INT") { puts; exit }
+
+require File.dirname(__FILE__) + '/../lib/rails/version'
+if %w(--version -v).include? ARGV.first
+ puts "Rails #{Rails::VERSION::STRING}"
+ exit(0)
+end
+
+require File.dirname(__FILE__) + '/../lib/generators'
+
+if ARGV.size == 0
+ rails = Rails::Generators.builtin.map do |group, name|
+ name if group == "rails"
+ end
+ rails.compact!
+ rails.sort!
+
+ others = Rails::Generators.builtin.map do |group, name|
+ "#{group}:#{name}" unless rails.include?(name)
+ end.compact
+ others.sort!
+
+ puts "Please select a generator."
+ puts "Builtin: #{rails.join(', ')}."
+ puts "Others: #{others.join(', ')}." unless others.empty?
+
+ exit
+end
+
+Rails::Generators.builtin.each do |group, name|
+ require "generators/#{group}/#{name}/#{name}_generator"
+end
+
+name = ARGV.shift
+
+if klass = Rails::Generators.find_by_namespace(name, "rails")
+ ARGV << "--help" if klass.arguments.any? { |a| a.required? } && ARGV.empty?
+ klass.start
+else
+ puts "Could not find generator #{name}."
+end
diff --git a/railties/bin/rails b/railties/bin/rails
index 6a0c675206..538d0cbc84 100755
--- a/railties/bin/rails
+++ b/railties/bin/rails
@@ -7,14 +7,9 @@ if %w(--version -v).include? ARGV.first
exit(0)
end
-freeze = ARGV.any? { |option| %w(--freeze -f).include?(option) }
+ARGV << "--help" if ARGV.empty?
-app_path = ARGV.first
+require File.dirname(__FILE__) + '/../lib/generators'
+require 'generators/rails/app/app_generator'
-require File.dirname(__FILE__) + '/../lib/rails_generator'
-
-require 'rails_generator/scripts/generate'
-Rails::Generator::Base.use_application_sources!
-Rails::Generator::Scripts::Generate.new.run(ARGV, :generator => 'app')
-
-Dir.chdir(app_path) { `rake rails:freeze:gems`; puts "froze" } if freeze \ No newline at end of file
+Rails::Generators::AppGenerator.start
diff --git a/railties/lib/generators.rb b/railties/lib/generators.rb
new file mode 100644
index 0000000000..fd7d3c9580
--- /dev/null
+++ b/railties/lib/generators.rb
@@ -0,0 +1,62 @@
+activesupport_path = "#{File.dirname(__FILE__)}/../../activesupport/lib"
+$:.unshift(activesupport_path) if File.directory?(activesupport_path)
+require 'active_support/all'
+
+# TODO Use vendored Thor
+require 'rubygems'
+gem 'josevalim-thor'
+require 'thor'
+
+$:.unshift(File.dirname(__FILE__))
+require 'rails/version' unless defined?(Rails::VERSION)
+
+require 'generators/base'
+require 'generators/named_base'
+
+module Rails
+ module Generators
+ def self.builtin
+ Dir[File.dirname(__FILE__) + '/generators/*/*'].collect do |file|
+ file.split('/')[-2, 2]
+ end
+ end
+
+ # Receives a namespace and tries different combinations to find a generator.
+ #
+ # ==== Examples
+ #
+ # lookup_by_namespace :webrat, :rails, :integration
+ #
+ # Will search for the following generators:
+ #
+ # "rails:generators:webrat", "webrat:generators:integration", "webrat"
+ #
+ # If the namespace has ":" included we consider that a absolute namespace
+ # was given and the lookup above does not happen. Just the name is searched.
+ #
+ # Finally, it deals with one kind of shortcut:
+ #
+ # lookup_by_namespace "test_unit:model"
+ #
+ # It will search for generators at:
+ #
+ # "test_unit:generators:model", "test_unit:model"
+ #
+ def self.find_by_namespace(name, base=nil, context=nil)
+ name, attempts = name.to_s, []
+
+ attempts << "#{base}:generators:#{name}" if base && name.count(':') == 0
+ attempts << "#{name}:generators:#{context}" if context && name.count(':') == 0
+ attempts << name.sub(':', ':generators:') if name.count(':') == 1
+ attempts << name
+
+ attempts.each do |namespace|
+ klass, task = Thor::Util.find_by_namespace(namespace)
+ return klass if klass
+ end
+
+ nil
+ end
+ end
+end
+
diff --git a/railties/lib/generators/actions.rb b/railties/lib/generators/actions.rb
new file mode 100644
index 0000000000..080d374a2f
--- /dev/null
+++ b/railties/lib/generators/actions.rb
@@ -0,0 +1,274 @@
+require 'open-uri'
+
+module Rails
+ module Generators
+ module Actions
+
+ # Loads an external file and execute it in the instance binding.
+ #
+ # ==== Parameters
+ # path<String>:: The path to the file to execute. Can be a web address or
+ # a relative path from the source root.
+ #
+ # ==== Examples
+ #
+ # apply "http://gist.github.com/103208"
+ #
+ # apply "recipes/jquery.rb"
+ #
+ def apply(path, log_status=true)
+ path = File.expand_path(path, source_root) unless path =~ /^http\:\/\//
+
+ log :apply, path, log_status
+ instance_eval(open(path).read)
+ log :applied, path, log_status
+ end
+
+ # Install a plugin. You must provide either a Subversion url or Git url.
+ # For a Git-hosted plugin, you can specify if it should be added as a submodule instead of cloned.
+ #
+ # ==== Examples
+ #
+ # plugin 'restful-authentication', :git => 'git://github.com/technoweenie/restful-authentication.git'
+ # plugin 'restful-authentication', :git => 'git://github.com/technoweenie/restful-authentication.git', :submodule => true
+ # plugin 'restful-authentication', :svn => 'svn://svnhub.com/technoweenie/restful-authentication/trunk'
+ #
+ def plugin(name, options)
+ log :plugin, name
+
+ if options[:git] && options[:submodule]
+ in_root do
+ run "git submodule add #{options[:git]} vendor/plugins/#{name}", false
+ end
+ elsif options[:git] || options[:svn]
+ in_root do
+ run_ruby_script "script/plugin install #{options[:svn] || options[:git]}", false
+ end
+ else
+ log "! no git or svn provided for #{name}. Skipping..."
+ end
+ end
+
+ # Adds an entry into config/environment.rb for the supplied gem. If env
+ # is specified, add the gem to the given environment.
+ #
+ # ==== Example
+ #
+ # gem "rspec", :env => :test
+ # gem "technoweenie-restful-authentication", :lib => "restful-authentication", :source => "http://gems.github.com/"
+ #
+ def gem(name, options = {})
+ log :gem, name
+ env = options.delete(:env)
+
+ gems_code = "config.gem '#{name}'"
+
+ if options.any?
+ opts = options.inject([]) {|result, h| result << [":#{h[0]} => #{h[1].inspect.gsub('"',"'")}"] }.sort.join(", ")
+ gems_code << ", #{opts}"
+ end
+
+ environment gems_code, :env => env
+ end
+
+ # Adds a line inside the Initializer block for config/environment.rb.
+ #
+ # If options :env is specified, the line is appended to the corresponding
+ # file in config/environments.
+ #
+ def environment(data=nil, options={}, &block)
+ sentinel = "Rails::Initializer.run do |config|"
+
+ data = block.call if !data && block_given?
+
+ in_root do
+ if options[:env].nil?
+ inject_into_file 'config/environment.rb', "\n #{data}", { :after => sentinel }, false
+ else
+ Array.wrap(options[:env]).each do|env|
+ append_file "config/environments/#{env}.rb", "\n#{data}", false
+ end
+ end
+ end
+ end
+
+ # Run a command in git.
+ #
+ # ==== Examples
+ #
+ # git :init
+ # git :add => "this.file that.rb"
+ # git :add => "onefile.rb", :rm => "badfile.cxx"
+ #
+ def git(command = {})
+ in_root do
+ if command.is_a?(Symbol)
+ run "git #{command}"
+ else
+ command.each do |command, options|
+ run "git #{command} #{options}"
+ end
+ end
+ end
+ end
+
+ # Create a new file in the vendor/ directory. Code can be specified
+ # in a block or a data string can be given.
+ #
+ # ==== Examples
+ #
+ # vendor("sekrit.rb") do
+ # sekrit_salt = "#{Time.now}--#{3.years.ago}--#{rand}--"
+ # "salt = '#{sekrit_salt}'"
+ # end
+ #
+ # vendor("foreign.rb", "# Foreign code is fun")
+ #
+ def vendor(filename, data=nil, &block)
+ log :vendor, filename
+ create_file("vendor/#{filename}", data, false, &block)
+ end
+
+ # Create a new file in the lib/ directory. Code can be specified
+ # in a block or a data string can be given.
+ #
+ # ==== Examples
+ #
+ # lib("crypto.rb") do
+ # "crypted_special_value = '#{rand}--#{Time.now}--#{rand(1337)}--'"
+ # end
+ #
+ # lib("foreign.rb", "# Foreign code is fun")
+ #
+ def lib(filename, data=nil, &block)
+ log :lib, filename
+ create_file("lib/#{filename}", data, false, &block)
+ end
+
+ # Create a new Rakefile with the provided code (either in a block or a string).
+ #
+ # ==== Examples
+ #
+ # rakefile("bootstrap.rake") do
+ # project = ask("What is the UNIX name of your project?")
+ #
+ # <<-TASK
+ # namespace :#{project} do
+ # task :bootstrap do
+ # puts "i like boots!"
+ # end
+ # end
+ # TASK
+ # end
+ #
+ # rakefile("seed.rake", "puts 'im plantin ur seedz'")
+ #
+ def rakefile(filename, data=nil, &block)
+ log :rakefile, filename
+ create_file("lib/tasks/#{filename}", data, false, &block)
+ end
+
+ # Create a new initializer with the provided code (either in a block or a string).
+ #
+ # ==== Examples
+ #
+ # initializer("globals.rb") do
+ # data = ""
+ #
+ # ['MY_WORK', 'ADMINS', 'BEST_COMPANY_EVAR'].each do
+ # data << "#{const} = :entp"
+ # end
+ #
+ # data
+ # end
+ #
+ # initializer("api.rb", "API_KEY = '123456'")
+ #
+ def initializer(filename, data=nil, &block)
+ log :initializer, filename
+ create_file("config/initializers/#{filename}", data, false, &block)
+ end
+
+ # Generate something using a generator from Rails or a plugin.
+ # The second parameter is the argument string that is passed to
+ # the generator or an Array that is joined.
+ #
+ # ==== Example
+ #
+ # generate(:authenticated, "user session")
+ #
+ def generate(what, *args)
+ log :generate, what
+ argument = args.map {|arg| arg.to_s }.flatten.join(" ")
+
+ in_root { run_ruby_script("script/generate #{what} #{argument}", false) }
+ end
+
+ # Runs the supplied rake task
+ #
+ # ==== Example
+ #
+ # rake("db:migrate")
+ # rake("db:migrate", :env => "production")
+ # rake("gems:install", :sudo => true)
+ #
+ def rake(command, options={})
+ log :rake, command
+ env = options[:env] || 'development'
+ sudo = options[:sudo] ? 'sudo ' : ''
+ in_root { run("#{sudo}rake #{command} RAILS_ENV=#{env}", false) }
+ end
+
+ # Just run the capify command in root
+ #
+ # ==== Example
+ #
+ # capify!
+ #
+ def capify!
+ log :capify, ""
+ in_root { run('capify .', false) }
+ end
+
+ # Add Rails to /vendor/rails
+ #
+ # ==== Example
+ #
+ # freeze!
+ #
+ def freeze!(args = {})
+ log :vendor, "rails"
+ in_root { run('rake rails:freeze:edge', false) }
+ end
+
+ # Make an entry in Rails routing file conifg/routes.rb
+ #
+ # === Example
+ #
+ # route "map.root :controller => :welcome"
+ #
+ def route(routing_code)
+ log :route, routing_code
+ sentinel = "ActionController::Routing::Routes.draw do |map|"
+
+ in_root do
+ inject_into_file 'config/routes.rb', "\n #{routing_code}\n", { :after => sentinel }, false
+ end
+ end
+
+ protected
+
+ # Define log for backwards compatibility. If just one argument is sent,
+ # invoke say, otherwise invoke say_status.
+ #
+ def log(*args)
+ if args.size == 1
+ say args.first.to_s
+ else
+ say_status *args
+ end
+ end
+
+ end
+ end
+end
diff --git a/railties/lib/generators/active_record.rb b/railties/lib/generators/active_record.rb
new file mode 100644
index 0000000000..4e585a11e7
--- /dev/null
+++ b/railties/lib/generators/active_record.rb
@@ -0,0 +1,58 @@
+require 'generators/named_base'
+require 'active_record'
+
+module ActiveRecord
+ module Generators
+ module Migration
+
+ # Creates a migration template at the given destination. The difference
+ # to the default template method is that the migration number is appended
+ # to the destination file name.
+ #
+ # The migration number, migration file name, migration class name are
+ # available as instance variables in the template to be rendered.
+ #
+ # ==== Examples
+ #
+ # migration_template "migration.rb", "db/migrate/add_foo_to_bar.rb"
+ #
+ def migration_template(source, destination=nil, log_status=true)
+ destination = File.expand_path(destination || source, self.destination_root)
+
+ migration_dir = File.dirname(destination)
+ @migration_number = next_migration_number(migration_dir)
+ @migration_file_name = File.basename(destination).sub(/\.rb$/, '')
+ @migration_class_name = @migration_file_name.camelize
+
+ if existing = migration_exists?(migration_dir, @migration_file_name)
+ raise Rails::Generators::Error, "Another migration is already named #{@migration_file_name}: #{existing}"
+ end
+
+ destination = File.join(migration_dir, "#{@migration_number}_#{@migration_file_name}.rb")
+ template(source, destination, log_status)
+ end
+
+ protected
+
+ def migration_exists?(dirname, file_name) #:nodoc:
+ Dir.glob("#{dirname}/[0-9]*_*.rb").grep(/\d+_#{file_name}.rb$/).first
+ end
+
+ def current_migration_number(dirname) #:nodoc:
+ Dir.glob("#{dirname}/[0-9]*_*.rb").collect{ |f| f.split("_").first.to_i }.max
+ end
+
+ def next_migration_number(dirname) #:nodoc:
+ if ActiveRecord::Base.timestamped_migrations
+ Time.now.utc.strftime("%Y%m%d%H%M%S")
+ else
+ "%.3d" % (current_migration_number(dirname) + 1)
+ end
+ end
+ end
+
+ class Base < Rails::Generators::NamedBase
+ include Migration
+ end
+ end
+end
diff --git a/railties/lib/generators/active_record/migration/migration_generator.rb b/railties/lib/generators/active_record/migration/migration_generator.rb
new file mode 100644
index 0000000000..95cc34ba42
--- /dev/null
+++ b/railties/lib/generators/active_record/migration/migration_generator.rb
@@ -0,0 +1,25 @@
+require 'generators/active_record'
+
+module ActiveRecord
+ module Generators
+ class MigrationGenerator < Base
+ argument :attributes, :type => :hash, :default => {}, :banner => "field:type field:type"
+
+ def create_migration_file
+ set_local_assigns!
+ migration_template "migration.rb", "db/migrate/#{file_name}.rb"
+ end
+
+ protected
+ attr_reader :migration_action
+
+ def set_local_assigns!
+ if file_name =~ /^(add|remove)_.*_(?:to|from)_(.*)/
+ @migration_action = $1
+ @table_name = $2.pluralize
+ end
+ end
+
+ end
+ end
+end
diff --git a/railties/lib/generators/active_record/migration/templates/migration.rb b/railties/lib/generators/active_record/migration/templates/migration.rb
new file mode 100644
index 0000000000..2851f7cb42
--- /dev/null
+++ b/railties/lib/generators/active_record/migration/templates/migration.rb
@@ -0,0 +1,11 @@
+class <%= @migration_class_name %> < ActiveRecord::Migration
+ def self.up<% attributes.each do |attribute| %>
+ <%= migration_action %>_column :<%= table_name %>, :<%= attribute.name %><% if migration_action == 'add' %>, :<%= attribute.type %><% end -%>
+ <%- end %>
+ end
+
+ def self.down<% attributes.reverse.each do |attribute| %>
+ <%= migration_action == 'add' ? 'remove' : 'add' %>_column :<%= table_name %>, :<%= attribute.name %><% if migration_action == 'remove' %>, :<%= attribute.type %><% end -%>
+ <%- end %>
+ end
+end
diff --git a/railties/lib/generators/active_record/model/model_generator.rb b/railties/lib/generators/active_record/model/model_generator.rb
new file mode 100644
index 0000000000..59310f6c61
--- /dev/null
+++ b/railties/lib/generators/active_record/model/model_generator.rb
@@ -0,0 +1,34 @@
+require 'generators/active_record'
+
+module ActiveRecord
+ module Generators
+ class ModelGenerator < Base
+ argument :attributes, :type => :hash, :default => {}, :banner => "field:type field:type"
+
+ check_class_collision
+
+ conditional_class_options :migration, :timestamps
+
+ class_option :parent, :type => :string,
+ :desc => "The parent class for the generated model"
+
+ def create_model_file
+ template 'model.rb', File.join('app/models', class_path, "#{file_name}.rb")
+ end
+
+ def create_migration_file
+ if options[:migration] && options[:parent].nil?
+ file_name = "create_#{file_path.gsub(/\//, '_').pluralize}"
+ migration_template "migration.rb", "db/migrate/#{file_name}.rb"
+ end
+ end
+
+ protected
+
+ def parent_class_name
+ options[:parent] || "ActiveRecord::Base"
+ end
+
+ end
+ end
+end
diff --git a/railties/lib/generators/active_record/model/templates/migration.rb b/railties/lib/generators/active_record/model/templates/migration.rb
new file mode 100644
index 0000000000..542e9db2fc
--- /dev/null
+++ b/railties/lib/generators/active_record/model/templates/migration.rb
@@ -0,0 +1,16 @@
+class <%= @migration_class_name %> < ActiveRecord::Migration
+ def self.up
+ create_table :<%= table_name %> do |t|
+<% for attribute in attributes -%>
+ t.<%= attribute.type %> :<%= attribute.name %>
+<% end -%>
+<% if options[:timestamps] %>
+ t.timestamps
+<% end -%>
+ end
+ end
+
+ def self.down
+ drop_table :<%= table_name %>
+ end
+end
diff --git a/railties/lib/generators/active_record/model/templates/model.rb b/railties/lib/generators/active_record/model/templates/model.rb
new file mode 100644
index 0000000000..21ae29e9f2
--- /dev/null
+++ b/railties/lib/generators/active_record/model/templates/model.rb
@@ -0,0 +1,5 @@
+class <%= class_name %> < <%= parent_class_name.classify %>
+<% attributes.select {|attr| attr.reference? }.each do |attribute| -%>
+ belongs_to :<%= attribute.name %>
+<% end -%>
+end
diff --git a/railties/lib/generators/active_record/observer/observer_generator.rb b/railties/lib/generators/active_record/observer/observer_generator.rb
new file mode 100644
index 0000000000..fa51c23336
--- /dev/null
+++ b/railties/lib/generators/active_record/observer/observer_generator.rb
@@ -0,0 +1,13 @@
+require 'generators/active_record'
+
+module ActiveRecord
+ module Generators
+ class ObserverGenerator < Base
+ check_class_collision :suffix => "Observer"
+
+ def create_observer_file
+ template 'observer.rb', File.join('app/models', class_path, "#{file_name}_observer.rb")
+ end
+ end
+ end
+end
diff --git a/railties/lib/generators/active_record/observer/templates/observer.rb b/railties/lib/generators/active_record/observer/templates/observer.rb
new file mode 100644
index 0000000000..b9a3004161
--- /dev/null
+++ b/railties/lib/generators/active_record/observer/templates/observer.rb
@@ -0,0 +1,2 @@
+class <%= class_name %>Observer < ActiveRecord::Observer
+end
diff --git a/railties/lib/generators/active_record/session_migration/session_migration_generator.rb b/railties/lib/generators/active_record/session_migration/session_migration_generator.rb
new file mode 100644
index 0000000000..d60da5c0a5
--- /dev/null
+++ b/railties/lib/generators/active_record/session_migration/session_migration_generator.rb
@@ -0,0 +1,20 @@
+require 'generators/active_record'
+
+module ActiveRecord
+ module Generators
+ class SessionMigrationGenerator < Base
+ argument :name, :type => :string, :default => "add_sessions_table"
+
+ def create_migration_file
+ migration_template "migration.rb", "db/migrate/#{file_name}.rb"
+ end
+
+ protected
+
+ def session_table_name
+ ActiveRecord::Base.pluralize_table_names ? 'session'.pluralize : 'session'
+ end
+
+ end
+ end
+end
diff --git a/railties/lib/generators/active_record/session_migration/templates/migration.rb b/railties/lib/generators/active_record/session_migration/templates/migration.rb
new file mode 100644
index 0000000000..19811d9455
--- /dev/null
+++ b/railties/lib/generators/active_record/session_migration/templates/migration.rb
@@ -0,0 +1,16 @@
+class <%= @migration_class_name %> < ActiveRecord::Migration
+ def self.up
+ create_table :<%= session_table_name %> do |t|
+ t.string :session_id, :null => false
+ t.text :data
+ t.timestamps
+ end
+
+ add_index :<%= session_table_name %>, :session_id
+ add_index :<%= session_table_name %>, :updated_at
+ end
+
+ def self.down
+ drop_table :<%= session_table_name %>
+ end
+end
diff --git a/railties/lib/generators/base.rb b/railties/lib/generators/base.rb
new file mode 100644
index 0000000000..c1a384647c
--- /dev/null
+++ b/railties/lib/generators/base.rb
@@ -0,0 +1,349 @@
+require 'generators/actions'
+
+module Rails
+ module Generators
+ DEFAULTS = {
+ :fixture => true,
+ :helper => true,
+ :migration => true,
+ :orm => 'active_record',
+ :resource_controller => 'controller',
+ :test_framework => 'test_unit',
+ :template_engine => 'erb',
+ :timestamps => true
+ }
+
+ ALIASES = {
+ :fixture_replacement => '-r',
+ :orm => '-o',
+ :resource_controller => '-c',
+ :test_framework => '-t',
+ :template_engine => '-e'
+ }
+
+ class Error < Thor::Error
+ end
+
+ class Base < Thor::Group
+ include Rails::Generators::Actions
+ include Thor::Actions
+
+ # Automatically sets the source root based on the class name.
+ #
+ def self.source_root
+ @source_root ||= File.expand_path(File.join(File.dirname(__FILE__), base_name, generator_name, 'templates'))
+ end
+
+ # Tries to get the description from a USAGE file one folder above the source
+ # root otherwise uses a default description.
+ #
+ def self.desc(description=nil)
+ return super if description
+ usage = File.expand_path(File.join(source_root, "..", "USAGE"))
+
+ @desc ||= if File.exist?(usage)
+ File.read(usage)
+ else
+ "Description:\n Create #{base_name.humanize.downcase} files for #{generator_name} generator."
+ end
+ end
+
+ # Convenience method to get the namespace from the class name. It's the
+ # same as Thor default except that the Generator at the end of the class
+ # is removed.
+ #
+ def self.namespace(name=nil)
+ return super if name
+ @namespace ||= super.sub(/_generator$/, '')
+ end
+
+ # Invoke a generator based on the value supplied by the user to the
+ # given option named "name". A class option is created when this method
+ # is invoked and you can set a hash to customize it, although type and
+ # default values cannot be given.
+ #
+ # ==== Examples
+ #
+ # class ControllerGenerator < Rails::Generators::Base
+ # hook_for :test_framework, :aliases => "-t"
+ # end
+ #
+ # The example above will create a test framework option and will invoke
+ # a generator based on the user supplied value.
+ #
+ # For example, if the user invoke the controller generator as:
+ #
+ # ruby script/generate controller Account --test-framework=test_unit
+ #
+ # The controller generator will then try to invoke the following generators:
+ #
+ # "rails:generators:test_unit", "test_unit:generators:controller", "test_unit"
+ #
+ # In this case, the "test_unit:generators:controller" is available and is
+ # invoked. This allows any test framework to hook into Rails as long as it
+ # provides any of the hooks above.
+ #
+ # Finally, if the user don't want to use any test framework, he can do:
+ #
+ # ruby script/generate controller Account --skip-test-framework
+ #
+ # Or similarly:
+ #
+ # ruby script/generate controller Account --no-test-framework
+ #
+ # ==== Custom invocations
+ #
+ # You can also supply a block to hook for to customize how the hook is
+ # going to be invoked. The block receives two parameters, an instance
+ # of the current class and the klass to be invoked.
+ #
+ # For example, in the resource generator, the controller should be invoked
+ # with a pluralized class name. By default, it is invoked with the same
+ # name as the resource generator, which is singular. To change this, we
+ # can give a block to customize how the controller can be invoked.
+ #
+ # hook_for :resource_controller do |instance, controller|
+ # instance.invoke controller, [ instance.name.pluralize ]
+ # end
+ #
+ def self.hook_for(*names, &block)
+ default_class_options(*names)
+ options = names.extract_options!
+ verbose = options.fetch(:verbose, :blue)
+
+ names.each do |name|
+ invocations << [ name, base_name, generator_name ]
+ invocation_blocks[name] = block if block_given?
+
+ class_eval <<-METHOD, __FILE__, __LINE__
+ def invoke_for_#{name}
+ return unless options[#{name.inspect}]
+
+ klass = Rails::Generators.find_by_namespace(options[#{name.inspect}],
+ #{base_name.inspect}, #{generator_name.inspect})
+
+ if klass
+ say_status :invoke, options[#{name.inspect}], #{verbose.inspect}
+ invoke_class_with_block #{name.inspect}, klass
+ else
+ say "Could not find and invoke '\#{options[#{name.inspect}]}'."
+ end
+ end
+ METHOD
+ end
+ end
+
+ # Invoke a generator with the given name if the user requires it. The
+ # difference to hook_for is that the class option here is boolean
+ # and the generator invoked is not based on user input.
+ #
+ # A class option is created when this method is invoked and you can set
+ # a hash to customize it, although type and default values cannot be
+ # given.
+ #
+ # ==== Examples
+ #
+ # class ControllerGenerator < Rails::Generators::Base
+ # invoke_if :webrat, :aliases => "-w"
+ # end
+ #
+ # The example above will create a helper option and will be invoked
+ # when the user requires so:
+ #
+ # ruby script/generate controller Account --webrat
+ #
+ # The controller generator will then try to invoke the following generators:
+ #
+ # "rails:generators:webrat", "webrat:generators:controller", "webrat"
+ #
+ # ==== Custom invocations
+ #
+ # This method accepts custom invocations as in hook_for. Check hook_for
+ # for usage and examples.
+ #
+ def self.invoke_if(*names, &block)
+ conditional_class_options(*names)
+ options = names.extract_options!
+ verbose = options.fetch(:verbose, :blue)
+
+ names.each do |name|
+ invocations << [ name, base_name, generator_name ]
+ invocation_blocks[name] = block if block_given?
+
+ class_eval <<-METHOD, __FILE__, __LINE__
+ def invoke_if_#{name}
+ return unless options[#{name.inspect}]
+
+ klass = Rails::Generators.find_by_namespace(#{name.inspect},
+ #{base_name.inspect}, #{generator_name.inspect})
+
+ if klass
+ say_status :invoke, #{name.inspect}, #{verbose.inspect}
+ invoke_class_with_block #{name.inspect}, klass
+ else
+ say "Could not find and invoke '#{name}'."
+ end
+ end
+ METHOD
+ end
+ end
+
+ protected
+
+ # This is the common method that both hook_for and invoke_if use to
+ # invoke a class. It searches for a block in the invocation blocks
+ # in case the user wants to customize how the class is invoked.
+ #
+ def invoke_class_with_block(name, klass) #:nodoc:
+ if block = self.class.invocation_blocks[name]
+ block.call(self, klass)
+ else
+ invoke klass
+ end
+ end
+
+ # Check whether the given class names are already taken by user
+ # application or Ruby on Rails.
+ #
+ def class_collisions(*class_names)
+ return unless behavior == :invoke
+
+ class_names.flatten.each do |class_name|
+ class_name = class_name.to_s
+ next if class_name.strip.empty?
+
+ # Split the class from its module nesting
+ nesting = class_name.split('::')
+ last_name = nesting.pop
+
+ # Hack to limit const_defined? to non-inherited on 1.9
+ extra = []
+ extra << false unless Object.method(:const_defined?).arity == 1
+
+ # Extract the last Module in the nesting
+ last = nesting.inject(Object) do |last, nest|
+ break unless last.const_defined?(nest, *extra)
+ last.const_get(nest)
+ end
+
+ if last && last.const_defined?(last_name.camelize, *extra)
+ raise Error, "The name '#{class_name}' is either already used in your application " <<
+ "or reserved by Ruby on Rails. Please choose an alternative and run " <<
+ "this generator again."
+ end
+ end
+ end
+
+ # Use Rails default banner.
+ #
+ def self.banner
+ "#{$0} #{generator_name} #{self.arguments.map(&:usage).join(' ')} [options]"
+ end
+
+ # Sets the base_name taking into account the current class namespace.
+ #
+ def self.base_name
+ @base_name ||= self.name.split('::').first.underscore
+ end
+
+ # Removes the namespaces and get the generator name. For example,
+ # Rails::Generators::MetalGenerator will return "metal" as generator name.
+ #
+ def self.generator_name
+ @generator_name ||= begin
+ klass_name = self.name.split('::').last
+ klass_name.sub!(/Generator$/, '')
+ klass_name.underscore
+ end
+ end
+
+ # Stores invocations for this class merging with superclass values.
+ #
+ def self.invocations #:nodoc:
+ @invocations ||= from_superclass(:invocations, [])
+ end
+
+ # Stores invocation blocks used on hook_for and invoke_if.
+ #
+ def self.invocation_blocks #:nodoc:
+ @invocation_blocks ||= from_superclass(:invocation_blocks, {})
+ end
+
+ # Creates a conditional class option with type boolean, default value
+ # lookup and default description.
+ #
+ def self.conditional_class_options(*names)
+ default_options = names.extract_options!
+
+ names.each do |name|
+ options = default_options.dup
+ options[:desc] ||= "Indicates when to generate #{name.to_s.humanize.downcase}"
+ class_option name, options.merge!(:type => :boolean, :default => DEFAULTS[name] || false)
+ end
+ end
+
+ # Creates a class option with type default, banner, alias lookup and
+ # description. Used internally by hook_for (ie, not part of plugin API).
+ #
+ def self.default_class_options(*names) #:nodoc:
+ default_options = names.extract_options!
+
+ names.each do |name|
+ options = default_options.dup
+ options[:desc] ||= "#{name.to_s.humanize} to be invoked"
+ options[:banner] ||= "NAME"
+ options[:aliases] ||= ALIASES[name]
+ class_option name, options.merge!(:type => :default, :default => DEFAULTS[name])
+ end
+ end
+
+ # Overwrite class options help to allow invoked generators options to be
+ # shown when invoking a generator. Only first level options and options
+ # that belongs to the default group are shown.
+ #
+ def self.class_options_help(shell, ungrouped_name=nil, extra_group=nil)
+ klass_options = Thor::CoreExt::OrderedHash.new
+
+ invocations.each do |args|
+ name, base, generator = args
+ option = class_options[name]
+
+ klass_name = option.type == :boolean ? name : option.default
+ next unless klass_name
+
+ klass = Rails::Generators.find_by_namespace(klass_name, base, generator)
+ next unless klass
+
+ human_name = klass_name.to_s.classify
+
+ klass_options[human_name] ||= []
+ klass_options[human_name] += klass.class_options.values.select do |option|
+ class_options[option.human_name.to_sym].nil? && option.group.nil?
+ end
+ end
+
+ klass_options.merge!(extra_group) if extra_group
+ super(shell, ungrouped_name, klass_options)
+ end
+
+ # Small macro to add ruby as an option to the generator with proper
+ # default value plus an instance helper method called shebang.
+ #
+ def self.add_shebang_option!
+ require 'rbconfig'
+ default = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])
+
+ class_option :ruby, :type => :string, :aliases => "-r", :default => default,
+ :desc => "Path to the Ruby binary of your choice", :banner => "PATH"
+
+ class_eval <<-METHOD, __FILE__, __LINE__
+ protected
+ def shebang
+ "#!\#{options[:ruby] || "/usr/bin/env ruby"}"
+ end
+ METHOD
+ end
+
+ end
+ end
+end
diff --git a/railties/lib/generators/erb.rb b/railties/lib/generators/erb.rb
new file mode 100644
index 0000000000..da99cec895
--- /dev/null
+++ b/railties/lib/generators/erb.rb
@@ -0,0 +1,8 @@
+require 'generators/named_base'
+
+module Erb
+ module Generators
+ class Base < Rails::Generators::NamedBase
+ end
+ end
+end
diff --git a/railties/lib/generators/erb/controller/controller_generator.rb b/railties/lib/generators/erb/controller/controller_generator.rb
new file mode 100644
index 0000000000..706c92cb91
--- /dev/null
+++ b/railties/lib/generators/erb/controller/controller_generator.rb
@@ -0,0 +1,21 @@
+require 'generators/erb'
+
+module Erb
+ module Generators
+ class ControllerGenerator < Base
+ argument :actions, :type => :array, :default => [], :banner => "action action"
+
+ def create_view_files
+ base_path = File.join('app', 'views', class_path, file_name)
+ empty_directory base_path
+
+ actions.each do |action|
+ @action = action
+ @path = File.join(base_path, "#{action}.html.erb")
+
+ template 'view.html.erb', @path
+ end
+ end
+ end
+ end
+end
diff --git a/railties/lib/generators/erb/controller/templates/view.html.erb b/railties/lib/generators/erb/controller/templates/view.html.erb
new file mode 100644
index 0000000000..cd54d13d83
--- /dev/null
+++ b/railties/lib/generators/erb/controller/templates/view.html.erb
@@ -0,0 +1,2 @@
+<h1><%= class_name %>#<%= @action %></h1>
+<p>Find me in <%= @path %></p>
diff --git a/railties/lib/generators/erb/mailer/mailer_generator.rb b/railties/lib/generators/erb/mailer/mailer_generator.rb
new file mode 100644
index 0000000000..398ab46dd8
--- /dev/null
+++ b/railties/lib/generators/erb/mailer/mailer_generator.rb
@@ -0,0 +1,20 @@
+require 'generators/erb'
+
+module Erb
+ module Generators
+ class MailerGenerator < Base
+ argument :actions, :type => :array, :default => [], :banner => "method method"
+
+ def create_view_folder
+ empty_directory File.join("app", "views", file_path)
+ end
+
+ def create_view_files
+ actions.each do |action|
+ @action, @path = action, File.join(file_path, action)
+ template "view.erb", File.join("app", "views", "#{@path}.erb")
+ end
+ end
+ end
+ end
+end
diff --git a/railties/lib/generators/erb/mailer/templates/view.erb b/railties/lib/generators/erb/mailer/templates/view.erb
new file mode 100644
index 0000000000..fcce7bd805
--- /dev/null
+++ b/railties/lib/generators/erb/mailer/templates/view.erb
@@ -0,0 +1,3 @@
+<%= class_name %>#<%= @action %>
+
+Find me in app/views/<%= @path %>
diff --git a/railties/lib/generators/generated_attribute.rb b/railties/lib/generators/generated_attribute.rb
new file mode 100644
index 0000000000..7cd1fed8a4
--- /dev/null
+++ b/railties/lib/generators/generated_attribute.rb
@@ -0,0 +1,43 @@
+module Rails
+ module Generators
+ class GeneratedAttribute
+ attr_accessor :name, :type
+
+ def initialize(name, type)
+ @name, @type = name, type.to_sym
+ end
+
+ def field_type
+ @field_type ||= case type
+ when :integer, :float, :decimal then :text_field
+ when :datetime, :timestamp, :time then :datetime_select
+ when :date then :date_select
+ when :string then :text_field
+ when :text then :text_area
+ when :boolean then :check_box
+ else
+ :text_field
+ end
+ end
+
+ def default
+ @default ||= case type
+ when :integer then 1
+ when :float then 1.5
+ when :decimal then "9.99"
+ when :datetime, :timestamp, :time then Time.now.to_s(:db)
+ when :date then Date.today.to_s(:db)
+ when :string then "MyString"
+ when :text then "MyText"
+ when :boolean then false
+ else
+ ""
+ end
+ end
+
+ def reference?
+ [ :references, :belongs_to ].include?(self.type)
+ end
+ end
+ end
+end
diff --git a/railties/lib/generators/named_base.rb b/railties/lib/generators/named_base.rb
new file mode 100644
index 0000000000..9538931a6e
--- /dev/null
+++ b/railties/lib/generators/named_base.rb
@@ -0,0 +1,108 @@
+require 'generators/base'
+require 'generators/generated_attribute'
+
+module Rails
+ module Generators
+ class NamedBase < Base
+ argument :name, :type => :string
+
+ attr_reader :class_name, :singular_name, :plural_name, :table_name,
+ :class_path, :file_path, :class_nesting, :class_nesting_depth
+
+ alias :file_name :singular_name
+
+ class << self
+ # Add a class collisions name to be checked on class initialization. You
+ # can supply a hash with a :prefix or :suffix to be tested.
+ #
+ # ==== Examples
+ #
+ # check_class_collision :suffix => "Observer"
+ #
+ # If the generator is invoked with class name Admin, it will check for
+ # the presence of "AdminObserver".
+ #
+ def check_class_collision(options={})
+ @class_collisions = options
+ end
+
+ # Returns the class collisions for this class and retreives one from
+ # superclass. The from_superclass method used below is from Thor.
+ #
+ def class_collisions #:nodoc:
+ @class_collisions ||= from_superclass(:class_collisions, nil)
+ end
+ end
+
+ def initialize(*args) #:nodoc:
+ super
+ assign_names!(self.name)
+ parse_attributes! if respond_to?(:attributes)
+
+ if self.class.class_collisions
+ value = add_prefix_and_suffix(class_name, self.class.class_collisions)
+ class_collisions(value)
+ end
+ end
+
+ protected
+
+ def assign_names!(given_name) #:nodoc:
+ self.name, @class_path, @file_path, @class_nesting, @class_nesting_depth = extract_modules(given_name)
+ @class_name_without_nesting, @singular_name, @plural_name = inflect_names(self.name)
+
+ @table_name = if !defined?(ActiveRecord::Base) || ActiveRecord::Base.pluralize_table_names
+ plural_name
+ else
+ singular_name
+ end
+ @table_name.gsub! '/', '_'
+
+ if @class_nesting.empty?
+ @class_name = @class_name_without_nesting
+ else
+ @table_name = @class_nesting.underscore << "_" << @table_name
+ @class_name = "#{@class_nesting}::#{@class_name_without_nesting}"
+ end
+ end
+
+ # Convert attributes hash into an array with GeneratedAttribute objects.
+ #
+ def parse_attributes! #:nodoc:
+ self.attributes = (attributes || {}).map do |name, type|
+ Rails::Generators::GeneratedAttribute.new(name, type)
+ end
+ end
+
+ # Extract modules from filesystem-style or ruby-style path. Both
+ # good/fun/stuff and Good::Fun::Stuff produce the same results.
+ #
+ def extract_modules(name) #:nodoc:
+ modules = name.include?('/') ? name.split('/') : name.split('::')
+ name = modules.pop
+ path = modules.map { |m| m.underscore }
+
+ file_path = (path + [name.underscore]).join('/')
+ nesting = modules.map { |m| m.camelize }.join('::')
+
+ [name, path, file_path, nesting, modules.size]
+ end
+
+ # Receives name and return camelized, underscored and pluralized names.
+ #
+ def inflect_names(name) #:nodoc:
+ camel = name.camelize
+ under = camel.underscore
+ plural = under.pluralize
+ [camel, under, plural]
+ end
+
+ # Receives a name and add suffix and prefix values frrm hash.
+ #
+ def add_prefix_and_suffix(name, hash) #:nodoc:
+ "#{hash[:prefix]}#{name}#{hash[:suffix]}"
+ end
+
+ end
+ end
+end
diff --git a/railties/lib/rails_generator/generators/applications/app/USAGE b/railties/lib/generators/rails/app/USAGE
index 36d6061a59..36d6061a59 100644
--- a/railties/lib/rails_generator/generators/applications/app/USAGE
+++ b/railties/lib/generators/rails/app/USAGE
diff --git a/railties/lib/generators/rails/app/app_generator.rb b/railties/lib/generators/rails/app/app_generator.rb
new file mode 100644
index 0000000000..6bd464a16c
--- /dev/null
+++ b/railties/lib/generators/rails/app/app_generator.rb
@@ -0,0 +1,207 @@
+require 'digest/md5'
+require 'active_support/secure_random'
+
+module Rails::Generators
+ class AppGenerator < Base
+ DATABASES = %w( mysql oracle postgresql sqlite2 sqlite3 frontbase ibm_db )
+ 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 :freeze, :type => :boolean, :aliases => "-F", :default => false,
+ :desc => "Freeze Rails in vendor/rails from the gems"
+
+ class_option :template, :type => :string, :aliases => "-m",
+ :desc => "Path to an application template (can be a filesystem path or URL)."
+
+ class_option :with_dispatchers, :type => :boolean, :aliases => "-D", :default => false,
+ :desc => "Add CGI/FastCGI/mod_ruby dispatchers code"
+
+ class_option :skip_activerecord, :type => :boolean, :aliases => "-A", :default => false,
+ :desc => "Skip ActiveRecord files"
+
+ class_option :skip_testunit, :type => :boolean, :aliases => "-U", :default => false,
+ :desc => "Skip TestUnit files"
+
+ class_option :skip_prototype, :type => :boolean, :aliases => "-P", :default => false,
+ :desc => "Skip Prototype files"
+
+ # Add 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)
+ super
+ if !options[:no_activerecord] && !DATABASES.include?(options[:database])
+ raise Error, "Invalid value for --database option. Supported for preconfiguration are: #{DATABASES.join(", ")}."
+ end
+ end
+
+ def create_root
+ self.root = File.expand_path(app_path, root)
+ empty_directory '.'
+
+ app_name # Sets the app name
+ FileUtils.cd(root)
+ end
+
+ def create_root_files
+ copy_file "Rakefile"
+ copy_file "README"
+ end
+
+ def create_app_files
+ directory "app"
+ end
+
+ def create_config_files
+ empty_directory "config"
+
+ inside "config" do
+ copy_file "boot.rb"
+ copy_file "routes.rb"
+ template "environment.rb"
+
+ directory "environments"
+ directory "initializers"
+ directory "locales"
+ end
+ end
+
+ def create_activerecord_files
+ return if options[:skip_activerecord]
+ template "config/databases/#{options[:database]}.yml", "config/database.yml"
+ end
+
+ def create_db_files
+ directory "db"
+ end
+
+ def create_doc_files
+ directory "doc"
+ end
+
+ def create_lib_files
+ empty_directory "lib"
+ empty_directory "lib/tasks"
+ end
+
+ def create_log_files
+ empty_directory "log"
+
+ inside "log" do
+ %w( server production development test ).each do |file|
+ create_file "#{file}.log"
+ chmod "#{file}.log", 0666, false
+ end
+ end
+ end
+
+ def create_public_files
+ directory "public", "public", false # Non-recursive. Do small steps, so anyone can overwrite it.
+ end
+
+ def create_dispatch_files
+ return unless options[:with_dispatchers]
+ copy_file "dispatchers/config.ru", "config.ru"
+
+ template "dispatchers/dispatch.rb", "public/dispatch.rb"
+ chmod "public/dispatch.rb", 0755, false
+
+ template "dispatchers/dispatch.rb", "public/dispatch.cgi"
+ chmod "public/dispatch.cgi", 0755, false
+
+ template "dispatchers/dispatch.fcgi", "public/dispatch.fcgi"
+ chmod "public/dispatch.fcgi", 0755, false
+ end
+
+ def create_public_image_files
+ directory "public/images"
+ end
+
+ def create_public_stylesheets_files
+ directory "public/stylesheets"
+ end
+
+ def create_prototype_files
+ return if options[:skip_prototype]
+ directory "public/javascripts"
+ end
+
+ def create_script_files
+ directory "script"
+ chmod "script", 0755, false
+ end
+
+ def create_test_files
+ return if options[:skip_testunit]
+ directory "test"
+ end
+
+ def create_tmp_files
+ empty_directory "tmp"
+
+ inside "tmp" do
+ %w(sessions sockets cache pids).each do |dir|
+ empty_directory dir
+ end
+ end
+ end
+
+ def create_vendor_files
+ empty_directory "vendor/plugins"
+ end
+
+ def apply_rails_template
+ apply options[:template] if options[:template]
+ rescue LoadError, Errno::ENOENT => e
+ raise Error, "The template [#{options[:template]}] could not be loaded. Error: #{e}"
+ end
+
+ def freeze?
+ freeze! if options[:freeze]
+ end
+
+ protected
+
+ # Define file as an alias to create_file for backwards compatibility.
+ # TODO Add deprecation warning?
+ #
+ def file(*args, &block)
+ create_file(*args, &block)
+ end
+
+ def app_name
+ @app_name ||= File.basename(root)
+ end
+
+ def app_secret
+ ActiveSupport::SecureRandom.hex(64)
+ end
+
+ def self.banner
+ "#{$0} #{self.arguments.map(&:usage).join(' ')} [options]"
+ end
+
+ def mysql_socket
+ @mysql_socket ||= [
+ "/tmp/mysql.sock", # default
+ "/var/run/mysqld/mysqld.sock", # debian/gentoo
+ "/var/tmp/mysql.sock", # freebsd
+ "/var/lib/mysql/mysql.sock", # fedora
+ "/opt/local/lib/mysql/mysql.sock", # fedora
+ "/opt/local/var/run/mysqld/mysqld.sock", # mac + darwinports + mysql
+ "/opt/local/var/run/mysql4/mysqld.sock", # mac + darwinports + mysql4
+ "/opt/local/var/run/mysql5/mysqld.sock", # mac + darwinports + mysql5
+ "/opt/lampp/var/mysql/mysql.sock" # xampp for linux
+ ].find { |f| File.exist?(f) } unless RUBY_PLATFORM =~ /(:?mswin|mingw)/
+ end
+ end
+end
diff --git a/railties/README b/railties/lib/generators/rails/app/templates/README
index 37ec8ea211..37ec8ea211 100644
--- a/railties/README
+++ b/railties/lib/generators/rails/app/templates/README
diff --git a/railties/fresh_rakefile b/railties/lib/generators/rails/app/templates/Rakefile
index 3bb0e8592a..3bb0e8592a 100755
--- a/railties/fresh_rakefile
+++ b/railties/lib/generators/rails/app/templates/Rakefile
diff --git a/railties/helpers/application_controller.rb b/railties/lib/generators/rails/app/templates/app/controllers/application_controller.rb
index 6635a3f487..6635a3f487 100644
--- a/railties/helpers/application_controller.rb
+++ b/railties/lib/generators/rails/app/templates/app/controllers/application_controller.rb
diff --git a/railties/helpers/application_helper.rb b/railties/lib/generators/rails/app/templates/app/helpers/application_helper.rb
index 22a7940eb2..22a7940eb2 100644
--- a/railties/helpers/application_helper.rb
+++ b/railties/lib/generators/rails/app/templates/app/helpers/application_helper.rb
diff --git a/railties/configs/empty.log b/railties/lib/generators/rails/app/templates/app/models/.empty_directory
index e69de29bb2..e69de29bb2 100644
--- a/railties/configs/empty.log
+++ b/railties/lib/generators/rails/app/templates/app/models/.empty_directory
diff --git a/railties/html/favicon.ico b/railties/lib/generators/rails/app/templates/app/views/layouts/.empty_directory
index e69de29bb2..e69de29bb2 100644
--- a/railties/html/favicon.ico
+++ b/railties/lib/generators/rails/app/templates/app/views/layouts/.empty_directory
diff --git a/railties/environments/boot.rb b/railties/lib/generators/rails/app/templates/config/boot.rb
index 0ad0f787f8..0ad0f787f8 100644
--- a/railties/environments/boot.rb
+++ b/railties/lib/generators/rails/app/templates/config/boot.rb
diff --git a/railties/configs/databases/frontbase.yml b/railties/lib/generators/rails/app/templates/config/databases/frontbase.yml
index c0c3588be1..c0c3588be1 100644
--- a/railties/configs/databases/frontbase.yml
+++ b/railties/lib/generators/rails/app/templates/config/databases/frontbase.yml
diff --git a/railties/configs/databases/ibm_db.yml b/railties/lib/generators/rails/app/templates/config/databases/ibm_db.yml
index a9716ddb44..a9716ddb44 100644
--- a/railties/configs/databases/ibm_db.yml
+++ b/railties/lib/generators/rails/app/templates/config/databases/ibm_db.yml
diff --git a/railties/configs/databases/mysql.yml b/railties/lib/generators/rails/app/templates/config/databases/mysql.yml
index 1a14bfb332..6bf2f7b1fd 100644
--- a/railties/configs/databases/mysql.yml
+++ b/railties/lib/generators/rails/app/templates/config/databases/mysql.yml
@@ -22,8 +22,8 @@ development:
pool: 5
username: root
password:
-<% if socket -%>
- socket: <%= socket %>
+<% if mysql_socket -%>
+ socket: <%= mysql_socket %>
<% else -%>
host: localhost
<% end -%>
@@ -39,8 +39,8 @@ test:
pool: 5
username: root
password:
-<% if socket -%>
- socket: <%= socket %>
+<% if mysql_socket -%>
+ socket: <%= mysql_socket %>
<% else -%>
host: localhost
<% end -%>
@@ -53,8 +53,8 @@ production:
pool: 5
username: root
password:
-<% if socket -%>
- socket: <%= socket %>
+<% if mysql_socket -%>
+ socket: <%= mysql_socket %>
<% else -%>
host: localhost
<% end -%>
diff --git a/railties/configs/databases/oracle.yml b/railties/lib/generators/rails/app/templates/config/databases/oracle.yml
index a1883f6256..a1883f6256 100644
--- a/railties/configs/databases/oracle.yml
+++ b/railties/lib/generators/rails/app/templates/config/databases/oracle.yml
diff --git a/railties/configs/databases/postgresql.yml b/railties/lib/generators/rails/app/templates/config/databases/postgresql.yml
index f600e054cf..f600e054cf 100644
--- a/railties/configs/databases/postgresql.yml
+++ b/railties/lib/generators/rails/app/templates/config/databases/postgresql.yml
diff --git a/railties/configs/databases/sqlite2.yml b/railties/lib/generators/rails/app/templates/config/databases/sqlite2.yml
index 46f01cb42c..46f01cb42c 100644
--- a/railties/configs/databases/sqlite2.yml
+++ b/railties/lib/generators/rails/app/templates/config/databases/sqlite2.yml
diff --git a/railties/configs/databases/sqlite3.yml b/railties/lib/generators/rails/app/templates/config/databases/sqlite3.yml
index 025d62a8d8..025d62a8d8 100644
--- a/railties/configs/databases/sqlite3.yml
+++ b/railties/lib/generators/rails/app/templates/config/databases/sqlite3.yml
diff --git a/railties/environments/environment.rb b/railties/lib/generators/rails/app/templates/config/environment.rb
index 4a2df36307..84c5abf1e9 100644
--- a/railties/environments/environment.rb
+++ b/railties/lib/generators/rails/app/templates/config/environment.rb
@@ -1,7 +1,7 @@
# Be sure to restart your server when you modify this file
# Specifies gem version of Rails to use when vendor/rails is not present
-<%= '# ' if freeze %>RAILS_GEM_VERSION = '<%= Rails::VERSION::STRING %>' unless defined? RAILS_GEM_VERSION
+<%= '# ' if options[:freeze] %>RAILS_GEM_VERSION = '<%= Rails::VERSION::STRING %>' unless defined? RAILS_GEM_VERSION
# Bootstrap the Rails environment, frameworks, and default configuration
require File.join(File.dirname(__FILE__), 'boot')
@@ -26,10 +26,14 @@ Rails::Initializer.run do |config|
# Skip frameworks you're not going to use. To use Rails without a database,
# you must remove the Active Record framework.
+<% if options[:skip_activerecord] -%>
+ config.frameworks -= [ :active_record ]
+<% else -%>
# config.frameworks -= [ :active_record, :active_resource, :action_mailer ]
# Activate observers that should always be running
# config.active_record.observers = :cacher, :garbage_collector, :forum_observer
+<% end -%>
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
# Run "rake -D time" for a list of tasks for finding time zone names.
@@ -38,4 +42,4 @@ Rails::Initializer.run do |config|
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}')]
# config.i18n.default_locale = :de
-end \ No newline at end of file
+end
diff --git a/railties/environments/development.rb b/railties/lib/generators/rails/app/templates/config/environments/development.rb
index 85c9a6080e..85c9a6080e 100644
--- a/railties/environments/development.rb
+++ b/railties/lib/generators/rails/app/templates/config/environments/development.rb
diff --git a/railties/environments/production.rb b/railties/lib/generators/rails/app/templates/config/environments/production.rb
index 1fc9f6b923..1fc9f6b923 100644
--- a/railties/environments/production.rb
+++ b/railties/lib/generators/rails/app/templates/config/environments/production.rb
diff --git a/railties/environments/test.rb b/railties/lib/generators/rails/app/templates/config/environments/test.rb
index 496eb9572b..496eb9572b 100644
--- a/railties/environments/test.rb
+++ b/railties/lib/generators/rails/app/templates/config/environments/test.rb
diff --git a/railties/configs/initializers/backtrace_silencers.rb b/railties/lib/generators/rails/app/templates/config/initializers/backtrace_silencers.rb
index 839d4cde19..839d4cde19 100644
--- a/railties/configs/initializers/backtrace_silencers.rb
+++ b/railties/lib/generators/rails/app/templates/config/initializers/backtrace_silencers.rb
diff --git a/railties/configs/initializers/inflections.rb b/railties/lib/generators/rails/app/templates/config/initializers/inflections.rb
index d531b8bb82..d531b8bb82 100644
--- a/railties/configs/initializers/inflections.rb
+++ b/railties/lib/generators/rails/app/templates/config/initializers/inflections.rb
diff --git a/railties/configs/initializers/mime_types.rb b/railties/lib/generators/rails/app/templates/config/initializers/mime_types.rb
index 72aca7e441..72aca7e441 100644
--- a/railties/configs/initializers/mime_types.rb
+++ b/railties/lib/generators/rails/app/templates/config/initializers/mime_types.rb
diff --git a/railties/configs/initializers/new_rails_defaults.rb b/railties/lib/generators/rails/app/templates/config/initializers/new_rails_defaults.rb
index 8ec3186c84..8ec3186c84 100644
--- a/railties/configs/initializers/new_rails_defaults.rb
+++ b/railties/lib/generators/rails/app/templates/config/initializers/new_rails_defaults.rb
diff --git a/railties/configs/initializers/session_store.rb b/railties/lib/generators/rails/app/templates/config/initializers/session_store.rb.tt
index 4499ab84b6..4499ab84b6 100644
--- a/railties/configs/initializers/session_store.rb
+++ b/railties/lib/generators/rails/app/templates/config/initializers/session_store.rb.tt
diff --git a/railties/configs/locales/en.yml b/railties/lib/generators/rails/app/templates/config/locales/en.yml
index f265c068d8..f265c068d8 100644
--- a/railties/configs/locales/en.yml
+++ b/railties/lib/generators/rails/app/templates/config/locales/en.yml
diff --git a/railties/configs/routes.rb b/railties/lib/generators/rails/app/templates/config/routes.rb
index ea14ce1bfc..ea14ce1bfc 100644
--- a/railties/configs/routes.rb
+++ b/railties/lib/generators/rails/app/templates/config/routes.rb
diff --git a/railties/configs/seeds.rb b/railties/lib/generators/rails/app/templates/db/seeds.rb
index 3174d0cb8a..3174d0cb8a 100644
--- a/railties/configs/seeds.rb
+++ b/railties/lib/generators/rails/app/templates/db/seeds.rb
diff --git a/railties/dispatches/config.ru b/railties/lib/generators/rails/app/templates/dispatchers/config.ru
index acbfe4e9ae..acbfe4e9ae 100644
--- a/railties/dispatches/config.ru
+++ b/railties/lib/generators/rails/app/templates/dispatchers/config.ru
diff --git a/railties/dispatches/dispatch.fcgi b/railties/lib/generators/rails/app/templates/dispatchers/dispatch.fcgi
index 664dbbbee8..f5b3b71875 100755
--- a/railties/dispatches/dispatch.fcgi
+++ b/railties/lib/generators/rails/app/templates/dispatchers/dispatch.fcgi
@@ -1,4 +1,4 @@
-#!/usr/bin/env ruby
+<%= shebang %>
#
# You may specify the path to the FastCGI crash log (a log of unhandled
# exceptions which forced the FastCGI instance to exit, great for debugging)
diff --git a/railties/dispatches/dispatch.rb b/railties/lib/generators/rails/app/templates/dispatchers/dispatch.rb
index 32fa3b2665..48e888113a 100755
--- a/railties/dispatches/dispatch.rb
+++ b/railties/lib/generators/rails/app/templates/dispatchers/dispatch.rb
@@ -1,4 +1,4 @@
-#!/usr/bin/env ruby
+<%= shebang %>
require File.dirname(__FILE__) + "/../config/environment" unless defined?(RAILS_ROOT)
diff --git a/railties/dispatches/gateway.cgi b/railties/lib/generators/rails/app/templates/dispatchers/gateway.cgi
index 0305b7f810..bdc1055a22 100755
--- a/railties/dispatches/gateway.cgi
+++ b/railties/lib/generators/rails/app/templates/dispatchers/gateway.cgi
@@ -1,4 +1,4 @@
-#!/usr/bin/env ruby
+<%= shebang %>
require 'drb'
diff --git a/railties/doc/README_FOR_APP b/railties/lib/generators/rails/app/templates/doc/README_FOR_APP
index fe41f5cc24..fe41f5cc24 100644
--- a/railties/doc/README_FOR_APP
+++ b/railties/lib/generators/rails/app/templates/doc/README_FOR_APP
diff --git a/railties/html/404.html b/railties/lib/generators/rails/app/templates/public/404.html
index eff660b90c..eff660b90c 100644
--- a/railties/html/404.html
+++ b/railties/lib/generators/rails/app/templates/public/404.html
diff --git a/railties/html/422.html b/railties/lib/generators/rails/app/templates/public/422.html
index b54e4a3cad..b54e4a3cad 100644
--- a/railties/html/422.html
+++ b/railties/lib/generators/rails/app/templates/public/422.html
diff --git a/railties/html/500.html b/railties/lib/generators/rails/app/templates/public/500.html
index ec3bbf02c4..ec3bbf02c4 100644
--- a/railties/html/500.html
+++ b/railties/lib/generators/rails/app/templates/public/500.html
diff --git a/railties/lib/generators/rails/app/templates/public/favicon.ico b/railties/lib/generators/rails/app/templates/public/favicon.ico
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/railties/lib/generators/rails/app/templates/public/favicon.ico
diff --git a/railties/html/images/rails.png b/railties/lib/generators/rails/app/templates/public/images/rails.png
index d5edc04e65..d5edc04e65 100644
--- a/railties/html/images/rails.png
+++ b/railties/lib/generators/rails/app/templates/public/images/rails.png
Binary files differ
diff --git a/railties/html/index.html b/railties/lib/generators/rails/app/templates/public/index.html
index cd337dc74c..cd337dc74c 100644
--- a/railties/html/index.html
+++ b/railties/lib/generators/rails/app/templates/public/index.html
diff --git a/railties/html/javascripts/application.js b/railties/lib/generators/rails/app/templates/public/javascripts/application.js
index fe4577696b..fe4577696b 100644
--- a/railties/html/javascripts/application.js
+++ b/railties/lib/generators/rails/app/templates/public/javascripts/application.js
diff --git a/railties/html/javascripts/controls.js b/railties/lib/generators/rails/app/templates/public/javascripts/controls.js
index ca29aefdd1..ca29aefdd1 100644
--- a/railties/html/javascripts/controls.js
+++ b/railties/lib/generators/rails/app/templates/public/javascripts/controls.js
diff --git a/railties/html/javascripts/dragdrop.js b/railties/lib/generators/rails/app/templates/public/javascripts/dragdrop.js
index 07229f986f..07229f986f 100644
--- a/railties/html/javascripts/dragdrop.js
+++ b/railties/lib/generators/rails/app/templates/public/javascripts/dragdrop.js
diff --git a/railties/html/javascripts/effects.js b/railties/lib/generators/rails/app/templates/public/javascripts/effects.js
index 5a639d2dea..5a639d2dea 100644
--- a/railties/html/javascripts/effects.js
+++ b/railties/lib/generators/rails/app/templates/public/javascripts/effects.js
diff --git a/railties/html/javascripts/prototype.js b/railties/lib/generators/rails/app/templates/public/javascripts/prototype.js
index dfe8ab4e13..dfe8ab4e13 100644
--- a/railties/html/javascripts/prototype.js
+++ b/railties/lib/generators/rails/app/templates/public/javascripts/prototype.js
diff --git a/railties/html/robots.txt b/railties/lib/generators/rails/app/templates/public/robots.txt
index 085187fa58..085187fa58 100644
--- a/railties/html/robots.txt
+++ b/railties/lib/generators/rails/app/templates/public/robots.txt
diff --git a/railties/lib/generators/rails/app/templates/public/stylesheets/.empty_directory b/railties/lib/generators/rails/app/templates/public/stylesheets/.empty_directory
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/railties/lib/generators/rails/app/templates/public/stylesheets/.empty_directory
diff --git a/railties/bin/about b/railties/lib/generators/rails/app/templates/script/about.tt
index ed8deb0dfc..9604485fd2 100755
--- a/railties/bin/about
+++ b/railties/lib/generators/rails/app/templates/script/about.tt
@@ -1,4 +1,4 @@
-#!/usr/bin/env ruby
+<%= shebang %>
require File.dirname(__FILE__) + '/../config/boot'
$LOAD_PATH.unshift "#{RAILTIES_PATH}/builtin/rails_info"
-require 'commands/about' \ No newline at end of file
+require 'commands/about'
diff --git a/railties/bin/console b/railties/lib/generators/rails/app/templates/script/console.tt
index 498077ab33..307b7c09c4 100755
--- a/railties/bin/console
+++ b/railties/lib/generators/rails/app/templates/script/console.tt
@@ -1,3 +1,3 @@
-#!/usr/bin/env ruby
+<%= shebang %>
require File.dirname(__FILE__) + '/../config/boot'
require 'commands/console'
diff --git a/railties/bin/dbconsole b/railties/lib/generators/rails/app/templates/script/dbconsole.tt
index caa60ce829..7ce41645a6 100755
--- a/railties/bin/dbconsole
+++ b/railties/lib/generators/rails/app/templates/script/dbconsole.tt
@@ -1,3 +1,3 @@
-#!/usr/bin/env ruby
+<%= shebang %>
require File.dirname(__FILE__) + '/../config/boot'
require 'commands/dbconsole'
diff --git a/railties/bin/destroy b/railties/lib/generators/rails/app/templates/script/destroy.tt
index a4df765a39..9f22a9dbca 100755
--- a/railties/bin/destroy
+++ b/railties/lib/generators/rails/app/templates/script/destroy.tt
@@ -1,3 +1,3 @@
-#!/usr/bin/env ruby
+<%= shebang %>
require File.dirname(__FILE__) + '/../config/boot'
require 'commands/destroy'
diff --git a/railties/bin/generate b/railties/lib/generators/rails/app/templates/script/generate.tt
index 173a9f147d..9a9e17ab29 100755
--- a/railties/bin/generate
+++ b/railties/lib/generators/rails/app/templates/script/generate.tt
@@ -1,3 +1,3 @@
-#!/usr/bin/env ruby
+<%= shebang %>
require File.dirname(__FILE__) + '/../config/boot'
require 'commands/generate'
diff --git a/railties/bin/performance/benchmarker b/railties/lib/generators/rails/app/templates/script/performance/benchmarker.tt
index c842d35d33..3abf448c15 100755
--- a/railties/bin/performance/benchmarker
+++ b/railties/lib/generators/rails/app/templates/script/performance/benchmarker.tt
@@ -1,3 +1,3 @@
-#!/usr/bin/env ruby
+<%= shebang %>
require File.dirname(__FILE__) + '/../../config/boot'
require 'commands/performance/benchmarker'
diff --git a/railties/bin/performance/profiler b/railties/lib/generators/rails/app/templates/script/performance/profiler.tt
index d855ac8b13..66f851a079 100755
--- a/railties/bin/performance/profiler
+++ b/railties/lib/generators/rails/app/templates/script/performance/profiler.tt
@@ -1,3 +1,3 @@
-#!/usr/bin/env ruby
+<%= shebang %>
require File.dirname(__FILE__) + '/../../config/boot'
require 'commands/performance/profiler'
diff --git a/railties/bin/plugin b/railties/lib/generators/rails/app/templates/script/plugin.tt
index 87cd2070fe..f0603c33c4 100755
--- a/railties/bin/plugin
+++ b/railties/lib/generators/rails/app/templates/script/plugin.tt
@@ -1,3 +1,3 @@
-#!/usr/bin/env ruby
+<%= shebang %>
require File.dirname(__FILE__) + '/../config/boot'
require 'commands/plugin'
diff --git a/railties/bin/runner b/railties/lib/generators/rails/app/templates/script/runner.tt
index a4a7cb25ba..7302825f6c 100755
--- a/railties/bin/runner
+++ b/railties/lib/generators/rails/app/templates/script/runner.tt
@@ -1,3 +1,3 @@
-#!/usr/bin/env ruby
+<%= shebang %>
require File.dirname(__FILE__) + '/../config/boot'
require 'commands/runner'
diff --git a/railties/bin/server b/railties/lib/generators/rails/app/templates/script/server.tt
index 3c67f39b69..893db31a20 100755
--- a/railties/bin/server
+++ b/railties/lib/generators/rails/app/templates/script/server.tt
@@ -1,3 +1,3 @@
-#!/usr/bin/env ruby
+<%= shebang %>
require File.dirname(__FILE__) + '/../config/boot'
require 'commands/server'
diff --git a/railties/lib/generators/rails/app/templates/test/fixtures/.empty_directory b/railties/lib/generators/rails/app/templates/test/fixtures/.empty_directory
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/railties/lib/generators/rails/app/templates/test/fixtures/.empty_directory
diff --git a/railties/lib/generators/rails/app/templates/test/functional/.empty_directory b/railties/lib/generators/rails/app/templates/test/functional/.empty_directory
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/railties/lib/generators/rails/app/templates/test/functional/.empty_directory
diff --git a/railties/lib/generators/rails/app/templates/test/integration/.empty_directory b/railties/lib/generators/rails/app/templates/test/integration/.empty_directory
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/railties/lib/generators/rails/app/templates/test/integration/.empty_directory
diff --git a/railties/helpers/performance_test.rb b/railties/lib/generators/rails/app/templates/test/performance/performance_test.rb
index 4b60558b43..4b60558b43 100644
--- a/railties/helpers/performance_test.rb
+++ b/railties/lib/generators/rails/app/templates/test/performance/performance_test.rb
diff --git a/railties/helpers/test_helper.rb b/railties/lib/generators/rails/app/templates/test/test_helper.rb
index b9fe2517c8..b9fe2517c8 100644
--- a/railties/helpers/test_helper.rb
+++ b/railties/lib/generators/rails/app/templates/test/test_helper.rb
diff --git a/railties/lib/generators/rails/app/templates/test/unit/.empty_directory b/railties/lib/generators/rails/app/templates/test/unit/.empty_directory
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/railties/lib/generators/rails/app/templates/test/unit/.empty_directory
diff --git a/railties/lib/generators/rails/controller/USAGE b/railties/lib/generators/rails/controller/USAGE
new file mode 100644
index 0000000000..6ed4b2edfc
--- /dev/null
+++ b/railties/lib/generators/rails/controller/USAGE
@@ -0,0 +1,18 @@
+Description:
+ Stubs out a new controller and its views. Pass the controller name, either
+ CamelCased or under_scored, and a list of views as arguments.
+
+ To create a controller within a module, specify the controller name as a
+ path like 'parent_module/controller_name'.
+
+ This generates a controller class in app/controllers and invokes helper,
+ template engine and test framework generators.
+
+Example:
+ `./script/generate controller CreditCard open debit credit close`
+
+ Credit card controller with URLs like /credit_card/debit.
+ Controller: app/controllers/credit_card_controller.rb
+ Functional Test: test/functional/credit_card_controller_test.rb
+ Views: app/views/credit_card/debit.html.erb [...]
+ Helper: app/helpers/credit_card_helper.rb
diff --git a/railties/lib/generators/rails/controller/controller_generator.rb b/railties/lib/generators/rails/controller/controller_generator.rb
new file mode 100644
index 0000000000..3fed058c00
--- /dev/null
+++ b/railties/lib/generators/rails/controller/controller_generator.rb
@@ -0,0 +1,15 @@
+module Rails
+ module Generators
+ class ControllerGenerator < NamedBase
+ argument :actions, :type => :array, :default => [], :banner => "action action"
+ check_class_collision :suffix => "Controller"
+
+ def create_controller_files
+ template 'controller.rb', File.join('app/controllers', class_path, "#{file_name}_controller.rb")
+ end
+
+ hook_for :template_engine, :test_framework
+ invoke_if :helper
+ end
+ end
+end
diff --git a/railties/lib/generators/rails/controller/templates/controller.rb b/railties/lib/generators/rails/controller/templates/controller.rb
new file mode 100644
index 0000000000..cda2659e69
--- /dev/null
+++ b/railties/lib/generators/rails/controller/templates/controller.rb
@@ -0,0 +1,7 @@
+class <%= class_name %>Controller < ApplicationController
+<% for action in actions -%>
+ def <%= action %>
+ end
+
+<% end -%>
+end
diff --git a/railties/lib/generators/rails/helper/USAGE b/railties/lib/generators/rails/helper/USAGE
new file mode 100644
index 0000000000..531c9b390a
--- /dev/null
+++ b/railties/lib/generators/rails/helper/USAGE
@@ -0,0 +1,17 @@
+Description:
+ Stubs out a new helper. Pass the helper name, either CamelCased
+ or under_scored.
+
+ To create a helper within a module, specify the helper name as a
+ path like 'parent_module/helper_name'.
+
+ This generates a helper class in app/helpers and invokes the configured
+ test framework.
+
+Example:
+ `./script/generate helper CreditCard`
+
+ Credit card helper.
+ Helper: app/helpers/credit_card_helper.rb
+ Test: test/unit/helpers/credit_card_helper_test.rb
+
diff --git a/railties/lib/generators/rails/helper/helper_generator.rb b/railties/lib/generators/rails/helper/helper_generator.rb
new file mode 100644
index 0000000000..ad66388591
--- /dev/null
+++ b/railties/lib/generators/rails/helper/helper_generator.rb
@@ -0,0 +1,13 @@
+module Rails
+ module Generators
+ class HelperGenerator < NamedBase
+ check_class_collision :suffix => "Helper"
+
+ def create_helper_files
+ template 'helper.rb', File.join('app/helpers', class_path, "#{file_name}_helper.rb")
+ end
+
+ hook_for :test_framework
+ end
+ end
+end
diff --git a/railties/lib/generators/rails/helper/templates/helper.rb b/railties/lib/generators/rails/helper/templates/helper.rb
new file mode 100644
index 0000000000..3fe2ecdc74
--- /dev/null
+++ b/railties/lib/generators/rails/helper/templates/helper.rb
@@ -0,0 +1,2 @@
+module <%= class_name %>Helper
+end
diff --git a/railties/lib/generators/rails/integration_test/USAGE b/railties/lib/generators/rails/integration_test/USAGE
new file mode 100644
index 0000000000..b76c35a702
--- /dev/null
+++ b/railties/lib/generators/rails/integration_test/USAGE
@@ -0,0 +1,10 @@
+Description:
+ Stubs out a new integration test. Pass the name of the test, either
+ CamelCased or under_scored, as an argument.
+
+ This generator invokes the current integration tool, which defaults to
+ TestUnit.
+
+Example:
+ `./script/generate integration_test GeneralStories` creates a GeneralStories
+ integration test in test/integration/general_stories_test.rb
diff --git a/railties/lib/generators/rails/integration_test/integration_test_generator.rb b/railties/lib/generators/rails/integration_test/integration_test_generator.rb
new file mode 100644
index 0000000000..b45ef1597c
--- /dev/null
+++ b/railties/lib/generators/rails/integration_test/integration_test_generator.rb
@@ -0,0 +1,11 @@
+module Rails
+ module Generators
+ class IntegrationTestGenerator < NamedBase
+ check_class_collision :suffix => "Test"
+
+ def create_test_files
+ template 'integration_test.rb', File.join('test/integration', class_path, "#{file_name}_test.rb")
+ end
+ end
+ end
+end
diff --git a/railties/lib/generators/rails/integration_test/templates/integration_test.rb b/railties/lib/generators/rails/integration_test/templates/integration_test.rb
new file mode 100644
index 0000000000..2c57158b1c
--- /dev/null
+++ b/railties/lib/generators/rails/integration_test/templates/integration_test.rb
@@ -0,0 +1,10 @@
+require 'test_helper'
+
+class <%= class_name %>Test < ActionController::IntegrationTest
+ fixtures :all
+
+ # Replace this with your real tests.
+ test "the truth" do
+ assert true
+ end
+end
diff --git a/railties/lib/generators/rails/mailer/USAGE b/railties/lib/generators/rails/mailer/USAGE
new file mode 100644
index 0000000000..c56095b2c8
--- /dev/null
+++ b/railties/lib/generators/rails/mailer/USAGE
@@ -0,0 +1,15 @@
+Description:
+ Stubs out a new mailer and its views. Pass the mailer name, either
+ CamelCased or under_scored, and an optional list of emails as arguments.
+
+ This generates a mailer class in app/models and invokes your template
+ engine and test framework generators.
+
+Example:
+ `./script/generate mailer Notifications signup forgot_password invoice`
+
+ creates a Notifications mailer class, views, test, and fixtures:
+ Mailer: app/models/notifications.rb
+ Views: app/views/notifications/signup.erb [...]
+ Test: test/unit/test/unit/notifications_test.rb
+ Fixtures: test/fixtures/notifications/signup [...]
diff --git a/railties/lib/generators/rails/mailer/mailer_generator.rb b/railties/lib/generators/rails/mailer/mailer_generator.rb
new file mode 100644
index 0000000000..33f1665b83
--- /dev/null
+++ b/railties/lib/generators/rails/mailer/mailer_generator.rb
@@ -0,0 +1,14 @@
+module Rails
+ module Generators
+ class MailerGenerator < NamedBase
+ argument :actions, :type => :array, :default => [], :banner => "method method"
+ check_class_collision
+
+ def create_mailer_file
+ template "mailer.rb", File.join('app/models', class_path, "#{file_name}.rb")
+ end
+
+ hook_for :template_engine, :test_framework
+ end
+ end
+end
diff --git a/railties/lib/generators/rails/mailer/templates/mailer.rb b/railties/lib/generators/rails/mailer/templates/mailer.rb
new file mode 100644
index 0000000000..ce15ae9de9
--- /dev/null
+++ b/railties/lib/generators/rails/mailer/templates/mailer.rb
@@ -0,0 +1,15 @@
+class <%= class_name %> < ActionMailer::Base
+
+<% for action in actions -%>
+
+ def <%= action %>(sent_at = Time.now)
+ subject '<%= class_name %>#<%= action %>'
+ recipients ''
+ from ''
+ sent_on sent_at
+
+ body :greeting => 'Hi,'
+ end
+<% end -%>
+
+end
diff --git a/railties/lib/generators/rails/metal/USAGE b/railties/lib/generators/rails/metal/USAGE
new file mode 100644
index 0000000000..123ec6c03f
--- /dev/null
+++ b/railties/lib/generators/rails/metal/USAGE
@@ -0,0 +1,8 @@
+Description:
+ Cast some metal!
+
+Examples:
+ `./script/generate metal poller`
+
+ This will create:
+ Metal: app/metal/poller.rb
diff --git a/railties/lib/generators/rails/metal/metal_generator.rb b/railties/lib/generators/rails/metal/metal_generator.rb
new file mode 100644
index 0000000000..d814b6c38b
--- /dev/null
+++ b/railties/lib/generators/rails/metal/metal_generator.rb
@@ -0,0 +1,11 @@
+module Rails
+ module Generators
+ class MetalGenerator < NamedBase
+ check_class_collision
+
+ def create_file
+ template "metal.rb", "app/metal/#{file_name}.rb"
+ end
+ end
+ end
+end
diff --git a/railties/lib/generators/rails/metal/templates/metal.rb b/railties/lib/generators/rails/metal/templates/metal.rb
new file mode 100644
index 0000000000..e94982b69a
--- /dev/null
+++ b/railties/lib/generators/rails/metal/templates/metal.rb
@@ -0,0 +1,12 @@
+# Allow the metal piece to run in isolation
+require(File.dirname(__FILE__) + "/../../config/environment") unless defined?(Rails)
+
+class <%= class_name %>
+ def self.call(env)
+ if env["PATH_INFO"] =~ /^\/<%= file_name %>/
+ [200, {"Content-Type" => "text/html"}, ["Hello, World!"]]
+ else
+ [404, {"Content-Type" => "text/html"}, ["Not Found"]]
+ end
+ end
+end
diff --git a/railties/lib/generators/rails/migration/USAGE b/railties/lib/generators/rails/migration/USAGE
new file mode 100644
index 0000000000..d91127aac3
--- /dev/null
+++ b/railties/lib/generators/rails/migration/USAGE
@@ -0,0 +1,29 @@
+Description:
+ Stubs out a new database migration. Pass the migration name, either
+ CamelCased or under_scored, and an optional list of attribute pairs as arguments.
+
+ A migration class is generated in db/migrate prefixed by a timestamp of the current date and time.
+
+ You can name your migration in either of these formats to generate add/remove
+ column lines from supplied attributes: AddColumnsToTable or RemoveColumnsFromTable
+
+Example:
+ `./script/generate migration AddSslFlag`
+
+ If the current date is May 14, 2008 and the current time 09:09:12, this creates the AddSslFlag migration
+ db/migrate/20080514090912_add_ssl_flag.rb
+
+ `./script/generate migration AddTitleBodyToPost title:string body:text published:boolean`
+
+ This will create the AddTitleBodyToPost in db/migrate/20080514090912_add_title_body_to_post.rb with
+ this in the Up migration:
+
+ add_column :posts, :title, :string
+ add_column :posts, :body, :text
+ add_column :posts, :published, :boolean
+
+ And this in the Down migration:
+
+ remove_column :posts, :published
+ remove_column :posts, :body
+ remove_column :posts, :title
diff --git a/railties/lib/generators/rails/migration/migration_generator.rb b/railties/lib/generators/rails/migration/migration_generator.rb
new file mode 100644
index 0000000000..cfaa5f0ad2
--- /dev/null
+++ b/railties/lib/generators/rails/migration/migration_generator.rb
@@ -0,0 +1,8 @@
+module Rails
+ module Generators
+ class MigrationGenerator < NamedBase
+ argument :attributes, :type => :hash, :default => {}, :banner => "field:type field:type"
+ hook_for :orm
+ end
+ end
+end
diff --git a/railties/lib/generators/rails/model/USAGE b/railties/lib/generators/rails/model/USAGE
new file mode 100644
index 0000000000..b056d5df8b
--- /dev/null
+++ b/railties/lib/generators/rails/model/USAGE
@@ -0,0 +1,30 @@
+Description:
+ Stubs out a new model. Pass the model name, either CamelCased or
+ under_scored, and an optional list of attribute pairs as arguments.
+
+ Attribute pairs are field:type arguments specifying the
+ model's attributes. Timestamps are added by default, so you don't have to
+ specify them by hand as 'created_at:datetime updated_at:datetime'.
+
+ You don't have to think up every attribute up front, but it helps to
+ sketch out a few so you can start working with the model immediately.
+
+ This generator invokes your configured ORM and test framework, which
+ defaults to ActiveRecord and TestUnit.
+
+ Finally, if --parent option is given, it's used as superclass of the
+ created model. This allows you create Single Table Inheritance models.
+
+Examples:
+ `./script/generate model account`
+
+ For ActiveRecord and TestUnit it creates:
+
+ Model: app/models/account.rb
+ Test: test/unit/account_test.rb
+ Fixtures: test/fixtures/accounts.yml
+ Migration: db/migrate/XXX_add_accounts.rb
+
+ `./script/generate model post title:string body:text published:boolean`
+
+ Creates a Post model with a string title, text body, and published flag.
diff --git a/railties/lib/generators/rails/model/model_generator.rb b/railties/lib/generators/rails/model/model_generator.rb
new file mode 100644
index 0000000000..36354c5638
--- /dev/null
+++ b/railties/lib/generators/rails/model/model_generator.rb
@@ -0,0 +1,8 @@
+module Rails
+ module Generators
+ class ModelGenerator < NamedBase
+ argument :attributes, :type => :hash, :default => {}, :banner => "field:type field:type"
+ hook_for :orm, :test_framework
+ end
+ end
+end
diff --git a/railties/lib/generators/rails/model_subclass/model_subclass_generator.rb b/railties/lib/generators/rails/model_subclass/model_subclass_generator.rb
new file mode 100644
index 0000000000..4649709780
--- /dev/null
+++ b/railties/lib/generators/rails/model_subclass/model_subclass_generator.rb
@@ -0,0 +1,11 @@
+module Rails
+ module Generators
+ class ModelSubclassGenerator < Base
+ desc "model_subclass is deprecated. Invoke model with --parent option instead."
+
+ def say_deprecation_warn
+ say self.class.desc
+ end
+ end
+ end
+end
diff --git a/railties/lib/generators/rails/observer/USAGE b/railties/lib/generators/rails/observer/USAGE
new file mode 100644
index 0000000000..9a20f55a89
--- /dev/null
+++ b/railties/lib/generators/rails/observer/USAGE
@@ -0,0 +1,12 @@
+Description:
+ Stubs out a new observer. Pass the observer name, either CamelCased or
+ under_scored, as an argument.
+
+ This generator only invokes your ORM and test framework generators.
+
+Example:
+ `./script/generate observer Account`
+
+ For ActiveRecord and TestUnit it creates:
+ Observer: app/models/account_observer.rb
+ TestUnit: test/unit/account_observer_test.rb
diff --git a/railties/lib/generators/rails/observer/observer_generator.rb b/railties/lib/generators/rails/observer/observer_generator.rb
new file mode 100644
index 0000000000..e33247959b
--- /dev/null
+++ b/railties/lib/generators/rails/observer/observer_generator.rb
@@ -0,0 +1,7 @@
+module Rails
+ module Generators
+ class ObserverGenerator < NamedBase
+ hook_for :orm, :test_framework
+ end
+ end
+end
diff --git a/railties/lib/generators/rails/performance_test/USAGE b/railties/lib/generators/rails/performance_test/USAGE
new file mode 100644
index 0000000000..ee82578cdb
--- /dev/null
+++ b/railties/lib/generators/rails/performance_test/USAGE
@@ -0,0 +1,10 @@
+Description:
+ Stubs out a new performance test. Pass the name of the test, either
+ CamelCased or under_scored, as an argument.
+
+ This generator invokes the current performance tool, which defaults to
+ TestUnit.
+
+Example:
+ `./script/generate performance_test GeneralStories` creates a GeneralStories
+ performance test in test/performance/general_stories_test.rb
diff --git a/railties/lib/generators/rails/performance_test/performance_test_generator.rb b/railties/lib/generators/rails/performance_test/performance_test_generator.rb
new file mode 100644
index 0000000000..b8efda8df3
--- /dev/null
+++ b/railties/lib/generators/rails/performance_test/performance_test_generator.rb
@@ -0,0 +1,11 @@
+module Rails
+ module Generators
+ class PerformanceTestGenerator < NamedBase
+ check_class_collision :suffix => "Test"
+
+ def create_test_files
+ template 'performance_test.rb', File.join('test/performance', class_path, "#{file_name}_test.rb")
+ end
+ end
+ end
+end
diff --git a/railties/lib/generators/rails/performance_test/templates/performance_test.rb b/railties/lib/generators/rails/performance_test/templates/performance_test.rb
new file mode 100644
index 0000000000..27c91b0fca
--- /dev/null
+++ b/railties/lib/generators/rails/performance_test/templates/performance_test.rb
@@ -0,0 +1,9 @@
+require 'test_helper'
+require 'performance_test_help'
+
+class <%= class_name %>Test < ActionController::PerformanceTest
+ # Replace this with your real tests.
+ def test_homepage
+ get '/'
+ end
+end
diff --git a/railties/lib/generators/rails/plugin/USAGE b/railties/lib/generators/rails/plugin/USAGE
new file mode 100644
index 0000000000..8a17fa4dec
--- /dev/null
+++ b/railties/lib/generators/rails/plugin/USAGE
@@ -0,0 +1,13 @@
+Description:
+ Stubs out a new plugin at vendor/plugins. Pass the plugin name, either
+ CamelCased or under_scored, as an argument.
+
+Example:
+ `./script/generate plugin BrowserFilters`
+
+ creates a standard browser_filters plugin:
+ vendor/plugins/browser_filters/README
+ vendor/plugins/browser_filters/init.rb
+ vendor/plugins/browser_filters/install.rb
+ vendor/plugins/browser_filters/lib/browser_filters.rb
+ vendor/plugins/browser_filters/test/browser_filters_test.rb
diff --git a/railties/lib/generators/rails/plugin/plugin_generator.rb b/railties/lib/generators/rails/plugin/plugin_generator.rb
new file mode 100644
index 0000000000..c2583ee147
--- /dev/null
+++ b/railties/lib/generators/rails/plugin/plugin_generator.rb
@@ -0,0 +1,41 @@
+module Rails
+ module Generators
+ class PluginGenerator < NamedBase
+ class_option :with_tasks, :type => :boolean, :aliases => "-r", :default => false,
+ :desc => "When supplied creates tasks base files."
+
+ class_option :with_generator, :type => :boolean, :aliases => "-g", :default => false,
+ :desc => "When supplied creates generator base files."
+
+ check_class_collision
+
+ def create_root
+ self.root = File.expand_path("vendor/plugins/#{file_name}", root)
+ empty_directory '.'
+ FileUtils.cd(root)
+ end
+
+ def create_root_files
+ %w(README MIT-LICENSE Rakefile init.rb install.rb uninstall.rb).each do |file|
+ template file
+ end
+ end
+
+ def create_lib_files
+ directory 'lib'
+ end
+
+ hook_for :test_framework
+
+ def create_tasks_files
+ return unless options[:with_tasks]
+ directory 'tasks'
+ end
+
+ def create_generator_files
+ return unless options[:with_generator]
+ directory 'generators'
+ end
+ end
+ end
+end
diff --git a/railties/lib/generators/rails/plugin/templates/MIT-LICENSE b/railties/lib/generators/rails/plugin/templates/MIT-LICENSE
new file mode 100644
index 0000000000..8717df053d
--- /dev/null
+++ b/railties/lib/generators/rails/plugin/templates/MIT-LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) <%= Date.today.year %> [name of plugin creator]
+
+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/generators/rails/plugin/templates/README b/railties/lib/generators/rails/plugin/templates/README
new file mode 100644
index 0000000000..702db07cb1
--- /dev/null
+++ b/railties/lib/generators/rails/plugin/templates/README
@@ -0,0 +1,13 @@
+<%= class_name %>
+<%= "=" * class_name.size %>
+
+Introduction goes here.
+
+
+Example
+=======
+
+Example goes here.
+
+
+Copyright (c) <%= Date.today.year %> [name of plugin creator], released under the MIT license
diff --git a/railties/lib/generators/rails/plugin/templates/Rakefile b/railties/lib/generators/rails/plugin/templates/Rakefile
new file mode 100644
index 0000000000..85e8ff1834
--- /dev/null
+++ b/railties/lib/generators/rails/plugin/templates/Rakefile
@@ -0,0 +1,23 @@
+require 'rake'
+require 'rake/testtask'
+require 'rake/rdoctask'
+
+desc 'Default: run unit tests.'
+task :default => :test
+
+desc 'Test the <%= file_name %> plugin.'
+Rake::TestTask.new(:test) do |t|
+ t.libs << 'lib'
+ t.libs << 'test'
+ t.pattern = 'test/**/*_test.rb'
+ t.verbose = true
+end
+
+desc 'Generate documentation for the <%= file_name %> plugin.'
+Rake::RDocTask.new(:rdoc) do |rdoc|
+ rdoc.rdoc_dir = 'rdoc'
+ rdoc.title = '<%= class_name %>'
+ rdoc.options << '--line-numbers' << '--inline-source'
+ rdoc.rdoc_files.include('README')
+ rdoc.rdoc_files.include('lib/**/*.rb')
+end
diff --git a/railties/lib/generators/rails/plugin/templates/generators/%file_name%/%file_name%_generator.rb.tt b/railties/lib/generators/rails/plugin/templates/generators/%file_name%/%file_name%_generator.rb.tt
new file mode 100644
index 0000000000..90aa557eeb
--- /dev/null
+++ b/railties/lib/generators/rails/plugin/templates/generators/%file_name%/%file_name%_generator.rb.tt
@@ -0,0 +1,2 @@
+class <%= class_name %>Generator < Rails::Generators::NamedBase
+end
diff --git a/railties/lib/generators/rails/plugin/templates/generators/%file_name%/USAGE.tt b/railties/lib/generators/rails/plugin/templates/generators/%file_name%/USAGE.tt
new file mode 100644
index 0000000000..ea9f4f12cc
--- /dev/null
+++ b/railties/lib/generators/rails/plugin/templates/generators/%file_name%/USAGE.tt
@@ -0,0 +1,8 @@
+Description:
+ Explain the generator
+
+Example:
+ ./script/generate <%= file_name %> Thing
+
+ This will create:
+ what/will/it/create
diff --git a/railties/lib/generators/rails/plugin/templates/generators/%file_name%/templates/.empty_directory b/railties/lib/generators/rails/plugin/templates/generators/%file_name%/templates/.empty_directory
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/railties/lib/generators/rails/plugin/templates/generators/%file_name%/templates/.empty_directory
diff --git a/railties/lib/generators/rails/plugin/templates/init.rb b/railties/lib/generators/rails/plugin/templates/init.rb
new file mode 100644
index 0000000000..3c19a743c9
--- /dev/null
+++ b/railties/lib/generators/rails/plugin/templates/init.rb
@@ -0,0 +1 @@
+# Include hook code here
diff --git a/railties/lib/generators/rails/plugin/templates/install.rb b/railties/lib/generators/rails/plugin/templates/install.rb
new file mode 100644
index 0000000000..f7732d3796
--- /dev/null
+++ b/railties/lib/generators/rails/plugin/templates/install.rb
@@ -0,0 +1 @@
+# Install hook code here
diff --git a/railties/lib/generators/rails/plugin/templates/lib/%file_name%.rb.tt b/railties/lib/generators/rails/plugin/templates/lib/%file_name%.rb.tt
new file mode 100644
index 0000000000..d8d908a959
--- /dev/null
+++ b/railties/lib/generators/rails/plugin/templates/lib/%file_name%.rb.tt
@@ -0,0 +1 @@
+# <%= class_name %>
diff --git a/railties/lib/generators/rails/plugin/templates/tasks/%file_name%_tasks.rake.tt b/railties/lib/generators/rails/plugin/templates/tasks/%file_name%_tasks.rake.tt
new file mode 100644
index 0000000000..72920a9d3a
--- /dev/null
+++ b/railties/lib/generators/rails/plugin/templates/tasks/%file_name%_tasks.rake.tt
@@ -0,0 +1,4 @@
+# desc "Explaining what the task does"
+# task :<%= file_name %> do
+# # Task goes here
+# end
diff --git a/railties/lib/generators/rails/plugin/templates/uninstall.rb b/railties/lib/generators/rails/plugin/templates/uninstall.rb
new file mode 100644
index 0000000000..9738333463
--- /dev/null
+++ b/railties/lib/generators/rails/plugin/templates/uninstall.rb
@@ -0,0 +1 @@
+# Uninstall hook code here
diff --git a/railties/lib/generators/rails/resource/USAGE b/railties/lib/generators/rails/resource/USAGE
new file mode 100644
index 0000000000..936619b0db
--- /dev/null
+++ b/railties/lib/generators/rails/resource/USAGE
@@ -0,0 +1,23 @@
+Description:
+ Stubs out a new resource including an empty model and controller suitable
+ for a restful, resource-oriented application. Pass the singular model name,
+ either CamelCased or under_scored, as the first argument, and an optional
+ list of attribute pairs.
+
+ Attribute pairs are field:type arguments specifying the
+ model's attributes. Timestamps are added by default, so you don't have to
+ specify them by hand as 'created_at:datetime updated_at:datetime'.
+
+ You don't have to think up every attribute up front, but it helps to
+ sketch out a few so you can start working with the model immediately.
+
+ This generator invokes your configured ORM and test framework, besides
+ creating helpers and add routes to config/routes.rb.
+
+ Unlike the scaffold generator, the resource generator does not create
+ views or add any methods to the generated controller.
+
+Examples:
+ `./script/generate resource post` # no attributes
+ `./script/generate resource post title:string body:text published:boolean`
+ `./script/generate resource purchase order_id:integer amount:decimal`
diff --git a/railties/lib/generators/rails/resource/resource_generator.rb b/railties/lib/generators/rails/resource/resource_generator.rb
new file mode 100644
index 0000000000..8d787aaa75
--- /dev/null
+++ b/railties/lib/generators/rails/resource/resource_generator.rb
@@ -0,0 +1,32 @@
+require 'generators/rails/model/model_generator'
+
+module Rails
+ module Generators
+ class ResourceGenerator < ModelGenerator
+ hook_for :resource_controller do |base, controller|
+ base.invoke controller, [ base.name.pluralize, base.options[:actions] ]
+ end
+
+ class_option :actions, :type => :array, :default => [], :banner => "ACTION ACTION",
+ :desc => "Actions for the resource controller", :aliases => "-a"
+
+ class_option :singleton, :type => :boolean, :default => false, :aliases => "-i",
+ :desc => "Supply to create a singleton controller"
+
+ def add_resource_route
+ route "map.resource#{:s unless options[:singleton]} :#{pluralize?(file_name)}"
+ end
+
+ protected
+
+ def pluralize?(name)
+ if options[:singleton]
+ name
+ else
+ name.pluralize
+ end
+ end
+
+ end
+ end
+end
diff --git a/railties/lib/generators/rails/session_migration/USAGE b/railties/lib/generators/rails/session_migration/USAGE
new file mode 100644
index 0000000000..e106f6ecc8
--- /dev/null
+++ b/railties/lib/generators/rails/session_migration/USAGE
@@ -0,0 +1,8 @@
+Description:
+ Creates a migration to add the sessions table used by the ORM session store.
+ Pass the migration name, either CamelCased or under_scored, as an argument.
+
+ Before invoking this generator, be sure that your ORM supports session stores.
+
+Example:
+ `./script/generate session_migration CreateSessionTable`
diff --git a/railties/lib/generators/rails/session_migration/session_migration_generator.rb b/railties/lib/generators/rails/session_migration/session_migration_generator.rb
new file mode 100644
index 0000000000..e7d988359c
--- /dev/null
+++ b/railties/lib/generators/rails/session_migration/session_migration_generator.rb
@@ -0,0 +1,8 @@
+module Rails
+ module Generators
+ class SessionMigrationGenerator < NamedBase
+ argument :name, :type => :string, :default => "add_session_table"
+ hook_for :orm
+ end
+ end
+end
diff --git a/railties/lib/generators/test_unit.rb b/railties/lib/generators/test_unit.rb
new file mode 100644
index 0000000000..c4b8a8702d
--- /dev/null
+++ b/railties/lib/generators/test_unit.rb
@@ -0,0 +1,9 @@
+require 'generators/named_base'
+
+module TestUnit
+ module Generators
+ class Base < Rails::Generators::NamedBase
+ check_class_collision :suffix => "Test"
+ end
+ end
+end
diff --git a/railties/lib/generators/test_unit/controller/controller_generator.rb b/railties/lib/generators/test_unit/controller/controller_generator.rb
new file mode 100644
index 0000000000..a8cb5cbdbb
--- /dev/null
+++ b/railties/lib/generators/test_unit/controller/controller_generator.rb
@@ -0,0 +1,13 @@
+require 'generators/test_unit'
+
+module TestUnit
+ module Generators
+ class ControllerGenerator < Base
+ check_class_collision :suffix => "ControllerTest"
+
+ def create_test_files
+ template 'functional_test.rb', File.join('test/functional', class_path, "#{file_name}_controller_test.rb")
+ end
+ end
+ end
+end
diff --git a/railties/lib/generators/test_unit/controller/templates/functional_test.rb b/railties/lib/generators/test_unit/controller/templates/functional_test.rb
new file mode 100644
index 0000000000..62fa5d86fd
--- /dev/null
+++ b/railties/lib/generators/test_unit/controller/templates/functional_test.rb
@@ -0,0 +1,8 @@
+require 'test_helper'
+
+class <%= class_name %>ControllerTest < ActionController::TestCase
+ # Replace this with your real tests.
+ test "the truth" do
+ assert true
+ end
+end
diff --git a/railties/lib/generators/test_unit/helper/helper_generator.rb b/railties/lib/generators/test_unit/helper/helper_generator.rb
new file mode 100644
index 0000000000..9ecfaa45ab
--- /dev/null
+++ b/railties/lib/generators/test_unit/helper/helper_generator.rb
@@ -0,0 +1,13 @@
+require 'generators/test_unit'
+
+module TestUnit
+ module Generators
+ class HelperGenerator < Base
+ check_class_collision :suffix => "HelperTest"
+
+ def create_helper_files
+ template 'helper_test.rb', File.join('test/unit/helpers', class_path, "#{file_name}_helper_test.rb")
+ end
+ end
+ end
+end
diff --git a/railties/lib/generators/test_unit/helper/templates/helper_test.rb b/railties/lib/generators/test_unit/helper/templates/helper_test.rb
new file mode 100644
index 0000000000..591e40900e
--- /dev/null
+++ b/railties/lib/generators/test_unit/helper/templates/helper_test.rb
@@ -0,0 +1,4 @@
+require 'test_helper'
+
+class <%= class_name %>HelperTest < ActionView::TestCase
+end
diff --git a/railties/lib/generators/test_unit/mailer/mailer_generator.rb b/railties/lib/generators/test_unit/mailer/mailer_generator.rb
new file mode 100644
index 0000000000..bd1906516c
--- /dev/null
+++ b/railties/lib/generators/test_unit/mailer/mailer_generator.rb
@@ -0,0 +1,20 @@
+require 'generators/test_unit'
+
+module TestUnit
+ module Generators
+ class MailerGenerator < Base
+ argument :actions, :type => :array, :default => [], :banner => "method method"
+
+ def create_test_files
+ template "unit_test.rb", File.join('test', 'unit', class_path, "#{file_name}_test.rb")
+ end
+
+ def create_fixtures_files
+ actions.each do |action|
+ @action, @path = action, File.join(file_path, action)
+ template "fixture", File.join("test", "fixtures", @path)
+ end
+ end
+ end
+ end
+end
diff --git a/railties/lib/generators/test_unit/mailer/templates/fixture b/railties/lib/generators/test_unit/mailer/templates/fixture
new file mode 100644
index 0000000000..fcce7bd805
--- /dev/null
+++ b/railties/lib/generators/test_unit/mailer/templates/fixture
@@ -0,0 +1,3 @@
+<%= class_name %>#<%= @action %>
+
+Find me in app/views/<%= @path %>
diff --git a/railties/lib/generators/test_unit/mailer/templates/unit_test.rb b/railties/lib/generators/test_unit/mailer/templates/unit_test.rb
new file mode 100644
index 0000000000..4de94076e9
--- /dev/null
+++ b/railties/lib/generators/test_unit/mailer/templates/unit_test.rb
@@ -0,0 +1,20 @@
+require 'test_helper'
+
+class <%= class_name %>Test < ActionMailer::TestCase
+<% for action in actions -%>
+ test "<%= action %>" do
+ @expected.subject = '<%= class_name %>#<%= action %>'
+ @expected.body = read_fixture('<%= action %>')
+ @expected.date = Time.now
+
+ assert_equal @expected.encoded, <%= class_name %>.create_<%= action %>(@expected.date).encoded
+ end
+
+<% end -%>
+<% if actions.blank? -%>
+ # replace this with your real tests
+ test "the truth" do
+ assert true
+ end
+<% end -%>
+end
diff --git a/railties/lib/generators/test_unit/model/model_generator.rb b/railties/lib/generators/test_unit/model/model_generator.rb
new file mode 100644
index 0000000000..96883f592f
--- /dev/null
+++ b/railties/lib/generators/test_unit/model/model_generator.rb
@@ -0,0 +1,24 @@
+require 'generators/test_unit'
+
+module TestUnit
+ module Generators
+ class ModelGenerator < Base
+ argument :attributes, :type => :hash, :default => {}, :banner => "field:type field:type"
+
+ check_class_collision :suffix => "Test"
+ conditional_class_options :fixture
+
+ def create_test_file
+ template 'unit_test.rb', File.join('test/unit', class_path, "#{file_name}_test.rb")
+ end
+
+ hook_for :fixture_replacement
+
+ def create_fixture_file
+ if options[:fixture] && options[:fixture_replacement].nil?
+ template 'fixtures.yml', File.join('test/fixtures', "#{table_name}.yml")
+ end
+ end
+ end
+ end
+end
diff --git a/railties/lib/generators/test_unit/model/templates/fixtures.yml b/railties/lib/generators/test_unit/model/templates/fixtures.yml
new file mode 100644
index 0000000000..c21035113e
--- /dev/null
+++ b/railties/lib/generators/test_unit/model/templates/fixtures.yml
@@ -0,0 +1,19 @@
+# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
+
+<% unless attributes.empty? -%>
+one:
+<% for attribute in attributes -%>
+ <%= attribute.name %>: <%= attribute.default %>
+<% end -%>
+
+two:
+<% for attribute in attributes -%>
+ <%= attribute.name %>: <%= attribute.default %>
+<% end -%>
+<% else -%>
+# one:
+# column: value
+#
+# two:
+# column: value
+<% end -%>
diff --git a/railties/lib/generators/test_unit/model/templates/unit_test.rb b/railties/lib/generators/test_unit/model/templates/unit_test.rb
new file mode 100644
index 0000000000..3e0bc29d3a
--- /dev/null
+++ b/railties/lib/generators/test_unit/model/templates/unit_test.rb
@@ -0,0 +1,8 @@
+require 'test_helper'
+
+class <%= class_name %>Test < ActiveSupport::TestCase
+ # Replace this with your real tests.
+ test "the truth" do
+ assert true
+ end
+end
diff --git a/railties/lib/generators/test_unit/observer/observer_generator.rb b/railties/lib/generators/test_unit/observer/observer_generator.rb
new file mode 100644
index 0000000000..48742f4b70
--- /dev/null
+++ b/railties/lib/generators/test_unit/observer/observer_generator.rb
@@ -0,0 +1,11 @@
+require 'generators/test_unit'
+
+module TestUnit
+ module Generators
+ class ObserverGenerator < Base
+ def create_test_files
+ template 'unit_test.rb', File.join('test', 'unit', class_path, "#{file_name}_observer_test.rb")
+ end
+ end
+ end
+end
diff --git a/railties/lib/generators/test_unit/observer/templates/unit_test.rb b/railties/lib/generators/test_unit/observer/templates/unit_test.rb
new file mode 100644
index 0000000000..03f6d5666e
--- /dev/null
+++ b/railties/lib/generators/test_unit/observer/templates/unit_test.rb
@@ -0,0 +1,8 @@
+require 'test_helper'
+
+class <%= class_name %>ObserverTest < ActiveSupport::TestCase
+ # Replace this with your real tests.
+ test "the truth" do
+ assert true
+ end
+end
diff --git a/railties/lib/generators/test_unit/plugin/plugin_generator.rb b/railties/lib/generators/test_unit/plugin/plugin_generator.rb
new file mode 100644
index 0000000000..9c08dc4d50
--- /dev/null
+++ b/railties/lib/generators/test_unit/plugin/plugin_generator.rb
@@ -0,0 +1,11 @@
+require 'generators/test_unit'
+
+module TestUnit
+ module Generators
+ class PluginGenerator < Base
+ def create_test_files
+ directory 'test'
+ end
+ end
+ end
+end
diff --git a/railties/lib/generators/test_unit/plugin/templates/test/%file_name%_test.rb.tt b/railties/lib/generators/test_unit/plugin/templates/test/%file_name%_test.rb.tt
new file mode 100644
index 0000000000..3e0bc29d3a
--- /dev/null
+++ b/railties/lib/generators/test_unit/plugin/templates/test/%file_name%_test.rb.tt
@@ -0,0 +1,8 @@
+require 'test_helper'
+
+class <%= class_name %>Test < ActiveSupport::TestCase
+ # Replace this with your real tests.
+ test "the truth" do
+ assert true
+ end
+end
diff --git a/railties/lib/generators/test_unit/plugin/templates/test/test_helper.rb b/railties/lib/generators/test_unit/plugin/templates/test/test_helper.rb
new file mode 100644
index 0000000000..cf148b8b47
--- /dev/null
+++ b/railties/lib/generators/test_unit/plugin/templates/test/test_helper.rb
@@ -0,0 +1,3 @@
+require 'rubygems'
+require 'active_support'
+require 'active_support/test_case' \ No newline at end of file
diff --git a/railties/lib/rails_generator/generators/applications/app/app_generator.rb b/railties/lib/rails_generator/generators/applications/app/app_generator.rb
deleted file mode 100644
index c8c2239f34..0000000000
--- a/railties/lib/rails_generator/generators/applications/app/app_generator.rb
+++ /dev/null
@@ -1,263 +0,0 @@
-require 'rbconfig'
-require File.dirname(__FILE__) + '/template_runner'
-require 'digest/md5'
-require 'active_support/secure_random'
-
-class AppGenerator < Rails::Generator::Base
- DEFAULT_SHEBANG = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])
-
- DATABASES = %w( mysql oracle postgresql sqlite2 sqlite3 frontbase ibm_db )
- DEFAULT_DATABASE = 'sqlite3'
-
- mandatory_options :source => "#{File.dirname(__FILE__)}/../../../../.."
- default_options :db => (ENV["RAILS_DEFAULT_DATABASE"] || DEFAULT_DATABASE),
- :shebang => DEFAULT_SHEBANG, :with_dispatchers => false, :freeze => false
-
-
- def initialize(runtime_args, runtime_options = {})
- super
-
- usage if args.empty?
- usage("Databases supported for preconfiguration are: #{DATABASES.join(", ")}") if (options[:db] && !DATABASES.include?(options[:db]))
-
- @destination_root = args.shift
- @app_name = File.basename(File.expand_path(@destination_root))
- end
-
- def manifest
- record do |m|
- create_directories(m)
- create_root_files(m)
- create_app_files(m)
- create_config_files(m)
- create_script_files(m)
- create_test_files(m)
- create_public_files(m)
- create_documentation_file(m)
- create_log_files(m)
- end
- end
-
- def after_generate
- if options[:template]
- Rails::TemplateRunner.new(options[:template], @destination_root)
- end
- end
-
- protected
- def banner
- "Usage: #{$0} /path/to/your/app [options]"
- end
-
- def add_options!(opt)
- opt.separator ''
- opt.separator 'Options:'
- opt.on("-r", "--ruby=path", String,
- "Path to the Ruby binary of your choice (otherwise scripts use env, dispatchers current path).",
- "Default: #{DEFAULT_SHEBANG}") { |v| options[:shebang] = v }
-
- opt.on("-d", "--database=name", String,
- "Preconfigure for selected database (options: #{DATABASES.join('/')}).",
- "Default: #{DEFAULT_DATABASE}") { |v| options[:db] = v }
-
- opt.on("-D", "--with-dispatchers",
- "Add CGI/FastCGI/mod_ruby dispatches code to generated application skeleton",
- "Default: false") { |v| options[:with_dispatchers] = v }
-
- opt.on("-f", "--freeze",
- "Freeze Rails in vendor/rails from the gems generating the skeleton",
- "Default: false") { |v| options[:freeze] = v }
-
- opt.on("-m", "--template=path", String,
- "Use an application template that lives at path (can be a filesystem path or URL).",
- "Default: (none)") { |v| options[:template] = v }
-
- end
-
-
- private
- def create_directories(m)
- m.directory ''
-
- # Intermediate directories are automatically created so don't sweat their absence here.
- %w(
- app/controllers
- app/helpers
- app/models
- app/views/layouts
- config/environments
- config/initializers
- config/locales
- db
- doc
- lib
- lib/tasks
- log
- public/images
- public/javascripts
- public/stylesheets
- script/performance
- test/fixtures
- test/functional
- test/integration
- test/performance
- test/unit
- vendor
- vendor/plugins
- tmp/sessions
- tmp/sockets
- tmp/cache
- tmp/pids
- ).each { |path| m.directory(path) }
- end
-
- def create_root_files(m)
- m.file "fresh_rakefile", "Rakefile"
- m.file "README", "README"
- end
-
- def create_app_files(m)
- m.file "helpers/application_controller.rb", "app/controllers/application_controller.rb"
- m.file "helpers/application_helper.rb", "app/helpers/application_helper.rb"
- end
-
- def create_config_files(m)
- create_database_configuration_file(m)
- create_routes_file(m)
- create_locale_file(m)
- create_seeds_file(m)
- create_initializer_files(m)
- create_environment_files(m)
- end
-
- def create_documentation_file(m)
- m.file "doc/README_FOR_APP", "doc/README_FOR_APP"
- end
-
- def create_log_files(m)
- %w( server production development test ).each do |file|
- m.file "configs/empty.log", "log/#{file}.log", :chmod => 0666
- end
- end
-
- def create_public_files(m)
- create_dispatch_files(m)
- create_error_files(m)
- create_welcome_file(m)
- create_browser_convention_files(m)
- create_rails_image(m)
- create_javascript_files(m)
- end
-
- def create_script_files(m)
- %w(
- about console dbconsole destroy generate runner server plugin
- performance/benchmarker performance/profiler
- ).each do |file|
- m.file "bin/#{file}", "script/#{file}", {
- :chmod => 0755,
- :shebang => options[:shebang] == DEFAULT_SHEBANG ? nil : options[:shebang]
- }
- end
- end
-
- def create_test_files(m)
- m.file "helpers/test_helper.rb", "test/test_helper.rb"
- m.file "helpers/performance_test.rb", "test/performance/browsing_test.rb"
- end
-
-
- def create_database_configuration_file(m)
- m.template "configs/databases/#{options[:db]}.yml", "config/database.yml", :assigns => {
- :app_name => @app_name,
- :socket => options[:db] == "mysql" ? mysql_socket_location : nil }
- end
-
- def create_routes_file(m)
- m.file "configs/routes.rb", "config/routes.rb"
- end
-
- def create_seeds_file(m)
- m.file "configs/seeds.rb", "db/seeds.rb"
- end
-
- def create_initializer_files(m)
- %w(
- backtrace_silencers
- inflections
- mime_types
- new_rails_defaults
- ).each do |initializer|
- m.file "configs/initializers/#{initializer}.rb", "config/initializers/#{initializer}.rb"
- end
-
- m.template "configs/initializers/session_store.rb", "config/initializers/session_store.rb",
- :assigns => { :app_name => @app_name, :app_secret => ActiveSupport::SecureRandom.hex(64) }
- end
-
- def create_locale_file(m)
- m.file "configs/locales/en.yml", "config/locales/en.yml"
- end
-
- def create_environment_files(m)
- m.template "environments/environment.rb", "config/environment.rb",
- :assigns => { :freeze => options[:freeze] }
-
- m.file "environments/boot.rb", "config/boot.rb"
- m.file "environments/production.rb", "config/environments/production.rb"
- m.file "environments/development.rb", "config/environments/development.rb"
- m.file "environments/test.rb", "config/environments/test.rb"
- end
-
-
- def create_dispatch_files(m)
- if options[:with_dispatchers]
- dispatcher_options = { :chmod => 0755, :shebang => options[:shebang] }
-
- m.file "dispatches/config.ru", "config.ru"
- m.file "dispatches/dispatch.rb", "public/dispatch.rb", dispatcher_options
- m.file "dispatches/dispatch.rb", "public/dispatch.cgi", dispatcher_options
- m.file "dispatches/dispatch.fcgi", "public/dispatch.fcgi", dispatcher_options
- end
- end
-
- def create_error_files(m)
- %w( 404 422 500 ).each do |file|
- m.file "html/#{file}.html", "public/#{file}.html"
- end
- end
-
- def create_welcome_file(m)
- m.file 'html/index.html', 'public/index.html'
- end
-
- def create_browser_convention_files(m)
- m.file "html/favicon.ico", "public/favicon.ico"
- m.file "html/robots.txt", "public/robots.txt"
- end
-
- def create_rails_image(m)
- m.file "html/images/rails.png", "public/images/rails.png"
- end
-
- def create_javascript_files(m)
- %w( prototype effects dragdrop controls application ).each do |javascript|
- m.file "html/javascripts/#{javascript}.js", "public/javascripts/#{javascript}.js"
- end
- end
-
-
- def mysql_socket_location
- [
- "/tmp/mysql.sock", # default
- "/var/run/mysqld/mysqld.sock", # debian/gentoo
- "/var/tmp/mysql.sock", # freebsd
- "/var/lib/mysql/mysql.sock", # fedora
- "/opt/local/lib/mysql/mysql.sock", # fedora
- "/opt/local/var/run/mysqld/mysqld.sock", # mac + darwinports + mysql
- "/opt/local/var/run/mysql4/mysqld.sock", # mac + darwinports + mysql4
- "/opt/local/var/run/mysql5/mysqld.sock", # mac + darwinports + mysql5
- "/opt/lampp/var/mysql/mysql.sock" # xampp for linux
- ].find { |f| File.exist?(f) } unless RUBY_PLATFORM =~ /(:?mswin|mingw)/
- end
-end \ No newline at end of file
diff --git a/railties/lib/rails_generator/generators/applications/app/scm/git.rb b/railties/lib/rails_generator/generators/applications/app/scm/git.rb
deleted file mode 100644
index 445de6ab42..0000000000
--- a/railties/lib/rails_generator/generators/applications/app/scm/git.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-module Rails
- class Git < Scm
- def self.clone(repos, branch=nil)
- `git clone #{repos}`
-
- if branch
- `cd #{repos.split('/').last}/`
- `git checkout #{branch}`
- end
- end
-
- def self.run(command)
- `git #{command}`
- end
- end
-end \ No newline at end of file
diff --git a/railties/lib/rails_generator/generators/applications/app/scm/scm.rb b/railties/lib/rails_generator/generators/applications/app/scm/scm.rb
deleted file mode 100644
index f6c08cad39..0000000000
--- a/railties/lib/rails_generator/generators/applications/app/scm/scm.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-module Rails
- class Scm
- private
- def self.hash_to_parameters(hash)
- hash.collect { |key, value| "--#{key} #{(value.kind_of?(String) ? value : "")}"}.join(" ")
- end
- end
-end \ No newline at end of file
diff --git a/railties/lib/rails_generator/generators/applications/app/scm/svn.rb b/railties/lib/rails_generator/generators/applications/app/scm/svn.rb
deleted file mode 100644
index 22b5966d25..0000000000
--- a/railties/lib/rails_generator/generators/applications/app/scm/svn.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-module Rails
- class Svn < Scm
- def self.checkout(repos, branch = nil)
- `svn checkout #{repos}/#{branch || "trunk"}`
- end
- end
-end \ No newline at end of file
diff --git a/railties/lib/rails_generator/generators/applications/app/template_runner.rb b/railties/lib/rails_generator/generators/applications/app/template_runner.rb
deleted file mode 100644
index 0e24d11950..0000000000
--- a/railties/lib/rails_generator/generators/applications/app/template_runner.rb
+++ /dev/null
@@ -1,401 +0,0 @@
-require File.dirname(__FILE__) + '/scm/scm'
-require File.dirname(__FILE__) + '/scm/git'
-require File.dirname(__FILE__) + '/scm/svn'
-
-require 'open-uri'
-require 'fileutils'
-
-module Rails
- class TemplateRunner
- attr_reader :root
- attr_writer :logger
-
- def initialize(template, root = '') # :nodoc:
- @root = File.expand_path(File.directory?(root) ? root : File.join(Dir.pwd, root))
-
- log 'applying', "template: #{template}"
-
- load_template(template)
-
- log 'applied', "#{template}"
- end
-
- def load_template(template)
- begin
- code = open(template).read
- in_root { self.instance_eval(code) }
- rescue LoadError, Errno::ENOENT => e
- raise "The template [#{template}] could not be loaded. Error: #{e}"
- end
- end
-
- # Create a new file in the Rails project folder. Specify the
- # relative path from RAILS_ROOT. Data is the return value of a block
- # or a data string.
- #
- # ==== Examples
- #
- # file("lib/fun_party.rb") do
- # hostname = ask("What is the virtual hostname I should use?")
- # "vhost.name = #{hostname}"
- # end
- #
- # file("config/apach.conf", "your apache config")
- #
- def file(filename, data = nil, log_action = true, &block)
- log 'file', filename if log_action
- dir, file = [File.dirname(filename), File.basename(filename)]
-
- inside(dir) do
- File.open(file, "w") do |f|
- if block_given?
- f.write(block.call)
- else
- f.write(data)
- end
- end
- end
- end
-
- # Install a plugin. You must provide either a Subversion url or Git url.
- # For a Git-hosted plugin, you can specify if it should be added as a submodule instead of cloned.
- #
- # ==== Examples
- #
- # plugin 'restful-authentication', :git => 'git://github.com/technoweenie/restful-authentication.git'
- # plugin 'restful-authentication', :git => 'git://github.com/technoweenie/restful-authentication.git', :submodule => true
- # plugin 'restful-authentication', :svn => 'svn://svnhub.com/technoweenie/restful-authentication/trunk'
- #
- def plugin(name, options)
- log 'plugin', name
-
- if options[:git] && options[:submodule]
- in_root do
- Git.run("submodule add #{options[:git]} vendor/plugins/#{name}")
- end
- elsif options[:git] || options[:svn]
- in_root do
- run_ruby_script("script/plugin install #{options[:svn] || options[:git]}", false)
- end
- else
- log "! no git or svn provided for #{name}. skipping..."
- end
- end
-
- # Adds an entry into config/environment.rb for the supplied gem :
- def gem(name, options = {})
- log 'gem', name
- env = options.delete(:env)
-
- gems_code = "config.gem '#{name}'"
-
- if options.any?
- opts = options.inject([]) {|result, h| result << [":#{h[0]} => #{h[1].inspect.gsub('"',"'")}"] }.sort.join(", ")
- gems_code << ", #{opts}"
- end
-
- environment gems_code, :env => env
- end
-
- # Adds a line inside the Initializer block for config/environment.rb. Used by #gem
- # If options :env is specified, the line is appended to the corresponding
- # file in config/environments/#{env}.rb
- def environment(data = nil, options = {}, &block)
- sentinel = 'Rails::Initializer.run do |config|'
-
- data = block.call if !data && block_given?
-
- in_root do
- if options[:env].nil?
- gsub_file 'config/environment.rb', /(#{Regexp.escape(sentinel)})/mi do |match|
- "#{match}\n " << data
- end
- else
- Array.wrap(options[:env]).each do|env|
- append_file "config/environments/#{env}.rb", "\n#{data}"
- end
- end
- end
- end
-
- # Run a command in git.
- #
- # ==== Examples
- #
- # git :init
- # git :add => "this.file that.rb"
- # git :add => "onefile.rb", :rm => "badfile.cxx"
- #
- def git(command = {})
- in_root do
- if command.is_a?(Symbol)
- log 'running', "git #{command}"
- Git.run(command.to_s)
- else
- command.each do |command, options|
- log 'running', "git #{command} #{options}"
- Git.run("#{command} #{options}")
- end
- end
- end
- end
-
- # Create a new file in the vendor/ directory. Code can be specified
- # in a block or a data string can be given.
- #
- # ==== Examples
- #
- # vendor("sekrit.rb") do
- # sekrit_salt = "#{Time.now}--#{3.years.ago}--#{rand}--"
- # "salt = '#{sekrit_salt}'"
- # end
- #
- # vendor("foreign.rb", "# Foreign code is fun")
- #
- def vendor(filename, data = nil, &block)
- log 'vendoring', filename
- file("vendor/#{filename}", data, false, &block)
- end
-
- # Create a new file in the lib/ directory. Code can be specified
- # in a block or a data string can be given.
- #
- # ==== Examples
- #
- # lib("crypto.rb") do
- # "crypted_special_value = '#{rand}--#{Time.now}--#{rand(1337)}--'"
- # end
- #
- # lib("foreign.rb", "# Foreign code is fun")
- #
- def lib(filename, data = nil, &block)
- log 'lib', filename
- file("lib/#{filename}", data, false, &block)
- end
-
- # Create a new Rakefile with the provided code (either in a block or a string).
- #
- # ==== Examples
- #
- # rakefile("bootstrap.rake") do
- # project = ask("What is the UNIX name of your project?")
- #
- # <<-TASK
- # namespace :#{project} do
- # task :bootstrap do
- # puts "i like boots!"
- # end
- # end
- # TASK
- # end
- #
- # rakefile("seed.rake", "puts 'im plantin ur seedz'")
- #
- def rakefile(filename, data = nil, &block)
- log 'rakefile', filename
- file("lib/tasks/#{filename}", data, false, &block)
- end
-
- # Create a new initializer with the provided code (either in a block or a string).
- #
- # ==== Examples
- #
- # initializer("globals.rb") do
- # data = ""
- #
- # ['MY_WORK', 'ADMINS', 'BEST_COMPANY_EVAR'].each do
- # data << "#{const} = :entp"
- # end
- #
- # data
- # end
- #
- # initializer("api.rb", "API_KEY = '123456'")
- #
- def initializer(filename, data = nil, &block)
- log 'initializer', filename
- file("config/initializers/#{filename}", data, false, &block)
- end
-
- # Generate something using a generator from Rails or a plugin.
- # The second parameter is the argument string that is passed to
- # the generator or an Array that is joined.
- #
- # ==== Example
- #
- # generate(:authenticated, "user session")
- #
- def generate(what, *args)
- log 'generating', what
- argument = args.map {|arg| arg.to_s }.flatten.join(" ")
-
- in_root { run_ruby_script("script/generate #{what} #{argument}", false) }
- end
-
- # Executes a command
- #
- # ==== Example
- #
- # inside('vendor') do
- # run('ln -s ~/edge rails)
- # end
- #
- def run(command, log_action = true)
- log 'executing', "#{command} from #{Dir.pwd}" if log_action
- `#{command}`
- end
-
- # Executes a ruby script (taking into account WIN32 platform quirks)
- def run_ruby_script(command, log_action = true)
- ruby_command = RUBY_PLATFORM=~ /win32/ ? 'ruby ' : ''
- run("#{ruby_command}#{command}", log_action)
- end
-
- # Runs the supplied rake task
- #
- # ==== Example
- #
- # rake("db:migrate")
- # rake("db:migrate", :env => "production")
- # rake("gems:install", :sudo => true)
- #
- def rake(command, options = {})
- log 'rake', command
- env = options[:env] || 'development'
- sudo = options[:sudo] ? 'sudo ' : ''
- in_root { run("#{sudo}rake #{command} RAILS_ENV=#{env}", false) }
- end
-
- # Just run the capify command in root
- #
- # ==== Example
- #
- # capify!
- #
- def capify!
- log 'capifying'
- in_root { run('capify .', false) }
- end
-
- # Add Rails to /vendor/rails
- #
- # ==== Example
- #
- # freeze!
- #
- def freeze!(args = {})
- log 'vendor', 'rails edge'
- in_root { run('rake rails:freeze:edge', false) }
- end
-
- # Make an entry in Rails routing file conifg/routes.rb
- #
- # === Example
- #
- # route "map.root :controller => :welcome"
- #
- def route(routing_code)
- log 'route', routing_code
- sentinel = 'ActionController::Routing::Routes.draw do |map|'
-
- in_root do
- gsub_file 'config/routes.rb', /(#{Regexp.escape(sentinel)})/mi do |match|
- "#{match}\n #{routing_code}\n"
- end
- end
- end
-
- protected
-
- # Get a user's input
- #
- # ==== Example
- #
- # answer = ask("Should I freeze the latest Rails?")
- # freeze! if ask("Should I freeze the latest Rails?") == "yes"
- #
- def ask(string)
- log '', string
- STDIN.gets.strip
- end
-
- # Do something in the root of the Rails application or
- # a provided subfolder; the full path is yielded to the block you provide.
- # The path is set back to the previous path when the method exits.
- def inside(dir = '', &block)
- folder = File.join(root, dir)
- FileUtils.mkdir_p(folder) unless File.exist?(folder)
- FileUtils.cd(folder) { block.arity == 1 ? yield(folder) : yield }
- end
-
- def in_root
- FileUtils.cd(root) { yield }
- end
-
- # Helper to test if the user says yes(y)?
- #
- # ==== Example
- #
- # freeze! if yes?("Should I freeze the latest Rails?")
- #
- def yes?(question)
- answer = ask(question).downcase
- answer == "y" || answer == "yes"
- end
-
- # Helper to test if the user does NOT say yes(y)?
- #
- # ==== Example
- #
- # capify! if no?("Will you be using vlad to deploy your application?")
- #
- def no?(question)
- !yes?(question)
- end
-
- # Run a regular expression replacement on a file
- #
- # ==== Example
- #
- # gsub_file 'app/controllers/application_controller.rb', /#\s*(filter_parameter_logging :password)/, '\1'
- #
- def gsub_file(relative_destination, regexp, *args, &block)
- path = destination_path(relative_destination)
- content = File.read(path).gsub(regexp, *args, &block)
- File.open(path, 'wb') { |file| file.write(content) }
- end
-
- # Append text to a file
- #
- # ==== Example
- #
- # append_file 'config/environments/test.rb', 'config.gem "rspec"'
- #
- def append_file(relative_destination, data)
- path = destination_path(relative_destination)
- File.open(path, 'ab') { |file| file.write(data) }
- end
-
- def destination_path(relative_destination)
- File.join(root, relative_destination)
- end
-
- def log(action, message = '')
- logger.log(action, message)
- end
-
- def logger
- @logger ||= Rails::Generator::Base.logger
- end
-
- def logger
- @logger ||= if defined?(Rails::Generator::Base)
- Rails::Generator::Base.logger
- else
- require 'rails_generator/simple_logger'
- Rails::Generator::SimpleLogger.new(STDOUT)
- end
- end
-
- end
-end
diff --git a/railties/lib/rails_generator/secret_key_generator.rb b/railties/lib/rails_generator/secret_key_generator.rb
deleted file mode 100644
index 7dd495a2f5..0000000000
--- a/railties/lib/rails_generator/secret_key_generator.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-require 'active_support/deprecation'
-
-module Rails
- # A class for creating random secret keys. This class will do its best to create a
- # random secret key that's as secure as possible, using whatever methods are
- # available on the current platform. For example:
- #
- # generator = Rails::SecretKeyGenerator("some unique identifier, such as the application name")
- # generator.generate_secret # => "f3f1be90053fa851... (some long string)"
- #
- # This class is *deprecated* in Rails 2.2 in favor of ActiveSupport::SecureRandom.
- # It is currently a wrapper around ActiveSupport::SecureRandom.
- class SecretKeyGenerator
- def initialize(identifier)
- end
-
- # Generate a random secret key with the best possible method available on
- # the current platform.
- def generate_secret
- ActiveSupport::SecureRandom.hex(64)
- end
- deprecate :generate_secret=>"You should use ActiveSupport::SecureRandom.hex(64)"
- end
-end
diff --git a/railties/test/boot_test.rb b/railties/test/boot_test.rb
index 2dd68857c3..7bf420d4f2 100644
--- a/railties/test/boot_test.rb
+++ b/railties/test/boot_test.rb
@@ -1,6 +1,6 @@
require 'abstract_unit'
require 'initializer'
-require "#{File.dirname(__FILE__)}/../environments/boot"
+require "#{File.dirname(__FILE__)}/../lib/generators/rails/app/templates/config/boot"
require 'rails/gem_dependency'
class BootTest < Test::Unit::TestCase
diff --git a/railties/test/generators/actions_test.rb b/railties/test/generators/actions_test.rb
new file mode 100644
index 0000000000..baf687336a
--- /dev/null
+++ b/railties/test/generators/actions_test.rb
@@ -0,0 +1,185 @@
+require 'abstract_unit'
+require 'generators/generators_test_helper'
+require 'generators/rails/app/app_generator'
+
+class ActionsTest < GeneratorsTestCase
+ def setup
+ super
+ @git_plugin_uri = 'git://github.com/technoweenie/restful-authentication.git'
+ @svn_plugin_uri = 'svn://svnhub.com/technoweenie/restful-authentication/trunk'
+ end
+
+ def test_apply_loads_and_evaluates_a_template
+ template = <<-TEMPLATE
+ @foo = "FOO"
+ TEMPLATE
+ template.instance_eval "def read; self; end" # Make the string respond to read
+
+ generator.expects(:open).with("http://gist.github.com/103208.txt").returns(template)
+ action :apply, "http://gist.github.com/103208.txt"
+ assert_equal generator.instance_variable_get("@foo"), "FOO"
+ end
+
+ def test_create_file_should_write_data_to_file_path
+ action :create_file, 'lib/test_file.rb', 'heres test data'
+ assert_file 'lib/test_file.rb', 'heres test data'
+ end
+
+ def test_create_file_should_write_block_contents_to_file_path
+ action(:create_file, 'lib/test_file.rb'){ 'heres block data' }
+ assert_file 'lib/test_file.rb', 'heres block data'
+ end
+
+ def test_plugin_with_git_option_should_run_plugin_install
+ generator.expects(:run).once.with("ruby script/plugin install #{@git_plugin_uri}", false)
+ action :plugin, 'restful-authentication', :git => @git_plugin_uri
+ end
+
+ def test_plugin_with_svn_option_should_run_plugin_install
+ generator.expects(:run).once.with("ruby script/plugin install #{@svn_plugin_uri}", false)
+ action :plugin, 'restful-authentication', :svn => @svn_plugin_uri
+ end
+
+ def test_plugin_with_git_option_and_submodule_should_use_git_scm
+ generator.expects(:run).with("git submodule add #{@git_plugin_uri} vendor/plugins/rest_auth", false)
+ action :plugin, 'rest_auth', :git => @git_plugin_uri, :submodule => true
+ end
+
+ def test_plugin_with_no_options_should_skip_method
+ generator.expects(:run).never
+ action :plugin, 'rest_auth', {}
+ end
+
+ def test_gem_should_put_gem_dependency_in_enviroment
+ run_generator
+ action :gem, 'will-paginate'
+ assert_file 'config/environment.rb', /config\.gem 'will\-paginate'/
+ end
+
+ def test_gem_with_options_should_include_options_in_gem_dependency_in_environment
+ run_generator
+ action :gem, 'mislav-will-paginate', :lib => 'will-paginate', :source => 'http://gems.github.com'
+
+ regexp = /#{Regexp.escape("config.gem 'mislav-will-paginate', :lib => 'will-paginate', :source => 'http://gems.github.com'")}/
+ assert_file 'config/environment.rb', regexp
+ end
+
+ def test_gem_with_env_string_should_put_gem_dependency_in_specified_environment
+ run_generator
+ action :gem, 'rspec', :env => 'test'
+ assert_file 'config/environments/test.rb', /config\.gem 'rspec'/
+ end
+
+ def test_gem_with_env_array_should_put_gem_dependency_in_specified_environments
+ run_generator
+ action :gem, 'quietbacktrace', :env => %w[ development test ]
+ assert_file 'config/environments/development.rb', /config\.gem 'quietbacktrace'/
+ assert_file 'config/environments/test.rb', /config\.gem 'quietbacktrace'/
+ end
+
+ def test_gem_with_lib_option_set_to_false_should_put_gem_dependency_in_enviroment_correctly
+ run_generator
+ action :gem, 'mislav-will-paginate', :lib => false
+ assert_file 'config/environment.rb', /config\.gem 'mislav\-will\-paginate'\, :lib => false/
+ end
+
+ def test_environment_should_include_data_in_environment_initializer_block
+ run_generator
+ load_paths = 'config.load_paths += %w["#{RAILS_ROOT}/app/extras"]'
+ action :environment, load_paths
+ assert_file 'config/environment.rb', /#{Regexp.escape(load_paths)}/
+ end
+
+ def test_environment_with_block_should_include_block_contents_in_environment_initializer_block
+ run_generator
+
+ action :environment do
+ '# This wont be added'
+ '# This will be added'
+ end
+
+ assert_file 'config/environment.rb', /# This will be added/
+ end
+
+ def test_git_with_symbol_should_run_command_using_git_scm
+ generator.expects(:run).once.with('git init')
+ action :git, :init
+ end
+
+ def test_git_with_hash_should_run_each_command_using_git_scm
+ generator.expects(:run).times(2)
+ action :git, :rm => 'README', :add => '.'
+ end
+
+ def test_vendor_should_write_data_to_file_in_vendor
+ action :vendor, 'vendor_file.rb', '# vendor data'
+ assert_file 'vendor/vendor_file.rb', '# vendor data'
+ end
+
+ def test_lib_should_write_data_to_file_in_lib
+ action :lib, 'my_library.rb', 'class MyLibrary'
+ assert_file 'lib/my_library.rb', 'class MyLibrary'
+ end
+
+ def test_rakefile_should_write_date_to_file_in_lib_tasks
+ action :rakefile, 'myapp.rake', 'task :run => [:environment]'
+ assert_file 'lib/tasks/myapp.rake', 'task :run => [:environment]'
+ end
+
+ def test_initializer_should_write_date_to_file_in_config_initializers
+ action :initializer, 'constants.rb', 'MY_CONSTANT = 42'
+ assert_file 'config/initializers/constants.rb', 'MY_CONSTANT = 42'
+ end
+
+ def test_generate_should_run_script_generate_with_argument_and_options
+ generator.expects(:run).once.with('ruby script/generate model MyModel', false)
+ action :generate, 'model', 'MyModel'
+ end
+
+ def test_rake_should_run_rake_command_with_development_env
+ generator.expects(:run).once.with('rake log:clear RAILS_ENV=development', false)
+ action :rake, 'log:clear'
+ end
+
+ def test_rake_with_env_option_should_run_rake_command_in_env
+ generator.expects(:run).once.with('rake log:clear RAILS_ENV=production', false)
+ action :rake, 'log:clear', :env => 'production'
+ end
+
+ def test_rake_with_sudo_option_should_run_rake_command_with_sudo
+ generator.expects(:run).once.with('sudo rake log:clear RAILS_ENV=development', false)
+ action :rake, 'log:clear', :sudo => true
+ end
+
+ def test_capify_should_run_the_capify_command
+ generator.expects(:run).once.with('capify .', false)
+ action :capify!
+ end
+
+ def test_freeze_should_freeze_rails_edge
+ generator.expects(:run).once.with('rake rails:freeze:edge', false)
+ action :freeze!
+ end
+
+ def test_route_should_add_data_to_the_routes_block_in_config_routes
+ run_generator
+ route_command = "map.route '/login', :controller => 'sessions', :action => 'new'"
+ action :route, route_command
+ assert_file 'config/routes.rb', /#{Regexp.escape(route_command)}/
+ end
+
+ protected
+
+ def run_generator
+ silence(:stdout) { Rails::Generators::AppGenerator.start [destination_root] }
+ end
+
+ def generator(config={})
+ @generator ||= Rails::Generators::Base.new([], {}, { :root => destination_root }.merge!(config))
+ end
+
+ def action(*args, &block)
+ silence(:stdout){ generator.send(*args, &block) }
+ end
+
+end
diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb
new file mode 100644
index 0000000000..98994f6ad2
--- /dev/null
+++ b/railties/test/generators/app_generator_test.rb
@@ -0,0 +1,166 @@
+require 'abstract_unit'
+require 'generators/generators_test_helper'
+require 'generators/rails/app/app_generator'
+
+class AppGeneratorTest < GeneratorsTestCase
+
+ def setup
+ super
+ Rails::Generators::AppGenerator.instance_variable_set('@desc', nil)
+ end
+
+ def teardown
+ super
+ Rails::Generators::AppGenerator.instance_variable_set('@desc', nil)
+ end
+
+ def test_application_skeleton_is_created
+ run_generator
+
+ %w(
+ app/controllers
+ app/helpers
+ app/models
+ app/views/layouts
+ config/environments
+ config/initializers
+ config/locales
+ db
+ doc
+ lib
+ lib/tasks
+ log
+ public/images
+ public/javascripts
+ public/stylesheets
+ script/performance
+ test/fixtures
+ test/functional
+ test/integration
+ test/performance
+ test/unit
+ vendor
+ vendor/plugins
+ tmp/sessions
+ tmp/sockets
+ tmp/cache
+ tmp/pids
+ ).each{ |path| assert_file path }
+ end
+
+ def test_invalid_database_option_raises_an_error
+ content = capture(:stderr){ run_generator(["-d", "unknown"]) }
+ assert_match /Invalid value for \-\-database option/, content
+ end
+
+ def test_dispatchers_are_not_added_by_default
+ run_generator
+ assert_no_file "config.ru"
+ assert_no_file "public/dispatch.cgi"
+ assert_no_file "public/dispatch.fcgi"
+ end
+
+ def test_dispatchers_are_added_if_required
+ run_generator ["--with-dispatchers"]
+ assert_file "config.ru"
+ assert_file "public/dispatch.cgi"
+ assert_file "public/dispatch.fcgi"
+ end
+
+ def test_config_database_is_added_by_default
+ run_generator
+ assert_file "config/database.yml", /sqlite3/
+ end
+
+ def test_config_database_is_not_added_if_skip_activerecord_is_given
+ run_generator ["--skip-activerecord"]
+ assert_no_file "config/database.yml"
+ end
+
+ def test_activerecord_is_removed_from_frameworks_if_skip_activerecord_is_given
+ run_generator ["--skip-activerecord"]
+ assert_file "config/environment.rb", /config\.frameworks \-= \[ :active_record \]/
+ end
+
+ def test_prototype_and_test_unit_are_added_by_default
+ run_generator
+ assert_file "public/javascripts/prototype.js"
+ assert_file "test"
+ end
+
+ def test_prototype_and_test_unit_are_skipped_if_required
+ run_generator ["--skip-prototype", "--skip-testunit"]
+ assert_no_file "public/javascripts/prototype.js"
+ assert_no_file "test"
+ end
+
+ def test_shebang_is_added_to_files
+ run_generator ["--ruby", "foo/bar/baz"]
+
+ %w(
+ about
+ console
+ dbconsole
+ destroy
+ generate
+ plugin
+ runner
+ server
+ ).each { |path| assert_file "script/#{path}", /#!foo\/bar\/baz/ }
+ end
+
+ def test_rails_is_frozen
+ generator(:freeze => true, :database => "sqlite3").expects(:run).with("rake rails:freeze:edge", false)
+ silence(:stdout){ generator.invoke }
+ assert_file 'config/environment.rb', /# RAILS_GEM_VERSION/
+ end
+
+ def test_template_raises_an_error_with_invalid_path
+ content = capture(:stderr){ run_generator(["-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(:template => path, :database => "sqlite3").expects(:open).with(path).returns(template)
+ assert_match /It works!/, silence(:stdout){ generator.invoke }
+ end
+
+ def test_usage_read_from_file
+ File.expects(:read).returns("USAGE FROM FILE")
+ assert_equal "USAGE FROM FILE", Rails::Generators::AppGenerator.desc
+ end
+
+ def test_default_usage
+ File.expects(:exist?).returns(false)
+ assert_match /Create rails files for app generator/, Rails::Generators::AppGenerator.desc
+ end
+
+ def test_default_namespace
+ assert_match "rails:generators:app", Rails::Generators::AppGenerator.namespace
+ end
+
+ def test_file_is_added_for_backwards_compatibility
+ action :file, 'lib/test_file.rb', 'heres test data'
+ assert_file 'lib/test_file.rb', 'heres test data'
+ end
+
+ protected
+
+ def run_generator(args=[])
+ silence(:stdout) { Rails::Generators::AppGenerator.start [destination_root].concat(args) }
+ end
+
+ def generator(options={})
+ @generator ||= Rails::Generators::AppGenerator.new([destination_root], options, :root => destination_root)
+ end
+
+ def action(*args, &block)
+ silence(:stdout){ generator.send(*args, &block) }
+ end
+
+end
diff --git a/railties/test/generators/controller_generator_test.rb b/railties/test/generators/controller_generator_test.rb
new file mode 100644
index 0000000000..e3fe2594b9
--- /dev/null
+++ b/railties/test/generators/controller_generator_test.rb
@@ -0,0 +1,83 @@
+require 'abstract_unit'
+require 'generators/generators_test_helper'
+require 'generators/erb/controller/controller_generator'
+require 'generators/rails/controller/controller_generator'
+require 'generators/rails/helper/helper_generator'
+require 'generators/test_unit/controller/controller_generator'
+require 'generators/test_unit/helper/helper_generator'
+
+ObjectController = Class.new
+
+class ControllerGeneratorTest < GeneratorsTestCase
+
+ def test_help_does_not_show_invoked_generators_options_if_they_already_exist
+ content = run_generator ["--help"]
+ assert_no_match /Helper options:/, content
+ end
+
+ def test_controller_skeleton_is_created
+ run_generator
+ assert_file "app/controllers/account_controller.rb", /class AccountController < ApplicationController/
+ end
+
+ def test_check_class_collision
+ content = capture(:stderr){ run_generator ["object"] }
+ assert_match /The name 'ObjectController' is either already used in your application or reserved/, content
+ end
+
+ # No need to spec content since it's already spec'ed on helper generator.
+ #
+ def test_invokes_helper
+ run_generator
+ assert_file "app/helpers/account_helper.rb"
+ assert_file "test/unit/helpers/account_helper_test.rb"
+ end
+
+ def test_does_not_invoke_helper_if_required
+ run_generator ["account", "--skip-helper"]
+ assert_no_file "app/helpers/account_helper.rb"
+ assert_no_file "test/unit/helpers/account_helper_test.rb"
+ end
+
+ def test_invokes_default_test_framework
+ run_generator
+ assert_file "test/functional/account_controller_test.rb"
+ end
+
+ def test_does_not_invoke_test_framework_if_required
+ run_generator ["account", "--no-test-framework"]
+ assert_no_file "test/functional/account_controller_test.rb"
+ end
+
+ def test_invokes_default_template_engine
+ run_generator
+ assert_file "app/views/account/foo.html.erb", /app\/views\/account\/foo/
+ assert_file "app/views/account/bar.html.erb", /app\/views\/account\/bar/
+ end
+
+ def test_invokes_default_template_engine_even_with_no_action
+ run_generator ["account"]
+ assert_file "app/views/account"
+ end
+
+ def test_template_engine_with_class_path
+ run_generator ["admin/account"]
+ assert_file "app/views/admin/account"
+ end
+
+ def test_actions_are_turned_into_methods
+ run_generator
+
+ assert_file "app/controllers/account_controller.rb" do |controller|
+ assert_instance_method controller, :foo
+ assert_instance_method controller, :bar
+ end
+ end
+
+ protected
+
+ def run_generator(args=["Account", "foo", "bar"])
+ silence(:stdout) { Rails::Generators::ControllerGenerator.start args, :root => destination_root }
+ end
+
+end
diff --git a/railties/test/generators/generators_test_helper.rb b/railties/test/generators/generators_test_helper.rb
new file mode 100644
index 0000000000..591da45c72
--- /dev/null
+++ b/railties/test/generators/generators_test_helper.rb
@@ -0,0 +1,88 @@
+require 'test/unit'
+require 'fileutils'
+
+$LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../../lib"
+require 'generators'
+
+class GeneratorsTestCase < Test::Unit::TestCase
+ include FileUtils
+
+ def destination_root
+ @destination_root ||= File.expand_path("#{File.dirname(__FILE__)}/../fixtures/tmp")
+ end
+
+ def setup
+ rm_rf(destination_root)
+ mkdir_p(destination_root)
+ end
+
+ def test_truth
+ # don't complain, test/unit
+ end
+
+ def capture(stream)
+ begin
+ stream = stream.to_s
+ eval "$#{stream} = StringIO.new"
+ yield
+ result = eval("$#{stream}").string
+ ensure
+ eval("$#{stream} = #{stream.upcase}")
+ end
+
+ result
+ end
+ alias :silence :capture
+
+ def assert_file(relative, *contents)
+ absolute = File.join(destination_root, relative)
+ assert File.exists?(absolute), "Expected file #{relative.inspect} to exist, but does not"
+
+ read = File.read(absolute) if block_given? || !contents.empty?
+ yield read if block_given?
+
+ contents.each do |content|
+ case content
+ when String
+ assert_equal content, read
+ when Regexp
+ assert_match content, read
+ end
+ end
+ end
+
+ def assert_no_file(relative)
+ absolute = File.join(destination_root, relative)
+ assert !File.exists?(absolute), "Expected file #{relative.inspect} to not exist, but does"
+ end
+
+ def assert_migration(relative, *contents, &block)
+ file_name = migration_file_name(relative)
+ assert file_name, "Expected migration #{relative} to exist, but was not found"
+ assert_file File.join(File.dirname(relative), file_name), *contents, &block
+ end
+
+ def assert_no_migration(relative)
+ file_name = migration_file_name(relative)
+ assert_nil file_name, "Expected migration #{relative} to not exist, but found #{file_name}"
+ end
+
+ def assert_class_method(content, method, &block)
+ assert_instance_method content, "self.#{method}", &block
+ end
+
+ def assert_instance_method(content, method)
+ assert_match /def #{method}(.*?)end/m, content
+ yield content.match(/def #{method}(.*?)end/m)[1] if block_given?
+ end
+
+ protected
+
+ def migration_file_name(relative)
+ absolute = File.join(destination_root, relative)
+ dirname, file_name = File.dirname(absolute), File.basename(absolute).sub(/\.rb$/, '')
+
+ migration = Dir.glob("#{dirname}/[0-9]*_*.rb").grep(/\d+_#{file_name}.rb$/).first
+ File.basename(migration) if migration
+ end
+end
diff --git a/railties/test/generators/helper_generator_test.rb b/railties/test/generators/helper_generator_test.rb
new file mode 100644
index 0000000000..41e1e1dce2
--- /dev/null
+++ b/railties/test/generators/helper_generator_test.rb
@@ -0,0 +1,61 @@
+require 'abstract_unit'
+require 'generators/generators_test_helper'
+require 'generators/rails/helper/helper_generator'
+require 'generators/test_unit/helper/helper_generator'
+
+ObjectHelper = Class.new
+AnotherObjectHelperTest = Class.new
+
+class HelperGeneratorTest < GeneratorsTestCase
+
+ def test_helper_skeleton_is_created
+ run_generator
+ assert_file "app/helpers/admin_helper.rb", /module AdminHelper/
+ end
+
+ def test_invokes_default_test_framework
+ run_generator
+ assert_file "test/unit/helpers/admin_helper_test.rb", /class AdminHelperTest < ActionView::TestCase/
+ end
+
+ def test_logs_if_the_test_framework_cannot_be_found
+ content = run_generator ["admin", "--test-framework=unknown"]
+ assert_match /Could not find and invoke 'unknown'/, content
+ end
+
+ def test_check_class_collision
+ content = capture(:stderr){ run_generator ["object"] }
+ assert_match /The name 'ObjectHelper' is either already used in your application or reserved/, content
+ end
+
+ def test_check_class_collision_on_tests
+ content = capture(:stderr){ run_generator ["another_object"] }
+ assert_match /The name 'AnotherObjectHelperTest' is either already used in your application or reserved/, content
+ end
+
+ def test_namespaced_and_not_namespaced_helpers
+ run_generator ["products"]
+
+ # We have to require the generated helper to show the problem because
+ # the test helpers just check for generated files and contents but
+ # do not actually load them. But they have to be loaded (as in a real environment)
+ # to make the second generator run fail
+ require "#{destination_root}/app/helpers/products_helper"
+
+ assert_nothing_raised do
+ begin
+ run_generator ["admin::products"]
+ ensure
+ # cleanup
+ Object.send(:remove_const, :ProductsHelper)
+ end
+ end
+ end
+
+ protected
+
+ def run_generator(args=["admin"])
+ silence(:stdout) { Rails::Generators::HelperGenerator.start args, :root => destination_root }
+ end
+
+end
diff --git a/railties/test/generators/integration_test_generator_test.rb b/railties/test/generators/integration_test_generator_test.rb
new file mode 100644
index 0000000000..1961a102b9
--- /dev/null
+++ b/railties/test/generators/integration_test_generator_test.rb
@@ -0,0 +1,18 @@
+require 'abstract_unit'
+require 'generators/generators_test_helper'
+require 'generators/rails/integration_test/integration_test_generator'
+
+class IntegrationTestGeneratorTest < GeneratorsTestCase
+
+ def test_integration_test_skeleton_is_created
+ run_generator
+ assert_file "test/integration/integration_test.rb", /class IntegrationTest < ActionController::IntegrationTest/
+ end
+
+ protected
+
+ def run_generator(args=["integration"])
+ silence(:stdout) { Rails::Generators::IntegrationTestGenerator.start args, :root => destination_root }
+ end
+
+end
diff --git a/railties/test/generators/mailer_generator_test.rb b/railties/test/generators/mailer_generator_test.rb
new file mode 100644
index 0000000000..5d21da3dd1
--- /dev/null
+++ b/railties/test/generators/mailer_generator_test.rb
@@ -0,0 +1,54 @@
+require 'abstract_unit'
+require 'generators/generators_test_helper'
+require 'generators/erb/mailer/mailer_generator'
+require 'generators/rails/mailer/mailer_generator'
+require 'generators/test_unit/mailer/mailer_generator'
+
+class MailerGeneratorTest < GeneratorsTestCase
+
+ def test_mailer_skeleton_is_created
+ run_generator
+ assert_file "app/models/notifier.rb", /class Notifier < ActionMailer::Base/
+ end
+
+ def test_check_class_collision
+ content = capture(:stderr){ run_generator ["object"] }
+ assert_match /The name 'Object' is either already used in your application or reserved/, content
+ end
+
+ def test_invokes_default_test_framework
+ run_generator
+ assert_file "test/unit/notifier_test.rb", /class NotifierTest < ActionMailer::TestCase/
+ assert_file "test/fixtures/notifier/foo", /app\/views\/notifier\/foo/
+ assert_file "test/fixtures/notifier/bar", /app\/views\/notifier\/bar/
+ end
+
+ def test_invokes_default_template_engine
+ run_generator
+ assert_file "app/views/notifier/foo.erb", /app\/views\/notifier\/foo/
+ assert_file "app/views/notifier/bar.erb", /app\/views\/notifier\/bar/
+ end
+
+ def test_invokes_default_template_engine_even_with_no_action
+ run_generator ["notifier"]
+ assert_file "app/views/notifier"
+ end
+
+ def test_logs_if_the_template_engine_cannot_be_found
+ content = run_generator ["notifier", "foo", "bar", "--template-engine=unknown"]
+ assert_match /Could not find and invoke 'unknown'/, content
+ end
+
+ def test_actions_are_turned_into_methods
+ run_generator
+ assert_file "app/models/notifier.rb", /def foo/
+ assert_file "app/models/notifier.rb", /def bar/
+ end
+
+ protected
+
+ def run_generator(args=["notifier", "foo", "bar"])
+ silence(:stdout) { Rails::Generators::MailerGenerator.start args, :root => destination_root }
+ end
+
+end
diff --git a/railties/test/generators/metal_generator_test.rb b/railties/test/generators/metal_generator_test.rb
new file mode 100644
index 0000000000..4e73883feb
--- /dev/null
+++ b/railties/test/generators/metal_generator_test.rb
@@ -0,0 +1,23 @@
+require 'abstract_unit'
+require 'generators/generators_test_helper'
+require 'generators/rails/metal/metal_generator'
+
+class MetalGeneratorTest < GeneratorsTestCase
+
+ def test_metal_skeleton_is_created
+ run_generator
+ assert_file "app/metal/foo.rb", /class Foo/
+ end
+
+ def test_check_class_collision
+ content = capture(:stderr){ run_generator ["object"] }
+ assert_match /The name 'Object' is either already used in your application or reserved/, content
+ end
+
+ protected
+
+ def run_generator(args=["foo"])
+ silence(:stdout) { Rails::Generators::MetalGenerator.start args, :root => destination_root }
+ end
+
+end
diff --git a/railties/test/generators/migration_generator_test.rb b/railties/test/generators/migration_generator_test.rb
new file mode 100644
index 0000000000..547ca6a9e3
--- /dev/null
+++ b/railties/test/generators/migration_generator_test.rb
@@ -0,0 +1,60 @@
+require 'abstract_unit'
+require 'generators/generators_test_helper'
+require 'generators/active_record/migration/migration_generator'
+require 'generators/rails/migration/migration_generator'
+
+class MigrationGeneratorTest < GeneratorsTestCase
+
+ def test_migration
+ @migration = "change_title_body_from_posts"
+ run_generator
+ assert_migration "db/migrate/#{@migration}.rb", /class ChangeTitleBodyFromPosts < ActiveRecord::Migration/
+ end
+
+ def test_migration_with_class_name
+ @migration = "ChangeTitleBodyFromPosts"
+ run_generator
+ assert_migration "db/migrate/change_title_body_from_posts.rb", /class #{@migration} < ActiveRecord::Migration/
+ end
+
+ def test_add_migration_with_attributes
+ @migration = "add_title_body_to_posts"
+ run_generator [@migration, "title:string", "body:text"]
+
+ assert_migration "db/migrate/#{@migration}.rb" do |content|
+ assert_class_method content, :up do |up|
+ assert_match /add_column :posts, :title, :string/, up
+ assert_match /add_column :posts, :body, :text/, up
+ end
+
+ assert_class_method content, :down do |down|
+ assert_match /remove_column :posts, :title/, down
+ assert_match /remove_column :posts, :body/, down
+ end
+ end
+ end
+
+ def test_remove_migration_with_attributes
+ @migration = "remove_title_body_from_posts"
+ run_generator [@migration, "title:string", "body:text"]
+
+ assert_migration "db/migrate/#{@migration}.rb" do |content|
+ assert_class_method content, :up do |up|
+ assert_match /remove_column :posts, :title/, up
+ assert_match /remove_column :posts, :body/, up
+ end
+
+ assert_class_method content, :down do |down|
+ assert_match /add_column :posts, :title, :string/, down
+ assert_match /add_column :posts, :body, :text/, down
+ end
+ end
+ end
+
+ protected
+
+ def run_generator(args=[@migration])
+ silence(:stdout) { Rails::Generators::MigrationGenerator.start args, :root => destination_root }
+ end
+
+end
diff --git a/railties/test/generators/model_generator_test.rb b/railties/test/generators/model_generator_test.rb
new file mode 100644
index 0000000000..14cafe7b0d
--- /dev/null
+++ b/railties/test/generators/model_generator_test.rb
@@ -0,0 +1,110 @@
+require 'abstract_unit'
+require 'generators/generators_test_helper'
+require 'generators/active_record/model/model_generator'
+require 'generators/rails/model/model_generator'
+require 'generators/test_unit/model/model_generator'
+
+class ModelGeneratorTest < GeneratorsTestCase
+
+ def test_help_shows_invoked_generators_options
+ content = run_generator ["--help"]
+ assert_match /ActiveRecord options:/, content
+ assert_match /TestUnit options:/, content
+ end
+
+ def test_invokes_default_orm
+ run_generator
+ assert_file "app/models/account.rb", /class Account < ActiveRecord::Base/
+ end
+
+ def test_model_with_parent_option
+ run_generator ["account", "--parent", "Admin::Account"]
+ assert_file "app/models/account.rb", /class Account < Admin::Account/
+ assert_no_migration "db/migrate/create_accounts.rb"
+ end
+
+ def test_model_with_underscored_parent_option
+ run_generator ["account", "--parent", "admin/account"]
+ assert_file "app/models/account.rb", /class Account < Admin::Account/
+ end
+
+ def test_migration
+ run_generator
+ assert_migration "db/migrate/create_accounts.rb", /class CreateAccounts < ActiveRecord::Migration/
+ end
+
+ def test_migration_is_skipped
+ run_generator ["account", "--no-migration"]
+ assert_no_migration "db/migrate/create_accounts.rb"
+ end
+
+ def test_migration_with_attributes
+ run_generator ["product", "name:string", "supplier_id:integer"]
+
+ assert_migration "db/migrate/create_products.rb" do |m|
+ assert_class_method m, :up do |up|
+ assert_match /create_table :products/, up
+ assert_match /t\.string :name/, up
+ assert_match /t\.integer :supplier_id/, up
+ end
+
+ assert_class_method m, :down do |down|
+ assert_match /drop_table :products/, down
+ end
+ end
+ end
+
+ def test_model_with_references_attribute_generates_belongs_to_associations
+ run_generator ["product", "name:string", "supplier_id:references"]
+ assert_file "app/models/product.rb", /belongs_to :supplier/
+ end
+
+ def test_model_with_belongs_to_attribute_generates_belongs_to_associations
+ run_generator ["product", "name:string", "supplier_id:belongs_to"]
+ assert_file "app/models/product.rb", /belongs_to :supplier/
+ end
+
+ def test_migration_with_timestamps
+ run_generator
+ assert_migration "db/migrate/create_accounts.rb", /t.timestamps/
+ end
+
+ def test_migration_timestamps_are_skipped
+ run_generator ["account", "--no-timestamps"]
+
+ assert_migration "db/migrate/create_accounts.rb" do |m|
+ assert_class_method m, :up do |up|
+ assert_no_match /t.timestamps/, up
+ end
+ end
+ end
+
+ def test_invokes_default_test_framework
+ run_generator
+ assert_file "test/unit/account_test.rb", /class AccountTest < ActiveSupport::TestCase/
+ assert_file "test/fixtures/accounts.yml", /name: MyString/, /age: 1/
+ end
+
+ def test_fixture_is_skipped
+ run_generator ["account", "--skip-fixture"]
+ assert_no_file "test/fixtures/accounts.yml"
+ end
+
+ def test_fixture_is_skipped_if_fixture_replacement_is_given
+ content = run_generator ["account", "-r", "fixjour"]
+ assert_match /Could not find and invoke 'fixjour'/, content
+ assert_no_file "test/fixtures/accounts.yml"
+ end
+
+ def test_check_class_collision
+ content = capture(:stderr){ run_generator ["object"] }
+ assert_match /The name 'Object' is either already used in your application or reserved/, content
+ end
+
+ protected
+
+ def run_generator(args=["Account", "name:string", "age:integer"])
+ silence(:stdout) { Rails::Generators::ModelGenerator.start args, :root => destination_root }
+ end
+
+end
diff --git a/railties/test/generators/observer_generator_test.rb b/railties/test/generators/observer_generator_test.rb
new file mode 100644
index 0000000000..3707b70c7e
--- /dev/null
+++ b/railties/test/generators/observer_generator_test.rb
@@ -0,0 +1,35 @@
+require 'abstract_unit'
+require 'generators/generators_test_helper'
+require 'generators/active_record/observer/observer_generator'
+require 'generators/rails/observer/observer_generator'
+require 'generators/test_unit/observer/observer_generator'
+
+class ObserverGeneratorTest < GeneratorsTestCase
+
+ def test_invokes_default_orm
+ run_generator
+ assert_file "app/models/account_observer.rb", /class AccountObserver < ActiveRecord::Observer/
+ end
+
+ def test_invokes_default_orm_with_class_path
+ run_generator ["admin/account"]
+ assert_file "app/models/admin/account_observer.rb", /class Admin::AccountObserver < ActiveRecord::Observer/
+ end
+
+ def test_invokes_default_test_framework
+ run_generator
+ assert_file "test/unit/account_observer_test.rb", /class AccountObserverTest < ActiveSupport::TestCase/
+ end
+
+ def test_logs_if_the_test_framework_cannot_be_found
+ content = run_generator ["account", "--test-framework=unknown"]
+ assert_match /Could not find and invoke 'unknown'/, content
+ end
+
+ protected
+
+ def run_generator(args=["account"])
+ silence(:stdout) { Rails::Generators::ObserverGenerator.start args, :root => destination_root }
+ end
+
+end
diff --git a/railties/test/generators/performance_test_generator_test.rb b/railties/test/generators/performance_test_generator_test.rb
new file mode 100644
index 0000000000..fdfbf9031c
--- /dev/null
+++ b/railties/test/generators/performance_test_generator_test.rb
@@ -0,0 +1,18 @@
+require 'abstract_unit'
+require 'generators/generators_test_helper'
+require 'generators/rails/performance_test/performance_test_generator'
+
+class PerformanceTestGeneratorTest < GeneratorsTestCase
+
+ def test_performance_test_skeleton_is_created
+ run_generator
+ assert_file "test/performance/performance_test.rb", /class PerformanceTest < ActionController::PerformanceTest/
+ end
+
+ protected
+
+ def run_generator(args=["performance"])
+ silence(:stdout) { Rails::Generators::PerformanceTestGenerator.start args, :root => destination_root }
+ end
+
+end
diff --git a/railties/test/generators/plugin_generator_test.rb b/railties/test/generators/plugin_generator_test.rb
new file mode 100644
index 0000000000..3388b2f6f5
--- /dev/null
+++ b/railties/test/generators/plugin_generator_test.rb
@@ -0,0 +1,53 @@
+require 'abstract_unit'
+require 'generators/generators_test_helper'
+require 'generators/rails/plugin/plugin_generator'
+require 'generators/test_unit/plugin/plugin_generator'
+
+class PluginGeneratorTest < GeneratorsTestCase
+
+ def test_plugin_skeleton_is_created
+ run_generator
+
+ %w(
+ vendor/plugins
+ vendor/plugins/plugin_fu
+ vendor/plugins/plugin_fu/lib
+ ).each{ |path| assert_file path }
+ end
+
+ def test_check_class_collision
+ content = capture(:stderr){ run_generator ["object"] }
+ assert_match /The name 'Object' is either already used in your application or reserved/, content
+ end
+
+ def test_invokes_default_test_framework
+ run_generator
+ assert_file "vendor/plugins/plugin_fu/test/plugin_fu_test.rb", /class PluginFuTest < ActiveSupport::TestCase/
+ assert_file "vendor/plugins/plugin_fu/test/test_helper.rb"
+ end
+
+ def test_logs_if_the_test_framework_cannot_be_found
+ content = run_generator ["plugin_fu", "--test-framework=unknown"]
+ assert_match /Could not find and invoke 'unknown'/, content
+ end
+
+ def test_creates_tasks_if_required
+ run_generator ["plugin_fu", "--with-tasks"]
+ assert_file "vendor/plugins/plugin_fu/tasks/plugin_fu_tasks.rake"
+ end
+
+ def test_creates_generator_if_required
+ run_generator ["plugin_fu", "--with-generator"]
+ assert_file "vendor/plugins/plugin_fu/generators/plugin_fu/templates"
+
+ flag = /class PluginFuGenerator < Rails::Generators::NamedBase/
+ assert_file "vendor/plugins/plugin_fu/generators/plugin_fu/plugin_fu_generator.rb", flag
+ end
+
+ protected
+
+ def run_generator(args=["plugin_fu"])
+ silence(:stdout) { Rails::Generators::PluginGenerator.start args, :root => destination_root }
+ end
+
+end
diff --git a/railties/test/generators/rails_template_runner_test.rb b/railties/test/generators/rails_template_runner_test.rb
deleted file mode 100644
index 2da6bd59b5..0000000000
--- a/railties/test/generators/rails_template_runner_test.rb
+++ /dev/null
@@ -1,216 +0,0 @@
-require 'abstract_unit'
-require 'generators/generator_test_helper'
-
-class RailsTemplateRunnerTest < GeneratorTestCase
- def setup
- Rails::Generator::Base.use_application_sources!
- run_generator('app', [RAILS_ROOT])
- # generate empty template
- @template_path = File.join(RAILS_ROOT, 'template.rb')
- File.open(File.join(@template_path), 'w') {|f| f << '' }
-
- @git_plugin_uri = 'git://github.com/technoweenie/restful-authentication.git'
- @svn_plugin_uri = 'svn://svnhub.com/technoweenie/restful-authentication/trunk'
- end
-
- def teardown
- super
- rm_rf "#{RAILS_ROOT}/README"
- rm_rf "#{RAILS_ROOT}/Rakefile"
- rm_rf "#{RAILS_ROOT}/doc"
- rm_rf "#{RAILS_ROOT}/lib"
- rm_rf "#{RAILS_ROOT}/log"
- rm_rf "#{RAILS_ROOT}/script"
- rm_rf "#{RAILS_ROOT}/vendor"
- rm_rf "#{RAILS_ROOT}/tmp"
- rm_rf "#{RAILS_ROOT}/Capfile"
- rm_rf @template_path
- end
-
- def test_initialize_should_load_template
- Rails::TemplateRunner.any_instance.expects(:load_template).with(@template_path)
- silence_generator do
- Rails::TemplateRunner.new(@template_path, RAILS_ROOT)
- end
- end
-
- def test_initialize_should_raise_error_on_missing_template_file
- assert_raise(RuntimeError) do
- silence_generator do
- Rails::TemplateRunner.new('non/existent/path/to/template.rb', RAILS_ROOT)
- end
- end
- end
-
- def test_file_should_write_data_to_file_path
- run_template_method(:file, 'lib/test_file.rb', 'heres test data')
- assert_generated_file_with_data 'lib/test_file.rb', 'heres test data'
- end
-
- def test_file_should_write_block_contents_to_file_path
- run_template_method(:file, 'lib/test_file.rb') { 'heres block data' }
- assert_generated_file_with_data 'lib/test_file.rb', 'heres block data'
- end
-
- def test_plugin_with_git_option_should_run_plugin_install
- expects_run_ruby_script_with_command("script/plugin install #{@git_plugin_uri}")
- run_template_method(:plugin, 'restful-authentication', :git => @git_plugin_uri)
- end
-
- def test_plugin_with_svn_option_should_run_plugin_install
- expects_run_ruby_script_with_command("script/plugin install #{@svn_plugin_uri}")
- run_template_method(:plugin, 'restful-authentication', :svn => @svn_plugin_uri)
- end
-
- def test_plugin_with_git_option_and_submodule_should_use_git_scm
- Rails::Git.expects(:run).with("submodule add #{@git_plugin_uri} vendor/plugins/rest_auth")
- run_template_method(:plugin, 'rest_auth', :git => @git_plugin_uri, :submodule => true)
- end
-
- def test_plugin_with_no_options_should_skip_method
- Rails::TemplateRunner.any_instance.expects(:run).never
- run_template_method(:plugin, 'rest_auth', {})
- end
-
- def test_gem_should_put_gem_dependency_in_enviroment
- run_template_method(:gem, 'will-paginate')
- assert_rails_initializer_includes("config.gem 'will-paginate'")
- end
-
- def test_gem_with_options_should_include_options_in_gem_dependency_in_environment
- run_template_method(:gem, 'mislav-will-paginate', :lib => 'will-paginate', :source => 'http://gems.github.com')
- assert_rails_initializer_includes("config.gem 'mislav-will-paginate', :lib => 'will-paginate', :source => 'http://gems.github.com'")
- end
-
- def test_gem_with_env_string_should_put_gem_dependency_in_specified_environment
- run_template_method(:gem, 'rspec', :env => 'test')
- assert_generated_file_with_data('config/environments/test.rb', "config.gem 'rspec'", 'test')
- end
-
- def test_gem_with_env_array_should_put_gem_dependency_in_specified_environments
- run_template_method(:gem, 'quietbacktrace', :env => %w[ development test ])
- assert_generated_file_with_data('config/environments/development.rb', "config.gem 'quietbacktrace'")
- assert_generated_file_with_data('config/environments/test.rb', "config.gem 'quietbacktrace'")
- end
-
- def test_gem_with_lib_option_set_to_false_should_put_gem_dependency_in_enviroment_correctly
- run_template_method(:gem, 'mislav-will-paginate', :lib => false, :source => 'http://gems.github.com')
- assert_rails_initializer_includes("config.gem 'mislav-will-paginate', :lib => false, :source => 'http://gems.github.com'")
- end
-
- def test_environment_should_include_data_in_environment_initializer_block
- load_paths = 'config.load_paths += %w["#{RAILS_ROOT}/app/extras"]'
- run_template_method(:environment, load_paths)
- assert_rails_initializer_includes(load_paths)
- end
-
- def test_environment_with_block_should_include_block_contents_in_environment_initializer_block
- run_template_method(:environment) do
- '# This wont be added'
- '# This will be added'
- end
- assert_rails_initializer_includes('# This will be added')
- end
-
- def test_git_with_symbol_should_run_command_using_git_scm
- Rails::Git.expects(:run).once.with('init')
- run_template_method(:git, :init)
- end
-
- def test_git_with_hash_should_run_each_command_using_git_scm
- Rails::Git.expects(:run).times(2)
- run_template_method(:git, {:init => '', :add => '.'})
- end
-
- def test_vendor_should_write_data_to_file_in_vendor
- run_template_method(:vendor, 'vendor_file.rb', '# vendor data')
- assert_generated_file_with_data('vendor/vendor_file.rb', '# vendor data')
- end
-
- def test_lib_should_write_data_to_file_in_lib
- run_template_method(:lib, 'my_library.rb', 'class MyLibrary')
- assert_generated_file_with_data('lib/my_library.rb', 'class MyLibrary')
- end
-
- def test_rakefile_should_write_date_to_file_in_lib_tasks
- run_template_method(:rakefile, 'myapp.rake', 'task :run => [:environment]')
- assert_generated_file_with_data('lib/tasks/myapp.rake', 'task :run => [:environment]')
- end
-
- def test_initializer_should_write_date_to_file_in_config_initializers
- run_template_method(:initializer, 'constants.rb', 'MY_CONSTANT = 42')
- assert_generated_file_with_data('config/initializers/constants.rb', 'MY_CONSTANT = 42')
- end
-
- def test_generate_should_run_script_generate_with_argument_and_options
- expects_run_ruby_script_with_command('script/generate model MyModel')
- run_template_method(:generate, 'model', 'MyModel')
- end
-
- def test_rake_should_run_rake_command_with_development_env
- expects_run_with_command('rake log:clear RAILS_ENV=development')
- run_template_method(:rake, 'log:clear')
- end
-
- def test_rake_with_env_option_should_run_rake_command_in_env
- expects_run_with_command('rake log:clear RAILS_ENV=production')
- run_template_method(:rake, 'log:clear', :env => 'production')
- end
-
- def test_rake_with_sudo_option_should_run_rake_command_with_sudo
- expects_run_with_command('sudo rake log:clear RAILS_ENV=development')
- run_template_method(:rake, 'log:clear', :sudo => true)
- end
-
- def test_capify_should_run_the_capify_command
- expects_run_with_command('capify .')
- run_template_method(:capify!)
- end
-
- def test_freeze_should_freeze_rails_edge
- expects_run_with_command('rake rails:freeze:edge')
- run_template_method(:freeze!)
- end
-
- def test_route_should_add_data_to_the_routes_block_in_config_routes
- route_command = "map.route '/login', :controller => 'sessions', :action => 'new'"
- run_template_method(:route, route_command)
- assert_generated_file_with_data 'config/routes.rb', route_command
- end
-
- def test_run_ruby_script_should_add_ruby_to_command_in_win32_environment
- ruby_command = RUBY_PLATFORM =~ /win32/ ? 'ruby ' : ''
- expects_run_with_command("#{ruby_command}script/generate model MyModel")
- run_template_method(:generate, 'model', 'MyModel')
- end
-
- protected
- def run_template_method(method_name, *args, &block)
- silence_generator do
- @template_runner = Rails::TemplateRunner.new(@template_path, RAILS_ROOT)
- @template_runner.send(method_name, *args, &block)
- end
- end
-
- def expects_run_with_command(command)
- Rails::TemplateRunner.any_instance.stubs(:run).once.with(command, false)
- end
-
- def expects_run_ruby_script_with_command(command)
- Rails::TemplateRunner.any_instance.stubs(:run_ruby_script).once.with(command,false)
- end
-
- def assert_rails_initializer_includes(data, message = nil)
- message ||= "Rails::Initializer should include #{data}"
- assert_generated_file 'config/environment.rb' do |body|
- assert_match(/#{Regexp.escape("Rails::Initializer.run do |config|")}.+#{Regexp.escape(data)}.+end/m, body, message)
- end
- end
-
- def assert_generated_file_with_data(file, data, message = nil)
- message ||= "#{file} should include '#{data}'"
- assert_generated_file(file) do |file|
- assert_match(/#{Regexp.escape(data)}/,file, message)
- end
- end
-end \ No newline at end of file
diff --git a/railties/test/generators/resource_generator_test.rb b/railties/test/generators/resource_generator_test.rb
new file mode 100644
index 0000000000..456e6ff3ea
--- /dev/null
+++ b/railties/test/generators/resource_generator_test.rb
@@ -0,0 +1,95 @@
+require 'abstract_unit'
+require 'generators/generators_test_helper'
+require 'generators/rails/resource/resource_generator'
+
+# Model
+require 'generators/active_record/model/model_generator'
+require 'generators/rails/model/model_generator'
+require 'generators/test_unit/model/model_generator'
+
+# Controller
+require 'generators/erb/controller/controller_generator'
+require 'generators/rails/controller/controller_generator'
+require 'generators/rails/helper/helper_generator'
+require 'generators/test_unit/controller/controller_generator'
+require 'generators/test_unit/helper/helper_generator'
+
+class ResourceGeneratorTest < GeneratorsTestCase
+
+ def setup
+ super
+ routes = Rails::Generators::ResourceGenerator.source_root
+ routes = File.join(routes, "..", "..", "app", "templates", "config", "routes.rb")
+ destination = File.join(destination_root, "config")
+
+ FileUtils.mkdir_p(destination)
+ FileUtils.cp File.expand_path(routes), destination
+ end
+
+ def test_help_with_inherited_options
+ content = run_generator ["--help"]
+ assert_match /ActiveRecord options:/, content
+ assert_match /TestUnit options:/, content
+ end
+
+ def test_files_from_inherited_invocation
+ run_generator
+
+ %w(
+ app/models/account.rb
+ test/unit/account_test.rb
+ test/fixtures/accounts.yml
+ ).each { |path| assert_file path }
+
+ assert_migration "db/migrate/create_accounts.rb"
+ end
+
+ def test_inherited_invocations_with_attributes
+ run_generator ["account", "name:string"]
+ assert_migration "db/migrate/create_accounts.rb", /t.string :name/
+ end
+
+ def test_resource_controller_with_pluralized_class_name
+ run_generator
+ assert_file "app/controllers/accounts_controller.rb", /class AccountsController < ApplicationController/
+ assert_file "test/functional/accounts_controller_test.rb", /class AccountsControllerTest < ActionController::TestCase/
+
+ assert_file "app/helpers/accounts_helper.rb", /module AccountsHelper/
+ assert_file "test/unit/helpers/accounts_helper_test.rb", /class AccountsHelperTest < ActionView::TestCase/
+ end
+
+ def test_resource_controller_with_actions
+ run_generator ["account", "--actions", "index", "new"]
+
+ assert_file "app/controllers/accounts_controller.rb" do |controller|
+ assert_instance_method controller, :index
+ assert_instance_method controller, :new
+ end
+
+ assert_file "app/views/accounts/index.html.erb"
+ assert_file "app/views/accounts/new.html.erb"
+ end
+
+ def test_resource_routes_are_added
+ run_generator
+
+ assert_file "config/routes.rb" do |route|
+ assert_match /map\.resources :accounts$/, route
+ end
+ end
+
+ def test_singleton_resource
+ run_generator ["account", "--singleton"]
+
+ assert_file "config/routes.rb" do |route|
+ assert_match /map\.resource :account$/, route
+ end
+ end
+
+ protected
+
+ def run_generator(args=["account"])
+ silence(:stdout) { Rails::Generators::ResourceGenerator.start args, :root => destination_root }
+ end
+
+end
diff --git a/railties/test/generators/session_migration_generator_test.rb b/railties/test/generators/session_migration_generator_test.rb
new file mode 100644
index 0000000000..05b51b1566
--- /dev/null
+++ b/railties/test/generators/session_migration_generator_test.rb
@@ -0,0 +1,24 @@
+require 'abstract_unit'
+require 'generators/generators_test_helper'
+require 'generators/active_record/session_migration/session_migration_generator'
+require 'generators/rails/session_migration/session_migration_generator'
+
+class SessionMigrationGeneratorTest < GeneratorsTestCase
+
+ def test_session_migration_with_default_name
+ run_generator
+ assert_migration "db/migrate/add_sessions_table.rb", /class AddSessionsTable < ActiveRecord::Migration/
+ end
+
+ def test_session_migration_with_given_name
+ run_generator ["create_session_table"]
+ assert_migration "db/migrate/create_session_table.rb", /class CreateSessionTable < ActiveRecord::Migration/
+ end
+
+ protected
+
+ def run_generator(args=[])
+ silence(:stdout) { Rails::Generators::SessionMigrationGenerator.start args, :root => destination_root }
+ end
+
+end
diff --git a/railties/test/generators/generator_test_helper.rb b/railties/test/rails_generator/generator_test_helper.rb
index 01bf1c90bd..01bf1c90bd 100644
--- a/railties/test/generators/generator_test_helper.rb
+++ b/railties/test/rails_generator/generator_test_helper.rb
diff --git a/railties/test/generators/rails_controller_generator_test.rb b/railties/test/rails_generator/rails_controller_generator_test.rb
index 43fbe972e2..6cbb6bf2bd 100644
--- a/railties/test/generators/rails_controller_generator_test.rb
+++ b/railties/test/rails_generator/rails_controller_generator_test.rb
@@ -1,4 +1,4 @@
-require 'generators/generator_test_helper'
+require 'rails_generator/generator_test_helper'
module Admin
end
diff --git a/railties/test/generators/rails_helper_generator_test.rb b/railties/test/rails_generator/rails_helper_generator_test.rb
index 8d05f555e6..8d05f555e6 100644
--- a/railties/test/generators/rails_helper_generator_test.rb
+++ b/railties/test/rails_generator/rails_helper_generator_test.rb
diff --git a/railties/test/generators/rails_mailer_generator_test.rb b/railties/test/rails_generator/rails_mailer_generator_test.rb
index de61e6736d..f580fe27ab 100644
--- a/railties/test/generators/rails_mailer_generator_test.rb
+++ b/railties/test/rails_generator/rails_mailer_generator_test.rb
@@ -1,4 +1,4 @@
-require 'generators/generator_test_helper'
+require 'rails_generator/generator_test_helper'
class RailsMailerGeneratorTest < GeneratorTestCase
diff --git a/railties/test/generators/rails_model_generator_test.rb b/railties/test/rails_generator/rails_model_generator_test.rb
index aea2abafba..ae3c2e316e 100644
--- a/railties/test/generators/rails_model_generator_test.rb
+++ b/railties/test/rails_generator/rails_model_generator_test.rb
@@ -1,4 +1,4 @@
-require 'generators/generator_test_helper'
+require 'rails_generator/generator_test_helper'
class RailsModelGeneratorTest < GeneratorTestCase
diff --git a/railties/test/generators/rails_model_subclass_generator_test.rb b/railties/test/rails_generator/rails_model_subclass_generator_test.rb
index 30066b5a3c..4f20de6eba 100644
--- a/railties/test/generators/rails_model_subclass_generator_test.rb
+++ b/railties/test/rails_generator/rails_model_subclass_generator_test.rb
@@ -1,4 +1,4 @@
-require 'generators/generator_test_helper'
+require 'rails_generator/generator_test_helper'
class RailsModelSubclassGeneratorTest < GeneratorTestCase
@@ -12,4 +12,4 @@ class RailsModelSubclassGeneratorTest < GeneratorTestCase
def test_model_subclass_must_have_a_parent_class_name
assert_raise(Rails::Generator::UsageError) { run_generator('model_subclass', %w(Car)) }
end
-end \ No newline at end of file
+end
diff --git a/railties/test/generators/rails_resource_generator_test.rb b/railties/test/rails_generator/rails_resource_generator_test.rb
index 1f5bd0ef1e..b9a432cbff 100644
--- a/railties/test/generators/rails_resource_generator_test.rb
+++ b/railties/test/rails_generator/rails_resource_generator_test.rb
@@ -1,4 +1,4 @@
-require 'generators/generator_test_helper'
+require 'rails_generator/generator_test_helper'
class RailsResourceGeneratorTest < GeneratorTestCase
def test_resource_generates_resources
diff --git a/railties/test/generators/rails_scaffold_generator_test.rb b/railties/test/rails_generator/rails_scaffold_generator_test.rb
index 70829a77fd..ffbeff79fb 100644
--- a/railties/test/generators/rails_scaffold_generator_test.rb
+++ b/railties/test/rails_generator/rails_scaffold_generator_test.rb
@@ -1,4 +1,4 @@
-require 'generators/generator_test_helper'
+require 'rails_generator/generator_test_helper'
require 'abstract_unit'
class RailsScaffoldGeneratorTest < GeneratorTestCase
diff --git a/railties/test/secret_key_generation_test.rb b/railties/test/secret_key_generation_test.rb
deleted file mode 100644
index 2c7c3d5dfe..0000000000
--- a/railties/test/secret_key_generation_test.rb
+++ /dev/null
@@ -1,38 +0,0 @@
-require 'abstract_unit'
-
-# Must set before requiring generator libs.
-if defined?(RAILS_ROOT)
- RAILS_ROOT.replace "#{File.dirname(__FILE__)}/fixtures"
-else
- RAILS_ROOT = "#{File.dirname(__FILE__)}/fixtures"
-end
-
-$LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib"
-
-require 'initializer'
-
-# Mocks out the configuration
-module Rails
- def self.configuration
- Rails::Configuration.new
- end
-end
-
-require 'rails_generator'
-require 'rails_generator/secret_key_generator'
-require 'rails_generator/generators/applications/app/app_generator'
-
-class SecretKeyGenerationTest < ActiveSupport::TestCase
- SECRET_KEY_MIN_LENGTH = 128
- APP_NAME = "foo"
-
- def setup
- @generator = Rails::SecretKeyGenerator.new(APP_NAME)
- end
-
- def test_secret_key_generation
- assert_deprecated /ActiveSupport::SecureRandom\.hex\(64\)/ do
- assert @generator.generate_secret.length >= SECRET_KEY_MIN_LENGTH
- end
- end
-end