aboutsummaryrefslogtreecommitdiffstats
path: root/railties
diff options
context:
space:
mode:
Diffstat (limited to 'railties')
-rw-r--r--railties/CHANGELOG.md79
-rw-r--r--railties/lib/rails/application/bootstrap.rb2
-rw-r--r--railties/lib/rails/application/configuration.rb8
-rw-r--r--railties/lib/rails/application/default_middleware_stack.rb38
-rw-r--r--railties/lib/rails/application/finisher.rb6
-rw-r--r--railties/lib/rails/application_controller.rb2
-rw-r--r--railties/lib/rails/commands/server.rb39
-rw-r--r--railties/lib/rails/commands/test.rb10
-rw-r--r--railties/lib/rails/configuration.rb3
-rw-r--r--railties/lib/rails/console/app.rb5
-rw-r--r--railties/lib/rails/engine.rb12
-rw-r--r--railties/lib/rails/engine/commands.rb6
-rw-r--r--railties/lib/rails/generators.rb19
-rw-r--r--railties/lib/rails/generators/actions.rb22
-rw-r--r--railties/lib/rails/generators/app_base.rb4
-rw-r--r--railties/lib/rails/generators/base.rb6
-rw-r--r--railties/lib/rails/generators/erb/scaffold/templates/index.html.erb2
-rw-r--r--railties/lib/rails/generators/named_base.rb8
-rw-r--r--railties/lib/rails/generators/rails/app/app_generator.rb41
-rw-r--r--railties/lib/rails/generators/rails/app/templates/Gemfile14
-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/assets/stylesheets/application.css3
-rw-r--r--railties/lib/rails/generators/rails/app/templates/app/controllers/application_controller.rb.tt4
-rw-r--r--railties/lib/rails/generators/rails/app/templates/bin/setup14
-rw-r--r--railties/lib/rails/generators/rails/app/templates/bin/update28
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/application.rb7
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt14
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt3
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/initializers/cors.rb14
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/initializers/wrap_parameters.rb.tt2
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/routes.rb55
-rw-r--r--railties/lib/rails/generators/rails/app/templates/gitignore3
-rw-r--r--railties/lib/rails/generators/rails/plugin/plugin_generator.rb35
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/app/controllers/%namespaced_name%/application_controller.rb.tt2
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%/engine.rb1
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%/version.rb2
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/rails/javascripts.js2
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/rails/stylesheets.css3
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/test/integration/navigation_test.rb4
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/test/test_helper.rb3
-rw-r--r--railties/lib/rails/generators/rails/resource_route/resource_route_generator.rb1
-rw-r--r--railties/lib/rails/generators/rails/scaffold/scaffold_generator.rb3
-rw-r--r--railties/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb5
-rw-r--r--railties/lib/rails/generators/rails/scaffold_controller/templates/api_controller.rb61
-rw-r--r--railties/lib/rails/generators/test_unit/controller/templates/functional_test.rb6
-rw-r--r--railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb15
-rw-r--r--railties/lib/rails/generators/test_unit/scaffold/templates/api_functional_test.rb43
-rw-r--r--railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb5
-rw-r--r--railties/lib/rails/generators/testing/assertions.rb2
-rw-r--r--railties/lib/rails/mailers_controller.rb2
-rw-r--r--railties/lib/rails/paths.rb8
-rw-r--r--railties/lib/rails/tasks.rb6
-rw-r--r--railties/lib/rails/tasks/dev.rake15
-rw-r--r--railties/lib/rails/tasks/restart.rake1
-rw-r--r--railties/lib/rails/test_help.rb7
-rw-r--r--railties/lib/rails/test_unit/minitest_plugin.rb52
-rw-r--r--railties/lib/rails/test_unit/reporter.rb22
-rw-r--r--railties/lib/rails/test_unit/runner.rb137
-rw-r--r--railties/lib/rails/test_unit/test_requirer.rb28
-rw-r--r--railties/lib/rails/test_unit/testing.rake15
-rw-r--r--railties/test/application/asset_debugging_test.rb2
-rw-r--r--railties/test/application/assets_test.rb5
-rw-r--r--railties/test/application/configuration_test.rb13
-rw-r--r--railties/test/application/console_test.rb12
-rw-r--r--railties/test/application/generators_test.rb35
-rw-r--r--railties/test/application/initializers/frameworks_test.rb33
-rw-r--r--railties/test/application/initializers/i18n_test.rb73
-rw-r--r--railties/test/application/middleware_test.rb58
-rw-r--r--railties/test/application/multiple_applications_test.rb2
-rw-r--r--railties/test/application/per_request_digest_cache_test.rb63
-rw-r--r--railties/test/application/rake/dbs_test.rb38
-rw-r--r--railties/test/application/rake/dev_test.rb35
-rw-r--r--railties/test/application/rake/migrations_test.rb98
-rw-r--r--railties/test/application/rake/notes_test.rb7
-rw-r--r--railties/test/application/rake/restart_test.rb12
-rw-r--r--railties/test/application/rake_test.rb94
-rw-r--r--railties/test/application/runner_test.rb20
-rw-r--r--railties/test/application/test_runner_test.rb167
-rw-r--r--railties/test/application/test_test.rb6
-rw-r--r--railties/test/commands/server_test.rb16
-rw-r--r--railties/test/generators/actions_test.rb87
-rw-r--r--railties/test/generators/api_app_generator_test.rb97
-rw-r--r--railties/test/generators/app_generator_test.rb33
-rw-r--r--railties/test/generators/plugin_generator_test.rb63
-rw-r--r--railties/test/generators/scaffold_controller_generator_test.rb69
-rw-r--r--railties/test/generators/scaffold_generator_test.rb140
-rw-r--r--railties/test/generators/shared_generator_tests.rb11
-rw-r--r--railties/test/paths_test.rb13
-rw-r--r--railties/test/railties/generators_test.rb8
-rw-r--r--railties/test/test_unit/reporter_test.rb14
-rw-r--r--railties/test/test_unit/runner_test.rb111
91 files changed, 1773 insertions, 623 deletions
diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md
index 02fdaf09e0..21adac272d 100644
--- a/railties/CHANGELOG.md
+++ b/railties/CHANGELOG.md
@@ -1,3 +1,82 @@
+* Plugins generated using `rails plugin new` are now generated with the
+ version number set to 0.1.0.
+
+ *Daniel Morris*
+
+* `I18n.load_path` is now reloaded under development so there's no need to
+ restart the server to make new locale files available. Also, I18n will no
+ longer raise for deleted locale files.
+
+ *Kir Shatrov*
+
+* Add `bin/update` script to update development environment automatically.
+
+ *Mehmet Emin İNAÇ*
+
+* Fix STATS_DIRECTORIES already defined warning when running rake from within
+ the top level directory of an engine that has a test app.
+
+ Fixes #20510
+
+ *Ersin Akinci*
+
+* Make enabling or disabling caching in development mode possible with
+ rake dev:cache.
+
+ Running rake dev:cache will create or remove tmp/caching-dev.txt. When this
+ file exists config.action_controller.perform_caching will be set to true in
+ config/environments/development.rb.
+
+ Additionally, a server can be started with either --dev-caching or
+ --no-dev-caching included to toggle caching on startup.
+
+ *Jussi Mertanen*, *Chuck Callebs*
+
+* Add a `--api` option in order to generate plugins that can be added
+ inside an API application.
+
+ *Robin Dupret*
+
+* Fix `NoMethodError` when generating a scaffold inside a full engine.
+
+ *Yuji Yaginuma*
+
+* Adding support for passing a block to the `add_source` action of a custom generator
+
+ *Mike Dalton*, *Hirofumi Wakasugi*
+
+* `assert_file` understands paths with special characters
+ (eg. `v0.1.4~alpha+nightly`).
+
+ *Diego Carrion*
+
+* Remove ContentLength middleware from the defaults. If you want it, just
+ add it as a middleware in your config.
+
+ *Egg McMuffin*
+
+* Make it possible to customize the executable inside rerun snippets.
+
+ *Yves Senn*
+
+* Add support for API only apps.
+ Middleware stack was slimmed down and it has only the needed
+ middleware for API apps & generators generates the right files,
+ folders and configurations.
+
+ *Santiago Pastorino & Jorge Bejar*
+
+* Make generated scaffold functional tests work inside engines.
+
+ *Yuji Yaginuma*
+
+* Generator a `.keep` file in the `tmp` folder by default as many scripts
+ assume the existence of this folder and most would fail if it is absent.
+
+ See #20299.
+
+ *Yoong Kang Lim*, *Sunny Juneja*
+
* `config.static_index` configures directory `index.html` filename
Set `config.static_index` to serve a static directory index file not named
diff --git a/railties/lib/rails/application/bootstrap.rb b/railties/lib/rails/application/bootstrap.rb
index 0f4d932749..9baf8aa742 100644
--- a/railties/lib/rails/application/bootstrap.rb
+++ b/railties/lib/rails/application/bootstrap.rb
@@ -63,7 +63,7 @@ INFO
Rails.cache = ActiveSupport::Cache.lookup_store(config.cache_store)
if Rails.cache.respond_to?(:middleware)
- config.middleware.insert_before("Rack::Runtime", Rails.cache.middleware)
+ config.middleware.insert_before(::Rack::Runtime, Rails.cache.middleware)
end
end
end
diff --git a/railties/lib/rails/application/configuration.rb b/railties/lib/rails/application/configuration.rb
index 78a47fcda9..4fc7a1db62 100644
--- a/railties/lib/rails/application/configuration.rb
+++ b/railties/lib/rails/application/configuration.rb
@@ -16,7 +16,7 @@ module Rails
:beginning_of_week, :filter_redirect, :x
attr_writer :log_level
- attr_reader :encoding
+ attr_reader :encoding, :api_only
def initialize(*)
super
@@ -49,6 +49,7 @@ module Rails
@eager_load = nil
@secret_token = nil
@secret_key_base = nil
+ @api_only = false
@x = Custom.new
end
@@ -60,6 +61,11 @@ module Rails
end
end
+ def api_only=(value)
+ @api_only = value
+ generators.api_only = value
+ end
+
def paths
@paths ||= begin
paths = super
diff --git a/railties/lib/rails/application/default_middleware_stack.rb b/railties/lib/rails/application/default_middleware_stack.rb
index 503977b395..88eade5c5a 100644
--- a/railties/lib/rails/application/default_middleware_stack.rb
+++ b/railties/lib/rails/application/default_middleware_stack.rb
@@ -18,7 +18,7 @@ module Rails
middleware.use ::Rack::Sendfile, config.action_dispatch.x_sendfile_header
if config.serve_static_files
- middleware.use ::ActionDispatch::Static, paths["public"].first, config.static_cache_control, config.static_index
+ middleware.use ::ActionDispatch::Static, paths["public"].first, config.static_cache_control, index: config.static_index
end
if rack_cache = load_rack_cache
@@ -26,9 +26,29 @@ module Rails
middleware.use ::Rack::Cache, rack_cache
end
- middleware.use ::Rack::Lock unless allow_concurrency?
+ if config.allow_concurrency == false
+ # User has explicitly opted out of concurrent request
+ # handling: presumably their code is not threadsafe
+
+ middleware.use ::Rack::Lock
+
+ elsif config.allow_concurrency == :unsafe
+ # Do nothing, even if we know this is dangerous. This is the
+ # historical behaviour for true.
+
+ else
+ # Default concurrency setting: enabled, but safe
+
+ unless config.cache_classes && config.eager_load
+ # Without cache_classes + eager_load, the load interlock
+ # is required for proper operation
+
+ middleware.use ::ActionDispatch::LoadInterlock
+ end
+ end
+
middleware.use ::Rack::Runtime
- middleware.use ::Rack::MethodOverride
+ middleware.use ::Rack::MethodOverride unless config.api_only
middleware.use ::ActionDispatch::RequestId
# Must come after Rack::MethodOverride to properly log overridden methods
@@ -42,9 +62,9 @@ module Rails
end
middleware.use ::ActionDispatch::Callbacks
- middleware.use ::ActionDispatch::Cookies
+ middleware.use ::ActionDispatch::Cookies unless config.api_only
- if config.session_store
+ if !config.api_only && config.session_store
if config.force_ssl && !config.session_options.key?(:secure)
config.session_options[:secure] = true
end
@@ -65,14 +85,6 @@ module Rails
config.reload_classes_only_on_change != true || app.reloaders.map(&:updated?).any?
end
- def allow_concurrency?
- if config.allow_concurrency.nil?
- config.cache_classes && config.eager_load
- else
- config.allow_concurrency
- end
- end
-
def load_rack_cache
rack_cache = config.action_dispatch.rack_cache
return unless rack_cache
diff --git a/railties/lib/rails/application/finisher.rb b/railties/lib/rails/application/finisher.rb
index 0599e988d9..404e3c3e23 100644
--- a/railties/lib/rails/application/finisher.rb
+++ b/railties/lib/rails/application/finisher.rb
@@ -86,8 +86,10 @@ module Rails
# added in the hook are taken into account.
initializer :set_clear_dependencies_hook, group: :all do
callback = lambda do
- ActiveSupport::DescendantsTracker.clear
- ActiveSupport::Dependencies.clear
+ ActiveSupport::Dependencies.interlock.attempt_unloading do
+ ActiveSupport::DescendantsTracker.clear
+ ActiveSupport::Dependencies.clear
+ end
end
if config.reload_classes_only_on_change
diff --git a/railties/lib/rails/application_controller.rb b/railties/lib/rails/application_controller.rb
index 9a29ec21cf..618a09a5b3 100644
--- a/railties/lib/rails/application_controller.rb
+++ b/railties/lib/rails/application_controller.rb
@@ -6,7 +6,7 @@ class Rails::ApplicationController < ActionController::Base # :nodoc:
def require_local!
unless local_request?
- render text: '<p>For security purposes, this information is only available to local requests.</p>', status: :forbidden
+ render html: '<p>For security purposes, this information is only available to local requests.</p>'.html_safe, status: :forbidden
end
end
diff --git a/railties/lib/rails/commands/server.rb b/railties/lib/rails/commands/server.rb
index 546d3725d8..c8fb58ab05 100644
--- a/railties/lib/rails/commands/server.rb
+++ b/railties/lib/rails/commands/server.rb
@@ -34,6 +34,9 @@ module Rails
opts.on("-P", "--pid=pid", String,
"Specifies the PID file.",
"Default: tmp/pids/server.pid") { |v| options[:pid] = v }
+ opts.on("-C", "--[no-]dev-caching",
+ "Specifies whether to perform caching in development.",
+ "true or false") { |v| options[:caching] = v }
opts.separator ""
@@ -67,6 +70,7 @@ module Rails
print_boot_information
trap(:INT) { exit }
create_tmp_directories
+ setup_dev_caching
log_to_stdout if options[:log_stdout]
super
@@ -77,18 +81,7 @@ module Rails
end
def middleware
- middlewares = []
- middlewares << [::Rack::ContentLength]
-
- # FIXME: add Rack::Lock in the case people are using webrick.
- # This is to remain backwards compatible for those who are
- # running webrick in production. We should consider removing this
- # in development.
- if server.name == 'Rack::Handler::WEBrick'
- middlewares << [::Rack::Lock]
- end
-
- Hash.new(middlewares)
+ Hash.new([])
end
def default_options
@@ -97,13 +90,23 @@ module Rails
DoNotReverseLookup: true,
environment: (ENV['RAILS_ENV'] || ENV['RACK_ENV'] || "development").dup,
daemonize: false,
- pid: File.expand_path("tmp/pids/server.pid"),
- config: File.expand_path("config.ru")
+ caching: false,
+ pid: File.expand_path("tmp/pids/server.pid")
})
end
private
+ def setup_dev_caching
+ return unless options[:environment] == "development"
+
+ if options[:caching] == false
+ delete_cache_file
+ elsif options[:caching]
+ create_cache_file
+ end
+ end
+
def print_boot_information
url = "#{options[:SSLEnable] ? 'https' : 'http'}://#{options[:Host]}:#{options[:Port]}"
puts "=> Booting #{ActiveSupport::Inflector.demodulize(server)}"
@@ -113,6 +116,14 @@ module Rails
puts "=> Ctrl-C to shutdown server" unless options[:daemonize]
end
+ def create_cache_file
+ FileUtils.touch("tmp/caching-dev.txt")
+ end
+
+ def delete_cache_file
+ FileUtils.rm("tmp/caching-dev.txt") if File.exist?("tmp/caching-dev.txt")
+ end
+
def create_tmp_directories
%w(cache pids sockets).each do |dir_to_make|
FileUtils.mkdir_p(File.join(Rails.root, 'tmp', dir_to_make))
diff --git a/railties/lib/rails/commands/test.rb b/railties/lib/rails/commands/test.rb
index 598e224a6f..dd069f081f 100644
--- a/railties/lib/rails/commands/test.rb
+++ b/railties/lib/rails/commands/test.rb
@@ -1,5 +1,9 @@
-require "rails/test_unit/runner"
+require "rails/test_unit/minitest_plugin"
-$: << File.expand_path("../../test", APP_PATH)
+if defined?(ENGINE_ROOT)
+ $: << File.expand_path('test', ENGINE_ROOT)
+else
+ $: << File.expand_path('../../test', APP_PATH)
+end
-Rails::TestRunner.run(ARGV)
+exit Minitest.run(ARGV)
diff --git a/railties/lib/rails/configuration.rb b/railties/lib/rails/configuration.rb
index 76364cea8f..d99d27a756 100644
--- a/railties/lib/rails/configuration.rb
+++ b/railties/lib/rails/configuration.rb
@@ -74,7 +74,7 @@ module Rails
end
class Generators #:nodoc:
- attr_accessor :aliases, :options, :templates, :fallbacks, :colorize_logging
+ attr_accessor :aliases, :options, :templates, :fallbacks, :colorize_logging, :api_only
attr_reader :hidden_namespaces
def initialize
@@ -83,6 +83,7 @@ module Rails
@fallbacks = {}
@templates = []
@colorize_logging = true
+ @api_only = false
@hidden_namespaces = []
end
diff --git a/railties/lib/rails/console/app.rb b/railties/lib/rails/console/app.rb
index 2a69c26deb..ac5836a588 100644
--- a/railties/lib/rails/console/app.rb
+++ b/railties/lib/rails/console/app.rb
@@ -18,6 +18,11 @@ module Rails
app = Rails.application
session = ActionDispatch::Integration::Session.new(app)
yield session if block_given?
+
+ # This makes app.url_for and app.foo_path available in the console
+ session.extend(app.routes.url_helpers)
+ session.extend(app.routes.mounted_helpers)
+
session
end
diff --git a/railties/lib/rails/engine.rb b/railties/lib/rails/engine.rb
index 1dede32dd4..e90d41cbec 100644
--- a/railties/lib/rails/engine.rb
+++ b/railties/lib/rails/engine.rb
@@ -519,17 +519,15 @@ module Rails
# Define the Rack API for this engine.
def call(env)
env.merge!(env_config)
- if env['SCRIPT_NAME']
- env[routes.env_key] = env['SCRIPT_NAME'].dup
- end
+ req = ActionDispatch::Request.new env
+ req.routes = routes
+ req.engine_script_name = req.script_name
app.call(env)
end
# Defines additional Rack env configuration that is added on each call.
def env_config
- @env_config ||= {
- 'action_dispatch.routes' => routes
- }
+ @env_config ||= {}
end
# Defines the routes for this engine. If a block is given to
@@ -589,7 +587,7 @@ module Rails
# I18n load paths are a special case since the ones added
# later have higher priority.
initializer :add_locales do
- config.i18n.railties_load_path.concat(paths["config/locales"].existent)
+ config.i18n.railties_load_path << paths["config/locales"]
end
initializer :add_view_paths do
diff --git a/railties/lib/rails/engine/commands.rb b/railties/lib/rails/engine/commands.rb
index f39f926109..a6d87b78e4 100644
--- a/railties/lib/rails/engine/commands.rb
+++ b/railties/lib/rails/engine/commands.rb
@@ -2,7 +2,8 @@ ARGV << '--help' if ARGV.empty?
aliases = {
"g" => "generate",
- "d" => "destroy"
+ "d" => "destroy",
+ "t" => "test"
}
command = ARGV.shift
@@ -12,7 +13,7 @@ require ENGINE_PATH
engine = ::Rails::Engine.find(ENGINE_ROOT)
case command
-when 'generate', 'destroy'
+when 'generate', 'destroy', 'test'
require 'rails/generators'
Rails::Generators.namespace = engine.railtie_namespace
engine.load_generators
@@ -30,6 +31,7 @@ Usage: rails COMMAND [ARGS]
The common Rails commands available for engines are:
generate Generate new code (short-cut alias: "g")
destroy Undo code generated with "generate" (short-cut alias: "d")
+ test Run tests (short-cut alias: "t")
All commands can be run with -h for more information.
diff --git a/railties/lib/rails/generators.rb b/railties/lib/rails/generators.rb
index a7da92168d..b430cf1909 100644
--- a/railties/lib/rails/generators.rb
+++ b/railties/lib/rails/generators.rb
@@ -33,6 +33,7 @@ module Rails
scaffold_controller: '-c',
stylesheets: '-y',
stylesheet_engine: '-se',
+ scaffold_stylesheet: '-ss',
template_engine: '-e',
test_framework: '-t'
},
@@ -44,6 +45,7 @@ module Rails
DEFAULT_OPTIONS = {
rails: {
+ api: false,
assets: true,
force_plural: false,
helper: true,
@@ -56,12 +58,14 @@ module Rails
scaffold_controller: :scaffold_controller,
stylesheets: true,
stylesheet_engine: :css,
+ scaffold_stylesheet: true,
test_framework: false,
template_engine: :erb
}
}
def self.configure!(config) #:nodoc:
+ api_only! if config.api_only
no_color! unless config.colorize_logging
aliases.deep_merge! config.aliases
options.deep_merge! config.options
@@ -99,6 +103,21 @@ module Rails
@fallbacks ||= {}
end
+ # Configure generators for API only applications. It basically hides
+ # everything that is usually browser related, such as assets and session
+ # migration generators, and completely disable views, helpers and assets
+ # so generators such as scaffold won't create them.
+ def self.api_only!
+ hide_namespaces "assets", "helper", "css", "js"
+
+ options[:rails].merge!(
+ api: true,
+ assets: false,
+ helper: false,
+ template_engine: nil
+ )
+ end
+
# Remove the color from output.
def self.no_color!
Thor::Base.shell = Thor::Shell::Basic
diff --git a/railties/lib/rails/generators/actions.rb b/railties/lib/rails/generators/actions.rb
index 70a20801a0..b4356f71e0 100644
--- a/railties/lib/rails/generators/actions.rb
+++ b/railties/lib/rails/generators/actions.rb
@@ -63,12 +63,26 @@ module Rails
# Add the given source to +Gemfile+
#
+ # If block is given, gem entries in block are wrapped into the source group.
+ #
# add_source "http://gems.github.com/"
- def add_source(source, options={})
+ #
+ # add_source "http://gems.github.com/" do
+ # gem "rspec-rails"
+ # end
+ def add_source(source, options={}, &block)
log :source, source
in_root do
- prepend_file "Gemfile", "source #{quote(source)}\n", verbose: false
+ if block
+ append_file "Gemfile", "source #{quote(source)} do", force: true
+ @in_group = true
+ instance_eval(&block)
+ @in_group = false
+ append_file "Gemfile", "\nend\n", force: true
+ else
+ prepend_file "Gemfile", "source #{quote(source)}\n", verbose: false
+ end
end
end
@@ -78,11 +92,11 @@ module Rails
# file in <tt>config/environments</tt>.
#
# environment do
- # "config.autoload_paths += %W(#{config.root}/extras)"
+ # "config.action_controller.asset_host = 'cdn.provider.com'"
# end
#
# environment(nil, env: "development") do
- # "config.autoload_paths += %W(#{config.root}/extras)"
+ # "config.action_controller.asset_host = 'localhost:3000'"
# end
def environment(data=nil, options={})
sentinel = /class [a-z_:]+ < Rails::Application/i
diff --git a/railties/lib/rails/generators/app_base.rb b/railties/lib/rails/generators/app_base.rb
index 061fafb156..249fe96772 100644
--- a/railties/lib/rails/generators/app_base.rb
+++ b/railties/lib/rails/generators/app_base.rb
@@ -208,11 +208,13 @@ module Rails
if options.dev?
[
GemfileEntry.path('rails', Rails::Generators::RAILS_DEV_PATH),
+ GemfileEntry.github('sprockets-rails', 'rails/sprockets-rails'),
GemfileEntry.github('arel', 'rails/arel')
]
elsif options.edge?
[
GemfileEntry.github('rails', 'rails/rails'),
+ GemfileEntry.github('sprockets-rails', 'rails/sprockets-rails'),
GemfileEntry.github('arel', 'rails/arel')
]
else
@@ -264,6 +266,8 @@ module Rails
end
def jbuilder_gemfile_entry
+ return [] if options[:api]
+
comment = 'Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder'
GemfileEntry.version('jbuilder', '~> 2.0', comment)
end
diff --git a/railties/lib/rails/generators/base.rb b/railties/lib/rails/generators/base.rb
index 813b8b629e..6fa413f8b0 100644
--- a/railties/lib/rails/generators/base.rb
+++ b/railties/lib/rails/generators/base.rb
@@ -103,12 +103,12 @@ module Rails
# hook_for :test_framework, as: :controller
# end
#
- # And now it will lookup at:
+ # And now it will look up at:
#
# "test_unit:controller", "test_unit"
#
- # Similarly, if you want it to also lookup in the rails namespace, you just
- # need to provide the :in value:
+ # Similarly, if you want it to also look up in the rails namespace, you
+ # just need to provide the :in value:
#
# class AwesomeGenerator < Rails::Generators::Base
# hook_for :test_framework, in: :rails, as: :controller
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 c3b8ef1181..5f4904fee1 100644
--- a/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb
+++ b/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb
@@ -28,4 +28,4 @@
<br>
-<%%= link_to 'New <%= human_name %>', new_<%= singular_table_name %>_path %>
+<%%= link_to 'New <%= singular_table_name.titleize %>', new_<%= singular_table_name %>_path %>
diff --git a/railties/lib/rails/generators/named_base.rb b/railties/lib/rails/generators/named_base.rb
index 01a8e2e9b4..243694f38e 100644
--- a/railties/lib/rails/generators/named_base.rb
+++ b/railties/lib/rails/generators/named_base.rb
@@ -18,8 +18,8 @@ module Rails
parse_attributes! if respond_to?(:attributes)
end
- # Defines the template that would be used for the migration file.
- # The arguments include the source template file, the migration filename etc.
+ # Overrides <tt>Thor::Actions#template</tt> so it can tell if
+ # a template is currently being created.
no_tasks do
def template(source, *args, &block)
inside_template do
@@ -183,6 +183,10 @@ module Rails
!defined?(ActiveRecord::Base) || ActiveRecord::Base.pluralize_table_names
end
+ def mountable_engine?
+ defined?(ENGINE_ROOT) && namespaced?
+ end
+
# Add a class collisions name to be checked on class initialization. You
# can supply a hash with a :prefix or :suffix to be tested.
#
diff --git a/railties/lib/rails/generators/rails/app/app_generator.rb b/railties/lib/rails/generators/rails/app/app_generator.rb
index 1047a2c429..b813b083f4 100644
--- a/railties/lib/rails/generators/rails/app/app_generator.rb
+++ b/railties/lib/rails/generators/rails/app/app_generator.rb
@@ -141,6 +141,7 @@ module Rails
end
def tmp
+ empty_directory_with_keep_file "tmp"
empty_directory "tmp/cache"
empty_directory "tmp/cache/assets"
end
@@ -174,6 +175,9 @@ module Rails
class_option :version, type: :boolean, aliases: "-v", group: :rails,
desc: "Show Rails version number and quit"
+ class_option :api, type: :boolean,
+ desc: "Preconfigure smaller stack for API only apps"
+
def initialize(*args)
super
@@ -184,6 +188,10 @@ module Rails
if !options[:skip_active_record] && !DATABASES.include?(options[:database])
raise Error, "Invalid value for --database option. Supported for preconfiguration are: #{DATABASES.join(", ")}."
end
+
+ # Force sprockets to be skipped when generating API only apps.
+ # Can't modify options hash as it's frozen by default.
+ self.options = options.merge(skip_sprockets: true, skip_javascript: true).freeze if options[:api]
end
public_task :set_default_accessors!
@@ -251,6 +259,28 @@ module Rails
build(:vendor)
end
+ def delete_app_assets_if_api_option
+ if options[:api]
+ remove_dir 'app/assets'
+ remove_dir 'lib/assets'
+ remove_dir 'tmp/cache/assets'
+ remove_dir 'vendor/assets'
+ end
+ end
+
+ def delete_app_helpers_if_api_option
+ if options[:api]
+ remove_dir 'app/helpers'
+ remove_dir 'test/helpers'
+ end
+ end
+
+ def delete_app_views_if_api_option
+ if options[:api]
+ remove_dir 'app/views'
+ end
+ end
+
def delete_js_folder_skipping_javascript
if options[:skip_javascript]
remove_dir 'app/assets/javascripts'
@@ -269,6 +299,13 @@ module Rails
end
end
+ def delete_non_api_initializers_if_api_option
+ if options[:api]
+ remove_file 'config/initializers/session_store.rb'
+ remove_file 'config/initializers/cookies_serializer.rb'
+ end
+ end
+
def finish_template
build(:leftovers)
end
@@ -319,7 +356,9 @@ module Rails
if app_const =~ /^\d/
raise Error, "Invalid application name #{app_name}. Please give a name which does not start with numbers."
elsif RESERVED_NAMES.include?(app_name)
- raise Error, "Invalid application name #{app_name}. Please give a name which does not match one of the reserved rails words: #{RESERVED_NAMES}"
+ raise Error, "Invalid application name #{app_name}. Please give a " \
+ "name which does not match one of the reserved rails " \
+ "words: #{RESERVED_NAMES.join(", ")}"
elsif Object.const_defined?(app_const_base)
raise Error, "Invalid application name #{app_name}, constant #{app_const_base} is already in use. Please choose another application name."
end
diff --git a/railties/lib/rails/generators/rails/app/templates/Gemfile b/railties/lib/rails/generators/rails/app/templates/Gemfile
index 29203b9c37..6a1c2faaab 100644
--- a/railties/lib/rails/generators/rails/app/templates/Gemfile
+++ b/railties/lib/rails/generators/rails/app/templates/Gemfile
@@ -21,6 +21,14 @@ source 'https://rubygems.org'
# Use Capistrano for deployment
# gem 'capistrano-rails', group: :development
+<%- if options.api? -%>
+# Use ActiveModelSerializers to serialize JSON responses
+gem 'active_model_serializers', '~> 0.10.0.rc2'
+
+# Use Rack CORS for handling Cross-Origin Resource Sharing (CORS), making cross-origin AJAX possible
+# gem 'rack-cors'
+
+<%- end -%>
<% if RUBY_ENGINE == 'ruby' -%>
group :development, :test do
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
@@ -28,13 +36,15 @@ group :development, :test do
end
group :development do
+<%- unless options.api? -%>
# Access an IRB console on exception pages or by using <%%= console %> in views
<%- if options.dev? || options.edge? -%>
- gem 'web-console', github: "rails/web-console"
+ gem 'web-console', github: 'rails/web-console'
<%- else -%>
gem 'web-console', '~> 2.0'
<%- end -%>
-<%- if spring_install? %>
+<%- end -%>
+<% if spring_install? -%>
# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
gem 'spring'
<% 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 cb86978d4c..c88426ec06 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
@@ -5,7 +5,7 @@
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
-// compiled file.
+// compiled file. JavaScript code in this file should be added after the last require_* statement.
//
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
// about supported directives.
diff --git a/railties/lib/rails/generators/rails/app/templates/app/assets/stylesheets/application.css b/railties/lib/rails/generators/rails/app/templates/app/assets/stylesheets/application.css
index 0cdd2788d0..0ebd7fe829 100644
--- a/railties/lib/rails/generators/rails/app/templates/app/assets/stylesheets/application.css
+++ b/railties/lib/rails/generators/rails/app/templates/app/assets/stylesheets/application.css
@@ -7,7 +7,8 @@
*
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
- * files in this directory. It is generally better to create a new file per style scope.
+ * files in this directory. Styles in this file should be added after the last require_* statement.
+ * It is generally better to create a new file per style scope.
*
*= require_tree .
*= require_self
diff --git a/railties/lib/rails/generators/rails/app/templates/app/controllers/application_controller.rb.tt b/railties/lib/rails/generators/rails/app/templates/app/controllers/application_controller.rb.tt
index d83690e1b9..f726fd6305 100644
--- a/railties/lib/rails/generators/rails/app/templates/app/controllers/application_controller.rb.tt
+++ b/railties/lib/rails/generators/rails/app/templates/app/controllers/application_controller.rb.tt
@@ -1,5 +1,7 @@
-class ApplicationController < ActionController::Base
+class ApplicationController < ActionController::<%= options[:api] ? "API" : "Base" %>
+<%- unless options[:api] -%>
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
+<%- end -%>
end
diff --git a/railties/lib/rails/generators/rails/app/templates/bin/setup b/railties/lib/rails/generators/rails/app/templates/bin/setup
index 3a5a2cc1e3..0c8b179827 100644
--- a/railties/lib/rails/generators/rails/app/templates/bin/setup
+++ b/railties/lib/rails/generators/rails/app/templates/bin/setup
@@ -5,13 +5,17 @@ include FileUtils
# path to your application root.
APP_ROOT = Pathname.new File.expand_path('../../', __FILE__)
+def system!(*args)
+ system(*args) || abort("\n== Command #{args} failed ==")
+end
+
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') or system('bundle install')
+ system! 'gem install bundler --conservative'
+ system('bundle check') or system!('bundle install')
# puts "\n== Copying sample files =="
# unless File.exist?('config/database.yml')
@@ -19,11 +23,11 @@ chdir APP_ROOT do
# end
puts "\n== Preparing database =="
- system 'ruby bin/rake db:setup'
+ system! 'ruby bin/rake db:setup'
puts "\n== Removing old logs and tempfiles =="
- system 'ruby bin/rake log:clear tmp:clear'
+ system! 'ruby bin/rake log:clear tmp:clear'
puts "\n== Restarting application server =="
- touch 'tmp/restart.txt'
+ system! 'ruby bin/rake restart'
end
diff --git a/railties/lib/rails/generators/rails/app/templates/bin/update b/railties/lib/rails/generators/rails/app/templates/bin/update
new file mode 100644
index 0000000000..9830e6b29a
--- /dev/null
+++ b/railties/lib/rails/generators/rails/app/templates/bin/update
@@ -0,0 +1,28 @@
+require 'pathname'
+require 'fileutils'
+include FileUtils
+
+# path to your application root.
+APP_ROOT = Pathname.new File.expand_path('../../', __FILE__)
+
+def system!(*args)
+ system(*args) || abort("\n== Command #{args} failed ==")
+end
+
+chdir APP_ROOT do
+ # This script is a way to update your development environment automatically.
+ # Add necessary update steps to this file.
+
+ puts '== Installing dependencies =='
+ system! 'gem install bundler --conservative'
+ system 'bundle check' or system! 'bundle install'
+
+ puts "\n== Updating database =="
+ system! 'bin/rake db:migrate'
+
+ puts "\n== Removing old logs and tempfiles =="
+ system! 'bin/rake log:clear tmp:clear'
+
+ puts "\n== Restarting application server =="
+ system! 'bin/rake restart'
+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 a2661bfb51..6b7d7abd0b 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/application.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/application.rb
@@ -32,5 +32,12 @@ 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[:api] -%>
+
+ # Only loads a smaller set of middleware suitable for API only apps.
+ # Middleware like session, flash, cookies can be added back manually.
+ # Skip views, helpers and assets when generating a new resource.
+ config.api_only = true
+<%- end -%>
end
end
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 ecb5d4170f..e29f0bacaa 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
@@ -9,9 +9,19 @@ Rails.application.configure do
# Do not eager load code on boot.
config.eager_load = false
- # Show full error reports and disable caching.
+ # Show full error reports.
config.consider_all_requests_local = true
- config.action_controller.perform_caching = false
+
+ # Enable/disable caching. By default caching is disabled.
+ if Rails.root.join('tmp/caching-dev.txt').exist?
+ config.action_controller.perform_caching = true
+ config.static_cache_control = "public, max-age=172800"
+ config.cache_store = :memory_store
+ else
+ config.action_controller.perform_caching = false
+ config.cache_store = :null_store
+ end
+
<%- unless options.skip_action_mailer? -%>
# Don't care if the mailer can't send.
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 8c09396fc1..0297ab75f6 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
@@ -51,7 +51,8 @@ Rails.application.configure do
# config.log_tags = [ :subdomain, :request_id ]
# Use a different logger for distributed setups.
- # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new)
+ # require 'syslog/logger'
+ # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name')
# Use a different cache store in production.
# config.cache_store = :mem_cache_store
diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/cors.rb b/railties/lib/rails/generators/rails/app/templates/config/initializers/cors.rb
new file mode 100644
index 0000000000..45c44d24f8
--- /dev/null
+++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/cors.rb
@@ -0,0 +1,14 @@
+# Avoid CORS issues when API is called from the frontend app
+# Handle Cross-Origin Resource Sharing (CORS) in order to accept cross-origin AJAX requests
+
+# Read more: https://github.com/cyu/rack-cors
+
+# Rails.application.config.middleware.insert_before 0, "Rack::Cors" do
+# allow do
+# origins 'example.com'
+#
+# resource '*',
+# headers: :any,
+# methods: [:get, :post, :put, :patch, :delete, :options, :head]
+# end
+# end
diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/wrap_parameters.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/initializers/wrap_parameters.rb.tt
index 94f612c3dd..cadc85cfac 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/initializers/wrap_parameters.rb.tt
+++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/wrap_parameters.rb.tt
@@ -5,7 +5,7 @@
# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
ActiveSupport.on_load(:action_controller) do
- wrap_parameters format: [:json] if respond_to?(:wrap_parameters)
+ wrap_parameters format: [:json]
end
<%- unless options.skip_active_record? -%>
diff --git a/railties/lib/rails/generators/rails/app/templates/config/routes.rb b/railties/lib/rails/generators/rails/app/templates/config/routes.rb
index 3f66539d54..787824f888 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/routes.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/routes.rb
@@ -1,56 +1,3 @@
Rails.application.routes.draw do
- # The priority is based upon order of creation: first created -> highest priority.
- # See how all your routes lay out with "rake routes".
-
- # You can have the root of your site routed with "root"
- # root 'welcome#index'
-
- # Example of regular route:
- # get 'products/:id' => 'catalog#view'
-
- # Example of named route that can be invoked with purchase_url(id: product.id)
- # get 'products/:id/purchase' => 'catalog#purchase', as: :purchase
-
- # Example resource route (maps HTTP verbs to controller actions automatically):
- # resources :products
-
- # Example resource route with options:
- # resources :products do
- # member do
- # get 'short'
- # post 'toggle'
- # end
- #
- # collection do
- # get 'sold'
- # end
- # end
-
- # Example resource route with sub-resources:
- # resources :products do
- # resources :comments, :sales
- # resource :seller
- # end
-
- # Example resource route with more complex sub-resources:
- # resources :products do
- # resources :comments
- # resources :sales do
- # get 'recent', on: :collection
- # end
- # end
-
- # Example resource route with concerns:
- # concern :toggleable do
- # post 'toggle'
- # end
- # resources :posts, concerns: :toggleable
- # resources :photos, concerns: :toggleable
-
- # Example resource route within a namespace:
- # namespace :admin do
- # # Directs /admin/products/* to Admin::ProductsController
- # # (app/controllers/admin/products_controller.rb)
- # resources :products
- # end
+ # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
diff --git a/railties/lib/rails/generators/rails/app/templates/gitignore b/railties/lib/rails/generators/rails/app/templates/gitignore
index e4a00ad181..1b8cf8a9fa 100644
--- a/railties/lib/rails/generators/rails/app/templates/gitignore
+++ b/railties/lib/rails/generators/rails/app/templates/gitignore
@@ -15,7 +15,8 @@
<% end -%>
# Ignore all logfiles and tempfiles.
/log/*
+/tmp/*
<% if keeps? -%>
!/log/.keep
+!/tmp/.keep
<% end -%>
-/tmp
diff --git a/railties/lib/rails/generators/rails/plugin/plugin_generator.rb b/railties/lib/rails/generators/rails/plugin/plugin_generator.rb
index 7f5bf0c8b8..0e1326ce4f 100644
--- a/railties/lib/rails/generators/rails/plugin/plugin_generator.rb
+++ b/railties/lib/rails/generators/rails/plugin/plugin_generator.rb
@@ -17,15 +17,22 @@ module Rails
def app
if mountable?
- directory 'app'
- empty_directory_with_keep_file "app/assets/images/#{namespaced_name}"
+ if api?
+ directory 'app', exclude_pattern: %r{app/(views|helpers)}
+ else
+ directory 'app'
+ empty_directory_with_keep_file "app/assets/images/#{namespaced_name}"
+ end
elsif full?
empty_directory_with_keep_file 'app/models'
empty_directory_with_keep_file 'app/controllers'
- empty_directory_with_keep_file 'app/views'
- empty_directory_with_keep_file 'app/helpers'
empty_directory_with_keep_file 'app/mailers'
- empty_directory_with_keep_file "app/assets/images/#{namespaced_name}"
+
+ unless api?
+ empty_directory_with_keep_file "app/assets/images/#{namespaced_name}"
+ empty_directory_with_keep_file 'app/helpers'
+ empty_directory_with_keep_file 'app/views'
+ end
end
end
@@ -82,6 +89,7 @@ task default: :test
opts = (options || {}).slice(*PASSTHROUGH_OPTIONS)
opts[:force] = force
opts[:skip_bundle] = true
+ opts[:api] = options.api?
invoke Rails::Generators::AppGenerator,
[ File.expand_path(dummy_path, destination_root) ], opts
@@ -176,6 +184,9 @@ task default: :test
desc: "If creating plugin in application's directory " +
"skip adding entry to Gemfile"
+ class_option :api, type: :boolean, default: false,
+ desc: "Generate a smaller stack for API application plugins"
+
def initialize(*args)
@dummy_path = nil
super
@@ -210,15 +221,15 @@ task default: :test
end
def create_public_stylesheets_files
- build(:stylesheets)
+ build(:stylesheets) unless api?
end
def create_javascript_files
- build(:javascripts)
+ build(:javascripts) unless api?
end
def create_images_directory
- build(:images)
+ build(:images) unless api?
end
def create_bin_files
@@ -305,6 +316,10 @@ task default: :test
options[:skip_test].blank? || options[:dummy_path] != 'test/dummy'
end
+ def api?
+ options[:api]
+ end
+
def self.banner
"rails plugin new #{self.arguments.map(&:usage).join(' ')} [options]"
end
@@ -364,7 +379,9 @@ task default: :test
elsif camelized =~ /^\d/
raise Error, "Invalid plugin name #{original_name}. Please give a name which does not start with numbers."
elsif RESERVED_NAMES.include?(name)
- raise Error, "Invalid plugin name #{original_name}. Please give a name which does not match one of the reserved rails words: #{RESERVED_NAMES}"
+ raise Error, "Invalid plugin name #{original_name}. Please give a " \
+ "name which does not match one of the reserved rails " \
+ "words: #{RESERVED_NAMES.join(", ")}"
elsif Object.const_defined?(camelized)
raise Error, "Invalid plugin name #{original_name}, constant #{camelized} is already in use. Please choose another plugin name."
end
diff --git a/railties/lib/rails/generators/rails/plugin/templates/app/controllers/%namespaced_name%/application_controller.rb.tt b/railties/lib/rails/generators/rails/plugin/templates/app/controllers/%namespaced_name%/application_controller.rb.tt
index 7157e48c42..7fe4e5034d 100644
--- a/railties/lib/rails/generators/rails/plugin/templates/app/controllers/%namespaced_name%/application_controller.rb.tt
+++ b/railties/lib/rails/generators/rails/plugin/templates/app/controllers/%namespaced_name%/application_controller.rb.tt
@@ -1,5 +1,5 @@
<%= wrap_in_modules <<-rb.strip_heredoc
- class ApplicationController < ActionController::Base
+ class ApplicationController < ActionController::#{api? ? "API" : "Base"}
end
rb
%>
diff --git a/railties/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%/engine.rb b/railties/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%/engine.rb
index 17afd52177..8938770fc4 100644
--- a/railties/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%/engine.rb
+++ b/railties/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%/engine.rb
@@ -1,6 +1,7 @@
<%= wrap_in_modules <<-rb.strip_heredoc
class Engine < ::Rails::Engine
#{mountable? ? ' isolate_namespace ' + camelized_modules : ' '}
+ #{api? ? " config.generators.api_only = true" : ' '}
end
rb
%>
diff --git a/railties/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%/version.rb b/railties/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%/version.rb
index d257295988..b08f4ef9ae 100644
--- a/railties/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%/version.rb
+++ b/railties/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%/version.rb
@@ -1 +1 @@
-<%= wrap_in_modules 'VERSION = "0.0.1"' %>
+<%= wrap_in_modules "VERSION = '0.1.0'" %>
diff --git a/railties/lib/rails/generators/rails/plugin/templates/rails/javascripts.js b/railties/lib/rails/generators/rails/plugin/templates/rails/javascripts.js
index 8913b40f69..e54c6461cc 100644
--- a/railties/lib/rails/generators/rails/plugin/templates/rails/javascripts.js
+++ b/railties/lib/rails/generators/rails/plugin/templates/rails/javascripts.js
@@ -5,7 +5,7 @@
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
-// compiled file.
+// compiled file. JavaScript code in this file should be added after the last require_* statement.
//
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
// about supported directives.
diff --git a/railties/lib/rails/generators/rails/plugin/templates/rails/stylesheets.css b/railties/lib/rails/generators/rails/plugin/templates/rails/stylesheets.css
index 0cdd2788d0..0ebd7fe829 100644
--- a/railties/lib/rails/generators/rails/plugin/templates/rails/stylesheets.css
+++ b/railties/lib/rails/generators/rails/plugin/templates/rails/stylesheets.css
@@ -7,7 +7,8 @@
*
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
- * files in this directory. It is generally better to create a new file per style scope.
+ * files in this directory. Styles in this file should be added after the last require_* statement.
+ * It is generally better to create a new file per style scope.
*
*= require_tree .
*= require_self
diff --git a/railties/lib/rails/generators/rails/plugin/templates/test/integration/navigation_test.rb b/railties/lib/rails/generators/rails/plugin/templates/test/integration/navigation_test.rb
index 824caecb24..f5d1ec2046 100644
--- a/railties/lib/rails/generators/rails/plugin/templates/test/integration/navigation_test.rb
+++ b/railties/lib/rails/generators/rails/plugin/templates/test/integration/navigation_test.rb
@@ -1,10 +1,6 @@
require 'test_helper'
class NavigationTest < ActionDispatch::IntegrationTest
-<% unless options[:skip_active_record] -%>
- fixtures :all
-<% end -%>
-
# test "the truth" do
# assert true
# end
diff --git a/railties/lib/rails/generators/rails/plugin/templates/test/test_helper.rb b/railties/lib/rails/generators/rails/plugin/templates/test/test_helper.rb
index 0852ffce9a..b1b77629d4 100644
--- a/railties/lib/rails/generators/rails/plugin/templates/test/test_helper.rb
+++ b/railties/lib/rails/generators/rails/plugin/templates/test/test_helper.rb
@@ -20,6 +20,7 @@ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
# Load fixtures from the engine
if ActiveSupport::TestCase.respond_to?(:fixture_path=)
ActiveSupport::TestCase.fixture_path = File.expand_path("../fixtures", __FILE__)
- ActiveSupport::TestCase.file_fixture_path = ActiveSupport::TestCase.fixture_path + "files"
+ ActionDispatch::IntegrationTest.fixture_path = ActiveSupport::TestCase.fixture_path
+ ActiveSupport::TestCase.file_fixture_path = ActiveSupport::TestCase.fixture_path + "/files"
ActiveSupport::TestCase.fixtures :all
end
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 c986f95e67..42705107ae 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
@@ -1,7 +1,6 @@
module Rails
module Generators
class ResourceRouteGenerator < NamedBase # :nodoc:
-
# Properly nests namespaces passed into a generator
#
# $ rails generate resource admin/users/products
diff --git a/railties/lib/rails/generators/rails/scaffold/scaffold_generator.rb b/railties/lib/rails/generators/rails/scaffold/scaffold_generator.rb
index e89789e72b..17c32bfdb3 100644
--- a/railties/lib/rails/generators/rails/scaffold/scaffold_generator.rb
+++ b/railties/lib/rails/generators/rails/scaffold/scaffold_generator.rb
@@ -10,10 +10,11 @@ module Rails
class_option :stylesheet_engine, desc: "Engine for Stylesheets"
class_option :assets, type: :boolean
class_option :resource_route, type: :boolean
+ class_option :scaffold_stylesheet, type: :boolean
def handle_skip
@options = @options.merge(stylesheets: false) unless options[:assets]
- @options = @options.merge(stylesheet_engine: false) unless options[:stylesheets]
+ @options = @options.merge(stylesheet_engine: false) unless options[:stylesheets] && options[:scaffold_stylesheet]
end
hook_for :scaffold_controller, required: true
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 c01b82884d..d0b8cad896 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
@@ -10,11 +10,14 @@ module Rails
class_option :helper, type: :boolean
class_option :orm, banner: "NAME", type: :string, required: true,
desc: "ORM to generate the controller for"
+ class_option :api, type: :boolean,
+ desc: "Generates API controller"
argument :attributes, type: :array, default: [], banner: "field:type field:type"
def create_controller_files
- template "controller.rb", File.join('app/controllers', controller_class_path, "#{controller_file_name}_controller.rb")
+ template_file = options.api? ? "api_controller.rb" : "controller.rb"
+ template template_file, 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/api_controller.rb b/railties/lib/rails/generators/rails/scaffold_controller/templates/api_controller.rb
new file mode 100644
index 0000000000..bc3c9b3f6b
--- /dev/null
+++ b/railties/lib/rails/generators/rails/scaffold_controller/templates/api_controller.rb
@@ -0,0 +1,61 @@
+<% if namespaced? -%>
+require_dependency "<%= namespaced_file_path %>/application_controller"
+
+<% end -%>
+<% module_namespacing do -%>
+class <%= controller_class_name %>Controller < ApplicationController
+ before_action :set_<%= singular_table_name %>, only: [:show, :update, :destroy]
+
+ # GET <%= route_url %>
+ def index
+ @<%= plural_table_name %> = <%= orm_class.all(class_name) %>
+
+ render json: <%= "@#{plural_table_name}" %>
+ end
+
+ # GET <%= route_url %>/1
+ def show
+ render json: <%= "@#{singular_table_name}" %>
+ end
+
+ # POST <%= route_url %>
+ def create
+ @<%= singular_table_name %> = <%= orm_class.build(class_name, "#{singular_table_name}_params") %>
+
+ if @<%= orm_instance.save %>
+ render json: <%= "@#{singular_table_name}" %>, status: :created, location: <%= "@#{singular_table_name}" %>
+ else
+ render json: <%= "@#{orm_instance.errors}" %>, status: :unprocessable_entity
+ end
+ end
+
+ # PATCH/PUT <%= route_url %>/1
+ def update
+ if @<%= orm_instance.update("#{singular_table_name}_params") %>
+ render json: <%= "@#{singular_table_name}" %>
+ else
+ render json: <%= "@#{orm_instance.errors}" %>, status: :unprocessable_entity
+ end
+ end
+
+ # DELETE <%= route_url %>/1
+ def destroy
+ @<%= orm_instance.destroy %>
+ end
+
+ private
+ # Use callbacks to share common setup or constraints between actions.
+ def set_<%= singular_table_name %>
+ @<%= singular_table_name %> = <%= orm_class.find(class_name, "params[:id]") %>
+ end
+
+ # Only allow a trusted parameter "white list" through.
+ def <%= "#{singular_table_name}_params" %>
+ <%- if attributes_names.empty? -%>
+ params[:<%= singular_table_name %>]
+ <%- else -%>
+ params.require(:<%= singular_table_name %>).permit(<%= attributes_names.map { |name| ":#{name}" }.join(', ') %>)
+ <%- end -%>
+ end
+end
+<% end -%>
diff --git a/railties/lib/rails/generators/test_unit/controller/templates/functional_test.rb b/railties/lib/rails/generators/test_unit/controller/templates/functional_test.rb
index 509bd60564..5a8a3ca5e0 100644
--- a/railties/lib/rails/generators/test_unit/controller/templates/functional_test.rb
+++ b/railties/lib/rails/generators/test_unit/controller/templates/functional_test.rb
@@ -2,6 +2,12 @@ require 'test_helper'
<% module_namespacing do -%>
class <%= class_name %>ControllerTest < ActionController::TestCase
+<% if mountable_engine? -%>
+ setup do
+ @routes = Engine.routes
+ end
+
+<% end -%>
<% if actions.empty? -%>
# test "the truth" do
# assert true
diff --git a/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb b/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb
index 2e1f55f2a6..0171da7cc7 100644
--- a/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb
+++ b/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb
@@ -8,13 +8,26 @@ module TestUnit # :nodoc:
check_class_collision suffix: "ControllerTest"
+ class_option :api, type: :boolean,
+ desc: "Generates API functional tests"
+
argument :attributes, type: :array, default: [], banner: "field:type field:type"
def create_test_files
- template "functional_test.rb",
+ template_file = options.api? ? "api_functional_test.rb" : "functional_test.rb"
+ template template_file,
File.join("test/controllers", controller_class_path, "#{controller_file_name}_controller_test.rb")
end
+ def fixture_name
+ @fixture_name ||=
+ if mountable_engine?
+ "%s_%s" % [namespaced_path, table_name]
+ else
+ table_name
+ end
+ end
+
private
def attributes_hash
diff --git a/railties/lib/rails/generators/test_unit/scaffold/templates/api_functional_test.rb b/railties/lib/rails/generators/test_unit/scaffold/templates/api_functional_test.rb
new file mode 100644
index 0000000000..f302cd6c3d
--- /dev/null
+++ b/railties/lib/rails/generators/test_unit/scaffold/templates/api_functional_test.rb
@@ -0,0 +1,43 @@
+require 'test_helper'
+
+<% module_namespacing do -%>
+class <%= controller_class_name %>ControllerTest < ActionController::TestCase
+ setup do
+ @<%= singular_table_name %> = <%= fixture_name %>(:one)
+<% if mountable_engine? -%>
+ @routes = Engine.routes
+<% end -%>
+ end
+
+ test "should get index" do
+ get :index
+ assert_response :success
+ end
+
+ test "should create <%= singular_table_name %>" do
+ assert_difference('<%= class_name %>.count') do
+ post :create, params: { <%= "#{singular_table_name}: { #{attributes_hash} }" %> }
+ end
+
+ assert_response 201
+ end
+
+ test "should show <%= singular_table_name %>" do
+ get :show, params: { id: <%= "@#{singular_table_name}" %> }
+ assert_response :success
+ end
+
+ test "should update <%= singular_table_name %>" do
+ patch :update, params: { id: <%= "@#{singular_table_name}" %>, <%= "#{singular_table_name}: { #{attributes_hash} }" %> }
+ assert_response 200
+ end
+
+ test "should destroy <%= singular_table_name %>" do
+ assert_difference('<%= class_name %>.count', -1) do
+ delete :destroy, params: { id: <%= "@#{singular_table_name}" %> }
+ end
+
+ assert_response 204
+ end
+end
+<% end -%>
diff --git a/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb b/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb
index 76313575e9..50b98b2631 100644
--- a/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb
+++ b/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb
@@ -3,7 +3,10 @@ require 'test_helper'
<% module_namespacing do -%>
class <%= controller_class_name %>ControllerTest < ActionController::TestCase
setup do
- @<%= singular_table_name %> = <%= table_name %>(:one)
+ @<%= singular_table_name %> = <%= fixture_name %>(:one)
+<% if mountable_engine? -%>
+ @routes = Engine.routes
+<% end -%>
end
test "should get index" do
diff --git a/railties/lib/rails/generators/testing/assertions.rb b/railties/lib/rails/generators/testing/assertions.rb
index bd069e4bd0..17af6eddfa 100644
--- a/railties/lib/rails/generators/testing/assertions.rb
+++ b/railties/lib/rails/generators/testing/assertions.rb
@@ -23,7 +23,7 @@ module Rails
# end
# end
def assert_file(relative, *contents)
- absolute = File.expand_path(relative, destination_root).shellescape
+ absolute = File.expand_path(relative, destination_root)
assert File.exist?(absolute), "Expected file #{relative.inspect} to exist, but does not"
read = File.read(absolute) if block_given? || !contents.empty?
diff --git a/railties/lib/rails/mailers_controller.rb b/railties/lib/rails/mailers_controller.rb
index 41422a656c..78a857e0f1 100644
--- a/railties/lib/rails/mailers_controller.rb
+++ b/railties/lib/rails/mailers_controller.rb
@@ -26,7 +26,7 @@ class Rails::MailersController < Rails::ApplicationController # :nodoc:
if part = find_part(part_type)
response.content_type = part_type
- render text: part.respond_to?(:decoded) ? part.decoded : part
+ render plain: part.respond_to?(:decoded) ? part.decoded : part
else
raise AbstractController::ActionNotFound, "Email part '#{part_type}' not found in #{@preview.name}##{@email_action}"
end
diff --git a/railties/lib/rails/paths.rb b/railties/lib/rails/paths.rb
index ebcaaaba46..e47616a87f 100644
--- a/railties/lib/rails/paths.rb
+++ b/railties/lib/rails/paths.rb
@@ -123,6 +123,10 @@ module Rails
options[:load_path] ? load_path! : skip_load_path!
end
+ def absolute_current # :nodoc:
+ File.expand_path(@current, @root.path)
+ end
+
def children
keys = @root.keys.find_all { |k|
k.start_with?(@current) && k != @current
@@ -175,6 +179,10 @@ module Rails
@paths
end
+ def extensions # :nodoc:
+ $1.split(',') if @glob =~ /\{([\S]+)\}/
+ end
+
# Expands all paths against the root and return all unique values.
def expanded
raise "You need to set a path root" unless @root.path
diff --git a/railties/lib/rails/tasks.rb b/railties/lib/rails/tasks.rb
index 2c3d278eca..d3e33584d7 100644
--- a/railties/lib/rails/tasks.rb
+++ b/railties/lib/rails/tasks.rb
@@ -3,6 +3,7 @@ require 'rake'
# Load Rails Rakefile extensions
%w(
annotations
+ dev
framework
initializers
log
@@ -10,8 +11,9 @@ require 'rake'
misc
restart
routes
- statistics
tmp
-).each do |task|
+).tap { |arr|
+ arr << 'statistics' if Rake.application.current_scope.empty?
+}.each do |task|
load "rails/tasks/#{task}.rake"
end
diff --git a/railties/lib/rails/tasks/dev.rake b/railties/lib/rails/tasks/dev.rake
new file mode 100644
index 0000000000..e949172d3f
--- /dev/null
+++ b/railties/lib/rails/tasks/dev.rake
@@ -0,0 +1,15 @@
+namespace :dev do
+ task :cache do
+ desc 'Toggle development mode caching on/off'
+
+ if File.exist? 'tmp/caching-dev.txt'
+ File.delete 'tmp/caching-dev.txt'
+ puts 'Development mode is no longer being cached.'
+ else
+ FileUtils.touch 'tmp/caching-dev.txt'
+ puts 'Development mode is now being cached.'
+ end
+
+ FileUtils.touch 'tmp/restart.txt'
+ end
+end
diff --git a/railties/lib/rails/tasks/restart.rake b/railties/lib/rails/tasks/restart.rake
index 1e8940b675..f36c86d81b 100644
--- a/railties/lib/rails/tasks/restart.rake
+++ b/railties/lib/rails/tasks/restart.rake
@@ -1,4 +1,5 @@
desc "Restart app by touching tmp/restart.txt"
task :restart do
+ FileUtils.mkdir_p('tmp')
FileUtils.touch('tmp/restart.txt')
end
diff --git a/railties/lib/rails/test_help.rb b/railties/lib/rails/test_help.rb
index a83e39faee..5cc1b5b219 100644
--- a/railties/lib/rails/test_help.rb
+++ b/railties/lib/rails/test_help.rb
@@ -3,13 +3,14 @@
abort("Abort testing: Your Rails environment is running in production mode!") if Rails.env.production?
require "rails/test_unit/minitest_plugin"
-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'
+require 'active_support/testing/autorun'
+
if defined?(ActiveRecord::Base)
ActiveRecord::Migration.maintain_test_schema!
@@ -27,14 +28,14 @@ if defined?(ActiveRecord::Base)
end
class ActionController::TestCase
- def before_setup
+ def before_setup # :nodoc:
@routes = Rails.application.routes
super
end
end
class ActionDispatch::IntegrationTest
- def before_setup
+ def before_setup # :nodoc:
@routes = Rails.application.routes
super
end
diff --git a/railties/lib/rails/test_unit/minitest_plugin.rb b/railties/lib/rails/test_unit/minitest_plugin.rb
index 70ce9d3360..5552779ef1 100644
--- a/railties/lib/rails/test_unit/minitest_plugin.rb
+++ b/railties/lib/rails/test_unit/minitest_plugin.rb
@@ -1,14 +1,52 @@
-require "minitest"
+require "active_support/core_ext/module/attribute_accessors"
require "rails/test_unit/reporter"
+require "rails/test_unit/test_requirer"
-def Minitest.plugin_rails_init(options)
- self.reporter << Rails::TestUnitReporter.new(options[:io], options)
- if $rails_test_runner && (method = $rails_test_runner.find_method)
- options[:filter] = method
+module Minitest
+ def self.plugin_rails_options(opts, options)
+ opts.separator ""
+ opts.separator "Usage: bin/rails test [options] [files or directories]"
+ opts.separator "You can run a single test by appending a line number to a filename:"
+ opts.separator ""
+ opts.separator " bin/rails test test/models/user_test.rb:27"
+ opts.separator ""
+ opts.separator "You can run multiple files and directories at the same time:"
+ opts.separator ""
+ opts.separator " bin/rails test test/controllers test/integration/login_test.rb"
+ opts.separator ""
+
+ opts.separator "Rails options:"
+ opts.on("-e", "--environment [ENV]",
+ "Run tests in the ENV environment") do |env|
+ options[:environment] = env.strip
+ end
+
+ opts.on("-b", "--backtrace",
+ "Show the complete backtrace") do
+ options[:full_backtrace] = true
+ end
+
+ options[:patterns] = opts.order!
end
- if !($rails_test_runner && $rails_test_runner.show_backtrace?)
- Minitest.backtrace_filter = Rails.backtrace_cleaner
+ def self.plugin_rails_init(options)
+ self.run_with_rails_extension = true
+
+ ENV["RAILS_ENV"] = options[:environment] || "test"
+
+ ::Rails::TestRequirer.require_files options[:patterns] unless run_with_autorun
+
+ unless options[:full_backtrace] || ENV["BACKTRACE"]
+ # Plugin can run without Rails loaded, check before filtering.
+ Minitest.backtrace_filter = ::Rails.backtrace_cleaner if ::Rails.respond_to?(:backtrace_cleaner)
+ end
+
+ self.reporter << ::Rails::TestUnitReporter.new(options[:io], options)
end
+
+ mattr_accessor(:run_with_autorun) { false }
+ mattr_accessor(:run_with_rails_extension) { false }
end
+
+Minitest.load_plugins
Minitest.extensions << 'rails'
diff --git a/railties/lib/rails/test_unit/reporter.rb b/railties/lib/rails/test_unit/reporter.rb
index 64e99626eb..09b8675cf8 100644
--- a/railties/lib/rails/test_unit/reporter.rb
+++ b/railties/lib/rails/test_unit/reporter.rb
@@ -1,9 +1,13 @@
+require "active_support/core_ext/class/attribute"
require "minitest"
module Rails
class TestUnitReporter < Minitest::StatisticsReporter
+ class_attribute :executable
+ self.executable = "bin/rails test"
+
def report
- return if results.empty?
+ return if filtered_results.empty?
io.puts
io.puts "Failed tests:"
io.puts
@@ -11,12 +15,22 @@ module Rails
end
def aggregated_results # :nodoc:
- filtered_results = results.dup
- filtered_results.reject!(&:skipped?) unless options[:verbose]
filtered_results.map do |result|
location, line = result.method(result.name).source_location
- "bin/rails test #{location}:#{line}"
+ "#{self.executable} #{relative_path_for(location)}:#{line}"
end.join "\n"
end
+
+ def filtered_results
+ if options[:verbose]
+ results
+ else
+ results.reject(&:skipped?)
+ end
+ end
+
+ def relative_path_for(file)
+ file.sub(/^#{Rails.root}\/?/, '')
+ end
end
end
diff --git a/railties/lib/rails/test_unit/runner.rb b/railties/lib/rails/test_unit/runner.rb
deleted file mode 100644
index 5573fa6904..0000000000
--- a/railties/lib/rails/test_unit/runner.rb
+++ /dev/null
@@ -1,137 +0,0 @@
-require "optparse"
-require "rake/file_list"
-require "method_source"
-
-module Rails
- class TestRunner
- class Options
- def self.parse(args)
- options = { backtrace: !ENV["BACKTRACE"].nil?, name: nil, environment: "test" }
-
- opt_parser = ::OptionParser.new do |opts|
- opts.banner = "Usage: bin/rails test [options] [file or directory]"
-
- opts.separator ""
- opts.on("-e", "--environment [ENV]",
- "Run tests in the ENV environment") do |env|
- options[:environment] = env.strip
- end
- opts.separator ""
- opts.separator "Filter options:"
- opts.separator ""
- opts.separator <<-DESC
- You can run a single test by appending the line number to filename:
-
- bin/rails test test/models/user_test.rb:27
-
- DESC
-
- opts.on("-n", "--name [NAME]",
- "Only run tests matching NAME") do |name|
- options[:name] = name
- end
- opts.on("-p", "--pattern [PATTERN]",
- "Only run tests matching PATTERN") do |pattern|
- options[:name] = "/#{pattern}/"
- end
-
- opts.separator ""
- opts.separator "Output options:"
-
- opts.on("-b", "--backtrace",
- "Show the complete backtrace") do
- options[:backtrace] = true
- end
-
- opts.separator ""
- opts.separator "Common options:"
-
- opts.on_tail("-h", "--help", "Show this message") do
- puts opts
- exit
- end
- end
-
- opt_parser.order!(args)
-
- options[:patterns] = []
- while arg = args.shift
- if (file_and_line = arg.split(':')).size > 1
- options[:filename], options[:line] = file_and_line
- options[:filename] = File.expand_path options[:filename]
- options[:line] &&= options[:line].to_i
- else
- arg = arg.gsub(':', '')
- if Dir.exist?("#{arg}")
- options[:patterns] << File.expand_path("#{arg}/**/*_test.rb")
- elsif File.file?(arg)
- options[:patterns] << File.expand_path(arg)
- end
- end
- end
- options
- end
- end
-
- def initialize(options = {})
- @options = options
- end
-
- def self.run(arguments)
- options = Rails::TestRunner::Options.parse(arguments)
- Rails::TestRunner.new(options).run
- end
-
- def run
- $rails_test_runner = self
- ENV["RAILS_ENV"] = @options[:environment]
- run_tests
- end
-
- def find_method
- return @options[:name] if @options[:name]
- return unless @options[:line]
- method = test_methods.find do |location, test_method, start_line, end_line|
- location == @options[:filename] &&
- (start_line..end_line).include?(@options[:line].to_i)
- end
- method[1] if method
- end
-
- def show_backtrace?
- @options[:backtrace]
- end
-
- def test_files
- return [@options[:filename]] if @options[:filename]
- if @options[:patterns] && @options[:patterns].count > 0
- pattern = @options[:patterns]
- else
- pattern = "test/**/*_test.rb"
- end
- Rake::FileList[pattern]
- end
-
- private
- def run_tests
- test_files.to_a.each do |file|
- require File.expand_path file
- end
- end
-
- def test_methods
- methods_map = []
- suites = Minitest::Runnable.runnables.shuffle
- suites.each do |suite_class|
- suite_class.runnable_methods.each do |test_method|
- method = suite_class.instance_method(test_method)
- location = method.source_location
- start_line = location.last
- end_line = method.source.split("\n").size + start_line - 1
- methods_map << [File.expand_path(location.first), test_method, start_line, end_line]
- end
- end
- methods_map
- end
- end
-end
diff --git a/railties/lib/rails/test_unit/test_requirer.rb b/railties/lib/rails/test_unit/test_requirer.rb
new file mode 100644
index 0000000000..84c2256729
--- /dev/null
+++ b/railties/lib/rails/test_unit/test_requirer.rb
@@ -0,0 +1,28 @@
+require 'active_support/core_ext/object/blank'
+require 'rake/file_list'
+
+module Rails
+ class TestRequirer # :nodoc:
+ class << self
+ def require_files(patterns)
+ patterns = expand_patterns(patterns)
+
+ Rake::FileList[patterns.compact.presence || 'test/**/*_test.rb'].to_a.each do |file|
+ require File.expand_path(file)
+ end
+ end
+
+ private
+ def expand_patterns(patterns)
+ patterns.map do |arg|
+ arg = arg.gsub(/:(\d+)?$/, '')
+ if Dir.exist?(arg)
+ "#{arg}/**/*_test.rb"
+ elsif File.file?(arg)
+ arg
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/railties/lib/rails/test_unit/testing.rake b/railties/lib/rails/test_unit/testing.rake
index 0f26621b59..dda492f974 100644
--- a/railties/lib/rails/test_unit/testing.rake
+++ b/railties/lib/rails/test_unit/testing.rake
@@ -1,12 +1,13 @@
-require "rails/test_unit/runner"
+gem 'minitest'
+require 'minitest'
+require 'rails/test_unit/minitest_plugin'
task default: :test
desc "Runs all tests in test folder"
task :test do
$: << "test"
- args = ARGV[0] == "test" ? ARGV[1..-1] : []
- Rails::TestRunner.run(args)
+ Minitest.run(['test'])
end
namespace :test do
@@ -23,22 +24,22 @@ namespace :test do
["models", "helpers", "controllers", "mailers", "integration", "jobs"].each do |name|
task name => "test:prepare" do
$: << "test"
- Rails::TestRunner.run(["test/#{name}"])
+ Minitest.run(["test/#{name}"])
end
end
task :generators => "test:prepare" do
$: << "test"
- Rails::TestRunner.run(["test/lib/generators"])
+ Minitest.run(["test/lib/generators"])
end
task :units => "test:prepare" do
$: << "test"
- Rails::TestRunner.run(["test/models", "test/helpers", "test/unit"])
+ Minitest.run(["test/models", "test/helpers", "test/unit"])
end
task :functionals => "test:prepare" do
$: << "test"
- Rails::TestRunner.run(["test/controllers", "test/mailers", "test/functional"])
+ Minitest.run(["test/controllers", "test/mailers", "test/functional"])
end
end
diff --git a/railties/test/application/asset_debugging_test.rb b/railties/test/application/asset_debugging_test.rb
index acd387256c..36ab8109a7 100644
--- a/railties/test/application/asset_debugging_test.rb
+++ b/railties/test/application/asset_debugging_test.rb
@@ -36,7 +36,7 @@ module ApplicationTests
test "assets are concatenated when debug is off and compile is off either if debug_assets param is provided" do
# config.assets.debug and config.assets.compile are false for production environment
ENV["RAILS_ENV"] = "production"
- output = Dir.chdir(app_path){ `bundle exec rake assets:precompile --trace 2>&1` }
+ output = Dir.chdir(app_path){ `bin/rake assets:precompile --trace 2>&1` }
assert $?.success?, output
require "#{app_path}/config/environment"
diff --git a/railties/test/application/assets_test.rb b/railties/test/application/assets_test.rb
index 1e2a9ba040..ba2c27d8e8 100644
--- a/railties/test/application/assets_test.rb
+++ b/railties/test/application/assets_test.rb
@@ -18,7 +18,7 @@ module ApplicationTests
def precompile!(env = nil)
quietly do
- precompile_task = "bundle exec rake assets:precompile #{env} --trace 2>&1"
+ precompile_task = "bin/rake assets:precompile #{env} --trace 2>&1"
output = Dir.chdir(app_path) { %x[ #{precompile_task} ] }
assert $?.success?, output
output
@@ -27,7 +27,7 @@ module ApplicationTests
def clean_assets!
quietly do
- assert Dir.chdir(app_path) { system('bundle exec rake assets:clobber') }
+ assert Dir.chdir(app_path) { system('bin/rake assets:clobber') }
end
end
@@ -60,6 +60,7 @@ module ApplicationTests
test "assets do not require compressors until it is used" do
app_file "app/assets/javascripts/demo.js.erb", "<%= :alert %>();"
add_to_env_config "production", "config.assets.compile = true"
+ add_to_env_config "production", "config.assets.precompile = []"
ENV["RAILS_ENV"] = "production"
require "#{app_path}/config/environment"
diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb
index 38516a1c1a..f677a7c42a 100644
--- a/railties/test/application/configuration_test.rb
+++ b/railties/test/application/configuration_test.rb
@@ -745,6 +745,19 @@ module ApplicationTests
assert_equal [::MyMailObserver, ::MyOtherMailObserver], ::Mail.send(:class_variable_get, "@@delivery_notification_observers")
end
+ test "allows setting the queue name for the ActionMailer::DeliveryJob" do
+ add_to_config <<-RUBY
+ config.action_mailer.deliver_later_queue_name = 'test_default'
+ RUBY
+
+ require "#{app_path}/config/environment"
+ require "mail"
+
+ _ = ActionMailer::Base
+
+ assert_equal 'test_default', ActionMailer::Base.send(:class_variable_get, "@@deliver_later_queue_name")
+ end
+
test "valid timezone is setup correctly" do
add_to_config <<-RUBY
config.root = "#{app_path}"
diff --git a/railties/test/application/console_test.rb b/railties/test/application/console_test.rb
index 31bc003dcb..7bf123d12b 100644
--- a/railties/test/application/console_test.rb
+++ b/railties/test/application/console_test.rb
@@ -29,6 +29,18 @@ class ConsoleTest < ActiveSupport::TestCase
assert_instance_of ActionDispatch::Integration::Session, console_session
end
+ def test_app_can_access_path_helper_method
+ app_file 'config/routes.rb', <<-RUBY
+ Rails.application.routes.draw do
+ get 'foo', to: 'foo#index'
+ end
+ RUBY
+
+ load_environment
+ console_session = irb_context.app
+ assert_equal '/foo', console_session.foo_path
+ end
+
def test_new_session_should_return_integration_session
load_environment
session = irb_context.new_session
diff --git a/railties/test/application/generators_test.rb b/railties/test/application/generators_test.rb
index 78ada58ec8..84cc6e120b 100644
--- a/railties/test/application/generators_test.rb
+++ b/railties/test/application/generators_test.rb
@@ -125,5 +125,40 @@ module ApplicationTests
assert_equal expected, c.generators.options
end
end
+
+ test "api only generators hide assets, helper, js and css namespaces and set api option" do
+ add_to_config <<-RUBY
+ config.api_only = true
+ RUBY
+
+ # Initialize the application
+ require "#{app_path}/config/environment"
+ Rails.application.load_generators
+
+ assert Rails::Generators.hidden_namespaces.include?("assets")
+ assert Rails::Generators.hidden_namespaces.include?("helper")
+ assert Rails::Generators.hidden_namespaces.include?("js")
+ assert Rails::Generators.hidden_namespaces.include?("css")
+ assert Rails::Generators.options[:rails][:api]
+ assert_equal false, Rails::Generators.options[:rails][:assets]
+ assert_equal false, Rails::Generators.options[:rails][:helper]
+ assert_nil Rails::Generators.options[:rails][:template_engine]
+ end
+
+ test "api only generators allow overriding generator options" do
+ add_to_config <<-RUBY
+ config.generators.helper = true
+ config.api_only = true
+ config.generators.template_engine = :my_template
+ RUBY
+
+ # Initialize the application
+ require "#{app_path}/config/environment"
+ Rails.application.load_generators
+
+ assert Rails::Generators.options[:rails][:api]
+ assert Rails::Generators.options[:rails][:helper]
+ assert_equal :my_template, Rails::Generators.options[:rails][:template_engine]
+ end
end
end
diff --git a/railties/test/application/initializers/frameworks_test.rb b/railties/test/application/initializers/frameworks_test.rb
index 97b51911d9..7bba910b9e 100644
--- a/railties/test/application/initializers/frameworks_test.rb
+++ b/railties/test/application/initializers/frameworks_test.rb
@@ -129,6 +129,35 @@ module ApplicationTests
assert_equal "false", last_response.body
end
+ test "action_controller api executes using all the middleware stack" do
+ add_to_config "config.api_only = true"
+
+ app_file "app/controllers/application_controller.rb", <<-RUBY
+ class ApplicationController < ActionController::API
+ end
+ RUBY
+
+ app_file "app/controllers/omg_controller.rb", <<-RUBY
+ class OmgController < ApplicationController
+ def show
+ render json: { omg: 'omg' }
+ end
+ end
+ RUBY
+
+ app_file "config/routes.rb", <<-RUBY
+ Rails.application.routes.draw do
+ get "/:controller(/:action)"
+ end
+ RUBY
+
+ require 'rack/test'
+ extend Rack::Test::Methods
+
+ get 'omg/show'
+ assert_equal '{"omg":"omg"}', last_response.body
+ end
+
# AD
test "action_dispatch extensions are applied to ActionDispatch" do
add_to_config "config.action_dispatch.tld_length = 2"
@@ -177,7 +206,7 @@ module ApplicationTests
test "use schema cache dump" do
Dir.chdir(app_path) do
`rails generate model post title:string;
- bundle exec rake db:migrate db:schema:cache:dump`
+ bin/rake db:migrate db:schema:cache:dump`
end
require "#{app_path}/config/environment"
ActiveRecord::Base.connection.drop_table("posts") # force drop posts table for test.
@@ -187,7 +216,7 @@ module ApplicationTests
test "expire schema cache dump" do
Dir.chdir(app_path) do
`rails generate model post title:string;
- bundle exec rake db:migrate db:schema:cache:dump db:rollback`
+ bin/rake db:migrate db:schema:cache:dump db:rollback`
end
silence_warnings {
require "#{app_path}/config/environment"
diff --git a/railties/test/application/initializers/i18n_test.rb b/railties/test/application/initializers/i18n_test.rb
index 9ee54796a4..ab7f29b0f2 100644
--- a/railties/test/application/initializers/i18n_test.rb
+++ b/railties/test/application/initializers/i18n_test.rb
@@ -132,6 +132,79 @@ en:
assert_equal "2", last_response.body
end
+ test "new locale files are loaded" do
+ add_to_config <<-RUBY
+ config.cache_classes = false
+ RUBY
+
+ app_file "config/locales/en.yml", <<-YAML
+en:
+ foo: "1"
+ YAML
+
+ app_file 'config/routes.rb', <<-RUBY
+ Rails.application.routes.draw do
+ get '/i18n', :to => lambda { |env| [200, {}, [I18n.t(:foo)]] }
+ end
+ RUBY
+
+ require 'rack/test'
+ extend Rack::Test::Methods
+ load_app
+
+ get "/i18n"
+ assert_equal "1", last_response.body
+
+ # Wait a full second so we have time for changes to propagate
+ sleep(1)
+
+ remove_file "config/locales/en.yml"
+ app_file "config/locales/custom.en.yml", <<-YAML
+en:
+ foo: "2"
+ YAML
+
+ get "/i18n"
+ assert_equal "2", last_response.body
+ end
+
+ test "I18n.load_path is reloaded" do
+ add_to_config <<-RUBY
+ config.cache_classes = false
+ RUBY
+
+ app_file "config/locales/en.yml", <<-YAML
+en:
+ foo: "1"
+ YAML
+
+ app_file 'config/routes.rb', <<-RUBY
+ Rails.application.routes.draw do
+ get '/i18n', :to => lambda { |env| [200, {}, [I18n.load_path.inspect]] }
+ end
+ RUBY
+
+ require 'rack/test'
+ extend Rack::Test::Methods
+ load_app
+
+ get "/i18n"
+
+ assert_match "en.yml", last_response.body
+
+ # Wait a full second so we have time for changes to propagate
+ sleep(1)
+
+ app_file "config/locales/fr.yml", <<-YAML
+fr:
+ foo: "2"
+ YAML
+
+ get "/i18n"
+ assert_match "fr.yml", last_response.body
+ assert_match "en.yml", last_response.body
+ end
+
# Fallbacks
test "not using config.i18n.fallbacks does not initialize I18n.fallbacks" do
I18n.backend = Class.new(I18n::Backend::Simple).new
diff --git a/railties/test/application/middleware_test.rb b/railties/test/application/middleware_test.rb
index 04bd19784a..d298e8d632 100644
--- a/railties/test/application/middleware_test.rb
+++ b/railties/test/application/middleware_test.rb
@@ -26,7 +26,7 @@ module ApplicationTests
assert_equal [
"Rack::Sendfile",
"ActionDispatch::Static",
- "Rack::Lock",
+ "ActionDispatch::LoadInterlock",
"ActiveSupport::Cache::Strategy::LocalCache",
"Rack::Runtime",
"Rack::MethodOverride",
@@ -50,6 +50,33 @@ module ApplicationTests
], middleware
end
+ test "api middleware stack" do
+ add_to_config "config.api_only = true"
+
+ boot!
+
+ assert_equal [
+ "Rack::Sendfile",
+ "ActionDispatch::Static",
+ "ActionDispatch::LoadInterlock",
+ "ActiveSupport::Cache::Strategy::LocalCache",
+ "Rack::Runtime",
+ "ActionDispatch::RequestId",
+ "Rails::Rack::Logger", # must come after Rack::MethodOverride to properly log overridden methods
+ "ActionDispatch::ShowExceptions",
+ "ActionDispatch::DebugExceptions",
+ "ActionDispatch::RemoteIp",
+ "ActionDispatch::Reloader",
+ "ActionDispatch::Callbacks",
+ "ActiveRecord::ConnectionAdapters::ConnectionManagement",
+ "ActiveRecord::QueryCache",
+ "ActionDispatch::ParamsParser",
+ "Rack::Head",
+ "Rack::ConditionalGet",
+ "Rack::ETag"
+ ], middleware
+ end
+
test "Rack::Cache is not included by default" do
boot!
@@ -94,23 +121,40 @@ module ApplicationTests
assert !middleware.include?("ActiveRecord::Migration::CheckPending")
end
- test "includes lock if cache_classes is set but eager_load is not" do
+ test "includes interlock if cache_classes is set but eager_load is not" do
add_to_config "config.cache_classes = true"
boot!
- assert middleware.include?("Rack::Lock")
+ assert_not_includes middleware, "Rack::Lock"
+ assert_includes middleware, "ActionDispatch::LoadInterlock"
+ end
+
+ test "includes interlock if cache_classes is off" do
+ add_to_config "config.cache_classes = false"
+ boot!
+ assert_not_includes middleware, "Rack::Lock"
+ assert_includes middleware, "ActionDispatch::LoadInterlock"
end
test "does not include lock if cache_classes is set and so is eager_load" do
add_to_config "config.cache_classes = true"
add_to_config "config.eager_load = true"
boot!
- assert !middleware.include?("Rack::Lock")
+ assert_not_includes middleware, "Rack::Lock"
+ assert_not_includes middleware, "ActionDispatch::LoadInterlock"
+ end
+
+ test "does not include lock if allow_concurrency is set to :unsafe" do
+ add_to_config "config.allow_concurrency = :unsafe"
+ boot!
+ assert_not_includes middleware, "Rack::Lock"
+ assert_not_includes middleware, "ActionDispatch::LoadInterlock"
end
- test "does not include lock if allow_concurrency is set" do
- add_to_config "config.allow_concurrency = true"
+ test "includes lock if allow_concurrency is disabled" do
+ add_to_config "config.allow_concurrency = false"
boot!
- assert !middleware.include?("Rack::Lock")
+ assert_includes middleware, "Rack::Lock"
+ assert_not_includes middleware, "ActionDispatch::LoadInterlock"
end
test "removes static asset server if serve_static_files is disabled" do
diff --git a/railties/test/application/multiple_applications_test.rb b/railties/test/application/multiple_applications_test.rb
index cddc79cc85..f2770a9cb4 100644
--- a/railties/test/application/multiple_applications_test.rb
+++ b/railties/test/application/multiple_applications_test.rb
@@ -118,7 +118,7 @@ module ApplicationTests
assert_equal 0, run_count, "Without loading the initializers, the count should be 0"
# Set config.eager_load to false so that an eager_load warning doesn't pop up
- AppTemplate::Application.new { config.eager_load = false }.initialize!
+ AppTemplate::Application.create { config.eager_load = false }.initialize!
assert_equal 3, run_count, "There should have been three initializers that incremented the count"
end
diff --git a/railties/test/application/per_request_digest_cache_test.rb b/railties/test/application/per_request_digest_cache_test.rb
new file mode 100644
index 0000000000..3198e12662
--- /dev/null
+++ b/railties/test/application/per_request_digest_cache_test.rb
@@ -0,0 +1,63 @@
+require 'isolation/abstract_unit'
+require 'rack/test'
+require 'minitest/mock'
+
+require 'action_view'
+require 'active_support/testing/method_call_assertions'
+
+class PerRequestDigestCacheTest < ActiveSupport::TestCase
+ include ActiveSupport::Testing::Isolation
+ include ActiveSupport::Testing::MethodCallAssertions
+ include Rack::Test::Methods
+
+ setup do
+ build_app
+ add_to_config 'config.consider_all_requests_local = true'
+
+ app_file 'app/models/customer.rb', <<-RUBY
+ class Customer < Struct.new(:name, :id)
+ extend ActiveModel::Naming
+ include ActiveModel::Conversion
+ end
+ RUBY
+
+ app_file 'config/routes.rb', <<-RUBY
+ Rails.application.routes.draw do
+ resources :customers, only: :index
+ end
+ RUBY
+
+ app_file 'app/controllers/customers_controller.rb', <<-RUBY
+ class CustomersController < ApplicationController
+ def index
+ render [ Customer.new('david', 1), Customer.new('dingus', 2) ]
+ end
+ end
+ RUBY
+
+ app_file 'app/views/customers/_customer.html.erb', <<-RUBY
+ <% cache customer do %>
+ <%= customer.name %>
+ <% end %>
+ RUBY
+
+ require "#{app_path}/config/environment"
+ end
+
+ teardown :teardown_app
+
+ test "digests are reused when rendering the same template twice" do
+ get '/customers'
+ assert_equal 200, last_response.status
+
+ assert_equal [ '8ba099b7749542fe765ff34a6824d548' ], ActionView::Digestor.cache.values
+ assert_equal %w(david dingus), last_response.body.split.map(&:strip)
+ end
+
+ test "template digests are cleared before a request" do
+ assert_called(ActionView::Digestor.cache, :clear) do
+ get '/customers'
+ assert_equal 200, last_response.status
+ end
+ end
+end
diff --git a/railties/test/application/rake/dbs_test.rb b/railties/test/application/rake/dbs_test.rb
index 5cc9790b28..e7beab8b5e 100644
--- a/railties/test/application/rake/dbs_test.rb
+++ b/railties/test/application/rake/dbs_test.rb
@@ -28,11 +28,11 @@ module ApplicationTests
def db_create_and_drop(expected_database)
Dir.chdir(app_path) do
- output = `bundle exec rake db:create`
+ output = `bin/rake db:create`
assert_empty output
assert File.exist?(expected_database)
assert_equal expected_database, ActiveRecord::Base.connection_config[:database]
- output = `bundle exec rake db:drop`
+ output = `bin/rake db:drop`
assert_empty output
assert !File.exist?(expected_database)
end
@@ -51,9 +51,9 @@ module ApplicationTests
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`
+ `bin/rails generate model book title:string;
+ bin/rake db:migrate`
+ output = `bin/rake db:migrate:status`
assert_match(%r{database:\s+\S*#{Regexp.escape(expected_database)}}, output)
assert_match(/up\s+\d{14}\s+Create books/, output)
end
@@ -72,8 +72,8 @@ module ApplicationTests
def db_schema_dump
Dir.chdir(app_path) do
- `rails generate model book title:string;
- rake db:migrate db:schema:dump`
+ `bin/rails generate model book title:string;
+ bin/rake db:migrate db:schema:dump`
schema_dump = File.read("db/schema.rb")
assert_match(/create_table \"books\"/, schema_dump)
end
@@ -90,8 +90,8 @@ module ApplicationTests
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`
+ `bin/rails generate model book title:string;
+ bin/rake db:migrate db:fixtures:load`
assert_match expected_database, ActiveRecord::Base.connection_config[:database]
require "#{app_path}/app/models/book"
assert_equal 2, Book.count
@@ -112,8 +112,8 @@ module ApplicationTests
test 'db:fixtures:load with namespaced fixture' do
require "#{app_path}/config/environment"
Dir.chdir(app_path) do
- `rails generate model admin::book title:string;
- bundle exec rake db:migrate db:fixtures:load`
+ `bin/rails generate model admin::book title:string;
+ bin/rake db:migrate db:fixtures:load`
require "#{app_path}/app/models/admin/book"
assert_equal 2, Admin::Book.count
end
@@ -121,11 +121,11 @@ module ApplicationTests
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`
+ `bin/rails generate model book title:string;
+ bin/rake db:migrate db:structure:dump`
structure_dump = File.read("db/structure.sql")
assert_match(/CREATE TABLE \"books\"/, structure_dump)
- `bundle exec rake environment db:drop db:structure:load`
+ `bin/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
@@ -147,9 +147,9 @@ module ApplicationTests
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 }'`
+ `bin/rails runner 'ActiveRecord::Base.connection.create_table(:posts) {|t| t.string :title }'`
- stderr_output = capture(:stderr) { `bundle exec rake db:structure:dump` }
+ stderr_output = capture(:stderr) { `bin/rake db:structure:dump` }
assert_empty stderr_output
structure_dump = File.read("db/structure.sql")
assert_match(/CREATE TABLE \"posts\"/, structure_dump)
@@ -211,8 +211,8 @@ module ApplicationTests
def db_test_load_structure
Dir.chdir(app_path) do
- `rails generate model book title:string;
- bundle exec rake db:migrate db:structure:dump db:test:load_structure`
+ `bin/rails generate model book title:string;
+ bin/rake db:migrate db:structure:dump db:test:load_structure`
ActiveRecord::Base.configurations = Rails.application.config.database_configuration
ActiveRecord::Base.establish_connection :test
require "#{app_path}/app/models/book"
@@ -248,7 +248,7 @@ module ApplicationTests
RUBY
Dir.chdir(app_path) do
- database_path = `bundle exec rake db:setup`
+ database_path = `bin/rake db:setup`
assert_equal "development.sqlite3", File.basename(database_path.strip)
end
ensure
diff --git a/railties/test/application/rake/dev_test.rb b/railties/test/application/rake/dev_test.rb
new file mode 100644
index 0000000000..28d8b22a37
--- /dev/null
+++ b/railties/test/application/rake/dev_test.rb
@@ -0,0 +1,35 @@
+require 'isolation/abstract_unit'
+
+module ApplicationTests
+ module RakeTests
+ class RakeDevTest < ActiveSupport::TestCase
+ include ActiveSupport::Testing::Isolation
+
+ def setup
+ build_app
+ boot_rails
+ end
+
+ def teardown
+ teardown_app
+ end
+
+ test 'dev:cache creates file and outputs message' do
+ Dir.chdir(app_path) do
+ output = `rake dev:cache`
+ assert File.exist?('tmp/caching-dev.txt')
+ assert_match(/Development mode is now being cached/, output)
+ end
+ end
+
+ test 'dev:cache deletes file and outputs message' do
+ Dir.chdir(app_path) do
+ output = `rake dev:cache`
+ output = `rake dev:cache`
+ assert_not File.exist?('tmp/caching-dev.txt')
+ assert_match(/Development mode is no longer being cached/, 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 a3819b93b2..2d8bd7c571 100644
--- a/railties/test/application/rake/migrations_test.rb
+++ b/railties/test/application/rake/migrations_test.rb
@@ -15,21 +15,21 @@ module ApplicationTests
test 'running migrations with given scope' do
Dir.chdir(app_path) do
- `rails generate model user username:string password:string`
+ `bin/rails generate model user username:string password:string`
app_file "db/migrate/01_a_migration.bukkits.rb", <<-MIGRATION
class AMigration < ActiveRecord::Migration
end
MIGRATION
- output = `rake db:migrate SCOPE=bukkits`
+ output = `bin/rake db:migrate SCOPE=bukkits`
assert_no_match(/create_table\(:users\)/, output)
assert_no_match(/CreateUsers/, output)
assert_no_match(/add_column\(:users, :email, :string\)/, output)
assert_match(/AMigration: migrated/, output)
- output = `rake db:migrate SCOPE=bukkits VERSION=0`
+ output = `bin/rake db:migrate SCOPE=bukkits VERSION=0`
assert_no_match(/drop_table\(:users\)/, output)
assert_no_match(/CreateUsers/, output)
assert_no_match(/remove_column\(:users, :email\)/, output)
@@ -40,16 +40,16 @@ module ApplicationTests
test 'model and migration generator with change syntax' do
Dir.chdir(app_path) do
- `rails generate model user username:string password:string;
- rails generate migration add_email_to_users email:string`
+ `bin/rails generate model user username:string password:string;
+ bin/rails generate migration add_email_to_users email:string`
- output = `rake db:migrate`
+ output = `bin/rake db:migrate`
assert_match(/create_table\(:users\)/, output)
assert_match(/CreateUsers: migrated/, output)
assert_match(/add_column\(:users, :email, :string\)/, output)
assert_match(/AddEmailToUsers: migrated/, output)
- output = `rake db:rollback STEP=2`
+ output = `bin/rake db:rollback STEP=2`
assert_match(/drop_table\(:users\)/, output)
assert_match(/CreateUsers: reverted/, output)
assert_match(/remove_column\(:users, :email, :string\)/, output)
@@ -58,23 +58,23 @@ module ApplicationTests
end
test 'migration status when schema migrations table is not present' do
- output = Dir.chdir(app_path){ `rake db:migrate:status 2>&1` }
+ output = Dir.chdir(app_path){ `bin/rake db:migrate:status 2>&1` }
assert_equal "Schema migrations table does not exist yet.\n", output
end
test 'test migration status' 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`
+ `bin/rails generate model user username:string password:string;
+ bin/rails generate migration add_email_to_users email:string;
+ bin/rake db:migrate`
- output = `rake db:migrate:status`
+ output = `bin/rake db:migrate:status`
assert_match(/up\s+\d{14}\s+Create users/, output)
assert_match(/up\s+\d{14}\s+Add email to users/, output)
- `rake db:rollback STEP=1`
- output = `rake db:migrate:status`
+ `bin/rake db:rollback STEP=1`
+ output = `bin/rake db:migrate:status`
assert_match(/up\s+\d{14}\s+Create users/, output)
assert_match(/down\s+\d{14}\s+Add email to users/, output)
@@ -85,17 +85,17 @@ module ApplicationTests
add_to_config('config.active_record.timestamped_migrations = false')
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`
+ `bin/rails generate model user username:string password:string;
+ bin/rails generate migration add_email_to_users email:string;
+ bin/rake db:migrate`
- output = `rake db:migrate:status`
+ output = `bin/rake db:migrate:status`
assert_match(/up\s+\d{3,}\s+Create users/, output)
assert_match(/up\s+\d{3,}\s+Add email to users/, output)
- `rake db:rollback STEP=1`
- output = `rake db:migrate:status`
+ `bin/rake db:rollback STEP=1`
+ output = `bin/rake db:migrate:status`
assert_match(/up\s+\d{3,}\s+Create users/, output)
assert_match(/down\s+\d{3,}\s+Add email to users/, output)
@@ -104,23 +104,23 @@ module ApplicationTests
test 'test migration status after rollback and redo' 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`
+ `bin/rails generate model user username:string password:string;
+ bin/rails generate migration add_email_to_users email:string;
+ bin/rake db:migrate`
- output = `rake db:migrate:status`
+ output = `bin/rake db:migrate:status`
assert_match(/up\s+\d{14}\s+Create users/, output)
assert_match(/up\s+\d{14}\s+Add email to users/, output)
- `rake db:rollback STEP=2`
- output = `rake db:migrate:status`
+ `bin/rake db:rollback STEP=2`
+ output = `bin/rake db:migrate:status`
assert_match(/down\s+\d{14}\s+Create users/, output)
assert_match(/down\s+\d{14}\s+Add email to users/, output)
- `rake db:migrate:redo`
- output = `rake db:migrate:status`
+ `bin/rake db:migrate:redo`
+ output = `bin/rake db:migrate:status`
assert_match(/up\s+\d{14}\s+Create users/, output)
assert_match(/up\s+\d{14}\s+Add email to users/, output)
@@ -131,23 +131,23 @@ module ApplicationTests
add_to_config('config.active_record.timestamped_migrations = false')
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`
+ `bin/rails generate model user username:string password:string;
+ bin/rails generate migration add_email_to_users email:string;
+ bin/rake db:migrate`
- output = `rake db:migrate:status`
+ output = `bin/rake db:migrate:status`
assert_match(/up\s+\d{3,}\s+Create users/, output)
assert_match(/up\s+\d{3,}\s+Add email to users/, output)
- `rake db:rollback STEP=2`
- output = `rake db:migrate:status`
+ `bin/rake db:rollback STEP=2`
+ output = `bin/rake db:migrate:status`
assert_match(/down\s+\d{3,}\s+Create users/, output)
assert_match(/down\s+\d{3,}\s+Add email to users/, output)
- `rake db:migrate:redo`
- output = `rake db:migrate:status`
+ `bin/rake db:migrate:redo`
+ output = `bin/rake db:migrate:status`
assert_match(/up\s+\d{3,}\s+Create users/, output)
assert_match(/up\s+\d{3,}\s+Add email to users/, output)
@@ -158,27 +158,29 @@ module ApplicationTests
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`
+ `bin/rails generate model book title:string`
+ output = `bin/rails generate model author name:string`
+ version = output =~ %r{[^/]+db/migrate/(\d+)_create_authors\.rb} && $1
- assert !File.exist?("db/schema.rb")
+ `bin/rake db:migrate db:rollback db:forward db:migrate:up db:migrate:down VERSION=#{version}`
+ assert !File.exist?("db/schema.rb"), "should not dump schema when configured not to"
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`
+ `bin/rails generate model reviews book_id:integer`
+ `bin/rake db:migrate`
structure_dump = File.read("db/schema.rb")
- assert_match(/create_table "authors"/, structure_dump)
+ assert_match(/create_table "reviews"/, 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`
+ `bin/rails generate model book title:string;
+ bin/rake db:migrate`
structure_dump = File.read("db/schema.rb")
assert_match(/create_table "books"/, structure_dump)
@@ -187,12 +189,12 @@ module ApplicationTests
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
+ `bin/rails generate model user username:string password:string;
+ bin/rails generate migration add_email_to_users email:string;
+ bin/rake db:migrate
rm db/migrate/*email*.rb`
- output = `rake db:migrate:status`
+ output = `bin/rake db:migrate:status`
File.write('test.txt', output)
assert_match(/up\s+\d{14}\s+Create users/, output)
diff --git a/railties/test/application/rake/notes_test.rb b/railties/test/application/rake/notes_test.rb
index 95087bf29f..c87515f00f 100644
--- a/railties/test/application/rake/notes_test.rb
+++ b/railties/test/application/rake/notes_test.rb
@@ -74,7 +74,7 @@ module ApplicationTests
app_file "some_other_dir/blah.rb", "# TODO: note in some_other directory"
- run_rake_notes "SOURCE_ANNOTATION_DIRECTORIES='some_other_dir' bundle exec rake notes" do |output, lines|
+ run_rake_notes "SOURCE_ANNOTATION_DIRECTORIES='some_other_dir' bin/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)
@@ -102,7 +102,7 @@ module ApplicationTests
end
EOS
- run_rake_notes "bundle exec rake notes_custom" do |output, lines|
+ run_rake_notes "bin/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)
@@ -114,6 +114,7 @@ module ApplicationTests
end
test 'register a new extension' do
+ add_to_config "config.assets.precompile = []"
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"
@@ -127,7 +128,7 @@ module ApplicationTests
private
- def run_rake_notes(command = 'bundle exec rake notes')
+ def run_rake_notes(command = 'bin/rake notes')
boot_rails
load_tasks
diff --git a/railties/test/application/rake/restart_test.rb b/railties/test/application/rake/restart_test.rb
index 35099913fb..4cae199e6b 100644
--- a/railties/test/application/rake/restart_test.rb
+++ b/railties/test/application/rake/restart_test.rb
@@ -13,12 +13,12 @@ module ApplicationTests
def teardown
teardown_app
end
-
+
test 'rake restart touches tmp/restart.txt' do
Dir.chdir(app_path) do
`rake restart`
assert File.exist?("tmp/restart.txt")
-
+
prev_mtime = File.mtime("tmp/restart.txt")
sleep(1)
`rake restart`
@@ -26,6 +26,14 @@ module ApplicationTests
assert_not_equal prev_mtime, curr_mtime
end
end
+
+ test 'rake restart should work even if tmp folder does not exist' do
+ Dir.chdir(app_path) do
+ FileUtils.remove_dir('tmp')
+ `rake restart`
+ assert File.exist?('tmp/restart.txt')
+ end
+ end
end
end
end
diff --git a/railties/test/application/rake_test.rb b/railties/test/application/rake_test.rb
index de14f269df..a040dd4cf6 100644
--- a/railties/test/application/rake_test.rb
+++ b/railties/test/application/rake_test.rb
@@ -36,7 +36,7 @@ module ApplicationTests
Rails.application.initialize!
RUBY
- assert_match("SuperMiddleware", Dir.chdir(app_path){ `rake middleware` })
+ assert_match("SuperMiddleware", Dir.chdir(app_path){ `bin/rake middleware` })
end
def test_initializers_are_executed_in_rake_tasks
@@ -51,7 +51,7 @@ module ApplicationTests
end
RUBY
- output = Dir.chdir(app_path){ `rake do_nothing` }
+ output = Dir.chdir(app_path){ `bin/rake do_nothing` }
assert_match "Doing something...", output
end
@@ -72,7 +72,7 @@ module ApplicationTests
end
RUBY
- output = Dir.chdir(app_path) { `rake do_nothing` }
+ output = Dir.chdir(app_path) { `bin/rake do_nothing` }
assert_match 'Hello world', output
end
@@ -93,14 +93,14 @@ module ApplicationTests
RUBY
Dir.chdir(app_path) do
- assert system('rake do_nothing RAILS_ENV=production'),
+ assert system('bin/rake do_nothing RAILS_ENV=production'),
'should not be pre-required for rake even eager_load=true'
end
end
def test_code_statistics_sanity
assert_match "Code LOC: 7 Test LOC: 0 Code to Test Ratio: 1:0.0",
- Dir.chdir(app_path){ `rake stats` }
+ Dir.chdir(app_path){ `bin/rake stats` }
end
def test_rake_routes_calls_the_route_inspector
@@ -110,7 +110,7 @@ module ApplicationTests
end
RUBY
- output = Dir.chdir(app_path){ `rake routes` }
+ output = Dir.chdir(app_path){ `bin/rake routes` }
assert_equal "Prefix Verb URI Pattern Controller#Action\n cart GET /cart(.:format) cart#show\n", output
end
@@ -123,7 +123,7 @@ module ApplicationTests
RUBY
ENV['CONTROLLER'] = 'cart'
- output = Dir.chdir(app_path){ `rake routes` }
+ output = Dir.chdir(app_path){ `bin/rake routes` }
assert_equal "Prefix Verb URI Pattern Controller#Action\n cart GET /cart(.:format) cart#show\n", output
end
@@ -133,7 +133,7 @@ module ApplicationTests
end
RUBY
- assert_equal <<-MESSAGE.strip_heredoc, Dir.chdir(app_path){ `rake routes` }
+ assert_equal <<-MESSAGE.strip_heredoc, Dir.chdir(app_path){ `bin/rake routes` }
You don't have any routes defined!
Please add some routes in config/routes.rb.
@@ -151,21 +151,21 @@ module ApplicationTests
end
RUBY
- output = Dir.chdir(app_path){ `rake log_something RAILS_ENV=production && cat log/production.log` }
+ output = Dir.chdir(app_path){ `bin/rake log_something RAILS_ENV=production && cat log/production.log` }
assert_match "Sample log message", output
end
def test_loading_specific_fixtures
Dir.chdir(app_path) do
- `rails generate model user username:string password:string;
- rails generate model product name:string;
- rake db:migrate`
+ `bin/rails generate model user username:string password:string;
+ bin/rails generate model product name:string;
+ bin/rake db:migrate`
end
require "#{rails_root}/config/environment"
# loading a specific fixture
- errormsg = Dir.chdir(app_path) { `rake db:fixtures:load FIXTURES=products` }
+ errormsg = Dir.chdir(app_path) { `bin/rake db:fixtures:load FIXTURES=products` }
assert $?.success?, errormsg
assert_equal 2, ::AppTemplate::Application::Product.count
@@ -174,33 +174,52 @@ module ApplicationTests
def test_loading_only_yml_fixtures
Dir.chdir(app_path) do
- `rake db:migrate`
+ `bin/rake db:migrate`
end
app_file "test/fixtures/products.csv", ""
require "#{rails_root}/config/environment"
- errormsg = Dir.chdir(app_path) { `rake db:fixtures:load` }
+ errormsg = Dir.chdir(app_path) { `bin/rake db:fixtures:load` }
assert $?.success?, errormsg
end
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 test`
+ `bin/rails generate scaffold user username:string password:string;
+ bin/rake db:migrate test`
end
assert_match(/7 runs, 12 assertions, 0 failures, 0 errors/, output)
assert_no_match(/Errors running/, output)
end
+ def test_api_scaffold_tests_pass_by_default
+ add_to_config <<-RUBY
+ config.api_only = true
+ RUBY
+
+ app_file "app/controllers/application_controller.rb", <<-RUBY
+ class ApplicationController < ActionController::API
+ end
+ RUBY
+
+ output = Dir.chdir(app_path) do
+ `bin/rails generate scaffold user username:string password:string;
+ bin/rake db:migrate test`
+ end
+
+ assert_match(/5 runs, 7 assertions, 0 failures, 0 errors/, output)
+ assert_no_match(/Errors running/, output)
+ end
+
def test_scaffold_with_references_columns_tests_pass_when_belongs_to_is_optional
app_file "config/initializers/active_record_belongs_to_required_by_default.rb",
"Rails.application.config.active_record.belongs_to_required_by_default = false"
output = Dir.chdir(app_path) do
- `rails generate scaffold LineItems product:references cart:belongs_to;
- bundle exec rake db:migrate test`
+ `bin/rails generate scaffold LineItems product:references cart:belongs_to;
+ bin/rake db:migrate test`
end
assert_match(/7 runs, 12 assertions, 0 failures, 0 errors/, output)
@@ -210,9 +229,9 @@ module ApplicationTests
def test_db_test_clone_when_using_sql_format
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;
- bundle exec rake db:test:clone 2>&1 --trace`
+ `bin/rails generate scaffold user username:string;
+ bin/rake db:migrate;
+ bin/rake db:test:clone 2>&1 --trace`
end
assert_match(/Execute db:test:clone_structure/, output)
end
@@ -220,9 +239,9 @@ module ApplicationTests
def test_db_test_prepare_when_using_sql_format
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;
- bundle exec rake db:test:prepare 2>&1 --trace`
+ `bin/rails generate scaffold user username:string;
+ bin/rake db:migrate;
+ bin/rake db:test:prepare 2>&1 --trace`
end
assert_match(/Execute db:test:load_structure/, output)
end
@@ -230,7 +249,7 @@ module ApplicationTests
def test_rake_dump_structure_should_respect_db_structure_env_variable
Dir.chdir(app_path) do
# ensure we have a schema_migrations table to dump
- `bundle exec rake db:migrate db:structure:dump SCHEMA=db/my_structure.sql`
+ `bin/rake db:migrate db:structure:dump SCHEMA=db/my_structure.sql`
end
assert File.exist?(File.join(app_path, 'db', 'my_structure.sql'))
end
@@ -239,8 +258,8 @@ module ApplicationTests
add_to_config "config.active_record.schema_format = :sql"
output = Dir.chdir(app_path) do
- `rails g model post title:string;
- bundle exec rake db:migrate:redo 2>&1 --trace;`
+ `bin/rails g model post title:string;
+ bin/rake db:migrate:redo 2>&1 --trace;`
end
# expect only Invoke db:structure:dump (first_time)
@@ -249,23 +268,23 @@ module ApplicationTests
def test_rake_dump_schema_cache
Dir.chdir(app_path) do
- `rails generate model post title:string;
- rails generate model product name:string;
- bundle exec rake db:migrate db:schema:cache:dump`
+ `bin/rails generate model post title:string;
+ bin/rails generate model product name:string;
+ bin/rake db:migrate db:schema:cache:dump`
end
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`
+ `bin/rake db:schema:cache:dump db:schema:cache:clear`
end
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`
+ `bin/rake rails:templates:copy`
%w(controller mailer scaffold).each do |dir|
assert File.exist?(File.join(app_path, 'lib', 'templates', 'erb', dir))
end
@@ -280,10 +299,17 @@ module ApplicationTests
app_file "template.rb", ""
output = Dir.chdir(app_path) do
- `bundle exec rake rails:template LOCATION=template.rb`
+ `bin/rake rails:template LOCATION=template.rb`
end
assert_match(/Hello, World!/, output)
end
+
+ def test_tmp_clear_should_work_if_folder_missing
+ FileUtils.remove_dir("#{app_path}/tmp")
+ errormsg = Dir.chdir(app_path) { `bin/rake tmp:clear` }
+ assert_predicate $?, :success?
+ assert_empty errormsg
+ end
end
end
diff --git a/railties/test/application/runner_test.rb b/railties/test/application/runner_test.rb
index 6595c40f8b..0c180339b4 100644
--- a/railties/test/application/runner_test.rb
+++ b/railties/test/application/runner_test.rb
@@ -25,15 +25,15 @@ module ApplicationTests
end
def test_should_include_runner_in_shebang_line_in_help_without_option
- assert_match "/rails runner", Dir.chdir(app_path) { `bundle exec rails runner` }
+ assert_match "/rails runner", Dir.chdir(app_path) { `bin/rails runner` }
end
def test_should_include_runner_in_shebang_line_in_help
- assert_match "/rails runner", Dir.chdir(app_path) { `bundle exec rails runner --help` }
+ assert_match "/rails runner", Dir.chdir(app_path) { `bin/rails runner --help` }
end
def test_should_run_ruby_statement
- assert_match "42", Dir.chdir(app_path) { `bundle exec rails runner "puts User.count"` }
+ assert_match "42", Dir.chdir(app_path) { `bin/rails runner "puts User.count"` }
end
def test_should_run_file
@@ -41,7 +41,7 @@ module ApplicationTests
puts User.count
SCRIPT
- assert_match "42", Dir.chdir(app_path) { `bundle exec rails runner "bin/count_users.rb"` }
+ assert_match "42", Dir.chdir(app_path) { `bin/rails runner "bin/count_users.rb"` }
end
def test_should_set_dollar_0_to_file
@@ -49,7 +49,7 @@ module ApplicationTests
puts $0
SCRIPT
- assert_match "bin/dollar0.rb", Dir.chdir(app_path) { `bundle exec rails runner "bin/dollar0.rb"` }
+ assert_match "bin/dollar0.rb", Dir.chdir(app_path) { `bin/rails runner "bin/dollar0.rb"` }
end
def test_should_set_dollar_program_name_to_file
@@ -57,7 +57,7 @@ module ApplicationTests
puts $PROGRAM_NAME
SCRIPT
- assert_match "bin/program_name.rb", Dir.chdir(app_path) { `bundle exec rails runner "bin/program_name.rb"` }
+ assert_match "bin/program_name.rb", Dir.chdir(app_path) { `bin/rails runner "bin/program_name.rb"` }
end
def test_with_hook
@@ -67,22 +67,22 @@ module ApplicationTests
end
RUBY
- assert_match "true", Dir.chdir(app_path) { `bundle exec rails runner "puts Rails.application.config.ran"` }
+ assert_match "true", Dir.chdir(app_path) { `bin/rails runner "puts Rails.application.config.ran"` }
end
def test_default_environment
- assert_match "development", Dir.chdir(app_path) { `bundle exec rails runner "puts Rails.env"` }
+ assert_match "development", Dir.chdir(app_path) { `bin/rails runner "puts Rails.env"` }
end
def test_environment_with_rails_env
with_rails_env "production" do
- assert_match "production", Dir.chdir(app_path) { `bundle exec rails runner "puts Rails.env"` }
+ assert_match "production", Dir.chdir(app_path) { `bin/rails runner "puts Rails.env"` }
end
end
def test_environment_with_rack_env
with_rack_env "production" do
- assert_match "production", Dir.chdir(app_path) { `bundle exec rails runner "puts Rails.env"` }
+ assert_match "production", Dir.chdir(app_path) { `bin/rails runner "puts Rails.env"` }
end
end
end
diff --git a/railties/test/application/test_runner_test.rb b/railties/test/application/test_runner_test.rb
index c122b315c0..494e6dd7bd 100644
--- a/railties/test/application/test_runner_test.rb
+++ b/railties/test/application/test_runner_test.rb
@@ -1,9 +1,10 @@
require 'isolation/abstract_unit'
require 'active_support/core_ext/string/strip'
+require 'env_helpers'
module ApplicationTests
class TestRunnerTest < ActiveSupport::TestCase
- include ActiveSupport::Testing::Isolation
+ include ActiveSupport::Testing::Isolation, EnvHelpers
def setup
build_app
@@ -14,20 +15,6 @@ module ApplicationTests
teardown_app
end
- def test_run_in_test_environment
- app_file 'test/unit/env_test.rb', <<-RUBY
- require 'test_helper'
-
- class EnvTest < ActiveSupport::TestCase
- def test_env
- puts "Current Environment: \#{Rails.env}"
- end
- end
- RUBY
-
- assert_match "Current Environment: test", run_test_command('test/unit/env_test.rb')
- end
-
def test_run_single_file
create_test_file :models, 'foo'
create_test_file :models, 'bar'
@@ -187,7 +174,7 @@ module ApplicationTests
end
RUBY
- run_test_command('-p rikka test/unit/chu_2_koi_test.rb').tap do |output|
+ run_test_command('-n /rikka/ test/unit/chu_2_koi_test.rb').tap do |output|
assert_match "Rikka", output
assert_no_match "Sanae", output
end
@@ -229,24 +216,128 @@ module ApplicationTests
assert_match "development", run_test_command('test/unit/env_test.rb')
end
+ def test_run_in_test_environment_by_default
+ create_env_test
+
+ assert_match "Current Environment: test", run_test_command('test/unit/env_test.rb')
+ end
+
def test_run_different_environment
- env = "development"
- app_file 'test/unit/env_test.rb', <<-RUBY
+ create_env_test
+
+ assert_match "Current Environment: development",
+ run_test_command("-e development test/unit/env_test.rb")
+ end
+
+ def test_generated_scaffold_works_with_rails_test
+ create_scaffold
+ assert_match "0 failures, 0 errors, 0 skips", run_test_command('')
+ end
+
+ def test_run_multiple_folders
+ create_test_file :models, 'account'
+ create_test_file :controllers, 'accounts_controller'
+
+ run_test_command('test/models test/controllers').tap do |output|
+ assert_match 'AccountTest', output
+ assert_match 'AccountsControllerTest', output
+ assert_match '2 runs, 2 assertions, 0 failures, 0 errors, 0 skips', output
+ end
+ end
+
+ def test_run_with_ruby_command
+ app_file 'test/models/post_test.rb', <<-RUBY
require 'test_helper'
- class EnvTest < ActiveSupport::TestCase
- def test_env
- puts Rails.env
+ class PostTest < ActiveSupport::TestCase
+ test 'declarative syntax works' do
+ puts 'PostTest'
+ assert true
end
end
RUBY
- assert_match env, run_test_command("-e #{env} test/unit/env_test.rb")
+ Dir.chdir(app_path) do
+ `ruby -Itest test/models/post_test.rb`.tap do |output|
+ assert_match 'PostTest', output
+ assert_no_match 'is already defined in', output
+ end
+ end
end
- def test_generated_scaffold_works_with_rails_test
- create_scaffold
- assert_match "0 failures, 0 errors, 0 skips", run_test_command('')
+ def test_mix_files_and_line_filters
+ create_test_file :models, 'account'
+ app_file 'test/models/post_test.rb', <<-RUBY
+ require 'test_helper'
+
+ class PostTest < ActiveSupport::TestCase
+ def test_post
+ puts 'PostTest'
+ assert true
+ end
+
+ def test_line_filter_does_not_run_this
+ assert true
+ end
+ end
+ RUBY
+
+ run_test_command('test/models/account_test.rb test/models/post_test.rb:4').tap do |output|
+ assert_match 'AccountTest', output
+ assert_match 'PostTest', output
+ assert_match '2 runs, 2 assertions', output
+ end
+ end
+
+ def test_multiple_line_filters
+ create_test_file :models, 'account'
+ create_test_file :models, 'post'
+
+ run_test_command('test/models/account_test.rb:4 test/models/post_test.rb:4').tap do |output|
+ assert_match 'AccountTest', output
+ assert_match 'PostTest', output
+ end
+ end
+
+ def test_line_filter_without_line_runs_all_tests
+ create_test_file :models, 'account'
+
+ run_test_command('test/models/account_test.rb:').tap do |output|
+ assert_match 'AccountTest', output
+ end
+ end
+
+ def test_shows_filtered_backtrace_by_default
+ create_backtrace_test
+
+ assert_match 'Rails::BacktraceCleaner', run_test_command('test/unit/backtrace_test.rb')
+ end
+
+ def test_backtrace_option
+ create_backtrace_test
+
+ assert_match 'Minitest::BacktraceFilter', run_test_command('test/unit/backtrace_test.rb -b')
+ assert_match 'Minitest::BacktraceFilter',
+ run_test_command('test/unit/backtrace_test.rb --backtrace')
+ end
+
+ def test_show_full_backtrace_using_backtrace_environment_variable
+ create_backtrace_test
+
+ switch_env 'BACKTRACE', 'true' do
+ assert_match 'Minitest::BacktraceFilter', run_test_command('test/unit/backtrace_test.rb')
+ end
+ end
+
+ def test_run_app_without_rails_loaded
+ # Simulate a real Rails app boot.
+ app_file 'config/boot.rb', <<-RUBY
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
+
+ require 'bundler/setup' # Set up gems listed in the Gemfile.
+ RUBY
+
+ assert_match '0 runs, 0 assertions', run_test_command('')
end
private
@@ -284,6 +375,18 @@ module ApplicationTests
RUBY
end
+ def create_backtrace_test
+ app_file 'test/unit/backtrace_test.rb', <<-RUBY
+ require 'test_helper'
+
+ class BacktraceTest < ActiveSupport::TestCase
+ def test_backtrace
+ puts Minitest.backtrace_filter
+ end
+ end
+ RUBY
+ end
+
def create_schema
app_file 'db/schema.rb', ''
end
@@ -301,6 +404,18 @@ module ApplicationTests
RUBY
end
+ def create_env_test
+ app_file 'test/unit/env_test.rb', <<-RUBY
+ require 'test_helper'
+
+ class EnvTest < ActiveSupport::TestCase
+ def test_env
+ puts "Current Environment: \#{Rails.env}"
+ end
+ end
+ RUBY
+ end
+
def create_scaffold
script 'generate scaffold user name:string'
Dir.chdir(app_path) { File.exist?('app/models/user.rb') }
@@ -308,7 +423,7 @@ module ApplicationTests
end
def run_migration
- Dir.chdir(app_path) { `bundle exec rake db:migrate` }
+ Dir.chdir(app_path) { `bin/rake db:migrate` }
end
end
end
diff --git a/railties/test/application/test_test.rb b/railties/test/application/test_test.rb
index 61652e5052..0e997f4ba7 100644
--- a/railties/test/application/test_test.rb
+++ b/railties/test/application/test_test.rb
@@ -44,7 +44,7 @@ module ApplicationTests
def test_index
get '/posts'
assert_response :success
- assert_template "index"
+ assert_includes @response.body, 'Posts#index'
end
end
RUBY
@@ -64,8 +64,8 @@ module ApplicationTests
RUBY
output = run_test_file('unit/failing_test.rb', env: { "BACKTRACE" => "1" })
- assert_match %r{/app/test/unit/failing_test\.rb}, output
- assert_match %r{/app/test/unit/failing_test\.rb:4}, output
+ assert_match %r{test/unit/failing_test\.rb}, output
+ assert_match %r{test/unit/failing_test\.rb:4}, output
end
test "ruby schema migrations" do
diff --git a/railties/test/commands/server_test.rb b/railties/test/commands/server_test.rb
index ba688f1e9e..7a063aeddf 100644
--- a/railties/test/commands/server_test.rb
+++ b/railties/test/commands/server_test.rb
@@ -44,6 +44,22 @@ class Rails::ServerTest < ActiveSupport::TestCase
end
end
+ def test_caching_without_option
+ args = []
+ options = Rails::Server::Options.new.parse!(args)
+ assert_equal nil, options[:caching]
+ end
+
+ def test_caching_with_option
+ args = ["--dev-caching"]
+ options = Rails::Server::Options.new.parse!(args)
+ assert_equal true, options[:caching]
+
+ args = ["--no-dev-caching"]
+ options = Rails::Server::Options.new.parse!(args)
+ assert_equal false, options[:caching]
+ end
+
def test_log_stdout
with_rack_env nil do
with_rails_env nil do
diff --git a/railties/test/generators/actions_test.rb b/railties/test/generators/actions_test.rb
index c0b88089b3..2857dae07e 100644
--- a/railties/test/generators/actions_test.rb
+++ b/railties/test/generators/actions_test.rb
@@ -1,7 +1,7 @@
require 'generators/generators_test_helper'
require 'rails/generators/rails/app/app_generator'
require 'env_helpers'
-require 'mocha/setup' # FIXME: stop using mocha
+require 'minitest/mock'
class ActionsTest < Rails::Generators::TestCase
include GeneratorsTestHelper
@@ -12,11 +12,13 @@ class ActionsTest < Rails::Generators::TestCase
def setup
Rails.application = TestApp::Application
+ @mock_generator = Minitest::Mock.new
super
end
def teardown
Rails.application = TestApp::Application.instance
+ @mock_generator.verify
end
def test_invoke_other_generator_with_shortcut
@@ -45,6 +47,14 @@ class ActionsTest < Rails::Generators::TestCase
assert_file 'Gemfile', /source 'http:\/\/gems\.github\.com'/
end
+ def test_add_source_with_block_adds_source_to_gemfile_with_gem
+ run_generator
+ action :add_source, 'http://gems.github.com' do
+ gem 'rspec-rails'
+ end
+ assert_file 'Gemfile', /source 'http:\/\/gems\.github\.com' do\n gem 'rspec-rails'\nend/
+ end
+
def test_gem_should_put_gem_dependency_in_gemfile
run_generator
action :gem, 'will-paginate'
@@ -140,13 +150,18 @@ class ActionsTest < Rails::Generators::TestCase
end
def test_git_with_symbol_should_run_command_using_git_scm
- generator.expects(:run).once.with('git init')
- action :git, :init
+ @mock_generator.expect(:call, nil, ['git init'])
+ generator.stub(:run, @mock_generator) do
+ action :git, :init
+ end
end
def test_git_with_hash_should_run_each_command_using_git_scm
- generator.expects(:run).times(2)
- action :git, rm: 'README', add: '.'
+ @mock_generator.expect(:call, nil, ["git rm README"])
+ @mock_generator.expect(:call, nil, ["git add ."])
+ generator.stub(:run, @mock_generator) do
+ action :git, rm: 'README', add: '.'
+ end
end
def test_vendor_should_write_data_to_file_in_vendor
@@ -170,46 +185,60 @@ class ActionsTest < Rails::Generators::TestCase
end
def test_generate_should_run_script_generate_with_argument_and_options
- generator.expects(:run_ruby_script).once.with('bin/rails generate model MyModel', verbose: false)
- action :generate, 'model', 'MyModel'
+ @mock_generator.expect(:call, nil, ['bin/rails generate model MyModel', verbose: false])
+ generator.stub(:run_ruby_script, @mock_generator) do
+ action :generate, 'model', 'MyModel'
+ end
end
def test_rake_should_run_rake_command_with_default_env
- generator.expects(:run).once.with("rake log:clear RAILS_ENV=development", verbose: false)
- with_rails_env nil do
- action :rake, 'log:clear'
+ @mock_generator.expect(:call, nil, ["rake log:clear RAILS_ENV=development", verbose: false])
+ generator.stub(:run, @mock_generator) do
+ with_rails_env nil do
+ action :rake, 'log:clear'
+ end
end
end
def test_rake_with_env_option_should_run_rake_command_in_env
- generator.expects(:run).once.with('rake log:clear RAILS_ENV=production', verbose: false)
- action :rake, 'log:clear', env: 'production'
+ @mock_generator.expect(:call, nil, ['rake log:clear RAILS_ENV=production', verbose: false])
+ generator.stub(:run, @mock_generator) do
+ action :rake, 'log:clear', env: 'production'
+ end
end
def test_rake_with_rails_env_variable_should_run_rake_command_in_env
- generator.expects(:run).once.with('rake log:clear RAILS_ENV=production', verbose: false)
- with_rails_env "production" do
- action :rake, 'log:clear'
+ @mock_generator.expect(:call, nil, ['rake log:clear RAILS_ENV=production', verbose: false])
+ generator.stub(:run, @mock_generator) do
+ with_rails_env "production" do
+ action :rake, 'log:clear'
+ end
end
end
def test_env_option_should_win_over_rails_env_variable_when_running_rake
- generator.expects(:run).once.with('rake log:clear RAILS_ENV=production', verbose: false)
- with_rails_env "staging" do
- action :rake, 'log:clear', env: 'production'
+ @mock_generator.expect(:call, nil, ['rake log:clear RAILS_ENV=production', verbose: false])
+ generator.stub(:run, @mock_generator) do
+ with_rails_env "staging" do
+ action :rake, 'log:clear', env: 'production'
+ end
end
end
def test_rake_with_sudo_option_should_run_rake_command_with_sudo
- generator.expects(:run).once.with("sudo rake log:clear RAILS_ENV=development", verbose: false)
- with_rails_env nil do
- action :rake, 'log:clear', sudo: true
+ @mock_generator.expect(:call, nil, ["sudo rake log:clear RAILS_ENV=development", verbose: false])
+ generator.stub(:run, @mock_generator) do
+ with_rails_env nil do
+ action :rake, 'log:clear', sudo: true
+ end
end
end
def test_capify_should_run_the_capify_command
- generator.expects(:run).once.with('capify .', verbose: false)
- action :capify!
+ @mock_generator.expect(:call, nil, ['capify .', verbose: false])
+ generator.stub(:run, @mock_generator) do
+ action :capify!
+ end
end
def test_route_should_add_data_to_the_routes_block_in_config_routes
@@ -245,15 +274,19 @@ F
def test_readme
run_generator
- Rails::Generators::AppGenerator.expects(:source_root).times(2).returns(destination_root)
- assert_match "application up and running", action(:readme, "README.md")
+ 2.times { @mock_generator.expect(:call, destination_root,[]) }
+ Rails::Generators::AppGenerator.stub(:source_root, @mock_generator) do
+ assert_match "application up and running", action(:readme, "README.md")
+ end
end
def test_readme_with_quiet
generator(default_arguments, quiet: true)
run_generator
- Rails::Generators::AppGenerator.expects(:source_root).times(2).returns(destination_root)
- assert_no_match "application up and running", action(:readme, "README.md")
+ 2.times { @mock_generator.expect(:call, destination_root,[]) }
+ Rails::Generators::AppGenerator.stub(:source_root, @mock_generator) do
+ assert_no_match "application up and running", action(:readme, "README.md")
+ end
end
def test_log
diff --git a/railties/test/generators/api_app_generator_test.rb b/railties/test/generators/api_app_generator_test.rb
new file mode 100644
index 0000000000..998da3ef84
--- /dev/null
+++ b/railties/test/generators/api_app_generator_test.rb
@@ -0,0 +1,97 @@
+require 'generators/generators_test_helper'
+require 'rails/generators/rails/app/app_generator'
+
+class ApiAppGeneratorTest < Rails::Generators::TestCase
+ include GeneratorsTestHelper
+ tests Rails::Generators::AppGenerator
+
+ arguments [destination_root, '--api']
+
+ def setup
+ Rails.application = TestApp::Application
+ super
+
+ Kernel::silence_warnings do
+ Thor::Base.shell.send(:attr_accessor, :always_force)
+ @shell = Thor::Base.shell.new
+ @shell.send(:always_force=, true)
+ end
+ end
+
+ def teardown
+ super
+ Rails.application = TestApp::Application.instance
+ end
+
+ def test_skeleton_is_created
+ run_generator
+
+ default_files.each { |path| assert_file path }
+ skipped_files.each { |path| assert_no_file path }
+ end
+
+ def test_api_modified_files
+ run_generator
+
+ assert_file "Gemfile" do |content|
+ assert_no_match(/gem 'coffee-rails'/, content)
+ assert_no_match(/gem 'jquery-rails'/, content)
+ assert_no_match(/gem 'sass-rails'/, content)
+ assert_no_match(/gem 'jbuilder'/, content)
+ assert_no_match(/gem 'web-console'/, content)
+ assert_match(/gem 'active_model_serializers'/, content)
+ end
+
+ assert_file "config/application.rb" do |content|
+ assert_match(/config.api_only = true/, content)
+ end
+
+ assert_file "config/initializers/cors.rb"
+
+ assert_file "config/initializers/wrap_parameters.rb"
+
+ assert_file "app/controllers/application_controller.rb", /ActionController::API/
+ end
+
+ private
+
+ def default_files
+ files = %W(
+ .gitignore
+ Gemfile
+ Rakefile
+ config.ru
+ app/controllers
+ app/mailers
+ app/models
+ config/environments
+ config/initializers
+ config/locales
+ db
+ lib
+ lib/tasks
+ log
+ test/fixtures
+ test/controllers
+ test/integration
+ test/models
+ tmp
+ vendor
+ )
+ files.concat %w(bin/bundle bin/rails bin/rake)
+ files
+ end
+
+ def skipped_files
+ %w(app/assets
+ app/helpers
+ app/views
+ config/initializers/assets.rb
+ config/initializers/cookies_serializer.rb
+ config/initializers/session_store.rb
+ lib/assets
+ vendor/assets
+ test/helpers
+ tmp/cache/assets)
+ end
+end
diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb
index 2bfa05a0b8..daf362357c 100644
--- a/railties/test/generators/app_generator_test.rb
+++ b/railties/test/generators/app_generator_test.rb
@@ -44,6 +44,7 @@ DEFAULT_APP_FILES = %w(
vendor/assets
vendor/assets/stylesheets
vendor/assets/javascripts
+ tmp
tmp/cache
tmp/cache/assets
)
@@ -498,7 +499,7 @@ class AppGeneratorTest < Rails::Generators::TestCase
end
def test_application_name_with_spaces
- path = File.join(destination_root, "foo bar".shellescape)
+ path = File.join(destination_root, "foo bar")
# This also applies to MySQL apps but not with SQLite
run_generator [path, "-d", 'postgresql']
@@ -516,7 +517,7 @@ class AppGeneratorTest < Rails::Generators::TestCase
run_generator [destination_root, "--dev"]
assert_file "Gemfile" do |content|
- assert_match(/gem 'web-console',\s+github: "rails\/web-console"/, content)
+ assert_match(/gem 'web-console',\s+github: 'rails\/web-console'/, content)
assert_no_match(/gem 'web-console', '~> 2.0'/, content)
end
end
@@ -525,7 +526,7 @@ class AppGeneratorTest < Rails::Generators::TestCase
run_generator [destination_root, "--edge"]
assert_file "Gemfile" do |content|
- assert_match(/gem 'web-console',\s+github: "rails\/web-console"/, content)
+ assert_match(/gem 'web-console',\s+github: 'rails\/web-console'/, content)
assert_no_match(/gem 'web-console', '~> 2.0'/, content)
end
end
@@ -606,6 +607,32 @@ class AppGeneratorTest < Rails::Generators::TestCase
end
end
+ def test_create_keeps
+ run_generator
+ folders_with_keep = %w(
+ app/assets/images
+ app/mailers
+ app/models
+ app/controllers/concerns
+ app/models/concerns
+ lib/tasks
+ lib/assets
+ log
+ test/fixtures
+ test/fixtures/files
+ test/controllers
+ test/mailers
+ test/models
+ test/helpers
+ test/integration
+ tmp
+ vendor/assets/stylesheets
+ )
+ folders_with_keep.each do |folder|
+ assert_file("#{folder}/.keep")
+ end
+ end
+
def test_psych_gem
run_generator
gem_regex = /gem 'psych',\s+'~> 2.0',\s+platforms: :rbx/
diff --git a/railties/test/generators/plugin_generator_test.rb b/railties/test/generators/plugin_generator_test.rb
index d6e5f4bd89..afccf9d885 100644
--- a/railties/test/generators/plugin_generator_test.rb
+++ b/railties/test/generators/plugin_generator_test.rb
@@ -38,7 +38,7 @@ class PluginGeneratorTest < Rails::Generators::TestCase
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: [\"application\", \"destroy\", \"plugin\", \"runner\", \"test\"]\n", content
+ assert_equal "Invalid plugin name plugin. Please give a name which does not match one of the reserved rails words: application, destroy, plugin, runner, test\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
@@ -313,6 +313,7 @@ class PluginGeneratorTest < Rails::Generators::TestCase
assert_file "test/test_helper.rb" do |content|
assert_match(/ActiveRecord::Migrator\.migrations_paths.+\.\.\/test\/dummy\/db\/migrate/, content)
assert_match(/ActiveRecord::Migrator\.migrations_paths.+<<.+\.\.\/db\/migrate/, content)
+ assert_match(/ActionDispatch::IntegrationTest\.fixture_path = ActiveSupport::TestCase\.fixture_pat/, content)
end
end
@@ -322,7 +323,7 @@ class PluginGeneratorTest < Rails::Generators::TestCase
assert_file "hyphenated-name/app/assets/stylesheets/hyphenated/name"
assert_file "hyphenated-name/app/assets/images/hyphenated/name"
assert_file "hyphenated-name/config/routes.rb", /Hyphenated::Name::Engine.routes.draw do/
- assert_file "hyphenated-name/lib/hyphenated/name/version.rb", /module Hyphenated\n module Name\n VERSION = "0.0.1"\n end\nend/
+ assert_file "hyphenated-name/lib/hyphenated/name/version.rb", /module Hyphenated\n module Name\n VERSION = '0.1.0'\n end\nend/
assert_file "hyphenated-name/lib/hyphenated/name/engine.rb", /module Hyphenated\n module Name\n class Engine < ::Rails::Engine\n isolate_namespace Hyphenated::Name\n end\n end\nend/
assert_file "hyphenated-name/lib/hyphenated/name.rb", /require "hyphenated\/name\/engine"/
assert_file "hyphenated-name/test/dummy/config/routes.rb", /mount Hyphenated::Name::Engine => "\/hyphenated-name"/
@@ -341,7 +342,7 @@ class PluginGeneratorTest < Rails::Generators::TestCase
assert_file "my_hyphenated-name/app/assets/stylesheets/my_hyphenated/name"
assert_file "my_hyphenated-name/app/assets/images/my_hyphenated/name"
assert_file "my_hyphenated-name/config/routes.rb", /MyHyphenated::Name::Engine.routes.draw do/
- assert_file "my_hyphenated-name/lib/my_hyphenated/name/version.rb", /module MyHyphenated\n module Name\n VERSION = "0.0.1"\n end\nend/
+ assert_file "my_hyphenated-name/lib/my_hyphenated/name/version.rb", /module MyHyphenated\n module Name\n VERSION = '0.1.0'\n end\nend/
assert_file "my_hyphenated-name/lib/my_hyphenated/name/engine.rb", /module MyHyphenated\n module Name\n class Engine < ::Rails::Engine\n isolate_namespace MyHyphenated::Name\n end\n end\nend/
assert_file "my_hyphenated-name/lib/my_hyphenated/name.rb", /require "my_hyphenated\/name\/engine"/
assert_file "my_hyphenated-name/test/dummy/config/routes.rb", /mount MyHyphenated::Name::Engine => "\/my_hyphenated-name"/
@@ -360,7 +361,7 @@ class PluginGeneratorTest < Rails::Generators::TestCase
assert_file "deep-hyphenated-name/app/assets/stylesheets/deep/hyphenated/name"
assert_file "deep-hyphenated-name/app/assets/images/deep/hyphenated/name"
assert_file "deep-hyphenated-name/config/routes.rb", /Deep::Hyphenated::Name::Engine.routes.draw do/
- assert_file "deep-hyphenated-name/lib/deep/hyphenated/name/version.rb", /module Deep\n module Hyphenated\n module Name\n VERSION = "0.0.1"\n end\n end\nend/
+ assert_file "deep-hyphenated-name/lib/deep/hyphenated/name/version.rb", /module Deep\n module Hyphenated\n module Name\n VERSION = '0.1.0'\n end\n end\nend/
assert_file "deep-hyphenated-name/lib/deep/hyphenated/name/engine.rb", /module Deep\n module Hyphenated\n module Name\n class Engine < ::Rails::Engine\n isolate_namespace Deep::Hyphenated::Name\n end\n end\n end\nend/
assert_file "deep-hyphenated-name/lib/deep/hyphenated/name.rb", /require "deep\/hyphenated\/name\/engine"/
assert_file "deep-hyphenated-name/test/dummy/config/routes.rb", /mount Deep::Hyphenated::Name::Engine => "\/deep-hyphenated-name"/
@@ -544,6 +545,60 @@ class PluginGeneratorTest < Rails::Generators::TestCase
end
end
+ def test_skipping_useless_folders_generation_for_api_engines
+ ['--full', '--mountable'].each do |option|
+ run_generator [destination_root, option, '--api']
+
+ assert_no_directory "app/assets"
+ assert_no_directory "app/helpers"
+ assert_no_directory "app/views"
+
+ FileUtils.rm_rf destination_root
+ end
+ end
+
+ def test_application_controller_parent_for_mountable_api_plugins
+ run_generator [destination_root, '--mountable', '--api']
+
+ assert_file "app/controllers/bukkits/application_controller.rb" do |content|
+ assert_match "ApplicationController < ActionController::API", content
+ end
+ end
+
+ def test_dummy_api_application_for_api_plugins
+ run_generator [destination_root, '--api']
+
+ assert_file "test/dummy/config/application.rb" do |content|
+ assert_match "config.api_only = true", content
+ end
+ end
+
+
+ def test_api_generators_configuration_for_api_engines
+ run_generator [destination_root, '--full', '--api']
+
+ assert_file "lib/bukkits/engine.rb" do |content|
+ assert_match "config.generators.api_only = true", content
+ end
+ end
+
+ def test_scaffold_generator_for_mountable_api_plugins
+ run_generator [destination_root, '--mountable', '--api']
+
+ capture(:stdout) do
+ `#{destination_root}/bin/rails g scaffold article`
+ end
+
+ assert_file "app/models/bukkits/article.rb"
+ assert_file "app/controllers/bukkits/articles_controller.rb" do |content|
+ assert_match "only: [:show, :update, :destroy]", content
+ end
+
+ assert_no_directory "app/assets"
+ assert_no_directory "app/helpers"
+ assert_no_directory "app/views"
+ end
+
protected
def action(*args, &block)
silence(:stdout){ generator.send(*args, &block) }
diff --git a/railties/test/generators/scaffold_controller_generator_test.rb b/railties/test/generators/scaffold_controller_generator_test.rb
index 34e752cea1..95ef853a11 100644
--- a/railties/test/generators/scaffold_controller_generator_test.rb
+++ b/railties/test/generators/scaffold_controller_generator_test.rb
@@ -174,4 +174,73 @@ class ScaffoldControllerGeneratorTest < Rails::Generators::TestCase
end
end
end
+
+ def test_controller_tests_pass_by_default_inside_mountable_engine
+ Dir.chdir(destination_root) { `bundle exec rails plugin new bukkits --mountable` }
+
+ engine_path = File.join(destination_root, "bukkits")
+
+ Dir.chdir(engine_path) do
+ quietly { `bin/rails g controller dashboard foo` }
+ assert_match(/2 runs, 2 assertions, 0 failures, 0 errors/, `bin/rails test 2>&1`)
+ end
+ end
+
+ def test_controller_tests_pass_by_default_inside_full_engine
+ Dir.chdir(destination_root) { `bundle exec rails plugin new bukkits --full` }
+
+ engine_path = File.join(destination_root, "bukkits")
+
+ Dir.chdir(engine_path) do
+ quietly { `bin/rails g controller dashboard foo` }
+ assert_match(/2 runs, 2 assertions, 0 failures, 0 errors/, `bin/rails test 2>&1`)
+ end
+ end
+
+ def test_api_only_generates_a_proper_api_controller
+ run_generator ["User", "--api"]
+
+ assert_file "app/controllers/users_controller.rb" do |content|
+ assert_match(/class UsersController < ApplicationController/, content)
+ assert_no_match(/respond_to/, content)
+
+ assert_match(/before_action :set_user, only: \[:show, :update, :destroy\]/, content)
+
+ assert_instance_method :index, content do |m|
+ assert_match(/@users = User\.all/, m)
+ assert_match(/render json: @users/, m)
+ end
+
+ assert_instance_method :show, content do |m|
+ assert_match(/render json: @user/, m)
+ end
+
+ assert_instance_method :create, content do |m|
+ assert_match(/@user = User\.new\(user_params\)/, m)
+ assert_match(/@user\.save/, m)
+ assert_match(/@user\.errors/, m)
+ end
+
+ assert_instance_method :update, content do |m|
+ assert_match(/@user\.update\(user_params\)/, m)
+ assert_match(/@user\.errors/, m)
+ end
+
+ assert_instance_method :destroy, content do |m|
+ assert_match(/@user\.destroy/, m)
+ end
+ end
+ end
+
+ def test_api_controller_tests
+ run_generator ["User", "name:string", "age:integer", "organization:references{polymorphic}", "--api"]
+
+ assert_file "test/controllers/users_controller_test.rb" do |content|
+ assert_match(/class UsersControllerTest < ActionController::TestCase/, content)
+ assert_match(/test "should get index"/, content)
+ assert_match(/post :create, params: \{ user: \{ age: @user\.age, name: @user\.name, organization_id: @user\.organization_id, organization_type: @user\.organization_type \} \}/, content)
+ assert_match(/patch :update, params: \{ id: @user, user: \{ age: @user\.age, name: @user\.name, organization_id: @user\.organization_id, organization_type: @user\.organization_type \} \}/, content)
+ assert_no_match(/assert_redirected_to/, content)
+ end
+ end
end
diff --git a/railties/test/generators/scaffold_generator_test.rb b/railties/test/generators/scaffold_generator_test.rb
index ee06802874..0c3808a9a0 100644
--- a/railties/test/generators/scaffold_generator_test.rb
+++ b/railties/test/generators/scaffold_generator_test.rb
@@ -87,6 +87,76 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase
assert_file "app/assets/stylesheets/product_lines.css"
end
+ def test_api_scaffold_on_invoke
+ run_generator %w(product_line title:string product:belongs_to user:references --api --no-template-engine --no-helper --no-assets)
+
+ # Model
+ assert_file "app/models/product_line.rb", /class ProductLine < ActiveRecord::Base/
+ assert_file "test/models/product_line_test.rb", /class ProductLineTest < ActiveSupport::TestCase/
+ assert_file "test/fixtures/product_lines.yml"
+ assert_migration "db/migrate/create_product_lines.rb", /belongs_to :product, index: true/
+ assert_migration "db/migrate/create_product_lines.rb", /references :user, index: true/
+
+ # Route
+ assert_file "config/routes.rb" do |route|
+ assert_match(/resources :product_lines$/, route)
+ end
+
+ # Controller
+ assert_file "app/controllers/product_lines_controller.rb" do |content|
+ assert_match(/class ProductLinesController < ApplicationController/, content)
+ assert_no_match(/respond_to/, content)
+
+ assert_match(/before_action :set_product_line, only: \[:show, :update, :destroy\]/, content)
+
+ assert_instance_method :index, content do |m|
+ assert_match(/@product_lines = ProductLine\.all/, m)
+ assert_match(/render json: @product_lines/, m)
+ end
+
+ assert_instance_method :show, content do |m|
+ assert_match(/render json: @product_line/, m)
+ end
+
+ assert_instance_method :create, content do |m|
+ assert_match(/@product_line = ProductLine\.new\(product_line_params\)/, m)
+ assert_match(/@product_line\.save/, m)
+ assert_match(/@product_line\.errors/, m)
+ end
+
+ assert_instance_method :update, content do |m|
+ assert_match(/@product_line\.update\(product_line_params\)/, m)
+ assert_match(/@product_line\.errors/, m)
+ end
+
+ assert_instance_method :destroy, content do |m|
+ assert_match(/@product_line\.destroy/, m)
+ end
+ end
+
+ assert_file "test/controllers/product_lines_controller_test.rb" do |test|
+ assert_match(/class ProductLinesControllerTest < ActionController::TestCase/, test)
+ assert_match(/post :create, params: \{ product_line: \{ product_id: @product_line\.product_id, title: @product_line\.title, user_id: @product_line\.user_id \} \}/, test)
+ assert_match(/patch :update, params: \{ id: @product_line, product_line: \{ product_id: @product_line\.product_id, title: @product_line\.title, user_id: @product_line\.user_id \} \}/, test)
+ assert_no_match(/assert_redirected_to/, test)
+ end
+
+ # Views
+ assert_no_file "app/views/layouts/product_lines.html.erb"
+
+ %w(index show new edit _form).each do |view|
+ assert_no_file "app/views/product_lines/#{view}.html.erb"
+ end
+
+ # Helpers
+ assert_no_file "app/helpers/product_lines_helper.rb"
+
+ # Assets
+ assert_no_file "app/assets/stylesheets/scaffold.css"
+ assert_no_file "app/assets/javascripts/product_lines.js"
+ assert_no_file "app/assets/stylesheets/product_lines.css"
+ end
+
def test_functional_tests_without_attributes
run_generator ["product_line"]
@@ -282,6 +352,20 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase
assert_no_file "app/assets/stylesheets/posts.css"
end
+ def test_scaffold_generator_no_scaffold_stylesheet_with_switch_no_scaffold_stylesheet
+ run_generator [ "posts", "--no-scaffold-stylesheet" ]
+ assert_no_file "app/assets/stylesheets/scaffold.css"
+ assert_file "app/assets/javascripts/posts.js"
+ assert_file "app/assets/stylesheets/posts.css"
+ end
+
+ def test_scaffold_generator_no_scaffold_stylesheet_with_switch_scaffold_stylesheet_false
+ run_generator [ "posts", "--scaffold-stylesheet=false" ]
+ assert_no_file "app/assets/stylesheets/scaffold.css"
+ assert_file "app/assets/javascripts/posts.js"
+ assert_file "app/assets/stylesheets/posts.css"
+ end
+
def test_scaffold_generator_with_switch_resource_route_false
run_generator [ "posts", "--resource-route=false" ]
assert_file "config/routes.rb" do |route|
@@ -393,4 +477,60 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase
assert_match(/password_digest: <%= BCrypt::Password.create\('secret'\) %>/, content)
end
end
+
+ def test_scaffold_tests_pass_by_default_inside_mountable_engine
+ Dir.chdir(destination_root) { `bundle exec rails plugin new bukkits --mountable` }
+
+ engine_path = File.join(destination_root, "bukkits")
+
+ Dir.chdir(engine_path) do
+ quietly do
+ `bin/rails g scaffold User name:string age:integer;
+ bundle exec rake db:migrate`
+ end
+ assert_match(/8 runs, 13 assertions, 0 failures, 0 errors/, `bin/rails test 2>&1`)
+ end
+ end
+
+ def test_scaffold_tests_pass_by_default_inside_full_engine
+ Dir.chdir(destination_root) { `bundle exec rails plugin new bukkits --full` }
+
+ engine_path = File.join(destination_root, "bukkits")
+
+ Dir.chdir(engine_path) do
+ quietly do
+ `bin/rails g scaffold User name:string age:integer;
+ bundle exec rake db:migrate`
+ end
+ assert_match(/8 runs, 13 assertions, 0 failures, 0 errors/, `bin/rails test 2>&1`)
+ end
+ end
+
+ def test_scaffold_tests_pass_by_default_inside_api_mountable_engine
+ Dir.chdir(destination_root) { `bundle exec rails plugin new bukkits --mountable --api` }
+
+ engine_path = File.join(destination_root, "bukkits")
+
+ Dir.chdir(engine_path) do
+ quietly do
+ `bin/rails g scaffold User name:string age:integer;
+ bundle exec rake db:migrate`
+ end
+ assert_match(/6 runs, 8 assertions, 0 failures, 0 errors/, `bin/rails test 2>&1`)
+ end
+ end
+
+ def test_scaffold_tests_pass_by_default_inside_api_full_engine
+ Dir.chdir(destination_root) { `bundle exec rails plugin new bukkits --full --api` }
+
+ engine_path = File.join(destination_root, "bukkits")
+
+ Dir.chdir(engine_path) do
+ quietly do
+ `bin/rails g scaffold User name:string age:integer;
+ bundle exec rake db:migrate`
+ end
+ assert_match(/6 runs, 8 assertions, 0 failures, 0 errors/, `bin/rails test 2>&1`)
+ end
+ end
end
diff --git a/railties/test/generators/shared_generator_tests.rb b/railties/test/generators/shared_generator_tests.rb
index 3a2195035f..77372fb514 100644
--- a/railties/test/generators/shared_generator_tests.rb
+++ b/railties/test/generators/shared_generator_tests.rb
@@ -56,7 +56,7 @@ module SharedGeneratorTests
reserved_words = %w[application destroy plugin runner test]
reserved_words.each do |reserved|
content = capture(:stderr){ run_generator [File.join(destination_root, reserved)] }
- assert_match(/Invalid \w+ name #{reserved}. Please give a name which does not match one of the reserved rails words: \["application", "destroy", "plugin", "runner", "test"\]\n/, content)
+ assert_match(/Invalid \w+ name #{reserved}. Please give a name which does not match one of the reserved rails words: application, destroy, plugin, runner, test\n/, content)
end
end
@@ -86,15 +86,6 @@ module SharedGeneratorTests
end
end
- def test_template_is_executed_when_supplied
- path = "https://gist.github.com/josevalim/103208/raw/"
- template = %{ say "It works!" }
- template.instance_eval "def read; self; end" # Make the string respond to read
-
- generator([destination_root], template: path).expects(:open).with(path, 'Accept' => 'application/x-thor-template').returns(template)
- quietly { assert_match(/It works!/, capture(:stdout) { generator.invoke_all }) }
- end
-
def test_template_is_executed_when_supplied_an_https_path
path = "https://gist.github.com/josevalim/103208/raw/"
template = %{ say "It works!" }
diff --git a/railties/test/paths_test.rb b/railties/test/paths_test.rb
index 12630e4d01..96b54c7264 100644
--- a/railties/test/paths_test.rb
+++ b/railties/test/paths_test.rb
@@ -62,6 +62,13 @@ class PathsTest < ActiveSupport::TestCase
assert_equal ["/foo/bar/baz"], @root["app/models"].to_a
end
+ test "absolute current path" do
+ @root.add "config"
+ @root.add "config/locales"
+
+ assert_equal "/foo/bar/config/locales", @root["config/locales"].absolute_current
+ end
+
test "adding multiple physical paths as an array" do
@root.add "app", with: ["/app", "/app2"]
assert_equal ["/app", "/app2"], @root["app"].to_a
@@ -215,6 +222,12 @@ class PathsTest < ActiveSupport::TestCase
assert_equal "*.rb", @root["app"].glob
end
+ test "it should be possible to get extensions by glob" do
+ @root["app"] = "/app"
+ @root["app"].glob = "*.{rb,yml}"
+ assert_equal ["rb", "yml"], @root["app"].extensions
+ end
+
test "it should be possible to override a path's default glob without assignment" do
@root.add "app", with: "/app", glob: "*.rb"
assert_equal "*.rb", @root["app"].glob
diff --git a/railties/test/railties/generators_test.rb b/railties/test/railties/generators_test.rb
index 423ece277e..5f4171d44b 100644
--- a/railties/test/railties/generators_test.rb
+++ b/railties/test/railties/generators_test.rb
@@ -122,5 +122,13 @@ module RailtiesTests
assert_no_file "app/helpers/foo_bar/topics_helper.rb"
end
end
+
+ def test_assert_file_with_special_characters
+ path = "#{app_path}/tmp"
+ file_name = "#{path}/v0.1.4~alpha+nightly"
+ FileUtils.mkdir_p path
+ FileUtils.touch file_name
+ assert_file file_name
+ end
end
end
diff --git a/railties/test/test_unit/reporter_test.rb b/railties/test/test_unit/reporter_test.rb
index 77883612f5..3066ba82d6 100644
--- a/railties/test/test_unit/reporter_test.rb
+++ b/railties/test/test_unit/reporter_test.rb
@@ -32,6 +32,7 @@ class TestUnitReporterTest < ActiveSupport::TestCase
@reporter.record(passing_test)
@reporter.record(skipped_test)
@reporter.report
+ assert_no_match 'Failed tests:', @output.string
assert_rerun_snippet_count 0
end
@@ -43,6 +44,19 @@ class TestUnitReporterTest < ActiveSupport::TestCase
assert_rerun_snippet_count 1
end
+ test "allows to customize the executable in the rerun snippet" do
+ original_executable = Rails::TestUnitReporter.executable
+ begin
+ Rails::TestUnitReporter.executable = "bin/test"
+ @reporter.record(failed_test)
+ @reporter.report
+
+ assert_match %r{^bin/test .*test/test_unit/reporter_test.rb:6$}, @output.string
+ ensure
+ Rails::TestUnitReporter.executable = original_executable
+ end
+ end
+
private
def assert_rerun_snippet_count(snippet_count)
assert_equal snippet_count, @output.string.scan(%r{^bin/rails test }).size
diff --git a/railties/test/test_unit/runner_test.rb b/railties/test/test_unit/runner_test.rb
deleted file mode 100644
index 9ea8b2c114..0000000000
--- a/railties/test/test_unit/runner_test.rb
+++ /dev/null
@@ -1,111 +0,0 @@
-require 'abstract_unit'
-require 'env_helpers'
-require 'rails/test_unit/runner'
-
-class TestUnitTestRunnerTest < ActiveSupport::TestCase
- include EnvHelpers
-
- setup do
- @options = Rails::TestRunner::Options
- end
-
- test "shows the filtered backtrace by default" do
- options = @options.parse([])
- assert_not options[:backtrace]
- end
-
- test "has --backtrace (-b) option to show the full backtrace" do
- options = @options.parse(["-b"])
- assert options[:backtrace]
-
- options = @options.parse(["--backtrace"])
- assert options[:backtrace]
- end
-
- test "show full backtrace using BACKTRACE environment variable" do
- switch_env "BACKTRACE", "true" do
- options = @options.parse([])
- assert options[:backtrace]
- end
- end
-
- test "tests run in the test environment by default" do
- options = @options.parse([])
- assert_equal "test", options[:environment]
- end
-
- test "can run in a specific environment" do
- options = @options.parse(["-e development"])
- assert_equal "development", options[:environment]
- end
-
- test "parse the filename and line" do
- file = "test/test_unit/runner_test.rb"
- absolute_file = File.expand_path __FILE__
- options = @options.parse(["#{file}:20"])
- assert_equal absolute_file, options[:filename]
- assert_equal 20, options[:line]
-
- options = @options.parse(["#{file}:"])
- assert_equal [absolute_file], options[:patterns]
- assert_nil options[:line]
-
- options = @options.parse([file])
- assert_equal [absolute_file], options[:patterns]
- assert_nil options[:line]
- end
-
- test "find_method on same file" do
- options = @options.parse(["#{__FILE__}:#{__LINE__}"])
- runner = Rails::TestRunner.new(options)
- assert_equal "test_find_method_on_same_file", runner.find_method
- end
-
- test "find_method on a different file" do
- options = @options.parse(["foobar.rb:#{__LINE__}"])
- runner = Rails::TestRunner.new(options)
- assert_nil runner.find_method
- end
-
- test "run all tests in a directory" do
- options = @options.parse([__dir__])
-
- assert_equal ["#{__dir__}/**/*_test.rb"], options[:patterns]
- assert_nil options[:filename]
- assert_nil options[:line]
- end
-
- test "run multiple folders" do
- application_dir = File.expand_path("#{__dir__}/../application")
-
- options = @options.parse([__dir__, application_dir])
-
- assert_equal ["#{__dir__}/**/*_test.rb", "#{application_dir}/**/*_test.rb"], options[:patterns]
- assert_nil options[:filename]
- assert_nil options[:line]
-
- runner = Rails::TestRunner.new(options)
- assert runner.test_files.size > 0
- end
-
- test "run multiple files and run one file by line" do
- line = __LINE__
- absolute_file = File.expand_path(__FILE__)
- options = @options.parse([__dir__, "#{__FILE__}:#{line}"])
-
- assert_equal ["#{__dir__}/**/*_test.rb"], options[:patterns]
- assert_equal absolute_file, options[:filename]
- assert_equal line, options[:line]
-
- runner = Rails::TestRunner.new(options)
- assert_equal [absolute_file], runner.test_files, 'Only returns the file that running by line'
- end
-
- test "running multiple files passing line number" do
- line = __LINE__
- options = @options.parse(["foobar.rb:8", "#{__FILE__}:#{line}"])
-
- assert_equal File.expand_path(__FILE__), options[:filename], 'Returns the last file'
- assert_equal line, options[:line]
- end
-end