aboutsummaryrefslogtreecommitdiffstats
path: root/railties
diff options
context:
space:
mode:
Diffstat (limited to 'railties')
-rw-r--r--railties/CHANGELOG.md130
-rw-r--r--railties/MIT-LICENSE2
-rw-r--r--railties/RDOC_MAIN.rdoc2
-rw-r--r--railties/README.rdoc6
-rwxr-xr-xrailties/bin/rails4
-rw-r--r--railties/lib/rails.rb5
-rw-r--r--railties/lib/rails/app_rails_loader.rb2
-rw-r--r--railties/lib/rails/application.rb124
-rw-r--r--railties/lib/rails/application/configuration.rb24
-rw-r--r--railties/lib/rails/application/default_middleware_stack.rb10
-rw-r--r--railties/lib/rails/application/finisher.rb2
-rw-r--r--railties/lib/rails/application_controller.rb16
-rw-r--r--railties/lib/rails/cli.rb1
-rw-r--r--railties/lib/rails/commands/application.rb4
-rw-r--r--railties/lib/rails/commands/commands_tasks.rb9
-rw-r--r--railties/lib/rails/commands/console.rb36
-rw-r--r--railties/lib/rails/commands/dbconsole.rb19
-rw-r--r--railties/lib/rails/commands/plugin.rb14
-rw-r--r--railties/lib/rails/commands/runner.rb21
-rw-r--r--railties/lib/rails/commands/server.rb89
-rw-r--r--railties/lib/rails/configuration.rb4
-rw-r--r--railties/lib/rails/engine.rb18
-rw-r--r--railties/lib/rails/gem_version.rb15
-rw-r--r--railties/lib/rails/generators.rb88
-rw-r--r--railties/lib/rails/generators/actions.rb35
-rw-r--r--railties/lib/rails/generators/actions/create_migration.rb68
-rw-r--r--railties/lib/rails/generators/app_base.rb215
-rw-r--r--railties/lib/rails/generators/base.rb14
-rw-r--r--railties/lib/rails/generators/erb.rb6
-rw-r--r--railties/lib/rails/generators/erb/controller/controller_generator.rb6
-rw-r--r--railties/lib/rails/generators/erb/mailer/mailer_generator.rb4
-rw-r--r--railties/lib/rails/generators/erb/mailer/templates/view.html.erb5
-rw-r--r--railties/lib/rails/generators/erb/mailer/templates/view.text.erb2
-rw-r--r--railties/lib/rails/generators/erb/scaffold/scaffold_generator.rb6
-rw-r--r--railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb9
-rw-r--r--railties/lib/rails/generators/erb/scaffold/templates/edit.html.erb2
-rw-r--r--railties/lib/rails/generators/erb/scaffold/templates/index.html.erb2
-rw-r--r--railties/lib/rails/generators/erb/scaffold/templates/new.html.erb2
-rw-r--r--railties/lib/rails/generators/generated_attribute.rb4
-rw-r--r--railties/lib/rails/generators/migration.rb38
-rw-r--r--railties/lib/rails/generators/model_helpers.rb28
-rw-r--r--railties/lib/rails/generators/named_base.rb9
-rw-r--r--railties/lib/rails/generators/rails/app/app_generator.rb95
-rw-r--r--railties/lib/rails/generators/rails/app/templates/Gemfile44
-rw-r--r--railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt2
-rw-r--r--railties/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt12
-rw-r--r--railties/lib/rails/generators/rails/app/templates/bin/setup28
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/application.rb7
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/boot.rb2
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/frontbase.yml36
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml69
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml64
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml39
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml47
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml9
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml53
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/oracle.yml37
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml53
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml16
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/sqlserver.yml43
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt13
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt26
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt5
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/initializers/assets.rb.tt8
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/initializers/cookies_serializer.rb3
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/initializers/mime_types.rb1
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/secrets.yml (renamed from railties/lib/rails/generators/rails/app/templates/config/initializers/secret_token.rb.tt)14
-rw-r--r--railties/lib/rails/generators/rails/app/templates/gitignore2
-rw-r--r--railties/lib/rails/generators/rails/app/templates/public/404.html31
-rw-r--r--railties/lib/rails/generators/rails/app/templates/public/422.html31
-rw-r--r--railties/lib/rails/generators/rails/app/templates/public/500.html29
-rw-r--r--railties/lib/rails/generators/rails/app/templates/public/robots.txt2
-rw-r--r--railties/lib/rails/generators/rails/app/templates/test/test_helper.rb7
-rw-r--r--railties/lib/rails/generators/rails/controller/controller_generator.rb18
-rw-r--r--railties/lib/rails/generators/rails/model/USAGE2
-rw-r--r--railties/lib/rails/generators/rails/model/model_generator.rb4
-rw-r--r--railties/lib/rails/generators/rails/plugin/plugin_generator.rb25
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/%name%.gemspec4
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/Gemfile29
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/MIT-LICENSE2
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/Rakefile4
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/bin/rails.tt4
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/rails/boot.rb2
-rw-r--r--railties/lib/rails/generators/rails/resource_route/resource_route_generator.rb2
-rw-r--r--railties/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb2
-rw-r--r--railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb4
-rw-r--r--railties/lib/rails/generators/resource_helpers.rb34
-rw-r--r--railties/lib/rails/generators/test_unit/mailer/mailer_generator.rb9
-rw-r--r--railties/lib/rails/generators/test_unit/mailer/templates/preview.rb13
-rw-r--r--railties/lib/rails/generators/testing/assertions.rb8
-rw-r--r--railties/lib/rails/info.rb2
-rw-r--r--railties/lib/rails/info_controller.rb22
-rw-r--r--railties/lib/rails/mailers_controller.rb73
-rw-r--r--railties/lib/rails/paths.rb35
-rw-r--r--railties/lib/rails/rack.rb2
-rw-r--r--railties/lib/rails/rack/log_tailer.rb6
-rw-r--r--railties/lib/rails/rack/logger.rb7
-rw-r--r--railties/lib/rails/railtie.rb28
-rw-r--r--railties/lib/rails/ruby_version_check.rb2
-rw-r--r--railties/lib/rails/source_annotation_extractor.rb41
-rw-r--r--railties/lib/rails/tasks/framework.rake6
-rw-r--r--railties/lib/rails/tasks/log.rake2
-rw-r--r--railties/lib/rails/tasks/statistics.rake11
-rw-r--r--railties/lib/rails/templates/layouts/application.html.erb4
-rw-r--r--railties/lib/rails/templates/rails/mailers/email.html.erb98
-rw-r--r--railties/lib/rails/templates/rails/mailers/index.html.erb8
-rw-r--r--railties/lib/rails/templates/rails/mailers/mailer.html.erb6
-rw-r--r--railties/lib/rails/test_help.rb7
-rw-r--r--railties/lib/rails/test_unit/sub_test_task.rb4
-rw-r--r--railties/lib/rails/test_unit/testing.rake3
-rw-r--r--railties/lib/rails/version.rb12
-rw-r--r--railties/lib/rails/welcome_controller.rb7
-rw-r--r--railties/test/abstract_unit.rb11
-rw-r--r--railties/test/app_rails_loader_test.rb10
-rw-r--r--railties/test/application/assets_test.rb42
-rw-r--r--railties/test/application/configuration_test.rb261
-rw-r--r--railties/test/application/initializers/frameworks_test.rb2
-rw-r--r--railties/test/application/initializers/i18n_test.rb45
-rw-r--r--railties/test/application/initializers/load_path_test.rb14
-rw-r--r--railties/test/application/initializers/notifications_test.rb13
-rw-r--r--railties/test/application/mailer_previews_test.rb428
-rw-r--r--railties/test/application/middleware/remote_ip_test.rb10
-rw-r--r--railties/test/application/middleware/session_test.rb2
-rw-r--r--railties/test/application/middleware_test.rb8
-rw-r--r--railties/test/application/multiple_applications_test.rb26
-rw-r--r--railties/test/application/rake/dbs_test.rb93
-rw-r--r--railties/test/application/rake/migrations_test.rb48
-rw-r--r--railties/test/application/rake/notes_test.rb127
-rw-r--r--railties/test/application/rake_test.rb35
-rw-r--r--railties/test/application/test_test.rb173
-rw-r--r--railties/test/commands/console_test.rb32
-rw-r--r--railties/test/commands/dbconsole_test.rb96
-rw-r--r--railties/test/commands/server_test.rb60
-rw-r--r--railties/test/configuration/middleware_stack_proxy_test.rb4
-rw-r--r--railties/test/env_helpers.rb4
-rw-r--r--railties/test/generators/actions_test.rb22
-rw-r--r--railties/test/generators/app_generator_test.rb198
-rw-r--r--railties/test/generators/argv_scrubber_test.rb136
-rw-r--r--railties/test/generators/controller_generator_test.rb17
-rw-r--r--railties/test/generators/create_migration_test.rb134
-rw-r--r--railties/test/generators/generator_test.rb85
-rw-r--r--railties/test/generators/generators_test_helper.rb8
-rw-r--r--railties/test/generators/mailer_generator_test.rb61
-rw-r--r--railties/test/generators/migration_generator_test.rb50
-rw-r--r--railties/test/generators/model_generator_test.rb7
-rw-r--r--railties/test/generators/named_base_test.rb19
-rw-r--r--railties/test/generators/namespaced_generators_test.rb2
-rw-r--r--railties/test/generators/plugin_generator_test.rb96
-rw-r--r--railties/test/generators/resource_generator_test.rb6
-rw-r--r--railties/test/generators/scaffold_controller_generator_test.rb10
-rw-r--r--railties/test/generators/shared_generator_tests.rb29
-rw-r--r--railties/test/generators/task_generator_test.rb14
-rw-r--r--railties/test/generators_test.rb16
-rw-r--r--railties/test/isolation/abstract_unit.rb24
-rw-r--r--railties/test/paths_test.rb2
-rw-r--r--railties/test/rails_info_controller_test.rb2
-rw-r--r--railties/test/rails_info_test.rb10
-rw-r--r--railties/test/railties/engine_test.rb51
-rw-r--r--railties/test/railties/mounted_engine_test.rb10
-rw-r--r--railties/test/railties/railtie_test.rb8
-rw-r--r--railties/test/version_test.rb12
161 files changed, 3943 insertions, 1110 deletions
diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md
index a4babbe8c3..c33a4ed192 100644
--- a/railties/CHANGELOG.md
+++ b/railties/CHANGELOG.md
@@ -1,121 +1,97 @@
-* Include `web-console` into newly generated applications' Gemfile.
+* Deprecate `Rails::Rack::LogTailer` with not replacement.
- *Genadi Samokovarov*
-
-* `rails server` will only extend the logger to output to STDOUT
- in development environment.
-
- *Richard Schneeman*
-
-* Don't require passing path to app before options in `rails new`
- and `rails plugin new`
-
- *Piotr Sarnacki*
-
-* rake notes now searches *.less files
-
- *Josh Crowder*
-
-* Generate nested route for namespaced controller generated using
- `rails g controller`.
- Fixes #11532.
-
- Example:
+ *Rafael Mendonça França*
- rails g controller admin/dashboard index
+* Add a generic --skip-gems options to generator
- # Before:
- get "dashboard/index"
+ This option is useful if users want to remove some gems like jbuilder,
+ turbolinks, coffee-rails, etc that don't have specific options on the
+ generator.
- # After:
- namespace :admin do
- get "dashboard/index"
- end
+ rails new my_app --skip-gems turbolinks coffee-rails
- *Prathamesh Sonpatki*
+ *Rafael Mendonça França*
-* Fix the event name of action_dispatch requests.
+* Invalid `bin/rails generate` commands will now show spelling suggestions.
- *Rafael Mendonça França*
+ *Richard Schneeman*
-* Make `config.log_level` work with custom loggers.
+* Add `bin/setup` script to bootstrap an application.
- *Max Shytikov*
+ *Yves Senn*
-* Changed stylesheet load order in the stylesheet manifest generator.
- Fixes #11639.
+* Replace double quotes with single quotes while adding an entry into Gemfile.
- *Pawel Janiak*
+ *Alexander Belaev*
-* Added generated unit test for generator generator using new
- `test:generators` rake task.
+* Default `config.assets.digest` to `true` in development.
- *Josef Šimánek*
+ *Dan Kang*
-* Removed `update:application_controller` rake task.
+* Load database configuration from the first `database.yml` available in paths.
- *Josef Šimánek*
+ *Pier-Olivier Thibault*
-* Fix `rake environment` to do not eager load modules
+* Reading name and email from git for plugin gemspec.
- *Paul Nikitochkin*
+ Fixes #9589.
-* Fix `rake notes` to look into `*.sass` files
+ *Arun Agrawal*, *Abd ar-Rahman Hamidi*, *Roman Shmatov*
- *Yuri Artemev*
+* Fix `console` and `generators` blocks defined at different environments.
-* Removed deprecated `Rails.application.railties.engines`.
+ Fixes #14748.
- *Arun Agrawal*
+ *Rafael Mendonça França*
-* Removed deprecated threadsafe! from Rails Config.
+* Move configuration of asset precompile list and version to an initializer.
- *Paul Nikitochkin*
+ *Matthew Draper*
-* Remove deprecated `ActiveRecord::Generators::ActiveModel#update_attributes` in
- favor of `ActiveRecord::Generators::ActiveModel#update`
+* Remove sqlite3 lines from `.gitignore` if the application is not using sqlite3.
- *Vipul A M*
+ *Dmitrii Golub*
-* Remove deprecated `config.whiny_nils` option
+* Add public API to register new extensions for `rake notes`.
- *Vipul A M*
+ Example:
-* Rename `commands/plugin_new.rb` to `commands/plugin.rb` and fix references
+ config.annotations.register_extensions("scss", "sass") { |tag| /\/\/\s*(#{tag}):?\s*(.*)$/ }
- *Richard Schneeman*
+ *Roberto Miranda*
-* Fix `rails plugin --help` command.
+* Removed unnecessary `rails application` command.
- *Richard Schneeman*
+ *Arun Agrawal*
-* Omit turbolinks configuration completely on skip_javascript generator option.
+* Make the `rails:template` rake task load the application's initializers.
- *Nikita Fedyashev*
+ Fixes #12133.
-* Removed deprecated rake tasks for running tests: `rake test:uncommitted` and
- `rake test:recent`.
+ *Robin Dupret*
- *John Wang*
+* Introduce `Rails.gem_version` as a convenience method to return
+ `Gem::Version.new(Rails.version)`, suggesting a more reliable way to perform
+ version comparison.
-* Clearing autoloaded constants triggers routes reloading.
- Fixes #10685.
+ Example:
- *Xavier Noria*
+ Rails.version #=> "4.1.2"
+ Rails.gem_version #=> #<Gem::Version "4.1.2">
-* Fixes bug with scaffold generator with `--assets=false --resource-route=false`.
- Fixes #9525.
+ Rails.version > "4.1.10" #=> false
+ Rails.gem_version > Gem::Version.new("4.1.10") #=> true
+ Gem::Requirement.new("~> 4.1.2") =~ Rails.gem_version #=> true
- *Arun Agrawal*
+ *Prem Sichanugrist*
-* Rails::Railtie no longer forces the Rails::Configurable module on everything
- that subclasses it. Instead, the methods from Rails::Configurable have been
- moved to class methods in Railtie and the Railtie has been made abstract.
+* Avoid namespacing routes inside engines.
- *John Wang*
+ Mountable engines are namespaced by default so the generated routes
+ were too while they should not.
-* Changes repetitive th tags to use colspan attribute in `index.html.erb` template.
+ Fixes #14079.
- *Sıtkı Bağdat*
+ *Yves Senn*, *Carlos Antonio da Silva*, *Robin Dupret*
-Please check [4-0-stable](https://github.com/rails/rails/blob/4-0-stable/railties/CHANGELOG.md) for previous changes.
+Please check [4-1-stable](https://github.com/rails/rails/blob/4-1-stable/railties/CHANGELOG.md) for previous changes.
diff --git a/railties/MIT-LICENSE b/railties/MIT-LICENSE
index 0d7fb865e2..2950f05b11 100644
--- a/railties/MIT-LICENSE
+++ b/railties/MIT-LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2013 David Heinemeier Hansson
+Copyright (c) 2004-2014 David Heinemeier Hansson
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
diff --git a/railties/RDOC_MAIN.rdoc b/railties/RDOC_MAIN.rdoc
index eccdee7b07..8d847eaa1c 100644
--- a/railties/RDOC_MAIN.rdoc
+++ b/railties/RDOC_MAIN.rdoc
@@ -1,7 +1,7 @@
== Welcome to \Rails
\Rails is a web-application framework that includes everything needed to create
-database-backed web applications according to the {Model-View-Controller (MVC)}[http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller] pattern.
+database-backed web applications according to the {Model-View-Controller (MVC)}[http://en.wikipedia.org/wiki/Model-view-controller] pattern.
Understanding the MVC pattern is key to understanding \Rails. MVC divides your application
into three layers, each with a specific responsibility.
diff --git a/railties/README.rdoc b/railties/README.rdoc
index 6248b5feed..a25658668c 100644
--- a/railties/README.rdoc
+++ b/railties/README.rdoc
@@ -31,7 +31,11 @@ API documentation is at
* http://api.rubyonrails.org
-Bug reports and feature requests can be filed with the rest for the Ruby on Rails project here:
+Bug reports can be filed for the Ruby on Rails project here:
* https://github.com/rails/rails/issues
+Feature requests should be discussed on the rails-core mailing list here:
+
+* https://groups.google.com/forum/?fromgroups#!forum/rubyonrails-core
+
diff --git a/railties/bin/rails b/railties/bin/rails
index b3026e8a93..82c17cabce 100755
--- a/railties/bin/rails
+++ b/railties/bin/rails
@@ -1,8 +1,8 @@
#!/usr/bin/env ruby
-git_path = File.join(File.expand_path('../../..', __FILE__), '.git')
+git_path = File.expand_path('../../../.git', __FILE__)
-if File.exists?(git_path)
+if File.exist?(git_path)
railties_path = File.expand_path('../../lib', __FILE__)
$:.unshift(railties_path)
end
diff --git a/railties/lib/rails.rb b/railties/lib/rails.rb
index ea82327365..ecd8c22dd8 100644
--- a/railties/lib/rails.rb
+++ b/railties/lib/rails.rb
@@ -25,6 +25,7 @@ module Rails
autoload :Info
autoload :InfoController
+ autoload :MailersController
autoload :WelcomeController
class << self
@@ -79,10 +80,6 @@ module Rails
groups
end
- def version
- VERSION::STRING
- end
-
def public_path
application && Pathname.new(application.paths["public"].first)
end
diff --git a/railties/lib/rails/app_rails_loader.rb b/railties/lib/rails/app_rails_loader.rb
index 71fcf83dae..56f05b3844 100644
--- a/railties/lib/rails/app_rails_loader.rb
+++ b/railties/lib/rails/app_rails_loader.rb
@@ -55,7 +55,7 @@ EOS
end
def self.find_executable
- EXECUTABLES.find { |exe| File.exists?(exe) }
+ EXECUTABLES.find { |exe| File.file?(exe) }
end
end
end
diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb
index 4faaf5ef1e..362713eb75 100644
--- a/railties/lib/rails/application.rb
+++ b/railties/lib/rails/application.rb
@@ -1,6 +1,8 @@
require 'fileutils'
+require 'active_support/core_ext/hash/keys'
require 'active_support/core_ext/object/blank'
require 'active_support/key_generator'
+require 'active_support/message_verifier'
require 'rails/engine'
module Rails
@@ -85,7 +87,7 @@ module Rails
class << self
def inherited(base)
super
- Rails.application ||= base.instance
+ base.instance
end
# Makes the +new+ method public.
@@ -103,16 +105,19 @@ module Rails
delegate :default_url_options, :default_url_options=, to: :routes
INITIAL_VARIABLES = [:config, :railties, :routes_reloader, :reloaders,
- :routes, :helpers, :app_env_config] # :nodoc:
+ :routes, :helpers, :app_env_config, :secrets] # :nodoc:
def initialize(initial_variable_values = {}, &block)
super()
- @initialized = false
- @reloaders = []
- @routes_reloader = nil
- @app_env_config = nil
- @ordered_railties = nil
- @railties = nil
+ @initialized = false
+ @reloaders = []
+ @routes_reloader = nil
+ @app_env_config = nil
+ @ordered_railties = nil
+ @railties = nil
+ @message_verifiers = {}
+
+ Rails.application ||= self
add_lib_to_load_path!
ActiveSupport.run_load_hooks(:before_configuration, self)
@@ -148,13 +153,37 @@ module Rails
def key_generator
# number of iterations selected based on consultation with the google security
# team. Details at https://github.com/rails/rails/pull/6952#issuecomment-7661220
- @caching_key_generator ||= begin
- if config.secret_key_base
- key_generator = ActiveSupport::KeyGenerator.new(config.secret_key_base, iterations: 1000)
+ @caching_key_generator ||=
+ if secrets.secret_key_base
+ key_generator = ActiveSupport::KeyGenerator.new(secrets.secret_key_base, iterations: 1000)
ActiveSupport::CachingKeyGenerator.new(key_generator)
else
ActiveSupport::LegacyKeyGenerator.new(config.secret_token)
end
+ end
+
+ # Returns a message verifier object.
+ #
+ # This verifier can be used to generate and verify signed messages in the application.
+ #
+ # It is recommended not to use the same verifier for different things, so you can get different
+ # verifiers passing the +verifier_name+ argument.
+ #
+ # ==== Parameters
+ #
+ # * +verifier_name+ - the name of the message verifier.
+ #
+ # ==== Examples
+ #
+ # message = Rails.application.message_verifier('sensitive_data').generate('my sensible data')
+ # Rails.application.message_verifier('sensitive_data').verify(message)
+ # # => 'my sensible data'
+ #
+ # See the +ActiveSupport::MessageVerifier+ documentation for more information.
+ def message_verifier(verifier_name)
+ @message_verifiers[verifier_name] ||= begin
+ secret = key_generator.generate_key(verifier_name.to_s)
+ ActiveSupport::MessageVerifier.new(secret)
end
end
@@ -168,7 +197,7 @@ module Rails
"action_dispatch.parameter_filter" => config.filter_parameters,
"action_dispatch.redirect_filter" => config.filter_redirect,
"action_dispatch.secret_token" => config.secret_token,
- "action_dispatch.secret_key_base" => config.secret_key_base,
+ "action_dispatch.secret_key_base" => secrets.secret_key_base,
"action_dispatch.show_exceptions" => config.action_dispatch.show_exceptions,
"action_dispatch.show_detailed_exceptions" => config.consider_all_requests_local,
"action_dispatch.logger" => Rails.logger,
@@ -177,7 +206,8 @@ module Rails
"action_dispatch.http_auth_salt" => config.action_dispatch.http_auth_salt,
"action_dispatch.signed_cookie_salt" => config.action_dispatch.signed_cookie_salt,
"action_dispatch.encrypted_cookie_salt" => config.action_dispatch.encrypted_cookie_salt,
- "action_dispatch.encrypted_signed_cookie_salt" => config.action_dispatch.encrypted_signed_cookie_salt
+ "action_dispatch.encrypted_signed_cookie_salt" => config.action_dispatch.encrypted_signed_cookie_salt,
+ "action_dispatch.cookies_serializer" => config.action_dispatch.cookies_serializer
})
end
end
@@ -201,6 +231,18 @@ module Rails
self.class.runner(&blk)
end
+ # Sends any console called in the instance of a new application up
+ # to the +console+ method defined in Rails::Railtie.
+ def console(&blk)
+ self.class.console(&blk)
+ end
+
+ # Sends any generators called in the instance of a new application up
+ # to the +generators+ method defined in Rails::Railtie.
+ def generators(&blk)
+ self.class.generators(&blk)
+ end
+
# Sends the +isolate_namespace+ method up to the class method.
def isolate_namespace(mod)
self.class.isolate_namespace(mod)
@@ -223,7 +265,7 @@ module Rails
# you need to load files in lib/ during the application configuration as well.
def add_lib_to_load_path! #:nodoc:
path = File.join config.root, 'lib'
- if File.exists?(path) && !$LOAD_PATH.include?(path)
+ if File.exist?(path) && !$LOAD_PATH.include?(path)
$LOAD_PATH.unshift(path)
end
end
@@ -273,6 +315,28 @@ module Rails
@config = configuration
end
+ def secrets #:nodoc:
+ @secrets ||= begin
+ secrets = ActiveSupport::OrderedOptions.new
+ yaml = config.paths["config/secrets"].first
+ if File.exist?(yaml)
+ require "erb"
+ all_secrets = YAML.load(ERB.new(IO.read(yaml)).result) || {}
+ env_secrets = all_secrets[Rails.env]
+ secrets.merge!(env_secrets.symbolize_keys) if env_secrets
+ end
+
+ # Fallback to config.secret_key_base if secrets.secret_key_base isn't set
+ secrets.secret_key_base ||= config.secret_key_base
+
+ secrets
+ end
+ end
+
+ def secrets=(secrets) #:nodoc:
+ @secrets = secrets
+ end
+
def to_app #:nodoc:
self
end
@@ -281,6 +345,29 @@ module Rails
config.helpers_paths
end
+ console do
+ require "pp"
+ end
+
+ console do
+ unless ::Kernel.private_method_defined?(:y)
+ if RUBY_VERSION >= '2.0'
+ require "psych/y"
+ else
+ module ::Kernel
+ def y(*objects)
+ puts ::Psych.dump_stream(*objects)
+ end
+ private :y
+ end
+ end
+ end
+ end
+
+ def migration_railties # :nodoc:
+ (ordered_railties & railties_without_main_app).reverse
+ end
+
protected
alias :build_middleware_stack :app
@@ -311,6 +398,11 @@ module Rails
super
end
+ def railties_without_main_app # :nodoc:
+ @railties_without_main_app ||= Rails::Railtie.subclasses.map(&:instance) +
+ Rails::Engine.subclasses.map(&:instance)
+ end
+
# Returns the ordered railties for this application considering railties_order.
def ordered_railties #:nodoc:
@ordered_railties ||= begin
@@ -364,8 +456,8 @@ module Rails
end
def validate_secret_key_config! #:nodoc:
- if config.secret_key_base.blank? && config.secret_token.blank?
- raise "You must set config.secret_key_base in your app's config."
+ if secrets.secret_key_base.blank? && config.secret_token.blank?
+ raise "Missing `secret_key_base` for '#{Rails.env}' environment, set this value in `config/secrets.yml`"
end
end
end
diff --git a/railties/lib/rails/application/configuration.rb b/railties/lib/rails/application/configuration.rb
index 7332444ab9..5e8f4de847 100644
--- a/railties/lib/rails/application/configuration.rb
+++ b/railties/lib/rails/application/configuration.rb
@@ -1,6 +1,7 @@
require 'active_support/core_ext/kernel/reporting'
require 'active_support/file_update_checker'
require 'rails/engine/configuration'
+require 'rails/source_annotation_extractor'
module Rails
class Application
@@ -76,6 +77,7 @@ module Rails
@paths ||= begin
paths = super
paths.add "config/database", with: "config/database.yml"
+ paths.add "config/secrets", with: "config/secrets.yml"
paths.add "config/environment", with: "config/environment.rb"
paths.add "lib/templates"
paths.add "log", with: "log/#{Rails.env}.log"
@@ -87,21 +89,30 @@ module Rails
end
end
- # Loads and returns the configuration of the database.
+ # Loads and returns the entire raw configuration of database from
+ # values stored in `config/database.yml`.
def database_configuration
- yaml = paths["config/database"].first
- if File.exists?(yaml)
+ yaml = Pathname.new(paths["config/database"].existent.first || "")
+
+ config = if yaml.exist?
+ require "yaml"
require "erb"
- YAML.load ERB.new(IO.read(yaml)).result
+ YAML.load(ERB.new(yaml.read).result) || {}
elsif ENV['DATABASE_URL']
- nil
+ # Value from ENV['DATABASE_URL'] is set to default database connection
+ # by Active Record.
+ {}
else
raise "Could not load database configuration. No such file - #{yaml}"
end
+
+ config
rescue Psych::SyntaxError => e
raise "YAML syntax error occurred while parsing #{paths["config/database"].first}. " \
"Please note that YAML must be consistently indented using spaces. Tabs are not allowed. " \
"Error: #{e.message}"
+ rescue => e
+ raise e, "Cannot load `Rails.application.database_configuration`:\n#{e.message}", e.backtrace
end
def log_level
@@ -140,6 +151,9 @@ module Rails
end
end
+ def annotations
+ SourceAnnotationExtractor::Annotation
+ end
end
end
end
diff --git a/railties/lib/rails/application/default_middleware_stack.rb b/railties/lib/rails/application/default_middleware_stack.rb
index 570ff02c83..a00afe008c 100644
--- a/railties/lib/rails/application/default_middleware_stack.rb
+++ b/railties/lib/rails/application/default_middleware_stack.rb
@@ -11,11 +11,6 @@ module Rails
def build_stack
ActionDispatch::MiddlewareStack.new.tap do |middleware|
- if rack_cache = load_rack_cache
- require "action_dispatch/http/rack_cache"
- middleware.use ::Rack::Cache, rack_cache
- end
-
if config.force_ssl
middleware.use ::ActionDispatch::SSL, config.ssl_options
end
@@ -26,6 +21,11 @@ module Rails
middleware.use ::ActionDispatch::Static, paths["public"].first, config.static_cache_control
end
+ if rack_cache = load_rack_cache
+ require "action_dispatch/http/rack_cache"
+ middleware.use ::Rack::Cache, rack_cache
+ end
+
middleware.use ::Rack::Lock unless allow_concurrency?
middleware.use ::Rack::Runtime
middleware.use ::Rack::MethodOverride
diff --git a/railties/lib/rails/application/finisher.rb b/railties/lib/rails/application/finisher.rb
index 7a1bb1e25c..5b8509b2e9 100644
--- a/railties/lib/rails/application/finisher.rb
+++ b/railties/lib/rails/application/finisher.rb
@@ -22,6 +22,8 @@ module Rails
initializer :add_builtin_route do |app|
if Rails.env.development?
app.routes.append do
+ get '/rails/mailers' => "rails/mailers#index"
+ get '/rails/mailers/*path' => "rails/mailers#preview"
get '/rails/info/properties' => "rails/info#properties"
get '/rails/info/routes' => "rails/info#routes"
get '/rails/info' => "rails/info#index"
diff --git a/railties/lib/rails/application_controller.rb b/railties/lib/rails/application_controller.rb
new file mode 100644
index 0000000000..9a29ec21cf
--- /dev/null
+++ b/railties/lib/rails/application_controller.rb
@@ -0,0 +1,16 @@
+class Rails::ApplicationController < ActionController::Base # :nodoc:
+ self.view_paths = File.expand_path('../templates', __FILE__)
+ layout 'application'
+
+ protected
+
+ def require_local!
+ unless local_request?
+ render text: '<p>For security purposes, this information is only available to local requests.</p>', status: :forbidden
+ end
+ end
+
+ def local_request?
+ Rails.application.config.consider_all_requests_local || request.local?
+ end
+end
diff --git a/railties/lib/rails/cli.rb b/railties/lib/rails/cli.rb
index 20313a2608..dd70c272c6 100644
--- a/railties/lib/rails/cli.rb
+++ b/railties/lib/rails/cli.rb
@@ -1,4 +1,3 @@
-require 'rbconfig'
require 'rails/app_rails_loader'
# If we are inside a Rails application this method performs an exec and thus
diff --git a/railties/lib/rails/commands/application.rb b/railties/lib/rails/commands/application.rb
index 678697f09b..c998e6b6a8 100644
--- a/railties/lib/rails/commands/application.rb
+++ b/railties/lib/rails/commands/application.rb
@@ -13,5 +13,5 @@ module Rails
end
end
-Rails::Generators::AppPreparer.new(ARGV).prepare!
-Rails::Generators::AppGenerator.start
+args = Rails::Generators::ARGVScrubber.new(ARGV).prepare!
+Rails::Generators::AppGenerator.start args
diff --git a/railties/lib/rails/commands/commands_tasks.rb b/railties/lib/rails/commands/commands_tasks.rb
index 59d2a0793e..6cfbc70c51 100644
--- a/railties/lib/rails/commands/commands_tasks.rb
+++ b/railties/lib/rails/commands/commands_tasks.rb
@@ -20,7 +20,6 @@ The most common rails commands are:
new application called MyApp in "./my_app"
In addition to those, there are:
- application Generate the Rails application code
destroy Undo code generated with "generate" (short-cut alias: "d")
plugin new Generates skeleton for developing a Rails plugin
runner Run a piece of code in the application environment (short-cut alias: "r")
@@ -28,7 +27,7 @@ In addition to those, there are:
All commands can be run with -h (or --help) for more information.
EOT
- COMMAND_WHITELIST = %(plugin generate destroy console server dbconsole application runner new version help)
+ COMMAND_WHITELIST = %w(plugin generate destroy console server dbconsole runner new version help)
def initialize(argv)
@argv = argv
@@ -87,10 +86,6 @@ EOT
Rails::DBConsole.start
end
- def application
- require_command!("application")
- end
-
def runner
require_command!("runner")
end
@@ -139,7 +134,7 @@ EOT
# This allows us to run `rails server` from other directories, but still get
# the main config.ru and properly set the tmp directory.
def set_application_directory!
- Dir.chdir(File.expand_path('../../', APP_PATH)) unless File.exists?(File.expand_path("config.ru"))
+ Dir.chdir(File.expand_path('../../', APP_PATH)) unless File.exist?(File.expand_path("config.ru"))
end
def require_application_and_environment!
diff --git a/railties/lib/rails/commands/console.rb b/railties/lib/rails/commands/console.rb
index f6bdf129d6..555d8f31e1 100644
--- a/railties/lib/rails/commands/console.rb
+++ b/railties/lib/rails/commands/console.rb
@@ -18,7 +18,14 @@ module Rails
opt.on("-e", "--environment=name", String,
"Specifies the environment to run this console under (test/development/production).",
"Default: development") { |v| options[:environment] = v.strip }
- opt.on("--debugger", 'Enable the debugger.') { |v| options[:debugger] = v }
+ opt.on("--debugger", 'Enable the debugger.') do |v|
+ if RUBY_VERSION < '2.0.0'
+ options[:debugger] = v
+ else
+ puts "=> Notice: debugger option is ignored since ruby 2.0 and " \
+ "it will be removed in future versions"
+ end
+ end
opt.parse!(arguments)
end
@@ -69,12 +76,25 @@ module Rails
Rails.env = environment
end
- def debugger?
- options[:debugger]
+ if RUBY_VERSION < '2.0.0'
+ def debugger?
+ options[:debugger]
+ end
+
+ def require_debugger
+ require 'debugger'
+ puts "=> Debugger enabled"
+ rescue LoadError
+ puts "You're missing the 'debugger' gem. Add it to your Gemfile, bundle it and try again."
+ exit(1)
+ end
end
def start
- require_debugger if debugger?
+ if RUBY_VERSION < '2.0.0'
+ require_debugger if debugger?
+ end
+
set_environment! if environment?
if sandbox?
@@ -89,13 +109,5 @@ module Rails
end
console.start
end
-
- def require_debugger
- require 'debugger'
- puts "=> Debugger enabled"
- rescue LoadError
- puts "You're missing the 'debugger' gem. Add it to your Gemfile, bundle it and try again."
- exit(1)
- end
end
end
diff --git a/railties/lib/rails/commands/dbconsole.rb b/railties/lib/rails/commands/dbconsole.rb
index 3e4cc787c4..1a2613a8d0 100644
--- a/railties/lib/rails/commands/dbconsole.rb
+++ b/railties/lib/rails/commands/dbconsole.rb
@@ -20,7 +20,7 @@ module Rails
ENV['RAILS_ENV'] = options[:environment] || environment
case config["adapter"]
- when /^mysql/
+ when /^(jdbc)?mysql/
args = {
'host' => '--host',
'port' => '--port',
@@ -81,14 +81,11 @@ module Rails
def config
@config ||= begin
- cfg = begin
- YAML.load(ERB.new(IO.read("config/database.yml")).result)
- rescue SyntaxError, StandardError
- require APP_PATH
- Rails.application.config.database_configuration
+ if configurations[environment].blank?
+ raise ActiveRecord::AdapterNotSpecified, "'#{environment}' database is not configured. Available configuration: #{configurations.inspect}"
+ else
+ configurations[environment]
end
-
- cfg[environment] || abort("No database is configured for the environment '#{environment}'")
end
end
@@ -102,6 +99,12 @@ module Rails
protected
+ def configurations
+ require APP_PATH
+ ActiveRecord::Base.configurations = Rails.application.config.database_configuration
+ ActiveRecord::Base.configurations
+ end
+
def parse_arguments(arguments)
options = {}
diff --git a/railties/lib/rails/commands/plugin.rb b/railties/lib/rails/commands/plugin.rb
index 837fe0ec10..95bbdd4cdf 100644
--- a/railties/lib/rails/commands/plugin.rb
+++ b/railties/lib/rails/commands/plugin.rb
@@ -2,6 +2,20 @@ if ARGV.first != "new"
ARGV[0] = "--help"
else
ARGV.shift
+ unless ARGV.delete("--no-rc")
+ customrc = ARGV.index{ |x| x.include?("--rc=") }
+ railsrc = if customrc
+ File.expand_path(ARGV.delete_at(customrc).gsub(/--rc=/, ""))
+ else
+ File.join(File.expand_path("~"), '.railsrc')
+ end
+ if File.exist?(railsrc)
+ extra_args_string = File.read(railsrc)
+ extra_args = extra_args_string.split(/\n+/).flat_map {|l| l.split}
+ puts "Using #{extra_args.join(" ")} from #{railsrc}"
+ ARGV.insert(1, *extra_args)
+ end
+ end
end
require 'rails/generators'
diff --git a/railties/lib/rails/commands/runner.rb b/railties/lib/rails/commands/runner.rb
index 2b77d5d387..3a71f8d3f8 100644
--- a/railties/lib/rails/commands/runner.rb
+++ b/railties/lib/rails/commands/runner.rb
@@ -9,7 +9,7 @@ if ARGV.first.nil?
end
ARGV.clone.options do |opts|
- opts.banner = "Usage: rails runner [options] ('Some.ruby(code)' or a filename)"
+ opts.banner = "Usage: rails runner [options] [<'Some.ruby(code)'> | <filename.rb>]"
opts.separator ""
@@ -22,14 +22,23 @@ ARGV.clone.options do |opts|
opts.on("-h", "--help",
"Show this help message.") { $stdout.puts opts; exit }
+ opts.separator ""
+ opts.separator "Examples: "
+
+ opts.separator " rails runner 'puts Rails.env'"
+ opts.separator " This runs the code `puts Rails.env` after loading the app"
+ opts.separator ""
+ opts.separator " rails runner path/to/filename.rb"
+ opts.separator " This runs the Ruby file located at `path/to/filename.rb` after loading the app"
+
if RbConfig::CONFIG['host_os'] !~ /mswin|mingw/
opts.separator ""
opts.separator "You can also use runner as a shebang line for your executables:"
- opts.separator "-------------------------------------------------------------"
- opts.separator "#!/usr/bin/env #{File.expand_path($0)} runner"
+ opts.separator " -------------------------------------------------------------"
+ opts.separator " #!/usr/bin/env #{File.expand_path($0)} runner"
opts.separator ""
- opts.separator "Product.all.each { |p| p.price *= 2 ; p.save! }"
- opts.separator "-------------------------------------------------------------"
+ opts.separator " Product.all.each { |p| p.price *= 2 ; p.save! }"
+ opts.separator " -------------------------------------------------------------"
end
opts.order! { |o| code_or_file ||= o } rescue retry
@@ -50,5 +59,5 @@ elsif File.exist?(code_or_file)
$0 = code_or_file
Kernel.load code_or_file
else
- eval(code_or_file)
+ eval(code_or_file, binding, __FILE__, __LINE__)
end
diff --git a/railties/lib/rails/commands/server.rb b/railties/lib/rails/commands/server.rb
index 485bd1eb09..6146b6c1db 100644
--- a/railties/lib/rails/commands/server.rb
+++ b/railties/lib/rails/commands/server.rb
@@ -1,6 +1,7 @@
require 'fileutils'
require 'optparse'
require 'action_dispatch'
+require 'rails'
module Rails
class Server < ::Rack::Server
@@ -17,11 +18,18 @@ module Rails
opts.on("-c", "--config=file", String,
"Use custom rackup configuration file") { |v| options[:config] = v }
opts.on("-d", "--daemon", "Make server run as a Daemon.") { options[:daemonize] = true }
- opts.on("-u", "--debugger", "Enable the debugger") { options[:debugger] = true }
+ opts.on("-u", "--debugger", "Enable the debugger") do
+ if RUBY_VERSION < '2.0.0'
+ options[:debugger] = true
+ else
+ puts "=> Notice: debugger option is ignored since ruby 2.0 and " \
+ "it will be removed in future versions"
+ end
+ end
opts.on("-e", "--environment=name", String,
"Specifies the environment to run this server under (test/development/production).",
"Default: development") { |v| options[:environment] = v }
- opts.on("-P","--pid=pid",String,
+ opts.on("-P", "--pid=pid", String,
"Specifies the PID file.",
"Default: tmp/pids/server.pid") { |v| options[:pid] = v }
@@ -32,7 +40,7 @@ module Rails
opt_parser.parse! args
- options[:log_stdout] = options[:daemonize].blank? && options[:environment] == "development"
+ options[:log_stdout] = options[:daemonize].blank? && (options[:environment] || Rails.env) == "development"
options[:server] = args.shift
options
end
@@ -60,30 +68,10 @@ module Rails
end
def start
- url = "#{options[:SSLEnable] ? 'https' : 'http'}://#{options[:Host]}:#{options[:Port]}"
- puts "=> Booting #{ActiveSupport::Inflector.demodulize(server)}"
- puts "=> Rails #{Rails.version} application starting in #{Rails.env} on #{url}"
- puts "=> Run `rails server -h` for more startup options"
- if options[:Host].to_s.match(/0\.0\.0\.0/)
- puts "=> Notice: server is listening on all interfaces (#{options[:Host]}). Consider using 127.0.0.1 (--binding option)"
- end
+ print_boot_information
trap(:INT) { exit }
- puts "=> Ctrl-C to shutdown server" unless options[:daemonize]
-
- #Create required tmp directories if not found
- %w(cache pids sessions sockets).each do |dir_to_make|
- FileUtils.mkdir_p(File.join(Rails.root, 'tmp', dir_to_make))
- end
-
- if options[:log_stdout]
- wrapped_app # touch the app so the logger is set up
-
- console = ActiveSupport::Logger.new($stdout)
- console.formatter = Rails.logger.formatter
- console.level = Rails.logger.level
-
- Rails.logger.extend(ActiveSupport::Logger.broadcast(console))
- end
+ create_tmp_directories
+ log_to_stdout if options[:log_stdout]
super
ensure
@@ -94,7 +82,9 @@ module Rails
def middleware
middlewares = []
- middlewares << [Rails::Rack::Debugger] if options[:debugger]
+ if RUBY_VERSION < '2.0.0'
+ middlewares << [Rails::Rack::Debugger] if options[:debugger]
+ end
middlewares << [::Rack::ContentLength]
# FIXME: add Rack::Lock in the case people are using webrick.
@@ -114,14 +104,45 @@ module Rails
def default_options
super.merge({
- Port: 3000,
- DoNotReverseLookup: true,
- environment: (ENV['RAILS_ENV'] || ENV['RACK_ENV'] || "development").dup,
- daemonize: false,
- debugger: false,
- pid: File.expand_path("tmp/pids/server.pid"),
- config: File.expand_path("config.ru")
+ Port: 3000,
+ DoNotReverseLookup: true,
+ environment: (ENV['RAILS_ENV'] || ENV['RACK_ENV'] || "development").dup,
+ daemonize: false,
+ debugger: false,
+ pid: File.expand_path("tmp/pids/server.pid"),
+ config: File.expand_path("config.ru")
})
end
+
+ private
+
+ def print_boot_information
+ url = "#{options[:SSLEnable] ? 'https' : 'http'}://#{options[:Host]}:#{options[:Port]}"
+ puts "=> Booting #{ActiveSupport::Inflector.demodulize(server)}"
+ puts "=> Rails #{Rails.version} application starting in #{Rails.env} on #{url}"
+ puts "=> Run `rails server -h` for more startup options"
+
+ if options[:Host].to_s.match(/0\.0\.0\.0/)
+ puts "=> Notice: server is listening on all interfaces (#{options[:Host]}). Consider using 127.0.0.1 (--binding option)"
+ end
+
+ puts "=> Ctrl-C to shutdown server" unless options[:daemonize]
+ end
+
+ def create_tmp_directories
+ %w(cache pids sessions sockets).each do |dir_to_make|
+ FileUtils.mkdir_p(File.join(Rails.root, 'tmp', dir_to_make))
+ end
+ end
+
+ def log_to_stdout
+ wrapped_app # touch the app so the logger is set up
+
+ console = ActiveSupport::Logger.new($stdout)
+ console.formatter = Rails.logger.formatter
+ console.level = Rails.logger.level
+
+ Rails.logger.extend(ActiveSupport::Logger.broadcast(console))
+ end
end
end
diff --git a/railties/lib/rails/configuration.rb b/railties/lib/rails/configuration.rb
index c694513960..f5d7dede66 100644
--- a/railties/lib/rails/configuration.rb
+++ b/railties/lib/rails/configuration.rb
@@ -59,6 +59,10 @@ module Rails
@operations << [__method__, args, block]
end
+ def unshift(*args, &block)
+ @operations << [__method__, args, block]
+ end
+
def merge_into(other) #:nodoc:
@operations.each do |operation, args, block|
other.send(operation, *args, &block)
diff --git a/railties/lib/rails/engine.rb b/railties/lib/rails/engine.rb
index e8adef2fd3..b36ab3d0d5 100644
--- a/railties/lib/rails/engine.rb
+++ b/railties/lib/rails/engine.rb
@@ -2,7 +2,6 @@ require 'rails/railtie'
require 'rails/engine/railties'
require 'active_support/core_ext/module/delegation'
require 'pathname'
-require 'rbconfig'
module Rails
# <tt>Rails::Engine</tt> allows you to wrap a specific Rails application or subset of
@@ -260,7 +259,7 @@ module Rails
#
# class FooController < ApplicationController
# def index
- # my_engine.root_url #=> /my_engine/
+ # my_engine.root_url # => /my_engine/
# end
# end
#
@@ -269,7 +268,7 @@ module Rails
# module MyEngine
# class BarController
# def index
- # main_app.foo_path #=> /foo
+ # main_app.foo_path # => /foo
# end
# end
# end
@@ -372,7 +371,7 @@ module Rails
end
def isolate_namespace(mod)
- engine_name(generate_railtie_name(mod))
+ engine_name(generate_railtie_name(mod.name))
self.routes.default_scope = { module: ActiveSupport::Inflector.underscore(mod.name) }
self.isolated = true
@@ -430,7 +429,6 @@ module Rails
# Load console and invoke the registered hooks.
# Check <tt>Rails::Railtie.console</tt> for more info.
def load_console(app=self)
- require "pp"
require "rails/console/app"
require "rails/console/helpers"
run_console_blocks(app)
@@ -465,7 +463,7 @@ module Rails
# files inside eager_load paths.
def eager_load!
config.eager_load_paths.each do |load_path|
- matcher = /\A#{Regexp.escape(load_path)}\/(.*)\.rb\Z/
+ matcher = /\A#{Regexp.escape(load_path.to_s)}\/(.*)\.rb\Z/
Dir.glob("#{load_path}/**/*.rb").sort.each do |file|
require_dependency file.sub(matcher, '\1')
end
@@ -611,7 +609,7 @@ module Rails
initializer :load_config_initializers do
config.paths["config/initializers"].existent.sort.each do |initializer|
- load(initializer)
+ load_config_initializer(initializer)
end
end
@@ -645,6 +643,12 @@ module Rails
protected
+ def load_config_initializer(initializer)
+ ActiveSupport::Notifications.instrument('load_config_initializer.railties', initializer: initializer) do
+ load(initializer)
+ end
+ end
+
def run_tasks_blocks(*) #:nodoc:
super
paths["lib/tasks"].existent.sort.each { |ext| load(ext) }
diff --git a/railties/lib/rails/gem_version.rb b/railties/lib/rails/gem_version.rb
new file mode 100644
index 0000000000..c7397c4f15
--- /dev/null
+++ b/railties/lib/rails/gem_version.rb
@@ -0,0 +1,15 @@
+module Rails
+ # Returns the version of the currently loaded Rails as a <tt>Gem::Version</tt>
+ def self.gem_version
+ Gem::Version.new VERSION::STRING
+ end
+
+ module VERSION
+ MAJOR = 4
+ MINOR = 2
+ TINY = 0
+ PRE = "alpha"
+
+ STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
+ end
+end
diff --git a/railties/lib/rails/generators.rb b/railties/lib/rails/generators.rb
index 6b34db3e3f..bf2390cb7e 100644
--- a/railties/lib/rails/generators.rb
+++ b/railties/lib/rails/generators.rb
@@ -1,6 +1,8 @@
activesupport_path = File.expand_path('../../../../activesupport/lib', __FILE__)
$:.unshift(activesupport_path) if File.directory?(activesupport_path) && !$:.include?(activesupport_path)
+require 'thor/group'
+
require 'active_support'
require 'active_support/core_ext/object/blank'
require 'active_support/core_ext/kernel/singleton_class'
@@ -9,12 +11,11 @@ require 'active_support/core_ext/hash/deep_merge'
require 'active_support/core_ext/module/attribute_accessors'
require 'active_support/core_ext/string/inflections'
-require 'rails/generators/base'
-
module Rails
module Generators
autoload :Actions, 'rails/generators/actions'
autoload :ActiveModel, 'rails/generators/active_model'
+ autoload :Base, 'rails/generators/base'
autoload :Migration, 'rails/generators/migration'
autoload :NamedBase, 'rails/generators/named_base'
autoload :ResourceHelpers, 'rails/generators/resource_helpers'
@@ -155,10 +156,20 @@ module Rails
args << "--help" if args.empty? && klass.arguments.any? { |a| a.required? }
klass.start(args, config)
else
- puts "Could not find generator #{namespace}."
+ options = sorted_groups.map(&:last).flatten
+ suggestions = options.sort_by {|suggested| levenshtein_distance(namespace.to_s, suggested) }.first(3)
+ msg = "Could not find generator '#{namespace}'. "
+ msg << "Maybe you meant #{ suggestions.map {|s| "'#{s}'"}.join(" or ") }\n"
+ msg << "Run `rails generate --help` for more options."
+ puts msg
end
end
+ # Returns an array of generator namespaces that are hidden.
+ # Generator namespaces may be hidden for a variety of reasons.
+ # Some are aliased such as "rails:migration" and can be
+ # invoked with the shorter "migration", others are private to other generators
+ # such as "css:scaffold".
def self.hidden_namespaces
@hidden_namespaces ||= begin
orm = options[:rails][:orm]
@@ -198,17 +209,6 @@ module Rails
# Show help message with available generators.
def self.help(command = 'generate')
- lookup!
-
- namespaces = subclasses.map{ |k| k.namespace }
- namespaces.sort!
-
- groups = Hash.new { |h,k| h[k] = [] }
- namespaces.each do |namespace|
- base = namespace.split(':').first
- groups[base] << namespace
- end
-
puts "Usage: rails #{command} GENERATOR [args] [options]"
puts
puts "General options:"
@@ -221,20 +221,74 @@ module Rails
puts "Please choose a generator below."
puts
- # Print Rails defaults first.
+ print_generators
+ end
+
+ def self.public_namespaces
+ lookup!
+ subclasses.map { |k| k.namespace }
+ end
+
+ def self.print_generators
+ sorted_groups.each { |b, n| print_list(b, n) }
+ end
+
+ def self.sorted_groups
+ namespaces = public_namespaces
+ namespaces.sort!
+ groups = Hash.new { |h,k| h[k] = [] }
+ namespaces.each do |namespace|
+ base = namespace.split(':').first
+ groups[base] << namespace
+ end
rails = groups.delete("rails")
rails.map! { |n| n.sub(/^rails:/, '') }
rails.delete("app")
rails.delete("plugin")
- print_list("rails", rails)
hidden_namespaces.each { |n| groups.delete(n.to_s) }
- groups.sort.each { |b, n| print_list(b, n) }
+ [["rails", rails]] + groups.sort.to_a
end
protected
+ # This code is based directly on the Text gem implementation
+ # Returns a value representing the "cost" of transforming str1 into str2
+ def self.levenshtein_distance str1, str2
+ s = str1
+ t = str2
+ n = s.length
+ m = t.length
+ max = n/2
+
+ return m if (0 == n)
+ return n if (0 == m)
+ return n if (n - m).abs > max
+
+ d = (0..m).to_a
+ x = nil
+
+ str1.each_char.each_with_index do |char1,i|
+ e = i+1
+
+ str2.each_char.each_with_index do |char2,j|
+ cost = (char1 == char2) ? 0 : 1
+ x = [
+ d[j+1] + 1, # insertion
+ e + 1, # deletion
+ d[j] + cost # substitution
+ ].min
+ d[j] = e
+ e = x
+ end
+
+ d[m] = x
+ end
+
+ return x
+ end
+
# Prints a list of generators.
def self.print_list(base, namespaces) #:nodoc:
namespaces = namespaces.reject do |n|
diff --git a/railties/lib/rails/generators/actions.rb b/railties/lib/rails/generators/actions.rb
index 366c72ebaa..a239874df0 100644
--- a/railties/lib/rails/generators/actions.rb
+++ b/railties/lib/rails/generators/actions.rb
@@ -9,7 +9,7 @@ module Rails
@in_group = nil
end
- # Adds an entry into Gemfile for the supplied gem.
+ # Adds an entry into +Gemfile+ for the supplied gem.
#
# gem "rspec", group: :test
# gem "technoweenie-restful-authentication", lib: "restful-authentication", source: "http://gems.github.com/"
@@ -20,9 +20,9 @@ module Rails
# Set the message to be shown in logs. Uses the git repo if one is given,
# otherwise use name (version).
- parts, message = [ name.inspect ], name
+ parts, message = [ quote(name) ], name
if version ||= options.delete(:version)
- parts << version.inspect
+ parts << quote(version)
message << " (#{version})"
end
message = options[:git] if options[:git]
@@ -30,7 +30,7 @@ module Rails
log :gemfile, message
options.each do |option, value|
- parts << "#{option}: #{value.inspect}"
+ parts << "#{option}: #{quote(value)}"
end
in_root do
@@ -61,21 +61,21 @@ module Rails
end
end
- # Add the given source to Gemfile
+ # Add the given source to +Gemfile+
#
# add_source "http://gems.github.com/"
def add_source(source, options={})
log :source, source
in_root do
- prepend_file "Gemfile", "source #{source.inspect}\n", verbose: false
+ prepend_file "Gemfile", "source #{quote(source)}\n", verbose: false
end
end
- # Adds a line inside the Application class for config/application.rb.
+ # Adds a line inside the Application class for <tt>config/application.rb</tt>.
#
- # If options :env is specified, the line is appended to the corresponding
- # file in config/environments.
+ # If options <tt>:env</tt> is specified, the line is appended to the corresponding
+ # file in <tt>config/environments</tt>.
#
# environment do
# "config.autoload_paths += %W(#{config.root}/extras)"
@@ -116,7 +116,7 @@ module Rails
end
end
- # Create a new file in the vendor/ directory. Code can be specified
+ # Create a new file in the <tt>vendor/</tt> directory. Code can be specified
# in a block or a data string can be given.
#
# vendor("sekrit.rb") do
@@ -143,7 +143,7 @@ module Rails
create_file("lib/#{filename}", data, verbose: false, &block)
end
- # Create a new Rakefile with the provided code (either in a block or a string).
+ # Create a new +Rakefile+ with the provided code (either in a block or a string).
#
# rakefile("bootstrap.rake") do
# project = ask("What is the UNIX name of your project?")
@@ -188,7 +188,7 @@ module Rails
# generate(:authenticated, "user session")
def generate(what, *args)
log :generate, what
- argument = args.map {|arg| arg.to_s }.flatten.join(" ")
+ argument = args.flat_map {|arg| arg.to_s }.join(" ")
in_root { run_ruby_script("bin/rails generate #{what} #{argument}", verbose: false) }
end
@@ -213,7 +213,7 @@ module Rails
in_root { run("#{extify(:capify)} .", verbose: false) }
end
- # Make an entry in Rails routing file config/routes.rb
+ # Make an entry in Rails routing file <tt>config/routes.rb</tt>
#
# route "root 'welcome#index'"
def route(routing_code)
@@ -255,6 +255,15 @@ module Rails
end
end
+ # Surround string with single quotes if there is no quotes.
+ # Otherwise fall back to double quotes
+ def quote(str)
+ if str.include?("'")
+ str.inspect
+ else
+ "'#{str}'"
+ end
+ end
end
end
end
diff --git a/railties/lib/rails/generators/actions/create_migration.rb b/railties/lib/rails/generators/actions/create_migration.rb
new file mode 100644
index 0000000000..cf3b7acfff
--- /dev/null
+++ b/railties/lib/rails/generators/actions/create_migration.rb
@@ -0,0 +1,68 @@
+require 'thor/actions'
+
+module Rails
+ module Generators
+ module Actions
+ class CreateMigration < Thor::Actions::CreateFile
+
+ def migration_dir
+ File.dirname(@destination)
+ end
+
+ def migration_file_name
+ @base.migration_file_name
+ end
+
+ def identical?
+ exists? && File.binread(existing_migration) == render
+ end
+
+ def revoke!
+ say_destination = exists? ? relative_existing_migration : relative_destination
+ say_status :remove, :red, say_destination
+ return unless exists?
+ ::FileUtils.rm_rf(existing_migration) unless pretend?
+ existing_migration
+ end
+
+ def relative_existing_migration
+ base.relative_to_original_destination_root(existing_migration)
+ end
+
+ def existing_migration
+ @existing_migration ||= begin
+ @base.class.migration_exists?(migration_dir, migration_file_name) ||
+ File.exist?(@destination) && @destination
+ end
+ end
+ alias :exists? :existing_migration
+
+ protected
+
+ def on_conflict_behavior(&block)
+ options = base.options.merge(config)
+ if identical?
+ say_status :identical, :blue, relative_existing_migration
+ elsif options[:force]
+ say_status :remove, :green, relative_existing_migration
+ say_status :create, :green
+ unless pretend?
+ ::FileUtils.rm_rf(existing_migration)
+ block.call
+ end
+ elsif options[:skip]
+ say_status :skip, :yellow
+ else
+ say_status :conflict, :red
+ raise Error, "Another migration is already named #{migration_file_name}: " +
+ "#{existing_migration}. Use --force to replace this migration file."
+ end
+ end
+
+ def say_status(status, color, message = relative_destination)
+ base.shell.say_status(status, message, color) if config[:verbose]
+ end
+ end
+ end
+ end
+end
diff --git a/railties/lib/rails/generators/app_base.rb b/railties/lib/rails/generators/app_base.rb
index 6f1b7e2218..76f8a1b816 100644
--- a/railties/lib/rails/generators/app_base.rb
+++ b/railties/lib/rails/generators/app_base.rb
@@ -1,10 +1,10 @@
require 'digest/md5'
-require 'securerandom'
require 'active_support/core_ext/string/strip'
require 'rails/version' unless defined?(Rails::VERSION)
-require 'rbconfig'
require 'open-uri'
require 'uri'
+require 'rails/generators'
+require 'active_support/core_ext/array/extract_options'
module Rails
module Generators
@@ -41,12 +41,18 @@ module Rails
class_option :skip_active_record, type: :boolean, aliases: '-O', default: false,
desc: 'Skip Active Record files'
+ class_option :skip_gems, type: :array, default: [],
+ desc: 'Skip the provided gems files'
+
class_option :skip_action_view, type: :boolean, aliases: '-V', default: false,
desc: 'Skip Action View files'
class_option :skip_sprockets, type: :boolean, aliases: '-S', default: false,
desc: 'Skip Sprockets files'
+ class_option :skip_spring, type: :boolean, default: false,
+ desc: "Don't install Spring application preloader"
+
class_option :database, type: :string, aliases: '-d', default: 'sqlite3',
desc: "Preconfigure for selected database (options: #{DATABASES.join('/')})"
@@ -76,13 +82,47 @@ module Rails
end
def initialize(*args)
- @original_wd = Dir.pwd
+ @gem_filter = lambda { |gem| !options[:skip_gems].include?(gem.name) }
+ @extra_entries = []
super
convert_database_option_for_jruby
end
protected
+ def gemfile_entry(name, *args)
+ options = args.extract_options!
+ version = args.first
+ github = options[:github]
+ path = options[:path]
+
+ if github
+ @extra_entries << GemfileEntry.github(name, github)
+ elsif path
+ @extra_entries << GemfileEntry.path(name, path)
+ else
+ @extra_entries << GemfileEntry.version(name, version)
+ end
+ self
+ end
+
+ def gemfile_entries
+ [rails_gemfile_entry,
+ database_gemfile_entry,
+ assets_gemfile_entry,
+ javascript_gemfile_entry,
+ jbuilder_gemfile_entry,
+ sdoc_gemfile_entry,
+ spring_gemfile_entry,
+ @extra_entries].flatten.find_all(&@gem_filter)
+ end
+
+ def add_gem_entry_filter
+ @gem_filter = lambda { |next_filter, entry|
+ yield(entry) && next_filter.call(entry)
+ }.curry[@gem_filter]
+ end
+
def builder
@builder ||= begin
builder_class = get_builder_class
@@ -96,11 +136,9 @@ module Rails
end
def create_root
- self.destination_root = File.expand_path(app_path, destination_root)
valid_const?
empty_directory '.'
- set_default_accessors!
FileUtils.cd(destination_root) unless options[:pretend]
end
@@ -111,6 +149,7 @@ module Rails
end
def set_default_accessors!
+ self.destination_root = File.expand_path(app_path, destination_root)
self.rails_template = case options[:template]
when /^https?:\/\//
options[:template]
@@ -122,11 +161,9 @@ module Rails
end
def database_gemfile_entry
- options[:skip_active_record] ? "" :
- <<-GEMFILE.strip_heredoc
- # Use #{options[:database]} as the database for Active Record
- gem '#{gem_for_database}'
- GEMFILE
+ return [] if options[:skip_active_record]
+ GemfileEntry.version gem_for_database, nil,
+ "Use #{options[:database]} as the database for Active Record"
end
def include_all_railties?
@@ -137,22 +174,43 @@ module Rails
options[value] ? '# ' : ''
end
+ def sqlite3?
+ !options[:skip_active_record] && options[:database] == 'sqlite3'
+ end
+
+ class GemfileEntry < Struct.new(:name, :version, :comment, :options, :commented_out)
+ def initialize(name, version, comment, options = {}, commented_out = false)
+ super
+ end
+
+ def self.github(name, github, comment = nil)
+ new(name, nil, comment, github: github)
+ end
+
+ def self.version(name, version, comment = nil)
+ new(name, version, comment)
+ end
+
+ def self.path(name, path, comment = nil)
+ new(name, nil, comment, path: path)
+ end
+
+ def padding(max_width)
+ ' ' * (max_width - name.length + 2)
+ end
+ end
+
def rails_gemfile_entry
if options.dev?
- <<-GEMFILE.strip_heredoc
- gem 'rails', path: '#{Rails::Generators::RAILS_DEV_PATH}'
- gem 'arel', github: 'rails/arel'
- GEMFILE
+ [GemfileEntry.path('rails', Rails::Generators::RAILS_DEV_PATH),
+ GemfileEntry.github('arel', 'rails/arel')]
elsif options.edge?
- <<-GEMFILE.strip_heredoc
- gem 'rails', github: 'rails/rails'
- gem 'arel', github: 'rails/arel'
- GEMFILE
+ [GemfileEntry.github('rails', 'rails/rails'),
+ GemfileEntry.github('arel', 'rails/arel')]
else
- <<-GEMFILE.strip_heredoc
- # Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
- gem 'rails', '#{Rails::VERSION::STRING}'
- GEMFILE
+ [GemfileEntry.version('rails',
+ Rails::VERSION::STRING,
+ "Bundle edge Rails instead: gem 'rails', github: 'rails/rails'")]
end
end
@@ -184,77 +242,73 @@ module Rails
end
def assets_gemfile_entry
- return if options[:skip_sprockets]
+ return [] if options[:skip_sprockets]
- gemfile = if options.dev? || options.edge?
- <<-GEMFILE.strip_heredoc
- # Use edge version of sprockets-rails
- gem 'sprockets-rails', github: 'rails/sprockets-rails'
-
- # Use SCSS for stylesheets
- gem 'sass-rails', github: 'rails/sass-rails'
- GEMFILE
+ gems = []
+ if options.dev? || options.edge?
+ gems << GemfileEntry.github('sprockets-rails', 'rails/sprockets-rails',
+ 'Use edge version of sprockets-rails')
+ gems << GemfileEntry.github('sass-rails', 'rails/sass-rails',
+ 'Use SCSS for stylesheets')
else
- <<-GEMFILE.strip_heredoc
- # Use SCSS for stylesheets
- gem 'sass-rails', '~> 4.0.0.rc1'
- GEMFILE
+ gems << GemfileEntry.version('sass-rails',
+ '~> 4.0.3',
+ 'Use SCSS for stylesheets')
end
- gemfile += <<-GEMFILE.strip_heredoc
+ gems << GemfileEntry.version('uglifier',
+ '>= 1.3.0',
+ 'Use Uglifier as compressor for JavaScript assets')
- # Use Uglifier as compressor for JavaScript assets
- gem 'uglifier', '>= 1.3.0'
- GEMFILE
+ gems
+ end
- if options[:skip_javascript]
- gemfile += <<-GEMFILE
- #{coffee_gemfile_entry}
- #{javascript_runtime_gemfile_entry}
- GEMFILE
- end
+ def jbuilder_gemfile_entry
+ comment = 'Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder'
+ GemfileEntry.version('jbuilder', '~> 2.0', comment)
+ end
- gemfile.gsub(/^[ \t]+/, '')
+ def sdoc_gemfile_entry
+ comment = 'bundle exec rake doc:rails generates the API under doc/api.'
+ GemfileEntry.new('sdoc', '~> 0.4.0', comment, group: :doc)
end
def coffee_gemfile_entry
+ comment = 'Use CoffeeScript for .js.coffee assets and views'
if options.dev? || options.edge?
- <<-GEMFILE
- # Use CoffeeScript for .js.coffee assets and views
- gem 'coffee-rails', github: 'rails/coffee-rails'
- GEMFILE
+ GemfileEntry.github 'coffee-rails', 'rails/coffee-rails', comment
else
- <<-GEMFILE
- # Use CoffeeScript for .js.coffee assets and views
- gem 'coffee-rails', '~> 4.0.0'
- GEMFILE
+ GemfileEntry.version 'coffee-rails', '~> 4.0.0', comment
end
end
def javascript_gemfile_entry
- unless options[:skip_javascript]
- <<-GEMFILE.gsub(/^[ \t]+/, '')
- #{coffee_gemfile_entry}
- #{javascript_runtime_gemfile_entry}
- # Use #{options[:javascript]} as the JavaScript library
- gem '#{options[:javascript]}-rails'
-
- # Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks
- gem 'turbolinks'
- GEMFILE
+ if options[:skip_javascript]
+ []
+ else
+ gems = [coffee_gemfile_entry, javascript_runtime_gemfile_entry]
+ gems << GemfileEntry.version("#{options[:javascript]}-rails", nil,
+ "Use #{options[:javascript]} as the JavaScript library")
+
+ gems << GemfileEntry.version("turbolinks", nil,
+ "Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks")
+ gems
end
end
def javascript_runtime_gemfile_entry
- runtime = if defined?(JRUBY_VERSION)
- "gem 'therubyrhino'"
+ comment = 'See https://github.com/sstephenson/execjs#readme for more supported runtimes'
+ if defined?(JRUBY_VERSION)
+ GemfileEntry.version 'therubyrhino', nil, comment
else
- "# gem 'therubyracer', platforms: :ruby"
+ GemfileEntry.new 'therubyracer', nil, comment, { platforms: :ruby }, true
end
- <<-GEMFILE
- # See https://github.com/sstephenson/execjs#readme for more supported runtimes
- #{runtime}
- GEMFILE
+ end
+
+ def spring_gemfile_entry
+ return [] unless spring_install?
+ comment = 'Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring'
+ GemfileEntry.new('spring', nil, comment, group: :development)
end
def bundle_command(command)
@@ -276,12 +330,27 @@ module Rails
require 'bundler'
Bundler.with_clean_env do
- print `"#{Gem.ruby}" "#{_bundle_command}" #{command}`
+ output = `"#{Gem.ruby}" "#{_bundle_command}" #{command}`
+ print output unless options[:quiet]
end
end
+ def bundle_install?
+ !(options[:skip_gemfile] || options[:skip_bundle] || options[:pretend])
+ end
+
+ def spring_install?
+ !options[:skip_spring] && Process.respond_to?(:fork)
+ end
+
def run_bundle
- bundle_command('install') unless options[:skip_gemfile] || options[:skip_bundle] || options[:pretend]
+ bundle_command('install') if bundle_install?
+ end
+
+ def generate_spring_binstubs
+ if bundle_install? && spring_install?
+ bundle_command("exec spring binstub --all")
+ end
end
def empty_directory_with_keep_file(destination, config = {})
diff --git a/railties/lib/rails/generators/base.rb b/railties/lib/rails/generators/base.rb
index 8aec8bc8f9..9af6435f23 100644
--- a/railties/lib/rails/generators/base.rb
+++ b/railties/lib/rails/generators/base.rb
@@ -7,8 +7,6 @@ rescue LoadError
exit
end
-require 'rails/generators/actions'
-
module Rails
module Generators
class Error < Thor::Error # :nodoc:
@@ -85,7 +83,7 @@ module Rails
#
# The first and last part used to find the generator to be invoked are
# guessed based on class invokes hook_for, as noticed in the example above.
- # This can be customized with two options: :base and :as.
+ # This can be customized with two options: :in and :as.
#
# Let's suppose you are creating a generator that needs to invoke the
# controller generator from test unit. Your first attempt is:
@@ -110,7 +108,7 @@ module Rails
# "test_unit:controller", "test_unit"
#
# Similarly, if you want it to also lookup in the rails namespace, you just
- # need to provide the :base value:
+ # need to provide the :in value:
#
# class AwesomeGenerator < Rails::Generators::Base
# hook_for :test_framework, in: :rails, as: :controller
@@ -211,7 +209,7 @@ module Rails
return unless base_name && generator_name
return unless default_generator_root
path = File.join(default_generator_root, 'templates')
- path if File.exists?(path)
+ path if File.exist?(path)
end
# Returns the base root for a common set of generators. This is used to dynamically
@@ -298,7 +296,7 @@ module Rails
end
end
- # Return the default value for the option name given doing a lookup in
+ # Returns the default value for the option name given doing a lookup in
# Rails::Generators.options.
def self.default_value_for_option(name, options)
default_for_option(Rails::Generators.options, name, options, options[:default])
@@ -368,12 +366,12 @@ module Rails
source_root && File.expand_path("../USAGE", source_root),
default_generator_root && File.join(default_generator_root, "USAGE")
]
- paths.compact.detect { |path| File.exists? path }
+ paths.compact.detect { |path| File.exist? path }
end
def self.default_generator_root
path = File.expand_path(File.join(base_name, generator_name), base_root)
- path if File.exists?(path)
+ path if File.exist?(path)
end
end
diff --git a/railties/lib/rails/generators/erb.rb b/railties/lib/rails/generators/erb.rb
index 73e986ee7f..0755ac335c 100644
--- a/railties/lib/rails/generators/erb.rb
+++ b/railties/lib/rails/generators/erb.rb
@@ -5,6 +5,10 @@ module Erb # :nodoc:
class Base < Rails::Generators::NamedBase #:nodoc:
protected
+ def formats
+ [format]
+ end
+
def format
:html
end
@@ -13,7 +17,7 @@ module Erb # :nodoc:
:erb
end
- def filename_with_extensions(name)
+ def filename_with_extensions(name, format = self.format)
[name, format, handler].compact.join(".")
end
end
diff --git a/railties/lib/rails/generators/erb/controller/controller_generator.rb b/railties/lib/rails/generators/erb/controller/controller_generator.rb
index 5f06734ab8..94c1b835d1 100644
--- a/railties/lib/rails/generators/erb/controller/controller_generator.rb
+++ b/railties/lib/rails/generators/erb/controller/controller_generator.rb
@@ -11,8 +11,10 @@ module Erb # :nodoc:
actions.each do |action|
@action = action
- @path = File.join(base_path, filename_with_extensions(action))
- template filename_with_extensions(:view), @path
+ formats.each do |format|
+ @path = File.join(base_path, filename_with_extensions(action, format))
+ template filename_with_extensions(:view, format), @path
+ end
end
end
end
diff --git a/railties/lib/rails/generators/erb/mailer/mailer_generator.rb b/railties/lib/rails/generators/erb/mailer/mailer_generator.rb
index 7bcac30dde..66b17bd10e 100644
--- a/railties/lib/rails/generators/erb/mailer/mailer_generator.rb
+++ b/railties/lib/rails/generators/erb/mailer/mailer_generator.rb
@@ -5,8 +5,8 @@ module Erb # :nodoc:
class MailerGenerator < ControllerGenerator # :nodoc:
protected
- def format
- :text
+ def formats
+ [:text, :html]
end
end
end
diff --git a/railties/lib/rails/generators/erb/mailer/templates/view.html.erb b/railties/lib/rails/generators/erb/mailer/templates/view.html.erb
new file mode 100644
index 0000000000..b5045671b3
--- /dev/null
+++ b/railties/lib/rails/generators/erb/mailer/templates/view.html.erb
@@ -0,0 +1,5 @@
+<h1><%= class_name %>#<%= @action %></h1>
+
+<p>
+ <%%= @greeting %>, find me in <%= @path %>
+</p>
diff --git a/railties/lib/rails/generators/erb/mailer/templates/view.text.erb b/railties/lib/rails/generators/erb/mailer/templates/view.text.erb
index 6d597256a6..342285df19 100644
--- a/railties/lib/rails/generators/erb/mailer/templates/view.text.erb
+++ b/railties/lib/rails/generators/erb/mailer/templates/view.text.erb
@@ -1,3 +1,3 @@
<%= class_name %>#<%= @action %>
-<%%= @greeting %>, find me in app/views/<%= @path %>
+<%%= @greeting %>, find me in <%= @path %>
diff --git a/railties/lib/rails/generators/erb/scaffold/scaffold_generator.rb b/railties/lib/rails/generators/erb/scaffold/scaffold_generator.rb
index bacbc2d280..c94829a0ae 100644
--- a/railties/lib/rails/generators/erb/scaffold/scaffold_generator.rb
+++ b/railties/lib/rails/generators/erb/scaffold/scaffold_generator.rb
@@ -14,8 +14,10 @@ module Erb # :nodoc:
def copy_view_files
available_views.each do |view|
- filename = filename_with_extensions(view)
- template filename, File.join("app/views", controller_file_path, filename)
+ formats.each do |format|
+ filename = filename_with_extensions(view, format)
+ template filename, File.join("app/views", controller_file_path, filename)
+ end
end
end
diff --git a/railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb b/railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb
index 69c10efa47..da99e74435 100644
--- a/railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb
+++ b/railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb
@@ -4,8 +4,8 @@
<h2><%%= pluralize(@<%= singular_table_name %>.errors.count, "error") %> prohibited this <%= singular_table_name %> from being saved:</h2>
<ul>
- <%% @<%= singular_table_name %>.errors.full_messages.each do |msg| %>
- <li><%%= msg %></li>
+ <%% @<%= singular_table_name %>.errors.full_messages.each do |message| %>
+ <li><%%= message %></li>
<%% end %>
</ul>
</div>
@@ -21,13 +21,8 @@
<%%= f.label :password_confirmation %><br>
<%%= f.password_field :password_confirmation %>
<% else -%>
- <%- if attribute.reference? -%>
<%%= f.label :<%= attribute.column_name %> %><br>
<%%= f.<%= attribute.field_type %> :<%= attribute.column_name %> %>
- <%- else -%>
- <%%= f.label :<%= attribute.name %> %><br>
- <%%= f.<%= attribute.field_type %> :<%= attribute.name %> %>
- <%- end -%>
<% end -%>
</div>
<% end -%>
diff --git a/railties/lib/rails/generators/erb/scaffold/templates/edit.html.erb b/railties/lib/rails/generators/erb/scaffold/templates/edit.html.erb
index e58b9fbd08..5620fcc850 100644
--- a/railties/lib/rails/generators/erb/scaffold/templates/edit.html.erb
+++ b/railties/lib/rails/generators/erb/scaffold/templates/edit.html.erb
@@ -1,4 +1,4 @@
-<h1>Editing <%= singular_table_name %></h1>
+<h1>Editing <%= singular_table_name.titleize %></h1>
<%%= render 'form' %>
diff --git a/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb b/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb
index 814d6fdb0e..025b1d8699 100644
--- a/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb
+++ b/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb
@@ -1,4 +1,4 @@
-<h1>Listing <%= plural_table_name %></h1>
+<h1>Listing <%= plural_table_name.titleize %></h1>
<table>
<thead>
diff --git a/railties/lib/rails/generators/erb/scaffold/templates/new.html.erb b/railties/lib/rails/generators/erb/scaffold/templates/new.html.erb
index 02ae4d015e..db13a5d870 100644
--- a/railties/lib/rails/generators/erb/scaffold/templates/new.html.erb
+++ b/railties/lib/rails/generators/erb/scaffold/templates/new.html.erb
@@ -1,4 +1,4 @@
-<h1>New <%= singular_table_name %></h1>
+<h1>New <%= singular_table_name.titleize %></h1>
<%%= render 'form' %>
diff --git a/railties/lib/rails/generators/generated_attribute.rb b/railties/lib/rails/generators/generated_attribute.rb
index 5e2784c4b0..c5326d70d1 100644
--- a/railties/lib/rails/generators/generated_attribute.rb
+++ b/railties/lib/rails/generators/generated_attribute.rb
@@ -94,6 +94,10 @@ module Rails
name.sub(/_id$/, '').pluralize
end
+ def singular_name
+ name.sub(/_id$/, '').singularize
+ end
+
def human_name
name.humanize
end
diff --git a/railties/lib/rails/generators/migration.rb b/railties/lib/rails/generators/migration.rb
index 3566f96f5e..cd388e590a 100644
--- a/railties/lib/rails/generators/migration.rb
+++ b/railties/lib/rails/generators/migration.rb
@@ -1,4 +1,5 @@
require 'active_support/concern'
+require 'rails/generators/actions/create_migration'
module Rails
module Generators
@@ -29,6 +30,19 @@ module Rails
end
end
+ def create_migration(destination, data, config = {}, &block)
+ action Rails::Generators::Actions::CreateMigration.new(self, destination, block || data.to_s, config)
+ end
+
+ def set_migration_assigns!(destination)
+ destination = File.expand_path(destination, self.destination_root)
+
+ migration_dir = File.dirname(destination)
+ @migration_number = self.class.next_migration_number(migration_dir)
+ @migration_file_name = File.basename(destination, '.rb')
+ @migration_class_name = @migration_file_name.camelize
+ end
+
# Creates a migration template at the given destination. The difference
# to the default template method is that the migration version is appended
# to the destination file name.
@@ -37,26 +51,18 @@ module Rails
# available as instance variables in the template to be rendered.
#
# migration_template "migration.rb", "db/migrate/add_foo_to_bar.rb"
- def migration_template(source, destination=nil, config={})
- destination = File.expand_path(destination || source, self.destination_root)
+ def migration_template(source, destination, config = {})
+ source = File.expand_path(find_in_source_paths(source.to_s))
- migration_dir = File.dirname(destination)
- @migration_number = self.class.next_migration_number(migration_dir)
- @migration_file_name = File.basename(destination).sub(/\.rb$/, '')
- @migration_class_name = @migration_file_name.camelize
+ set_migration_assigns!(destination)
+ context = instance_eval('binding')
- destination = self.class.migration_exists?(migration_dir, @migration_file_name)
+ dir, base = File.split(destination)
+ numbered_destination = File.join(dir, ["%migration_number%", base].join('_'))
- if !(destination && options[:skip]) && behavior == :invoke
- if destination && options.force?
- remove_file(destination)
- elsif destination
- raise Error, "Another migration is already named #{@migration_file_name}: #{destination}. Use --force to remove the old migration file and replace it."
- end
- destination = File.join(migration_dir, "#{@migration_number}_#{@migration_file_name}.rb")
+ create_migration numbered_destination, nil, config do
+ ERB.new(::File.binread(source), nil, '-', '@output_buffer').result(context)
end
-
- template(source, destination, config)
end
end
end
diff --git a/railties/lib/rails/generators/model_helpers.rb b/railties/lib/rails/generators/model_helpers.rb
new file mode 100644
index 0000000000..42c646543e
--- /dev/null
+++ b/railties/lib/rails/generators/model_helpers.rb
@@ -0,0 +1,28 @@
+require 'rails/generators/active_model'
+
+module Rails
+ module Generators
+ module ModelHelpers # :nodoc:
+ PLURAL_MODEL_NAME_WARN_MESSAGE = "[WARNING] The model name '%s' was recognized as a plural, using the singular '%s' instead. " \
+ "Override with --force-plural or setup custom inflection rules for this noun before running the generator."
+ mattr_accessor :skip_warn
+
+ def self.included(base) #:nodoc:
+ base.class_option :force_plural, type: :boolean, default: false, desc: 'Forces the use of the given model name'
+ end
+
+ def initialize(args, *_options)
+ super
+ if name == name.pluralize && name.singularize != name.pluralize && !options[:force_plural]
+ singular = name.singularize
+ unless ModelHelpers.skip_warn
+ say PLURAL_MODEL_NAME_WARN_MESSAGE % [name, singular]
+ ModelHelpers.skip_warn = true
+ end
+ name.replace singular
+ assign_names!(name)
+ end
+ end
+ end
+ end
+end
diff --git a/railties/lib/rails/generators/named_base.rb b/railties/lib/rails/generators/named_base.rb
index e712c747b0..b7da44ca2d 100644
--- a/railties/lib/rails/generators/named_base.rb
+++ b/railties/lib/rails/generators/named_base.rb
@@ -30,7 +30,12 @@ module Rails
protected
attr_reader :file_name
- alias :singular_name :file_name
+
+ # FIXME: We are avoiding to use alias because a bug on thor that make
+ # this method public and add it to the task list.
+ def singular_name
+ file_name
+ end
# Wrap block with namespace of current application
# if namespace exists and is not skipped
@@ -90,7 +95,7 @@ module Rails
end
def namespaced_path
- @namespaced_path ||= namespace.name.split("::").map {|m| m.underscore }[0]
+ @namespaced_path ||= namespace.name.split("::").first.underscore
end
def class_name
diff --git a/railties/lib/rails/generators/rails/app/app_generator.rb b/railties/lib/rails/generators/rails/app/app_generator.rb
index 92c876c835..188e62b6c8 100644
--- a/railties/lib/rails/generators/rails/app/app_generator.rb
+++ b/railties/lib/rails/generators/rails/app/app_generator.rb
@@ -50,7 +50,7 @@ module Rails
end
def gitignore
- copy_file "gitignore", ".gitignore"
+ template "gitignore", ".gitignore"
end
def app
@@ -78,6 +78,7 @@ module Rails
template "routes.rb"
template "application.rb"
template "environment.rb"
+ template "secrets.yml"
directory "environments"
directory "initializers"
@@ -85,6 +86,16 @@ module Rails
end
end
+ def config_when_updating
+ cookie_serializer_config_exist = File.exist?('config/initializers/cookies_serializer.rb')
+
+ config
+
+ unless cookie_serializer_config_exist
+ gsub_file 'config/initializers/cookies_serializer.rb', /json/, 'marshal'
+ end
+ end
+
def database_yml
template "config/databases/#{options[:database]}.yml", "config/database.yml"
end
@@ -129,7 +140,9 @@ module Rails
end
def vendor_javascripts
- empty_directory_with_keep_file 'vendor/assets/javascripts'
+ unless options[:skip_javascript]
+ empty_directory_with_keep_file 'vendor/assets/javascripts'
+ end
end
def vendor_stylesheets
@@ -162,6 +175,7 @@ module Rails
end
end
+ public_task :set_default_accessors!
public_task :create_root
def create_root_files
@@ -184,6 +198,11 @@ module Rails
build(:config)
end
+ def update_config_files
+ build(:config_when_updating)
+ end
+ remove_task :update_config_files
+
def create_boot_file
template "config/boot.rb"
end
@@ -221,11 +240,24 @@ module Rails
build(:vendor)
end
+ def delete_js_folder_skipping_javascript
+ if options[:skip_javascript]
+ remove_dir 'app/assets/javascripts'
+ end
+ end
+
+ def delete_assets_initializer_skipping_sprockets
+ if options[:skip_sprockets]
+ remove_file 'config/initializers/assets.rb'
+ end
+ end
+
def finish_template
build(:leftovers)
end
public_task :apply_rails_template, :run_bundle
+ public_task :generate_spring_binstubs
protected
@@ -239,7 +271,7 @@ module Rails
end
def app_name
- @app_name ||= (defined_app_const_base? ? defined_app_name : File.basename(destination_root)).tr(".", "_")
+ @app_name ||= (defined_app_const_base? ? defined_app_name : File.basename(destination_root)).tr('\\', '').tr(". ", "_")
end
def defined_app_name
@@ -302,58 +334,67 @@ module Rails
#
# This class should be called before the AppGenerator is required and started
# since it configures and mutates ARGV correctly.
- class AppPreparer # :nodoc
- attr_reader :argv
-
+ class ARGVScrubber # :nodoc
def initialize(argv = ARGV)
@argv = argv
end
def prepare!
- handle_version_request!(argv.first)
- unless handle_invalid_command!(argv.first)
- argv.shift
- handle_rails_rc!
+ handle_version_request!(@argv.first)
+ handle_invalid_command!(@argv.first, @argv) do
+ handle_rails_rc!(@argv.drop(1))
end
end
+ def self.default_rc_file
+ File.expand_path('~/.railsrc')
+ end
+
private
def handle_version_request!(argument)
- if ['--version', '-v'].include?(argv.first)
+ if ['--version', '-v'].include?(argument)
require 'rails/version'
puts "Rails #{Rails::VERSION::STRING}"
exit(0)
end
end
- def handle_invalid_command!(argument)
- if argument != "new"
- argv[0] = "--help"
+ def handle_invalid_command!(argument, argv)
+ if argument == "new"
+ yield
+ else
+ ['--help'] + argv.drop(1)
end
end
- def handle_rails_rc!
- unless argv.delete("--no-rc")
- insert_railsrc_into_argv!(railsrc)
+ def handle_rails_rc!(argv)
+ if argv.find { |arg| arg == '--no-rc' }
+ argv.reject { |arg| arg == '--no-rc' }
+ else
+ railsrc(argv) { |rc_argv, rc| insert_railsrc_into_argv!(rc_argv, rc) }
end
end
- def railsrc
+ def railsrc(argv)
if (customrc = argv.index{ |x| x.include?("--rc=") })
- File.expand_path(argv.delete_at(customrc).gsub(/--rc=/, ""))
+ fname = File.expand_path(argv[customrc].gsub(/--rc=/, ""))
+ yield(argv.take(customrc) + argv.drop(customrc + 1), fname)
else
- File.join(File.expand_path("~"), '.railsrc')
+ yield argv, self.class.default_rc_file
end
end
- def insert_railsrc_into_argv!(railsrc)
- if File.exist?(railsrc)
- extra_args_string = File.read(railsrc)
- extra_args = extra_args_string.split(/\n+/).map {|l| l.split}.flatten
- puts "Using #{extra_args.join(" ")} from #{railsrc}"
- argv.insert(1, *extra_args)
- end
+ def read_rc_file(railsrc)
+ extra_args = File.readlines(railsrc).flat_map(&:split)
+ puts "Using #{extra_args.join(" ")} from #{railsrc}"
+ extra_args
+ end
+
+ def insert_railsrc_into_argv!(argv, railsrc)
+ return argv unless File.exist?(railsrc)
+ extra_args = read_rc_file railsrc
+ argv.take(1) + extra_args + argv.drop(1)
end
end
end
diff --git a/railties/lib/rails/generators/rails/app/templates/Gemfile b/railties/lib/rails/generators/rails/app/templates/Gemfile
index edc76e6c34..5bdbd58097 100644
--- a/railties/lib/rails/generators/rails/app/templates/Gemfile
+++ b/railties/lib/rails/generators/rails/app/templates/Gemfile
@@ -1,33 +1,37 @@
source 'https://rubygems.org'
-<%= rails_gemfile_entry -%>
+<% max_width = gemfile_entries.map { |g| g.name.length }.max -%>
+<% gemfile_entries.each do |gem| -%>
+<% if gem.comment -%>
-<%= database_gemfile_entry -%>
-
-<%= assets_gemfile_entry %>
-<%= javascript_gemfile_entry -%>
-
-# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
-gem 'jbuilder', '~> 1.2'
-
-# Run `rails console` in the browser. Read more: https://github.com/rails/web-console
-gem 'web-console', group: :development
-
-group :doc do
- # bundle exec rake doc:rails generates the API under doc/api.
- gem 'sdoc', require: false
-end
+# <%= gem.comment %>
+<% end -%>
+<%= gem.commented_out ? '# ' : '' %>gem '<%= gem.name %>'<%= %(, '#{gem.version}') if gem.version -%>
+<% if gem.options.any? -%>
+,<%= gem.padding(max_width) %><%= gem.options.map { |k,v|
+ "#{k}: #{v.inspect}" }.join(', ') %>
+<% end -%>
+<% end -%>
# Use ActiveModel has_secure_password
-# gem 'bcrypt-ruby', '~> 3.1.2'
+# gem 'bcrypt', '~> 3.1.7'
-# Use unicorn as the app server
+# Use Unicorn as the app server
# gem 'unicorn'
# Use Capistrano for deployment
-# gem 'capistrano', group: :development
+# gem 'capistrano-rails', group: :development
<% unless defined?(JRUBY_VERSION) -%>
-# Use debugger
+# To use a debugger
+ <%- if RUBY_VERSION < '2.0.0' -%>
# gem 'debugger', group: [:development, :test]
+ <%- else -%>
+# gem 'byebug', group: [:development, :test]
+ <%- end -%>
+<% end -%>
+
+<% if RUBY_PLATFORM.match(/bccwin|cygwin|emx|mingw|mswin|wince/) -%>
+# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
+gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw]
<% end -%>
diff --git a/railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt b/railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt
index 8b91313e51..07ea09cdbd 100644
--- a/railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt
+++ b/railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt
@@ -13,6 +13,8 @@
<% unless options[:skip_javascript] -%>
//= require <%= options[:javascript] %>
//= require <%= options[:javascript] %>_ujs
+<% if gemfile_entries.any? { |m| m.name == "turbolinks" } -%>
//= require turbolinks
<% end -%>
+<% end -%>
//= require_tree .
diff --git a/railties/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt b/railties/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt
index c3d1578818..75ea52828e 100644
--- a/railties/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt
+++ b/railties/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt
@@ -3,11 +3,15 @@
<head>
<title><%= camelized %></title>
<%- if options[:skip_javascript] -%>
- <%%= stylesheet_link_tag "application", media: "all" %>
- <%%= javascript_include_tag "application" %>
+ <%%= stylesheet_link_tag 'application', media: 'all' %>
<%- else -%>
- <%%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %>
- <%%= javascript_include_tag "application", "data-turbolinks-track" => true %>
+ <%- if gemfile_entries.any? { |m| m.name == 'turbolinks' } -%>
+ <%%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
+ <%%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
+ <%- else -%>
+ <%%= stylesheet_link_tag 'application', media: 'all' %>
+ <%%= javascript_include_tag 'application' %>
+ <%- end -%>
<%- end -%>
<%%= csrf_meta_tags %>
</head>
diff --git a/railties/lib/rails/generators/rails/app/templates/bin/setup b/railties/lib/rails/generators/rails/app/templates/bin/setup
new file mode 100644
index 0000000000..0e22b3fa5c
--- /dev/null
+++ b/railties/lib/rails/generators/rails/app/templates/bin/setup
@@ -0,0 +1,28 @@
+require 'pathname'
+
+# path to your application root.
+APP_ROOT = Pathname.new File.expand_path('../../', __FILE__)
+
+Dir.chdir APP_ROOT do
+ # This script is a starting point to setup your application.
+ # Add necessary setup steps to this file:
+
+ puts "== Installing dependencies =="
+ system "gem install bundler --conservative"
+ system "bundle check || bundle install"
+
+ # puts "\n== Copying sample files =="
+ # unless File.exist?("config/database.yml")
+ # system "cp config/database.yml.sample config/database.yml"
+ # end
+
+ puts "\n== Preparing database =="
+ system "bin/rake db:setup"
+
+ puts "\n== Removing old logs and tempfiles =="
+ system "rm -f log/*"
+ system "rm -rf tmp/cache"
+
+ puts "\n== Restarting application server =="
+ system "touch tmp/restart.txt"
+end
diff --git a/railties/lib/rails/generators/rails/app/templates/config/application.rb b/railties/lib/rails/generators/rails/app/templates/config/application.rb
index ac41a0cadb..16fe50bab8 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/application.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/application.rb
@@ -15,7 +15,7 @@ require "action_mailer/railtie"
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
-Bundler.require(:default, Rails.env)
+Bundler.require(*Rails.groups)
module <%= app_const_base %>
class Application < Rails::Application
@@ -30,10 +30,5 @@ module <%= app_const_base %>
# 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}').to_s]
# config.i18n.default_locale = :de
-<% if options.skip_sprockets? -%>
-
- # Disable the asset pipeline.
- config.assets.enabled = false
-<% end -%>
end
end
diff --git a/railties/lib/rails/generators/rails/app/templates/config/boot.rb b/railties/lib/rails/generators/rails/app/templates/config/boot.rb
index 3596736667..5e5f0c1fac 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/boot.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/boot.rb
@@ -1,4 +1,4 @@
# Set up gems listed in the Gemfile.
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
-require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
+require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/frontbase.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/frontbase.yml
index 4807986333..34fc0e3465 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/frontbase.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/frontbase.yml
@@ -6,26 +6,44 @@
# Configure Using Gemfile
# gem 'ruby-frontbase'
#
-development:
+default: &default
adapter: frontbase
host: localhost
- database: <%= app_name %>_development
username: <%= app_name %>
password: ''
+development:
+ <<: *default
+ database: <%= app_name %>_development
+
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
- adapter: frontbase
- host: localhost
+ <<: *default
database: <%= app_name %>_test
- username: <%= app_name %>
- password: ''
+# As with config/secrets.yml, you never want to store sensitive information,
+# like your database password, in your source code. If your source code is
+# ever seen by anyone, they now have access to your database.
+#
+# Instead, provide the password as a unix environment variable when you boot
+# the app. Read http://guides.rubyonrails.org/configuring.html#configuring-a-database
+# for a full rundown on how to provide these environment variables in a
+# production deployment.
+#
+# On Heroku and other platform providers, you may have a full connection URL
+# available as an environment variable. For example:
+#
+# DATABASE_URL="frontbase://myuser:mypass@localhost/somedatabase"
+#
+# You can use this database configuration with:
+#
+# production:
+# url: <%%= ENV['DATABASE_URL'] %>
+#
production:
- adapter: frontbase
- host: localhost
+ <<: *default
database: <%= app_name %>_production
username: <%= app_name %>
- password: ''
+ password: <%%= ENV['<%= app_name.upcase %>_DATABASE_PASSWORD'] %>
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml
index 3d689a110a..187ff01bac 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml
@@ -1,7 +1,7 @@
# IBM Dataservers
#
# Home Page
-# http://rubyforge.org/projects/rubyibm/
+# https://github.com/dparnell/ibm_db
#
# To install the ibm_db gem:
#
@@ -31,14 +31,11 @@
# Configure Using Gemfile
# gem 'ibm_db'
#
-# For more details on the installation and the connection parameters below,
-# please refer to the latest documents at http://rubyforge.org/docman/?group_id=2361
-
-development:
+#
+default: &default
adapter: ibm_db
username: db2inst1
password:
- database: <%= app_name[0,4] %>_dev
#schema: db2inst1
#host: localhost
#port: 50000
@@ -51,36 +48,38 @@ development:
#authentication: SERVER
#parameterized: false
+development:
+ <<: *default
+ database: <%= app_name[0,4] %>_dev
+
+# Warning: The database defined as "test" will be erased and
+# re-generated from your development database when you run "rake".
+# Do not set this db to the same as development or production.
test:
- adapter: ibm_db
- username: db2inst1
- password:
+ <<: *default
database: <%= app_name[0,4] %>_tst
- #schema: db2inst1
- #host: localhost
- #port: 50000
- #account: my_account
- #app_user: my_app_user
- #application: my_application
- #workstation: my_workstation
- #security: SSL
- #timeout: 10
- #authentication: SERVER
- #parameterized: false
+# As with config/secrets.yml, you never want to store sensitive information,
+# like your database password, in your source code. If your source code is
+# ever seen by anyone, they now have access to your database.
+#
+# Instead, provide the password as a unix environment variable when you boot
+# the app. Read http://guides.rubyonrails.org/configuring.html#configuring-a-database
+# for a full rundown on how to provide these environment variables in a
+# production deployment.
+#
+# On Heroku and other platform providers, you may have a full connection URL
+# available as an environment variable. For example:
+#
+# DATABASE_URL="ibm-db://myuser:mypass@localhost/somedatabase"
+#
+# You can use this database configuration with:
+#
+# production:
+# url: <%%= ENV['DATABASE_URL'] %>
+#
production:
- adapter: ibm_db
- username: db2inst1
- password:
- database: <%= app_name[0,8] %>
- #schema: db2inst1
- #host: localhost
- #port: 50000
- #account: my_account
- #app_user: my_app_user
- #application: my_application
- #workstation: my_workstation
- #security: SSL
- #timeout: 10
- #authentication: SERVER
- #parameterized: false \ No newline at end of file
+ <<: *default
+ database: <%= app_name %>_production
+ username: <%= app_name %>
+ password: <%%= ENV['<%= app_name.upcase %>_DATABASE_PASSWORD'] %>
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml
index 1d2bf08b91..db0a429753 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml
@@ -5,58 +5,64 @@
# Configure using Gemfile:
# gem 'activerecord-jdbcmssql-adapter'
#
-#development:
-# adapter: mssql
-# username: <%= app_name %>
-# password:
-# host: localhost
-# database: <%= app_name %>_development
+# development:
+# adapter: mssql
+# username: <%= app_name %>
+# password:
+# host: localhost
+# database: <%= app_name %>_development
#
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
#
-#test:
-# adapter: mssql
-# username: <%= app_name %>
-# password:
-# host: localhost
-# database: <%= app_name %>_test
+# test:
+# adapter: mssql
+# username: <%= app_name %>
+# password:
+# host: localhost
+# database: <%= app_name %>_test
#
-#production:
-# adapter: mssql
-# username: <%= app_name %>
-# password:
-# host: localhost
-# database: <%= app_name %>_production
+# production:
+# adapter: mssql
+# username: <%= app_name %>
+# password:
+# host: localhost
+# database: <%= app_name %>_production
# If you are using oracle, db2, sybase, informix or prefer to use the plain
# JDBC adapter, configure your database setting as the example below (requires
# you to download and manually install the database vendor's JDBC driver .jar
-# file). See your driver documentation for the apropriate driver class and
+# file). See your driver documentation for the appropriate driver class and
# connection string:
-development:
+default: &default
adapter: jdbc
username: <%= app_name %>
password:
driver:
+
+development:
+ <<: *default
url: jdbc:db://localhost/<%= app_name %>_development
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
-
test:
- adapter: jdbc
- username: <%= app_name %>
- password:
- driver:
+ <<: *default
url: jdbc:db://localhost/<%= app_name %>_test
+# As with config/secrets.yml, you never want to store sensitive information,
+# like your database password, in your source code. If your source code is
+# ever seen by anyone, they now have access to your database.
+#
+# Instead, provide the password as a unix environment variable when you boot
+# the app. Read http://guides.rubyonrails.org/configuring.html#configuring-a-database
+# for a full rundown on how to provide these environment variables in a
+# production deployment.
+#
production:
- adapter: jdbc
- username: <%= app_name %>
- password:
- driver:
url: jdbc:db://localhost/<%= app_name %>_production
+ username: <%= app_name %>
+ password: <%%= ENV['<%= app_name.upcase %>_DATABASE_PASSWORD'] %>
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml
index 5a594ac1f3..acb93939e1 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml
@@ -8,26 +8,45 @@
#
# And be sure to use new-style password hashing:
# http://dev.mysql.com/doc/refman/5.0/en/old-client.html
-development:
+#
+default: &default
adapter: mysql
- database: <%= app_name %>_development
username: root
password:
host: localhost
+development:
+ <<: *default
+ database: <%= app_name %>_development
+
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
- adapter: mysql
+ <<: *default
database: <%= app_name %>_test
- username: root
- password:
- host: localhost
+# As with config/secrets.yml, you never want to store sensitive information,
+# like your database password, in your source code. If your source code is
+# ever seen by anyone, they now have access to your database.
+#
+# Instead, provide the password as a unix environment variable when you boot
+# the app. Read http://guides.rubyonrails.org/configuring.html#configuring-a-database
+# for a full rundown on how to provide these environment variables in a
+# production deployment.
+#
+# On Heroku and other platform providers, you may have a full connection URL
+# available as an environment variable. For example:
+#
+# DATABASE_URL="mysql://myuser:mypass@localhost/somedatabase"
+#
+# You can use this database configuration with:
+#
+# production:
+# url: <%%= ENV['DATABASE_URL'] %>
+#
production:
- adapter: mysql
+ <<: *default
database: <%= app_name %>_production
- username: root
- password:
- host: localhost
+ username: <%= app_name %>
+ password: <%%= ENV['<%= app_name.upcase %>_DATABASE_PASSWORD'] %>
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml
index e1a00d076f..9e99264d33 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml
@@ -2,13 +2,23 @@
#
# Configure Using Gemfile
# gem 'activerecord-jdbcpostgresql-adapter'
-
-development:
+#
+default: &default
adapter: postgresql
encoding: unicode
+
+development:
+ <<: *default
database: <%= app_name %>_development
- username: <%= app_name %>
- password:
+
+ # The specified database role being used to connect to postgres.
+ # To create additional roles in postgres see `$ createuser --help`.
+ # When left blank, postgres will use the default role. This is
+ # the same name as the operating system user that initialized the database.
+ #username: <%= app_name %>
+
+ # The password associated with the postgres role (username).
+ #password:
# Connect on a TCP socket. Omitted by default since the client uses a
# domain socket that doesn't need configuration. Windows does not have
@@ -29,15 +39,30 @@ development:
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
- adapter: postgresql
- encoding: unicode
+ <<: *default
database: <%= app_name %>_test
- username: <%= app_name %>
- password:
+# As with config/secrets.yml, you never want to store sensitive information,
+# like your database password, in your source code. If your source code is
+# ever seen by anyone, they now have access to your database.
+#
+# Instead, provide the password as a unix environment variable when you boot
+# the app. Read http://guides.rubyonrails.org/configuring.html#configuring-a-database
+# for a full rundown on how to provide these environment variables in a
+# production deployment.
+#
+# On Heroku and other platform providers, you may have a full connection URL
+# available as an environment variable. For example:
+#
+# DATABASE_URL="postgres://myuser:mypass@localhost/somedatabase"
+#
+# You can use this database configuration with:
+#
+# production:
+# url: <%%= ENV['DATABASE_URL'] %>
+#
production:
- adapter: postgresql
- encoding: unicode
+ <<: *default
database: <%= app_name %>_production
username: <%= app_name %>
- password:
+ password: <%%= ENV['<%= app_name.upcase %>_DATABASE_PASSWORD'] %>
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml
index 175f3eb3db..28c36eb82f 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml
@@ -4,17 +4,20 @@
# Configure Using Gemfile
# gem 'activerecord-jdbcsqlite3-adapter'
#
-development:
+default: &default
adapter: sqlite3
+
+development:
+ <<: *default
database: db/development.sqlite3
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
- adapter: sqlite3
+ <<: *default
database: db/test.sqlite3
production:
- adapter: sqlite3
+ <<: *default
database: db/production.sqlite3
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml
index c3349912aa..4b2e6646c7 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml
@@ -1,4 +1,4 @@
-# MySQL. Versions 4.1 and 5.0 are recommended.
+# MySQL. Versions 5.0+ are recommended.
#
# Install the MYSQL driver
# gem install mysql2
@@ -8,10 +8,10 @@
#
# And be sure to use new-style password hashing:
# http://dev.mysql.com/doc/refman/5.0/en/old-client.html
-development:
+#
+default: &default
adapter: mysql2
encoding: utf8
- database: <%= app_name %>_development
pool: 5
username: root
password:
@@ -21,31 +21,38 @@ development:
host: localhost
<% end -%>
+development:
+ <<: *default
+ database: <%= app_name %>_development
+
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
- adapter: mysql2
- encoding: utf8
+ <<: *default
database: <%= app_name %>_test
- pool: 5
- username: root
- password:
-<% if mysql_socket -%>
- socket: <%= mysql_socket %>
-<% else -%>
- host: localhost
-<% end -%>
+# As with config/secrets.yml, you never want to store sensitive information,
+# like your database password, in your source code. If your source code is
+# ever seen by anyone, they now have access to your database.
+#
+# Instead, provide the password as a unix environment variable when you boot
+# the app. Read http://guides.rubyonrails.org/configuring.html#configuring-a-database
+# for a full rundown on how to provide these environment variables in a
+# production deployment.
+#
+# On Heroku and other platform providers, you may have a full connection URL
+# available as an environment variable. For example:
+#
+# DATABASE_URL="mysql2://myuser:mypass@localhost/somedatabase"
+#
+# You can use this database configuration with:
+#
+# production:
+# url: <%%= ENV['DATABASE_URL'] %>
+#
production:
- adapter: mysql2
- encoding: utf8
+ <<: *default
database: <%= app_name %>_production
- pool: 5
- username: root
- password:
-<% if mysql_socket -%>
- socket: <%= mysql_socket %>
-<% else -%>
- host: localhost
-<% end -%>
+ username: <%= app_name %>
+ password: <%%= ENV['<%= app_name.upcase %>_DATABASE_PASSWORD'] %>
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/oracle.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/oracle.yml
index b661a60389..9aedcc15cb 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/oracle.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/oracle.yml
@@ -1,7 +1,7 @@
# Oracle/OCI 8i, 9, 10g
#
# Requires Ruby/OCI8:
-# http://rubyforge.org/projects/ruby-oci8/
+# https://github.com/kubo/ruby-oci8
#
# Specify your database using any valid connection syntax, such as a
# tnsnames.ora service name, or an SQL connect string of the form:
@@ -16,24 +16,43 @@
# prefetch_rows: 100
# cursor_sharing: similar
#
-
-development:
+default: &default
adapter: oracle
- database: <%= app_name %>_development
username: <%= app_name %>
password:
+development:
+ <<: *default
+ database: <%= app_name %>_development
+
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
- adapter: oracle
+ <<: *default
database: <%= app_name %>_test
- username: <%= app_name %>
- password:
+# As with config/secrets.yml, you never want to store sensitive information,
+# like your database password, in your source code. If your source code is
+# ever seen by anyone, they now have access to your database.
+#
+# Instead, provide the password as a unix environment variable when you boot
+# the app. Read http://guides.rubyonrails.org/configuring.html#configuring-a-database
+# for a full rundown on how to provide these environment variables in a
+# production deployment.
+#
+# On Heroku and other platform providers, you may have a full connection URL
+# available as an environment variable. For example:
+#
+# DATABASE_URL="oracle://myuser:mypass@localhost/somedatabase"
+#
+# You can use this database configuration with:
+#
+# production:
+# url: <%%= ENV['DATABASE_URL'] %>
+#
production:
- adapter: oracle
+ <<: *default
database: <%= app_name %>_production
username: <%= app_name %>
- password:
+ password: <%%= ENV['<%= app_name.upcase %>_DATABASE_PASSWORD'] %>
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml
index 0194dce6f3..feb25bbc6b 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml
@@ -14,13 +14,25 @@
# Configure Using Gemfile
# gem 'pg'
#
-development:
+default: &default
adapter: postgresql
encoding: unicode
- database: <%= app_name %>_development
+ # For details on connection pooling, see rails configuration guide
+ # http://guides.rubyonrails.org/configuring.html#database-pooling
pool: 5
- username: <%= app_name %>
- password:
+
+development:
+ <<: *default
+ database: <%= app_name %>_development
+
+ # The specified database role being used to connect to postgres.
+ # To create additional roles in postgres see `$ createuser --help`.
+ # When left blank, postgres will use the default role. This is
+ # the same name as the operating system user that initialized the database.
+ #username: <%= app_name %>
+
+ # The password associated with the postgres role (username).
+ #password:
# Connect on a TCP socket. Omitted by default since the client uses a
# domain socket that doesn't need configuration. Windows does not have
@@ -44,19 +56,30 @@ development:
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
- adapter: postgresql
- encoding: unicode
+ <<: *default
database: <%= app_name %>_test
- pool: 5
- username: <%= app_name %>
- password:
+# As with config/secrets.yml, you never want to store sensitive information,
+# like your database password, in your source code. If your source code is
+# ever seen by anyone, they now have access to your database.
+#
+# Instead, provide the password as a unix environment variable when you boot
+# the app. Read http://guides.rubyonrails.org/configuring.html#configuring-a-database
+# for a full rundown on how to provide these environment variables in a
+# production deployment.
+#
+# On Heroku and other platform providers, you may have a full connection URL
+# available as an environment variable. For example:
+#
+# DATABASE_URL="postgres://myuser:mypass@localhost/somedatabase"
+#
+# You can use this database configuration with:
+#
+# production:
+# url: <%%= ENV['DATABASE_URL'] %>
+#
production:
- adapter: postgresql
- encoding: unicode
+ <<: *default
database: <%= app_name %>_production
- # For details on connection pooling, see rails configration guide
- # http://guides.rubyonrails.org/configuring.html#database-pooling
- pool: 5
username: <%= app_name %>
- password:
+ password: <%%= ENV['<%= app_name.upcase %>_DATABASE_PASSWORD'] %>
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml
index 51a4dd459d..1c1a37ca8d 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml
@@ -3,23 +3,23 @@
#
# Ensure the SQLite 3 gem is defined in your Gemfile
# gem 'sqlite3'
-development:
+#
+default: &default
adapter: sqlite3
- database: db/development.sqlite3
pool: 5
timeout: 5000
+development:
+ <<: *default
+ database: db/development.sqlite3
+
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
- adapter: sqlite3
+ <<: *default
database: db/test.sqlite3
- pool: 5
- timeout: 5000
production:
- adapter: sqlite3
+ <<: *default
database: db/production.sqlite3
- pool: 5
- timeout: 5000
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/sqlserver.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/sqlserver.yml
index 7ef89d6608..30b0df34a8 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/sqlserver.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/sqlserver.yml
@@ -21,37 +21,48 @@
# If you can connect with "tsql -S servername", your basic FreeTDS installation is working.
# 'man tsql' for more info
# Set timeout to a larger number if valid queries against a live db fail
-
-development:
+#
+default: &default
adapter: sqlserver
encoding: utf8
reconnect: false
- database: <%= app_name %>_development
username: <%= app_name %>
password:
timeout: 25
dataserver: from_freetds.conf
+development:
+ <<: *default
+ database: <%= app_name %>_development
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
- adapter: sqlserver
- encoding: utf8
- reconnect: false
+ <<: *default
database: <%= app_name %>_test
- username: <%= app_name %>
- password:
- timeout: 25
- dataserver: from_freetds.conf
+# As with config/secrets.yml, you never want to store sensitive information,
+# like your database password, in your source code. If your source code is
+# ever seen by anyone, they now have access to your database.
+#
+# Instead, provide the password as a unix environment variable when you boot
+# the app. Read http://guides.rubyonrails.org/configuring.html#configuring-a-database
+# for a full rundown on how to provide these environment variables in a
+# production deployment.
+#
+# On Heroku and other platform providers, you may have a full connection URL
+# available as an environment variable. For example:
+#
+# DATABASE_URL="sqlserver://myuser:mypass@localhost/somedatabase"
+#
+# You can use this database configuration with:
+#
+# production:
+# url: <%%= ENV['DATABASE_URL'] %>
+#
production:
- adapter: sqlserver
- encoding: utf8
- reconnect: false
+ <<: *default
database: <%= app_name %>_production
username: <%= app_name %>
- password:
- timeout: 25
- dataserver: from_freetds.conf
+ password: <%%= ENV['<%= app_name.upcase %>_DATABASE_PASSWORD'] %>
diff --git a/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt
index cff570a631..bbb409616d 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt
+++ b/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt
@@ -22,12 +22,23 @@ Rails.application.configure do
<%- unless options.skip_active_record? -%>
# Raise an error on page load if there are pending migrations.
config.active_record.migration_error = :page_load
- <%- end -%>
+ <%- end -%>
<%- unless options.skip_sprockets? -%>
# Debug mode disables concatenation and preprocessing of assets.
# This option may cause significant delays in view rendering with a large
# number of complex assets.
config.assets.debug = true
+
+ # Generate digests for assets URLs.
+ config.assets.digest = true
+
+ # Adds additional error checking when serving assets at runtime.
+ # Checks for improperly declared sprockets dependencies.
+ # Raises helpful error messages.
+ config.assets.raise_runtime_errors = true
<%- end -%>
+
+ # Raises error for missing translations
+ # config.action_view.raise_on_missing_translations = true
end
diff --git a/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt
index 1dfc9f136b..a2aa7c09db 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt
+++ b/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt
@@ -5,7 +5,7 @@ Rails.application.configure do
config.cache_classes = true
# Eager load code on boot. This eager loads most of Rails and
- # your application in memory, allowing both thread web servers
+ # your application in memory, allowing both threaded web servers
# and those relying on copy on write to perform better.
# Rake tasks automatically ignore this option for performance.
config.eager_load = true
@@ -16,10 +16,10 @@ Rails.application.configure do
# Enable Rack::Cache to put a simple HTTP cache in front of your application
# Add `rack-cache` to your Gemfile before enabling this.
- # For large-scale production use, consider using a caching reverse proxy like nginx, varnish or squid.
+ # For large-scale production use, consider using a caching reverse proxy like NGINX, varnish or squid.
# config.action_dispatch.rack_cache = true
- # Disable Rails's static asset server (Apache or nginx will already do this).
+ # Disable Rails's static asset server (Apache or NGINX will already do this).
config.serve_static_assets = false
<%- unless options.skip_sprockets? -%>
@@ -33,13 +33,12 @@ Rails.application.configure do
# Generate digests for assets URLs.
config.assets.digest = true
- # Version of your assets, change this if you want to expire all your assets.
- config.assets.version = '1.0'
+ # `config.assets.precompile` has moved to config/initializers/assets.rb
<%- end -%>
# Specifies the header that your server uses for sending files.
- # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache
- # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx
+ # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for Apache
+ # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
# config.force_ssl = true
@@ -59,18 +58,12 @@ Rails.application.configure do
# Enable serving of images, stylesheets, and JavaScripts from an asset server.
# config.action_controller.asset_host = "http://assets.example.com"
- <%- unless options.skip_sprockets? -%>
- # Precompile additional assets.
- # application.js, application.css, and all non-JS/CSS in app/assets folder are already added.
- # config.assets.precompile += %w( search.js )
- <%- end -%>
-
# Ignore bad email addresses and do not raise email delivery errors.
# Set this to true and configure the email server for immediate delivery to raise delivery errors.
# config.action_mailer.raise_delivery_errors = false
# Enable locale fallbacks for I18n (makes lookups for any locale fall back to
- # the I18n.default_locale when a translation can not be found).
+ # the I18n.default_locale when a translation cannot be found).
config.i18n.fallbacks = true
# Send deprecation notices to registered listeners.
@@ -81,4 +74,9 @@ Rails.application.configure do
# Use default logging formatter so that PID and timestamp are not suppressed.
config.log_formatter = ::Logger::Formatter.new
+ <%- unless options.skip_active_record? -%>
+
+ # Do not dump schema after migrations.
+ config.active_record.dump_schema_after_migration = false
+ <%- end -%>
end
diff --git a/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt
index ba0742f97f..053f5b66d7 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt
+++ b/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt
@@ -14,7 +14,7 @@ Rails.application.configure do
# Configure static asset server for tests with Cache-Control for performance.
config.serve_static_assets = true
- config.static_cache_control = "public, max-age=3600"
+ config.static_cache_control = 'public, max-age=3600'
# Show full error reports and disable caching.
config.consider_all_requests_local = true
@@ -33,4 +33,7 @@ Rails.application.configure do
# Print deprecation notices to the stderr.
config.active_support.deprecation = :stderr
+
+ # Raises error for missing translations
+ # config.action_view.raise_on_missing_translations = true
end
diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/assets.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/initializers/assets.rb.tt
new file mode 100644
index 0000000000..d2f4ec33a6
--- /dev/null
+++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/assets.rb.tt
@@ -0,0 +1,8 @@
+# Be sure to restart your server when you modify this file.
+
+# Version of your assets, change this if you want to expire all your assets.
+Rails.application.config.assets.version = '1.0'
+
+# Precompile additional assets.
+# application.js, application.css, and all non-JS/CSS in app/assets folder are already added.
+# Rails.application.config.assets.precompile += %w( search.js )
diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/cookies_serializer.rb b/railties/lib/rails/generators/rails/app/templates/config/initializers/cookies_serializer.rb
new file mode 100644
index 0000000000..7f70458dee
--- /dev/null
+++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/cookies_serializer.rb
@@ -0,0 +1,3 @@
+# Be sure to restart your server when you modify this file.
+
+Rails.application.config.action_dispatch.cookies_serializer = :json
diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/mime_types.rb b/railties/lib/rails/generators/rails/app/templates/config/initializers/mime_types.rb
index 72aca7e441..dc1899682b 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/initializers/mime_types.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/mime_types.rb
@@ -2,4 +2,3 @@
# Add new mime types for use in respond_to blocks:
# Mime::Type.register "text/richtext", :rtf
-# Mime::Type.register_alias "text/html", :iphone
diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/secret_token.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/secrets.yml
index f3cc6098a3..b2669a0f79 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/initializers/secret_token.rb.tt
+++ b/railties/lib/rails/generators/rails/app/templates/config/secrets.yml
@@ -7,6 +7,16 @@
# no regular words or you'll be exposed to dictionary attacks.
# You can use `rake secret` to generate a secure secret key.
-# Make sure your secret_key_base is kept private
+# Make sure the secrets in this file are kept private
# if you're sharing your code publicly.
-Rails.application.config.secret_key_base = '<%= app_secret %>'
+
+development:
+ secret_key_base: <%= app_secret %>
+
+test:
+ secret_key_base: <%= app_secret %>
+
+# Do not keep production secrets in the repository,
+# instead read values from the environment.
+production:
+ secret_key_base: <%%= ENV["SECRET_KEY_BASE"] %>
diff --git a/railties/lib/rails/generators/rails/app/templates/gitignore b/railties/lib/rails/generators/rails/app/templates/gitignore
index 6a502e997f..8775e5e235 100644
--- a/railties/lib/rails/generators/rails/app/templates/gitignore
+++ b/railties/lib/rails/generators/rails/app/templates/gitignore
@@ -7,10 +7,12 @@
# Ignore bundler config.
/.bundle
+<% if sqlite3? -%>
# Ignore the default SQLite database.
/db/*.sqlite3
/db/*.sqlite3-journal
+<% end -%>
# Ignore all logfiles and tempfiles.
/log/*.log
/tmp
diff --git a/railties/lib/rails/generators/rails/app/templates/public/404.html b/railties/lib/rails/generators/rails/app/templates/public/404.html
index a0daa0c156..b612547fc2 100644
--- a/railties/lib/rails/generators/rails/app/templates/public/404.html
+++ b/railties/lib/rails/generators/rails/app/templates/public/404.html
@@ -2,17 +2,23 @@
<html>
<head>
<title>The page you were looking for doesn't exist (404)</title>
+ <meta name="viewport" content="width=device-width,initial-scale=1">
<style>
body {
background-color: #EFEFEF;
color: #2E2F30;
text-align: center;
font-family: arial, sans-serif;
+ margin: 0;
}
div.dialog {
- width: 25em;
- margin: 4em auto 0 auto;
+ width: 95%;
+ max-width: 33em;
+ margin: 4em auto 0;
+ }
+
+ div.dialog > div {
border: 1px solid #CCC;
border-right-color: #999;
border-left-color: #999;
@@ -21,7 +27,8 @@
border-top-left-radius: 9px;
border-top-right-radius: 9px;
background-color: white;
- padding: 7px 4em 0 4em;
+ padding: 7px 12% 0;
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
}
h1 {
@@ -30,19 +37,19 @@
line-height: 1.5em;
}
- body > p {
- width: 33em;
- margin: 0 auto 1em;
- padding: 1em 0;
+ div.dialog > p {
+ margin: 0 0 1em;
+ padding: 1em;
background-color: #F7F7F7;
border: 1px solid #CCC;
border-right-color: #999;
+ border-left-color: #999;
border-bottom-color: #999;
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
border-top-color: #DADADA;
color: #666;
- box-shadow:0 3px 8px rgba(50, 50, 50, 0.17);
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
}
</style>
</head>
@@ -50,9 +57,11 @@
<body>
<!-- This file lives in public/404.html -->
<div class="dialog">
- <h1>The page you were looking for doesn't exist.</h1>
- <p>You may have mistyped the address or the page may have moved.</p>
+ <div>
+ <h1>The page you were looking for doesn't exist.</h1>
+ <p>You may have mistyped the address or the page may have moved.</p>
+ </div>
+ <p>If you are the application owner check the logs for more information.</p>
</div>
- <p>If you are the application owner check the logs for more information.</p>
</body>
</html>
diff --git a/railties/lib/rails/generators/rails/app/templates/public/422.html b/railties/lib/rails/generators/rails/app/templates/public/422.html
index fbb4b84d72..a21f82b3bd 100644
--- a/railties/lib/rails/generators/rails/app/templates/public/422.html
+++ b/railties/lib/rails/generators/rails/app/templates/public/422.html
@@ -2,17 +2,23 @@
<html>
<head>
<title>The change you wanted was rejected (422)</title>
+ <meta name="viewport" content="width=device-width,initial-scale=1">
<style>
body {
background-color: #EFEFEF;
color: #2E2F30;
text-align: center;
font-family: arial, sans-serif;
+ margin: 0;
}
div.dialog {
- width: 25em;
- margin: 4em auto 0 auto;
+ width: 95%;
+ max-width: 33em;
+ margin: 4em auto 0;
+ }
+
+ div.dialog > div {
border: 1px solid #CCC;
border-right-color: #999;
border-left-color: #999;
@@ -21,7 +27,8 @@
border-top-left-radius: 9px;
border-top-right-radius: 9px;
background-color: white;
- padding: 7px 4em 0 4em;
+ padding: 7px 12% 0;
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
}
h1 {
@@ -30,19 +37,19 @@
line-height: 1.5em;
}
- body > p {
- width: 33em;
- margin: 0 auto 1em;
- padding: 1em 0;
+ div.dialog > p {
+ margin: 0 0 1em;
+ padding: 1em;
background-color: #F7F7F7;
border: 1px solid #CCC;
border-right-color: #999;
+ border-left-color: #999;
border-bottom-color: #999;
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
border-top-color: #DADADA;
color: #666;
- box-shadow:0 3px 8px rgba(50, 50, 50, 0.17);
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
}
</style>
</head>
@@ -50,9 +57,11 @@
<body>
<!-- This file lives in public/422.html -->
<div class="dialog">
- <h1>The change you wanted was rejected.</h1>
- <p>Maybe you tried to change something you didn't have access to.</p>
+ <div>
+ <h1>The change you wanted was rejected.</h1>
+ <p>Maybe you tried to change something you didn't have access to.</p>
+ </div>
+ <p>If you are the application owner check the logs for more information.</p>
</div>
- <p>If you are the application owner check the logs for more information.</p>
</body>
</html>
diff --git a/railties/lib/rails/generators/rails/app/templates/public/500.html b/railties/lib/rails/generators/rails/app/templates/public/500.html
index e9052d35bf..061abc587d 100644
--- a/railties/lib/rails/generators/rails/app/templates/public/500.html
+++ b/railties/lib/rails/generators/rails/app/templates/public/500.html
@@ -2,17 +2,23 @@
<html>
<head>
<title>We're sorry, but something went wrong (500)</title>
+ <meta name="viewport" content="width=device-width,initial-scale=1">
<style>
body {
background-color: #EFEFEF;
color: #2E2F30;
text-align: center;
font-family: arial, sans-serif;
+ margin: 0;
}
div.dialog {
- width: 25em;
- margin: 4em auto 0 auto;
+ width: 95%;
+ max-width: 33em;
+ margin: 4em auto 0;
+ }
+
+ div.dialog > div {
border: 1px solid #CCC;
border-right-color: #999;
border-left-color: #999;
@@ -21,7 +27,8 @@
border-top-left-radius: 9px;
border-top-right-radius: 9px;
background-color: white;
- padding: 7px 4em 0 4em;
+ padding: 7px 12% 0;
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
}
h1 {
@@ -30,19 +37,19 @@
line-height: 1.5em;
}
- body > p {
- width: 33em;
- margin: 0 auto 1em;
- padding: 1em 0;
+ div.dialog > p {
+ margin: 0 0 1em;
+ padding: 1em;
background-color: #F7F7F7;
border: 1px solid #CCC;
border-right-color: #999;
+ border-left-color: #999;
border-bottom-color: #999;
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
border-top-color: #DADADA;
color: #666;
- box-shadow:0 3px 8px rgba(50, 50, 50, 0.17);
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
}
</style>
</head>
@@ -50,8 +57,10 @@
<body>
<!-- This file lives in public/500.html -->
<div class="dialog">
- <h1>We're sorry, but something went wrong.</h1>
+ <div>
+ <h1>We're sorry, but something went wrong.</h1>
+ </div>
+ <p>If you are the application owner check the logs for more information.</p>
</div>
- <p>If you are the application owner check the logs for more information.</p>
</body>
</html>
diff --git a/railties/lib/rails/generators/rails/app/templates/public/robots.txt b/railties/lib/rails/generators/rails/app/templates/public/robots.txt
index 1a3a5e4dd2..3c9c7c01f3 100644
--- a/railties/lib/rails/generators/rails/app/templates/public/robots.txt
+++ b/railties/lib/rails/generators/rails/app/templates/public/robots.txt
@@ -1,4 +1,4 @@
-# See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file
+# See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file
#
# To ban all spiders from the entire site uncomment the next two lines:
# User-agent: *
diff --git a/railties/lib/rails/generators/rails/app/templates/test/test_helper.rb b/railties/lib/rails/generators/rails/app/templates/test/test_helper.rb
index 4fd060341e..87b8fe3516 100644
--- a/railties/lib/rails/generators/rails/app/templates/test/test_helper.rb
+++ b/railties/lib/rails/generators/rails/app/templates/test/test_helper.rb
@@ -1,15 +1,10 @@
-ENV["RAILS_ENV"] ||= "test"
+ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
require 'rails/test_help'
class ActiveSupport::TestCase
<% unless options[:skip_active_record] -%>
- ActiveRecord::Migration.check_pending!
-
# Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
- #
- # Note: You'll currently still have to declare fixtures explicitly in integration tests
- # -- they do not yet inherit this setting
fixtures :all
<% end -%>
diff --git a/railties/lib/rails/generators/rails/controller/controller_generator.rb b/railties/lib/rails/generators/rails/controller/controller_generator.rb
index ef84447df9..fbecab1823 100644
--- a/railties/lib/rails/generators/rails/controller/controller_generator.rb
+++ b/railties/lib/rails/generators/rails/controller/controller_generator.rb
@@ -2,6 +2,8 @@ module Rails
module Generators
class ControllerGenerator < NamedBase # :nodoc:
argument :actions, type: :array, default: [], banner: "action action"
+ class_option :skip_routes, type: :boolean, desc: "Dont' add routes to config/routes.rb."
+
check_class_collision suffix: "Controller"
def create_controller_files
@@ -9,8 +11,10 @@ module Rails
end
def add_routes
- actions.reverse.each do |action|
- route generate_routing_code(action)
+ unless options[:skip_routes]
+ actions.reverse.each do |action|
+ route generate_routing_code(action)
+ end
end
end
@@ -23,21 +27,21 @@ module Rails
# Will generate -
# namespace :foo do
# namespace :bar do
- # get "baz/index"
+ # get 'baz/index'
# end
# end
def generate_routing_code(action)
- depth = class_path.length
+ depth = regular_class_path.length
# Create 'namespace' ladder
# namespace :foo do
# namespace :bar do
- namespace_ladder = class_path.each_with_index.map do |ns, i|
+ namespace_ladder = regular_class_path.each_with_index.map do |ns, i|
indent("namespace :#{ns} do\n", i * 2)
end.join
# Create route
- # get "baz/index"
- route = indent(%{get "#{file_name}/#{action}"\n}, depth * 2)
+ # get 'baz/index'
+ route = indent(%{get '#{file_name}/#{action}'\n}, depth * 2)
# Create `end` ladder
# end
diff --git a/railties/lib/rails/generators/rails/model/USAGE b/railties/lib/rails/generators/rails/model/USAGE
index 145d9ee6e0..833b7beb7f 100644
--- a/railties/lib/rails/generators/rails/model/USAGE
+++ b/railties/lib/rails/generators/rails/model/USAGE
@@ -60,7 +60,7 @@ Available field types:
For decimal, two integers separated by a comma in curly braces will be used
for precision and scale:
- `rails generate model product price:decimal{10,2}`
+ `rails generate model product 'price:decimal{10,2}'`
You can add a `:uniq` or `:index` suffix for unique or standard indexes
respectively:
diff --git a/railties/lib/rails/generators/rails/model/model_generator.rb b/railties/lib/rails/generators/rails/model/model_generator.rb
index ea3d69d7c9..87bab129bb 100644
--- a/railties/lib/rails/generators/rails/model/model_generator.rb
+++ b/railties/lib/rails/generators/rails/model/model_generator.rb
@@ -1,6 +1,10 @@
+require 'rails/generators/model_helpers'
+
module Rails
module Generators
class ModelGenerator < NamedBase # :nodoc:
+ include Rails::Generators::ModelHelpers
+
argument :attributes, type: :array, default: [], banner: "field[:type][:index] field[:type][:index]"
hook_for :orm, required: true
end
diff --git a/railties/lib/rails/generators/rails/plugin/plugin_generator.rb b/railties/lib/rails/generators/rails/plugin/plugin_generator.rb
index 97ff6d1b8b..584f776c01 100644
--- a/railties/lib/rails/generators/rails/plugin/plugin_generator.rb
+++ b/railties/lib/rails/generators/rails/plugin/plugin_generator.rb
@@ -184,6 +184,7 @@ task default: :test
end
end
+ public_task :set_default_accessors!
public_task :create_root
def create_root_files
@@ -287,6 +288,10 @@ task default: :test
options[:mountable]
end
+ def skip_git?
+ options[:skip_git]
+ end
+
def with_dummy_app?
options[:skip_test_unit].blank? || options[:dummy_path] != 'test/dummy'
end
@@ -303,6 +308,24 @@ task default: :test
@camelized ||= name.gsub(/\W/, '_').squeeze('_').camelize
end
+ def author
+ default = "TODO: Write your name"
+ if skip_git?
+ @author = default
+ else
+ @author = `git config user.name`.chomp rescue default
+ end
+ end
+
+ def email
+ default = "TODO: Write your email address"
+ if skip_git?
+ @email = default
+ else
+ @email = `git config user.email`.chomp rescue default
+ end
+ end
+
def valid_const?
if original_name =~ /[^0-9a-zA-Z_]+/
raise Error, "Invalid plugin name #{original_name}. Please give a name which use only alphabetic or numeric or \"_\" characters."
@@ -319,7 +342,7 @@ task default: :test
@application_definition ||= begin
dummy_application_path = File.expand_path("#{dummy_path}/config/application.rb", destination_root)
- unless options[:pretend] || !File.exists?(dummy_application_path)
+ unless options[:pretend] || !File.exist?(dummy_application_path)
contents = File.read(dummy_application_path)
contents[(contents.index(/module ([\w]+)\n(.*)class Application/m))..-1]
end
diff --git a/railties/lib/rails/generators/rails/plugin/templates/%name%.gemspec b/railties/lib/rails/generators/rails/plugin/templates/%name%.gemspec
index 5fdf0e1554..919c349470 100644
--- a/railties/lib/rails/generators/rails/plugin/templates/%name%.gemspec
+++ b/railties/lib/rails/generators/rails/plugin/templates/%name%.gemspec
@@ -7,8 +7,8 @@ require "<%= name %>/version"
Gem::Specification.new do |s|
s.name = "<%= name %>"
s.version = <%= camelized %>::VERSION
- s.authors = ["TODO: Your name"]
- s.email = ["TODO: Your email"]
+ s.authors = ["<%= author %>"]
+ s.email = ["<%= email %>"]
s.homepage = "TODO"
s.summary = "TODO: Summary of <%= camelized %>."
s.description = "TODO: Description of <%= camelized %>."
diff --git a/railties/lib/rails/generators/rails/plugin/templates/Gemfile b/railties/lib/rails/generators/rails/plugin/templates/Gemfile
index 3f2b78f2fd..796587f316 100644
--- a/railties/lib/rails/generators/rails/plugin/templates/Gemfile
+++ b/railties/lib/rails/generators/rails/plugin/templates/Gemfile
@@ -1,7 +1,7 @@
-source "https://rubygems.org"
+source 'https://rubygems.org'
<% if options[:skip_gemspec] -%>
-<%= '# ' if options.dev? || options.edge? -%>gem "rails", "~> <%= Rails::VERSION::STRING %>"
+<%= '# ' if options.dev? || options.edge? -%>gem 'rails', '~> <%= Rails::VERSION::STRING %>'
<% else -%>
# Declare your gem's dependencies in <%= name %>.gemspec.
# Bundler will treat runtime dependencies like base dependencies, and
@@ -11,7 +11,7 @@ gemspec
<% if options[:skip_gemspec] -%>
group :development do
- gem "<%= gem_for_database %>"
+ gem '<%= gem_for_database %>'
end
<% else -%>
# Declare any dependencies that are still in development here instead of in
@@ -23,8 +23,25 @@ end
<% if options.dev? || options.edge? -%>
# Your gem is dependent on dev or edge Rails. Once you can lock this
# dependency down to a specific version, move it to your gemspec.
-<%= rails_gemfile_entry -%>
+<% max_width = gemfile_entries.map { |g| g.name.length }.max -%>
+<% gemfile_entries.each do |gem| -%>
+<% if gem.comment -%>
+# <%= gem.comment %>
+<% end -%>
+<%= gem.commented_out ? '# ' : '' %>gem '<%= gem.name %>'<%= %(, '#{gem.version}') if gem.version -%>
+<% if gem.options.any? -%>
+,<%= gem.padding(max_width) %><%= gem.options.map { |k,v|
+ "#{k}: #{v.inspect}" }.join(', ') %>
+<% end -%>
+<% end -%>
+
+<% end -%>
+<% unless defined?(JRUBY_VERSION) -%>
+# To use a debugger
+ <%- if RUBY_VERSION < '2.0.0' -%>
+# gem 'debugger', group: [:development, :test]
+ <%- else -%>
+# gem 'byebug', group: [:development, :test]
+ <%- end -%>
<% end -%>
-# To use debugger
-# gem 'debugger'
diff --git a/railties/lib/rails/generators/rails/plugin/templates/MIT-LICENSE b/railties/lib/rails/generators/rails/plugin/templates/MIT-LICENSE
index d7a9109894..ff2fb3ba4e 100644
--- a/railties/lib/rails/generators/rails/plugin/templates/MIT-LICENSE
+++ b/railties/lib/rails/generators/rails/plugin/templates/MIT-LICENSE
@@ -1,4 +1,4 @@
-Copyright <%= Date.today.year %> YOURNAME
+Copyright <%= Date.today.year %> <%= author %>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
diff --git a/railties/lib/rails/generators/rails/plugin/templates/Rakefile b/railties/lib/rails/generators/rails/plugin/templates/Rakefile
index 0ba899176c..c338a0bdb1 100644
--- a/railties/lib/rails/generators/rails/plugin/templates/Rakefile
+++ b/railties/lib/rails/generators/rails/plugin/templates/Rakefile
@@ -19,6 +19,10 @@ APP_RAKEFILE = File.expand_path("../<%= dummy_path -%>/Rakefile", __FILE__)
load 'rails/tasks/engine.rake'
<% end %>
+<% if engine? -%>
+load 'rails/tasks/statistics.rake'
+<% end %>
+
<% unless options[:skip_gemspec] -%>
Bundler::GemHelper.install_tasks
diff --git a/railties/lib/rails/generators/rails/plugin/templates/bin/rails.tt b/railties/lib/rails/generators/rails/plugin/templates/bin/rails.tt
index c8de9f3e0f..c3314d7e68 100644
--- a/railties/lib/rails/generators/rails/plugin/templates/bin/rails.tt
+++ b/railties/lib/rails/generators/rails/plugin/templates/bin/rails.tt
@@ -3,5 +3,9 @@
ENGINE_ROOT = File.expand_path('../..', __FILE__)
ENGINE_PATH = File.expand_path('../../lib/<%= name -%>/engine', __FILE__)
+# Set up gems listed in the Gemfile.
+ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
+require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
+
require 'rails/all'
require 'rails/engine/commands'
diff --git a/railties/lib/rails/generators/rails/plugin/templates/rails/boot.rb b/railties/lib/rails/generators/rails/plugin/templates/rails/boot.rb
index ef360470a3..6266cfc509 100644
--- a/railties/lib/rails/generators/rails/plugin/templates/rails/boot.rb
+++ b/railties/lib/rails/generators/rails/plugin/templates/rails/boot.rb
@@ -1,5 +1,5 @@
# Set up gems listed in the Gemfile.
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../../../Gemfile', __FILE__)
-require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
+require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
$LOAD_PATH.unshift File.expand_path('../../../../lib', __FILE__)
diff --git a/railties/lib/rails/generators/rails/resource_route/resource_route_generator.rb b/railties/lib/rails/generators/rails/resource_route/resource_route_generator.rb
index a0e5553e44..e4a2bc2b0f 100644
--- a/railties/lib/rails/generators/rails/resource_route/resource_route_generator.rb
+++ b/railties/lib/rails/generators/rails/resource_route/resource_route_generator.rb
@@ -9,7 +9,7 @@ module Rails
# should give you
#
# namespace :admin do
- # namespace :users
+ # namespace :users do
# resources :products
# end
# end
diff --git a/railties/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb b/railties/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb
index 4f36b612ae..6bf0a33a5f 100644
--- a/railties/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb
+++ b/railties/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb
@@ -13,7 +13,7 @@ module Rails
argument :attributes, type: :array, default: [], banner: "field:type field:type"
def create_controller_files
- template "controller.rb", File.join('app/controllers', class_path, "#{controller_file_name}_controller.rb")
+ template "controller.rb", File.join('app/controllers', controller_class_path, "#{controller_file_name}_controller.rb")
end
hook_for :template_engine, :test_framework, as: :scaffold
diff --git a/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb b/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb
index 0e69aa101f..2c3b04043f 100644
--- a/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb
+++ b/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb
@@ -31,7 +31,7 @@ class <%= controller_class_name %>Controller < ApplicationController
if @<%= orm_instance.save %>
redirect_to @<%= singular_table_name %>, notice: <%= "'#{human_name} was successfully created.'" %>
else
- render action: 'new'
+ render :new
end
end
@@ -40,7 +40,7 @@ class <%= controller_class_name %>Controller < ApplicationController
if @<%= orm_instance.update("#{singular_table_name}_params") %>
redirect_to @<%= singular_table_name %>, notice: <%= "'#{human_name} was successfully updated.'" %>
else
- render action: 'edit'
+ render :edit
end
end
diff --git a/railties/lib/rails/generators/resource_helpers.rb b/railties/lib/rails/generators/resource_helpers.rb
index 7fd5c00768..4669935156 100644
--- a/railties/lib/rails/generators/resource_helpers.rb
+++ b/railties/lib/rails/generators/resource_helpers.rb
@@ -1,42 +1,46 @@
require 'rails/generators/active_model'
+require 'rails/generators/model_helpers'
module Rails
module Generators
# Deal with controller names on scaffold and add some helpers to deal with
# ActiveModel.
module ResourceHelpers # :nodoc:
- mattr_accessor :skip_warn
def self.included(base) #:nodoc:
- base.class_option :force_plural, type: :boolean, desc: "Forces the use of a plural ModelName"
+ base.send :include, Rails::Generators::ModelHelpers
+ base.class_option :model_name, type: :string, desc: "ModelName to be used"
end
# Set controller variables on initialization.
def initialize(*args) #:nodoc:
super
-
- if name == name.pluralize && name.singularize != name.pluralize && !options[:force_plural]
- unless ResourceHelpers.skip_warn
- say "Plural version of the model detected, using singularized version. Override with --force-plural."
- ResourceHelpers.skip_warn = true
- end
- name.replace name.singularize
- assign_names!(name)
+ controller_name = name
+ if options[:model_name]
+ self.name = options[:model_name]
+ assign_names!(self.name)
end
- @controller_name = name.pluralize
+ assign_controller_names!(controller_name.pluralize)
end
protected
- attr_reader :controller_name
+ attr_reader :controller_name, :controller_file_name
def controller_class_path
- class_path
+ if options[:model_name]
+ @controller_class_path
+ else
+ class_path
+ end
end
- def controller_file_name
- @controller_file_name ||= file_name.pluralize
+ def assign_controller_names!(name)
+ @controller_name = name
+ @controller_class_path = name.include?('/') ? name.split('/') : name.split('::')
+ @controller_class_path.map! { |m| m.underscore }
+ @controller_file_name = @controller_class_path.pop
end
def controller_file_path
diff --git a/railties/lib/rails/generators/test_unit/mailer/mailer_generator.rb b/railties/lib/rails/generators/test_unit/mailer/mailer_generator.rb
index 3334b189bf..85dee1a066 100644
--- a/railties/lib/rails/generators/test_unit/mailer/mailer_generator.rb
+++ b/railties/lib/rails/generators/test_unit/mailer/mailer_generator.rb
@@ -4,11 +4,18 @@ module TestUnit # :nodoc:
module Generators # :nodoc:
class MailerGenerator < Base # :nodoc:
argument :actions, type: :array, default: [], banner: "method method"
- check_class_collision suffix: "Test"
+
+ def check_class_collision
+ class_collisions "#{class_name}Test", "#{class_name}Preview"
+ end
def create_test_files
template "functional_test.rb", File.join('test/mailers', class_path, "#{file_name}_test.rb")
end
+
+ def create_preview_files
+ template "preview.rb", File.join('test/mailers/previews', class_path, "#{file_name}_preview.rb")
+ end
end
end
end
diff --git a/railties/lib/rails/generators/test_unit/mailer/templates/preview.rb b/railties/lib/rails/generators/test_unit/mailer/templates/preview.rb
new file mode 100644
index 0000000000..3bfd5426e8
--- /dev/null
+++ b/railties/lib/rails/generators/test_unit/mailer/templates/preview.rb
@@ -0,0 +1,13 @@
+<% module_namespacing do -%>
+# Preview all emails at http://localhost:3000/rails/mailers/<%= file_path %>
+class <%= class_name %>Preview < ActionMailer::Preview
+<% actions.each do |action| -%>
+
+ # Preview this email at http://localhost:3000/rails/mailers/<%= file_path %>/<%= action %>
+ def <%= action %>
+ <%= class_name %>.<%= action %>
+ end
+<% end -%>
+
+end
+<% end -%>
diff --git a/railties/lib/rails/generators/testing/assertions.rb b/railties/lib/rails/generators/testing/assertions.rb
index 6267b2f2ee..bd069e4bd0 100644
--- a/railties/lib/rails/generators/testing/assertions.rb
+++ b/railties/lib/rails/generators/testing/assertions.rb
@@ -1,3 +1,5 @@
+require 'shellwords'
+
module Rails
module Generators
module Testing
@@ -21,8 +23,8 @@ module Rails
# end
# end
def assert_file(relative, *contents)
- absolute = File.expand_path(relative, destination_root)
- assert File.exists?(absolute), "Expected file #{relative.inspect} to exist, but does not"
+ absolute = File.expand_path(relative, destination_root).shellescape
+ assert File.exist?(absolute), "Expected file #{relative.inspect} to exist, but does not"
read = File.read(absolute) if block_given? || !contents.empty?
yield read if block_given?
@@ -44,7 +46,7 @@ module Rails
# assert_no_file "config/random.rb"
def assert_no_file(relative)
absolute = File.expand_path(relative, destination_root)
- assert !File.exists?(absolute), "Expected file #{relative.inspect} to not exist, but does"
+ assert !File.exist?(absolute), "Expected file #{relative.inspect} to not exist, but does"
end
alias :assert_no_directory :assert_no_file
diff --git a/railties/lib/rails/info.rb b/railties/lib/rails/info.rb
index edadeaca0e..9502876ebb 100644
--- a/railties/lib/rails/info.rb
+++ b/railties/lib/rails/info.rb
@@ -23,7 +23,7 @@ module Rails
end
def frameworks
- %w( active_record action_pack action_view action_mailer active_support )
+ %w( active_record action_pack action_view action_mailer active_support active_model )
end
def framework_version(framework)
diff --git a/railties/lib/rails/info_controller.rb b/railties/lib/rails/info_controller.rb
index fa5668a5b5..49e5431a16 100644
--- a/railties/lib/rails/info_controller.rb
+++ b/railties/lib/rails/info_controller.rb
@@ -1,11 +1,11 @@
+require 'rails/application_controller'
require 'action_dispatch/routing/inspector'
-class Rails::InfoController < ActionController::Base # :nodoc:
- self.view_paths = File.expand_path('../templates', __FILE__)
+class Rails::InfoController < Rails::ApplicationController # :nodoc:
prepend_view_path ActionDispatch::DebugExceptions::RESCUES_TEMPLATE_PATH
- layout -> { request.xhr? ? nil : 'application' }
+ layout -> { request.xhr? ? false : 'application' }
- before_filter :require_local!
+ before_action :require_local!
def index
redirect_to action: :routes
@@ -13,21 +13,11 @@ class Rails::InfoController < ActionController::Base # :nodoc:
def properties
@info = Rails::Info.to_html
+ @page_title = 'Properties'
end
def routes
@routes_inspector = ActionDispatch::Routing::RoutesInspector.new(_routes.routes)
- end
-
- protected
-
- def require_local!
- unless local_request?
- render text: '<p>For security purposes, this information is only available to local requests.</p>', status: :forbidden
- end
- end
-
- def local_request?
- Rails.application.config.consider_all_requests_local || request.local?
+ @page_title = 'Routes'
end
end
diff --git a/railties/lib/rails/mailers_controller.rb b/railties/lib/rails/mailers_controller.rb
new file mode 100644
index 0000000000..32740d66da
--- /dev/null
+++ b/railties/lib/rails/mailers_controller.rb
@@ -0,0 +1,73 @@
+require 'rails/application_controller'
+
+class Rails::MailersController < Rails::ApplicationController # :nodoc:
+ prepend_view_path ActionDispatch::DebugExceptions::RESCUES_TEMPLATE_PATH
+
+ before_action :require_local!
+ before_action :find_preview, only: :preview
+
+ def index
+ @previews = ActionMailer::Preview.all
+ @page_title = "Mailer Previews"
+ end
+
+ def preview
+ if params[:path] == @preview.preview_name
+ @page_title = "Mailer Previews for #{@preview.preview_name}"
+ render action: 'mailer'
+ else
+ email = File.basename(params[:path])
+
+ if @preview.email_exists?(email)
+ @email = @preview.call(email)
+
+ if params[:part]
+ part_type = Mime::Type.lookup(params[:part])
+
+ if part = find_part(part_type)
+ response.content_type = part_type
+ render text: part.respond_to?(:decoded) ? part.decoded : part
+ else
+ raise AbstractController::ActionNotFound, "Email part '#{part_type}' not found in #{@preview.name}##{email}"
+ end
+ else
+ @part = find_preferred_part(request.format, Mime::HTML, Mime::TEXT)
+ render action: 'email', layout: false, formats: %w[html]
+ end
+ else
+ raise AbstractController::ActionNotFound, "Email '#{email}' not found in #{@preview.name}"
+ end
+ end
+ end
+
+ protected
+ def find_preview
+ candidates = []
+ params[:path].to_s.scan(%r{/|$}){ candidates << $` }
+ preview = candidates.detect{ |candidate| ActionMailer::Preview.exists?(candidate) }
+
+ if preview
+ @preview = ActionMailer::Preview.find(preview)
+ else
+ raise AbstractController::ActionNotFound, "Mailer preview '#{params[:path]}' not found"
+ end
+ end
+
+ def find_preferred_part(*formats)
+ if @email.multipart?
+ formats.each do |format|
+ return find_part(format) if @email.parts.any?{ |p| p.mime_type == format }
+ end
+ else
+ @email
+ end
+ end
+
+ def find_part(format)
+ if @email.multipart?
+ @email.parts.find{ |p| p.mime_type == format }
+ elsif @email.mime_type == format
+ @email
+ end
+ end
+end
diff --git a/railties/lib/rails/paths.rb b/railties/lib/rails/paths.rb
index de6795eda2..3eb66c07af 100644
--- a/railties/lib/rails/paths.rb
+++ b/railties/lib/rails/paths.rb
@@ -24,7 +24,7 @@ module Rails
#
# Notice that when you add a path using +add+, the path object created already
# contains the path with the same path value given to +add+. In some situations,
- # you may not want this behavior, so you can give :with as option.
+ # you may not want this behavior, so you can give <tt>:with</tt> as option.
#
# root.add "config/routes", with: "config/routes.rb"
# root["config/routes"].inspect # => ["config/routes.rb"]
@@ -81,34 +81,28 @@ module Rails
end
def autoload_once
- filter_by(:autoload_once?)
+ filter_by { |p| p.autoload_once? }
end
def eager_load
- filter_by(:eager_load?)
+ filter_by { |p| p.eager_load? }
end
def autoload_paths
- filter_by(:autoload?)
+ filter_by { |p| p.autoload? }
end
def load_paths
- filter_by(:load_path?)
+ filter_by { |p| p.load_path? }
end
- protected
+ private
- def filter_by(constraint)
- all = []
- all_paths.each do |path|
- if path.send(constraint)
- paths = path.existent
- paths -= path.children.map { |p| p.send(constraint) ? [] : p.existent }.flatten
- all.concat(paths)
- end
- end
- all.uniq!
- all
+ def filter_by(&block)
+ all_paths.find_all(&block).flat_map { |path|
+ paths = path.existent
+ paths - path.children.flat_map { |p| yield(p) ? [] : p.existent }
+ }.uniq
end
end
@@ -130,8 +124,9 @@ module Rails
end
def children
- keys = @root.keys.select { |k| k.include?(@current) }
- keys.delete(@current)
+ keys = @root.keys.find_all { |k|
+ k.start_with?(@current) && k != @current
+ }
@root.values_at(*keys.sort)
end
@@ -203,7 +198,7 @@ module Rails
# Returns all expanded paths but only if they exist in the filesystem.
def existent
- expanded.select { |f| File.exists?(f) }
+ expanded.select { |f| File.exist?(f) }
end
def existent_directories
diff --git a/railties/lib/rails/rack.rb b/railties/lib/rails/rack.rb
index d1ee96f7fd..886f0e52e1 100644
--- a/railties/lib/rails/rack.rb
+++ b/railties/lib/rails/rack.rb
@@ -1,6 +1,6 @@
module Rails
module Rack
- autoload :Debugger, "rails/rack/debugger"
+ autoload :Debugger, "rails/rack/debugger" if RUBY_VERSION < '2.0.0'
autoload :Logger, "rails/rack/logger"
autoload :LogTailer, "rails/rack/log_tailer"
end
diff --git a/railties/lib/rails/rack/log_tailer.rb b/railties/lib/rails/rack/log_tailer.rb
index 18f22e8089..bc26421a9e 100644
--- a/railties/lib/rails/rack/log_tailer.rb
+++ b/railties/lib/rails/rack/log_tailer.rb
@@ -1,13 +1,17 @@
+require 'active_support/deprecation'
+
module Rails
module Rack
class LogTailer
def initialize(app, log = nil)
+ ActiveSupport::Deprecation.warn "LogTailer is deprecated and will be removed on Rails 5"
+
@app = app
path = Pathname.new(log || "#{::File.expand_path(Rails.root)}/log/#{Rails.env}.log").cleanpath
@cursor = @file = nil
- if ::File.exists?(path)
+ if ::File.exist?(path)
@cursor = ::File.size(path)
@file = ::File.open(path, 'r')
end
diff --git a/railties/lib/rails/rack/logger.rb b/railties/lib/rails/rack/logger.rb
index ef4cdcb080..3b35798679 100644
--- a/railties/lib/rails/rack/logger.rb
+++ b/railties/lib/rails/rack/logger.rb
@@ -11,7 +11,6 @@ module Rails
def initialize(app, taggers = nil)
@app = app
@taggers = taggers || []
- @instrumenter = ActiveSupport::Notifications.instrumenter
end
def call(env)
@@ -33,7 +32,8 @@ module Rails
logger.debug ''
end
- @instrumenter.start 'request.action_dispatch', request: request
+ instrumenter = ActiveSupport::Notifications.instrumenter
+ instrumenter.start 'request.action_dispatch', request: request
logger.info started_request_message(request)
resp = @app.call(env)
resp[2] = ::Rack::BodyProxy.new(resp[2]) { finish(request) }
@@ -70,7 +70,8 @@ module Rails
private
def finish(request)
- @instrumenter.finish 'request.action_dispatch', request: request
+ instrumenter = ActiveSupport::Notifications.instrumenter
+ instrumenter.finish 'request.action_dispatch', request: request
end
def development?
diff --git a/railties/lib/rails/railtie.rb b/railties/lib/rails/railtie.rb
index 89ca8cbe11..2b33beaa2b 100644
--- a/railties/lib/rails/railtie.rb
+++ b/railties/lib/rails/railtie.rb
@@ -22,7 +22,7 @@ module Rails
#
# * creating initializers
# * configuring a Rails framework for the application, like setting a generator
- # * +adding config.*+ keys to the environment
+ # * adding <tt>config.*</tt> keys to the environment
# * setting up a subscriber with ActiveSupport::Notifications
# * adding rake tasks
#
@@ -63,8 +63,8 @@ module Rails
# end
# end
#
- # Finally, you can also pass :before and :after as option to initializer, in case
- # you want to couple it with a specific step in the initialization process.
+ # Finally, you can also pass <tt>:before</tt> and <tt>:after</tt> as option to initializer,
+ # in case you want to couple it with a specific step in the initialization process.
#
# == Configuration
#
@@ -183,8 +183,8 @@ module Rails
end
protected
- def generate_railtie_name(class_or_module)
- ActiveSupport::Inflector.underscore(class_or_module).tr("/", "_")
+ def generate_railtie_name(string)
+ ActiveSupport::Inflector.underscore(string).tr("/", "_")
end
# If the class method does not have a method, then send the method call
@@ -221,26 +221,28 @@ module Rails
protected
def run_console_blocks(app) #:nodoc:
- self.class.console.each { |block| block.call(app) }
+ each_registered_block(:console) { |block| block.call(app) }
end
def run_generators_blocks(app) #:nodoc:
- self.class.generators.each { |block| block.call(app) }
+ each_registered_block(:generators) { |block| block.call(app) }
end
def run_runner_blocks(app) #:nodoc:
- self.class.runner.each { |block| block.call(app) }
+ each_registered_block(:runner) { |block| block.call(app) }
end
def run_tasks_blocks(app) #:nodoc:
extend Rake::DSL
- self.class.rake_tasks.each { |block| instance_exec(app, &block) }
+ each_registered_block(:rake_tasks) { |block| instance_exec(app, &block) }
+ end
- # Load also tasks from all superclasses
- klass = self.class.superclass
+ private
- while klass.respond_to?(:rake_tasks)
- klass.rake_tasks.each { |t| instance_exec(app, &t) }
+ def each_registered_block(type, &block)
+ klass = self.class
+ while klass.respond_to?(type)
+ klass.public_send(type).each(&block)
klass = klass.superclass
end
end
diff --git a/railties/lib/rails/ruby_version_check.rb b/railties/lib/rails/ruby_version_check.rb
index 3b7f358a5b..df74643a59 100644
--- a/railties/lib/rails/ruby_version_check.rb
+++ b/railties/lib/rails/ruby_version_check.rb
@@ -2,7 +2,7 @@ if RUBY_VERSION < '1.9.3'
desc = defined?(RUBY_DESCRIPTION) ? RUBY_DESCRIPTION : "ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE})"
abort <<-end_message
- Rails 4 prefers to run on Ruby 2.0.
+ Rails 4 prefers to run on Ruby 2.1 or newer.
You're running
#{desc}
diff --git a/railties/lib/rails/source_annotation_extractor.rb b/railties/lib/rails/source_annotation_extractor.rb
index b806b922b7..201532d299 100644
--- a/railties/lib/rails/source_annotation_extractor.rb
+++ b/railties/lib/rails/source_annotation_extractor.rb
@@ -18,6 +18,20 @@ class SourceAnnotationExtractor
@@directories ||= %w(app config db lib test) + (ENV['SOURCE_ANNOTATION_DIRECTORIES'] || '').split(',')
end
+ def self.extensions
+ @@extensions ||= {}
+ end
+
+ # Registers new Annotations File Extensions
+ # SourceAnnotationExtractor::Annotation.register_extensions("css", "scss", "sass", "less", "js") { |tag| /\/\/\s*(#{tag}):?\s*(.*)$/ }
+ def self.register_extensions(*exts, &block)
+ extensions[/\.(#{exts.join("|")})$/] = block
+ end
+
+ register_extensions("builder", "rb", "rake", "yml", "yaml", "ruby") { |tag| /#\s*(#{tag}):?\s*(.*)$/ }
+ register_extensions("css", "js") { |tag| /\/\/\s*(#{tag}):?\s*(.*)$/ }
+ register_extensions("erb") { |tag| /<%\s*#\s*(#{tag}):?\s*(.*?)\s*%>/ }
+
# Returns a representation of the annotation that looks like this:
#
# [126] [TODO] This algorithm is simple and clearly correct, make it faster.
@@ -67,7 +81,7 @@ class SourceAnnotationExtractor
# Returns a hash that maps filenames under +dir+ (recursively) to arrays
# with their annotations. Only files with annotations are included. Files
# with extension +.builder+, +.rb+, +.erb+, +.haml+, +.slim+, +.css+,
- # +.scss+, +.js+, +.coffee+, and +.rake+
+ # +.scss+, +.js+, +.coffee+, +.rake+, +.sass+ and +.less+
# are taken into account.
def find_in(dir)
results = {}
@@ -78,21 +92,14 @@ class SourceAnnotationExtractor
if File.directory?(item)
results.update(find_in(item))
else
- pattern =
- case item
- when /\.(builder|rb|coffee|rake)$/
- /#\s*(#{tag}):?\s*(.*)$/
- when /\.(css|scss|sass|less|js)$/
- /\/\/\s*(#{tag}):?\s*(.*)$/
- when /\.erb$/
- /<%\s*#\s*(#{tag}):?\s*(.*?)\s*%>/
- when /\.haml$/
- /-\s*#\s*(#{tag}):?\s*(.*)$/
- when /\.slim$/
- /\/\s*\s*(#{tag}):?\s*(.*)$/
- else nil
- end
- results.update(extract_annotations_from(item, pattern)) if pattern
+ extension = Annotation.extensions.detect do |regexp, _block|
+ regexp.match(item)
+ end
+
+ if extension
+ pattern = extension.last.call(tag)
+ results.update(extract_annotations_from(item, pattern)) if pattern
+ end
end
end
@@ -115,7 +122,7 @@ class SourceAnnotationExtractor
# Prints the mapping from filenames to annotations in +results+ ordered by filename.
# The +options+ hash is passed to each annotation's +to_s+.
def display(results, options={})
- options[:indent] = results.map { |f, a| a.map(&:line) }.flatten.max.to_s.size
+ options[:indent] = results.flat_map { |f, a| a.map(&:line) }.max.to_s.size
results.keys.sort.each do |file|
puts "#{file}:"
results[file].each do |note|
diff --git a/railties/lib/rails/tasks/framework.rake b/railties/lib/rails/tasks/framework.rake
index bd4e7c33e0..a1c805f8aa 100644
--- a/railties/lib/rails/tasks/framework.rake
+++ b/railties/lib/rails/tasks/framework.rake
@@ -3,7 +3,7 @@ namespace :rails do
task update: [ "update:configs", "update:bin" ]
desc "Applies the template supplied by LOCATION=(/path/to/template) or URL"
- task :template do
+ task template: :environment do
template = ENV["LOCATION"]
raise "No LOCATION value given. Please set LOCATION either as path to a file or a URL" if template.blank?
template = File.expand_path(template) if template !~ %r{\A[A-Za-z][A-Za-z0-9+\-\.]*://}
@@ -46,7 +46,7 @@ namespace :rails do
require 'rails/generators/rails/app/app_generator'
gen = Rails::Generators::AppGenerator.new ["rails"], { with_dispatchers: true },
destination_root: Rails.root
- File.exists?(Rails.root.join("config", "application.rb")) ?
+ File.exist?(Rails.root.join("config", "application.rb")) ?
gen.send(:app_const) : gen.send(:valid_const?)
gen
end
@@ -55,7 +55,7 @@ namespace :rails do
# desc "Update config/boot.rb from your current rails install"
task :configs do
invoke_from_app_generator :create_boot_file
- invoke_from_app_generator :create_config_files
+ invoke_from_app_generator :update_config_files
end
# desc "Adds new executables to the application bin/ directory"
diff --git a/railties/lib/rails/tasks/log.rake b/railties/lib/rails/tasks/log.rake
index 6c3f02eb0c..877f175ef3 100644
--- a/railties/lib/rails/tasks/log.rake
+++ b/railties/lib/rails/tasks/log.rake
@@ -10,7 +10,7 @@ namespace :log do
if ENV['LOGS']
ENV['LOGS'].split(',')
.map { |file| "log/#{file.strip}.log" }
- .select { |file| File.exists?(file) }
+ .select { |file| File.exist?(file) }
else
FileList["log/*.log"]
end
diff --git a/railties/lib/rails/tasks/statistics.rake b/railties/lib/rails/tasks/statistics.rake
index c1674c72ad..ae5a7d2759 100644
--- a/railties/lib/rails/tasks/statistics.rake
+++ b/railties/lib/rails/tasks/statistics.rake
@@ -1,3 +1,6 @@
+# while having global constant is not good,
+# many 3rd party tools depend on it, like rspec-rails, cucumber-rails, etc
+# so if will be removed - deprecation warning is needed
STATS_DIRECTORIES = [
%w(Controllers app/controllers),
%w(Helpers app/helpers),
@@ -13,10 +16,12 @@ STATS_DIRECTORIES = [
%w(Integration\ tests test/integration),
%w(Functional\ tests\ (old) test/functional),
%w(Unit\ tests \ (old) test/unit)
-].collect { |name, dir| [ name, "#{Rails.root}/#{dir}" ] }.select { |name, dir| File.directory?(dir) }
+].collect do |name, dir|
+ [ name, "#{File.dirname(Rake.application.rakefile_location)}/#{dir}" ]
+end.select { |name, dir| File.directory?(dir) }
-desc "Report code statistics (KLOCs, etc) from the application"
+desc "Report code statistics (KLOCs, etc) from the application or engine"
task :stats do
require 'rails/code_statistics'
CodeStatistics.new(*STATS_DIRECTORIES).to_s
-end
+end \ No newline at end of file
diff --git a/railties/lib/rails/templates/layouts/application.html.erb b/railties/lib/rails/templates/layouts/application.html.erb
index 7352d48e7b..5aecaa712a 100644
--- a/railties/lib/rails/templates/layouts/application.html.erb
+++ b/railties/lib/rails/templates/layouts/application.html.erb
@@ -2,7 +2,7 @@
<html lang="en">
<head>
<meta charset="utf-8" />
- <title>Routes</title>
+ <title><%= @page_title %></title>
<style>
body { background-color: #fff; color: #333; }
@@ -29,7 +29,7 @@
</style>
</head>
<body>
-<h2>Your App: <%= link_to 'properties', '/rails/info/properties' %> | <%= link_to 'routes', '/rails/info/routes' %></h2>
+
<%= yield %>
</body>
diff --git a/railties/lib/rails/templates/rails/mailers/email.html.erb b/railties/lib/rails/templates/rails/mailers/email.html.erb
new file mode 100644
index 0000000000..977feb922b
--- /dev/null
+++ b/railties/lib/rails/templates/rails/mailers/email.html.erb
@@ -0,0 +1,98 @@
+<!DOCTYPE html>
+<html><head>
+<meta name="viewport" content="width=device-width" />
+<style type="text/css">
+ header {
+ width: 100%;
+ padding: 10px 0 0 0;
+ margin: 0;
+ background: white;
+ font: 12px "Lucida Grande", sans-serif;
+ border-bottom: 1px solid #dedede;
+ overflow: hidden;
+ }
+
+ dl {
+ margin: 0 0 10px 0;
+ padding: 0;
+ }
+
+ dt {
+ width: 80px;
+ padding: 1px;
+ float: left;
+ clear: left;
+ text-align: right;
+ color: #7f7f7f;
+ }
+
+ dd {
+ margin-left: 90px; /* 80px + 10px */
+ padding: 1px;
+ }
+
+ iframe {
+ border: 0;
+ width: 100%;
+ height: 800px;
+ }
+</style>
+</head>
+
+<body>
+<header>
+ <dl>
+ <% if @email.respond_to?(:smtp_envelope_from) && Array(@email.from) != Array(@email.smtp_envelope_from) %>
+ <dt>SMTP-From:</dt>
+ <dd><%= @email.smtp_envelope_from %></dd>
+ <% end %>
+
+ <% if @email.respond_to?(:smtp_envelope_to) && @email.to != @email.smtp_envelope_to %>
+ <dt>SMTP-To:</dt>
+ <dd><%= @email.smtp_envelope_to %></dd>
+ <% end %>
+
+ <dt>From:</dt>
+ <dd><%= @email.header['from'] %></dd>
+
+ <% if @email.reply_to %>
+ <dt>Reply-To:</dt>
+ <dd><%= @email.header['reply-to'] %></dd>
+ <% end %>
+
+ <dt>To:</dt>
+ <dd><%= @email.header['to'] %></dd>
+
+ <% if @email.cc %>
+ <dt>CC:</dt>
+ <dd><%= @email.header['cc'] %></dd>
+ <% end %>
+
+ <dt>Date:</dt>
+ <dd><%= Time.current.rfc2822 %></dd>
+
+ <dt>Subject:</dt>
+ <dd><strong><%= @email.subject %></strong></dd>
+
+ <% unless @email.attachments.nil? || @email.attachments.empty? %>
+ <dt>Attachments:</dt>
+ <dd>
+ <%= @email.attachments.map { |a| a.respond_to?(:original_filename) ? a.original_filename : a.filename }.inspect %>
+ </dd>
+ <% end %>
+
+ <% if @email.multipart? %>
+ <dd>
+ <select onchange="document.getElementsByName('messageBody')[0].src=this.options[this.selectedIndex].value;">
+ <option <%= request.format == Mime::HTML ? 'selected' : '' %> value="?part=text%2Fhtml">View as HTML email</option>
+ <option <%= request.format == Mime::TEXT ? 'selected' : '' %> value="?part=text%2Fplain">View as plain-text email</option>
+ </select>
+ </dd>
+ <% end %>
+ </dl>
+</header>
+
+<iframe seamless name="messageBody" src="?part=<%= Rack::Utils.escape(@part.mime_type) %>"></iframe>
+
+</body>
+</html> \ No newline at end of file
diff --git a/railties/lib/rails/templates/rails/mailers/index.html.erb b/railties/lib/rails/templates/rails/mailers/index.html.erb
new file mode 100644
index 0000000000..c4c9757d57
--- /dev/null
+++ b/railties/lib/rails/templates/rails/mailers/index.html.erb
@@ -0,0 +1,8 @@
+<% @previews.each do |preview| %>
+<h3><%= link_to preview.preview_name.titleize, "/rails/mailers/#{preview.preview_name}" %></h3>
+<ul>
+<% preview.emails.each do |email| %>
+<li><%= link_to email, "/rails/mailers/#{preview.preview_name}/#{email}" %></li>
+<% end %>
+</ul>
+<% end %>
diff --git a/railties/lib/rails/templates/rails/mailers/mailer.html.erb b/railties/lib/rails/templates/rails/mailers/mailer.html.erb
new file mode 100644
index 0000000000..607c8d1677
--- /dev/null
+++ b/railties/lib/rails/templates/rails/mailers/mailer.html.erb
@@ -0,0 +1,6 @@
+<h3><%= @preview.preview_name.titleize %></h3>
+<ul>
+<% @preview.emails.each do |email| %>
+<li><%= link_to email, "/rails/mailers/#{@preview.preview_name}/#{email}" %></li>
+<% end %>
+</ul>
diff --git a/railties/lib/rails/test_help.rb b/railties/lib/rails/test_help.rb
index 46f7466551..c837fadb40 100644
--- a/railties/lib/rails/test_help.rb
+++ b/railties/lib/rails/test_help.rb
@@ -4,15 +4,20 @@ abort("Abort testing: Your Rails environment is running in production mode!") if
require 'active_support/testing/autorun'
require 'active_support/test_case'
+require 'action_controller'
require 'action_controller/test_case'
require 'action_dispatch/testing/integration'
require 'rails/generators/test_case'
# Config Rails backtrace in tests.
require 'rails/backtrace_cleaner'
-MiniTest.backtrace_filter = Rails.backtrace_cleaner
+if ENV["BACKTRACE"].nil?
+ Minitest.backtrace_filter = Rails.backtrace_cleaner
+end
if defined?(ActiveRecord::Base)
+ ActiveRecord::Migration.maintain_test_schema!
+
class ActiveSupport::TestCase
include ActiveRecord::TestFixtures
self.fixture_path = "#{Rails.root}/test/fixtures/"
diff --git a/railties/lib/rails/test_unit/sub_test_task.rb b/railties/lib/rails/test_unit/sub_test_task.rb
index d9bffba4d7..6fa96d2ced 100644
--- a/railties/lib/rails/test_unit/sub_test_task.rb
+++ b/railties/lib/rails/test_unit/sub_test_task.rb
@@ -7,7 +7,7 @@ module Rails
#
# This class takes a TestInfo class and defines the appropriate rake task
# based on the information, then invokes it.
- class TestCreator
+ class TestCreator # :nodoc:
def initialize(info)
@info = info
end
@@ -41,7 +41,7 @@ module Rails
# to test files (or can be transformed into test files). Calling <tt>files</tt>
# provides the set of test files and is used when initializing tests after
# a call to <tt>rake test</tt>.
- class TestInfo
+ class TestInfo # :nodoc:
def initialize(tasks)
@tasks = tasks
@files = nil
diff --git a/railties/lib/rails/test_unit/testing.rake b/railties/lib/rails/test_unit/testing.rake
index 547846c833..285e2ce846 100644
--- a/railties/lib/rails/test_unit/testing.rake
+++ b/railties/lib/rails/test_unit/testing.rake
@@ -1,10 +1,9 @@
-require 'rbconfig'
require 'rake/testtask'
require 'rails/test_unit/sub_test_task'
task default: :test
-desc 'Runs test:units, test:functionals, test:integration together'
+desc 'Runs test:units, test:functionals, test:generators, test:integration together'
task :test do
Rails::TestTask.test_creator(Rake.application.top_level_tasks).invoke_rake_task
end
diff --git a/railties/lib/rails/version.rb b/railties/lib/rails/version.rb
index 5a6d8d0983..df351c4238 100644
--- a/railties/lib/rails/version.rb
+++ b/railties/lib/rails/version.rb
@@ -1,10 +1,8 @@
-module Rails
- module VERSION
- MAJOR = 4
- MINOR = 1
- TINY = 0
- PRE = "beta"
+require_relative 'gem_version'
- STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
+module Rails
+ # Returns the version of the currently loaded Rails as a string.
+ def self.version
+ VERSION::STRING
end
end
diff --git a/railties/lib/rails/welcome_controller.rb b/railties/lib/rails/welcome_controller.rb
index 45b764fa6b..de9cd18b01 100644
--- a/railties/lib/rails/welcome_controller.rb
+++ b/railties/lib/rails/welcome_controller.rb
@@ -1,6 +1,7 @@
-class Rails::WelcomeController < ActionController::Base # :nodoc:
- self.view_paths = File.expand_path('../templates', __FILE__)
- layout nil
+require 'rails/application_controller'
+
+class Rails::WelcomeController < Rails::ApplicationController # :nodoc:
+ layout false
def index
end
diff --git a/railties/test/abstract_unit.rb b/railties/test/abstract_unit.rb
index 643cc6b0ee..9ccc286b4e 100644
--- a/railties/test/abstract_unit.rb
+++ b/railties/test/abstract_unit.rb
@@ -14,6 +14,15 @@ require 'rails/all'
module TestApp
class Application < Rails::Application
config.root = File.dirname(__FILE__)
- config.secret_key_base = 'b3c631c314c0bbca50c1b2843150fe33'
+ secrets.secret_key_base = 'b3c631c314c0bbca50c1b2843150fe33'
end
end
+
+# Skips the current run on Rubinius using Minitest::Assertions#skip
+def rubinius_skip(message = '')
+ skip message if RUBY_ENGINE == 'rbx'
+end
+# Skips the current run on JRuby using Minitest::Assertions#skip
+def jruby_skip(message = '')
+ skip message if defined?(JRUBY_VERSION)
+end
diff --git a/railties/test/app_rails_loader_test.rb b/railties/test/app_rails_loader_test.rb
index ceae78ae80..1d3b80253a 100644
--- a/railties/test/app_rails_loader_test.rb
+++ b/railties/test/app_rails_loader_test.rb
@@ -22,8 +22,14 @@ class AppRailsLoaderTest < ActiveSupport::TestCase
exe = "#{script_dir}/rails"
test "is not in a Rails application if #{exe} is not found in the current or parent directories" do
- File.stubs(:exists?).with('bin/rails').returns(false)
- File.stubs(:exists?).with('script/rails').returns(false)
+ File.stubs(:file?).with('bin/rails').returns(false)
+ File.stubs(:file?).with('script/rails').returns(false)
+
+ assert !Rails::AppRailsLoader.exec_app_rails
+ end
+
+ test "is not in a Rails application if #{exe} exists but is a folder" do
+ FileUtils.mkdir_p(exe)
assert !Rails::AppRailsLoader.exec_app_rails
end
diff --git a/railties/test/application/assets_test.rb b/railties/test/application/assets_test.rb
index 035535ce22..8f091cfdbf 100644
--- a/railties/test/application/assets_test.rb
+++ b/railties/test/application/assets_test.rb
@@ -37,7 +37,7 @@ module ApplicationTests
end
def assert_no_file_exists(filename)
- assert !File.exists?(filename), "#{filename} does exist"
+ assert !File.exist?(filename), "#{filename} does exist"
end
test "assets routes have higher priority" do
@@ -50,6 +50,8 @@ module ApplicationTests
end
RUBY
+ add_to_env_config "development", "config.assets.digest = false"
+
require "#{app_path}/config/environment"
get "/assets/demo.js"
@@ -189,7 +191,6 @@ module ApplicationTests
end
test "asset pipeline should use a Sprockets::Index when config.assets.digest is true" do
- add_to_config "config.assets.digest = true"
add_to_config "config.action_controller.perform_caching = false"
ENV["RAILS_ENV"] = "production"
@@ -199,10 +200,9 @@ module ApplicationTests
end
test "precompile creates a manifest file with all the assets listed" do
+ app_file "app/assets/images/rails.png", "notactuallyapng"
app_file "app/assets/stylesheets/application.css.erb", "<%= asset_path('rails.png') %>"
app_file "app/assets/javascripts/application.js", "alert();"
- # digest is default in false, we must enable it for test environment
- add_to_config "config.assets.digest = true"
precompile!
manifest = Dir["#{app_path}/public/assets/manifest-*.json"].first
@@ -214,8 +214,6 @@ module ApplicationTests
test "the manifest file should be saved by default in the same assets folder" do
app_file "app/assets/javascripts/application.js", "alert();"
- # digest is default in false, we must enable it for test environment
- add_to_config "config.assets.digest = true"
add_to_config "config.assets.prefix = '/x'"
precompile!
@@ -248,7 +246,6 @@ module ApplicationTests
test "precompile properly refers files referenced with asset_path and runs in the provided RAILS_ENV" do
app_file "app/assets/images/rails.png", "notactuallyapng"
app_file "app/assets/stylesheets/application.css.erb", "<%= asset_path('rails.png') %>"
- # digest is default in false, we must enable it for test environment
add_to_env_config "test", "config.assets.digest = true"
precompile!('RAILS_ENV=test')
@@ -260,7 +257,7 @@ module ApplicationTests
test "precompile shouldn't use the digests present in manifest.json" do
app_file "app/assets/images/rails.png", "notactuallyapng"
- app_file "app/assets/stylesheets/application.css.erb", "//= depend_on rails.png\np { url: <%= asset_path('rails.png') %> }"
+ app_file "app/assets/stylesheets/application.css.erb", "p { url: <%= asset_path('rails.png') %> }"
ENV["RAILS_ENV"] = "production"
precompile!
@@ -280,12 +277,9 @@ module ApplicationTests
test "precompile appends the md5 hash to files referenced with asset_path and run in production with digest true" do
app_file "app/assets/images/rails.png", "notactuallyapng"
app_file "app/assets/stylesheets/application.css.erb", "<%= asset_path('rails.png') %>"
- add_to_config "config.assets.compile = true"
- add_to_config "config.assets.digest = true"
-
- ENV["RAILS_ENV"] = nil
- precompile!('RAILS_GROUPS=assets')
+ ENV["RAILS_ENV"] = "production"
+ precompile!
file = Dir["#{app_path}/public/assets/application-*.css"].first
assert_match(/\/assets\/rails-([0-z]+)\.png/, File.read(file))
@@ -341,6 +335,8 @@ module ApplicationTests
end
RUBY
+ add_to_env_config "development", "config.assets.digest = false"
+
require "#{app_path}/config/environment"
class ::OmgController < ActionController::Base
@@ -365,6 +361,8 @@ module ApplicationTests
app_file "app/assets/javascripts/demo.js", "alert();"
+ add_to_env_config "development", "config.assets.digest = false"
+
require "#{app_path}/config/environment"
get "/assets/demo.js"
@@ -394,7 +392,6 @@ module ApplicationTests
app_file "app/assets/javascripts/application.js", "//= require_tree ."
app_file "app/assets/javascripts/xmlhr.js.erb", "<%= Post.name %>"
- add_to_config "config.assets.digest = false"
precompile!
assert_equal "Post;\n", File.read(Dir["#{app_path}/public/assets/application-*.js"].first)
end
@@ -414,7 +411,6 @@ module ApplicationTests
test "digested assets are not mistakenly removed" do
app_file "app/assets/application.js", "alert();"
add_to_config "config.assets.compile = true"
- add_to_config "config.assets.digest = true"
precompile!
@@ -437,6 +433,7 @@ module ApplicationTests
test "asset urls should use the request's protocol by default" do
app_with_assets_in_view
add_to_config "config.asset_host = 'example.com'"
+ add_to_env_config "development", "config.assets.digest = false"
require "#{app_path}/config/environment"
class ::PostsController < ActionController::Base; end
@@ -448,23 +445,24 @@ module ApplicationTests
test "asset urls should be protocol-relative if no request is in scope" do
app_file "app/assets/images/rails.png", "notreallyapng"
- app_file "app/assets/javascripts/image_loader.js.erb", 'var src="<%= image_path("rails.png") %>";'
- add_to_config "config.assets.precompile = %w{image_loader.js}"
+ app_file "app/assets/javascripts/image_loader.js.erb", "var src='<%= image_path('rails.png') %>';"
+ add_to_config "config.assets.precompile = %w{rails.png image_loader.js}"
add_to_config "config.asset_host = 'example.com'"
+ add_to_env_config "development", "config.assets.digest = false"
precompile!
- assert_match 'src="//example.com/assets/rails.png"', File.read(Dir["#{app_path}/public/assets/image_loader-*.js"].first)
+ assert_match "src='//example.com/assets/rails.png'", File.read(Dir["#{app_path}/public/assets/image_loader-*.js"].first)
end
test "asset paths should use RAILS_RELATIVE_URL_ROOT by default" do
ENV["RAILS_RELATIVE_URL_ROOT"] = "/sub/uri"
app_file "app/assets/images/rails.png", "notreallyapng"
-
- app_file "app/assets/javascripts/app.js.erb", 'var src="<%= image_path("rails.png") %>";'
- add_to_config "config.assets.precompile = %w{app.js}"
+ app_file "app/assets/javascripts/app.js.erb", "var src='<%= image_path('rails.png') %>';"
+ add_to_config "config.assets.precompile = %w{rails.png app.js}"
+ add_to_env_config "development", "config.assets.digest = false"
precompile!
- assert_match 'src="/sub/uri/assets/rails.png"', File.read(Dir["#{app_path}/public/assets/app-*.js"].first)
+ assert_match "src='/sub/uri/assets/rails.png'", File.read(Dir["#{app_path}/public/assets/app-*.js"].first)
end
test "assets:cache:clean should clean cache" do
diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb
index 03a735b1c1..207a0c7e86 100644
--- a/railties/test/application/configuration_test.rb
+++ b/railties/test/application/configuration_test.rb
@@ -8,6 +8,12 @@ end
class ::MyOtherMailInterceptor < ::MyMailInterceptor; end
+class ::MyPreviewMailInterceptor
+ def self.previewing_email(email); email; end
+end
+
+class ::MyOtherPreviewMailInterceptor < ::MyPreviewMailInterceptor; end
+
class ::MyMailObserver
def self.delivered_email(email); email; end
end
@@ -250,7 +256,7 @@ module ApplicationTests
test "Use key_generator when secret_key_base is set" do
make_basic_app do |app|
- app.config.secret_key_base = 'b3c631c314c0bbca50c1b2843150fe33'
+ app.secrets.secret_key_base = 'b3c631c314c0bbca50c1b2843150fe33'
app.config.session_store :disabled
end
@@ -268,6 +274,82 @@ module ApplicationTests
assert_equal 'some_value', verifier.verify(last_response.body)
end
+ test "application verifier can be used in the entire application" do
+ make_basic_app do |app|
+ app.secrets.secret_key_base = 'b3c631c314c0bbca50c1b2843150fe33'
+ app.config.session_store :disabled
+ end
+
+ message = app.message_verifier(:sensitive_value).generate("some_value")
+
+ assert_equal 'some_value', Rails.application.message_verifier(:sensitive_value).verify(message)
+
+ secret = app.key_generator.generate_key('sensitive_value')
+ verifier = ActiveSupport::MessageVerifier.new(secret)
+ assert_equal 'some_value', verifier.verify(message)
+ end
+
+ test "application verifier can build different verifiers" do
+ make_basic_app do |app|
+ app.secrets.secret_key_base = 'b3c631c314c0bbca50c1b2843150fe33'
+ app.config.session_store :disabled
+ end
+
+ default_verifier = app.message_verifier(:sensitive_value)
+ text_verifier = app.message_verifier(:text)
+
+ message = text_verifier.generate('some_value')
+
+ assert_equal 'some_value', text_verifier.verify(message)
+ assert_raises ActiveSupport::MessageVerifier::InvalidSignature do
+ default_verifier.verify(message)
+ end
+
+ assert_equal default_verifier.object_id, app.message_verifier(:sensitive_value).object_id
+ assert_not_equal default_verifier.object_id, text_verifier.object_id
+ end
+
+ test "secrets.secret_key_base is used when config/secrets.yml is present" do
+ app_file 'config/secrets.yml', <<-YAML
+ development:
+ secret_key_base: 3b7cd727ee24e8444053437c36cc66c3
+ YAML
+
+ require "#{app_path}/config/environment"
+ assert_equal '3b7cd727ee24e8444053437c36cc66c3', app.secrets.secret_key_base
+ end
+
+ test "secret_key_base is copied from config to secrets when not set" do
+ remove_file "config/secrets.yml"
+ app_file 'config/initializers/secret_token.rb', <<-RUBY
+ Rails.application.config.secret_key_base = "3b7cd727ee24e8444053437c36cc66c3"
+ RUBY
+
+ require "#{app_path}/config/environment"
+ assert_equal '3b7cd727ee24e8444053437c36cc66c3', app.secrets.secret_key_base
+ end
+
+ test "custom secrets saved in config/secrets.yml are loaded in app secrets" do
+ app_file 'config/secrets.yml', <<-YAML
+ development:
+ secret_key_base: 3b7cd727ee24e8444053437c36cc66c3
+ aws_access_key_id: myamazonaccesskeyid
+ aws_secret_access_key: myamazonsecretaccesskey
+ YAML
+
+ require "#{app_path}/config/environment"
+ assert_equal 'myamazonaccesskeyid', app.secrets.aws_access_key_id
+ assert_equal 'myamazonsecretaccesskey', app.secrets.aws_secret_access_key
+ end
+
+ test "blank config/secrets.yml does not crash the loading process" do
+ app_file 'config/secrets.yml', <<-YAML
+ YAML
+ require "#{app_path}/config/environment"
+
+ assert_nil app.secrets.not_defined
+ end
+
test "protect from forgery is the default in a new app" do
make_basic_app
@@ -284,7 +366,7 @@ module ApplicationTests
test "default method for update can be changed" do
app_file 'app/models/post.rb', <<-RUBY
class Post
- extend ActiveModel::Naming
+ include ActiveModel::Model
def to_key; [1]; end
def persisted?; true; end
end
@@ -384,6 +466,32 @@ module ApplicationTests
assert_equal [::MyMailInterceptor, ::MyOtherMailInterceptor], ::Mail.send(:class_variable_get, "@@delivery_interceptors")
end
+ test "registers preview interceptors with ActionMailer" do
+ add_to_config <<-RUBY
+ config.action_mailer.preview_interceptors = MyPreviewMailInterceptor
+ RUBY
+
+ require "#{app_path}/config/environment"
+ require "mail"
+
+ _ = ActionMailer::Base
+
+ assert_equal [::MyPreviewMailInterceptor], ActionMailer::Base.preview_interceptors
+ end
+
+ test "registers multiple preview interceptors with ActionMailer" do
+ add_to_config <<-RUBY
+ config.action_mailer.preview_interceptors = [MyPreviewMailInterceptor, "MyOtherPreviewMailInterceptor"]
+ RUBY
+
+ require "#{app_path}/config/environment"
+ require "mail"
+
+ _ = ActionMailer::Base
+
+ assert_equal [MyPreviewMailInterceptor, MyOtherPreviewMailInterceptor], ActionMailer::Base.preview_interceptors
+ end
+
test "registers observers with ActionMailer" do
add_to_config <<-RUBY
config.action_mailer.observers = MyMailObserver
@@ -413,7 +521,7 @@ module ApplicationTests
test "valid timezone is setup correctly" do
add_to_config <<-RUBY
config.root = "#{app_path}"
- config.time_zone = "Wellington"
+ config.time_zone = "Wellington"
RUBY
require "#{app_path}/config/environment"
@@ -424,7 +532,7 @@ module ApplicationTests
test "raises when an invalid timezone is defined in the config" do
add_to_config <<-RUBY
config.root = "#{app_path}"
- config.time_zone = "That big hill over yonder hill"
+ config.time_zone = "That big hill over yonder hill"
RUBY
assert_raise(ArgumentError) do
@@ -435,7 +543,7 @@ module ApplicationTests
test "valid beginning of week is setup correctly" do
add_to_config <<-RUBY
config.root = "#{app_path}"
- config.beginning_of_week = :wednesday
+ config.beginning_of_week = :wednesday
RUBY
require "#{app_path}/config/environment"
@@ -446,7 +554,7 @@ module ApplicationTests
test "raises when an invalid beginning of week is defined in the config" do
add_to_config <<-RUBY
config.root = "#{app_path}"
- config.beginning_of_week = :invalid
+ config.beginning_of_week = :invalid
RUBY
assert_raise(ArgumentError) do
@@ -459,7 +567,7 @@ module ApplicationTests
require "#{app_path}/config/environment"
require 'action_view/base'
- assert ActionView::Resolver.caching?
+ assert_equal true, ActionView::Resolver.caching?
end
test "config.action_view.cache_template_loading without cache_classes default" do
@@ -467,7 +575,7 @@ module ApplicationTests
require "#{app_path}/config/environment"
require 'action_view/base'
- assert !ActionView::Resolver.caching?
+ assert_equal false, ActionView::Resolver.caching?
end
test "config.action_view.cache_template_loading = false" do
@@ -478,7 +586,7 @@ module ApplicationTests
require "#{app_path}/config/environment"
require 'action_view/base'
- assert !ActionView::Resolver.caching?
+ assert_equal false, ActionView::Resolver.caching?
end
test "config.action_view.cache_template_loading = true" do
@@ -489,7 +597,21 @@ module ApplicationTests
require "#{app_path}/config/environment"
require 'action_view/base'
- assert ActionView::Resolver.caching?
+ assert_equal true, ActionView::Resolver.caching?
+ end
+
+ test "config.action_view.cache_template_loading with cache_classes in an environment" do
+ build_app(initializers: true)
+ add_to_env_config "development", "config.cache_classes = false"
+
+ # These requires are to emulate an engine loading Action View before the application
+ require 'action_view'
+ require 'action_view/railtie'
+ require 'action_view/base'
+
+ require "#{app_path}/config/environment"
+
+ assert_equal false, ActionView::Resolver.caching?
end
test "config.action_dispatch.show_exceptions is sent in env" do
@@ -686,5 +808,124 @@ module ApplicationTests
assert_not Rails.configuration.respond_to?(:method_missing)
assert Rails.configuration.respond_to?(:method_missing, true)
end
+
+ test "config.active_record.dump_schema_after_migration is false on production" do
+ build_app
+ ENV["RAILS_ENV"] = "production"
+
+ require "#{app_path}/config/environment"
+
+ assert_not ActiveRecord::Base.dump_schema_after_migration
+ end
+
+ test "config.active_record.dump_schema_after_migration is true by default on development" do
+ ENV["RAILS_ENV"] = "development"
+
+ require "#{app_path}/config/environment"
+
+ assert ActiveRecord::Base.dump_schema_after_migration
+ end
+
+ test "config.annotations wrapping SourceAnnotationExtractor::Annotation class" do
+ make_basic_app do |app|
+ app.config.annotations.register_extensions("coffee") do |tag|
+ /#\s*(#{tag}):?\s*(.*)$/
+ end
+ end
+
+ assert_not_nil SourceAnnotationExtractor::Annotation.extensions[/\.(coffee)$/]
+ end
+
+ test "rake_tasks block works at instance level" do
+ $ran_block = false
+
+ app_file "config/environments/development.rb", <<-RUBY
+ Rails.application.configure do
+ rake_tasks do
+ $ran_block = true
+ end
+ end
+ RUBY
+
+ require "#{app_path}/config/environment"
+
+ assert !$ran_block
+ require 'rake'
+ require 'rake/testtask'
+ require 'rdoc/task'
+
+ Rails.application.load_tasks
+ assert $ran_block
+ end
+
+ test "generators block works at instance level" do
+ $ran_block = false
+
+ app_file "config/environments/development.rb", <<-RUBY
+ Rails.application.configure do
+ generators do
+ $ran_block = true
+ end
+ end
+ RUBY
+
+ require "#{app_path}/config/environment"
+
+ assert !$ran_block
+ Rails.application.load_generators
+ assert $ran_block
+ end
+
+ test "console block works at instance level" do
+ $ran_block = false
+
+ app_file "config/environments/development.rb", <<-RUBY
+ Rails.application.configure do
+ console do
+ $ran_block = true
+ end
+ end
+ RUBY
+
+ require "#{app_path}/config/environment"
+
+ assert !$ran_block
+ Rails.application.load_console
+ assert $ran_block
+ end
+
+ test "runner block works at instance level" do
+ $ran_block = false
+
+ app_file "config/environments/development.rb", <<-RUBY
+ Rails.application.configure do
+ runner do
+ $ran_block = true
+ end
+ end
+ RUBY
+
+ require "#{app_path}/config/environment"
+
+ assert !$ran_block
+ Rails.application.load_runner
+ assert $ran_block
+ end
+
+ test "loading the first existing database configuration available" do
+ app_file 'config/environments/development.rb', <<-RUBY
+
+ Rails.application.configure do
+ config.paths.add 'config/database', with: 'config/nonexistant.yml'
+ config.paths['config/database'] << 'config/database.yml'
+ end
+ RUBY
+
+ require "#{app_path}/config/environment"
+
+ db_config = Rails.application.config.database_configuration
+
+ assert db_config.is_a?(Hash)
+ end
end
end
diff --git a/railties/test/application/initializers/frameworks_test.rb b/railties/test/application/initializers/frameworks_test.rb
index 83104acf3c..8e76bf27f3 100644
--- a/railties/test/application/initializers/frameworks_test.rb
+++ b/railties/test/application/initializers/frameworks_test.rb
@@ -217,7 +217,7 @@ module ApplicationTests
orig_database_url = ENV.delete("DATABASE_URL")
orig_rails_env, Rails.env = Rails.env, 'development'
database_url_db_name = "db/database_url_db.sqlite3"
- ENV["DATABASE_URL"] = "sqlite3://:@localhost/#{database_url_db_name}"
+ ENV["DATABASE_URL"] = "sqlite3:#{database_url_db_name}"
ActiveRecord::Base.establish_connection
assert ActiveRecord::Base.connection
assert_match(/#{database_url_db_name}/, ActiveRecord::Base.connection_config[:database])
diff --git a/railties/test/application/initializers/i18n_test.rb b/railties/test/application/initializers/i18n_test.rb
index 97df073ec7..bc34897cdf 100644
--- a/railties/test/application/initializers/i18n_test.rb
+++ b/railties/test/application/initializers/i18n_test.rb
@@ -183,5 +183,50 @@ en:
load_app
assert_fallbacks ca: [:ca, :"es-ES", :es, :'en-US', :en]
end
+
+ test "config.i18n.enforce_available_locales is set to true by default and avoids I18n warnings" do
+ add_to_config <<-RUBY
+ config.i18n.default_locale = :it
+ RUBY
+
+ output = capture(:stderr) { load_app }
+ assert_no_match %r{deprecated.*enforce_available_locales}, output
+ assert_equal true, I18n.enforce_available_locales
+
+ assert_raise I18n::InvalidLocale do
+ I18n.locale = :es
+ end
+ end
+
+ test "disable config.i18n.enforce_available_locales" do
+ add_to_config <<-RUBY
+ config.i18n.enforce_available_locales = false
+ config.i18n.default_locale = :fr
+ RUBY
+
+ output = capture(:stderr) { load_app }
+ assert_no_match %r{deprecated.*enforce_available_locales}, output
+ assert_equal false, I18n.enforce_available_locales
+
+ assert_nothing_raised do
+ I18n.locale = :es
+ end
+ end
+
+ test "default config.i18n.enforce_available_locales does not override I18n.enforce_available_locales" do
+ I18n.enforce_available_locales = false
+
+ add_to_config <<-RUBY
+ config.i18n.default_locale = :fr
+ RUBY
+
+ output = capture(:stderr) { load_app }
+ assert_no_match %r{deprecated.*enforce_available_locales}, output
+ assert_equal false, I18n.enforce_available_locales
+
+ assert_nothing_raised do
+ I18n.locale = :es
+ end
+ end
end
end
diff --git a/railties/test/application/initializers/load_path_test.rb b/railties/test/application/initializers/load_path_test.rb
index b36628ee37..cd05956356 100644
--- a/railties/test/application/initializers/load_path_test.rb
+++ b/railties/test/application/initializers/load_path_test.rb
@@ -71,6 +71,20 @@ module ApplicationTests
assert Zoo
end
+ test "eager loading accepts Pathnames" do
+ app_file "lib/foo.rb", <<-RUBY
+ module Foo; end
+ RUBY
+
+ add_to_config <<-RUBY
+ config.eager_load = true
+ config.eager_load_paths << Pathname.new("#{app_path}/lib")
+ RUBY
+
+ require "#{app_path}/config/environment"
+ assert Foo
+ end
+
test "load environment with global" do
$initialize_test_set_from_env = nil
app_file "config/environments/development.rb", <<-RUBY
diff --git a/railties/test/application/initializers/notifications_test.rb b/railties/test/application/initializers/notifications_test.rb
index baae6fd928..95655b74cf 100644
--- a/railties/test/application/initializers/notifications_test.rb
+++ b/railties/test/application/initializers/notifications_test.rb
@@ -39,5 +39,18 @@ module ApplicationTests
assert_equal 1, logger.logged(:debug).size
assert_match(/SHOW tables/, logger.logged(:debug).last)
end
+
+ test 'rails load_config_initializer event is instrumented' do
+ app_file 'config/initializers/foo.rb', ''
+
+ events = []
+ callback = ->(*_) { events << _ }
+ ActiveSupport::Notifications.subscribed(callback, 'load_config_initializer.railties') do
+ app
+ end
+
+ assert_equal %w[load_config_initializer.railties], events.map(&:first)
+ assert_includes events.first.last[:initializer], 'config/initializers/foo.rb'
+ end
end
end
diff --git a/railties/test/application/mailer_previews_test.rb b/railties/test/application/mailer_previews_test.rb
new file mode 100644
index 0000000000..c588fd7012
--- /dev/null
+++ b/railties/test/application/mailer_previews_test.rb
@@ -0,0 +1,428 @@
+require 'isolation/abstract_unit'
+require 'rack/test'
+module ApplicationTests
+ class MailerPreviewsTest < ActiveSupport::TestCase
+ include ActiveSupport::Testing::Isolation
+ include Rack::Test::Methods
+
+ def setup
+ build_app
+ boot_rails
+ end
+
+ def teardown
+ teardown_app
+ end
+
+ test "/rails/mailers is accessible in development" do
+ app("development")
+ get "/rails/mailers"
+ assert_equal 200, last_response.status
+ end
+
+ test "/rails/mailers is not accessible in production" do
+ app("production")
+ get "/rails/mailers"
+ assert_equal 404, last_response.status
+ end
+
+ test "mailer previews are loaded from the default preview_path" do
+ mailer 'notifier', <<-RUBY
+ class Notifier < ActionMailer::Base
+ default from: "from@example.com"
+
+ def foo
+ mail to: "to@example.org"
+ end
+ end
+ RUBY
+
+ text_template 'notifier/foo', <<-RUBY
+ Hello, World!
+ RUBY
+
+ mailer_preview 'notifier', <<-RUBY
+ class NotifierPreview < ActionMailer::Preview
+ def foo
+ Notifier.foo
+ end
+ end
+ RUBY
+
+ app('development')
+
+ get "/rails/mailers"
+ assert_match '<h3><a href="/rails/mailers/notifier">Notifier</a></h3>', last_response.body
+ assert_match '<li><a href="/rails/mailers/notifier/foo">foo</a></li>', last_response.body
+ end
+
+ test "mailer previews are loaded from a custom preview_path" do
+ add_to_config "config.action_mailer.preview_path = '#{app_path}/lib/mailer_previews'"
+
+ mailer 'notifier', <<-RUBY
+ class Notifier < ActionMailer::Base
+ default from: "from@example.com"
+
+ def foo
+ mail to: "to@example.org"
+ end
+ end
+ RUBY
+
+ text_template 'notifier/foo', <<-RUBY
+ Hello, World!
+ RUBY
+
+ app_file 'lib/mailer_previews/notifier_preview.rb', <<-RUBY
+ class NotifierPreview < ActionMailer::Preview
+ def foo
+ Notifier.foo
+ end
+ end
+ RUBY
+
+ app('development')
+
+ get "/rails/mailers"
+ assert_match '<h3><a href="/rails/mailers/notifier">Notifier</a></h3>', last_response.body
+ assert_match '<li><a href="/rails/mailers/notifier/foo">foo</a></li>', last_response.body
+ end
+
+ test "mailer previews are reloaded across requests" do
+ app('development')
+
+ get "/rails/mailers"
+ assert_no_match '<h3><a href="/rails/mailers/notifier">Notifier</a></h3>', last_response.body
+
+ mailer 'notifier', <<-RUBY
+ class Notifier < ActionMailer::Base
+ default from: "from@example.com"
+
+ def foo
+ mail to: "to@example.org"
+ end
+ end
+ RUBY
+
+ text_template 'notifier/foo', <<-RUBY
+ Hello, World!
+ RUBY
+
+ mailer_preview 'notifier', <<-RUBY
+ class NotifierPreview < ActionMailer::Preview
+ def foo
+ Notifier.foo
+ end
+ end
+ RUBY
+
+ get "/rails/mailers"
+ assert_match '<h3><a href="/rails/mailers/notifier">Notifier</a></h3>', last_response.body
+
+ remove_file 'test/mailers/previews/notifier_preview.rb'
+ sleep(1)
+
+ get "/rails/mailers"
+ assert_no_match '<h3><a href="/rails/mailers/notifier">Notifier</a></h3>', last_response.body
+ end
+
+ test "mailer preview actions are added and removed" do
+ mailer 'notifier', <<-RUBY
+ class Notifier < ActionMailer::Base
+ default from: "from@example.com"
+
+ def foo
+ mail to: "to@example.org"
+ end
+ end
+ RUBY
+
+ text_template 'notifier/foo', <<-RUBY
+ Hello, World!
+ RUBY
+
+ mailer_preview 'notifier', <<-RUBY
+ class NotifierPreview < ActionMailer::Preview
+ def foo
+ Notifier.foo
+ end
+ end
+ RUBY
+
+ app('development')
+
+ get "/rails/mailers"
+ assert_match '<h3><a href="/rails/mailers/notifier">Notifier</a></h3>', last_response.body
+ assert_match '<li><a href="/rails/mailers/notifier/foo">foo</a></li>', last_response.body
+ assert_no_match '<li><a href="/rails/mailers/notifier/bar">bar</a></li>', last_response.body
+
+ mailer 'notifier', <<-RUBY
+ class Notifier < ActionMailer::Base
+ default from: "from@example.com"
+
+ def foo
+ mail to: "to@example.org"
+ end
+
+ def bar
+ mail to: "to@example.net"
+ end
+ end
+ RUBY
+
+ text_template 'notifier/foo', <<-RUBY
+ Hello, World!
+ RUBY
+
+ text_template 'notifier/bar', <<-RUBY
+ Goodbye, World!
+ RUBY
+
+ mailer_preview 'notifier', <<-RUBY
+ class NotifierPreview < ActionMailer::Preview
+ def foo
+ Notifier.foo
+ end
+
+ def bar
+ Notifier.bar
+ end
+ end
+ RUBY
+
+ sleep(1)
+
+ get "/rails/mailers"
+ assert_match '<h3><a href="/rails/mailers/notifier">Notifier</a></h3>', last_response.body
+ assert_match '<li><a href="/rails/mailers/notifier/foo">foo</a></li>', last_response.body
+ assert_match '<li><a href="/rails/mailers/notifier/bar">bar</a></li>', last_response.body
+
+ mailer 'notifier', <<-RUBY
+ class Notifier < ActionMailer::Base
+ default from: "from@example.com"
+
+ def foo
+ mail to: "to@example.org"
+ end
+ end
+ RUBY
+
+ remove_file 'app/views/notifier/bar.text.erb'
+
+ mailer_preview 'notifier', <<-RUBY
+ class NotifierPreview < ActionMailer::Preview
+ def foo
+ Notifier.foo
+ end
+ end
+ RUBY
+
+ sleep(1)
+
+ get "/rails/mailers"
+ assert_match '<h3><a href="/rails/mailers/notifier">Notifier</a></h3>', last_response.body
+ assert_match '<li><a href="/rails/mailers/notifier/foo">foo</a></li>', last_response.body
+ assert_no_match '<li><a href="/rails/mailers/notifier/bar">bar</a></li>', last_response.body
+ end
+
+ test "mailer previews are reloaded from a custom preview_path" do
+ add_to_config "config.action_mailer.preview_path = '#{app_path}/lib/mailer_previews'"
+
+ app('development')
+
+ get "/rails/mailers"
+ assert_no_match '<h3><a href="/rails/mailers/notifier">Notifier</a></h3>', last_response.body
+
+ mailer 'notifier', <<-RUBY
+ class Notifier < ActionMailer::Base
+ default from: "from@example.com"
+
+ def foo
+ mail to: "to@example.org"
+ end
+ end
+ RUBY
+
+ text_template 'notifier/foo', <<-RUBY
+ Hello, World!
+ RUBY
+
+ app_file 'lib/mailer_previews/notifier_preview.rb', <<-RUBY
+ class NotifierPreview < ActionMailer::Preview
+ def foo
+ Notifier.foo
+ end
+ end
+ RUBY
+
+ get "/rails/mailers"
+ assert_match '<h3><a href="/rails/mailers/notifier">Notifier</a></h3>', last_response.body
+
+ remove_file 'lib/mailer_previews/notifier_preview.rb'
+ sleep(1)
+
+ get "/rails/mailers"
+ assert_no_match '<h3><a href="/rails/mailers/notifier">Notifier</a></h3>', last_response.body
+ end
+
+ test "mailer preview not found" do
+ app('development')
+ get "/rails/mailers/notifier"
+ assert last_response.not_found?
+ assert_match "Mailer preview &#39;notifier&#39; not found", last_response.body
+ end
+
+ test "mailer preview email not found" do
+ mailer 'notifier', <<-RUBY
+ class Notifier < ActionMailer::Base
+ default from: "from@example.com"
+
+ def foo
+ mail to: "to@example.org"
+ end
+ end
+ RUBY
+
+ text_template 'notifier/foo', <<-RUBY
+ Hello, World!
+ RUBY
+
+ mailer_preview 'notifier', <<-RUBY
+ class NotifierPreview < ActionMailer::Preview
+ def foo
+ Notifier.foo
+ end
+ end
+ RUBY
+
+ app('development')
+
+ get "/rails/mailers/notifier/bar"
+ assert last_response.not_found?
+ assert_match "Email &#39;bar&#39; not found in NotifierPreview", last_response.body
+ end
+
+ test "mailer preview email part not found" do
+ mailer 'notifier', <<-RUBY
+ class Notifier < ActionMailer::Base
+ default from: "from@example.com"
+
+ def foo
+ mail to: "to@example.org"
+ end
+ end
+ RUBY
+
+ text_template 'notifier/foo', <<-RUBY
+ Hello, World!
+ RUBY
+
+ mailer_preview 'notifier', <<-RUBY
+ class NotifierPreview < ActionMailer::Preview
+ def foo
+ Notifier.foo
+ end
+ end
+ RUBY
+
+ app('development')
+
+ get "/rails/mailers/notifier/foo?part=text%2Fhtml"
+ assert last_response.not_found?
+ assert_match "Email part &#39;text/html&#39; not found in NotifierPreview#foo", last_response.body
+ end
+
+ test "message header uses full display names" do
+ mailer 'notifier', <<-RUBY
+ class Notifier < ActionMailer::Base
+ default from: "Ruby on Rails <core@rubyonrails.org>"
+
+ def foo
+ mail to: "Andrew White <andyw@pixeltrix.co.uk>",
+ cc: "David Heinemeier Hansson <david@heinemeierhansson.com>"
+ end
+ end
+ RUBY
+
+ text_template 'notifier/foo', <<-RUBY
+ Hello, World!
+ RUBY
+
+ mailer_preview 'notifier', <<-RUBY
+ class NotifierPreview < ActionMailer::Preview
+ def foo
+ Notifier.foo
+ end
+ end
+ RUBY
+
+ app('development')
+
+ get "/rails/mailers/notifier/foo"
+ assert_equal 200, last_response.status
+ assert_match "Ruby on Rails &lt;core@rubyonrails.org&gt;", last_response.body
+ assert_match "Andrew White &lt;andyw@pixeltrix.co.uk&gt;", last_response.body
+ assert_match "David Heinemeier Hansson &lt;david@heinemeierhansson.com&gt;", last_response.body
+ end
+
+ test "part menu selects correct option" do
+ mailer 'notifier', <<-RUBY
+ class Notifier < ActionMailer::Base
+ default from: "from@example.com"
+
+ def foo
+ mail to: "to@example.org"
+ end
+ end
+ RUBY
+
+ html_template 'notifier/foo', <<-RUBY
+ <p>Hello, World!</p>
+ RUBY
+
+ text_template 'notifier/foo', <<-RUBY
+ Hello, World!
+ RUBY
+
+ mailer_preview 'notifier', <<-RUBY
+ class NotifierPreview < ActionMailer::Preview
+ def foo
+ Notifier.foo
+ end
+ end
+ RUBY
+
+ app('development')
+
+ get "/rails/mailers/notifier/foo.html"
+ assert_equal 200, last_response.status
+ assert_match '<option selected value="?part=text%2Fhtml">View as HTML email</option>', last_response.body
+
+ get "/rails/mailers/notifier/foo.txt"
+ assert_equal 200, last_response.status
+ assert_match '<option selected value="?part=text%2Fplain">View as plain-text email</option>', last_response.body
+ end
+
+ private
+ def build_app
+ super
+ app_file "config/routes.rb", "Rails.application.routes.draw do; end"
+ end
+
+ def mailer(name, contents)
+ app_file("app/mailers/#{name}.rb", contents)
+ end
+
+ def mailer_preview(name, contents)
+ app_file("test/mailers/previews/#{name}_preview.rb", contents)
+ end
+
+ def html_template(name, contents)
+ app_file("app/views/#{name}.html.erb", contents)
+ end
+
+ def text_template(name, contents)
+ app_file("app/views/#{name}.text.erb", contents)
+ end
+ end
+end
diff --git a/railties/test/application/middleware/remote_ip_test.rb b/railties/test/application/middleware/remote_ip_test.rb
index 91c5807379..946b82eeb3 100644
--- a/railties/test/application/middleware/remote_ip_test.rb
+++ b/railties/test/application/middleware/remote_ip_test.rb
@@ -33,6 +33,16 @@ module ApplicationTests
end
end
+ test "works with both headers individually" do
+ make_basic_app
+ assert_nothing_raised(ActionDispatch::RemoteIp::IpSpoofAttackError) do
+ assert_equal "1.1.1.1", remote_ip("HTTP_X_FORWARDED_FOR" => "1.1.1.1")
+ end
+ assert_nothing_raised(ActionDispatch::RemoteIp::IpSpoofAttackError) do
+ assert_equal "1.1.1.2", remote_ip("HTTP_CLIENT_IP" => "1.1.1.2")
+ end
+ end
+
test "can disable IP spoofing check" do
make_basic_app do |app|
app.config.action_dispatch.ip_spoofing_check = false
diff --git a/railties/test/application/middleware/session_test.rb b/railties/test/application/middleware/session_test.rb
index 14a56176f5..31a64c2f5a 100644
--- a/railties/test/application/middleware/session_test.rb
+++ b/railties/test/application/middleware/session_test.rb
@@ -318,7 +318,7 @@ module ApplicationTests
add_to_config <<-RUBY
config.secret_token = "3b7cd727ee24e8444053437c36cc66c4"
- config.secret_key_base = nil
+ secrets.secret_key_base = nil
RUBY
require "#{app_path}/config/environment"
diff --git a/railties/test/application/middleware_test.rb b/railties/test/application/middleware_test.rb
index 31a35a09bb..1557b90d27 100644
--- a/railties/test/application/middleware_test.rb
+++ b/railties/test/application/middleware_test.rb
@@ -61,7 +61,7 @@ module ApplicationTests
boot!
- assert_equal "Rack::Cache", middleware.first
+ assert middleware.include?("Rack::Cache")
end
test "ActiveRecord::Migration::CheckPending is present when active_record.migration_error is set to :page_load" do
@@ -144,6 +144,12 @@ module ApplicationTests
assert_equal "Rack::Config", middleware.second
end
+ test 'unshift middleware' do
+ add_to_config 'config.middleware.unshift Rack::Config'
+ boot!
+ assert_equal 'Rack::Config', middleware.first
+ end
+
test "Rails.cache does not respond to middleware" do
add_to_config "config.cache_store = :memory_store"
boot!
diff --git a/railties/test/application/multiple_applications_test.rb b/railties/test/application/multiple_applications_test.rb
index 5bfea599e0..f8d8a673ae 100644
--- a/railties/test/application/multiple_applications_test.rb
+++ b/railties/test/application/multiple_applications_test.rb
@@ -21,6 +21,12 @@ module ApplicationTests
assert_equal Rails.application.config.secret_key_base, clone.config.secret_key_base, "The base secret key on the config should be the same"
end
+ def test_inheriting_multiple_times_from_application
+ new_application_class = Class.new(Rails::Application)
+
+ assert_not_equal Rails.application.object_id, new_application_class.instance.object_id
+ end
+
def test_initialization_of_multiple_copies_of_same_application
application1 = AppTemplate::Application.new
application2 = AppTemplate::Application.new
@@ -116,6 +122,26 @@ module ApplicationTests
assert_equal 3, $run_count, "There should have been three initializers that incremented the count"
end
+ def test_consoles_run_on_different_applications_go_to_the_same_class
+ $run_count = 0
+ AppTemplate::Application.console { $run_count += 1 }
+ AppTemplate::Application.new.console { $run_count += 1 }
+
+ assert_equal 0, $run_count, "Without loading the consoles, the count should be 0"
+ Rails.application.load_console
+ assert_equal 2, $run_count, "There should have been two consoles that increment the count"
+ end
+
+ def test_generators_run_on_different_applications_go_to_the_same_class
+ $run_count = 0
+ AppTemplate::Application.generators { $run_count += 1 }
+ AppTemplate::Application.new.generators { $run_count += 1 }
+
+ assert_equal 0, $run_count, "Without loading the generators, the count should be 0"
+ Rails.application.load_generators
+ assert_equal 2, $run_count, "There should have been two generators that increment the count"
+ end
+
def test_runners_run_on_different_applications_go_to_the_same_class
$run_count = 0
AppTemplate::Application.runner { $run_count += 1 }
diff --git a/railties/test/application/rake/dbs_test.rb b/railties/test/application/rake/dbs_test.rb
index 9e711f25bd..15414db00f 100644
--- a/railties/test/application/rake/dbs_test.rb
+++ b/railties/test/application/rake/dbs_test.rb
@@ -1,4 +1,5 @@
require "isolation/abstract_unit"
+require "active_support/core_ext/string/strip"
module ApplicationTests
module RakeTests
@@ -20,62 +21,53 @@ module ApplicationTests
end
def set_database_url
- ENV['DATABASE_URL'] = "sqlite3://:@localhost/#{database_url_db_name}"
+ ENV['DATABASE_URL'] = "sqlite3:#{database_url_db_name}"
# ensure it's using the DATABASE_URL
FileUtils.rm_rf("#{app_path}/config/database.yml")
end
- def expected
- @expected ||= {}
- end
-
- def db_create_and_drop
+ def db_create_and_drop(expected_database)
Dir.chdir(app_path) do
output = `bundle exec rake db:create`
- assert_equal output, ""
- assert File.exists?(expected[:database])
- assert_equal expected[:database],
- ActiveRecord::Base.connection_config[:database]
+ assert_empty output
+ assert File.exist?(expected_database)
+ assert_equal expected_database, ActiveRecord::Base.connection_config[:database]
output = `bundle exec rake db:drop`
- assert_equal output, ""
- assert !File.exists?(expected[:database])
+ assert_empty output
+ assert !File.exist?(expected_database)
end
end
test 'db:create and db:drop without database url' do
require "#{app_path}/config/environment"
- expected[:database] = ActiveRecord::Base.configurations[Rails.env]['database']
- db_create_and_drop
- end
+ db_create_and_drop ActiveRecord::Base.configurations[Rails.env]['database']
+ end
test 'db:create and db:drop with database url' do
require "#{app_path}/config/environment"
set_database_url
- expected[:database] = database_url_db_name
- db_create_and_drop
+ db_create_and_drop database_url_db_name
end
- def db_migrate_and_status
+ def db_migrate_and_status(expected_database)
Dir.chdir(app_path) do
`rails generate model book title:string;
bundle exec rake db:migrate`
output = `bundle exec rake db:migrate:status`
- assert_match(/database:\s+\S+#{expected[:database]}/, output)
+ assert_match(%r{database:\s+\S*#{Regexp.escape(expected_database)}}, output)
assert_match(/up\s+\d{14}\s+Create books/, output)
end
end
test 'db:migrate and db:migrate:status without database_url' do
require "#{app_path}/config/environment"
- expected[:database] = ActiveRecord::Base.configurations[Rails.env]['database']
- db_migrate_and_status
+ db_migrate_and_status ActiveRecord::Base.configurations[Rails.env]['database']
end
test 'db:migrate and db:migrate:status with database_url' do
require "#{app_path}/config/environment"
set_database_url
- expected[:database] = database_url_db_name
- db_migrate_and_status
+ db_migrate_and_status database_url_db_name
end
def db_schema_dump
@@ -96,12 +88,11 @@ module ApplicationTests
db_schema_dump
end
- def db_fixtures_load
+ def db_fixtures_load(expected_database)
Dir.chdir(app_path) do
`rails generate model book title:string;
bundle exec rake db:migrate db:fixtures:load`
- assert_match(/#{expected[:database]}/,
- ActiveRecord::Base.connection_config[:database])
+ assert_match expected_database, ActiveRecord::Base.connection_config[:database]
require "#{app_path}/app/models/book"
assert_equal 2, Book.count
end
@@ -109,43 +100,50 @@ module ApplicationTests
test 'db:fixtures:load without database_url' do
require "#{app_path}/config/environment"
- expected[:database] = ActiveRecord::Base.configurations[Rails.env]['database']
- db_fixtures_load
+ db_fixtures_load ActiveRecord::Base.configurations[Rails.env]['database']
end
test 'db:fixtures:load with database_url' do
require "#{app_path}/config/environment"
set_database_url
- expected[:database] = database_url_db_name
- db_fixtures_load
+ db_fixtures_load database_url_db_name
end
- def db_structure_dump_and_load
+ def db_structure_dump_and_load(expected_database)
Dir.chdir(app_path) do
`rails generate model book title:string;
bundle exec rake db:migrate db:structure:dump`
structure_dump = File.read("db/structure.sql")
assert_match(/CREATE TABLE \"books\"/, structure_dump)
- `bundle exec rake db:drop db:structure:load`
- assert_match(/#{expected[:database]}/,
- ActiveRecord::Base.connection_config[:database])
+ `bundle exec rake environment db:drop db:structure:load`
+ assert_match expected_database, ActiveRecord::Base.connection_config[:database]
require "#{app_path}/app/models/book"
#if structure is not loaded correctly, exception would be raised
- assert Book.count, 0
+ assert_equal 0, Book.count
end
end
test 'db:structure:dump and db:structure:load without database_url' do
require "#{app_path}/config/environment"
- expected[:database] = ActiveRecord::Base.configurations[Rails.env]['database']
- db_structure_dump_and_load
+ db_structure_dump_and_load ActiveRecord::Base.configurations[Rails.env]['database']
end
test 'db:structure:dump and db:structure:load with database_url' do
require "#{app_path}/config/environment"
set_database_url
- expected[:database] = database_url_db_name
- db_structure_dump_and_load
+ db_structure_dump_and_load database_url_db_name
+ end
+
+ test 'db:structure:dump does not dump schema information when no migrations are used' do
+ Dir.chdir(app_path) do
+ # create table without migrations
+ `bundle exec rails runner 'ActiveRecord::Base.connection.create_table(:posts) {|t| t.string :title }'`
+
+ stderr_output = capture(:stderr) { `bundle exec rake db:structure:dump` }
+ assert_empty stderr_output
+ structure_dump = File.read("db/structure.sql")
+ assert_match(/CREATE TABLE \"posts\"/, structure_dump)
+ end
end
def db_test_load_structure
@@ -153,12 +151,12 @@ module ApplicationTests
`rails generate model book title:string;
bundle exec rake db:migrate db:structure:dump db:test:load_structure`
ActiveRecord::Base.configurations = Rails.application.config.database_configuration
- ActiveRecord::Base.establish_connection 'test'
+ ActiveRecord::Base.establish_connection :test
require "#{app_path}/app/models/book"
#if structure is not loaded correctly, exception would be raised
- assert Book.count, 0
- assert_match(/#{ActiveRecord::Base.configurations['test']['database']}/,
- ActiveRecord::Base.connection_config[:database])
+ assert_equal 0, Book.count
+ assert_match ActiveRecord::Base.configurations['test']['database'],
+ ActiveRecord::Base.connection_config[:database]
end
end
@@ -166,6 +164,15 @@ module ApplicationTests
require "#{app_path}/config/environment"
db_test_load_structure
end
+
+ test 'db:test deprecation' do
+ require "#{app_path}/config/environment"
+ Dir.chdir(app_path) do
+ output = `bundle exec rake db:migrate db:test:prepare 2>&1`
+ assert_equal "WARNING: db:test:prepare is deprecated. The Rails test helper now maintains " \
+ "your test schema automatically, see the release notes for details.\n", output
+ end
+ end
end
end
end
diff --git a/railties/test/application/rake/migrations_test.rb b/railties/test/application/rake/migrations_test.rb
index 33c753868c..a3819b93b2 100644
--- a/railties/test/application/rake/migrations_test.rb
+++ b/railties/test/application/rake/migrations_test.rb
@@ -58,7 +58,7 @@ module ApplicationTests
end
test 'migration status when schema migrations table is not present' do
- output = Dir.chdir(app_path){ `rake db:migrate:status` }
+ output = Dir.chdir(app_path){ `rake db:migrate:status 2>&1` }
assert_equal "Schema migrations table does not exist yet.\n", output
end
@@ -153,6 +153,52 @@ module ApplicationTests
assert_match(/up\s+\d{3,}\s+Add email to users/, output)
end
end
+
+ test 'schema generation when dump_schema_after_migration is set' do
+ add_to_config('config.active_record.dump_schema_after_migration = false')
+
+ Dir.chdir(app_path) do
+ `rails generate model book title:string;
+ bundle exec rake db:migrate`
+
+ assert !File.exist?("db/schema.rb")
+ end
+
+ add_to_config('config.active_record.dump_schema_after_migration = true')
+
+ Dir.chdir(app_path) do
+ `rails generate model author name:string;
+ bundle exec rake db:migrate`
+
+ structure_dump = File.read("db/schema.rb")
+ assert_match(/create_table "authors"/, structure_dump)
+ end
+ end
+
+ test 'default schema generation after migration' do
+ Dir.chdir(app_path) do
+ `rails generate model book title:string;
+ bundle exec rake db:migrate`
+
+ structure_dump = File.read("db/schema.rb")
+ assert_match(/create_table "books"/, structure_dump)
+ end
+ end
+
+ test 'test migration status migrated file is deleted' do
+ Dir.chdir(app_path) do
+ `rails generate model user username:string password:string;
+ rails generate migration add_email_to_users email:string;
+ rake db:migrate
+ rm db/migrate/*email*.rb`
+
+ output = `rake db:migrate:status`
+ File.write('test.txt', output)
+
+ assert_match(/up\s+\d{14}\s+Create users/, output)
+ assert_match(/up\s+\d{14}\s+\** NO FILE \**/, output)
+ end
+ end
end
end
end
diff --git a/railties/test/application/rake/notes_test.rb b/railties/test/application/rake/notes_test.rb
index 01d751e822..95087bf29f 100644
--- a/railties/test/application/rake/notes_test.rb
+++ b/railties/test/application/rake/notes_test.rb
@@ -1,4 +1,5 @@
require "isolation/abstract_unit"
+require 'rails/source_annotation_extractor'
module ApplicationTests
module RakeTests
@@ -18,46 +19,27 @@ module ApplicationTests
test 'notes finds notes for certain file_types' do
app_file "app/views/home/index.html.erb", "<% # TODO: note in erb %>"
- app_file "app/views/home/index.html.haml", "-# TODO: note in haml"
- app_file "app/views/home/index.html.slim", "/ TODO: note in slim"
- app_file "app/assets/javascripts/application.js.coffee", "# TODO: note in coffee"
app_file "app/assets/javascripts/application.js", "// TODO: note in js"
app_file "app/assets/stylesheets/application.css", "// TODO: note in css"
- app_file "app/assets/stylesheets/application.css.scss", "// TODO: note in scss"
- app_file "app/assets/stylesheets/application.css.sass", "// TODO: note in sass"
- app_file "app/assets/stylesheets/application.css.less", "// TODO: note in less"
app_file "app/controllers/application_controller.rb", 1000.times.map { "" }.join("\n") << "# TODO: note in ruby"
app_file "lib/tasks/task.rake", "# TODO: note in rake"
+ app_file 'app/views/home/index.html.builder', '# TODO: note in builder'
+ app_file 'config/locales/en.yml', '# TODO: note in yml'
+ app_file 'config/locales/en.yaml', '# TODO: note in yaml'
+ app_file "app/views/home/index.ruby", "# TODO: note in ruby"
- boot_rails
- require 'rake'
- require 'rdoc/task'
- require 'rake/testtask'
-
- Rails.application.load_tasks
-
- Dir.chdir(app_path) do
- output = `bundle exec rake notes`
- lines = output.scan(/\[([0-9\s]+)\](\s)/)
-
+ run_rake_notes do |output, lines|
assert_match(/note in erb/, output)
- assert_match(/note in haml/, output)
- assert_match(/note in slim/, output)
- assert_match(/note in ruby/, output)
- assert_match(/note in coffee/, output)
assert_match(/note in js/, output)
assert_match(/note in css/, output)
- assert_match(/note in scss/, output)
- assert_match(/note in sass/, output)
- assert_match(/note in less/, output)
assert_match(/note in rake/, output)
+ assert_match(/note in builder/, output)
+ assert_match(/note in yml/, output)
+ assert_match(/note in yaml/, output)
+ assert_match(/note in ruby/, output)
- assert_equal 11, lines.size
-
- lines.each do |line|
- assert_equal 4, line[0].size
- assert_equal ' ', line[1]
- end
+ assert_equal 9, lines.size
+ assert_equal [4], lines.map(&:size).uniq
end
end
@@ -70,18 +52,7 @@ module ApplicationTests
app_file "some_other_dir/blah.rb", "# TODO: note in some_other directory"
- boot_rails
-
- require 'rake'
- require 'rdoc/task'
- require 'rake/testtask'
-
- Rails.application.load_tasks
-
- Dir.chdir(app_path) do
- output = `bundle exec rake notes`
- lines = output.scan(/\[([0-9\s]+)\]/).flatten
-
+ run_rake_notes do |output, lines|
assert_match(/note in app directory/, output)
assert_match(/note in config directory/, output)
assert_match(/note in db directory/, output)
@@ -90,10 +61,7 @@ module ApplicationTests
assert_no_match(/note in some_other directory/, output)
assert_equal 5, lines.size
-
- lines.each do |line_number|
- assert_equal 4, line_number.size
- end
+ assert_equal [4], lines.map(&:size).uniq
end
end
@@ -106,18 +74,7 @@ module ApplicationTests
app_file "some_other_dir/blah.rb", "# TODO: note in some_other directory"
- boot_rails
-
- require 'rake'
- require 'rdoc/task'
- require 'rake/testtask'
-
- Rails.application.load_tasks
-
- Dir.chdir(app_path) do
- output = `SOURCE_ANNOTATION_DIRECTORIES='some_other_dir' bundle exec rake notes`
- lines = output.scan(/\[([0-9\s]+)\]/).flatten
-
+ run_rake_notes "SOURCE_ANNOTATION_DIRECTORIES='some_other_dir' bundle exec rake notes" do |output, lines|
assert_match(/note in app directory/, output)
assert_match(/note in config directory/, output)
assert_match(/note in db directory/, output)
@@ -127,10 +84,7 @@ module ApplicationTests
assert_match(/note in some_other directory/, output)
assert_equal 6, lines.size
-
- lines.each do |line_number|
- assert_equal 4, line_number.size
- end
+ assert_equal [4], lines.map(&:size).uniq
end
end
@@ -148,32 +102,51 @@ module ApplicationTests
end
EOS
- boot_rails
-
- require 'rake'
- require 'rdoc/task'
- require 'rake/testtask'
-
- Rails.application.load_tasks
-
- Dir.chdir(app_path) do
- output = `bundle exec rake notes_custom`
- lines = output.scan(/\[([0-9\s]+)\]/).flatten
-
+ run_rake_notes "bundle exec rake notes_custom" do |output, lines|
assert_match(/\[FIXME\] note in lib directory/, output)
assert_match(/\[TODO\] note in test directory/, output)
assert_no_match(/OPTIMIZE/, output)
assert_no_match(/note in app directory/, output)
assert_equal 2, lines.size
+ assert_equal [4], lines.map(&:size).uniq
+ end
+ end
- lines.each do |line_number|
- assert_equal 4, line_number.size
- end
+ test 'register a new extension' do
+ add_to_config %q{ config.annotations.register_extensions("scss", "sass") { |annotation| /\/\/\s*(#{annotation}):?\s*(.*)$/ } }
+ app_file "app/assets/stylesheets/application.css.scss", "// TODO: note in scss"
+ app_file "app/assets/stylesheets/application.css.sass", "// TODO: note in sass"
+
+ run_rake_notes do |output, lines|
+ assert_match(/note in scss/, output)
+ assert_match(/note in sass/, output)
+ assert_equal 2, lines.size
end
end
private
+
+ def run_rake_notes(command = 'bundle exec rake notes')
+ boot_rails
+ load_tasks
+
+ Dir.chdir(app_path) do
+ output = `#{command}`
+ lines = output.scan(/\[([0-9\s]+)\]\s/).flatten
+
+ yield output, lines
+ end
+ end
+
+ def load_tasks
+ require 'rake'
+ require 'rdoc/task'
+ require 'rake/testtask'
+
+ Rails.application.load_tasks
+ end
+
def boot_rails
super
require "#{app_path}/config/environment"
diff --git a/railties/test/application/rake_test.rb b/railties/test/application/rake_test.rb
index c1cb1c1eba..e8c8de9f73 100644
--- a/railties/test/application/rake_test.rb
+++ b/railties/test/application/rake_test.rb
@@ -111,7 +111,7 @@ module ApplicationTests
RUBY
output = Dir.chdir(app_path){ `rake routes` }
- assert_equal "Prefix Verb URI Pattern Controller#Action\ncart GET /cart(.:format) cart#show\n", output
+ assert_equal "Prefix Verb URI Pattern Controller#Action\n cart GET /cart(.:format) cart#show\n", output
end
def test_rake_routes_with_controller_environment
@@ -124,7 +124,7 @@ module ApplicationTests
ENV['CONTROLLER'] = 'cart'
output = Dir.chdir(app_path){ `rake routes` }
- assert_equal "Prefix Verb URI Pattern Controller#Action\ncart GET /cart(.:format) cart#show\n", output
+ assert_equal "Prefix Verb URI Pattern Controller#Action\n cart GET /cart(.:format) cart#show\n", output
end
def test_rake_routes_displays_message_when_no_routes_are_defined
@@ -187,7 +187,7 @@ module ApplicationTests
def test_scaffold_tests_pass_by_default
output = Dir.chdir(app_path) do
`rails generate scaffold user username:string password:string;
- bundle exec rake db:migrate db:test:clone test`
+ bundle exec rake db:migrate test`
end
assert_match(/7 runs, 13 assertions, 0 failures, 0 errors/, output)
@@ -197,7 +197,7 @@ module ApplicationTests
def test_scaffold_with_references_columns_tests_pass_by_default
output = Dir.chdir(app_path) do
`rails generate scaffold LineItems product:references cart:belongs_to;
- bundle exec rake db:migrate db:test:clone test`
+ bundle exec rake db:migrate test`
end
assert_match(/7 runs, 13 assertions, 0 failures, 0 errors/, output)
@@ -208,7 +208,8 @@ module ApplicationTests
add_to_config "config.active_record.schema_format = :sql"
output = Dir.chdir(app_path) do
`rails generate scaffold user username:string;
- bundle exec rake db:migrate db:test:clone 2>&1 --trace`
+ bundle exec rake db:migrate;
+ bundle exec rake db:test:clone 2>&1 --trace`
end
assert_match(/Execute db:test:clone_structure/, output)
end
@@ -217,7 +218,8 @@ module ApplicationTests
add_to_config "config.active_record.schema_format = :sql"
output = Dir.chdir(app_path) do
`rails generate scaffold user username:string;
- bundle exec rake db:migrate db:test:prepare 2>&1 --trace`
+ bundle exec rake db:migrate;
+ bundle exec rake db:test:prepare 2>&1 --trace`
end
assert_match(/Execute db:test:load_structure/, output)
end
@@ -227,7 +229,7 @@ module ApplicationTests
# ensure we have a schema_migrations table to dump
`bundle exec rake db:migrate db:structure:dump DB_STRUCTURE=db/my_structure.sql`
end
- assert File.exists?(File.join(app_path, 'db', 'my_structure.sql'))
+ assert File.exist?(File.join(app_path, 'db', 'my_structure.sql'))
end
def test_rake_dump_structure_should_be_called_twice_when_migrate_redo
@@ -248,26 +250,37 @@ module ApplicationTests
rails generate model product name:string;
bundle exec rake db:migrate db:schema:cache:dump`
end
- assert File.exists?(File.join(app_path, 'db', 'schema_cache.dump'))
+ assert File.exist?(File.join(app_path, 'db', 'schema_cache.dump'))
end
def test_rake_clear_schema_cache
Dir.chdir(app_path) do
`bundle exec rake db:schema:cache:dump db:schema:cache:clear`
end
- assert !File.exists?(File.join(app_path, 'db', 'schema_cache.dump'))
+ assert !File.exist?(File.join(app_path, 'db', 'schema_cache.dump'))
end
def test_copy_templates
Dir.chdir(app_path) do
`bundle exec rake rails:templates:copy`
%w(controller mailer scaffold).each do |dir|
- assert File.exists?(File.join(app_path, 'lib', 'templates', 'erb', dir))
+ assert File.exist?(File.join(app_path, 'lib', 'templates', 'erb', dir))
end
%w(controller helper scaffold_controller assets).each do |dir|
- assert File.exists?(File.join(app_path, 'lib', 'templates', 'rails', dir))
+ assert File.exist?(File.join(app_path, 'lib', 'templates', 'rails', dir))
end
end
end
+
+ def test_template_load_initializers
+ app_file "config/initializers/dummy.rb", "puts 'Hello, World!'"
+ app_file "template.rb", ""
+
+ output = Dir.chdir(app_path) do
+ `bundle exec rake rails:template LOCATION=template.rb`
+ end
+
+ assert_match(/Hello, World!/, output)
+ end
end
end
diff --git a/railties/test/application/test_test.rb b/railties/test/application/test_test.rb
index c7ad2fba8f..c724c867ec 100644
--- a/railties/test/application/test_test.rb
+++ b/railties/test/application/test_test.rb
@@ -24,7 +24,7 @@ module ApplicationTests
end
RUBY
- run_test_file 'unit/foo_test.rb'
+ assert_successful_test_run 'unit/foo_test.rb'
end
test "integration test" do
@@ -49,19 +49,182 @@ module ApplicationTests
end
RUBY
- run_test_file 'integration/posts_test.rb'
+ assert_successful_test_run 'integration/posts_test.rb'
+ end
+
+ test "enable full backtraces on test failures" do
+ app_file 'test/unit/failing_test.rb', <<-RUBY
+ require 'test_helper'
+
+ class FailingTest < ActiveSupport::TestCase
+ def test_failure
+ raise "fail"
+ end
+ end
+ RUBY
+
+ output = run_test_file('unit/failing_test.rb', env: { "BACKTRACE" => "1" })
+ assert_match %r{/app/test/unit/failing_test\.rb}, output
+ end
+
+ test "ruby schema migrations" do
+ output = script('generate model user name:string')
+ version = output.match(/(\d+)_create_users\.rb/)[1]
+
+ app_file 'test/models/user_test.rb', <<-RUBY
+ require 'test_helper'
+
+ class UserTest < ActiveSupport::TestCase
+ test "user" do
+ User.create! name: "Jon"
+ end
+ end
+ RUBY
+ app_file 'db/schema.rb', ''
+
+ assert_unsuccessful_run "models/user_test.rb", "Migrations are pending"
+
+ app_file 'db/schema.rb', <<-RUBY
+ ActiveRecord::Schema.define(version: #{version}) do
+ create_table :users do |t|
+ t.string :name
+ end
+ end
+ RUBY
+
+ app_file 'config/initializers/disable_maintain_test_schema.rb', <<-RUBY
+ Rails.application.config.active_record.maintain_test_schema = false
+ RUBY
+
+ assert_unsuccessful_run "models/user_test.rb", "Could not find table 'users'"
+
+ File.delete "#{app_path}/config/initializers/disable_maintain_test_schema.rb"
+
+ result = assert_successful_test_run('models/user_test.rb')
+ assert !result.include?("create_table(:users)")
+ end
+
+ test "sql structure migrations" do
+ output = script('generate model user name:string')
+ version = output.match(/(\d+)_create_users\.rb/)[1]
+
+ app_file 'test/models/user_test.rb', <<-RUBY
+ require 'test_helper'
+
+ class UserTest < ActiveSupport::TestCase
+ test "user" do
+ User.create! name: "Jon"
+ end
+ end
+ RUBY
+
+ app_file 'db/structure.sql', ''
+ app_file 'config/initializers/enable_sql_schema_format.rb', <<-RUBY
+ Rails.application.config.active_record.schema_format = :sql
+ RUBY
+
+ assert_unsuccessful_run "models/user_test.rb", "Migrations are pending"
+
+ app_file 'db/structure.sql', <<-SQL
+ CREATE TABLE "schema_migrations" ("version" varchar(255) NOT NULL);
+ CREATE UNIQUE INDEX "unique_schema_migrations" ON "schema_migrations" ("version");
+ CREATE TABLE "users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255));
+ INSERT INTO schema_migrations (version) VALUES ('#{version}');
+ SQL
+
+ app_file 'config/initializers/disable_maintain_test_schema.rb', <<-RUBY
+ Rails.application.config.active_record.maintain_test_schema = false
+ RUBY
+
+ assert_unsuccessful_run "models/user_test.rb", "Could not find table 'users'"
+
+ File.delete "#{app_path}/config/initializers/disable_maintain_test_schema.rb"
+
+ assert_successful_test_run('models/user_test.rb')
+ end
+
+ test "sql structure migrations when adding column to existing table" do
+ output_1 = script('generate model user name:string')
+ version_1 = output_1.match(/(\d+)_create_users\.rb/)[1]
+
+ app_file 'test/models/user_test.rb', <<-RUBY
+ require 'test_helper'
+ class UserTest < ActiveSupport::TestCase
+ test "user" do
+ User.create! name: "Jon"
+ end
+ end
+ RUBY
+
+ app_file 'config/initializers/enable_sql_schema_format.rb', <<-RUBY
+ Rails.application.config.active_record.schema_format = :sql
+ RUBY
+
+ app_file 'db/structure.sql', <<-SQL
+ CREATE TABLE "schema_migrations" ("version" varchar(255) NOT NULL);
+ CREATE UNIQUE INDEX "unique_schema_migrations" ON "schema_migrations" ("version");
+ CREATE TABLE "users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255));
+ INSERT INTO schema_migrations (version) VALUES ('#{version_1}');
+ SQL
+
+ assert_successful_test_run('models/user_test.rb')
+
+ output_2 = script('generate migration add_email_to_users')
+ version_2 = output_2.match(/(\d+)_add_email_to_users\.rb/)[1]
+
+ app_file 'test/models/user_test.rb', <<-RUBY
+ require 'test_helper'
+
+ class UserTest < ActiveSupport::TestCase
+ test "user" do
+ User.create! name: "Jon", email: "jon@doe.com"
+ end
+ end
+ RUBY
+
+ app_file 'db/structure.sql', <<-SQL
+ CREATE TABLE "schema_migrations" ("version" varchar(255) NOT NULL);
+ CREATE UNIQUE INDEX "unique_schema_migrations" ON "schema_migrations" ("version");
+ CREATE TABLE "users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255), "email" varchar(255));
+ INSERT INTO schema_migrations (version) VALUES ('#{version_1}');
+ INSERT INTO schema_migrations (version) VALUES ('#{version_2}');
+ SQL
+
+ assert_successful_test_run('models/user_test.rb')
end
private
- def run_test_file(name)
- result = ruby '-Itest', "#{app_path}/test/#{name}"
+ def assert_unsuccessful_run(name, message)
+ result = run_test_file(name)
+ assert_not_equal 0, $?.to_i
+ assert result.include?(message)
+ result
+ end
+
+ def assert_successful_test_run(name)
+ result = run_test_file(name)
assert_equal 0, $?.to_i, result
+ result
+ end
+
+ def run_test_file(name, options = {})
+ ruby '-Itest', "#{app_path}/test/#{name}", options
end
def ruby(*args)
+ options = args.extract_options!
+ env = options.fetch(:env, {})
+ env["RUBYLIB"] = $:.join(':')
+
Dir.chdir(app_path) do
- `RUBYLIB='#{$:.join(':')}' #{Gem.ruby} #{args.join(' ')}`
+ `#{env_string(env)} #{Gem.ruby} #{args.join(' ')} 2>&1`
end
end
+
+ def env_string(variables)
+ variables.map do |key, value|
+ "#{key}='#{value}'"
+ end.join " "
+ end
end
end
diff --git a/railties/test/commands/console_test.rb b/railties/test/commands/console_test.rb
index a34beaedb3..1273f9d4c2 100644
--- a/railties/test/commands/console_test.rb
+++ b/railties/test/commands/console_test.rb
@@ -19,14 +19,8 @@ class Rails::ConsoleTest < ActiveSupport::TestCase
assert console.sandbox?
end
- def test_debugger_option
- console = Rails::Console.new(app, parse_arguments(["--debugger"]))
- assert console.debugger?
- end
-
def test_no_options
console = Rails::Console.new(app, parse_arguments([]))
- assert !console.debugger?
assert !console.sandbox?
end
@@ -36,13 +30,6 @@ class Rails::ConsoleTest < ActiveSupport::TestCase
assert_match(/Loading \w+ environment \(Rails/, output)
end
- def test_start_with_debugger
- rails_console = Rails::Console.new(app, parse_arguments(["--debugger"]))
- rails_console.expects(:require_debugger).returns(nil)
-
- silence_stream(STDOUT) { rails_console.start }
- end
-
def test_start_with_sandbox
app.expects(:sandbox=).with(true)
FakeConsole.expects(:start)
@@ -52,6 +39,25 @@ class Rails::ConsoleTest < ActiveSupport::TestCase
assert_match(/Loading \w+ environment in sandbox \(Rails/, output)
end
+ if RUBY_VERSION < '2.0.0'
+ def test_debugger_option
+ console = Rails::Console.new(app, parse_arguments(["--debugger"]))
+ assert console.debugger?
+ end
+
+ def test_no_options_does_not_set_debugger_flag
+ console = Rails::Console.new(app, parse_arguments([]))
+ assert !console.debugger?
+ end
+
+ def test_start_with_debugger
+ rails_console = Rails::Console.new(app, parse_arguments(["--debugger"]))
+ rails_console.expects(:require_debugger).returns(nil)
+
+ silence_stream(STDOUT) { rails_console.start }
+ end
+ end
+
def test_console_with_environment
start ["-e production"]
assert_match(/\sproduction\s/, output)
diff --git a/railties/test/commands/dbconsole_test.rb b/railties/test/commands/dbconsole_test.rb
index edb92b3aa2..24db395e6e 100644
--- a/railties/test/commands/dbconsole_test.rb
+++ b/railties/test/commands/dbconsole_test.rb
@@ -2,29 +2,74 @@ require 'abstract_unit'
require 'rails/commands/dbconsole'
class Rails::DBConsoleTest < ActiveSupport::TestCase
- def teardown
- %w[PGUSER PGHOST PGPORT PGPASSWORD].each{|key| ENV.delete(key)}
- end
- def test_config
- Rails::DBConsole.const_set(:APP_PATH, "erb")
-
- app_config({})
- capture_abort { Rails::DBConsole.new.config }
- assert aborted
- assert_match(/No database is configured for the environment '\w+'/, output)
- app_config(test: "with_init")
- assert_equal Rails::DBConsole.new.config, "with_init"
-
- app_db_file("test:\n without_init")
- assert_equal Rails::DBConsole.new.config, "without_init"
-
- app_db_file("test:\n <%= Rails.something_app_specific %>")
- assert_equal Rails::DBConsole.new.config, "with_init"
+ def setup
+ Rails::DBConsole.const_set('APP_PATH', 'rails/all')
+ end
- app_db_file("test:\n\ninvalid")
- assert_equal Rails::DBConsole.new.config, "with_init"
+ def teardown
+ Rails::DBConsole.send(:remove_const, 'APP_PATH')
+ %w[PGUSER PGHOST PGPORT PGPASSWORD DATABASE_URL].each{|key| ENV.delete(key)}
+ end
+
+ def test_config_with_db_config_only
+ config_sample = {
+ "test"=> {
+ "adapter"=> "sqlite3",
+ "host"=> "localhost",
+ "port"=> "9000",
+ "database"=> "foo_test",
+ "user"=> "foo",
+ "password"=> "bar",
+ "pool"=> "5",
+ "timeout"=> "3000"
+ }
+ }
+ app_db_config(config_sample)
+ assert_equal Rails::DBConsole.new.config, config_sample["test"]
+ end
+
+ def test_config_with_no_db_config
+ app_db_config(nil)
+ assert_raise(ActiveRecord::AdapterNotSpecified) {
+ Rails::DBConsole.new.config
+ }
+ end
+
+ def test_config_with_database_url_only
+ ENV['DATABASE_URL'] = 'postgresql://foo:bar@localhost:9000/foo_test?pool=5&timeout=3000'
+ app_db_config(nil)
+ expected = {
+ "adapter" => "postgresql",
+ "host" => "localhost",
+ "port" => 9000,
+ "database" => "foo_test",
+ "username" => "foo",
+ "password" => "bar",
+ "pool" => "5",
+ "timeout" => "3000"
+ }.sort
+ assert_equal expected, Rails::DBConsole.new.config.sort
+ end
+
+ def test_config_choose_database_url_if_exists
+ host = "database-url-host.com"
+ ENV['DATABASE_URL'] = "postgresql://foo:bar@#{host}:9000/foo_test?pool=5&timeout=3000"
+ sample_config = {
+ "test" => {
+ "adapter" => "postgresql",
+ "host" => "not-the-#{host}",
+ "port" => 9000,
+ "database" => "foo_test",
+ "username" => "foo",
+ "password" => "bar",
+ "pool" => "5",
+ "timeout" => "3000"
+ }
+ }
+ app_db_config(sample_config)
+ assert_equal host, Rails::DBConsole.new.config["host"]
end
def test_env
@@ -177,6 +222,10 @@ class Rails::DBConsoleTest < ActiveSupport::TestCase
private
+ def app_db_config(results)
+ Rails.application.config.stubs(:database_configuration).returns(results || {})
+ end
+
def dbconsole
@dbconsole ||= Rails::DBConsole.new(nil)
end
@@ -197,11 +246,4 @@ class Rails::DBConsoleTest < ActiveSupport::TestCase
end
end
- def app_db_file(result)
- IO.stubs(:read).with("config/database.yml").returns(result)
- end
-
- def app_config(result)
- Rails.application.config.stubs(:database_configuration).returns(result.stringify_keys)
- end
end
diff --git a/railties/test/commands/server_test.rb b/railties/test/commands/server_test.rb
index 20afca2618..ba688f1e9e 100644
--- a/railties/test/commands/server_test.rb
+++ b/railties/test/commands/server_test.rb
@@ -27,26 +27,62 @@ class Rails::ServerTest < ActiveSupport::TestCase
end
def test_environment_with_rails_env
- with_rails_env 'production' do
- server = Rails::Server.new
- assert_equal 'production', server.options[:environment]
+ with_rack_env nil do
+ with_rails_env 'production' do
+ server = Rails::Server.new
+ assert_equal 'production', server.options[:environment]
+ end
end
end
def test_environment_with_rack_env
- with_rack_env 'production' do
- server = Rails::Server.new
- assert_equal 'production', server.options[:environment]
+ with_rails_env nil do
+ with_rack_env 'production' do
+ server = Rails::Server.new
+ assert_equal 'production', server.options[:environment]
+ end
end
end
def test_log_stdout
- args = ["-e", "development"]
- options = Rails::Server::Options.new.parse!(args)
- assert_equal true, options[:log_stdout]
+ with_rack_env nil do
+ with_rails_env nil do
+ args = []
+ options = Rails::Server::Options.new.parse!(args)
+ assert_equal true, options[:log_stdout]
- args = ["-e", "production"]
- options = Rails::Server::Options.new.parse!(args)
- assert_equal false, options[:log_stdout]
+ args = ["-e", "development"]
+ options = Rails::Server::Options.new.parse!(args)
+ assert_equal true, options[:log_stdout]
+
+ args = ["-e", "production"]
+ options = Rails::Server::Options.new.parse!(args)
+ assert_equal false, options[:log_stdout]
+
+ with_rack_env 'development' do
+ args = []
+ options = Rails::Server::Options.new.parse!(args)
+ assert_equal true, options[:log_stdout]
+ end
+
+ with_rack_env 'production' do
+ args = []
+ options = Rails::Server::Options.new.parse!(args)
+ assert_equal false, options[:log_stdout]
+ end
+
+ with_rails_env 'development' do
+ args = []
+ options = Rails::Server::Options.new.parse!(args)
+ assert_equal true, options[:log_stdout]
+ end
+
+ with_rails_env 'production' do
+ args = []
+ options = Rails::Server::Options.new.parse!(args)
+ assert_equal false, options[:log_stdout]
+ end
+ end
+ end
end
end
diff --git a/railties/test/configuration/middleware_stack_proxy_test.rb b/railties/test/configuration/middleware_stack_proxy_test.rb
index 2442cb995d..6f3e45f320 100644
--- a/railties/test/configuration/middleware_stack_proxy_test.rb
+++ b/railties/test/configuration/middleware_stack_proxy_test.rb
@@ -39,7 +39,7 @@ module Rails
@stack.swap :foo
@stack.delete :foo
- mock = MiniTest::Mock.new
+ mock = Minitest::Mock.new
mock.expect :send, nil, [:swap, :foo]
mock.expect :send, nil, [:delete, :foo]
@@ -50,7 +50,7 @@ module Rails
private
def assert_playback(msg_name, args)
- mock = MiniTest::Mock.new
+ mock = Minitest::Mock.new
mock.expect :send, nil, [msg_name, args]
@stack.merge_into(mock)
mock.verify
diff --git a/railties/test/env_helpers.rb b/railties/test/env_helpers.rb
index 6223c85bbf..330fe150ca 100644
--- a/railties/test/env_helpers.rb
+++ b/railties/test/env_helpers.rb
@@ -1,7 +1,10 @@
+require 'rails'
+
module EnvHelpers
private
def with_rails_env(env)
+ Rails.instance_variable_set :@_env, nil
switch_env 'RAILS_ENV', env do
switch_env 'RACK_ENV', nil do
yield
@@ -10,6 +13,7 @@ module EnvHelpers
end
def with_rack_env(env)
+ Rails.instance_variable_set :@_env, nil
switch_env 'RACK_ENV', env do
switch_env 'RAILS_ENV', nil do
yield
diff --git a/railties/test/generators/actions_test.rb b/railties/test/generators/actions_test.rb
index 0db40c1d32..6d6de0fb52 100644
--- a/railties/test/generators/actions_test.rb
+++ b/railties/test/generators/actions_test.rb
@@ -41,13 +41,13 @@ class ActionsTest < Rails::Generators::TestCase
def test_add_source_adds_source_to_gemfile
run_generator
action :add_source, 'http://gems.github.com'
- assert_file 'Gemfile', /source "http:\/\/gems\.github\.com"/
+ assert_file 'Gemfile', /source 'http:\/\/gems\.github\.com'/
end
def test_gem_should_put_gem_dependency_in_gemfile
run_generator
action :gem, 'will-paginate'
- assert_file 'Gemfile', /gem "will\-paginate"/
+ assert_file 'Gemfile', /gem 'will\-paginate'/
end
def test_gem_with_version_should_include_version_in_gemfile
@@ -55,7 +55,7 @@ class ActionsTest < Rails::Generators::TestCase
action :gem, 'rspec', '>=2.0.0.a5'
- assert_file 'Gemfile', /gem "rspec", ">=2.0.0.a5"/
+ assert_file 'Gemfile', /gem 'rspec', '>=2.0.0.a5'/
end
def test_gem_should_insert_on_separate_lines
@@ -66,8 +66,8 @@ class ActionsTest < Rails::Generators::TestCase
action :gem, 'rspec'
action :gem, 'rspec-rails'
- assert_file 'Gemfile', /^gem "rspec"$/
- assert_file 'Gemfile', /^gem "rspec-rails"$/
+ assert_file 'Gemfile', /^gem 'rspec'$/
+ assert_file 'Gemfile', /^gem 'rspec-rails'$/
end
def test_gem_should_include_options
@@ -75,7 +75,15 @@ class ActionsTest < Rails::Generators::TestCase
action :gem, 'rspec', github: 'dchelimsky/rspec', tag: '1.2.9.rc1'
- assert_file 'Gemfile', /gem "rspec", github: "dchelimsky\/rspec", tag: "1\.2\.9\.rc1"/
+ assert_file 'Gemfile', /gem 'rspec', github: 'dchelimsky\/rspec', tag: '1\.2\.9\.rc1'/
+ end
+
+ def test_gem_falls_back_to_inspect_if_string_contains_single_quote
+ run_generator
+
+ action :gem, 'rspec', ">=2.0'0"
+
+ assert_file 'Gemfile', /^gem 'rspec', ">=2\.0'0"$/
end
def test_gem_group_should_wrap_gems_in_a_group
@@ -89,7 +97,7 @@ class ActionsTest < Rails::Generators::TestCase
gem 'fakeweb'
end
- assert_file 'Gemfile', /\ngroup :development, :test do\n gem "rspec-rails"\nend\n\ngroup :test do\n gem "fakeweb"\nend/
+ assert_file 'Gemfile', /\ngroup :development, :test do\n gem 'rspec-rails'\nend\n\ngroup :test do\n gem 'fakeweb'\nend/
end
def test_environment_should_include_data_in_environment_initializer_block
diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb
index 2f0dfc7d3e..2ac5410960 100644
--- a/railties/test/generators/app_generator_test.rb
+++ b/railties/test/generators/app_generator_test.rb
@@ -4,6 +4,7 @@ require 'generators/shared_generator_tests'
DEFAULT_APP_FILES = %w(
.gitignore
+ README.rdoc
Gemfile
Rakefile
config.ru
@@ -20,6 +21,7 @@ DEFAULT_APP_FILES = %w(
bin/bundle
bin/rails
bin/rake
+ bin/setup
config/environments
config/initializers
config/locales
@@ -28,6 +30,7 @@ DEFAULT_APP_FILES = %w(
lib/tasks
lib/assets
log
+ test/test_helper.rb
test/fixtures
test/controllers
test/models
@@ -36,6 +39,8 @@ DEFAULT_APP_FILES = %w(
test/integration
vendor
vendor/assets
+ vendor/assets/stylesheets
+ vendor/assets/javascripts
tmp/cache
tmp/cache/assets
)
@@ -54,9 +59,10 @@ class AppGeneratorTest < Rails::Generators::TestCase
def test_assets
run_generator
- assert_file("app/views/layouts/application.html.erb", /stylesheet_link_tag\s+"application", media: "all", "data-turbolinks-track" => true/)
- assert_file("app/views/layouts/application.html.erb", /javascript_include_tag\s+"application", "data-turbolinks-track" => true/)
+ assert_file("app/views/layouts/application.html.erb", /stylesheet_link_tag\s+'application', media: 'all', 'data-turbolinks-track' => true/)
+ assert_file("app/views/layouts/application.html.erb", /javascript_include_tag\s+'application', 'data-turbolinks-track' => true/)
assert_file("app/assets/stylesheets/application.css")
+ assert_file("app/assets/javascripts/application.js")
end
def test_invalid_application_name_raises_an_error
@@ -108,10 +114,13 @@ class AppGeneratorTest < Rails::Generators::TestCase
FileUtils.mv(app_root, app_moved_root)
+ # make sure we are in correct dir
+ FileUtils.cd(app_moved_root)
+
generator = Rails::Generators::AppGenerator.new ["rails"], { with_dispatchers: true },
destination_root: app_moved_root, shell: @shell
generator.send(:app_const)
- quietly { generator.send(:create_config_files) }
+ quietly { generator.send(:update_config_files) }
assert_file "myapp_moved/config/environment.rb", /Rails\.application\.initialize!/
assert_file "myapp_moved/config/initializers/session_store.rb", /_myapp_session/
end
@@ -126,10 +135,46 @@ class AppGeneratorTest < Rails::Generators::TestCase
generator = Rails::Generators::AppGenerator.new ["rails"], { with_dispatchers: true }, destination_root: app_root, shell: @shell
generator.send(:app_const)
- quietly { generator.send(:create_config_files) }
+ quietly { generator.send(:update_config_files) }
assert_file "myapp/config/initializers/session_store.rb", /_myapp_session/
end
+ def test_new_application_use_json_serialzier
+ run_generator
+
+ assert_file("config/initializers/cookies_serializer.rb", /Rails\.application\.config\.action_dispatch\.cookies_serializer = :json/)
+ end
+
+ def test_rails_update_keep_the_cookie_serializer_if_it_is_already_configured
+ app_root = File.join(destination_root, 'myapp')
+ run_generator [app_root]
+
+ Rails.application.config.root = app_root
+ Rails.application.class.stubs(:name).returns("Myapp")
+ Rails.application.stubs(:is_a?).returns(Rails::Application)
+
+ generator = Rails::Generators::AppGenerator.new ["rails"], { with_dispatchers: true }, destination_root: app_root, shell: @shell
+ generator.send(:app_const)
+ quietly { generator.send(:update_config_files) }
+ assert_file("#{app_root}/config/initializers/cookies_serializer.rb", /Rails\.application\.config\.action_dispatch\.cookies_serializer = :json/)
+ end
+
+ def test_rails_update_set_the_cookie_serializer_to_marchal_if_it_is_not_already_configured
+ app_root = File.join(destination_root, 'myapp')
+ run_generator [app_root]
+
+ FileUtils.rm("#{app_root}/config/initializers/cookies_serializer.rb")
+
+ Rails.application.config.root = app_root
+ Rails.application.class.stubs(:name).returns("Myapp")
+ Rails.application.stubs(:is_a?).returns(Rails::Application)
+
+ generator = Rails::Generators::AppGenerator.new ["rails"], { with_dispatchers: true }, destination_root: app_root, shell: @shell
+ generator.send(:app_const)
+ quietly { generator.send(:update_config_files) }
+ assert_file("#{app_root}/config/initializers/cookies_serializer.rb", /Rails\.application\.config\.action_dispatch\.cookies_serializer = :marshal/)
+ end
+
def test_application_names_are_not_singularized
run_generator [File.join(destination_root, "hats")]
assert_file "hats/config/environment.rb", /Rails\.application\.initialize!/
@@ -229,9 +274,9 @@ class AppGeneratorTest < Rails::Generators::TestCase
def test_generator_if_skip_sprockets_is_given
run_generator [destination_root, "--skip-sprockets"]
+ assert_no_file "config/initializers/assets.rb"
assert_file "config/application.rb" do |content|
assert_match(/#\s+require\s+["']sprockets\/railtie["']/, content)
- assert_match(/config\.assets\.enabled = false/, content)
end
assert_file "Gemfile" do |content|
assert_no_match(/sass-rails/, content)
@@ -245,7 +290,6 @@ class AppGeneratorTest < Rails::Generators::TestCase
assert_no_match(/config\.assets\.digest = true/, content)
assert_no_match(/config\.assets\.js_compressor = :uglifier/, content)
assert_no_match(/config\.assets\.css_compressor = :sass/, content)
- assert_no_match(/config\.assets\.version = '1\.0'/, content)
end
end
@@ -254,37 +298,17 @@ class AppGeneratorTest < Rails::Generators::TestCase
if defined?(JRUBY_VERSION)
assert_gem "therubyrhino"
else
- assert_file "Gemfile", /# gem\s+["']therubyracer["']+, platforms: :ruby$/
+ assert_file "Gemfile", /# gem\s+["']therubyracer["']+, \s+platforms: :ruby$/
end
end
- def test_creation_of_a_test_directory
- run_generator
- assert_file 'test'
- end
-
- def test_creation_of_app_assets_images_directory
- run_generator
- assert_file "app/assets/images"
- end
-
- def test_creation_of_vendor_assets_javascripts_directory
- run_generator
- assert_file "vendor/assets/javascripts"
- end
-
- def test_creation_of_vendor_assets_stylesheets_directory
- run_generator
- assert_file "vendor/assets/stylesheets"
- end
-
def test_jquery_is_the_default_javascript_library
run_generator
assert_file "app/assets/javascripts/application.js" do |contents|
assert_match %r{^//= require jquery}, contents
assert_match %r{^//= require jquery_ujs}, contents
end
- assert_file "Gemfile", /^gem 'jquery-rails'/
+ assert_gem "jquery-rails"
end
def test_other_javascript_libraries
@@ -298,26 +322,43 @@ class AppGeneratorTest < Rails::Generators::TestCase
def test_javascript_is_skipped_if_required
run_generator [destination_root, "--skip-javascript"]
- assert_file "app/assets/javascripts/application.js" do |contents|
- assert_no_match %r{^//=\s+require\s}, contents
- end
+
+ assert_no_file "app/assets/javascripts"
+ assert_no_file "vendor/assets/javascripts"
+
assert_file "app/views/layouts/application.html.erb" do |contents|
- assert_match(/stylesheet_link_tag\s+"application", media: "all" %>/, contents)
- assert_match(/javascript_include_tag\s+"application" \%>/, contents)
+ assert_match(/stylesheet_link_tag\s+'application', media: 'all' %>/, contents)
+ assert_no_match(/javascript_include_tag\s+'application' \%>/, contents)
end
+
assert_file "Gemfile" do |content|
- assert_match(/coffee-rails/, content)
+ assert_no_match(/coffee-rails/, content)
+ assert_no_match(/jquery-rails/, content)
end
end
- def test_inclusion_of_debugger
+ def test_inclusion_of_jbuilder
+ run_generator
+ assert_file "Gemfile", /gem 'jbuilder'/
+ end
+
+ def test_inclusion_of_a_debugger
run_generator
- assert_file "Gemfile", /# gem 'debugger'/
+ if defined?(JRUBY_VERSION)
+ assert_file "Gemfile" do |content|
+ assert_no_match(/byebug/, content)
+ assert_no_match(/debugger/, content)
+ end
+ elsif RUBY_VERSION < '2.0.0'
+ assert_file "Gemfile", /# gem 'debugger'/
+ else
+ assert_file "Gemfile", /# gem 'byebug'/
+ end
end
- def test_inclusion_of_lazy_loaded_sdoc
+ def test_inclusion_of_doc
run_generator
- assert_file 'Gemfile', /gem 'sdoc', require: false/
+ assert_file 'Gemfile', /gem 'sdoc',\s+'~> 0.4.0',\s+group: :doc/
end
def test_template_from_dir_pwd
@@ -367,7 +408,86 @@ class AppGeneratorTest < Rails::Generators::TestCase
assert_no_match(/run bundle install/, output)
end
-protected
+ def test_application_name_with_spaces
+ path = File.join(destination_root, "foo bar".shellescape)
+
+ # This also applies to MySQL apps but not with SQLite
+ run_generator [path, "-d", 'postgresql']
+
+ assert_file "foo bar/config/database.yml", /database: foo_bar_development/
+ assert_file "foo bar/config/initializers/session_store.rb", /key: '_foo_bar/
+ end
+
+ def test_spring
+ run_generator
+ assert_file "Gemfile", /gem 'spring', \s+group: :development/
+ end
+
+ def test_spring_binstubs
+ jruby_skip "spring doesn't run on JRuby"
+ generator.stubs(:bundle_command).with('install')
+ generator.expects(:bundle_command).with('exec spring binstub --all').once
+ quietly { generator.invoke_all }
+ end
+
+ def test_spring_no_fork
+ jruby_skip "spring doesn't run on JRuby"
+ Process.stubs(:respond_to?).with(:fork).returns(false)
+ run_generator
+
+ assert_file "Gemfile" do |content|
+ assert_no_match(/spring/, content)
+ end
+ end
+
+ def test_skip_spring
+ run_generator [destination_root, "--skip-spring"]
+
+ assert_file "Gemfile" do |content|
+ assert_no_match(/spring/, content)
+ end
+ end
+
+ def test_generator_if_skip_gems_is_given
+ run_generator [destination_root, "--skip-gems", "turbolinks", "coffee-rails"]
+
+ assert_file "Gemfile" do |content|
+ assert_no_match(/turbolinks/, content)
+ assert_no_match(/coffee-rails/, content)
+ end
+ assert_file "app/views/layouts/application.html.erb" do |content|
+ assert_no_match(/data-turbolinks-track/, content)
+ end
+ assert_file "app/assets/javascripts/application.js" do |content|
+ assert_no_match(/turbolinks/, content)
+ end
+ end
+
+ def test_gitignore_when_sqlite3
+ run_generator
+
+ assert_file '.gitignore' do |content|
+ assert_match(/sqlite3/, content)
+ end
+ end
+
+ def test_gitignore_when_no_active_record
+ run_generator [destination_root, '--skip-active-record']
+
+ assert_file '.gitignore' do |content|
+ assert_no_match(/sqlite/i, content)
+ end
+ end
+
+ def test_gitignore_when_non_sqlite3_db
+ run_generator([destination_root, "-d", "mysql"])
+
+ assert_file '.gitignore' do |content|
+ assert_no_match(/sqlite/i, content)
+ end
+ end
+
+ protected
def action(*args, &block)
silence(:stdout) { generator.send(*args, &block) }
diff --git a/railties/test/generators/argv_scrubber_test.rb b/railties/test/generators/argv_scrubber_test.rb
new file mode 100644
index 0000000000..31c2d846e2
--- /dev/null
+++ b/railties/test/generators/argv_scrubber_test.rb
@@ -0,0 +1,136 @@
+require 'active_support/testing/autorun'
+require 'active_support/test_case'
+require 'rails/generators/rails/app/app_generator'
+require 'tempfile'
+
+module Rails
+ module Generators
+ class ARGVScrubberTest < ActiveSupport::TestCase # :nodoc:
+ # Future people who read this... These tests are just to surround the
+ # current behavior of the ARGVScrubber, they do not mean that the class
+ # *must* act this way, I just want to prevent regressions.
+
+ def test_version
+ ['-v', '--version'].each do |str|
+ scrubber = ARGVScrubber.new [str]
+ output = nil
+ exit_code = nil
+ scrubber.extend(Module.new {
+ define_method(:puts) { |string| output = string }
+ define_method(:exit) { |code| exit_code = code }
+ })
+ scrubber.prepare!
+ assert_equal "Rails #{Rails::VERSION::STRING}", output
+ assert_equal 0, exit_code
+ end
+ end
+
+ def test_default_help
+ argv = ['zomg', 'how', 'are', 'you']
+ scrubber = ARGVScrubber.new argv
+ args = scrubber.prepare!
+ assert_equal ['--help'] + argv.drop(1), args
+ end
+
+ def test_prepare_returns_args
+ scrubber = ARGVScrubber.new ['hi mom']
+ args = scrubber.prepare!
+ assert_equal '--help', args.first
+ end
+
+ def test_no_mutations
+ scrubber = ARGVScrubber.new ['hi mom'].freeze
+ args = scrubber.prepare!
+ assert_equal '--help', args.first
+ end
+
+ def test_new_command_no_rc
+ scrubber = Class.new(ARGVScrubber) {
+ def self.default_rc_file
+ File.join(Dir.tmpdir, 'whatever')
+ end
+ }.new ['new']
+ args = scrubber.prepare!
+ assert_equal [], args
+ end
+
+ def test_new_homedir_rc
+ file = Tempfile.new 'myrcfile'
+ file.puts '--hello-world'
+ file.flush
+
+ message = nil
+ scrubber = Class.new(ARGVScrubber) {
+ define_singleton_method(:default_rc_file) do
+ file.path
+ end
+ define_method(:puts) { |msg| message = msg }
+ }.new ['new']
+ args = scrubber.prepare!
+ assert_equal ['--hello-world'], args
+ assert_match 'hello-world', message
+ assert_match file.path, message
+ ensure
+ file.close
+ file.unlink
+ end
+
+ def test_rc_whitespace_separated
+ file = Tempfile.new 'myrcfile'
+ file.puts '--hello --world'
+ file.flush
+
+ message = nil
+ scrubber = Class.new(ARGVScrubber) {
+ define_method(:puts) { |msg| message = msg }
+ }.new ['new', "--rc=#{file.path}"]
+ args = scrubber.prepare!
+ assert_equal ['--hello', '--world'], args
+ ensure
+ file.close
+ file.unlink
+ end
+
+ def test_new_rc_option
+ file = Tempfile.new 'myrcfile'
+ file.puts '--hello-world'
+ file.flush
+
+ message = nil
+ scrubber = Class.new(ARGVScrubber) {
+ define_method(:puts) { |msg| message = msg }
+ }.new ['new', "--rc=#{file.path}"]
+ args = scrubber.prepare!
+ assert_equal ['--hello-world'], args
+ assert_match 'hello-world', message
+ assert_match file.path, message
+ ensure
+ file.close
+ file.unlink
+ end
+
+ def test_new_rc_option_and_custom_options
+ file = Tempfile.new 'myrcfile'
+ file.puts '--hello'
+ file.puts '--world'
+ file.flush
+
+ scrubber = Class.new(ARGVScrubber) {
+ define_method(:puts) { |msg| }
+ }.new ['new', 'tenderapp', '--love', "--rc=#{file.path}"]
+
+ args = scrubber.prepare!
+ assert_equal ["tenderapp", "--hello", "--world", "--love"], args
+ ensure
+ file.close
+ file.unlink
+ end
+
+ def test_no_rc
+ scrubber = ARGVScrubber.new ['new', '--no-rc']
+ args = scrubber.prepare!
+ assert_equal [], args
+ end
+ end
+ end
+end
diff --git a/railties/test/generators/controller_generator_test.rb b/railties/test/generators/controller_generator_test.rb
index 9c664a903a..c906d56b8f 100644
--- a/railties/test/generators/controller_generator_test.rb
+++ b/railties/test/generators/controller_generator_test.rb
@@ -43,6 +43,12 @@ class ControllerGeneratorTest < Rails::Generators::TestCase
assert_file "app/assets/stylesheets/account.css"
end
+ def test_does_not_invoke_assets_if_required
+ run_generator ["account", "--skip-assets"]
+ assert_no_file "app/assets/javascripts/account.js"
+ assert_no_file "app/assets/stylesheets/account.css"
+ end
+
def test_invokes_default_test_framework
run_generator
assert_file "test/controllers/account_controller_test.rb"
@@ -61,7 +67,14 @@ class ControllerGeneratorTest < Rails::Generators::TestCase
def test_add_routes
run_generator
- assert_file "config/routes.rb", /get "account\/foo"/, /get "account\/bar"/
+ assert_file "config/routes.rb", /get 'account\/foo'/, /get 'account\/bar'/
+ end
+
+ def test_skip_routes
+ run_generator ["account", "foo", "--skip-routes"]
+ assert_file "config/routes.rb" do |routes|
+ assert_no_match /get 'account\/foo'/, routes
+ end
end
def test_invokes_default_template_engine_even_with_no_action
@@ -85,6 +98,6 @@ class ControllerGeneratorTest < Rails::Generators::TestCase
def test_namespaced_routes_are_created_in_routes
run_generator ["admin/dashboard", "index"]
- assert_file "config/routes.rb", /namespace :admin do\n\s+get "dashboard\/index"\n/
+ assert_file "config/routes.rb", /namespace :admin do\n\s+get 'dashboard\/index'\n/
end
end
diff --git a/railties/test/generators/create_migration_test.rb b/railties/test/generators/create_migration_test.rb
new file mode 100644
index 0000000000..e16a77479a
--- /dev/null
+++ b/railties/test/generators/create_migration_test.rb
@@ -0,0 +1,134 @@
+require 'generators/generators_test_helper'
+require 'rails/generators/rails/migration/migration_generator'
+
+class CreateMigrationTest < Rails::Generators::TestCase
+ include GeneratorsTestHelper
+
+ class Migrator < Rails::Generators::MigrationGenerator
+ include Rails::Generators::Migration
+
+ def self.next_migration_number(dirname)
+ current_migration_number(dirname) + 1
+ end
+ end
+
+ tests Migrator
+
+ def default_destination_path
+ "db/migrate/create_articles.rb"
+ end
+
+ def create_migration(destination_path = default_destination_path, config = {}, generator_options = {}, &block)
+ migration_name = File.basename(destination_path, '.rb')
+ generator([migration_name], generator_options)
+ generator.set_migration_assigns!(destination_path)
+
+ dir, base = File.split(destination_path)
+ timestamped_destination_path = File.join(dir, ["%migration_number%", base].join('_'))
+
+ @migration = Rails::Generators::Actions::CreateMigration.new(generator, timestamped_destination_path, block || "contents", config)
+ end
+
+ def migration_exists!(*args)
+ @existing_migration = create_migration(*args)
+ invoke!
+ @generator = nil
+ end
+
+ def invoke!
+ capture(:stdout) { @migration.invoke! }
+ end
+
+ def revoke!
+ capture(:stdout) { @migration.revoke! }
+ end
+
+ def test_invoke
+ create_migration
+
+ assert_match(/create db\/migrate\/1_create_articles.rb\n/, invoke!)
+ assert_file @migration.destination
+ end
+
+ def test_invoke_pretended
+ create_migration(default_destination_path, {}, { pretend: true })
+
+ assert_no_file @migration.destination
+ end
+
+ def test_invoke_when_exists
+ migration_exists!
+ create_migration
+
+ assert_equal @existing_migration.destination, @migration.existing_migration
+ end
+
+ def test_invoke_when_exists_identical
+ migration_exists!
+ create_migration
+
+ assert_match(/identical db\/migrate\/1_create_articles.rb\n/, invoke!)
+ assert @migration.identical?
+ end
+
+ def test_invoke_when_exists_not_identical
+ migration_exists!
+ create_migration { "different content" }
+
+ assert_raise(Rails::Generators::Error) { invoke! }
+ end
+
+ def test_invoke_forced_when_exists_not_identical
+ dest = "db/migrate/migration.rb"
+ migration_exists!(dest)
+ create_migration(dest, force: true) { "different content" }
+
+ stdout = invoke!
+ assert_match(/remove db\/migrate\/1_migration.rb\n/, stdout)
+ assert_match(/create db\/migrate\/2_migration.rb\n/, stdout)
+ assert_file @migration.destination
+ assert_no_file @existing_migration.destination
+ end
+
+ def test_invoke_forced_pretended_when_exists_not_identical
+ migration_exists!
+ create_migration(default_destination_path, { force: true }, { pretend: true }) do
+ "different content"
+ end
+
+ stdout = invoke!
+ assert_match(/remove db\/migrate\/1_create_articles.rb\n/, stdout)
+ assert_match(/create db\/migrate\/2_create_articles.rb\n/, stdout)
+ assert_no_file @migration.destination
+ end
+
+ def test_invoke_skipped_when_exists_not_identical
+ migration_exists!
+ create_migration(default_destination_path, {}, { skip: true }) { "different content" }
+
+ assert_match(/skip db\/migrate\/2_create_articles.rb\n/, invoke!)
+ assert_no_file @migration.destination
+ end
+
+ def test_revoke
+ migration_exists!
+ create_migration
+
+ assert_match(/remove db\/migrate\/1_create_articles.rb\n/, revoke!)
+ assert_no_file @existing_migration.destination
+ end
+
+ def test_revoke_pretended
+ migration_exists!
+ create_migration(default_destination_path, {}, { pretend: true })
+
+ assert_match(/remove db\/migrate\/1_create_articles.rb\n/, revoke!)
+ assert_file @existing_migration.destination
+ end
+
+ def test_revoke_when_no_exists
+ create_migration
+
+ assert_match(/remove db\/migrate\/1_create_articles.rb\n/, revoke!)
+ end
+end
diff --git a/railties/test/generators/generator_test.rb b/railties/test/generators/generator_test.rb
new file mode 100644
index 0000000000..b136239795
--- /dev/null
+++ b/railties/test/generators/generator_test.rb
@@ -0,0 +1,85 @@
+require 'active_support/testing/autorun'
+require 'active_support/test_case'
+require 'rails/generators/app_base'
+
+module Rails
+ module Generators
+ class GeneratorTest < ActiveSupport::TestCase
+ def make_builder_class
+ Class.new(AppBase) do
+ add_shared_options_for "application"
+
+ # include a module to get around thor's method_added hook
+ include(Module.new {
+ def gemfile_entries; super; end
+ def invoke_all; super; self; end
+ def add_gem_entry_filter; super; end
+ def gemfile_entry(*args); super; end
+ })
+ end
+ end
+
+ def test_construction
+ klass = make_builder_class
+ assert klass.start(['new', 'blah'])
+ end
+
+ def test_add_gem
+ klass = make_builder_class
+ generator = klass.start(['new', 'blah'])
+ generator.gemfile_entry 'tenderlove'
+ assert_includes generator.gemfile_entries.map(&:name), 'tenderlove'
+ end
+
+ def test_add_gem_with_version
+ klass = make_builder_class
+ generator = klass.start(['new', 'blah'])
+ generator.gemfile_entry 'tenderlove', '2.0.0'
+ assert generator.gemfile_entries.find { |gfe|
+ gfe.name == 'tenderlove' && gfe.version == '2.0.0'
+ }
+ end
+
+ def test_add_github_gem
+ klass = make_builder_class
+ generator = klass.start(['new', 'blah'])
+ generator.gemfile_entry 'tenderlove', github: 'hello world'
+ assert generator.gemfile_entries.find { |gfe|
+ gfe.name == 'tenderlove' && gfe.options[:github] == 'hello world'
+ }
+ end
+
+ def test_add_path_gem
+ klass = make_builder_class
+ generator = klass.start(['new', 'blah'])
+ generator.gemfile_entry 'tenderlove', path: 'hello world'
+ assert generator.gemfile_entries.find { |gfe|
+ gfe.name == 'tenderlove' && gfe.options[:path] == 'hello world'
+ }
+ end
+
+ def test_filter
+ klass = make_builder_class
+ generator = klass.start(['new', 'blah'])
+ gems = generator.gemfile_entries
+ generator.add_gem_entry_filter { |gem|
+ gem.name != gems.first.name
+ }
+ assert_equal gems.drop(1), generator.gemfile_entries
+ end
+
+ def test_two_filters
+ klass = make_builder_class
+ generator = klass.start(['new', 'blah'])
+ gems = generator.gemfile_entries
+ generator.add_gem_entry_filter { |gem|
+ gem.name != gems.first.name
+ }
+ generator.add_gem_entry_filter { |gem|
+ gem.name != gems[1].name
+ }
+ assert_equal gems.drop(2), generator.gemfile_entries
+ end
+ end
+ end
+end
diff --git a/railties/test/generators/generators_test_helper.rb b/railties/test/generators/generators_test_helper.rb
index 32a3d072c9..77ec2f1c0c 100644
--- a/railties/test/generators/generators_test_helper.rb
+++ b/railties/test/generators/generators_test_helper.rb
@@ -1,10 +1,14 @@
require 'abstract_unit'
+require 'active_support/core_ext/module/remove_method'
require 'rails/generators'
require 'rails/generators/test_case'
module Rails
- def self.root
- @root ||= File.expand_path(File.join(File.dirname(__FILE__), '..', 'fixtures'))
+ class << self
+ remove_possible_method :root
+ def root
+ @root ||= File.expand_path(File.join(File.dirname(__FILE__), '..', 'fixtures'))
+ end
end
end
Rails.application.config.root = Rails.root
diff --git a/railties/test/generators/mailer_generator_test.rb b/railties/test/generators/mailer_generator_test.rb
index 6b2351fc1a..25649881eb 100644
--- a/railties/test/generators/mailer_generator_test.rb
+++ b/railties/test/generators/mailer_generator_test.rb
@@ -1,7 +1,6 @@
require 'generators/generators_test_helper'
require 'rails/generators/mailer/mailer_generator'
-
class MailerGeneratorTest < Rails::Generators::TestCase
include GeneratorsTestHelper
arguments %w(notifier foo bar)
@@ -23,8 +22,11 @@ class MailerGeneratorTest < Rails::Generators::TestCase
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)
+ Object.send :const_set, :Notifier, Class.new
+ content = capture(:stderr){ run_generator }
+ assert_match(/The name 'Notifier' is either already used in your application or reserved/, content)
+ ensure
+ Object.send :remove_const, :Notifier
end
def test_invokes_default_test_framework
@@ -34,17 +36,58 @@ class MailerGeneratorTest < Rails::Generators::TestCase
assert_match(/test "foo"/, test)
assert_match(/test "bar"/, test)
end
+ assert_file "test/mailers/previews/notifier_preview.rb" do |preview|
+ assert_match(/\# Preview all emails at http:\/\/localhost\:3000\/rails\/mailers\/notifier/, preview)
+ assert_match(/class NotifierPreview < ActionMailer::Preview/, preview)
+ assert_match(/\# Preview this email at http:\/\/localhost\:3000\/rails\/mailers\/notifier\/foo/, preview)
+ assert_instance_method :foo, preview do |foo|
+ assert_match(/Notifier.foo/, foo)
+ end
+ assert_match(/\# Preview this email at http:\/\/localhost\:3000\/rails\/mailers\/notifier\/bar/, preview)
+ assert_instance_method :bar, preview do |bar|
+ assert_match(/Notifier.bar/, bar)
+ end
+ end
end
- def test_invokes_default_template_engine
+ def test_check_test_class_collision
+ Object.send :const_set, :NotifierTest, Class.new
+ content = capture(:stderr){ run_generator }
+ assert_match(/The name 'NotifierTest' is either already used in your application or reserved/, content)
+ ensure
+ Object.send :remove_const, :NotifierTest
+ end
+
+ def test_check_preview_class_collision
+ Object.send :const_set, :NotifierPreview, Class.new
+ content = capture(:stderr){ run_generator }
+ assert_match(/The name 'NotifierPreview' is either already used in your application or reserved/, content)
+ ensure
+ Object.send :remove_const, :NotifierPreview
+ end
+
+ def test_invokes_default_text_template_engine
run_generator
assert_file "app/views/notifier/foo.text.erb" do |view|
- assert_match(%r(app/views/notifier/foo\.text\.erb), view)
+ assert_match(%r(\sapp/views/notifier/foo\.text\.erb), view)
assert_match(/<%= @greeting %>/, view)
end
assert_file "app/views/notifier/bar.text.erb" do |view|
- assert_match(%r(app/views/notifier/bar\.text\.erb), view)
+ assert_match(%r(\sapp/views/notifier/bar\.text\.erb), view)
+ assert_match(/<%= @greeting %>/, view)
+ end
+ end
+
+ def test_invokes_default_html_template_engine
+ run_generator
+ assert_file "app/views/notifier/foo.html.erb" do |view|
+ assert_match(%r(\sapp/views/notifier/foo\.html\.erb), view)
+ assert_match(/<%= @greeting %>/, view)
+ end
+
+ assert_file "app/views/notifier/bar.html.erb" do |view|
+ assert_match(%r(\sapp/views/notifier/bar\.html\.erb), view)
assert_match(/<%= @greeting %>/, view)
end
end
@@ -65,7 +108,13 @@ class MailerGeneratorTest < Rails::Generators::TestCase
assert_match(/class Farm::Animal < ActionMailer::Base/, mailer)
assert_match(/en\.farm\.animal\.moos\.subject/, mailer)
end
+ assert_file "test/mailers/previews/farm/animal_preview.rb" do |preview|
+ assert_match(/\# Preview all emails at http:\/\/localhost\:3000\/rails\/mailers\/farm\/animal/, preview)
+ assert_match(/class Farm::AnimalPreview < ActionMailer::Preview/, preview)
+ assert_match(/\# Preview this email at http:\/\/localhost\:3000\/rails\/mailers\/farm\/animal\/moos/, preview)
+ end
assert_file "app/views/farm/animal/moos.text.erb"
+ assert_file "app/views/farm/animal/moos.html.erb"
end
def test_actions_are_turned_into_methods
diff --git a/railties/test/generators/migration_generator_test.rb b/railties/test/generators/migration_generator_test.rb
index d876597944..6fac643ed0 100644
--- a/railties/test/generators/migration_generator_test.rb
+++ b/railties/test/generators/migration_generator_test.rb
@@ -197,4 +197,54 @@ class MigrationGeneratorTest < Rails::Generators::TestCase
def test_properly_identifies_usage_file
assert generator_class.send(:usage_path)
end
+
+ def test_migration_with_singular_table_name
+ with_singular_table_name do
+ migration = "add_title_body_to_post"
+ run_generator [migration, 'title:string']
+ assert_migration "db/migrate/#{migration}.rb" do |content|
+ assert_method :change, content do |change|
+ assert_match(/add_column :post, :title, :string/, change)
+ end
+ end
+ end
+ end
+
+ def test_create_join_table_migration_with_singular_table_name
+ with_singular_table_name do
+ migration = "add_media_join_table"
+ run_generator [migration, "artist_id", "music:uniq"]
+
+ assert_migration "db/migrate/#{migration}.rb" do |content|
+ assert_method :change, content do |change|
+ assert_match(/create_join_table :artist, :music/, change)
+ assert_match(/# t.index \[:artist_id, :music_id\]/, change)
+ assert_match(/ t.index \[:music_id, :artist_id\], unique: true/, change)
+ end
+ end
+ end
+ end
+
+ def test_create_table_migration_with_singular_table_name
+ with_singular_table_name do
+ run_generator ["create_book", "title:string", "content:text"]
+ assert_migration "db/migrate/create_book.rb" do |content|
+ assert_method :change, content do |change|
+ assert_match(/create_table :book/, change)
+ assert_match(/ t\.string :title/, change)
+ assert_match(/ t\.text :content/, change)
+ end
+ end
+ end
+ end
+
+ private
+
+ def with_singular_table_name
+ old_state = ActiveRecord::Base.pluralize_table_names
+ ActiveRecord::Base.pluralize_table_names = false
+ yield
+ ensure
+ ActiveRecord::Base.pluralize_table_names = old_state
+ end
end
diff --git a/railties/test/generators/model_generator_test.rb b/railties/test/generators/model_generator_test.rb
index 01ab77ee20..b67cf02d7b 100644
--- a/railties/test/generators/model_generator_test.rb
+++ b/railties/test/generators/model_generator_test.rb
@@ -34,6 +34,13 @@ class ModelGeneratorTest < Rails::Generators::TestCase
assert_no_migration "db/migrate/create_accounts.rb"
end
+ def test_plural_names_are_singularized
+ content = run_generator ["accounts".freeze]
+ assert_file "app/models/account.rb", /class Account < ActiveRecord::Base/
+ assert_file "test/models/account_test.rb", /class AccountTest/
+ assert_match(/\[WARNING\] The model name 'accounts' was recognized as a plural, using the singular 'account' instead\. Override with --force-plural or setup custom inflection rules for this noun before running the generator\./, content)
+ end
+
def test_model_with_underscored_parent_option
run_generator ["account", "--parent", "admin/account"]
assert_file "app/models/account.rb", /class Account < Admin::Account/
diff --git a/railties/test/generators/named_base_test.rb b/railties/test/generators/named_base_test.rb
index 2bc2c33a72..ac5cfff229 100644
--- a/railties/test/generators/named_base_test.rb
+++ b/railties/test/generators/named_base_test.rb
@@ -117,6 +117,25 @@ class NamedBaseTest < Rails::Generators::TestCase
assert Rails::Generators.hidden_namespaces.include?('hidden')
end
+ def test_scaffold_plural_names_with_model_name_option
+ g = generator ['Admin::Foo'], model_name: 'User'
+ assert_name g, 'user', :singular_name
+ assert_name g, 'User', :name
+ assert_name g, 'user', :file_path
+ assert_name g, 'User', :class_name
+ assert_name g, 'user', :file_name
+ assert_name g, 'User', :human_name
+ assert_name g, 'users', :plural_name
+ assert_name g, 'user', :i18n_scope
+ assert_name g, 'users', :table_name
+ assert_name g, 'Admin::Foos', :controller_name
+ assert_name g, %w(admin), :controller_class_path
+ assert_name g, 'Admin::Foos', :controller_class_name
+ assert_name g, 'admin/foos', :controller_file_path
+ assert_name g, 'foos', :controller_file_name
+ assert_name g, 'admin.foos', :controller_i18n_scope
+ end
+
protected
def assert_name(generator, value, method)
diff --git a/railties/test/generators/namespaced_generators_test.rb b/railties/test/generators/namespaced_generators_test.rb
index e17925ff65..d677c21f15 100644
--- a/railties/test/generators/namespaced_generators_test.rb
+++ b/railties/test/generators/namespaced_generators_test.rb
@@ -63,7 +63,7 @@ class NamespacedControllerGeneratorTest < NamespacedGeneratorTestCase
def test_routes_should_not_be_namespaced
run_generator
- assert_file "config/routes.rb", /get "account\/foo"/, /get "account\/bar"/
+ assert_file "config/routes.rb", /get 'account\/foo'/, /get 'account\/bar'/
end
def test_invokes_default_template_engine_even_with_no_action
diff --git a/railties/test/generators/plugin_generator_test.rb b/railties/test/generators/plugin_generator_test.rb
index 068eb66bc6..7180efee41 100644
--- a/railties/test/generators/plugin_generator_test.rb
+++ b/railties/test/generators/plugin_generator_test.rb
@@ -35,6 +35,12 @@ class PluginGeneratorTest < Rails::Generators::TestCase
content = capture(:stderr){ run_generator [File.join(destination_root, "43things")] }
assert_equal "Invalid plugin name 43things. Please give a name which does not start with numbers.\n", content
+
+ content = capture(:stderr){ run_generator [File.join(destination_root, "plugin")] }
+ assert_equal "Invalid plugin name plugin. Please give a name which does not match one of the reserved rails words.\n", content
+
+ content = capture(:stderr){ run_generator [File.join(destination_root, "Digest")] }
+ assert_equal "Invalid plugin name Digest, constant Digest is already in use. Please choose another plugin name.\n", content
end
def test_camelcase_plugin_name_underscores_filenames
@@ -58,6 +64,20 @@ class PluginGeneratorTest < Rails::Generators::TestCase
assert_file "test/integration/navigation_test.rb", /ActionDispatch::IntegrationTest/
end
+ def test_inclusion_of_a_debugger
+ run_generator [destination_root, '--full']
+ if defined?(JRUBY_VERSION)
+ assert_file "Gemfile" do |content|
+ assert_no_match(/byebug/, content)
+ assert_no_match(/debugger/, content)
+ end
+ elsif RUBY_VERSION < '2.0.0'
+ assert_file "Gemfile", /# gem 'debugger'/
+ else
+ assert_file "Gemfile", /# gem 'byebug'/
+ end
+ end
+
def test_generating_test_files_in_full_mode_without_unit_test_files
run_generator [destination_root, "-T", "--full"]
@@ -139,7 +159,7 @@ class PluginGeneratorTest < Rails::Generators::TestCase
assert_match(/bukkits/, contents)
end
assert_match(/run bundle install/, result)
- assert_match(/Using bukkits \(0\.0\.1\)/, result)
+ assert_match(/Using bukkits \(?0\.0\.1\)?/, result)
assert_match(/Your bundle is complete/, result)
assert_equal 1, result.scan("Your bundle is complete").size
end
@@ -168,22 +188,22 @@ class PluginGeneratorTest < Rails::Generators::TestCase
run_generator
FileUtils.cd destination_root
quietly { system 'bundle install' }
- assert_match(/1 runs, 1 assertions, 0 failures, 0 errors/, `bundle exec rake test`)
+ assert_match(/1 runs, 1 assertions, 0 failures, 0 errors/, `bundle exec rake test 2>&1`)
end
def test_ensure_that_tests_works_in_full_mode
run_generator [destination_root, "--full", "--skip_active_record"]
FileUtils.cd destination_root
quietly { system 'bundle install' }
- assert_match(/1 runs, 1 assertions, 0 failures, 0 errors/, `bundle exec rake test`)
+ assert_match(/1 runs, 1 assertions, 0 failures, 0 errors/, `bundle exec rake test 2>&1`)
end
def test_ensure_that_migration_tasks_work_with_mountable_option
run_generator [destination_root, "--mountable"]
FileUtils.cd destination_root
quietly { system 'bundle install' }
- `bundle exec rake db:migrate`
- assert_equal 0, $?.exitstatus
+ output = `bundle exec rake db:migrate 2>&1`
+ assert $?.success?, "Command failed: #{output}"
end
def test_creating_engine_in_full_mode
@@ -292,8 +312,8 @@ class PluginGeneratorTest < Rails::Generators::TestCase
assert_no_file "bukkits.gemspec"
assert_file "Gemfile" do |contents|
assert_no_match('gemspec', contents)
- assert_match(/gem "rails", "~> #{Rails.version}"/, contents)
- assert_match(/group :development do\n gem "sqlite3"\nend/, contents)
+ assert_match(/gem 'rails', '~> #{Rails.version}'/, contents)
+ assert_match_sqlite3(contents)
assert_no_match(/# gem "jquery-rails"/, contents)
end
end
@@ -303,13 +323,13 @@ class PluginGeneratorTest < Rails::Generators::TestCase
assert_no_file "bukkits.gemspec"
assert_file "Gemfile" do |contents|
assert_no_match('gemspec', contents)
- assert_match(/gem "rails", "~> #{Rails.version}"/, contents)
- assert_match(/group :development do\n gem "sqlite3"\nend/, contents)
+ assert_match(/gem 'rails', '~> #{Rails.version}'/, contents)
+ assert_match_sqlite3(contents)
end
end
def test_creating_plugin_in_app_directory_adds_gemfile_entry
- # simulate application existance
+ # simulate application existence
gemfile_path = "#{Rails.root}/Gemfile"
Object.const_set('APP_PATH', Rails.root)
FileUtils.touch gemfile_path
@@ -323,7 +343,7 @@ class PluginGeneratorTest < Rails::Generators::TestCase
end
def test_skipping_gemfile_entry
- # simulate application existance
+ # simulate application existence
gemfile_path = "#{Rails.root}/Gemfile"
Object.const_set('APP_PATH', Rails.root)
FileUtils.touch gemfile_path
@@ -338,6 +358,52 @@ class PluginGeneratorTest < Rails::Generators::TestCase
FileUtils.rm gemfile_path
end
+ def test_generating_controller_inside_mountable_engine
+ run_generator [destination_root, "--mountable"]
+
+ capture(:stdout) do
+ `#{destination_root}/bin/rails g controller admin/dashboard foo`
+ end
+
+ assert_file "config/routes.rb" do |contents|
+ assert_match(/namespace :admin/, contents)
+ assert_no_match(/namespace :bukkit/, contents)
+ end
+ end
+
+ def test_git_name_and_email_in_gemspec_file
+ name = `git config user.name`.chomp rescue "TODO: Write your name"
+ email = `git config user.email`.chomp rescue "TODO: Write your email address"
+
+ run_generator [destination_root]
+ assert_file "bukkits.gemspec" do |contents|
+ assert_match(/#{Regexp.escape(name)}/, contents)
+ assert_match(/#{Regexp.escape(email)}/, contents)
+ end
+ end
+
+ def test_git_name_in_license_file
+ name = `git config user.name`.chomp rescue "TODO: Write your name"
+
+ run_generator [destination_root]
+ assert_file "MIT-LICENSE" do |contents|
+ assert_match(/#{Regexp.escape(name)}/, contents)
+ end
+ end
+
+ def test_no_details_from_git_when_skip_git
+ name = "TODO: Write your name"
+ email = "TODO: Write your email address"
+
+ run_generator [destination_root, '--skip-git']
+ assert_file "MIT-LICENSE" do |contents|
+ assert_match(/#{Regexp.escape(name)}/, contents)
+ end
+ assert_file "bukkits.gemspec" do |contents|
+ assert_match(/#{Regexp.escape(name)}/, contents)
+ assert_match(/#{Regexp.escape(email)}/, contents)
+ end
+ end
protected
def action(*args, &block)
@@ -347,4 +413,12 @@ protected
def default_files
::DEFAULT_PLUGIN_FILES
end
+
+ def assert_match_sqlite3(contents)
+ unless defined?(JRUBY_VERSION)
+ assert_match(/group :development do\n gem 'sqlite3'\nend/, contents)
+ else
+ assert_match(/group :development do\n gem 'activerecord-jdbcsqlite3-adapter'\nend/, contents)
+ end
+ end
end
diff --git a/railties/test/generators/resource_generator_test.rb b/railties/test/generators/resource_generator_test.rb
index 3d4e694361..dcdff22152 100644
--- a/railties/test/generators/resource_generator_test.rb
+++ b/railties/test/generators/resource_generator_test.rb
@@ -63,19 +63,19 @@ class ResourceGeneratorTest < Rails::Generators::TestCase
content = run_generator ["accounts".freeze]
assert_file "app/models/account.rb", /class Account < ActiveRecord::Base/
assert_file "test/models/account_test.rb", /class AccountTest/
- assert_match(/Plural version of the model detected, using singularized version. Override with --force-plural./, content)
+ assert_match(/\[WARNING\] The model name 'accounts' was recognized as a plural, using the singular 'account' instead\. Override with --force-plural or setup custom inflection rules for this noun before running the generator\./, content)
end
def test_plural_names_can_be_forced
content = run_generator ["accounts", "--force-plural"]
assert_file "app/models/accounts.rb", /class Accounts < ActiveRecord::Base/
assert_file "test/models/accounts_test.rb", /class AccountsTest/
- assert_no_match(/Plural version of the model detected/, content)
+ assert_no_match(/\[WARNING\]/, content)
end
def test_mass_nouns_do_not_throw_warnings
content = run_generator ["sheep".freeze]
- assert_no_match(/Plural version of the model detected/, content)
+ assert_no_match(/\[WARNING\]/, content)
end
def test_route_is_removed_on_revoke
diff --git a/railties/test/generators/scaffold_controller_generator_test.rb b/railties/test/generators/scaffold_controller_generator_test.rb
index 013cb78252..3c1123b53d 100644
--- a/railties/test/generators/scaffold_controller_generator_test.rb
+++ b/railties/test/generators/scaffold_controller_generator_test.rb
@@ -160,10 +160,12 @@ class ScaffoldControllerGeneratorTest < Rails::Generators::TestCase
Unknown::Generators.send :remove_const, :ActiveModel
end
- def test_new_hash_style
- run_generator
- assert_file "app/controllers/users_controller.rb" do |content|
- assert_match(/render action: 'new'/, content)
+ def test_model_name_option
+ run_generator ["Admin::User", "--model-name=User"]
+ assert_file "app/controllers/admin/users_controller.rb" do |content|
+ assert_instance_method :index, content do |m|
+ assert_match("@users = User.all", m)
+ end
end
end
end
diff --git a/railties/test/generators/shared_generator_tests.rb b/railties/test/generators/shared_generator_tests.rb
index 7184639d23..b998fef42e 100644
--- a/railties/test/generators/shared_generator_tests.rb
+++ b/railties/test/generators/shared_generator_tests.rb
@@ -26,11 +26,17 @@ module SharedGeneratorTests
default_files.each { |path| assert_file path }
end
- def test_generation_runs_bundle_install
- generator([destination_root]).expects(:bundle_command).with('install').once
+ def assert_generates_with_bundler(options = {})
+ generator([destination_root], options)
+ generator.expects(:bundle_command).with('install').once
+ generator.stubs(:bundle_command).with('exec spring binstub --all')
quietly { generator.invoke_all }
end
+ def test_generation_runs_bundle_install
+ assert_generates_with_bundler
+ end
+
def test_plugin_new_generate_pretend
run_generator ["testapp", "--pretend"]
default_files.each{ |path| assert_no_file File.join("testapp",path) }
@@ -72,9 +78,12 @@ module SharedGeneratorTests
end
def test_template_raises_an_error_with_invalid_path
- content = capture(:stderr){ run_generator([destination_root, "-m", "non/existent/path"]) }
- assert_match(/The template \[.*\] could not be loaded/, content)
- assert_match(/non\/existent\/path/, content)
+ quietly do
+ content = capture(:stderr){ run_generator([destination_root, "-m", "non/existent/path"]) }
+
+ assert_match(/The template \[.*\] could not be loaded/, content)
+ assert_match(/non\/existent\/path/, content)
+ end
end
def test_template_is_executed_when_supplied
@@ -83,7 +92,7 @@ module SharedGeneratorTests
template.instance_eval "def read; self; end" # Make the string respond to read
generator([destination_root], template: path).expects(:open).with(path, 'Accept' => 'application/x-thor-template').returns(template)
- assert_match(/It works!/, capture(:stdout) { generator.invoke_all })
+ quietly { assert_match(/It works!/, capture(:stdout) { generator.invoke_all }) }
end
def test_template_is_executed_when_supplied_an_https_path
@@ -92,19 +101,17 @@ module SharedGeneratorTests
template.instance_eval "def read; self; end" # Make the string respond to read
generator([destination_root], template: path).expects(:open).with(path, 'Accept' => 'application/x-thor-template').returns(template)
- assert_match(/It works!/, capture(:stdout) { generator.invoke_all })
+ quietly { assert_match(/It works!/, capture(:stdout) { generator.invoke_all }) }
end
def test_dev_option
- generator([destination_root], dev: true).expects(:bundle_command).with('install').once
- quietly { generator.invoke_all }
+ assert_generates_with_bundler dev: true
rails_path = File.expand_path('../../..', Rails.root)
assert_file 'Gemfile', /^gem\s+["']rails["'],\s+path:\s+["']#{Regexp.escape(rails_path)}["']$/
end
def test_edge_option
- generator([destination_root], edge: true).expects(:bundle_command).with('install').once
- quietly { generator.invoke_all }
+ assert_generates_with_bundler edge: true
assert_file 'Gemfile', %r{^gem\s+["']rails["'],\s+github:\s+["']#{Regexp.escape("rails/rails")}["']$}
end
diff --git a/railties/test/generators/task_generator_test.rb b/railties/test/generators/task_generator_test.rb
index 9399be9510..d5bd44b9db 100644
--- a/railties/test/generators/task_generator_test.rb
+++ b/railties/test/generators/task_generator_test.rb
@@ -7,6 +7,18 @@ class TaskGeneratorTest < Rails::Generators::TestCase
def test_task_is_created
run_generator
- assert_file "lib/tasks/feeds.rake", /namespace :feeds/
+ assert_file "lib/tasks/feeds.rake" do |content|
+ assert_match(/namespace :feeds/, content)
+ assert_match(/task foo:/, content)
+ assert_match(/task bar:/, content)
+ end
+ end
+
+ def test_task_on_revoke
+ task_path = 'lib/tasks/feeds.rake'
+ run_generator
+ assert_file task_path
+ run_generator ['feeds'], behavior: :revoke
+ assert_no_file task_path
end
end
diff --git a/railties/test/generators_test.rb b/railties/test/generators_test.rb
index 5130b285a9..0b4edafaca 100644
--- a/railties/test/generators_test.rb
+++ b/railties/test/generators_test.rb
@@ -15,14 +15,22 @@ class GeneratorsTest < Rails::Generators::TestCase
end
def test_simple_invoke
- assert File.exists?(File.join(@path, 'generators', 'model_generator.rb'))
+ assert File.exist?(File.join(@path, 'generators', 'model_generator.rb'))
TestUnit::Generators::ModelGenerator.expects(:start).with(["Account"], {})
Rails::Generators.invoke("test_unit:model", ["Account"])
end
def test_invoke_when_generator_is_not_found
- output = capture(:stdout){ Rails::Generators.invoke :unknown }
- assert_equal "Could not find generator unknown.\n", output
+ name = :unknown
+ output = capture(:stdout){ Rails::Generators.invoke name }
+ assert_match "Could not find generator '#{name}'", output
+ assert_match "`rails generate --help`", output
+ end
+
+ def test_generator_suggestions
+ name = :migrationz
+ output = capture(:stdout){ Rails::Generators.invoke name }
+ assert_match "Maybe you meant 'migration'", output
end
def test_help_when_a_generator_with_required_arguments_is_invoked_without_arguments
@@ -31,7 +39,7 @@ class GeneratorsTest < Rails::Generators::TestCase
end
def test_should_give_higher_preference_to_rails_generators
- assert File.exists?(File.join(@path, 'generators', 'model_generator.rb'))
+ assert File.exist?(File.join(@path, 'generators', 'model_generator.rb'))
Rails::Generators::ModelGenerator.expects(:start).with(["Account"], {})
warnings = capture(:stderr){ Rails::Generators.invoke :model, ["Account"] }
assert warnings.empty?
diff --git a/railties/test/isolation/abstract_unit.rb b/railties/test/isolation/abstract_unit.rb
index 913e2b5e29..6c50911666 100644
--- a/railties/test/isolation/abstract_unit.rb
+++ b/railties/test/isolation/abstract_unit.rb
@@ -93,7 +93,8 @@ module TestHelpers
# Build an application by invoking the generator and going through the whole stack.
def build_app(options = {})
@prev_rails_env = ENV['RAILS_ENV']
- ENV['RAILS_ENV'] = 'development'
+ ENV['RAILS_ENV'] = "development"
+ ENV['SECRET_KEY_BASE'] ||= SecureRandom.hex(16)
FileUtils.rm_rf(app_path)
FileUtils.cp_r(app_template_path, app_path)
@@ -117,9 +118,26 @@ module TestHelpers
end
end
+ File.open("#{app_path}/config/database.yml", "w") do |f|
+ f.puts <<-YAML
+ default: &default
+ adapter: sqlite3
+ pool: 5
+ timeout: 5000
+ development:
+ <<: *default
+ database: db/development.sqlite3
+ test:
+ <<: *default
+ database: db/test.sqlite3
+ production:
+ <<: *default
+ database: db/production.sqlite3
+ YAML
+ end
+
add_to_config <<-RUBY
config.eager_load = false
- config.secret_key_base = "3b7cd727ee24e8444053437c36cc66c4"
config.session_store :cookie_store, key: "_myapp_session"
config.active_support.deprecation = :log
config.action_controller.allow_forgery_protection = false
@@ -139,7 +157,7 @@ module TestHelpers
app = Class.new(Rails::Application)
app.config.eager_load = false
- app.config.secret_key_base = "3b7cd727ee24e8444053437c36cc66c4"
+ app.secrets.secret_key_base = "3b7cd727ee24e8444053437c36cc66c4"
app.config.session_store :cookie_store, key: "_myapp_session"
app.config.active_support.deprecation = :log
diff --git a/railties/test/paths_test.rb b/railties/test/paths_test.rb
index 178c505865..ed4559ec6f 100644
--- a/railties/test/paths_test.rb
+++ b/railties/test/paths_test.rb
@@ -3,7 +3,7 @@ require 'rails/paths'
class PathsTest < ActiveSupport::TestCase
def setup
- File.stubs(:exists?).returns(true)
+ File.stubs(:exist?).returns(true)
@root = Rails::Paths::Root.new("/foo/bar")
end
diff --git a/railties/test/rails_info_controller_test.rb b/railties/test/rails_info_controller_test.rb
index e45a5228a1..a9b237d0a5 100644
--- a/railties/test/rails_info_controller_test.rb
+++ b/railties/test/rails_info_controller_test.rb
@@ -1,7 +1,5 @@
require 'abstract_unit'
-ActionController::Base.superclass.send(:include, ActionView::Layouts)
-
module ActionController
class Base
include ActionController::Testing
diff --git a/railties/test/rails_info_test.rb b/railties/test/rails_info_test.rb
index 44a5fd1904..4bec302ff8 100644
--- a/railties/test/rails_info_test.rb
+++ b/railties/test/rails_info_test.rb
@@ -66,16 +66,6 @@ class InfoTest < ActiveSupport::TestCase
end
protected
- def svn_info=(info)
- Rails::Info.module_eval do
- class << self
- def svn_info
- info
- end
- end
- end
- end
-
def properties
Rails::Info.properties
end
diff --git a/railties/test/railties/engine_test.rb b/railties/test/railties/engine_test.rb
index d095535abd..ec64ce5941 100644
--- a/railties/test/railties/engine_test.rb
+++ b/railties/test/railties/engine_test.rb
@@ -34,6 +34,7 @@ module RailtiesTest
test "serving sprocket's assets" do
@plugin.write "app/assets/javascripts/engine.js.erb", "<%= :alert %>();"
+ add_to_env_config "development", "config.assets.digest = false"
boot_rails
require 'rack/test'
@@ -90,8 +91,8 @@ module RailtiesTest
Dir.chdir(app_path) do
output = `bundle exec rake bukkits:install:migrations`
- assert File.exists?("#{app_path}/db/migrate/2_create_users.bukkits.rb")
- assert File.exists?("#{app_path}/db/migrate/3_add_last_name_to_users.bukkits.rb")
+ assert File.exist?("#{app_path}/db/migrate/2_create_users.bukkits.rb")
+ assert File.exist?("#{app_path}/db/migrate/3_add_last_name_to_users.bukkits.rb")
assert_match(/Copied migration 2_create_users.bukkits.rb from bukkits/, output)
assert_match(/Copied migration 3_add_last_name_to_users.bukkits.rb from bukkits/, output)
assert_match(/NOTE: Migration 3_create_sessions.rb from bukkits has been skipped/, output)
@@ -111,6 +112,38 @@ module RailtiesTest
end
end
+ test 'respects the order of railties when installing migrations' do
+ @blog = engine "blog" do |plugin|
+ plugin.write "lib/blog.rb", <<-RUBY
+ module Blog
+ class Engine < ::Rails::Engine
+ end
+ end
+ RUBY
+ end
+
+ @plugin.write "db/migrate/1_create_users.rb", <<-RUBY
+ class CreateUsers < ActiveRecord::Migration
+ end
+ RUBY
+
+ @blog.write "db/migrate/2_create_blogs.rb", <<-RUBY
+ class CreateBlogs < ActiveRecord::Migration
+ end
+ RUBY
+
+ add_to_config("config.railties_order = [Bukkits::Engine, Blog::Engine, :all, :main_app]")
+
+ boot_rails
+
+ Dir.chdir(app_path) do
+ output = `bundle exec rake railties:install:migrations`.split("\n")
+
+ assert_match(/Copied migration \d+_create_users.bukkits.rb from bukkits/, output.first)
+ assert_match(/Copied migration \d+_create_blogs.blog_engine.rb from blog_engine/, output.last)
+ end
+ end
+
test "mountable engine should copy migrations within engine_path" do
@plugin.write "lib/bukkits.rb", <<-RUBY
module Bukkits
@@ -136,7 +169,7 @@ module RailtiesTest
Dir.chdir(@plugin.path) do
output = `bundle exec rake app:bukkits:install:migrations`
- assert File.exists?("#{app_path}/db/migrate/0_add_first_name_to_users.bukkits.rb")
+ assert File.exist?("#{app_path}/db/migrate/0_add_first_name_to_users.bukkits.rb")
assert_match(/Copied migration 0_add_first_name_to_users.bukkits.rb from bukkits/, output)
assert_equal 1, Dir["#{app_path}/db/migrate/*.rb"].length
end
@@ -399,7 +432,7 @@ YAML
assert $plugin_initializer
end
- test "midleware referenced in configuration" do
+ test "middleware referenced in configuration" do
@plugin.write "lib/bukkits.rb", <<-RUBY
class Bukkits
def initialize(app)
@@ -592,11 +625,15 @@ YAML
@plugin.write "app/models/bukkits/post.rb", <<-RUBY
module Bukkits
class Post
- extend ActiveModel::Naming
+ include ActiveModel::Model
def to_param
"1"
end
+
+ def persisted?
+ true
+ end
end
end
RUBY
@@ -704,8 +741,7 @@ YAML
@plugin.write "app/models/bukkits/post.rb", <<-RUBY
module Bukkits
class Post
- extend ActiveModel::Naming
- include ActiveModel::Conversion
+ include ActiveModel::Model
attr_accessor :title
def to_param
@@ -1077,6 +1113,7 @@ YAML
RUBY
add_to_config("config.railties_order = [:all, :main_app, Blog::Engine]")
+ add_to_env_config "development", "config.assets.digest = false"
boot_rails
diff --git a/railties/test/railties/mounted_engine_test.rb b/railties/test/railties/mounted_engine_test.rb
index 0ef2ff2e2e..fb2071c7c3 100644
--- a/railties/test/railties/mounted_engine_test.rb
+++ b/railties/test/railties/mounted_engine_test.rb
@@ -88,18 +88,14 @@ module ApplicationTests
@plugin.write "app/models/blog/post.rb", <<-RUBY
module Blog
class Post
- extend ActiveModel::Naming
+ include ActiveModel::Model
def id
44
end
- def to_param
- id.to_s
- end
-
- def new_record?
- false
+ def persisted?
+ true
end
end
end
diff --git a/railties/test/railties/railtie_test.rb b/railties/test/railties/railtie_test.rb
index 4cbd4822be..5042d628cf 100644
--- a/railties/test/railties/railtie_test.rb
+++ b/railties/test/railties/railtie_test.rb
@@ -72,6 +72,14 @@ module RailtiesTest
assert $to_prepare
end
+ test "railtie have access to application in before_configuration callbacks" do
+ $before_configuration = false
+ class Foo < Rails::Railtie ; config.before_configuration { $before_configuration = Rails.root.to_path } ; end
+ assert_not $before_configuration
+ require "#{app_path}/config/environment"
+ assert_equal app_path, $before_configuration
+ end
+
test "railtie can add after_initialize callbacks" do
$after_initialize = false
class Foo < Rails::Railtie ; config.after_initialize { $after_initialize = true } ; end
diff --git a/railties/test/version_test.rb b/railties/test/version_test.rb
new file mode 100644
index 0000000000..f270d8f0c9
--- /dev/null
+++ b/railties/test/version_test.rb
@@ -0,0 +1,12 @@
+require 'abstract_unit'
+
+class VersionTest < ActiveSupport::TestCase
+ def test_rails_version_returns_a_string
+ assert Rails.version.is_a? String
+ end
+
+ def test_rails_gem_version_returns_a_correct_gem_version_object
+ assert Rails.gem_version.is_a? Gem::Version
+ assert_equal Rails.version, Rails.gem_version.to_s
+ end
+end