aboutsummaryrefslogtreecommitdiffstats
path: root/railties
diff options
context:
space:
mode:
Diffstat (limited to 'railties')
-rw-r--r--railties/CHANGELOG.md295
-rw-r--r--railties/MIT-LICENSE4
-rw-r--r--railties/RDOC_MAIN.rdoc2
-rw-r--r--railties/Rakefile20
-rw-r--r--railties/lib/rails/all.rb19
-rw-r--r--railties/lib/rails/api/task.rb7
-rw-r--r--railties/lib/rails/app_loader.rb (renamed from railties/lib/rails/app_rails_loader.rb)4
-rw-r--r--railties/lib/rails/application.rb37
-rw-r--r--railties/lib/rails/application/bootstrap.rb2
-rw-r--r--railties/lib/rails/application/configuration.rb136
-rw-r--r--railties/lib/rails/application/default_middleware_stack.rb48
-rw-r--r--railties/lib/rails/application/finisher.rb6
-rw-r--r--railties/lib/rails/application_controller.rb2
-rw-r--r--railties/lib/rails/cli.rb4
-rw-r--r--railties/lib/rails/code_statistics.rb2
-rw-r--r--railties/lib/rails/code_statistics_calculator.rb1
-rw-r--r--railties/lib/rails/command.rb70
-rw-r--r--railties/lib/rails/commands.rb7
-rw-r--r--railties/lib/rails/commands/commands_tasks.rb43
-rw-r--r--railties/lib/rails/commands/dbconsole.rb2
-rw-r--r--railties/lib/rails/commands/dev_cache.rb21
-rw-r--r--railties/lib/rails/commands/rake_proxy.rb34
-rw-r--r--railties/lib/rails/commands/runner.rb8
-rw-r--r--railties/lib/rails/commands/server.rb47
-rw-r--r--railties/lib/rails/commands/test.rb10
-rw-r--r--railties/lib/rails/configuration.rb22
-rw-r--r--railties/lib/rails/console/app.rb5
-rw-r--r--railties/lib/rails/console/helpers.rb2
-rw-r--r--railties/lib/rails/engine.rb47
-rw-r--r--railties/lib/rails/engine/commands.rb6
-rw-r--r--railties/lib/rails/engine/configuration.rb11
-rw-r--r--railties/lib/rails/gem_version.rb2
-rw-r--r--railties/lib/rails/generators.rb22
-rw-r--r--railties/lib/rails/generators/actions.rb24
-rw-r--r--railties/lib/rails/generators/actions/create_migration.rb2
-rw-r--r--railties/lib/rails/generators/app_base.rb94
-rw-r--r--railties/lib/rails/generators/base.rb10
-rw-r--r--railties/lib/rails/generators/erb/mailer/mailer_generator.rb7
-rw-r--r--railties/lib/rails/generators/erb/mailer/templates/layout.html.erb5
-rw-r--r--railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb6
-rw-r--r--railties/lib/rails/generators/erb/scaffold/templates/index.html.erb2
-rw-r--r--railties/lib/rails/generators/migration.rb10
-rw-r--r--railties/lib/rails/generators/named_base.rb24
-rw-r--r--railties/lib/rails/generators/rails/app/USAGE1
-rw-r--r--railties/lib/rails/generators/rails/app/app_generator.rb74
-rw-r--r--railties/lib/rails/generators/rails/app/templates/Gemfile27
-rw-r--r--railties/lib/rails/generators/rails/app/templates/app/assets/config/manifest.js.tt7
-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/javascripts/cable.coffee11
-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/channels/application_cable/channel.rb5
-rw-r--r--railties/lib/rails/generators/rails/app/templates/app/channels/application_cable/connection.rb5
-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/app/mailers/application_mailer.rb4
-rw-r--r--railties/lib/rails/generators/rails/app/templates/app/models/application_record.rb3
-rw-r--r--railties/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt37
-rw-r--r--railties/lib/rails/generators/rails/app/templates/app/views/layouts/mailer.html.erb.tt13
-rw-r--r--railties/lib/rails/generators/rails/app/templates/app/views/layouts/mailer.text.erb.tt (renamed from railties/lib/rails/generators/erb/mailer/templates/layout.text.erb)0
-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.ru4
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config.ru.tt11
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/application.rb14
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml2
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml2
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt21
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt13
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt8
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/initializers/active_record_belongs_to_required_by_default.rb4
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/initializers/application_controller_renderer.rb4
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/initializers/callback_terminator.rb4
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/initializers/cookies_serializer.rb2
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/initializers/cors.rb16
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/initializers/per_form_csrf_tokens.rb4
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/initializers/request_forgery_protection.rb4
-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/redis/cable.yml9
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/routes.rb56
-rw-r--r--railties/lib/rails/generators/rails/app/templates/db/seeds.rb.tt6
-rw-r--r--railties/lib/rails/generators/rails/app/templates/gitignore6
-rw-r--r--railties/lib/rails/generators/rails/model/USAGE8
-rw-r--r--railties/lib/rails/generators/rails/plugin/plugin_generator.rb59
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/%name%.gemspec9
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/Gemfile4
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/README.md28
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/README.rdoc3
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/Rakefile2
-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/app/jobs/%namespaced_name%/application_job.rb.tt5
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/app/models/%namespaced_name%/application_record.rb.tt6
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/app/models/.empty_directory0
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/bin/test.tt8
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/gitignore1
-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/dummy_manifest.js11
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/rails/engine_manifest.js6
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/rails/javascripts.js2
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/rails/routes.rb1
-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.rb10
-rw-r--r--railties/lib/rails/generators/rails/resource_route/resource_route_generator.rb1
-rw-r--r--railties/lib/rails/generators/rails/scaffold/USAGE2
-rw-r--r--railties/lib/rails/generators/rails/scaffold/scaffold_generator.rb3
-rw-r--r--railties/lib/rails/generators/rails/scaffold/templates/scaffold.css4
-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/rails/scaffold_controller/templates/controller.rb4
-rw-r--r--railties/lib/rails/generators/test_unit/controller/templates/functional_test.rb8
-rw-r--r--railties/lib/rails/generators/test_unit/model/templates/fixtures.yml4
-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.rb44
-rw-r--r--railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb22
-rw-r--r--railties/lib/rails/generators/testing/assertions.rb4
-rw-r--r--railties/lib/rails/generators/testing/behaviour.rb3
-rw-r--r--railties/lib/rails/mailers_controller.rb10
-rw-r--r--railties/lib/rails/paths.rb8
-rw-r--r--railties/lib/rails/source_annotation_extractor.rb2
-rw-r--r--railties/lib/rails/tasks.rb5
-rw-r--r--railties/lib/rails/tasks/engine.rake2
-rw-r--r--railties/lib/rails/tasks/framework.rake34
-rw-r--r--railties/lib/rails/tasks/log.rake25
-rw-r--r--railties/lib/rails/tasks/restart.rake1
-rw-r--r--railties/lib/rails/tasks/statistics.rake1
-rw-r--r--railties/lib/rails/templates/rails/mailers/email.html.erb20
-rw-r--r--railties/lib/rails/test_help.rb7
-rw-r--r--railties/lib/rails/test_unit/line_filtering.rb70
-rw-r--r--railties/lib/rails/test_unit/minitest_plugin.rb94
-rw-r--r--railties/lib/rails/test_unit/railtie.rb6
-rw-r--r--railties/lib/rails/test_unit/reporter.rb102
-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.rake20
-rw-r--r--railties/railties.gemspec2
-rw-r--r--railties/test/app_loader_test.rb (renamed from railties/test/app_rails_loader_test.rb)18
-rw-r--r--railties/test/application/asset_debugging_test.rb20
-rw-r--r--railties/test/application/assets_test.rb132
-rw-r--r--railties/test/application/bin_setup_test.rb8
-rw-r--r--railties/test/application/configuration_test.rb383
-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.rb45
-rw-r--r--railties/test/application/initializers/i18n_test.rb73
-rw-r--r--railties/test/application/loading_test.rb12
-rw-r--r--railties/test/application/mailer_previews_test.rb2
-rw-r--r--railties/test/application/middleware/exceptions_test.rb6
-rw-r--r--railties/test/application/middleware/sendfile_test.rb2
-rw-r--r--railties/test/application/middleware/session_test.rb27
-rw-r--r--railties/test/application/middleware/static_test.rb38
-rw-r--r--railties/test/application/middleware_test.rb62
-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.rb94
-rw-r--r--railties/test/application/rake/framework_test.rb48
-rw-r--r--railties/test/application/rake/migrations_test.rb122
-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.rb117
-rw-r--r--railties/test/application/routing_test.rb12
-rw-r--r--railties/test/application/runner_test.rb30
-rw-r--r--railties/test/application/test_runner_test.rb296
-rw-r--r--railties/test/application/test_test.rb6
-rw-r--r--railties/test/code_statistics_calculator_test.rb16
-rw-r--r--railties/test/commands/dbconsole_test.rb6
-rw-r--r--railties/test/commands/dev_cache_test.rb32
-rw-r--r--railties/test/commands/server_test.rb23
-rw-r--r--railties/test/generators/actions_test.rb105
-rw-r--r--railties/test/generators/api_app_generator_test.rb97
-rw-r--r--railties/test/generators/app_generator_test.rb262
-rw-r--r--railties/test/generators/channel_generator_test.rb29
-rw-r--r--railties/test/generators/generator_test.rb15
-rw-r--r--railties/test/generators/generators_test_helper.rb2
-rw-r--r--railties/test/generators/mailer_generator_test.rb23
-rw-r--r--railties/test/generators/migration_generator_test.rb13
-rw-r--r--railties/test/generators/model_generator_test.rb36
-rw-r--r--railties/test/generators/named_base_test.rb1
-rw-r--r--railties/test/generators/namespaced_generators_test.rb39
-rw-r--r--railties/test/generators/plugin_generator_test.rb116
-rw-r--r--railties/test/generators/plugin_test_helper.rb24
-rw-r--r--railties/test/generators/plugin_test_runner_test.rb105
-rw-r--r--railties/test/generators/resource_generator_test.rb2
-rw-r--r--railties/test/generators/scaffold_controller_generator_test.rb83
-rw-r--r--railties/test/generators/scaffold_generator_test.rb154
-rw-r--r--railties/test/generators/shared_generator_tests.rb62
-rw-r--r--railties/test/generators/test_runner_in_engine_test.rb32
-rw-r--r--railties/test/generators_test.rb42
-rw-r--r--railties/test/isolation/abstract_unit.rb33
-rw-r--r--railties/test/path_generation_test.rb18
-rw-r--r--railties/test/paths_test.rb13
-rw-r--r--railties/test/railties/engine_test.rb69
-rw-r--r--railties/test/railties/generators_test.rb8
-rw-r--r--railties/test/test_unit/reporter_test.rb114
-rw-r--r--railties/test/test_unit/runner_test.rb111
194 files changed, 4444 insertions, 1416 deletions
diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md
index b61c4448b5..2c363c55da 100644
--- a/railties/CHANGELOG.md
+++ b/railties/CHANGELOG.md
@@ -1,3 +1,289 @@
+* Bring back `TEST=` env for `rake test` task.
+
+ *Yves Senn*
+
+* Specify log file names or all logs to clear `rake log:clear`
+
+ Specify which logs to clear when using the `rake log:clear` task, e.g. `rake log:clear LOGS=test,staging`
+
+ Clear all logs from log/*.log e.g. `rake log:clear LOGS=all`
+
+ By default `rake log:clear` clears standard environment log files i.e. 'development,test,production'
+
+ *Pramod Shinde*
+
+* Fix using `add_source` with a block after using `gem` in a custom generator.
+
+ *Will Fisher*
+
+## Rails 5.0.0.beta1 (December 18, 2015) ##
+
+* Newly generated plugins get a `README.md` in Markdown.
+
+ *Yuji Yaginuma*
+
+* The generated config file for the development environment includes a new
+ config line, commented out, showing how to enable the evented file watcher.
+
+ *Xavier Noria*
+
+* `config.debug_exception_response_format` configures the format used
+ in responses when errors occur in development mode.
+
+ Set `config.debug_exception_response_format` to render an HTML page with
+ debug info (using the value `:default`) or render debug info preserving
+ the response format (using the value `:api`).
+
+ *Jorge Bejar*
+
+* Fix setting exit status code for rake test tasks. The exit status code
+ was not set when tests were fired with `rake`. Now, it is being set and it matches
+ behavior of running tests via `rails` command (`rails test`), so no matter if
+ `rake test` or `rails test` command is used the exit code will be set.
+
+ *Arkadiusz Fal*
+
+* Add Command infrastructure to replace rake.
+
+ Also move `rake dev:cache` to new infrastructure. You'll need to use
+ `rails dev:cache` to toggle development caching from now on.
+
+ *Chuck Callebs*
+
+* Allow use of minitest-rails gem with Rails test runner.
+
+ Fixes #22455.
+
+ *Chris Kottom*
+
+* Add `bin/test` script to rails plugin.
+
+ `bin/test` can use the same API as `bin/rails test`.
+
+ *Yuji Yaginuma*
+
+* Make `static_index` part of the `config.public_file_server` config and
+ call it `public_file_server.index_name`.
+
+ *Yuki Nishijima*
+
+* Deprecate `serve_static_files` in favor of `public_file_server.enabled`.
+
+ Unifies the static asset options under `public_file_server`.
+
+ To upgrade, replace occurrences of:
+
+ ```
+ config.serve_static_files = # false or true
+ ```
+
+ in your environment files, with:
+
+ ```
+ config.public_file_server.enabled = # false or true
+ ```
+
+ *Kasper Timm Hansen*
+
+* Deprecate `config.static_cache_control` in favor of
+ `config.public_file_server.headers`.
+
+ To upgrade, replace occurrences of:
+
+ ```
+ config.static_cache_control = 'public, max-age=60'
+ ```
+
+ in your environment files, with:
+
+ ```
+ config.public_file_server.headers = {
+ 'Cache-Control' => 'public, max-age=60'
+ }
+ ```
+
+ `config.public_file_server.headers` can set arbitrary headers, sent along when
+ a response is delivered.
+
+ *Yuki Nishijima*
+
+* Route generator should be idempotent
+ running generators several times no longer require you to cleanup routes.rb
+
+ *Thiago Pinto*
+
+* Allow passing an environment to `config_for`.
+
+ *Simon Eskildsen*
+
+* Allow rake:stats to account for rake tasks in lib/tasks
+
+ *Kevin Deisz*
+
+* Added javascript to update the URL on mailer previews with the currently
+ selected email format. Reloading the page now keeps you on your selected
+ format rather than going back to the default html version.
+
+ *James Kerr*
+
+* Add fail fast to `bin/rails test`
+
+ Adding `--fail-fast` or `-f` when running tests will interrupt the run on
+ the first failure:
+
+ ```
+ # Running:
+
+ ................................................S......E
+
+ ArgumentError: Wups! Bet you didn't expect this!
+ test/models/bunny_test.rb:19:in `block in <class:BunnyTest>'
+
+ bin/rails test test/models/bunny_test.rb:18
+
+ ....................................F
+
+ This failed
+
+ bin/rails test test/models/bunny_test.rb:14
+
+ Interrupted. Exiting...
+
+
+ Finished in 0.051427s, 1808.3872 runs/s, 1769.4972 assertions/s.
+
+ ```
+
+ Note that any unexpected errors don't abort the run.
+
+ *Kasper Timm Hansen*
+
+* Add inline output to `bin/rails test`
+
+ Any failures or errors (and skips if running in verbose mode) are output
+ during a test run:
+
+ ```
+ # Running:
+
+ .....S..........................................F
+
+ This failed
+
+ bin/rails test test/models/bunny_test.rb:14
+
+ .................................E
+
+ ArgumentError: Wups! Bet you didn't expect this!
+ test/models/bunny_test.rb:19:in `block in <class:BunnyTest>'
+
+ bin/rails test test/models/bunny_test.rb:18
+
+ ....................
+
+ Finished in 0.069708s, 1477.6019 runs/s, 1448.9106 assertions/s.
+ ```
+
+ Output can be deferred to after a run with the `--defer-output` option.
+
+ *Kasper Timm Hansen*
+
+* Fix displaying mailer previews on non local requests when config
+ `action_mailer.show_previews` is set
+
+ *Wojciech Wnętrzak*
+
+* `rails server` will now honour the `PORT` environment variable
+
+ *David Cornu*
+
+* 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*
+
+* Generate 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
+ `index`. E.g. to serve `main.html` instead of `index.html` for directory
+ requests, set `config.static_index` to `"main"`.
+
+ *Eliot Sykes*
+
* `bin/setup` uses built-in rake tasks (`log:clear`, `tmp:clear`).
*Mohnish Thallavajhula*
@@ -49,7 +335,7 @@
* Created rake restart task. Restarts your Rails app by touching the
`tmp/restart.txt`.
- Fixes #18876.
+ See #18876.
*Hyonjee Joo*
@@ -138,10 +424,11 @@
Newly generated Rails apps have a new initializer called
`callback_terminator.rb` which sets the value of the configuration option
- `config.active_support.halt_callback_chains_on_return_false` to `false`.
+ `ActiveSupport.halt_callback_chains_on_return_false` to `false`.
- As a result, new Rails apps do not halt callback chains when a callback
- returns `false`; only when they are explicitly halted with `throw(:abort)`.
+ As a result, new Rails apps do not halt Active Record and Active Model
+ callback chains when a callback returns `false`; only when they are
+ explicitly halted with `throw(:abort)`.
The terminator is *not* added when running `rake rails:update`, so returning
`false` will still work on old apps ported to Rails 5, displaying a
diff --git a/railties/MIT-LICENSE b/railties/MIT-LICENSE
index 7c2197229d..1f496cf280 100644
--- a/railties/MIT-LICENSE
+++ b/railties/MIT-LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2015 David Heinemeier Hansson
+Copyright (c) 2004-2016 David Heinemeier Hansson
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
@@ -17,4 +17,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/railties/RDOC_MAIN.rdoc b/railties/RDOC_MAIN.rdoc
index 8d847eaa1c..ce024563c4 100644
--- a/railties/RDOC_MAIN.rdoc
+++ b/railties/RDOC_MAIN.rdoc
@@ -57,7 +57,7 @@ can read more about Action Pack in its {README}[link:files/actionpack/README_rdo
* The \README file created within your application.
* {Getting Started with \Rails}[http://guides.rubyonrails.org/getting_started.html].
-* {Ruby on \Rails Tutorial}[http://ruby.railstutorial.org/ruby-on-rails-tutorial-book].
+* {Ruby on \Rails Tutorial}[http://www.railstutorial.org/book].
* {Ruby on \Rails Guides}[http://guides.rubyonrails.org].
* {The API Documentation}[http://api.rubyonrails.org].
diff --git a/railties/Rakefile b/railties/Rakefile
index 9a377ce4ee..cf130a5f14 100644
--- a/railties/Rakefile
+++ b/railties/Rakefile
@@ -1,5 +1,4 @@
require 'rake/testtask'
-require 'rubygems/package_task'
task :default => :test
@@ -27,24 +26,7 @@ end
Rake::TestTask.new('test:regular') do |t|
t.libs << 'test' << "#{File.dirname(__FILE__)}/../activesupport/lib"
t.pattern = 'test/**/*_test.rb'
- t.warning = true
+ t.warning = false
t.verbose = true
t.ruby_opts = ["--dev"] if defined?(JRUBY_VERSION)
end
-
-# Generate GEM ----------------------------------------------------------------------------
-
-spec = eval(File.read('railties.gemspec'))
-
-Gem::PackageTask.new(spec) do |pkg|
- pkg.gem_spec = spec
-end
-
-# Publishing -------------------------------------------------------
-
-desc "Release to rubygems"
-task :release => :package do
- require 'rake/gemcutter'
- Rake::Gemcutter::Tasks.new(spec).define
- Rake::Task['gem:push'].invoke
-end
diff --git a/railties/lib/rails/all.rb b/railties/lib/rails/all.rb
index 45361fca83..11f4d5c4bc 100644
--- a/railties/lib/rails/all.rb
+++ b/railties/lib/rails/all.rb
@@ -1,16 +1,17 @@
require "rails"
%w(
- active_record
- action_controller
- action_view
- action_mailer
- active_job
- rails/test_unit
- sprockets
-).each do |framework|
+ active_record/railtie
+ action_controller/railtie
+ action_view/railtie
+ action_mailer/railtie
+ active_job/railtie
+ action_cable/engine
+ rails/test_unit/railtie
+ sprockets/railtie
+).each do |railtie|
begin
- require "#{framework}/railtie"
+ require "#{railtie}"
rescue LoadError
end
end
diff --git a/railties/lib/rails/api/task.rb b/railties/lib/rails/api/task.rb
index a082932632..d478bbf9e8 100644
--- a/railties/lib/rails/api/task.rb
+++ b/railties/lib/rails/api/task.rb
@@ -57,6 +57,13 @@ module Rails
)
},
+ 'actioncable' => {
+ :include => %w(
+ README.md
+ lib/action_cable/**/*.rb
+ )
+ },
+
'railties' => {
:include => %w(
README.rdoc
diff --git a/railties/lib/rails/app_rails_loader.rb b/railties/lib/rails/app_loader.rb
index 9a7c6c5f2d..a9fe21824e 100644
--- a/railties/lib/rails/app_rails_loader.rb
+++ b/railties/lib/rails/app_loader.rb
@@ -2,7 +2,7 @@ require 'pathname'
require 'rails/version'
module Rails
- module AppRailsLoader
+ module AppLoader # :nodoc:
extend self
RUBY = Gem.ruby
@@ -29,7 +29,7 @@ generate it and add it to source control:
EOS
- def exec_app_rails
+ def exec_app
original_cwd = Dir.pwd
loop do
diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb
index 8075068b3f..cac31e1eed 100644
--- a/railties/lib/rails/application.rb
+++ b/railties/lib/rails/application.rb
@@ -156,26 +156,20 @@ module Rails
self
end
- # Implements call according to the Rack API. It simply
- # dispatches the request to the underlying middleware stack.
- def call(env)
- req = ActionDispatch::Request.new env
- env["ORIGINAL_FULLPATH"] = req.fullpath
- env["ORIGINAL_SCRIPT_NAME"] = req.script_name
- super(env)
- end
-
# Reload application routes regardless if they changed or not.
def reload_routes!
routes_reloader.reload!
end
- # Return the application's KeyGenerator
+ # Returns the application's KeyGenerator
def key_generator
# number of iterations selected based on consultation with the google security
# team. Details at https://github.com/rails/rails/pull/6952#issuecomment-7661220
@caching_key_generator ||=
if secrets.secret_key_base
+ unless secrets.secret_key_base.kind_of?(String)
+ raise ArgumentError, "`secret_key_base` for #{Rails.env} environment must be a type of String, change this value in `config/secrets.yml`"
+ end
key_generator = ActiveSupport::KeyGenerator.new(secrets.secret_key_base, iterations: 1000)
ActiveSupport::CachingKeyGenerator.new(key_generator)
else
@@ -224,12 +218,16 @@ module Rails
# Rails.application.configure do
# config.middleware.use ExceptionNotifier, config_for(:exception_notification)
# end
- def config_for(name)
- yaml = Pathname.new("#{paths["config"].existent.first}/#{name}.yml")
+ def config_for(name, env: Rails.env)
+ if name.is_a?(Pathname)
+ yaml = name
+ else
+ yaml = Pathname.new("#{paths["config"].existent.first}/#{name}.yml")
+ end
if yaml.exist?
require "erb"
- (YAML.load(ERB.new(yaml.read).result) || {})[Rails.env] || {}
+ (YAML.load(ERB.new(yaml.read).result) || {})[env] || {}
else
raise "Could not load configuration. No such file - #{yaml}"
end
@@ -514,5 +512,18 @@ module Rails
end
end
end
+
+ private
+
+ def build_request(env)
+ req = super
+ env["ORIGINAL_FULLPATH"] = req.fullpath
+ env["ORIGINAL_SCRIPT_NAME"] = req.script_name
+ req
+ end
+
+ def build_middleware
+ config.app_middleware + super
+ end
end
end
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 dc3ec4274b..65cff1561a 100644
--- a/railties/lib/rails/application/configuration.rb
+++ b/railties/lib/rails/application/configuration.rb
@@ -3,6 +3,9 @@ require 'active_support/file_update_checker'
require 'rails/engine/configuration'
require 'rails/source_annotation_extractor'
+require 'active_support/deprecation'
+require 'active_support/core_ext/string/strip' # for strip_heredoc
+
module Rails
class Application
class Configuration < ::Rails::Engine::Configuration
@@ -11,44 +14,75 @@ module Rails
:eager_load, :exceptions_app, :file_watcher, :filter_parameters,
:force_ssl, :helpers_paths, :logger, :log_formatter, :log_tags,
:railties_order, :relative_url_root, :secret_key_base, :secret_token,
- :serve_static_files, :ssl_options, :static_cache_control, :session_options,
- :time_zone, :reload_classes_only_on_change,
+ :ssl_options, :public_file_server,
+ :session_options, :time_zone, :reload_classes_only_on_change,
:beginning_of_week, :filter_redirect, :x
attr_writer :log_level
- attr_reader :encoding
+ attr_reader :encoding, :api_only, :static_cache_control
def initialize(*)
super
self.encoding = "utf-8"
- @allow_concurrency = nil
- @consider_all_requests_local = false
- @filter_parameters = []
- @filter_redirect = []
- @helpers_paths = []
- @serve_static_files = true
- @static_cache_control = nil
- @force_ssl = false
- @ssl_options = {}
- @session_store = :cookie_store
- @session_options = {}
- @time_zone = "UTC"
- @beginning_of_week = :monday
- @log_level = nil
- @middleware = app_middleware
- @generators = app_generators
- @cache_store = [ :file_store, "#{root}/tmp/cache/" ]
- @railties_order = [:all]
- @relative_url_root = ENV["RAILS_RELATIVE_URL_ROOT"]
- @reload_classes_only_on_change = true
- @file_watcher = ActiveSupport::FileUpdateChecker
- @exceptions_app = nil
- @autoflush_log = true
- @log_formatter = ActiveSupport::Logger::SimpleFormatter.new
- @eager_load = nil
- @secret_token = nil
- @secret_key_base = nil
- @x = Custom.new
+ @allow_concurrency = nil
+ @consider_all_requests_local = false
+ @filter_parameters = []
+ @filter_redirect = []
+ @helpers_paths = []
+ @public_file_server = ActiveSupport::OrderedOptions.new
+ @public_file_server.enabled = true
+ @public_file_server.index_name = "index"
+ @force_ssl = false
+ @ssl_options = {}
+ @session_store = :cookie_store
+ @session_options = {}
+ @time_zone = "UTC"
+ @beginning_of_week = :monday
+ @log_level = nil
+ @generators = app_generators
+ @cache_store = [ :file_store, "#{root}/tmp/cache/" ]
+ @railties_order = [:all]
+ @relative_url_root = ENV["RAILS_RELATIVE_URL_ROOT"]
+ @reload_classes_only_on_change = true
+ @file_watcher = ActiveSupport::FileUpdateChecker
+ @exceptions_app = nil
+ @autoflush_log = true
+ @log_formatter = ActiveSupport::Logger::SimpleFormatter.new
+ @eager_load = nil
+ @secret_token = nil
+ @secret_key_base = nil
+ @api_only = false
+ @debug_exception_response_format = nil
+ @x = Custom.new
+ end
+
+ def static_cache_control=(value)
+ ActiveSupport::Deprecation.warn <<-eow.strip_heredoc
+ `static_cache_control` is deprecated and will be removed in Rails 5.1.
+ Please use
+ `config.public_file_server.headers = { 'Cache-Control' => '#{value}' }`
+ instead.
+ eow
+
+ @static_cache_control = value
+ end
+
+ def serve_static_files
+ ActiveSupport::Deprecation.warn <<-eow.strip_heredoc
+ `serve_static_files` is deprecated and will be removed in Rails 5.1.
+ Please use `public_file_server.enabled` instead.
+ eow
+
+ @public_file_server.enabled
+ end
+
+ def serve_static_files=(value)
+ ActiveSupport::Deprecation.warn <<-eow.strip_heredoc
+ `serve_static_files` is deprecated and will be removed in Rails 5.1.
+ Please use `public_file_server.enabled = #{value}` instead.
+ eow
+
+ @public_file_server.enabled = value
end
def encoding=(value)
@@ -59,6 +93,21 @@ module Rails
end
end
+ def api_only=(value)
+ @api_only = value
+ generators.api_only = value
+
+ @debug_exception_response_format ||= :api
+ end
+
+ def debug_exception_response_format
+ @debug_exception_response_format || :default
+ end
+
+ def debug_exception_response_format=(value)
+ @debug_exception_response_format = value
+ end
+
def paths
@paths ||= begin
paths = super
@@ -142,22 +191,21 @@ module Rails
SourceAnnotationExtractor::Annotation
end
- private
- class Custom #:nodoc:
- def initialize
- @configurations = Hash.new
- end
+ class Custom #:nodoc:
+ def initialize
+ @configurations = Hash.new
+ end
- def method_missing(method, *args)
- if method =~ /=$/
- @configurations[$`.to_sym] = args.first
- else
- @configurations.fetch(method) {
- @configurations[method] = ActiveSupport::OrderedOptions.new
- }
- end
+ def method_missing(method, *args)
+ if method =~ /=$/
+ @configurations[$`.to_sym] = args.first
+ else
+ @configurations.fetch(method) {
+ @configurations[method] = ActiveSupport::OrderedOptions.new
+ }
end
end
+ end
end
end
end
diff --git a/railties/lib/rails/application/default_middleware_stack.rb b/railties/lib/rails/application/default_middleware_stack.rb
index 02eea82b0c..4f1cc0703d 100644
--- a/railties/lib/rails/application/default_middleware_stack.rb
+++ b/railties/lib/rails/application/default_middleware_stack.rb
@@ -17,8 +17,11 @@ 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
+ if config.public_file_server.enabled
+ headers = config.public_file_server.headers || {}
+ headers['Cache-Control'.freeze] = config.static_cache_control if config.static_cache_control
+
+ middleware.use ::ActionDispatch::Static, paths["public"].first, index: config.public_file_server.index_name, headers: headers
end
if rack_cache = load_rack_cache
@@ -26,15 +29,35 @@ 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
middleware.use ::Rails::Rack::Logger, config.log_tags
middleware.use ::ActionDispatch::ShowExceptions, show_exceptions_app
- middleware.use ::ActionDispatch::DebugExceptions, app
+ middleware.use ::ActionDispatch::DebugExceptions, app, config.debug_exception_response_format
middleware.use ::ActionDispatch::RemoteIp, config.action_dispatch.ip_spoofing_check, config.action_dispatch.trusted_proxies
unless config.cache_classes
@@ -42,17 +65,16 @@ 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.force_ssl && !config.session_options.key?(:secure)
+ if !config.api_only && config.session_store
+ if config.force_ssl && config.ssl_options.fetch(:secure_cookies, true) && !config.session_options.key?(:secure)
config.session_options[:secure] = true
end
middleware.use config.session_store, config.session_options
middleware.use ::ActionDispatch::Flash
end
- middleware.use ::ActionDispatch::ParamsParser
middleware.use ::Rack::Head
middleware.use ::Rack::ConditionalGet
middleware.use ::Rack::ETag, "no-cache"
@@ -65,14 +87,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/cli.rb b/railties/lib/rails/cli.rb
index dd70c272c6..a8794bc0de 100644
--- a/railties/lib/rails/cli.rb
+++ b/railties/lib/rails/cli.rb
@@ -1,8 +1,8 @@
-require 'rails/app_rails_loader'
+require 'rails/app_loader'
# If we are inside a Rails application this method performs an exec and thus
# the rest of this script is not run.
-Rails::AppRailsLoader.exec_app_rails
+Rails::AppLoader.exec_app
require 'rails/ruby_version_check'
Signal.trap("INT") { puts; exit(1) }
diff --git a/railties/lib/rails/code_statistics.rb b/railties/lib/rails/code_statistics.rb
index fd352dc9b7..8e9097e1ef 100644
--- a/railties/lib/rails/code_statistics.rb
+++ b/railties/lib/rails/code_statistics.rb
@@ -33,7 +33,7 @@ class CodeStatistics #:nodoc:
Hash[@pairs.map{|pair| [pair.first, calculate_directory_statistics(pair.last)]}]
end
- def calculate_directory_statistics(directory, pattern = /.*\.(rb|js|coffee)$/)
+ def calculate_directory_statistics(directory, pattern = /.*\.(rb|js|coffee|rake)$/)
stats = CodeStatisticsCalculator.new
Dir.foreach(directory) do |file_name|
diff --git a/railties/lib/rails/code_statistics_calculator.rb b/railties/lib/rails/code_statistics_calculator.rb
index a142236dbe..fad13e8517 100644
--- a/railties/lib/rails/code_statistics_calculator.rb
+++ b/railties/lib/rails/code_statistics_calculator.rb
@@ -25,6 +25,7 @@ class CodeStatisticsCalculator #:nodoc:
}
PATTERNS[:minitest] = PATTERNS[:rb].merge method: /^\s*(def|test)\s+['"_a-z]/
+ PATTERNS[:rake] = PATTERNS[:rb]
def initialize(lines = 0, code_lines = 0, classes = 0, methods = 0)
@lines = lines
diff --git a/railties/lib/rails/command.rb b/railties/lib/rails/command.rb
new file mode 100644
index 0000000000..f7753cbb83
--- /dev/null
+++ b/railties/lib/rails/command.rb
@@ -0,0 +1,70 @@
+require 'rails/commands/commands_tasks'
+
+module Rails
+ class Command #:nodoc:
+ attr_reader :argv
+
+ def initialize(argv = [])
+ @argv = argv
+
+ @option_parser = build_option_parser
+ @options = {}
+ end
+
+ def self.run(task_name, argv)
+ command_name = command_name_for(task_name)
+
+ if command = command_for(command_name)
+ command.new(argv).run(command_name)
+ else
+ Rails::CommandsTasks.new(argv).run_command!(task_name)
+ end
+ end
+
+ def run(command_name)
+ parse_options_for(command_name)
+ @option_parser.parse! @argv
+
+ public_send(command_name)
+ end
+
+ def self.options_for(command_name, &options_to_parse)
+ @@command_options[command_name] = options_to_parse
+ end
+
+ def self.set_banner(command_name, banner)
+ options_for(command_name) { |opts, _| opts.banner = banner }
+ end
+
+ private
+ @@commands = []
+ @@command_options = {}
+
+ def parse_options_for(command_name)
+ @@command_options.fetch(command_name, proc {}).call(@option_parser, @options)
+ end
+
+ def build_option_parser
+ OptionParser.new do |opts|
+ opts.on('-h', '--help', 'Show this help.') do
+ puts opts
+ exit
+ end
+ end
+ end
+
+ def self.inherited(command)
+ @@commands << command
+ end
+
+ def self.command_name_for(task_name)
+ task_name.gsub(':', '_').to_sym
+ end
+
+ def self.command_for(command_name)
+ @@commands.find do |command|
+ command.public_instance_methods.include?(command_name)
+ end
+ end
+ end
+end
diff --git a/railties/lib/rails/commands.rb b/railties/lib/rails/commands.rb
index 12bd73db24..7627fcf5a0 100644
--- a/railties/lib/rails/commands.rb
+++ b/railties/lib/rails/commands.rb
@@ -7,12 +7,13 @@ aliases = {
"s" => "server",
"db" => "dbconsole",
"r" => "runner",
- "t" => "test",
+ "t" => "test"
}
command = ARGV.shift
command = aliases[command] || command
-require 'rails/commands/commands_tasks'
+require 'rails/command'
+require 'rails/commands/dev_cache'
-Rails::CommandsTasks.new(ARGV).run_command!(command)
+Rails::Command.run(command, ARGV)
diff --git a/railties/lib/rails/commands/commands_tasks.rb b/railties/lib/rails/commands/commands_tasks.rb
index 685d55eea8..da3b9452d5 100644
--- a/railties/lib/rails/commands/commands_tasks.rb
+++ b/railties/lib/rails/commands/commands_tasks.rb
@@ -1,3 +1,5 @@
+require 'rails/commands/rake_proxy'
+
module Rails
# This is a class which takes in a rails command and initiates the appropriate
# initiation sequence.
@@ -5,6 +7,8 @@ module Rails
# Warning: This class mutates ARGV because some commands require manipulating
# it before they are run.
class CommandsTasks # :nodoc:
+ include Rails::RakeProxy
+
attr_reader :argv
HELP_MESSAGE = <<-EOT
@@ -20,14 +24,18 @@ The most common rails commands are:
new Create a new Rails application. "rails new my_app" creates a
new application called MyApp in "./my_app"
-In addition to those, there are:
- destroy Undo code generated with "generate" (short-cut alias: "d")
- plugin new Generates skeleton for developing a Rails plugin
- runner Run a piece of code in the application environment (short-cut alias: "r")
-
All commands can be run with -h (or --help) for more information.
+
+In addition to those commands, there are:
EOT
+ ADDITIONAL_COMMANDS = [
+ [ 'destroy', 'Undo code generated with "generate" (short-cut alias: "d")' ],
+ [ 'plugin new', 'Generates skeleton for developing a Rails plugin' ],
+ [ 'runner',
+ 'Run a piece of code in the application environment (short-cut alias: "r")' ]
+ ]
+
COMMAND_WHITELIST = %w(plugin generate destroy console server dbconsole runner new version help test)
def initialize(argv)
@@ -36,10 +44,11 @@ EOT
def run_command!(command)
command = parse_command(command)
+
if COMMAND_WHITELIST.include?(command)
send(command)
else
- write_error_message(command)
+ run_rake_task(command)
end
end
@@ -110,6 +119,7 @@ EOT
def help
write_help_message
+ write_commands ADDITIONAL_COMMANDS + formatted_rake_tasks
end
private
@@ -151,24 +161,9 @@ EOT
puts HELP_MESSAGE
end
- # Output an error message stating that the attempted command is not a valid rails command.
- # Run the attempted command as a rake command with the --dry-run flag. If successful, suggest
- # to the user that they possibly meant to run the given rails command as a rake command.
- # Append the help message.
- #
- # Example:
- # $ rails db:migrate
- # Error: Command 'db:migrate' not recognized
- # Did you mean: `$ rake db:migrate` ?
- # (Help message output)
- #
- def write_error_message(command)
- puts "Error: Command '#{command}' not recognized"
- if %x{rake #{command} --dry-run 2>&1 } && $?.success?
- puts "Did you mean: `$ rake #{command}` ?\n\n"
- end
- write_help_message
- exit(1)
+ def write_commands(commands)
+ width = commands.map { |name, _| name.size }.max || 10
+ commands.each { |command| printf(" %-#{width}s %s\n", *command) }
end
def parse_command(command)
diff --git a/railties/lib/rails/commands/dbconsole.rb b/railties/lib/rails/commands/dbconsole.rb
index dca60f948f..2c36edfa3f 100644
--- a/railties/lib/rails/commands/dbconsole.rb
+++ b/railties/lib/rails/commands/dbconsole.rb
@@ -65,7 +65,7 @@ module Rails
'sslca' => '--ssl-ca',
'sslcert' => '--ssl-cert',
'sslcapath' => '--ssl-capath',
- 'sslcipher' => '--ssh-cipher',
+ 'sslcipher' => '--ssl-cipher',
'sslkey' => '--ssl-key'
}.map { |opt, arg| "#{arg}=#{config[opt]}" if config[opt] }.compact
diff --git a/railties/lib/rails/commands/dev_cache.rb b/railties/lib/rails/commands/dev_cache.rb
new file mode 100644
index 0000000000..ec96e8f630
--- /dev/null
+++ b/railties/lib/rails/commands/dev_cache.rb
@@ -0,0 +1,21 @@
+require 'rails/command'
+
+module Rails
+ module Commands
+ # This is a wrapper around the Rails dev:cache command
+ class DevCache < Command
+ set_banner :dev_cache, 'Toggle development mode caching on/off'
+ def dev_cache
+ 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
+ end
+end
diff --git a/railties/lib/rails/commands/rake_proxy.rb b/railties/lib/rails/commands/rake_proxy.rb
new file mode 100644
index 0000000000..f7d5df6b2f
--- /dev/null
+++ b/railties/lib/rails/commands/rake_proxy.rb
@@ -0,0 +1,34 @@
+require 'rake'
+require 'active_support'
+
+module Rails
+ module RakeProxy #:nodoc:
+ private
+ def run_rake_task(command)
+ ARGV.unshift(command) # Prepend the command, so Rake knows how to run it.
+
+ Rake.application.standard_exception_handling do
+ Rake.application.init('rails')
+ Rake.application.load_rakefile
+ Rake.application.top_level
+ end
+ end
+
+ def rake_tasks
+ return @rake_tasks if defined?(@rake_tasks)
+
+ ActiveSupport::Deprecation.silence do
+ require_application_and_environment!
+ end
+
+ Rake::TaskManager.record_task_metadata = true
+ Rake.application.instance_variable_set(:@name, 'rails')
+ Rails.application.load_tasks
+ @rake_tasks = Rake.application.tasks.select(&:comment)
+ end
+
+ def formatted_rake_tasks
+ rake_tasks.map { |t| [ t.name_with_args, t.comment ] }
+ end
+ end
+end
diff --git a/railties/lib/rails/commands/runner.rb b/railties/lib/rails/commands/runner.rb
index 86bce9b2fe..babb197ba1 100644
--- a/railties/lib/rails/commands/runner.rb
+++ b/railties/lib/rails/commands/runner.rb
@@ -58,5 +58,11 @@ elsif File.exist?(code_or_file)
$0 = code_or_file
Kernel.load code_or_file
else
- eval(code_or_file, binding, __FILE__, __LINE__)
+ begin
+ eval(code_or_file, binding, __FILE__, __LINE__)
+ rescue SyntaxError,NameError => err
+ $stderr.puts "Please specify a valid ruby command or the path of a script to run."
+ $stderr.puts "Run '#{$0} -h' for help."
+ exit 1
+ end
end
diff --git a/railties/lib/rails/commands/server.rb b/railties/lib/rails/commands/server.rb
index 546d3725d8..45d649ec31 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,33 +81,32 @@ 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
super.merge({
- Port: 3000,
+ Port: ENV.fetch('PORT', 3000).to_i,
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))
@@ -122,11 +133,13 @@ module Rails
def log_to_stdout
wrapped_app # touch the app so the logger is set up
- console = ActiveSupport::Logger.new($stdout)
+ console = ActiveSupport::Logger.new(STDOUT)
console.formatter = Rails.logger.formatter
console.level = Rails.logger.level
- Rails.logger.extend(ActiveSupport::Logger.broadcast(console))
+ unless ActiveSupport::Logger.logger_outputs_to?(Rails.logger, STDOUT)
+ Rails.logger.extend(ActiveSupport::Logger.broadcast(console))
+ end
end
end
end
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..30eafd59f2 100644
--- a/railties/lib/rails/configuration.rb
+++ b/railties/lib/rails/configuration.rb
@@ -33,9 +33,9 @@ module Rails
# config.middleware.delete ActionDispatch::Flash
#
class MiddlewareStackProxy
- def initialize
- @operations = []
- @delete_operations = []
+ def initialize(operations = [], delete_operations = [])
+ @operations = operations
+ @delete_operations = delete_operations
end
def insert_before(*args, &block)
@@ -71,10 +71,23 @@ module Rails
other
end
+
+ def +(other) # :nodoc:
+ MiddlewareStackProxy.new(@operations + other.operations, @delete_operations + other.delete_operations)
+ end
+
+ protected
+ def operations
+ @operations
+ end
+
+ def delete_operations
+ @delete_operations
+ end
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 +96,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/console/helpers.rb b/railties/lib/rails/console/helpers.rb
index b775f1ff8d..a33f71dc5b 100644
--- a/railties/lib/rails/console/helpers.rb
+++ b/railties/lib/rails/console/helpers.rb
@@ -4,7 +4,7 @@ module Rails
#
# This method assumes an +ApplicationController+ exists, and it extends +ActionController::Base+
def helper
- @helper ||= ApplicationController.helpers
+ ApplicationController.helpers
end
# Gets a new instance of a controller object.
diff --git a/railties/lib/rails/engine.rb b/railties/lib/rails/engine.rb
index 1dede32dd4..5757d235d2 100644
--- a/railties/lib/rails/engine.rb
+++ b/railties/lib/rails/engine.rb
@@ -2,6 +2,7 @@ require 'rails/railtie'
require 'rails/engine/railties'
require 'active_support/core_ext/module/delegation'
require 'pathname'
+require 'thread'
module Rails
# <tt>Rails::Engine</tt> allows you to wrap a specific Rails application or subset of
@@ -357,12 +358,7 @@ module Rails
Rails::Railtie::Configuration.eager_load_namespaces << base
base.called_from = begin
- call_stack = if Kernel.respond_to?(:caller_locations)
- caller_locations.map { |l| l.absolute_path || l.path }
- else
- # Remove the line number from backtraces making sure we don't leave anything behind
- caller.map { |p| p.sub(/:\d+.*/, '') }
- end
+ call_stack = caller_locations.map { |l| l.absolute_path || l.path }
File.dirname(call_stack.detect { |p| p !~ %r[railties[\w.-]*/lib/rails|rack[\w.-]*/lib/rack] })
end
@@ -434,6 +430,7 @@ module Rails
@env_config = nil
@helpers = nil
@routes = nil
+ @app_build_lock = Mutex.new
super
end
@@ -504,10 +501,13 @@ module Rails
# Returns the underlying rack application for this engine.
def app
- @app ||= begin
- config.middleware = config.middleware.merge_into(default_middleware_stack)
- config.middleware.build(endpoint)
- end
+ @app || @app_build_lock.synchronize {
+ @app ||= begin
+ stack = default_middleware_stack
+ config.middleware = build_middleware.merge_into(stack)
+ config.middleware.build(endpoint)
+ end
+ }
end
# Returns the endpoint for this engine. If none is registered,
@@ -518,18 +518,13 @@ 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
- app.call(env)
+ req = build_request env
+ app.call req.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 +584,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
@@ -691,5 +686,19 @@ module Rails
def _all_load_paths #:nodoc:
@_all_load_paths ||= (config.paths.load_paths + _all_autoload_paths).uniq
end
+
+ private
+
+ def build_request(env)
+ env.merge!(env_config)
+ req = ActionDispatch::Request.new env
+ req.routes = routes
+ req.engine_script_name = req.script_name
+ req
+ end
+
+ def build_middleware
+ config.middleware
+ end
end
end
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/engine/configuration.rb b/railties/lib/rails/engine/configuration.rb
index 62a4139d07..8cadbc3ddd 100644
--- a/railties/lib/rails/engine/configuration.rb
+++ b/railties/lib/rails/engine/configuration.rb
@@ -4,17 +4,14 @@ module Rails
class Engine
class Configuration < ::Rails::Railtie::Configuration
attr_reader :root
- attr_writer :middleware, :eager_load_paths, :autoload_once_paths, :autoload_paths
+ attr_accessor :middleware
+ attr_writer :eager_load_paths, :autoload_once_paths, :autoload_paths
def initialize(root=nil)
super()
@root = root
@generators = app_generators.dup
- end
-
- # Returns the middleware stack for the engine.
- def middleware
- @middleware ||= Rails::Configuration::MiddlewareStackProxy.new
+ @middleware = Rails::Configuration::MiddlewareStackProxy.new
end
# Holds generators configuration:
@@ -29,7 +26,7 @@ module Rails
#
# config.generators.colorize_logging = false
#
- def generators #:nodoc:
+ def generators
@generators ||= Rails::Configuration::Generators.new
yield(@generators) if block_given?
@generators
diff --git a/railties/lib/rails/gem_version.rb b/railties/lib/rails/gem_version.rb
index 7d74b1bfe5..92230a74e4 100644
--- a/railties/lib/rails/gem_version.rb
+++ b/railties/lib/rails/gem_version.rb
@@ -8,7 +8,7 @@ module Rails
MAJOR = 5
MINOR = 0
TINY = 0
- PRE = "alpha"
+ PRE = "beta1"
STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
end
diff --git a/railties/lib/rails/generators.rb b/railties/lib/rails/generators.rb
index a7da92168d..e3d79521e7 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
@@ -159,7 +178,7 @@ module Rails
options = sorted_groups.flat_map(&:last)
suggestions = options.sort_by {|suggested| levenshtein_distance(namespace.to_s, suggested) }.first(3)
msg = "Could not find generator '#{namespace}'. "
- msg << "Maybe you meant #{ suggestions.map {|s| "'#{s}'"}.to_sentence(last_word_connector: " or ") }\n"
+ msg << "Maybe you meant #{ suggestions.map {|s| "'#{s}'"}.to_sentence(last_word_connector: " or ", locale: :en) }\n"
msg << "Run `rails generate --help` for more options."
puts msg
end
@@ -189,6 +208,7 @@ module Rails
"#{test}:model",
"#{test}:scaffold",
"#{test}:view",
+ "#{test}:job",
"#{template}:controller",
"#{template}:scaffold",
"#{template}:mailer",
diff --git a/railties/lib/rails/generators/actions.rb b/railties/lib/rails/generators/actions.rb
index 70a20801a0..cd83175da8 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", "\nsource #{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
@@ -221,7 +235,7 @@ module Rails
sentinel = /\.routes\.draw do\s*\n/m
in_root do
- inject_into_file 'config/routes.rb', " #{routing_code}\n", { after: sentinel, verbose: false, force: true }
+ inject_into_file 'config/routes.rb', " #{routing_code}\n", { after: sentinel, verbose: false, force: false }
end
end
diff --git a/railties/lib/rails/generators/actions/create_migration.rb b/railties/lib/rails/generators/actions/create_migration.rb
index cffdef6ec9..d664b07652 100644
--- a/railties/lib/rails/generators/actions/create_migration.rb
+++ b/railties/lib/rails/generators/actions/create_migration.rb
@@ -3,7 +3,7 @@ require 'thor/actions'
module Rails
module Generators
module Actions
- class CreateMigration < Thor::Actions::CreateFile
+ class CreateMigration < Thor::Actions::CreateFile #:nodoc:
def migration_dir
File.dirname(@destination)
diff --git a/railties/lib/rails/generators/app_base.rb b/railties/lib/rails/generators/app_base.rb
index 061fafb156..297ccb1dbf 100644
--- a/railties/lib/rails/generators/app_base.rb
+++ b/railties/lib/rails/generators/app_base.rb
@@ -26,6 +26,12 @@ module Rails
class_option :template, type: :string, aliases: '-m',
desc: "Path to some #{name} template (can be a filesystem path or URL)"
+ class_option :database, type: :string, aliases: '-d', default: 'sqlite3',
+ desc: "Preconfigure for selected database (options: #{DATABASES.join('/')})"
+
+ class_option :javascript, type: :string, aliases: '-j', default: 'jquery',
+ desc: 'Preconfigure for selected JavaScript library'
+
class_option :skip_gemfile, type: :boolean, default: false,
desc: "Don't create a Gemfile"
@@ -45,34 +51,31 @@ module Rails
class_option :skip_active_record, type: :boolean, aliases: '-O', default: false,
desc: 'Skip Active Record files'
+ class_option :skip_action_cable, type: :boolean, aliases: '-C', default: false,
+ desc: 'Skip Action Cable files'
+
class_option :skip_sprockets, type: :boolean, aliases: '-S', default: false,
desc: 'Skip Sprockets files'
class_option :skip_spring, type: :boolean, default: false,
desc: "Don't install Spring application preloader"
- class_option :database, type: :string, aliases: '-d', default: 'sqlite3',
- desc: "Preconfigure for selected database (options: #{DATABASES.join('/')})"
-
- class_option :javascript, type: :string, aliases: '-j', default: 'jquery',
- desc: 'Preconfigure for selected JavaScript library'
-
class_option :skip_javascript, type: :boolean, aliases: '-J', default: false,
desc: 'Skip JavaScript files'
- class_option :dev, type: :boolean, default: false,
- desc: "Setup the #{name} with Gemfile pointing to your Rails checkout"
-
- class_option :edge, type: :boolean, default: false,
- desc: "Setup the #{name} with Gemfile pointing to Rails repository"
-
class_option :skip_turbolinks, type: :boolean, default: false,
desc: 'Skip turbolinks gem'
class_option :skip_test, type: :boolean, aliases: '-T', default: false,
desc: 'Skip test files'
- class_option :rc, type: :string, default: false,
+ class_option :dev, type: :boolean, default: false,
+ desc: "Setup the #{name} with Gemfile pointing to your Rails checkout"
+
+ class_option :edge, type: :boolean, default: false,
+ desc: "Setup the #{name} with Gemfile pointing to Rails repository"
+
+ class_option :rc, type: :string, default: nil,
desc: "Path to file containing extra configuration options for rails command"
class_option :no_rc, type: :boolean, default: false,
@@ -162,12 +165,13 @@ module Rails
def database_gemfile_entry
return [] if options[:skip_active_record]
- GemfileEntry.version gem_for_database, nil,
+ gem_name, gem_version = gem_for_database
+ GemfileEntry.version gem_name, gem_version,
"Use #{options[:database]} as the database for Active Record"
end
def include_all_railties?
- options.values_at(:skip_active_record, :skip_action_mailer, :skip_test, :skip_sprockets).none?
+ options.values_at(:skip_active_record, :skip_action_mailer, :skip_test, :skip_sprockets, :skip_action_cable).none?
end
def comment_if(value)
@@ -202,39 +206,63 @@ module Rails
def self.path(name, path, comment = nil)
new(name, nil, comment, path: path)
end
+
+ def version
+ version = super
+
+ if version.is_a?(Array)
+ version.join("', '")
+ else
+ version
+ end
+ end
end
def rails_gemfile_entry
+ dev_edge_common = [
+ ]
if options.dev?
[
- GemfileEntry.path('rails', Rails::Generators::RAILS_DEV_PATH),
- GemfileEntry.github('arel', 'rails/arel')
- ]
+ GemfileEntry.path('rails', Rails::Generators::RAILS_DEV_PATH)
+ ] + dev_edge_common
elsif options.edge?
[
- GemfileEntry.github('rails', 'rails/rails'),
- GemfileEntry.github('arel', 'rails/arel')
- ]
+ GemfileEntry.github('rails', 'rails/rails')
+ ] + dev_edge_common
else
[GemfileEntry.version('rails',
- Rails::VERSION::STRING,
+ rails_version_specifier,
"Bundle edge Rails instead: gem 'rails', github: 'rails/rails'")]
end
end
+ def rails_version_specifier(gem_version = Rails.gem_version)
+ if gem_version.prerelease?
+ next_series = gem_version
+ next_series = next_series.bump while next_series.segments.size > 2
+
+ [">= #{gem_version}", "< #{next_series}"]
+ elsif gem_version.segments.size == 3
+ "~> #{gem_version}"
+ else
+ patch = gem_version.segments[0, 3].join(".")
+ ["~> #{patch}", ">= #{gem_version}"]
+ end
+ end
+
def gem_for_database
# %w( mysql oracle postgresql sqlite3 frontbase ibm_db sqlserver jdbcmysql jdbcsqlite3 jdbcpostgresql )
case options[:database]
- when "oracle" then "ruby-oci8"
- when "postgresql" then "pg"
- when "frontbase" then "ruby-frontbase"
- when "mysql" then "mysql2"
- when "sqlserver" then "activerecord-sqlserver-adapter"
- when "jdbcmysql" then "activerecord-jdbcmysql-adapter"
- when "jdbcsqlite3" then "activerecord-jdbcsqlite3-adapter"
- when "jdbcpostgresql" then "activerecord-jdbcpostgresql-adapter"
- when "jdbc" then "activerecord-jdbc-adapter"
- else options[:database]
+ when "oracle" then ["ruby-oci8", nil]
+ when "postgresql" then ["pg", ["~> 0.18"]]
+ when "frontbase" then ["ruby-frontbase", nil]
+ when "mysql" then ["mysql2", [">= 0.3.18", "< 0.5"]]
+ when "sqlserver" then ["activerecord-sqlserver-adapter", nil]
+ when "jdbcmysql" then ["activerecord-jdbcmysql-adapter", nil]
+ when "jdbcsqlite3" then ["activerecord-jdbcsqlite3-adapter", nil]
+ when "jdbcpostgresql" then ["activerecord-jdbcpostgresql-adapter", nil]
+ when "jdbc" then ["activerecord-jdbc-adapter", nil]
+ else [options[:database], nil]
end
end
@@ -265,7 +293,7 @@ module Rails
def jbuilder_gemfile_entry
comment = 'Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder'
- GemfileEntry.version('jbuilder', '~> 2.0', comment)
+ GemfileEntry.new 'jbuilder', '~> 2.0', comment, {}, options[:api]
end
def coffee_gemfile_entry
diff --git a/railties/lib/rails/generators/base.rb b/railties/lib/rails/generators/base.rb
index 813b8b629e..c72ec400a0 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
@@ -302,13 +302,13 @@ module Rails
default_for_option(Rails::Generators.options, name, options, options[:default])
end
- # Return default aliases for the option name given doing a lookup in
+ # Returns default aliases for the option name given doing a lookup in
# Rails::Generators.aliases.
def self.default_aliases_for_option(name, options)
default_for_option(Rails::Generators.aliases, name, options, options[:aliases])
end
- # Return default for the option name given doing a lookup in config.
+ # Returns default for the option name given doing a lookup in config.
def self.default_for_option(config, name, options, default)
if generator_name and c = config[generator_name.to_sym] and c.key?(name)
c[name]
diff --git a/railties/lib/rails/generators/erb/mailer/mailer_generator.rb b/railties/lib/rails/generators/erb/mailer/mailer_generator.rb
index 65563aa6db..bc249aa5e5 100644
--- a/railties/lib/rails/generators/erb/mailer/mailer_generator.rb
+++ b/railties/lib/rails/generators/erb/mailer/mailer_generator.rb
@@ -9,13 +9,6 @@ module Erb # :nodoc:
view_base_path = File.join("app/views", class_path, file_name + '_mailer')
empty_directory view_base_path
- if self.behavior == :invoke
- formats.each do |format|
- layout_path = File.join("app/views/layouts", filename_with_extensions("mailer", format))
- template filename_with_extensions(:layout, format), layout_path
- end
- end
-
actions.each do |action|
@action = action
diff --git a/railties/lib/rails/generators/erb/mailer/templates/layout.html.erb b/railties/lib/rails/generators/erb/mailer/templates/layout.html.erb
deleted file mode 100644
index 93110e74ad..0000000000
--- a/railties/lib/rails/generators/erb/mailer/templates/layout.html.erb
+++ /dev/null
@@ -1,5 +0,0 @@
-<html>
- <body>
- <%%= yield %>
- </body>
-</html>
diff --git a/railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb b/railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb
index d99b27cb2d..519b6c8603 100644
--- a/railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb
+++ b/railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb
@@ -14,15 +14,15 @@
<% attributes.each do |attribute| -%>
<div class="field">
<% if attribute.password_digest? -%>
- <%%= f.label :password %><br>
+ <%%= f.label :password %>
<%%= f.password_field :password %>
</div>
<div class="field">
- <%%= f.label :password_confirmation %><br>
+ <%%= f.label :password_confirmation %>
<%%= f.password_field :password_confirmation %>
<% else -%>
- <%%= f.label :<%= attribute.column_name %> %><br>
+ <%%= f.label :<%= attribute.column_name %> %>
<%%= f.<%= attribute.field_type %> :<%= attribute.column_name %> %>
<% end -%>
</div>
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/migration.rb b/railties/lib/rails/generators/migration.rb
index 51e6d68bf0..87f2e1d42b 100644
--- a/railties/lib/rails/generators/migration.rb
+++ b/railties/lib/rails/generators/migration.rb
@@ -10,22 +10,22 @@ module Rails
extend ActiveSupport::Concern
attr_reader :migration_number, :migration_file_name, :migration_class_name
- module ClassMethods
- def migration_lookup_at(dirname) #:nodoc:
+ module ClassMethods #:nodoc:
+ def migration_lookup_at(dirname)
Dir.glob("#{dirname}/[0-9]*_*.rb")
end
- def migration_exists?(dirname, file_name) #:nodoc:
+ def migration_exists?(dirname, file_name)
migration_lookup_at(dirname).grep(/\d+_#{file_name}.rb$/).first
end
- def current_migration_number(dirname) #:nodoc:
+ def current_migration_number(dirname)
migration_lookup_at(dirname).collect do |file|
File.basename(file).split("_").first.to_i
end.max.to_i
end
- def next_migration_number(dirname) #:nodoc:
+ def next_migration_number(dirname)
raise NotImplementedError
end
end
diff --git a/railties/lib/rails/generators/named_base.rb b/railties/lib/rails/generators/named_base.rb
index 01a8e2e9b4..efbf51ddfb 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
@@ -129,6 +129,18 @@ module Rails
uncountable? ? "#{plural_table_name}_index" : plural_table_name
end
+ def show_helper
+ "#{singular_table_name}_url(@#{singular_table_name})"
+ end
+
+ def edit_helper
+ "edit_#{show_helper}"
+ end
+
+ def new_helper
+ "new_#{singular_table_name}_url"
+ end
+
def singular_table_name
@singular_table_name ||= (pluralize_table_names? ? table_name.singularize : table_name)
end
@@ -149,6 +161,10 @@ module Rails
@route_url ||= class_path.collect {|dname| "/" + dname }.join + "/" + plural_file_name
end
+ def url_helper_prefix
+ @url_helper_prefix ||= (class_path + [file_name]).join('_')
+ end
+
# Tries to retrieve the application name or simply return application.
def application_name
if defined?(Rails) && Rails.application
@@ -183,6 +199,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/USAGE b/railties/lib/rails/generators/rails/app/USAGE
index 691095f33f..28df6ebf44 100644
--- a/railties/lib/rails/generators/rails/app/USAGE
+++ b/railties/lib/rails/generators/rails/app/USAGE
@@ -12,4 +12,3 @@ Example:
rails new ~/Code/Ruby/weblog
This generates a skeletal Rails installation in ~/Code/Ruby/weblog.
- See the README in the newly created application to get going.
diff --git a/railties/lib/rails/generators/rails/app/app_generator.rb b/railties/lib/rails/generators/rails/app/app_generator.rb
index 1047a2c429..f4deec7135 100644
--- a/railties/lib/rails/generators/rails/app/app_generator.rb
+++ b/railties/lib/rails/generators/rails/app/app_generator.rb
@@ -57,8 +57,7 @@ module Rails
directory 'app'
keep_file 'app/assets/images'
- keep_file 'app/mailers'
- keep_file 'app/models'
+ empty_directory_with_keep_file 'app/assets/javascripts/channels' unless options[:skip_action_cable]
keep_file 'app/controllers/concerns'
keep_file 'app/models/concerns'
@@ -83,6 +82,7 @@ module Rails
directory "environments"
directory "initializers"
directory "locales"
+ directory "redis" unless options[:skip_action_cable]
end
end
@@ -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'
@@ -263,12 +293,48 @@ module Rails
end
end
+ def delete_application_record_skipping_active_record
+ if options[:skip_active_record]
+ remove_file 'app/models/application_record.rb'
+ end
+ end
+
+ def delete_action_mailer_files_skipping_action_mailer
+ if options[:skip_action_mailer]
+ remove_file 'app/mailers/application_mailer.rb'
+ remove_file 'app/views/layouts/mailer.html.erb'
+ remove_file 'app/views/layouts/mailer.text.erb'
+ end
+ end
+
def delete_active_record_initializers_skipping_active_record
if options[:skip_active_record]
remove_file 'config/initializers/active_record_belongs_to_required_by_default.rb'
end
end
+ def delete_action_cable_files_skipping_action_cable
+ if options[:skip_action_cable]
+ remove_file 'config/redis/cable.yml'
+ remove_file 'app/assets/javascripts/cable.coffee'
+ remove_dir 'app/channels'
+ 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'
+ remove_file 'config/initializers/request_forgery_protection.rb'
+ end
+ end
+
+ def delete_api_initializers
+ unless options[:api]
+ remove_file 'config/initializers/cors.rb'
+ end
+ end
+
def finish_template
build(:leftovers)
end
@@ -319,7 +385,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 c11bb58bfa..da5af4eefc 100644
--- a/railties/lib/rails/generators/rails/app/templates/Gemfile
+++ b/railties/lib/rails/generators/rails/app/templates/Gemfile
@@ -12,34 +12,41 @@ source 'https://rubygems.org'
<% end -%>
<% end -%>
+# Use Puma as the app server
+gem 'puma'
+
# Use ActiveModel has_secure_password
# gem 'bcrypt', '~> 3.1.7'
-# Use Unicorn as the app server
-# gem 'unicorn'
-
# Use Capistrano for deployment
# gem 'capistrano-rails', group: :development
-group :development, :test do
+<%- if options.api? -%>
+# 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
gem 'byebug'
+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'
+ gem 'web-console', '~> 3.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 -%>
-<% end -%>
end
-<% if RUBY_PLATFORM.match(/bccwin|cygwin|emx|mingw|mswin|wince|java/) -%>
+<% end -%>
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
-<% end -%>
diff --git a/railties/lib/rails/generators/rails/app/templates/app/assets/config/manifest.js.tt b/railties/lib/rails/generators/rails/app/templates/app/assets/config/manifest.js.tt
new file mode 100644
index 0000000000..f4ee1409af
--- /dev/null
+++ b/railties/lib/rails/generators/rails/app/templates/app/assets/config/manifest.js.tt
@@ -0,0 +1,7 @@
+<% unless options.api? -%>
+//= link_tree ../images
+<% end -%>
+<% unless options.skip_javascript -%>
+//= link_directory ../javascripts .js
+<% end -%>
+//= link_directory ../stylesheets .css
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/javascripts/cable.coffee b/railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/cable.coffee
new file mode 100644
index 0000000000..07934d026f
--- /dev/null
+++ b/railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/cable.coffee
@@ -0,0 +1,11 @@
+# Action Cable provides the framework to deal with WebSockets in Rails.
+# You can generate new channels where WebSocket features live using the rails generate channel command.
+#
+# Turn on the cable connection by removing the comments after the require statements (and ensure it's also on in config/routes.rb).
+#
+#= require action_cable
+#= require_self
+#= require_tree ./channels
+#
+# @App ||= {}
+# App.cable = ActionCable.createConsumer()
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/channels/application_cable/channel.rb b/railties/lib/rails/generators/rails/app/templates/app/channels/application_cable/channel.rb
new file mode 100644
index 0000000000..438c84154d
--- /dev/null
+++ b/railties/lib/rails/generators/rails/app/templates/app/channels/application_cable/channel.rb
@@ -0,0 +1,5 @@
+# Be sure to restart your server when you modify this file. Action Cable runs in an EventMachine loop that does not support auto reloading.
+module ApplicationCable
+ class Channel < ActionCable::Channel::Base
+ end
+end
diff --git a/railties/lib/rails/generators/rails/app/templates/app/channels/application_cable/connection.rb b/railties/lib/rails/generators/rails/app/templates/app/channels/application_cable/connection.rb
new file mode 100644
index 0000000000..965046f3c7
--- /dev/null
+++ b/railties/lib/rails/generators/rails/app/templates/app/channels/application_cable/connection.rb
@@ -0,0 +1,5 @@
+# Be sure to restart your server when you modify this file. Action Cable runs in an EventMachine loop that does not support auto reloading.
+module ApplicationCable
+ class Connection < ActionCable::Connection::Base
+ end
+end
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/app/mailers/application_mailer.rb b/railties/lib/rails/generators/rails/app/templates/app/mailers/application_mailer.rb
new file mode 100644
index 0000000000..286b2239d1
--- /dev/null
+++ b/railties/lib/rails/generators/rails/app/templates/app/mailers/application_mailer.rb
@@ -0,0 +1,4 @@
+class ApplicationMailer < ActionMailer::Base
+ default from: 'from@example.com'
+ layout 'mailer'
+end
diff --git a/railties/lib/rails/generators/rails/app/templates/app/models/application_record.rb b/railties/lib/rails/generators/rails/app/templates/app/models/application_record.rb
new file mode 100644
index 0000000000..10a4cba84d
--- /dev/null
+++ b/railties/lib/rails/generators/rails/app/templates/app/models/application_record.rb
@@ -0,0 +1,3 @@
+class ApplicationRecord < ActiveRecord::Base
+ self.abstract_class = true
+end
diff --git a/railties/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt b/railties/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt
index 75ea52828e..68b5c051b2 100644
--- a/railties/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt
+++ b/railties/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt
@@ -1,23 +1,26 @@
<!DOCTYPE html>
<html>
-<head>
- <title><%= camelized %></title>
- <%- if options[:skip_javascript] -%>
- <%%= stylesheet_link_tag 'application', media: 'all' %>
- <%- else -%>
- <%- if gemfile_entries.any? { |m| m.name == 'turbolinks' } -%>
- <%%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
- <%%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
- <%- else -%>
- <%%= stylesheet_link_tag 'application', media: 'all' %>
- <%%= javascript_include_tag 'application' %>
+ <head>
+ <title><%= camelized %></title>
+ <%%= csrf_meta_tags %>
+ <%- unless options[:skip_action_cable] -%>
+ <%%= action_cable_meta_tag %>
<%- end -%>
- <%- end -%>
- <%%= csrf_meta_tags %>
-</head>
-<body>
-<%%= yield %>
+ <%- if options[:skip_javascript] -%>
+ <%%= stylesheet_link_tag 'application', media: 'all' %>
+ <%- else -%>
+ <%- if gemfile_entries.any? { |m| m.name == 'turbolinks' } -%>
+ <%%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
+ <%%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
+ <%- else -%>
+ <%%= stylesheet_link_tag 'application', media: 'all' %>
+ <%%= javascript_include_tag 'application' %>
+ <%- end -%>
+ <%- end -%>
+ </head>
-</body>
+ <body>
+ <%%= yield %>
+ </body>
</html>
diff --git a/railties/lib/rails/generators/rails/app/templates/app/views/layouts/mailer.html.erb.tt b/railties/lib/rails/generators/rails/app/templates/app/views/layouts/mailer.html.erb.tt
new file mode 100644
index 0000000000..55f3675d49
--- /dev/null
+++ b/railties/lib/rails/generators/rails/app/templates/app/views/layouts/mailer.html.erb.tt
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <style>
+ /* Email styles need to be inline */
+ </style>
+ </head>
+
+ <body>
+ <%%= yield %>
+ </body>
+</html>
diff --git a/railties/lib/rails/generators/erb/mailer/templates/layout.text.erb b/railties/lib/rails/generators/rails/app/templates/app/views/layouts/mailer.text.erb.tt
index 6363733e6e..6363733e6e 100644
--- a/railties/lib/rails/generators/erb/mailer/templates/layout.text.erb
+++ b/railties/lib/rails/generators/rails/app/templates/app/views/layouts/mailer.text.erb.tt
diff --git a/railties/lib/rails/generators/rails/app/templates/bin/setup b/railties/lib/rails/generators/rails/app/templates/bin/setup
index 3a5a2cc1e3..df88bfd3bc 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! 'bin/rails db:setup'
puts "\n== Removing old logs and tempfiles =="
- system 'ruby bin/rake log:clear tmp:clear'
+ system! 'bin/rails log:clear tmp:clear'
puts "\n== Restarting application server =="
- touch 'tmp/restart.txt'
+ system! 'bin/rails 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..c6ed3ae64b
--- /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/rails db:migrate'
+
+ puts "\n== Removing old logs and tempfiles =="
+ system! 'bin/rails log:clear tmp:clear'
+
+ puts "\n== Restarting application server =="
+ system! 'bin/rails restart'
+end
diff --git a/railties/lib/rails/generators/rails/app/templates/config.ru b/railties/lib/rails/generators/rails/app/templates/config.ru
deleted file mode 100644
index bd83b25412..0000000000
--- a/railties/lib/rails/generators/rails/app/templates/config.ru
+++ /dev/null
@@ -1,4 +0,0 @@
-# This file is used by Rack-based servers to start the application.
-
-require ::File.expand_path('../config/environment', __FILE__)
-run Rails.application
diff --git a/railties/lib/rails/generators/rails/app/templates/config.ru.tt b/railties/lib/rails/generators/rails/app/templates/config.ru.tt
new file mode 100644
index 0000000000..70556fcc99
--- /dev/null
+++ b/railties/lib/rails/generators/rails/app/templates/config.ru.tt
@@ -0,0 +1,11 @@
+# This file is used by Rack-based servers to start the application.
+
+require ::File.expand_path('../config/environment', __FILE__)
+<%- unless options[:skip_action_cable] -%>
+
+# Action Cable uses EventMachine which requires that all classes are loaded in advance
+Rails.application.eager_load!
+require 'action_cable/process/logging'
+<%- end -%>
+
+run Rails.application
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..cb83364360 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/application.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/application.rb
@@ -11,6 +11,7 @@ require "active_job/railtie"
require "action_controller/railtie"
<%= comment_if :skip_action_mailer %>require "action_mailer/railtie"
require "action_view/railtie"
+<%= comment_if :skip_action_cable %>require "action_cable/engine"
<%= comment_if :skip_sprockets %>require "sprockets/railtie"
<%= comment_if :skip_test %>require "rails/test_unit/railtie"
<% end -%>
@@ -24,13 +25,12 @@ module <%= app_const_base %>
# Settings in config/environments/* take precedence over those specified here.
# Application configuration should go into files in config/initializers
# -- all .rb files in that directory are automatically loaded.
+<%- if options[:api] -%>
- # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
- # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
- # config.time_zone = 'Central Time (US & Canada)'
-
- # 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
+ # 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/databases/jdbcmysql.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml
index f5b62e8fb3..5ca549a8c8 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml
@@ -7,7 +7,7 @@
# gem 'activerecord-jdbcmysql-adapter'
#
# And be sure to use new-style password hashing:
-# http://dev.mysql.com/doc/refman/5.6/en/old-client.html
+# http://dev.mysql.com/doc/refman/5.7/en/old-client.html
#
default: &default
adapter: mysql
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml
index b0767bd93a..119c2fe2c3 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml
@@ -7,7 +7,7 @@
# gem 'mysql2'
#
# And be sure to use new-style password hashing:
-# http://dev.mysql.com/doc/refman/5.6/en/old-client.html
+# http://dev.mysql.com/doc/refman/5.7/en/old-client.html
#
default: &default
adapter: mysql2
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..fd41372d9c 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,20 @@ Rails.application.configure do
# Do not eager load code on boot.
config.eager_load = false
- # Show full error reports and disable caching.
- config.consider_all_requests_local = true
- config.action_controller.perform_caching = false
+ # Show full error reports.
+ config.consider_all_requests_local = true
+
+ # Enable/disable caching. By default caching is disabled.
+ if Rails.root.join('tmp/caching-dev.txt').exist?
+ config.action_controller.perform_caching = true
+ config.cache_store = :memory_store
+ config.public_file_server.headers = {
+ 'Cache-Control' => 'public, max-age=172800'
+ }
+ 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.
@@ -44,4 +55,8 @@ Rails.application.configure do
# Raises error for missing translations
# config.action_view.raise_on_missing_translations = true
+
+ # Use an evented file watcher to asynchronously detect changes in source code,
+ # routes, locales, etc. This feature depends on the listen gem.
+ # config.file_watcher = ActiveSupport::EventedFileUpdateChecker
end
diff --git a/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt
index 8c09396fc1..82509f5ef5 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
@@ -16,7 +16,7 @@ Rails.application.configure do
# Disable serving static files from the `/public` folder by default since
# Apache or NGINX already handles this.
- config.serve_static_files = ENV['RAILS_SERVE_STATIC_FILES'].present?
+ config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?
<%- unless options.skip_sprockets? -%>
# Compress JavaScripts and CSS.
@@ -40,6 +40,12 @@ Rails.application.configure do
# config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX
+ <%- unless options[:skip_action_cable] -%>
+ # Action Cable endpoint configuration
+ # config.action_cable.url = 'wss://example.com/cable'
+ # config.action_cable.allowed_request_origins = [ 'http://example.com', /http:\/\/example.*/ ]
+ <%- end -%>
+
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
# config.force_ssl = true
@@ -48,10 +54,11 @@ Rails.application.configure do
config.log_level = :debug
# Prepend all log lines with the following tags.
- # config.log_tags = [ :subdomain, :request_id ]
+ config.log_tags = [ :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/environments/test.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt
index 0306deb18c..8133917591 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt
+++ b/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt
@@ -12,9 +12,11 @@ Rails.application.configure do
# preloads Rails for running tests, you may have to set it to true.
config.eager_load = false
- # Configure static file server for tests with Cache-Control for performance.
- config.serve_static_files = true
- config.static_cache_control = 'public, max-age=3600'
+ # Configure public file server for tests with Cache-Control for performance.
+ config.public_file_server.enabled = true
+ config.public_file_server.headers = {
+ 'Cache-Control' => 'public, max-age=3600'
+ }
# Show full error reports and disable caching.
config.consider_all_requests_local = true
diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/active_record_belongs_to_required_by_default.rb b/railties/lib/rails/generators/rails/app/templates/config/initializers/active_record_belongs_to_required_by_default.rb
index 30c4f89792..f613b40f80 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/initializers/active_record_belongs_to_required_by_default.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/active_record_belongs_to_required_by_default.rb
@@ -1,4 +1,6 @@
# Be sure to restart your server when you modify this file.
-# Require `belongs_to` associations by default.
+# Require `belongs_to` associations by default. This is a new Rails 5.0
+# default, so it is introduced as a configuration option to ensure that apps
+# made on earlier versions of Rails are not affected when upgrading.
Rails.application.config.active_record.belongs_to_required_by_default = true
diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/application_controller_renderer.rb b/railties/lib/rails/generators/rails/app/templates/config/initializers/application_controller_renderer.rb
index ea930f54da..51639b67a0 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/initializers/application_controller_renderer.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/application_controller_renderer.rb
@@ -1,5 +1,5 @@
-## Change renderer defaults here.
-#
+# Be sure to restart your server when you modify this file.
+
# ApplicationController.renderer.defaults.merge!(
# http_host: 'example.org',
# https: false
diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/callback_terminator.rb b/railties/lib/rails/generators/rails/app/templates/config/initializers/callback_terminator.rb
index a70a1b9cde..649e82280e 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/initializers/callback_terminator.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/callback_terminator.rb
@@ -1,4 +1,6 @@
# Be sure to restart your server when you modify this file.
-# Do not halt callback chains when a callback returns false.
+# Do not halt callback chains when a callback returns false. This is a new
+# Rails 5.0 default, so it is introduced as a configuration option to ensure
+# that apps made with earlier versions of Rails are not affected when upgrading.
ActiveSupport.halt_callback_chains_on_return_false = false
diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/cookies_serializer.rb b/railties/lib/rails/generators/rails/app/templates/config/initializers/cookies_serializer.rb
index 7f70458dee..5a6a32d371 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/initializers/cookies_serializer.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/cookies_serializer.rb
@@ -1,3 +1,5 @@
# Be sure to restart your server when you modify this file.
+# Specify a serializer for the signed and encrypted cookie jars.
+# Valid options are :json, :marshal, and :hybrid.
Rails.application.config.action_dispatch.cookies_serializer = :json
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..3b1c1b5ed1
--- /dev/null
+++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/cors.rb
@@ -0,0 +1,16 @@
+# Be sure to restart your server when you modify this file.
+
+# 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/per_form_csrf_tokens.rb b/railties/lib/rails/generators/rails/app/templates/config/initializers/per_form_csrf_tokens.rb
new file mode 100644
index 0000000000..1f569dedfd
--- /dev/null
+++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/per_form_csrf_tokens.rb
@@ -0,0 +1,4 @@
+# Be sure to restart your server when you modify this file.
+
+# Enable per-form CSRF tokens.
+Rails.application.config.action_controller.per_form_csrf_tokens = true
diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/request_forgery_protection.rb b/railties/lib/rails/generators/rails/app/templates/config/initializers/request_forgery_protection.rb
new file mode 100644
index 0000000000..3eab78a885
--- /dev/null
+++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/request_forgery_protection.rb
@@ -0,0 +1,4 @@
+# Be sure to restart your server when you modify this file.
+
+# Enable origin-checking CSRF mitigation.
+Rails.application.config.action_controller.forgery_protection_origin_check = true
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/redis/cable.yml b/railties/lib/rails/generators/rails/app/templates/config/redis/cable.yml
new file mode 100644
index 0000000000..0176be24f9
--- /dev/null
+++ b/railties/lib/rails/generators/rails/app/templates/config/redis/cable.yml
@@ -0,0 +1,9 @@
+# Action Cable uses Redis to administer connections, channels, and sending/receiving messages over the WebSocket.
+production:
+ url: redis://localhost:6379/1
+
+development:
+ url: redis://localhost:6379/2
+
+test:
+ url: redis://localhost:6379/3
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..8293c8a483 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,6 @@
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".
+ # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
- # 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
+ # Serve websocket cable requests in-process
+ # mount ActionCable.server => '/cable'
end
diff --git a/railties/lib/rails/generators/rails/app/templates/db/seeds.rb.tt b/railties/lib/rails/generators/rails/app/templates/db/seeds.rb.tt
index 4edb1e857e..1beea2accd 100644
--- a/railties/lib/rails/generators/rails/app/templates/db/seeds.rb.tt
+++ b/railties/lib/rails/generators/rails/app/templates/db/seeds.rb.tt
@@ -1,7 +1,7 @@
# This file should contain all the record creation needed to seed the database with its default values.
-# The data can then be loaded with the rake db:seed (or created alongside the db with db:setup).
+# The data can then be loaded with the rails db:seed command (or created alongside the database with db:setup).
#
# Examples:
#
-# cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }])
-# Mayor.create(name: 'Emanuel', city: cities.first)
+# movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }])
+# Character.create(name: 'Luke', movie: movies.first)
diff --git a/railties/lib/rails/generators/rails/app/templates/gitignore b/railties/lib/rails/generators/rails/app/templates/gitignore
index e4a00ad181..0e66cc4237 100644
--- a/railties/lib/rails/generators/rails/app/templates/gitignore
+++ b/railties/lib/rails/generators/rails/app/templates/gitignore
@@ -15,7 +15,11 @@
<% end -%>
# Ignore all logfiles and tempfiles.
/log/*
+/tmp/*
<% if keeps? -%>
!/log/.keep
+!/tmp/.keep
<% end -%>
-/tmp
+
+# Ignore Byebug command history file.
+.byebug_history
diff --git a/railties/lib/rails/generators/rails/model/USAGE b/railties/lib/rails/generators/rails/model/USAGE
index 11daa5c3cb..025bcf4774 100644
--- a/railties/lib/rails/generators/rails/model/USAGE
+++ b/railties/lib/rails/generators/rails/model/USAGE
@@ -8,14 +8,14 @@ Description:
As a special case, specifying 'password:digest' will generate a
password_digest field of string type, and configure your generated model and
- tests for use with ActiveModel has_secure_password (assuming the default ORM
+ tests for use with Active Model has_secure_password (assuming the default ORM
and test framework are being used).
You don't have to think up every attribute up front, but it helps to
sketch out a few so you can start working with the model immediately.
This generator invokes your configured ORM and test framework, which
- defaults to ActiveRecord and TestUnit.
+ defaults to Active Record and TestUnit.
Finally, if --parent option is given, it's used as superclass of the
created model. This allows you create Single Table Inheritance models.
@@ -91,7 +91,7 @@ Available field types:
Examples:
`rails generate model account`
- For ActiveRecord and TestUnit it creates:
+ For Active Record and TestUnit it creates:
Model: app/models/account.rb
Test: test/models/account_test.rb
@@ -104,7 +104,7 @@ Examples:
`rails generate model admin/account`
- For ActiveRecord and TestUnit it creates:
+ For Active Record and TestUnit it creates:
Module: app/models/admin.rb
Model: app/models/admin/account.rb
diff --git a/railties/lib/rails/generators/rails/plugin/plugin_generator.rb b/railties/lib/rails/generators/rails/plugin/plugin_generator.rb
index 7f5bf0c8b8..7d7477de75 100644
--- a/railties/lib/rails/generators/rails/plugin/plugin_generator.rb
+++ b/railties/lib/rails/generators/rails/plugin/plugin_generator.rb
@@ -17,20 +17,27 @@ 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
def readme
- template "README.rdoc"
+ template "README.md"
end
def gemfile
@@ -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
@@ -96,8 +104,9 @@ task default: :test
end
def test_dummy_assets
- template "rails/javascripts.js", "#{dummy_path}/app/assets/javascripts/application.js", force: true
- template "rails/stylesheets.css", "#{dummy_path}/app/assets/stylesheets/application.css", force: true
+ template "rails/javascripts.js", "#{dummy_path}/app/assets/javascripts/application.js", force: true
+ template "rails/stylesheets.css", "#{dummy_path}/app/assets/stylesheets/application.css", force: true
+ template "rails/dummy_manifest.js", "#{dummy_path}/app/assets/config/manifest.js", force: true
end
def test_dummy_clean
@@ -108,12 +117,16 @@ task default: :test
remove_file "Gemfile"
remove_file "lib/tasks"
remove_file "public/robots.txt"
- remove_file "README"
+ remove_file "README.md"
remove_file "test"
remove_file "vendor"
end
end
+ def assets_manifest
+ template "rails/engine_manifest.js", "app/assets/config/#{underscored_name}_manifest.js"
+ end
+
def stylesheets
if mountable?
copy_file "rails/stylesheets.css",
@@ -135,9 +148,8 @@ task default: :test
end
def bin(force = false)
- return unless engine?
-
- directory "bin", force: force do |content|
+ bin_file = engine? ? 'bin/rails.tt' : 'bin/test.tt'
+ template bin_file, force: force do |content|
"#{shebang}\n" + content
end
chmod "bin", 0755, verbose: false
@@ -176,6 +188,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
@@ -209,16 +224,16 @@ task default: :test
build(:lib)
end
- def create_public_stylesheets_files
- build(:stylesheets)
+ def create_assets_manifest_file
+ build(:assets_manifest) if !api? && engine?
end
- def create_javascript_files
- build(:javascripts)
+ def create_public_stylesheets_files
+ build(:stylesheets) unless api?
end
- def create_images_directory
- build(:images)
+ def create_javascript_files
+ build(:javascripts) unless api?
end
def create_bin_files
@@ -305,6 +320,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 +383,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/%name%.gemspec b/railties/lib/rails/generators/rails/plugin/templates/%name%.gemspec
index f8ece4fe73..d84d1aabdb 100644
--- a/railties/lib/rails/generators/rails/plugin/templates/%name%.gemspec
+++ b/railties/lib/rails/generators/rails/plugin/templates/%name%.gemspec
@@ -14,14 +14,11 @@ Gem::Specification.new do |s|
s.description = "TODO: Description of <%= camelized_modules %>."
s.license = "MIT"
- s.files = Dir["{app,config,db,lib}/**/*", "MIT-LICENSE", "Rakefile", "README.rdoc"]
-<% unless options.skip_test? -%>
- s.test_files = Dir["test/**/*"]
-<% end -%>
+ s.files = Dir["{app,config,db,lib}/**/*", "MIT-LICENSE", "Rakefile", "README.md"]
- <%= '# ' if options.dev? || options.edge? -%>s.add_dependency "rails", "~> <%= Rails::VERSION::STRING %>"
+ <%= '# ' if options.dev? || options.edge? -%>s.add_dependency "rails", "<%= Array(rails_version_specifier).join('", "') %>"
<% unless options[:skip_active_record] -%>
- s.add_development_dependency "<%= gem_for_database %>"
+ s.add_development_dependency "<%= gem_for_database[0] %>"
<% end -%>
end
diff --git a/railties/lib/rails/generators/rails/plugin/templates/Gemfile b/railties/lib/rails/generators/rails/plugin/templates/Gemfile
index 2c91c6a0ea..22a4548ff2 100644
--- a/railties/lib/rails/generators/rails/plugin/templates/Gemfile
+++ b/railties/lib/rails/generators/rails/plugin/templates/Gemfile
@@ -1,7 +1,7 @@
source 'https://rubygems.org'
<% if options[:skip_gemspec] -%>
-<%= '# ' if options.dev? || options.edge? -%>gem 'rails', '~> <%= Rails::VERSION::STRING %>'
+<%= '# ' if options.dev? || options.edge? -%>gem 'rails', '<%= Array(rails_version_specifier).join("', '") %>'
<% else -%>
# Declare your gem's dependencies in <%= name %>.gemspec.
# Bundler will treat runtime dependencies like base dependencies, and
@@ -11,7 +11,7 @@ gemspec
<% if options[:skip_gemspec] -%>
group :development do
- gem '<%= gem_for_database %>'
+ gem '<%= gem_for_database[0] %>'
end
<% else -%>
# Declare any dependencies that are still in development here instead of in
diff --git a/railties/lib/rails/generators/rails/plugin/templates/README.md b/railties/lib/rails/generators/rails/plugin/templates/README.md
new file mode 100644
index 0000000000..9d2b74416e
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin/templates/README.md
@@ -0,0 +1,28 @@
+# <%= camelized_modules %>
+Short description and motivation.
+
+## Usage
+How to use my plugin.
+
+## Installation
+Add this line to your application's Gemfile:
+
+```ruby
+gem '<%= name %>'
+```
+
+And then execute:
+```bash
+$ bundle
+```
+
+Or install it yourself as:
+```bash
+$ gem install <%= name %>
+```
+
+## Contributing
+Contribution directions go here.
+
+## License
+The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
diff --git a/railties/lib/rails/generators/rails/plugin/templates/README.rdoc b/railties/lib/rails/generators/rails/plugin/templates/README.rdoc
deleted file mode 100644
index 25983ca5da..0000000000
--- a/railties/lib/rails/generators/rails/plugin/templates/README.rdoc
+++ /dev/null
@@ -1,3 +0,0 @@
-= <%= camelized_modules %>
-
-This project rocks and uses MIT-LICENSE. \ No newline at end of file
diff --git a/railties/lib/rails/generators/rails/plugin/templates/Rakefile b/railties/lib/rails/generators/rails/plugin/templates/Rakefile
index bda55bae29..f1943644e4 100644
--- a/railties/lib/rails/generators/rails/plugin/templates/Rakefile
+++ b/railties/lib/rails/generators/rails/plugin/templates/Rakefile
@@ -10,7 +10,7 @@ RDoc::Task.new(:rdoc) do |rdoc|
rdoc.rdoc_dir = 'rdoc'
rdoc.title = '<%= camelized_modules %>'
rdoc.options << '--line-numbers'
- rdoc.rdoc_files.include('README.rdoc')
+ rdoc.rdoc_files.include('README.md')
rdoc.rdoc_files.include('lib/**/*.rb')
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/app/jobs/%namespaced_name%/application_job.rb.tt b/railties/lib/rails/generators/rails/plugin/templates/app/jobs/%namespaced_name%/application_job.rb.tt
new file mode 100644
index 0000000000..bad1ff2d16
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin/templates/app/jobs/%namespaced_name%/application_job.rb.tt
@@ -0,0 +1,5 @@
+<%= wrap_in_modules <<-rb.strip_heredoc
+ class ApplicationJob < ActiveJob::Base
+ end
+rb
+%>
diff --git a/railties/lib/rails/generators/rails/plugin/templates/app/models/%namespaced_name%/application_record.rb.tt b/railties/lib/rails/generators/rails/plugin/templates/app/models/%namespaced_name%/application_record.rb.tt
new file mode 100644
index 0000000000..8aa3de78f1
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin/templates/app/models/%namespaced_name%/application_record.rb.tt
@@ -0,0 +1,6 @@
+<%= wrap_in_modules <<-rb.strip_heredoc
+ class ApplicationRecord < ActiveRecord::Base
+ self.abstract_class = true
+ end
+rb
+%>
diff --git a/railties/lib/rails/generators/rails/plugin/templates/app/models/.empty_directory b/railties/lib/rails/generators/rails/plugin/templates/app/models/.empty_directory
deleted file mode 100644
index e69de29bb2..0000000000
--- a/railties/lib/rails/generators/rails/plugin/templates/app/models/.empty_directory
+++ /dev/null
diff --git a/railties/lib/rails/generators/rails/plugin/templates/bin/test.tt b/railties/lib/rails/generators/rails/plugin/templates/bin/test.tt
new file mode 100644
index 0000000000..62b94618fd
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin/templates/bin/test.tt
@@ -0,0 +1,8 @@
+$: << File.expand_path(File.expand_path('../../test', __FILE__))
+
+require 'bundler/setup'
+require 'rails/test_unit/minitest_plugin'
+
+Rails::TestUnitReporter.executable = 'bin/test'
+
+exit Minitest.run(ARGV)
diff --git a/railties/lib/rails/generators/rails/plugin/templates/gitignore b/railties/lib/rails/generators/rails/plugin/templates/gitignore
index d524fcbc4e..54c78d7927 100644
--- a/railties/lib/rails/generators/rails/plugin/templates/gitignore
+++ b/railties/lib/rails/generators/rails/plugin/templates/gitignore
@@ -6,5 +6,4 @@ pkg/
<%= dummy_path %>/db/*.sqlite3-journal
<%= dummy_path %>/log/*.log
<%= dummy_path %>/tmp/
-<%= dummy_path %>/.sass-cache
<% end -%>
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/dummy_manifest.js b/railties/lib/rails/generators/rails/plugin/templates/rails/dummy_manifest.js
new file mode 100644
index 0000000000..8d21b2b6fb
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin/templates/rails/dummy_manifest.js
@@ -0,0 +1,11 @@
+
+<% unless api? -%>
+//= link_tree ../images
+<% end -%>
+<% unless options.skip_javascript -%>
+//= link_directory ../javascripts .js
+<% end -%>
+//= link_directory ../stylesheets .css
+<% if mountable? && !api? -%>
+//= link <%= underscored_name %>_manifest.js
+<% end -%>
diff --git a/railties/lib/rails/generators/rails/plugin/templates/rails/engine_manifest.js b/railties/lib/rails/generators/rails/plugin/templates/rails/engine_manifest.js
new file mode 100644
index 0000000000..2f23844f5e
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin/templates/rails/engine_manifest.js
@@ -0,0 +1,6 @@
+<% if mountable? -%>
+<% if !options.skip_javascript -%>
+//= link_directory ../javascripts/<%= namespaced_name %> .js
+<% end -%>
+//= link_directory ../stylesheets/<%= namespaced_name %> .css
+<% end -%>
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/routes.rb b/railties/lib/rails/generators/rails/plugin/templates/rails/routes.rb
index 673de44108..694510edc0 100644
--- a/railties/lib/rails/generators/rails/plugin/templates/rails/routes.rb
+++ b/railties/lib/rails/generators/rails/plugin/templates/rails/routes.rb
@@ -1,4 +1,3 @@
Rails.application.routes.draw do
-
mount <%= camelized_modules %>::Engine => "/<%= name %>"
end
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..a5eebcb19f 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
@@ -1,7 +1,7 @@
# Configure Rails Environment
ENV["RAILS_ENV"] = "test"
-require File.expand_path("../../<%= options[:dummy_path] -%>/config/environment.rb", __FILE__)
+require File.expand_path("../../<%= options[:dummy_path] -%>/config/environment.rb", __FILE__)
<% unless options[:skip_active_record] -%>
ActiveRecord::Migrator.migrations_paths = [File.expand_path("../../<%= options[:dummy_path] -%>/db/migrate", __FILE__)]
<% if options[:mountable] -%>
@@ -14,12 +14,14 @@ require "rails/test_help"
# to be shown.
Minitest.backtrace_filter = Minitest::BacktraceFilter.new
-# Load support files
-Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
+<% unless engine? -%>
+Rails::TestUnitReporter.executable = 'bin/test'
+<% end -%>
# 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/USAGE b/railties/lib/rails/generators/rails/scaffold/USAGE
index d2e495758d..c9283eda87 100644
--- a/railties/lib/rails/generators/rails/scaffold/USAGE
+++ b/railties/lib/rails/generators/rails/scaffold/USAGE
@@ -16,7 +16,7 @@ Description:
As a special case, specifying 'password:digest' will generate a
password_digest field of string type, and configure your generated model,
- controller, views, and test suite for use with ActiveModel
+ controller, views, and test suite for use with Active Model
has_secure_password (assuming they are using Rails defaults).
Timestamps are added by default, so you don't have to specify them by hand
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/templates/scaffold.css b/railties/lib/rails/generators/rails/scaffold/templates/scaffold.css
index b7818883d1..79f8b7f96f 100644
--- a/railties/lib/rails/generators/rails/scaffold/templates/scaffold.css
+++ b/railties/lib/rails/generators/rails/scaffold/templates/scaffold.css
@@ -78,3 +78,7 @@ div.actions {
font-size: 12px;
list-style: square;
}
+
+label {
+ display: block;
+}
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..400afec6dc
--- /dev/null
+++ b/railties/lib/rails/generators/rails/scaffold_controller/templates/api_controller.rb
@@ -0,0 +1,61 @@
+<% if namespaced? -%>
+require_dependency "<%= namespaced_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.fetch(:<%= 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/rails/scaffold_controller/templates/controller.rb b/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb
index 2c3b04043f..42b9e34274 100644
--- a/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb
+++ b/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb
@@ -1,5 +1,5 @@
<% if namespaced? -%>
-require_dependency "<%= namespaced_file_path %>/application_controller"
+require_dependency "<%= namespaced_path %>/application_controller"
<% end -%>
<% module_namespacing do -%>
@@ -59,7 +59,7 @@ class <%= controller_class_name %>Controller < ApplicationController
# Only allow a trusted parameter "white list" through.
def <%= "#{singular_table_name}_params" %>
<%- if attributes_names.empty? -%>
- params[:<%= singular_table_name %>]
+ params.fetch(:<%= singular_table_name %>, {})
<%- else -%>
params.require(:<%= singular_table_name %>).permit(<%= attributes_names.map { |name| ":#{name}" }.join(', ') %>)
<%- 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..ff41fef9e9 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
@@ -1,7 +1,11 @@
require 'test_helper'
<% module_namespacing do -%>
-class <%= class_name %>ControllerTest < ActionController::TestCase
+class <%= class_name %>ControllerTest < ActionDispatch::IntegrationTest
+<% if mountable_engine? -%>
+ include Engine.routes.url_helpers
+
+<% end -%>
<% if actions.empty? -%>
# test "the truth" do
# assert true
@@ -9,7 +13,7 @@ class <%= class_name %>ControllerTest < ActionController::TestCase
<% else -%>
<% actions.each do |action| -%>
test "should get <%= action %>" do
- get :<%= action %>
+ get <%= url_helper_prefix %>_<%= action %>_url
assert_response :success
end
diff --git a/railties/lib/rails/generators/test_unit/model/templates/fixtures.yml b/railties/lib/rails/generators/test_unit/model/templates/fixtures.yml
index 50ca61a35b..2656767eb4 100644
--- a/railties/lib/rails/generators/test_unit/model/templates/fixtures.yml
+++ b/railties/lib/rails/generators/test_unit/model/templates/fixtures.yml
@@ -17,7 +17,7 @@
<% end -%>
<% else -%>
-# This model initially had no columns defined. If you add columns to the
+# This model initially had no columns defined. If you add columns to the
# model remove the '{}' from the fixture names and add the columns immediately
# below each fixture, per the syntax in the comments below
#
@@ -25,5 +25,5 @@ one: {}
# column: value
#
two: {}
-# column: value
+# column: value
<% end -%>
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..0d18478043
--- /dev/null
+++ b/railties/lib/rails/generators/test_unit/scaffold/templates/api_functional_test.rb
@@ -0,0 +1,44 @@
+require 'test_helper'
+
+<% module_namespacing do -%>
+class <%= controller_class_name %>ControllerTest < ActionDispatch::IntegrationTest
+ <%- if mountable_engine? -%>
+ include Engine.routes.url_helpers
+
+ <%- end -%>
+ setup do
+ @<%= singular_table_name %> = <%= fixture_name %>(:one)
+ end
+
+ test "should get index" do
+ get <%= index_helper %>_url
+ assert_response :success
+ end
+
+ test "should create <%= singular_table_name %>" do
+ assert_difference('<%= class_name %>.count') do
+ post <%= index_helper %>_url, params: { <%= "#{singular_table_name}: { #{attributes_hash} }" %> }
+ end
+
+ assert_response 201
+ end
+
+ test "should show <%= singular_table_name %>" do
+ get <%= show_helper %>
+ assert_response :success
+ end
+
+ test "should update <%= singular_table_name %>" do
+ patch <%= show_helper %>, params: { <%= "#{singular_table_name}: { #{attributes_hash} }" %> }
+ assert_response 200
+ end
+
+ test "should destroy <%= singular_table_name %>" do
+ assert_difference('<%= class_name %>.count', -1) do
+ delete <%= show_helper %>
+ 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..0e6bef12fc 100644
--- a/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb
+++ b/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb
@@ -1,47 +1,51 @@
require 'test_helper'
<% module_namespacing do -%>
-class <%= controller_class_name %>ControllerTest < ActionController::TestCase
+class <%= controller_class_name %>ControllerTest < ActionDispatch::IntegrationTest
+ <%- if mountable_engine? -%>
+ include Engine.routes.url_helpers
+
+ <%- end -%>
setup do
- @<%= singular_table_name %> = <%= table_name %>(:one)
+ @<%= singular_table_name %> = <%= fixture_name %>(:one)
end
test "should get index" do
- get :index
+ get <%= index_helper %>_url
assert_response :success
end
test "should get new" do
- get :new
+ get <%= new_helper %>
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} }" %> }
+ post <%= index_helper %>_url, params: { <%= "#{singular_table_name}: { #{attributes_hash} }" %> }
end
assert_redirected_to <%= singular_table_name %>_path(<%= class_name %>.last)
end
test "should show <%= singular_table_name %>" do
- get :show, params: { id: <%= "@#{singular_table_name}" %> }
+ get <%= show_helper %>
assert_response :success
end
test "should get edit" do
- get :edit, params: { id: <%= "@#{singular_table_name}" %> }
+ get <%= edit_helper %>
assert_response :success
end
test "should update <%= singular_table_name %>" do
- patch :update, params: { id: <%= "@#{singular_table_name}" %>, <%= "#{singular_table_name}: { #{attributes_hash} }" %> }
+ patch <%= show_helper %>, params: { <%= "#{singular_table_name}: { #{attributes_hash} }" %> }
assert_redirected_to <%= singular_table_name %>_path(<%= "@#{singular_table_name}" %>)
end
test "should destroy <%= singular_table_name %>" do
assert_difference('<%= class_name %>.count', -1) do
- delete :destroy, params: { id: <%= "@#{singular_table_name}" %> }
+ delete <%= show_helper %>
end
assert_redirected_to <%= index_helper %>_path
diff --git a/railties/lib/rails/generators/testing/assertions.rb b/railties/lib/rails/generators/testing/assertions.rb
index bd069e4bd0..76758df86d 100644
--- a/railties/lib/rails/generators/testing/assertions.rb
+++ b/railties/lib/rails/generators/testing/assertions.rb
@@ -1,5 +1,3 @@
-require 'shellwords'
-
module Rails
module Generators
module Testing
@@ -23,7 +21,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/generators/testing/behaviour.rb b/railties/lib/rails/generators/testing/behaviour.rb
index c9700e1cd7..94b5e52224 100644
--- a/railties/lib/rails/generators/testing/behaviour.rb
+++ b/railties/lib/rails/generators/testing/behaviour.rb
@@ -92,7 +92,8 @@ module Rails
cd current_path
end
- def prepare_destination # :nodoc:
+ # Clears all files and directories in destination.
+ def prepare_destination
rm_rf(destination_root)
mkdir_p(destination_root)
end
diff --git a/railties/lib/rails/mailers_controller.rb b/railties/lib/rails/mailers_controller.rb
index 41422a656c..6143cf2dd9 100644
--- a/railties/lib/rails/mailers_controller.rb
+++ b/railties/lib/rails/mailers_controller.rb
@@ -3,7 +3,7 @@ require 'rails/application_controller'
class Rails::MailersController < Rails::ApplicationController # :nodoc:
prepend_view_path ActionDispatch::DebugExceptions::RESCUES_TEMPLATE_PATH
- before_action :require_local!
+ before_action :require_local!, unless: :show_previews?
before_action :find_preview, only: :preview
def index
@@ -26,12 +26,12 @@ 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
else
- @part = find_preferred_part(request.format, Mime::HTML, Mime::TEXT)
+ @part = find_preferred_part(request.format, Mime[:html], Mime[:text])
render action: 'email', layout: false, formats: %w[html]
end
else
@@ -41,6 +41,10 @@ class Rails::MailersController < Rails::ApplicationController # :nodoc:
end
protected
+ def show_previews?
+ ActionMailer::Base.show_previews
+ end
+
def find_preview
candidates = []
params[:path].to_s.scan(%r{/|$}){ candidates << $` }
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/source_annotation_extractor.rb b/railties/lib/rails/source_annotation_extractor.rb
index 9b058a1848..8dd87b6cc5 100644
--- a/railties/lib/rails/source_annotation_extractor.rb
+++ b/railties/lib/rails/source_annotation_extractor.rb
@@ -3,7 +3,7 @@
# rake notes
# rake notes:optimize
#
-# and friends. See <tt>rake -T notes</tt> and <tt>railties/lib/tasks/annotations.rake</tt>.
+# and friends. See <tt>rake -T notes</tt> and <tt>railties/lib/rails/tasks/annotations.rake</tt>.
#
# Annotation objects are triplets <tt>:line</tt>, <tt>:tag</tt>, <tt>:text</tt> that
# represent the line where the annotation lives, its tag, and its text. Note
diff --git a/railties/lib/rails/tasks.rb b/railties/lib/rails/tasks.rb
index 2c3d278eca..d60eaf6f4f 100644
--- a/railties/lib/rails/tasks.rb
+++ b/railties/lib/rails/tasks.rb
@@ -10,8 +10,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/engine.rake b/railties/lib/rails/tasks/engine.rake
index 16ad1bfc84..c51524f8f6 100644
--- a/railties/lib/rails/tasks/engine.rake
+++ b/railties/lib/rails/tasks/engine.rake
@@ -40,7 +40,7 @@ namespace :db do
desc "Rolls the schema back to the previous version (specify steps w/ STEP=n)."
app_task "rollback"
- desc "Create a db/schema.rb file that can be portably used against any DB supported by AR"
+ desc "Create a db/schema.rb file that can be portably used against any DB supported by Active Record"
app_task "schema:dump"
desc "Load a schema.rb file into the database"
diff --git a/railties/lib/rails/tasks/framework.rake b/railties/lib/rails/tasks/framework.rake
index a1c805f8aa..904b9d9ad6 100644
--- a/railties/lib/rails/tasks/framework.rake
+++ b/railties/lib/rails/tasks/framework.rake
@@ -32,35 +32,37 @@ namespace :rails do
FileUtils.cp_r src_name, dst_name
end
end
- end
+ end
end
namespace :update do
- def invoke_from_app_generator(method)
- app_generator.send(method)
- end
+ class RailsUpdate
+ def self.invoke_from_app_generator(method)
+ app_generator.send(method)
+ end
- def app_generator
- @app_generator ||= begin
- require 'rails/generators'
- require 'rails/generators/rails/app/app_generator'
- gen = Rails::Generators::AppGenerator.new ["rails"], { with_dispatchers: true },
- destination_root: Rails.root
- File.exist?(Rails.root.join("config", "application.rb")) ?
- gen.send(:app_const) : gen.send(:valid_const?)
- gen
+ def self.app_generator
+ @app_generator ||= begin
+ require 'rails/generators'
+ require 'rails/generators/rails/app/app_generator'
+ gen = Rails::Generators::AppGenerator.new ["rails"], { with_dispatchers: true },
+ destination_root: Rails.root
+ File.exist?(Rails.root.join("config", "application.rb")) ?
+ gen.send(:app_const) : gen.send(:valid_const?)
+ gen
+ end
end
end
# desc "Update config/boot.rb from your current rails install"
task :configs do
- invoke_from_app_generator :create_boot_file
- invoke_from_app_generator :update_config_files
+ RailsUpdate.invoke_from_app_generator :create_boot_file
+ RailsUpdate.invoke_from_app_generator :update_config_files
end
# desc "Adds new executables to the application bin/ directory"
task :bin do
- invoke_from_app_generator :create_bin_files
+ RailsUpdate.invoke_from_app_generator :create_bin_files
end
end
end
diff --git a/railties/lib/rails/tasks/log.rake b/railties/lib/rails/tasks/log.rake
index 877f175ef3..073f235ec5 100644
--- a/railties/lib/rails/tasks/log.rake
+++ b/railties/lib/rails/tasks/log.rake
@@ -1,5 +1,12 @@
namespace :log do
- desc "Truncates all *.log files in log/ to zero bytes (specify which logs with LOGS=test,development)"
+
+ ##
+ # Truncates all/specified log files
+ # ENV['LOGS']
+ # - defaults to standard environment log files i.e. 'development,test,production'
+ # - ENV['LOGS']=all truncates all files i.e. log/*.log
+ # - ENV['LOGS']='test,development' truncates only specified files
+ desc "Truncates all/specified *.log files in log/ to zero bytes (specify which logs with LOGS=test,development)"
task :clear do
log_files.each do |file|
clear_log_file(file)
@@ -7,15 +14,21 @@ namespace :log do
end
def log_files
- if ENV['LOGS']
- ENV['LOGS'].split(',')
- .map { |file| "log/#{file.strip}.log" }
- .select { |file| File.exist?(file) }
- else
+ if ENV['LOGS'] == 'all'
FileList["log/*.log"]
+ elsif ENV['LOGS']
+ log_files_to_truncate(ENV['LOGS'])
+ else
+ log_files_to_truncate("development,test,production")
end
end
+ def log_files_to_truncate(envs)
+ envs.split(',')
+ .map { |file| "log/#{file.strip}.log" }
+ .select { |file| File.exist?(file) }
+ end
+
def clear_log_file(file)
f = File.open(file, "w")
f.close
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/tasks/statistics.rake b/railties/lib/rails/tasks/statistics.rake
index 735c36eb3a..a919d36939 100644
--- a/railties/lib/rails/tasks/statistics.rake
+++ b/railties/lib/rails/tasks/statistics.rake
@@ -9,6 +9,7 @@ STATS_DIRECTORIES = [
%w(Mailers app/mailers),
%w(Javascripts app/assets/javascripts),
%w(Libraries lib/),
+ %w(Tasks lib/tasks),
%w(APIs app/apis),
%w(Controller\ tests test/controllers),
%w(Helper\ tests test/helpers),
diff --git a/railties/lib/rails/templates/rails/mailers/email.html.erb b/railties/lib/rails/templates/rails/mailers/email.html.erb
index bb6e49966d..fed96fbc85 100644
--- a/railties/lib/rails/templates/rails/mailers/email.html.erb
+++ b/railties/lib/rails/templates/rails/mailers/email.html.erb
@@ -94,9 +94,9 @@
<% if @email.multipart? %>
<dd>
- <select onchange="document.getElementsByName('messageBody')[0].src=this.options[this.selectedIndex].value;">
- <option <%= request.format == Mime::HTML ? 'selected' : '' %> value="?part=text%2Fhtml">View as HTML email</option>
- <option <%= request.format == Mime::TEXT ? 'selected' : '' %> value="?part=text%2Fplain">View as plain-text email</option>
+ <select onchange="formatChanged(this);">
+ <option <%= request.format == Mime[:html] ? 'selected' : '' %> value="?part=text%2Fhtml">View as HTML email</option>
+ <option <%= request.format == Mime[:text] ? 'selected' : '' %> value="?part=text%2Fplain">View as plain-text email</option>
</select>
</dd>
<% end %>
@@ -112,5 +112,19 @@
</p>
<% end %>
+<script>
+ function formatChanged(form) {
+ var part_name = form.options[form.selectedIndex].value
+ var iframe =document.getElementsByName('messageBody')[0];
+ iframe.contentWindow.location.replace(part_name);
+
+ if (history.replaceState) {
+ var url = location.pathname.replace(/\.(txt|html)$/, '');
+ var format = /html/.test(part_name) ? '.html' : '.txt';
+ window.history.replaceState({}, '', url + format);
+ }
+ }
+</script>
+
</body>
</html>
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/line_filtering.rb b/railties/lib/rails/test_unit/line_filtering.rb
new file mode 100644
index 0000000000..dab4d3631d
--- /dev/null
+++ b/railties/lib/rails/test_unit/line_filtering.rb
@@ -0,0 +1,70 @@
+require 'method_source'
+
+module Rails
+ module LineFiltering # :nodoc:
+ def run(reporter, options = {})
+ if options[:patterns] && options[:patterns].any? { |p| p =~ /:\d+/ }
+ options[:filter] = \
+ CompositeFilter.new(self, options[:filter], options[:patterns])
+ end
+
+ super
+ end
+ end
+
+ class CompositeFilter # :nodoc:
+ def initialize(runnable, filter, patterns)
+ @runnable = runnable
+ @filters = [ derive_regexp(filter), *derive_line_filters(patterns) ].compact
+ end
+
+ # Minitest uses === to find matching filters.
+ def ===(method)
+ @filters.any? { |filter| filter === method }
+ end
+
+ private
+ def derive_regexp(filter)
+ # Regexp filtering copied from Minitest.
+ filter =~ %r%/(.*)/% ? Regexp.new($1) : filter
+ end
+
+ def derive_line_filters(patterns)
+ patterns.flat_map do |file_and_line|
+ file, *lines = file_and_line.split(':')
+
+ if lines.empty?
+ Filter.new(@runnable, file, nil) if file
+ else
+ lines.map { |line| Filter.new(@runnable, file, line) }
+ end
+ end
+ end
+ end
+
+ class Filter # :nodoc:
+ def initialize(runnable, file, line)
+ @runnable, @file = runnable, File.expand_path(file)
+ @line = line.to_i if line
+ end
+
+ def ===(method)
+ return unless @runnable.method_defined?(method)
+
+ if @line
+ test_file, test_range = definition_for(@runnable.instance_method(method))
+ test_file == @file && test_range.include?(@line)
+ else
+ @runnable.instance_method(method).source_location.first == @file
+ end
+ end
+
+ private
+ def definition_for(method)
+ file, start_line = method.source_location
+ end_line = method.source.count("\n") + start_line - 1
+
+ return file, start_line..end_line
+ end
+ end
+end
diff --git a/railties/lib/rails/test_unit/minitest_plugin.rb b/railties/lib/rails/test_unit/minitest_plugin.rb
index 70ce9d3360..29a3d991b8 100644
--- a/railties/lib/rails/test_unit/minitest_plugin.rb
+++ b/railties/lib/rails/test_unit/minitest_plugin.rb
@@ -1,14 +1,94 @@
-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
+ class SuppressedSummaryReporter < SummaryReporter
+ # Disable extra failure output after a run if output is inline.
+ def aggregated_results
+ super unless options[:output_inline]
+ end
end
- if !($rails_test_runner && $rails_test_runner.show_backtrace?)
- Minitest.backtrace_filter = Rails.backtrace_cleaner
+ def self.plugin_rails_options(opts, options)
+ executable = ::Rails::TestUnitReporter.executable
+ opts.separator ""
+ opts.separator "Usage: #{executable} [options] [files or directories]"
+ opts.separator "You can run a single test by appending a line number to a filename:"
+ opts.separator ""
+ opts.separator " #{executable} 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 " #{executable} test/controllers test/integration/login_test.rb"
+ opts.separator ""
+ opts.separator "By default test failures and errors are reported inline during a run."
+ 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
+
+ opts.on("-d", "--defer-output",
+ "Output test failures and errors after the test run") do
+ options[:output_inline] = false
+ end
+
+ opts.on("-f", "--fail-fast",
+ "Abort test run on first failure") do
+ options[:fail_fast] = true
+ end
+
+ opts.on("-c", "--[no-]color",
+ "Enable color in the output") do |value|
+ options[:color] = value
+ end
+
+ options[:color] = true
+ options[:output_inline] = true
+ options[:patterns] = opts.order!
+ end
+
+ # Running several Rake tasks in a single command would trip up the runner,
+ # as the patterns would also contain the other Rake tasks.
+ def self.rake_run(patterns) # :nodoc:
+ @rake_patterns = patterns
+ passed = run
+ exit passed unless passed
+ passed
end
+
+ def self.plugin_rails_init(options)
+ self.run_with_rails_extension = true
+
+ ENV["RAILS_ENV"] = options[:environment] || "test"
+
+ unless run_with_autorun
+ patterns = defined?(@rake_patterns) ? @rake_patterns : options[:patterns]
+ ::Rails::TestRequirer.require_files(patterns)
+ end
+
+ 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
+
+ # Replace progress reporter for colors.
+ self.reporter.reporters.delete_if { |reporter| reporter.kind_of?(SummaryReporter) || reporter.kind_of?(ProgressReporter) }
+ self.reporter << SuppressedSummaryReporter.new(options[:io], options)
+ 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/railtie.rb b/railties/lib/rails/test_unit/railtie.rb
index 75180ff978..511cee33bd 100644
--- a/railties/lib/rails/test_unit/railtie.rb
+++ b/railties/lib/rails/test_unit/railtie.rb
@@ -1,3 +1,5 @@
+require 'rails/test_unit/line_filtering'
+
if defined?(Rake.application) && Rake.application.top_level_tasks.grep(/^(default$|test(:|$))/).any?
ENV['RAILS_ENV'] ||= 'test'
end
@@ -11,6 +13,10 @@ module Rails
c.integration_tool :test_unit
end
+ initializer "test_unit.line_filtering" do
+ ActiveSupport::TestCase.extend Rails::LineFiltering
+ end
+
rake_tasks do
load "rails/test_unit/testing.rake"
end
diff --git a/railties/lib/rails/test_unit/reporter.rb b/railties/lib/rails/test_unit/reporter.rb
index 64e99626eb..73b8d7d27b 100644
--- a/railties/lib/rails/test_unit/reporter.rb
+++ b/railties/lib/rails/test_unit/reporter.rb
@@ -1,9 +1,36 @@
+require "active_support/core_ext/class/attribute"
require "minitest"
module Rails
class TestUnitReporter < Minitest::StatisticsReporter
+ class_attribute :executable
+ self.executable = "bin/rails test"
+
+ def record(result)
+ super
+
+ if options[:verbose]
+ io.puts color_output(format_line(result), by: result)
+ else
+ io.print color_output(result.result_code, by: result)
+ end
+
+ if output_inline? && result.failure && (!result.skipped? || options[:verbose])
+ io.puts
+ io.puts
+ io.puts format_failures(result).map { |line| color_output(line, by: result) }
+ io.puts
+ io.puts format_rerun_snippet(result)
+ io.puts
+ end
+
+ if fail_fast? && result.failure && !result.error? && !result.skipped?
+ raise Interrupt
+ end
+ end
+
def report
- return if results.empty?
+ return if output_inline? || filtered_results.empty?
io.puts
io.puts "Failed tests:"
io.puts
@@ -11,12 +38,73 @@ 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}"
- end.join "\n"
+ filtered_results.map { |result| format_rerun_snippet(result) }.join "\n"
+ end
+
+ def filtered_results
+ if options[:verbose]
+ results
+ else
+ results.reject(&:skipped?)
+ end
+ end
+
+ def relative_path_for(file)
+ file.sub(/^#{app_root}\/?/, '')
end
+
+ private
+ def output_inline?
+ options[:output_inline]
+ end
+
+ def fail_fast?
+ options[:fail_fast]
+ end
+
+ def format_line(result)
+ "%s#%s = %.2f s = %s" % [result.class, result.name, result.time, result.result_code]
+ end
+
+ def format_failures(result)
+ result.failures.map do |failure|
+ "#{failure.result_label}:\n#{result.class}##{result.name}:\n#{failure.message}\n"
+ end
+ end
+
+ def format_rerun_snippet(result)
+ # Try to extract path to assertion from backtrace.
+ if result.location =~ /\[(.*)\]\z/
+ assertion_path = $1
+ else
+ assertion_path = result.method(result.name).source_location.join(':')
+ end
+
+ "#{self.executable} #{relative_path_for(assertion_path)}"
+ end
+
+ def app_root
+ @app_root ||= defined?(ENGINE_ROOT) ? ENGINE_ROOT : Rails.root
+ end
+
+ def colored_output?
+ options[:color] && io.respond_to?(:tty?) && io.tty?
+ end
+
+ codes = { red: 31, green: 32, yellow: 33 }
+ COLOR_BY_RESULT_CODE = {
+ "." => codes[:green],
+ "E" => codes[:red],
+ "F" => codes[:red],
+ "S" => codes[:yellow]
+ }
+
+ def color_output(string, by:)
+ if colored_output?
+ "\e[#{COLOR_BY_RESULT_CODE[by.result_code]}m#{string}\e[0m"
+ else
+ string
+ end
+ 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..8b9933bed4
--- /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"
+ else
+ 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..41921e43f3 100644
--- a/railties/lib/rails/test_unit/testing.rake
+++ b/railties/lib/rails/test_unit/testing.rake
@@ -1,12 +1,18 @@
-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)
+ pattern = if ENV.key?('TEST')
+ ENV['TEST']
+ else
+ "test"
+ end
+ Minitest.rake_run([pattern])
end
namespace :test do
@@ -23,22 +29,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.rake_run(["test/#{name}"])
end
end
task :generators => "test:prepare" do
$: << "test"
- Rails::TestRunner.run(["test/lib/generators"])
+ Minitest.rake_run(["test/lib/generators"])
end
task :units => "test:prepare" do
$: << "test"
- Rails::TestRunner.run(["test/models", "test/helpers", "test/unit"])
+ Minitest.rake_run(["test/models", "test/helpers", "test/unit"])
end
task :functionals => "test:prepare" do
$: << "test"
- Rails::TestRunner.run(["test/controllers", "test/mailers", "test/functional"])
+ Minitest.rake_run(["test/controllers", "test/mailers", "test/functional"])
end
end
diff --git a/railties/railties.gemspec b/railties/railties.gemspec
index afe1603448..a06336f698 100644
--- a/railties/railties.gemspec
+++ b/railties/railties.gemspec
@@ -15,7 +15,7 @@ Gem::Specification.new do |s|
s.email = 'david@loudthinking.com'
s.homepage = 'http://www.rubyonrails.org'
- s.files = Dir['CHANGELOG.md', 'README.rdoc', 'RDOC_MAIN.rdoc', 'exe/**/*', 'lib/**/{*,.[a-z]*}']
+ s.files = Dir['CHANGELOG.md', 'README.rdoc', 'MIT-LICENSE', 'RDOC_MAIN.rdoc', 'exe/**/*', 'lib/**/{*,.[a-z]*}']
s.require_path = 'lib'
s.bindir = 'exe'
diff --git a/railties/test/app_rails_loader_test.rb b/railties/test/app_loader_test.rb
index d4885447e6..5946c8fd4c 100644
--- a/railties/test/app_rails_loader_test.rb
+++ b/railties/test/app_loader_test.rb
@@ -1,11 +1,11 @@
require 'tmpdir'
require 'abstract_unit'
-require 'rails/app_rails_loader'
+require 'rails/app_loader'
-class AppRailsLoaderTest < ActiveSupport::TestCase
+class AppLoaderTest < ActiveSupport::TestCase
def loader
@loader ||= Class.new do
- extend Rails::AppRailsLoader
+ extend Rails::AppLoader
def self.exec_arguments
@exec_arguments
@@ -23,7 +23,7 @@ class AppRailsLoaderTest < ActiveSupport::TestCase
end
def expects_exec(exe)
- assert_equal [Rails::AppRailsLoader::RUBY, exe], loader.exec_arguments
+ assert_equal [Rails::AppLoader::RUBY, exe], loader.exec_arguments
end
setup do
@@ -38,20 +38,20 @@ class AppRailsLoaderTest < ActiveSupport::TestCase
test "is not in a Rails application if #{exe} is not found in the current or parent directories" do
def loader.find_executables; end
- assert !loader.exec_app_rails
+ assert !loader.exec_app
end
test "is not in a Rails application if #{exe} exists but is a folder" do
FileUtils.mkdir_p(exe)
- assert !loader.exec_app_rails
+ assert !loader.exec_app
end
['APP_PATH', 'ENGINE_PATH'].each do |keyword|
test "is in a Rails application if #{exe} exists and contains #{keyword}" do
write exe, keyword
- loader.exec_app_rails
+ loader.exec_app
expects_exec exe
end
@@ -59,7 +59,7 @@ class AppRailsLoaderTest < ActiveSupport::TestCase
test "is not in a Rails application if #{exe} exists but doesn't contain #{keyword}" do
write exe
- assert !loader.exec_app_rails
+ assert !loader.exec_app
end
test "is in a Rails application if parent directory has #{exe} containing #{keyword} and chdirs to the root directory" do
@@ -68,7 +68,7 @@ class AppRailsLoaderTest < ActiveSupport::TestCase
Dir.chdir('foo/bar')
- loader.exec_app_rails
+ loader.exec_app
expects_exec exe
diff --git a/railties/test/application/asset_debugging_test.rb b/railties/test/application/asset_debugging_test.rb
index acd387256c..0659110ac0 100644
--- a/railties/test/application/asset_debugging_test.rb
+++ b/railties/test/application/asset_debugging_test.rb
@@ -7,7 +7,10 @@ module ApplicationTests
include Rack::Test::Methods
def setup
- build_app(initializers: true)
+ # FIXME: shush Sass warning spam, not relevant to testing Railties
+ Kernel.silence_warnings do
+ build_app(initializers: true)
+ end
app_file "app/assets/javascripts/application.js", "//= require_tree ."
app_file "app/assets/javascripts/xmlhr.js", "function f1() { alert(); }"
@@ -33,12 +36,19 @@ module ApplicationTests
teardown_app
end
+ # FIXME: shush Sass warning spam, not relevant to testing Railties
+ def get(*)
+ Kernel.silence_warnings { super }
+ end
+
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"
+
+ # Load app env
+ app "production"
class ::PostsController < ActionController::Base ; end
@@ -51,8 +61,8 @@ module ApplicationTests
test "assets aren't concatenated when compile is true is on and debug_assets params is true" do
add_to_env_config "production", "config.assets.compile = true"
- ENV["RAILS_ENV"] = "production"
- require "#{app_path}/config/environment"
+ # Load app env
+ app "production"
class ::PostsController < ActionController::Base ; end
diff --git a/railties/test/application/assets_test.rb b/railties/test/application/assets_test.rb
index 1e2a9ba040..5f3b364f97 100644
--- a/railties/test/application/assets_test.rb
+++ b/railties/test/application/assets_test.rb
@@ -17,22 +17,32 @@ module ApplicationTests
end
def precompile!(env = nil)
- quietly do
- precompile_task = "bundle exec rake assets:precompile #{env} --trace 2>&1"
- output = Dir.chdir(app_path) { %x[ #{precompile_task} ] }
- assert $?.success?, output
- output
+ with_env env.to_h do
+ quietly do
+ precompile_task = "bin/rake assets:precompile --trace 2>&1"
+ output = Dir.chdir(app_path) { %x[ #{precompile_task} ] }
+ assert $?.success?, output
+ output
+ end
end
end
+ def with_env(env)
+ env.each { |k, v| ENV[k.to_s] = v }
+ yield
+ ensure
+ env.each_key { |k| ENV.delete k.to_s }
+ end
+
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
def assert_file_exists(filename)
- assert Dir[filename].first, "missing #{filename}"
+ globbed = Dir[filename]
+ assert globbed.one?, "Found #{globbed.size} files matching #{filename}. All files in the directory: #{Dir.entries(File.dirname(filename)).inspect}"
end
def assert_no_file_exists(filename)
@@ -51,7 +61,10 @@ module ApplicationTests
add_to_env_config "development", "config.assets.digest = false"
- require "#{app_path}/config/environment"
+ # FIXME: shush Sass warning spam, not relevant to testing Railties
+ Kernel.silence_warnings do
+ require "#{app_path}/config/environment"
+ end
get "/assets/demo.js"
assert_equal 'a = "/assets/rails.png";', last_response.body.strip
@@ -60,9 +73,10 @@ 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"
+ # Load app env
+ app "production"
assert !defined?(Uglifier)
get "/assets/demo.js"
@@ -71,10 +85,10 @@ module ApplicationTests
end
test "precompile creates the file, gives it the original asset's content and run in production as default" do
+ app_file "app/assets/config/manifest.js", "//= link_tree ../javascripts"
app_file "app/assets/javascripts/application.js", "alert();"
app_file "app/assets/javascripts/foo/application.js", "alert();"
- ENV["RAILS_ENV"] = nil
precompile!
files = Dir["#{app_path}/public/assets/application-*.js"]
@@ -86,6 +100,7 @@ module ApplicationTests
end
def test_precompile_does_not_hit_the_database
+ app_file "app/assets/config/manifest.js", "//= link_tree ../javascripts"
app_file "app/assets/javascripts/application.js", "alert();"
app_file "app/assets/javascripts/foo/application.js", "alert();"
app_file "app/controllers/users_controller.rb", <<-eoruby
@@ -95,10 +110,9 @@ module ApplicationTests
class User < ActiveRecord::Base; raise 'should not be reached'; end
eoruby
- ENV['RAILS_ENV'] = 'production'
- ENV['DATABASE_URL'] = 'postgresql://baduser:badpass@127.0.0.1/dbname'
-
- precompile!
+ precompile! \
+ RAILS_ENV: 'production',
+ DATABASE_URL: 'postgresql://baduser:badpass@127.0.0.1/dbname'
files = Dir["#{app_path}/public/assets/application-*.js"]
files << Dir["#{app_path}/public/assets/foo/application-*.js"].first
@@ -106,9 +120,6 @@ module ApplicationTests
assert_not_nil file, "Expected application.js asset to be generated, but none found"
assert_equal "alert();".strip, File.read(file).strip
end
- ensure
- ENV.delete 'RAILS_ENV'
- ENV.delete 'DATABASE_URL'
end
test "precompile application.js and application.css and all other non JS/CSS files" do
@@ -163,40 +174,44 @@ module ApplicationTests
precompile!
- assert_file_exists("#{app_path}/public/assets/something-*.js")
+ assert_file_exists("#{app_path}/public/assets/something/index-*.js")
end
test 'precompile use assets defined in app env config' do
add_to_env_config 'production', 'config.assets.precompile = [ "something.js" ]'
-
app_file 'app/assets/javascripts/something.js.erb', 'alert();'
- precompile! 'RAILS_ENV=production'
+ precompile! RAILS_ENV: 'production'
assert_file_exists("#{app_path}/public/assets/something-*.js")
end
test 'precompile use assets defined in app config and reassigned in app env config' do
- add_to_config 'config.assets.precompile = [ "something.js" ]'
- add_to_env_config 'production', 'config.assets.precompile += [ "another.js" ]'
+ add_to_config 'config.assets.precompile = [ "something_manifest.js" ]'
+ add_to_env_config 'production', 'config.assets.precompile += [ "another_manifest.js" ]'
+
+ app_file 'app/assets/config/something_manifest.js', '//= link something.js'
+ app_file 'app/assets/config/another_manifest.js', '//= link another.js'
app_file 'app/assets/javascripts/something.js.erb', 'alert();'
app_file 'app/assets/javascripts/another.js.erb', 'alert();'
- precompile! 'RAILS_ENV=production'
+ precompile! RAILS_ENV: 'production'
+ assert_file_exists("#{app_path}/public/assets/something_manifest-*.js")
assert_file_exists("#{app_path}/public/assets/something-*.js")
+ assert_file_exists("#{app_path}/public/assets/another_manifest-*.js")
assert_file_exists("#{app_path}/public/assets/another-*.js")
end
- test "asset pipeline should use a Sprockets::Index when config.assets.digest is true" do
+ test "asset pipeline should use a Sprockets::CachedEnvironment when config.assets.digest is true" do
add_to_config "config.action_controller.perform_caching = false"
add_to_env_config "production", "config.assets.compile = true"
- ENV["RAILS_ENV"] = "production"
- require "#{app_path}/config/environment"
+ # Load app env
+ app "production"
- assert_equal Sprockets::Index, Rails.application.assets.class
+ assert_equal Sprockets::CachedEnvironment, Rails.application.assets.class
end
test "precompile creates a manifest file with all the assets listed" do
@@ -205,8 +220,8 @@ module ApplicationTests
app_file "app/assets/javascripts/application.js", "alert();"
precompile!
- manifest = Dir["#{app_path}/public/assets/.sprockets-manifest-*.json"].first
+ manifest = Dir["#{app_path}/public/assets/.sprockets-manifest-*.json"].first
assets = ActiveSupport::JSON.decode(File.read(manifest))
assert_match(/application-([0-z]+)\.js/, assets["assets"]["application.js"])
assert_match(/application-([0-z]+)\.css/, assets["assets"]["application.css"])
@@ -225,16 +240,16 @@ module ApplicationTests
test "assets do not require any assets group gem when manifest file is present" do
app_file "app/assets/javascripts/application.js", "alert();"
- add_to_env_config "production", "config.serve_static_files = true"
+ add_to_env_config "production", "config.public_file_server.enabled = true"
- ENV["RAILS_ENV"] = "production"
- precompile!
+ precompile! RAILS_ENV: 'production'
manifest = Dir["#{app_path}/public/assets/.sprockets-manifest-*.json"].first
assets = ActiveSupport::JSON.decode(File.read(manifest))
asset_path = assets["assets"]["application.js"]
- require "#{app_path}/config/environment"
+ # Load app env
+ app "production"
# Checking if Uglifier is defined we can know if Sprockets was reached or not
assert !defined?(Uglifier)
@@ -243,12 +258,11 @@ module ApplicationTests
assert !defined?(Uglifier)
end
- test "precompile properly refers files referenced with asset_path and runs in the provided RAILS_ENV" do
+ test "precompile properly refers files referenced with asset_path" do
app_file "app/assets/images/rails.png", "notactuallyapng"
- app_file "app/assets/stylesheets/application.css.erb", "<%= asset_path('rails.png') %>"
- add_to_env_config "test", "config.assets.digest = true"
+ app_file "app/assets/stylesheets/application.css.erb", "p { background-image: url(<%= asset_path('rails.png') %>) }"
- precompile!('RAILS_ENV=test')
+ precompile!
file = Dir["#{app_path}/public/assets/application-*.css"].first
assert_match(/\/assets\/rails-([0-z]+)\.png/, File.read(file))
@@ -257,10 +271,9 @@ module ApplicationTests
test "precompile shouldn't use the digests present in manifest.json" do
app_file "app/assets/images/rails.png", "notactuallyapng"
- app_file "app/assets/stylesheets/application.css.erb", "p { url: <%= asset_path('rails.png') %> }"
+ app_file "app/assets/stylesheets/application.css.erb", "p { background-image: url(<%= asset_path('rails.png') %>) }"
- ENV["RAILS_ENV"] = "production"
- precompile!
+ precompile! RAILS_ENV: 'production'
manifest = Dir["#{app_path}/public/assets/.sprockets-manifest-*.json"].first
assets = ActiveSupport::JSON.decode(File.read(manifest))
@@ -269,17 +282,16 @@ module ApplicationTests
app_file "app/assets/images/rails.png", "p { url: change }"
precompile!
- assets = ActiveSupport::JSON.decode(File.read(manifest))
+ assets = ActiveSupport::JSON.decode(File.read(manifest))
assert_not_equal asset_path, assets["assets"]["application.css"]
end
test "precompile appends the md5 hash to files referenced with asset_path and run in production with digest true" do
app_file "app/assets/images/rails.png", "notactuallyapng"
- app_file "app/assets/stylesheets/application.css.erb", "<%= asset_path('rails.png') %>"
+ app_file "app/assets/stylesheets/application.css.erb", "p { background-image: url(<%= asset_path('rails.png') %>) }"
- ENV["RAILS_ENV"] = "production"
- precompile!
+ precompile! RAILS_ENV: 'production'
file = Dir["#{app_path}/public/assets/application-*.css"].first
assert_match(/\/assets\/rails-([0-z]+)\.png/, File.read(file))
@@ -288,7 +300,8 @@ module ApplicationTests
test "precompile should handle utf8 filenames" do
filename = "レイルズ.png"
app_file "app/assets/images/#{filename}", "not an image really"
- add_to_config "config.assets.precompile = [ /\.png$/, /application.(css|js)$/ ]"
+ app_file "app/assets/config/manifest.js", "//= link_tree ../images"
+ add_to_config "config.assets.precompile = %w(manifest.js)"
precompile!
@@ -296,7 +309,8 @@ module ApplicationTests
assets = ActiveSupport::JSON.decode(File.read(manifest))
assert asset_path = assets["assets"].find { |(k, _)| k && k =~ /.png/ }[1]
- require "#{app_path}/config/environment"
+ # Load app env
+ app "development"
get "/assets/#{URI.parser.escape(asset_path)}"
assert_match "not an image really", last_response.body
@@ -319,8 +333,8 @@ module ApplicationTests
app_file "app/assets/javascripts/demo.js.erb", "<%= :alert %>();"
add_to_config "config.assets.compile = false"
- ENV["RAILS_ENV"] = "production"
- require "#{app_path}/config/environment"
+ # Load app env
+ app "production"
get "/assets/demo.js"
assert_equal 404, last_response.status
@@ -337,7 +351,8 @@ module ApplicationTests
add_to_env_config "development", "config.assets.digest = false"
- require "#{app_path}/config/environment"
+ # Load app env
+ app "development"
class ::OmgController < ActionController::Base
def index
@@ -363,7 +378,8 @@ module ApplicationTests
add_to_env_config "development", "config.assets.digest = false"
- require "#{app_path}/config/environment"
+ # Load app env
+ app "development"
get "/assets/demo.js"
assert_match "alert();", last_response.body
@@ -374,10 +390,10 @@ module ApplicationTests
app_with_assets_in_view
# config.assets.debug and config.assets.compile are false for production environment
- ENV["RAILS_ENV"] = "production"
- precompile!
+ precompile! RAILS_ENV: 'production'
- require "#{app_path}/config/environment"
+ # Load app env
+ app "production"
class ::PostsController < ActionController::Base ; end
@@ -393,7 +409,8 @@ module ApplicationTests
app_file "app/assets/javascripts/xmlhr.js.erb", "<%= Post.name %>"
precompile!
- assert_equal "Post;\n", File.read(Dir["#{app_path}/public/assets/application-*.js"].first)
+
+ assert_match(/Post;/, File.read(Dir["#{app_path}/public/assets/application-*.js"].first))
end
test "initialization on the assets group should set assets_dir" do
@@ -434,7 +451,10 @@ module ApplicationTests
app_with_assets_in_view
add_to_config "config.asset_host = 'example.com'"
add_to_env_config "development", "config.assets.digest = false"
- require "#{app_path}/config/environment"
+
+ # Load app env
+ app "development"
+
class ::PostsController < ActionController::Base; end
get '/posts', {}, {'HTTPS'=>'off'}
@@ -449,6 +469,7 @@ module ApplicationTests
add_to_config "config.assets.precompile = %w{rails.png image_loader.js}"
add_to_config "config.asset_host = 'example.com'"
add_to_env_config "development", "config.assets.digest = false"
+
precompile!
assert_match "src='//example.com/assets/rails.png'", File.read(Dir["#{app_path}/public/assets/image_loader-*.js"].first)
@@ -460,6 +481,7 @@ module ApplicationTests
app_file "app/assets/javascripts/app.js.erb", "var src='<%= image_path('rails.png') %>';"
add_to_config "config.assets.precompile = %w{rails.png app.js}"
add_to_env_config "development", "config.assets.digest = false"
+
precompile!
assert_match "src='/sub/uri/assets/rails.png'", File.read(Dir["#{app_path}/public/assets/app-*.js"].first)
diff --git a/railties/test/application/bin_setup_test.rb b/railties/test/application/bin_setup_test.rb
index 1bdced02e9..8c3ab65c51 100644
--- a/railties/test/application/bin_setup_test.rb
+++ b/railties/test/application/bin_setup_test.rb
@@ -21,14 +21,14 @@ module ApplicationTests
RUBY
list_tables = lambda { `bin/rails runner 'p ActiveRecord::Base.connection.tables'`.strip }
- File.write("log/my.log", "zomg!")
+ File.write("log/test.log", "zomg!")
assert_equal '[]', list_tables.call
- assert_equal 5, File.size("log/my.log")
+ assert_equal 5, File.size("log/test.log")
assert_not File.exist?("tmp/restart.txt")
`bin/setup 2>&1`
- assert_equal 0, File.size("log/my.log")
- assert_equal '["articles", "schema_migrations"]', list_tables.call
+ assert_equal 0, File.size("log/test.log")
+ assert_equal '["articles", "schema_migrations", "active_record_internal_metadatas"]', list_tables.call
assert File.exist?("tmp/restart.txt")
end
end
diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb
index 38516a1c1a..7bcfc86d03 100644
--- a/railties/test/application/configuration_test.rb
+++ b/railties/test/application/configuration_test.rb
@@ -34,8 +34,19 @@ module ApplicationTests
FileUtils.cp_r(app_path, new_app)
end
- def app
- @app ||= Rails.application
+ def app(env = 'development')
+ @app ||= begin
+ ENV['RAILS_ENV'] = env
+
+ # FIXME: shush Sass warning spam, not relevant to testing Railties
+ Kernel.silence_warnings do
+ require "#{app_path}/config/environment"
+ end
+
+ Rails.application
+ ensure
+ ENV.delete 'RAILS_ENV'
+ end
end
def setup
@@ -68,6 +79,24 @@ module ApplicationTests
end
end
+ test "By default logs tags are not set in development" do
+ restore_default_config
+
+ with_rails_env "development" do
+ app 'development'
+ assert Rails.application.config.log_tags.blank?
+ end
+ end
+
+ test "By default logs are tagged with :request_id in production" do
+ restore_default_config
+
+ with_rails_env "production" do
+ app 'production'
+ assert_equal [:request_id], Rails.application.config.log_tags
+ end
+ end
+
test "lib dir is on LOAD_PATH during config" do
app_file 'lib/my_logger.rb', <<-RUBY
require "logger"
@@ -78,7 +107,9 @@ module ApplicationTests
require 'my_logger'
config.logger = MyLogger.new STDOUT
RUBY
- require "#{app_path}/config/environment"
+
+ app 'development'
+
assert_equal 'MyLogger', Rails.application.config.logger.class.name
end
@@ -90,14 +121,14 @@ module ApplicationTests
RUBY
app_file 'db/migrate/20140708012246_create_user.rb', <<-RUBY
- class CreateUser < ActiveRecord::Migration
+ class CreateUser < ActiveRecord::Migration::Current
def change
create_table :users
end
end
RUBY
- require "#{app_path}/config/environment"
+ app 'development'
ActiveRecord::Migrator.migrations_paths = ["#{app_path}/db/migrate"]
@@ -128,29 +159,29 @@ module ApplicationTests
test "Rails.application is nil until app is initialized" do
require 'rails'
assert_nil Rails.application
- require "#{app_path}/config/environment"
+ app 'development'
assert_equal AppTemplate::Application.instance, Rails.application
end
test "Rails.application responds to all instance methods" do
- require "#{app_path}/config/environment"
+ app 'development'
assert_respond_to Rails.application, :routes_reloader
assert_equal Rails.application.routes_reloader, AppTemplate::Application.routes_reloader
end
test "Rails::Application responds to paths" do
- require "#{app_path}/config/environment"
+ app 'development'
assert_respond_to AppTemplate::Application, :paths
assert_equal ["#{app_path}/app/views"], AppTemplate::Application.paths["app/views"].expanded
end
test "the application root is set correctly" do
- require "#{app_path}/config/environment"
+ app 'development'
assert_equal Pathname.new(app_path), Rails.application.root
end
test "the application root can be seen from the application singleton" do
- require "#{app_path}/config/environment"
+ app 'development'
assert_equal Pathname.new(app_path), AppTemplate::Application.root
end
@@ -162,7 +193,8 @@ module ApplicationTests
use_frameworks []
- require "#{app_path}/config/environment"
+ app 'development'
+
assert_equal Pathname.new(new_app), Rails.application.root
end
@@ -172,7 +204,7 @@ module ApplicationTests
use_frameworks []
Dir.chdir("#{app_path}") do
- require "#{app_path}/config/environment"
+ app 'development'
assert_equal Pathname.new("#{app_path}"), Rails.application.root
end
end
@@ -181,7 +213,9 @@ module ApplicationTests
add_to_config <<-RUBY
config.root = "#{app_path}"
RUBY
- require "#{app_path}/config/environment"
+
+ app 'development'
+
assert_instance_of Pathname, Rails.root
end
@@ -189,7 +223,9 @@ module ApplicationTests
add_to_config <<-RUBY
config.paths["public"] = "somewhere"
RUBY
- require "#{app_path}/config/environment"
+
+ app 'development'
+
assert_instance_of Pathname, Rails.public_path
end
@@ -199,16 +235,19 @@ module ApplicationTests
config.cache_classes = true
RUBY
- require "#{app_path}/config/application"
- assert Rails.application.initialize!
+ app 'development'
+
+ assert_equal :require, ActiveSupport::Dependencies.mechanism
end
test "application is always added to eager_load namespaces" do
- require "#{app_path}/config/application"
+ app 'development'
assert_includes Rails.application.config.eager_load_namespaces, AppTemplate::Application
end
test "the application can be eager loaded even when there are no frameworks" do
+ FileUtils.rm_rf("#{app_path}/app/models/application_record.rb")
+ FileUtils.rm_rf("#{app_path}/app/mailers/application_mailer.rb")
FileUtils.rm_rf("#{app_path}/config/environments")
add_to_config <<-RUBY
config.eager_load = true
@@ -218,7 +257,7 @@ module ApplicationTests
use_frameworks []
assert_nothing_raised do
- require "#{app_path}/config/application"
+ app 'development'
end
end
@@ -230,7 +269,7 @@ module ApplicationTests
RUBY
assert_nothing_raised do
- require "#{app_path}/config/application"
+ app 'development'
end
end
@@ -239,7 +278,7 @@ module ApplicationTests
Rails.application.config.filter_parameters += [ :password, :foo, 'bar' ]
RUBY
- require "#{app_path}/config/environment"
+ app 'development'
assert_equal [:password, :foo, 'bar'], Rails.application.env_config['action_dispatch.parameter_filter']
end
@@ -255,7 +294,7 @@ module ApplicationTests
assert !$prepared
- require "#{app_path}/config/environment"
+ app 'development'
get "/"
assert $prepared
@@ -267,7 +306,7 @@ module ApplicationTests
end
test "skipping config.encoding still results in 'utf-8' as the default" do
- require "#{app_path}/config/application"
+ app 'development'
assert_utf8
end
@@ -276,7 +315,7 @@ module ApplicationTests
config.encoding = "utf-8"
RUBY
- require "#{app_path}/config/application"
+ app 'development'
assert_utf8
end
@@ -285,41 +324,61 @@ module ApplicationTests
config.paths["public"] = "somewhere"
RUBY
- require "#{app_path}/config/application"
+ app 'development'
assert_equal Pathname.new(app_path).join("somewhere"), Rails.public_path
end
- test "In production mode, config.serve_static_files is off by default" do
+ test "In production mode, config.public_file_server.enabled is off by default" do
restore_default_config
with_rails_env "production" do
- require "#{app_path}/config/environment"
- assert_not app.config.serve_static_files
+ app 'production'
+ assert_not app.config.public_file_server.enabled
end
end
- test "In production mode, config.serve_static_files is enabled when RAILS_SERVE_STATIC_FILES is set" do
+ test "In production mode, config.public_file_server.enabled is enabled when RAILS_SERVE_STATIC_FILES is set" do
restore_default_config
with_rails_env "production" do
switch_env "RAILS_SERVE_STATIC_FILES", "1" do
- require "#{app_path}/config/environment"
- assert app.config.serve_static_files
+ app 'production'
+ assert app.config.public_file_server.enabled
end
end
end
- test "In production mode, config.serve_static_files is disabled when RAILS_SERVE_STATIC_FILES is blank" do
+ test "In production mode, config.public_file_server.enabled is disabled when RAILS_SERVE_STATIC_FILES is blank" do
restore_default_config
with_rails_env "production" do
switch_env "RAILS_SERVE_STATIC_FILES", " " do
- require "#{app_path}/config/environment"
- assert_not app.config.serve_static_files
+ app 'production'
+ assert_not app.config.public_file_server.enabled
end
end
end
+ test "config.serve_static_files is deprecated" do
+ make_basic_app do |application|
+ assert_deprecated do
+ application.config.serve_static_files = true
+ end
+
+ assert application.config.public_file_server.enabled
+ end
+ end
+
+ test "config.static_cache_control is deprecated" do
+ make_basic_app do |application|
+ assert_deprecated do
+ application.config.static_cache_control = "public, max-age=60"
+ end
+
+ assert_equal application.config.static_cache_control, "public, max-age=60"
+ end
+ end
+
test "Use key_generator when secret_key_base is set" do
make_basic_app do |application|
application.secrets.secret_key_base = 'b3c631c314c0bbca50c1b2843150fe33'
@@ -363,8 +422,8 @@ module ApplicationTests
development:
secret_key_base:
YAML
- require "#{app_path}/config/environment"
+ app 'development'
assert_equal app.env_config['action_dispatch.key_generator'], Rails.application.key_generator
assert_equal app.env_config['action_dispatch.key_generator'].class, ActiveSupport::LegacyKeyGenerator
@@ -380,13 +439,27 @@ module ApplicationTests
development:
secret_key_base:
YAML
- require "#{app_path}/config/environment"
+
+ app 'development'
assert_deprecated(/You didn't set `secret_key_base`./) do
app.env_config
end
end
+ test "raise when secrets.secret_key_base is not a type of string" do
+ app_file 'config/secrets.yml', <<-YAML
+ development:
+ secret_key_base: 123
+ YAML
+
+ app 'development'
+
+ assert_raise(ArgumentError) do
+ app.key_generator
+ end
+ end
+
test "prefer secrets.secret_token over config.secret_token" do
app_file 'config/initializers/secret_token.rb', <<-RUBY
Rails.application.config.secret_token = ""
@@ -395,7 +468,8 @@ module ApplicationTests
development:
secret_token: 3b7cd727ee24e8444053437c36cc66c3
YAML
- require "#{app_path}/config/environment"
+
+ app 'development'
assert_equal '3b7cd727ee24e8444053437c36cc66c3', app.secrets.secret_token
end
@@ -426,7 +500,7 @@ module ApplicationTests
secret_key_base: 3b7cd727ee24e8444053437c36cc66c3
YAML
- require "#{app_path}/config/environment"
+ app 'development'
assert_equal '3b7cd727ee24e8444053437c36cc66c3', app.secrets.secret_key_base
end
@@ -436,7 +510,7 @@ module ApplicationTests
Rails.application.config.secret_key_base = "3b7cd727ee24e8444053437c36cc66c3"
RUBY
- require "#{app_path}/config/environment"
+ app 'development'
assert_equal '3b7cd727ee24e8444053437c36cc66c3', app.secrets.secret_key_base
end
@@ -449,7 +523,8 @@ module ApplicationTests
secret_key_base:
secret_token:
YAML
- require "#{app_path}/config/environment"
+
+ app 'development'
assert_equal 'b3c631c314c0bbca50c1b2843150fe33', app.secrets.secret_token
assert_equal 'b3c631c314c0bbca50c1b2843150fe33', app.config.secret_token
@@ -463,7 +538,8 @@ module ApplicationTests
aws_secret_access_key: myamazonsecretaccesskey
YAML
- require "#{app_path}/config/environment"
+ app 'development'
+
assert_equal 'myamazonaccesskeyid', app.secrets.aws_access_key_id
assert_equal 'myamazonsecretaccesskey', app.secrets.aws_secret_access_key
end
@@ -471,7 +547,8 @@ module ApplicationTests
test "blank config/secrets.yml does not crash the loading process" do
app_file 'config/secrets.yml', <<-YAML
YAML
- require "#{app_path}/config/environment"
+
+ app 'development'
assert_nil app.secrets.not_defined
end
@@ -484,7 +561,8 @@ module ApplicationTests
development:
secret_key_base:
YAML
- require "#{app_path}/config/environment"
+
+ app 'development'
assert_equal "iaminallyoursecretkeybase", app.secrets.secret_key_base
end
@@ -497,7 +575,8 @@ module ApplicationTests
development:
secret_key_base:
YAML
- require "#{app_path}/config/environment"
+
+ app 'development'
assert_equal 'b3c631c314c0bbca50c1b2843150fe33', app.config.secret_token
assert_equal nil, app.secrets.secret_key_base
@@ -512,7 +591,8 @@ module ApplicationTests
development:
secret_key_base:
YAML
- require "#{app_path}/config/environment"
+
+ app 'development'
assert_equal '', app.config.secret_token
assert_equal nil, app.secrets.secret_key_base
@@ -535,7 +615,6 @@ module ApplicationTests
end
test "default form builder specified as a string" do
-
app_file 'config/initializers/form_builder.rb', <<-RUBY
class CustomFormBuilder < ActionView::Helpers::FormBuilder
def text_field(attribute, *args)
@@ -567,7 +646,7 @@ module ApplicationTests
end
RUBY
- require "#{app_path}/config/environment"
+ app 'development'
get "/posts"
assert_match(/label/, last_response.body)
@@ -596,7 +675,7 @@ module ApplicationTests
private
- def form_authenticity_token; token; end # stub the authenticy token
+ def form_authenticity_token(*args); token; end # stub the authenticy token
end
RUBY
@@ -606,9 +685,9 @@ module ApplicationTests
end
RUBY
- require "#{app_path}/config/environment"
+ app 'development'
- params = {authenticity_token: token}
+ params = { authenticity_token: token }
get "/posts/1"
assert_match(/patch/, last_response.body)
@@ -659,9 +738,9 @@ module ApplicationTests
config.action_mailer.interceptors = MyMailInterceptor
RUBY
- require "#{app_path}/config/environment"
- require "mail"
+ app 'development'
+ require "mail"
_ = ActionMailer::Base
assert_equal [::MyMailInterceptor], ::Mail.send(:class_variable_get, "@@delivery_interceptors")
@@ -672,9 +751,9 @@ module ApplicationTests
config.action_mailer.interceptors = [MyMailInterceptor, "MyOtherMailInterceptor"]
RUBY
- require "#{app_path}/config/environment"
- require "mail"
+ app 'development'
+ require "mail"
_ = ActionMailer::Base
assert_equal [::MyMailInterceptor, ::MyOtherMailInterceptor], ::Mail.send(:class_variable_get, "@@delivery_interceptors")
@@ -685,9 +764,9 @@ module ApplicationTests
config.action_mailer.preview_interceptors = MyPreviewMailInterceptor
RUBY
- require "#{app_path}/config/environment"
- require "mail"
+ app 'development'
+ require "mail"
_ = ActionMailer::Base
assert_equal [ActionMailer::InlinePreviewInterceptor, ::MyPreviewMailInterceptor], ActionMailer::Base.preview_interceptors
@@ -698,9 +777,9 @@ module ApplicationTests
config.action_mailer.preview_interceptors = [MyPreviewMailInterceptor, "MyOtherPreviewMailInterceptor"]
RUBY
- require "#{app_path}/config/environment"
- require "mail"
+ app 'development'
+ require "mail"
_ = ActionMailer::Base
assert_equal [ActionMailer::InlinePreviewInterceptor, MyPreviewMailInterceptor, MyOtherPreviewMailInterceptor], ActionMailer::Base.preview_interceptors
@@ -711,9 +790,9 @@ module ApplicationTests
ActionMailer::Base.preview_interceptors.delete(ActionMailer::InlinePreviewInterceptor)
RUBY
- require "#{app_path}/config/environment"
- require "mail"
+ app 'development'
+ require "mail"
_ = ActionMailer::Base
assert_equal [], ActionMailer::Base.preview_interceptors
@@ -724,9 +803,9 @@ module ApplicationTests
config.action_mailer.observers = MyMailObserver
RUBY
- require "#{app_path}/config/environment"
- require "mail"
+ app 'development'
+ require "mail"
_ = ActionMailer::Base
assert_equal [::MyMailObserver], ::Mail.send(:class_variable_get, "@@delivery_notification_observers")
@@ -737,21 +816,34 @@ module ApplicationTests
config.action_mailer.observers = [MyMailObserver, "MyOtherMailObserver"]
RUBY
- require "#{app_path}/config/environment"
- require "mail"
+ app 'development'
+ require "mail"
_ = ActionMailer::Base
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
+
+ app 'development'
+
+ 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}"
config.time_zone = "Wellington"
RUBY
- require "#{app_path}/config/environment"
+ app 'development'
assert_equal "Wellington", Rails.application.config.time_zone
end
@@ -763,7 +855,7 @@ module ApplicationTests
RUBY
assert_raise(ArgumentError) do
- require "#{app_path}/config/environment"
+ app 'development'
end
end
@@ -773,7 +865,7 @@ module ApplicationTests
config.beginning_of_week = :wednesday
RUBY
- require "#{app_path}/config/environment"
+ app 'development'
assert_equal :wednesday, Rails.application.config.beginning_of_week
end
@@ -785,13 +877,14 @@ module ApplicationTests
RUBY
assert_raise(ArgumentError) do
- require "#{app_path}/config/environment"
+ app 'development'
end
end
test "config.action_view.cache_template_loading with cache_classes default" do
add_to_config "config.cache_classes = true"
- require "#{app_path}/config/environment"
+
+ app 'development'
require 'action_view/base'
assert_equal true, ActionView::Resolver.caching?
@@ -799,7 +892,8 @@ module ApplicationTests
test "config.action_view.cache_template_loading without cache_classes default" do
add_to_config "config.cache_classes = false"
- require "#{app_path}/config/environment"
+
+ app 'development'
require 'action_view/base'
assert_equal false, ActionView::Resolver.caching?
@@ -810,7 +904,8 @@ module ApplicationTests
config.cache_classes = true
config.action_view.cache_template_loading = false
RUBY
- require "#{app_path}/config/environment"
+
+ app 'development'
require 'action_view/base'
assert_equal false, ActionView::Resolver.caching?
@@ -821,7 +916,8 @@ module ApplicationTests
config.cache_classes = false
config.action_view.cache_template_loading = true
RUBY
- require "#{app_path}/config/environment"
+
+ app 'development'
require 'action_view/base'
assert_equal true, ActionView::Resolver.caching?
@@ -836,7 +932,7 @@ module ApplicationTests
require 'action_view/railtie'
require 'action_view/base'
- require "#{app_path}/config/environment"
+ app 'development'
assert_equal false, ActionView::Resolver.caching?
end
@@ -889,7 +985,7 @@ module ApplicationTests
end
RUBY
- require "#{app_path}/config/environment"
+ app 'development'
post "/posts.json", '{ "title": "foo", "name": "bar" }', "CONTENT_TYPE" => "application/json"
assert_equal '{"title"=>"foo"}', last_response.body
@@ -911,7 +1007,7 @@ module ApplicationTests
config.action_controller.permit_all_parameters = true
RUBY
- require "#{app_path}/config/environment"
+ app 'development'
post "/posts", {post: {"title" =>"zomg"}}
assert_equal 'permitted', last_response.body
@@ -933,7 +1029,7 @@ module ApplicationTests
config.action_controller.action_on_unpermitted_parameters = :raise
RUBY
- require "#{app_path}/config/environment"
+ app 'development'
assert_equal :raise, ActionController::Parameters.action_on_unpermitted_parameters
@@ -942,7 +1038,7 @@ module ApplicationTests
end
test "config.action_controller.always_permitted_parameters are: controller, action by default" do
- require "#{app_path}/config/environment"
+ app 'development'
assert_equal %w(controller action), ActionController::Parameters.always_permitted_parameters
end
@@ -950,7 +1046,9 @@ module ApplicationTests
add_to_config <<-RUBY
config.action_controller.always_permitted_parameters = %w( controller action format )
RUBY
- require "#{app_path}/config/environment"
+
+ app 'development'
+
assert_equal %w( controller action format ), ActionController::Parameters.always_permitted_parameters
end
@@ -971,7 +1069,7 @@ module ApplicationTests
config.action_controller.action_on_unpermitted_parameters = :raise
RUBY
- require "#{app_path}/config/environment"
+ app 'development'
assert_equal :raise, ActionController::Parameters.action_on_unpermitted_parameters
@@ -980,25 +1078,19 @@ module ApplicationTests
end
test "config.action_controller.action_on_unpermitted_parameters is :log by default on development" do
- ENV["RAILS_ENV"] = "development"
-
- require "#{app_path}/config/environment"
+ app 'development'
assert_equal :log, ActionController::Parameters.action_on_unpermitted_parameters
end
test "config.action_controller.action_on_unpermitted_parameters is :log by default on test" do
- ENV["RAILS_ENV"] = "test"
-
- require "#{app_path}/config/environment"
+ app 'test'
assert_equal :log, ActionController::Parameters.action_on_unpermitted_parameters
end
test "config.action_controller.action_on_unpermitted_parameters is false by default on production" do
- ENV["RAILS_ENV"] = "production"
-
- require "#{app_path}/config/environment"
+ app 'production'
assert_equal false, ActionController::Parameters.action_on_unpermitted_parameters
end
@@ -1076,17 +1168,14 @@ module ApplicationTests
test "config.active_record.dump_schema_after_migration is false on production" do
build_app
- ENV["RAILS_ENV"] = "production"
- require "#{app_path}/config/environment"
+ app 'production'
assert_not ActiveRecord::Base.dump_schema_after_migration
end
test "config.active_record.dump_schema_after_migration is true by default on development" do
- ENV["RAILS_ENV"] = "development"
-
- require "#{app_path}/config/environment"
+ app 'development'
assert ActiveRecord::Base.dump_schema_after_migration
end
@@ -1112,7 +1201,7 @@ module ApplicationTests
end
RUBY
- require "#{app_path}/config/environment"
+ app 'development'
assert_not Rails.configuration.ran_block
require 'rake'
@@ -1134,7 +1223,7 @@ module ApplicationTests
end
RUBY
- require "#{app_path}/config/environment"
+ app 'development'
assert_not Rails.configuration.ran_block
Rails.application.load_generators
@@ -1152,7 +1241,7 @@ module ApplicationTests
end
RUBY
- require "#{app_path}/config/environment"
+ app 'development'
assert_not Rails.configuration.ran_block
Rails.application.load_console
@@ -1170,7 +1259,7 @@ module ApplicationTests
end
RUBY
- require "#{app_path}/config/environment"
+ app 'development'
assert_not Rails.configuration.ran_block
Rails.application.load_runner
@@ -1186,14 +1275,14 @@ module ApplicationTests
end
RUBY
- require "#{app_path}/config/environment"
+ app 'development'
assert_kind_of Hash, Rails.application.config.database_configuration
end
test 'raises with proper error message if no database configuration found' do
FileUtils.rm("#{app_path}/config/database.yml")
- require "#{app_path}/config/environment"
+ app 'development'
err = assert_raises RuntimeError do
Rails.application.config.database_configuration
end
@@ -1201,25 +1290,23 @@ module ApplicationTests
end
test 'config.action_mailer.show_previews defaults to true in development' do
- Rails.env = "development"
- require "#{app_path}/config/environment"
+ app 'development'
assert Rails.application.config.action_mailer.show_previews
end
test 'config.action_mailer.show_previews defaults to false in production' do
- Rails.env = "production"
- require "#{app_path}/config/environment"
+ app 'production'
assert_equal false, Rails.application.config.action_mailer.show_previews
end
test 'config.action_mailer.show_previews can be set in the configuration file' do
- Rails.env = "production"
add_to_config <<-RUBY
config.action_mailer.show_previews = true
RUBY
- require "#{app_path}/config/environment"
+
+ app 'production'
assert_equal true, Rails.application.config.action_mailer.show_previews
end
@@ -1234,7 +1321,22 @@ module ApplicationTests
config.my_custom_config = config_for('custom')
RUBY
- require "#{app_path}/config/environment"
+ app 'development'
+
+ assert_equal 'custom key', Rails.application.config.my_custom_config['key']
+ end
+
+ test "config_for use the Pathname object if it is provided" do
+ app_file 'config/custom.yml', <<-RUBY
+ development:
+ key: 'custom key'
+ RUBY
+
+ add_to_config <<-RUBY
+ config.my_custom_config = config_for(Pathname.new(Rails.root.join("config/custom.yml")))
+ RUBY
+
+ app 'development'
assert_equal 'custom key', Rails.application.config.my_custom_config['key']
end
@@ -1245,7 +1347,7 @@ module ApplicationTests
RUBY
exception = assert_raises(RuntimeError) do
- require "#{app_path}/config/environment"
+ app 'development'
end
assert_equal "Could not load configuration. No such file - #{app_path}/config/custom.yml", exception.message
@@ -1260,7 +1362,8 @@ module ApplicationTests
add_to_config <<-RUBY
config.my_custom_config = config_for('custom')
RUBY
- require "#{app_path}/config/environment"
+
+ app 'development'
assert_equal({}, Rails.application.config.my_custom_config)
end
@@ -1272,7 +1375,8 @@ module ApplicationTests
add_to_config <<-RUBY
config.my_custom_config = config_for('custom')
RUBY
- require "#{app_path}/config/environment"
+
+ app 'development'
assert_equal({}, Rails.application.config.my_custom_config)
end
@@ -1286,12 +1390,13 @@ module ApplicationTests
add_to_config <<-RUBY
config.my_custom_config = config_for('custom')
RUBY
- require "#{app_path}/config/environment"
+
+ app 'development'
assert_equal 'custom key', Rails.application.config.my_custom_config['key']
end
- test "config_for with syntax error show a more descritive exception" do
+ test "config_for with syntax error show a more descriptive exception" do
app_file 'config/custom.yml', <<-RUBY
development:
key: foo:
@@ -1302,10 +1407,66 @@ module ApplicationTests
RUBY
exception = assert_raises(RuntimeError) do
- require "#{app_path}/config/environment"
+ app 'development'
end
assert_match 'YAML syntax error occurred while parsing', exception.message
end
+
+ test "config_for allows overriding the environment" do
+ app_file 'config/custom.yml', <<-RUBY
+ test:
+ key: 'walrus'
+ production:
+ key: 'unicorn'
+ RUBY
+
+ add_to_config <<-RUBY
+ config.my_custom_config = config_for('custom', env: 'production')
+ RUBY
+ require "#{app_path}/config/environment"
+
+ assert_equal 'unicorn', Rails.application.config.my_custom_config['key']
+ end
+
+ test "api_only is false by default" do
+ app 'development'
+ refute Rails.application.config.api_only
+ end
+
+ test "api_only generator config is set when api_only is set" do
+ add_to_config <<-RUBY
+ config.api_only = true
+ RUBY
+ app 'development'
+
+ Rails.application.load_generators
+ assert Rails.configuration.api_only
+ end
+
+ test "debug_exception_response_format is :api by default if only_api is enabled" do
+ add_to_config <<-RUBY
+ config.api_only = true
+ RUBY
+ app 'development'
+
+ assert_equal :api, Rails.configuration.debug_exception_response_format
+ end
+
+ test "debug_exception_response_format can be override" do
+ add_to_config <<-RUBY
+ config.api_only = true
+ RUBY
+
+ app_file 'config/environments/development.rb', <<-RUBY
+ Rails.application.configure do
+ config.debug_exception_response_format = :default
+ end
+ RUBY
+
+ app 'development'
+
+ assert_equal :default, Rails.configuration.debug_exception_response_format
+ end
end
end
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..13f3250f5b 100644
--- a/railties/test/application/initializers/frameworks_test.rb
+++ b/railties/test/application/initializers/frameworks_test.rb
@@ -1,5 +1,4 @@
require "isolation/abstract_unit"
-require 'set'
module ApplicationTests
class FrameworksTest < ActiveSupport::TestCase
@@ -50,6 +49,17 @@ module ApplicationTests
assert_equal "test.rails", ActionMailer::Base.default_url_options[:host]
end
+ test "Default to HTTPS for ActionMailer URLs when force_ssl is on" do
+ app_file "config/environments/development.rb", <<-RUBY
+ Rails.application.configure do
+ config.force_ssl = true
+ end
+ RUBY
+
+ require "#{app_path}/config/environment"
+ assert_equal "https", ActionMailer::Base.default_url_options[:protocol]
+ end
+
test "includes url helpers as action methods" do
app_file "config/routes.rb", <<-RUBY
Rails.application.routes.draw do
@@ -129,6 +139,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 +216,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 +226,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/loading_test.rb b/railties/test/application/loading_test.rb
index 1027bca2c1..40abaf860d 100644
--- a/railties/test/application/loading_test.rb
+++ b/railties/test/application/loading_test.rb
@@ -116,11 +116,11 @@ class LoadingTest < ActiveSupport::TestCase
require "#{rails_root}/config/environment"
setup_ar!
- assert_equal [ActiveRecord::SchemaMigration], ActiveRecord::Base.descendants
+ assert_equal [ActiveRecord::SchemaMigration, ActiveRecord::InternalMetadata], ActiveRecord::Base.descendants
get "/load"
- assert_equal [ActiveRecord::SchemaMigration, Post], ActiveRecord::Base.descendants
+ assert_equal [ActiveRecord::SchemaMigration, ActiveRecord::InternalMetadata, Post], ActiveRecord::Base.descendants
get "/unload"
- assert_equal [ActiveRecord::SchemaMigration], ActiveRecord::Base.descendants
+ assert_equal [ActiveRecord::SchemaMigration, ActiveRecord::InternalMetadata], ActiveRecord::Base.descendants
end
test "initialize cant be called twice" do
@@ -169,6 +169,8 @@ class LoadingTest < ActiveSupport::TestCase
config.file_watcher = Class.new do
def initialize(*); end
def updated?; false; end
+ def execute; end
+ def execute_if_updated; false; end
end
RUBY
@@ -288,7 +290,7 @@ class LoadingTest < ActiveSupport::TestCase
extend Rack::Test::Methods
app_file "db/migrate/1_create_posts.rb", <<-MIGRATION
- class CreatePosts < ActiveRecord::Migration
+ class CreatePosts < ActiveRecord::Migration::Current
def change
create_table :posts do |t|
t.string :title, default: "TITLE"
@@ -304,7 +306,7 @@ class LoadingTest < ActiveSupport::TestCase
assert_equal "TITLE", last_response.body
app_file "db/migrate/2_add_body_to_posts.rb", <<-MIGRATION
- class AddBodyToPosts < ActiveRecord::Migration
+ class AddBodyToPosts < ActiveRecord::Migration::Current
def change
add_column :posts, :body, :text, default: "BODY"
end
diff --git a/railties/test/application/mailer_previews_test.rb b/railties/test/application/mailer_previews_test.rb
index e462d2c15e..643d876a26 100644
--- a/railties/test/application/mailer_previews_test.rb
+++ b/railties/test/application/mailer_previews_test.rb
@@ -31,7 +31,7 @@ module ApplicationTests
test "/rails/mailers is accessible with correct configuraiton" do
add_to_config "config.action_mailer.show_previews = true"
app("production")
- get "/rails/mailers"
+ get "/rails/mailers", {}, {"REMOTE_ADDR" => "4.2.42.42"}
assert_equal 200, last_response.status
end
diff --git a/railties/test/application/middleware/exceptions_test.rb b/railties/test/application/middleware/exceptions_test.rb
index 4906f9a1e8..7b4babb13b 100644
--- a/railties/test/application/middleware/exceptions_test.rb
+++ b/railties/test/application/middleware/exceptions_test.rb
@@ -48,7 +48,7 @@ module ApplicationTests
test "uses custom exceptions app" do
add_to_config <<-RUBY
config.exceptions_app = lambda do |env|
- [404, { "Content-Type" => "text/plain" }, ["YOU FAILED BRO"]]
+ [404, { "Content-Type" => "text/plain" }, ["YOU FAILED"]]
end
RUBY
@@ -56,7 +56,7 @@ module ApplicationTests
get "/foo"
assert_equal 404, last_response.status
- assert_equal "YOU FAILED BRO", last_response.body
+ assert_equal "YOU FAILED", last_response.body
end
test "url generation error when action_dispatch.show_exceptions is set raises an exception" do
@@ -67,7 +67,7 @@ module ApplicationTests
end
end
RUBY
-
+
app.config.action_dispatch.show_exceptions = true
get '/foo'
diff --git a/railties/test/application/middleware/sendfile_test.rb b/railties/test/application/middleware/sendfile_test.rb
index dc96480d6d..be86f1a3b8 100644
--- a/railties/test/application/middleware/sendfile_test.rb
+++ b/railties/test/application/middleware/sendfile_test.rb
@@ -61,7 +61,7 @@ module ApplicationTests
test "files handled by ActionDispatch::Static are handled by Rack::Sendfile" do
make_basic_app do |app|
app.config.action_dispatch.x_sendfile_header = 'X-Sendfile'
- app.config.serve_static_files = true
+ app.config.public_file_server.enabled = true
app.paths["public"] = File.join(rails_root, "public")
end
diff --git a/railties/test/application/middleware/session_test.rb b/railties/test/application/middleware/session_test.rb
index a8dc79d10a..f847e80471 100644
--- a/railties/test/application/middleware/session_test.rb
+++ b/railties/test/application/middleware/session_test.rb
@@ -20,12 +20,19 @@ module ApplicationTests
@app ||= Rails.application
end
- test "config.force_ssl sets cookie to secure only" do
+ test "config.force_ssl sets cookie to secure only by default" do
add_to_config "config.force_ssl = true"
require "#{app_path}/config/environment"
assert app.config.session_options[:secure], "Expected session to be marked as secure"
end
+ test "config.force_ssl doesn't set cookie to secure only when changed from default" do
+ add_to_config "config.force_ssl = true"
+ add_to_config "config.ssl_options = { secure_cookies: false }"
+ require "#{app_path}/config/environment"
+ assert !app.config.session_options[:secure]
+ end
+
test "session is not loaded if it's not used" do
make_basic_app
@@ -35,7 +42,7 @@ module ApplicationTests
flash[:notice] = "notice"
end
- render nothing: true
+ head :ok
end
end
@@ -60,7 +67,7 @@ module ApplicationTests
def write_session
session[:foo] = 1
- render nothing: true
+ head :ok
end
def read_session
@@ -101,7 +108,7 @@ module ApplicationTests
def write_cookie
cookies[:foo] = '1'
- render nothing: true
+ head :ok
end
def read_cookie
@@ -139,7 +146,7 @@ module ApplicationTests
class FooController < ActionController::Base
def write_session
session[:foo] = 1
- render nothing: true
+ head :ok
end
def read_session
@@ -184,7 +191,7 @@ module ApplicationTests
class FooController < ActionController::Base
def write_session
session[:foo] = 1
- render nothing: true
+ head :ok
end
def read_session
@@ -234,12 +241,12 @@ module ApplicationTests
def write_raw_session
# {"session_id"=>"1965d95720fffc123941bdfb7d2e6870", "foo"=>1}
cookies[:_myapp_session] = "BAh7B0kiD3Nlc3Npb25faWQGOgZFRkkiJTE5NjVkOTU3MjBmZmZjMTIzOTQxYmRmYjdkMmU2ODcwBjsAVEkiCGZvbwY7AEZpBg==--315fb9931921a87ae7421aec96382f0294119749"
- render nothing: true
+ head :ok
end
def write_session
session[:foo] = session[:foo] + 1
- render nothing: true
+ head :ok
end
def read_session
@@ -293,12 +300,12 @@ module ApplicationTests
def write_raw_session
# {"session_id"=>"1965d95720fffc123941bdfb7d2e6870", "foo"=>1}
cookies[:_myapp_session] = "BAh7B0kiD3Nlc3Npb25faWQGOgZFRkkiJTE5NjVkOTU3MjBmZmZjMTIzOTQxYmRmYjdkMmU2ODcwBjsAVEkiCGZvbwY7AEZpBg==--315fb9931921a87ae7421aec96382f0294119749"
- render nothing: true
+ head :ok
end
def write_session
session[:foo] = session[:foo] + 1
- render nothing: true
+ head :ok
end
def read_session
diff --git a/railties/test/application/middleware/static_test.rb b/railties/test/application/middleware/static_test.rb
index 121c5d3321..1246e20d94 100644
--- a/railties/test/application/middleware/static_test.rb
+++ b/railties/test/application/middleware/static_test.rb
@@ -26,5 +26,43 @@ module ApplicationTests
assert_not last_response.headers.has_key?('Cache-Control'), "Cache-Control should not be set"
end
+
+ test "headers for static files are configurable" do
+ app_file "public/about.html", 'static'
+ add_to_config <<-CONFIG
+ config.public_file_server.headers = {
+ "Access-Control-Allow-Origin" => "http://rubyonrails.org",
+ "Cache-Control" => "public, max-age=60"
+ }
+ CONFIG
+
+ require "#{app_path}/config/environment"
+
+ get '/about.html'
+
+ assert_equal 'http://rubyonrails.org', last_response.headers["Access-Control-Allow-Origin"]
+ assert_equal 'public, max-age=60', last_response.headers["Cache-Control"]
+ end
+
+ test "public_file_server.index_name defaults to 'index'" do
+ app_file "public/index.html", "/index.html"
+
+ require "#{app_path}/config/environment"
+
+ get '/'
+
+ assert_equal "/index.html\n", last_response.body
+ end
+
+ test "public_file_server.index_name configurable" do
+ app_file "public/other-index.html", "/other-index.html"
+ add_to_config "config.public_file_server.index_name = 'other-index'"
+
+ require "#{app_path}/config/environment"
+
+ get '/'
+
+ assert_equal "/other-index.html\n", last_response.body
+ end
end
end
diff --git a/railties/test/application/middleware_test.rb b/railties/test/application/middleware_test.rb
index 04bd19784a..1434522cce 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",
@@ -43,7 +43,32 @@ module ApplicationTests
"ActionDispatch::Cookies",
"ActionDispatch::Session::CookieStore",
"ActionDispatch::Flash",
- "ActionDispatch::ParamsParser",
+ "Rack::Head",
+ "Rack::ConditionalGet",
+ "Rack::ETag"
+ ], 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",
"Rack::Head",
"Rack::ConditionalGet",
"Rack::ETag"
@@ -94,27 +119,44 @@ 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
- add_to_config "config.serve_static_files = false"
+ test "removes static asset server if public_file_server.enabled is disabled" do
+ add_to_config "config.public_file_server.enabled = false"
boot!
assert !middleware.include?("ActionDispatch::Static")
end
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..1304e73378 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
@@ -49,11 +49,63 @@ module ApplicationTests
db_create_and_drop database_url_db_name
end
+ def with_database_existing
+ Dir.chdir(app_path) do
+ set_database_url
+ `bin/rake db:create`
+ yield
+ `bin/rake db:drop`
+ end
+ end
+
+ test 'db:create failure because database exists' do
+ with_database_existing do
+ output = `bin/rake db:create 2>&1`
+ assert_match(/already exists/, output)
+ assert_equal 0, $?.exitstatus
+ end
+ end
+
+ def with_bad_permissions
+ Dir.chdir(app_path) do
+ set_database_url
+ FileUtils.chmod("-w", "db")
+ yield
+ FileUtils.chmod("+w", "db")
+ end
+ end
+
+ test 'db:create failure because bad permissions' do
+ with_bad_permissions do
+ output = `bin/rake db:create 2>&1`
+ assert_match(/Couldn't create database/, output)
+ assert_equal 1, $?.exitstatus
+ end
+ end
+
+ test 'db:drop failure because database does not exist' do
+ Dir.chdir(app_path) do
+ output = `bin/rake db:drop:_unsafe --trace 2>&1`
+ assert_match(/does not exist/, output)
+ assert_equal 0, $?.exitstatus
+ end
+ end
+
+ test 'db:drop failure because bad permissions' do
+ with_database_existing do
+ with_bad_permissions do
+ output = `bin/rake db:drop 2>&1`
+ assert_match(/Couldn't drop/, output)
+ assert_equal 1, $?.exitstatus
+ end
+ end
+ end
+
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 +124,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 +142,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 +164,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 +173,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 +199,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)
@@ -170,14 +222,14 @@ module ApplicationTests
assert_equal '["posts"]', list_tables[]
`bin/rake db:schema:load`
- assert_equal '["posts", "comments", "schema_migrations"]', list_tables[]
+ assert_equal '["posts", "comments", "schema_migrations", "active_record_internal_metadatas"]', list_tables[]
app_file 'db/structure.sql', <<-SQL
CREATE TABLE "users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255));
SQL
`bin/rake db:structure:load`
- assert_equal '["posts", "comments", "schema_migrations", "users"]', list_tables[]
+ assert_equal '["posts", "comments", "schema_migrations", "active_record_internal_metadatas", "users"]', list_tables[]
end
end
@@ -211,8 +263,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 +300,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/framework_test.rb b/railties/test/application/rake/framework_test.rb
new file mode 100644
index 0000000000..ec57af79f6
--- /dev/null
+++ b/railties/test/application/rake/framework_test.rb
@@ -0,0 +1,48 @@
+require "isolation/abstract_unit"
+require "active_support/core_ext/string/strip"
+
+module ApplicationTests
+ module RakeTests
+ class FrameworkTest < ActiveSupport::TestCase
+ include ActiveSupport::Testing::Isolation
+
+ def setup
+ build_app
+ boot_rails
+ FileUtils.rm_rf("#{app_path}/config/environments")
+ end
+
+ def teardown
+ teardown_app
+ end
+
+ def load_tasks
+ require 'rake'
+ require 'rdoc/task'
+ require 'rake/testtask'
+
+ Rails.application.load_tasks
+ end
+
+ test 'requiring the rake task should not define method .app_generator on Object' do
+ require "#{app_path}/config/environment"
+
+ load_tasks
+
+ assert_raise NameError do
+ Object.method(:app_generator)
+ end
+ end
+
+ test 'requiring the rake task should not define method .invoke_from_app_generator on Object' do
+ require "#{app_path}/config/environment"
+
+ load_tasks
+
+ assert_raise NameError do
+ Object.method(:invoke_from_app_generator)
+ 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..580ed269cb 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
+ class AMigration < ActiveRecord::Migration::Current
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,54 +131,78 @@ 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)
end
end
+ test 'running migrations with not timestamp head migration files' do
+ Dir.chdir(app_path) do
+
+ app_file "db/migrate/1_one_migration.rb", <<-MIGRATION
+ class OneMigration < ActiveRecord::Migration::Current
+ end
+ MIGRATION
+
+ app_file "db/migrate/02_two_migration.rb", <<-MIGRATION
+ class TwoMigration < ActiveRecord::Migration::Current
+ end
+ MIGRATION
+
+ `bin/rake db:migrate`
+
+ output = `bin/rake db:migrate:status`
+
+ assert_match(/up\s+001\s+One migration/, output)
+ assert_match(/up\s+002\s+Two migration/, output)
+ end
+ end
+
test 'schema generation when dump_schema_after_migration is set' do
add_to_config('config.active_record.dump_schema_after_migration = false')
Dir.chdir(app_path) do
- `rails generate model book title:string;
- bundle exec rake db:migrate`
+ `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 +211,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..639875dd6e 100644
--- a/railties/test/application/rake_test.rb
+++ b/railties/test/application/rake_test.rb
@@ -1,4 +1,3 @@
-# coding:utf-8
require "isolation/abstract_unit"
require "active_support/core_ext/string/strip"
@@ -25,6 +24,26 @@ module ApplicationTests
assert $task_loaded
end
+ def test_the_test_rake_task_is_protected_when_previous_migration_was_production
+ Dir.chdir(app_path) do
+ output = `bin/rails generate model product name:string;
+ env RAILS_ENV=production bin/rake db:create db:migrate;
+ env RAILS_ENV=production bin/rake db:test:prepare test 2>&1`
+
+ assert_match(/ActiveRecord::ProtectedEnvironmentError/, output)
+ end
+ end
+
+ def test_not_protected_when_previous_migration_was_not_production
+ Dir.chdir(app_path) do
+ output = `bin/rails generate model product name:string;
+ env RAILS_ENV=test bin/rake db:create db:migrate;
+ env RAILS_ENV=test bin/rake db:test:prepare test 2>&1`
+
+ refute_match(/ActiveRecord::ProtectedEnvironmentError/, output)
+ end
+ end
+
def test_environment_is_required_in_rake_tasks
app_file "config/environment.rb", <<-RUBY
SuperMiddleware = Struct.new(:app)
@@ -36,7 +55,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 +70,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 +91,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 +112,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` }
+ assert_match "Code LOC: 14 Test LOC: 0 Code to Test Ratio: 1:0.0",
+ Dir.chdir(app_path){ `bin/rake stats` }
end
def test_rake_routes_calls_the_route_inspector
@@ -110,7 +129,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 +142,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 +152,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 +170,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 +193,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;
+ RAILS_ENV=test 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;
+ RAILS_ENV=test 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;
+ RAILS_ENV=test bin/rake db:migrate test`
end
assert_match(/7 runs, 12 assertions, 0 failures, 0 errors/, output)
@@ -210,9 +248,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 +258,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 +268,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 +277,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 +287,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 +318,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/routing_test.rb b/railties/test/application/routing_test.rb
index cbada6be97..0777714d35 100644
--- a/railties/test/application/routing_test.rb
+++ b/railties/test/application/routing_test.rb
@@ -21,6 +21,12 @@ module ApplicationTests
assert_equal 200, last_response.status
end
+ test "rails/info in development" do
+ app("development")
+ get "/rails/info"
+ assert_equal 302, last_response.status
+ end
+
test "rails/info/routes in development" do
app("development")
get "/rails/info/routes"
@@ -63,6 +69,12 @@ module ApplicationTests
assert_equal 404, last_response.status
end
+ test "rails/info in production" do
+ app("production")
+ get "/rails/info"
+ assert_equal 404, last_response.status
+ end
+
test "rails/info/routes in production" do
app("production")
get "/rails/info/routes"
diff --git a/railties/test/application/runner_test.rb b/railties/test/application/runner_test.rb
index 6595c40f8b..9f15ce5e85 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,32 @@ 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_runner_detects_syntax_errors
+ Dir.chdir(app_path) { `bin/rails runner "puts 'hello world" 2>&1` }
+ refute $?.success?
+ end
+
+ def test_runner_detects_bad_script_name
+ Dir.chdir(app_path) { `bin/rails runner "iuiqwiourowe" 2>&1` }
+ refute $?.success?
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..bb6c6574c5 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,249 @@ 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_generated_controller_works_with_rails_test
+ create_controller
+ 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_more_than_one_line_filter
+ app_file 'test/models/post_test.rb', <<-RUBY
+ require 'test_helper'
+
+ class PostTest < ActiveSupport::TestCase
+ test "first filter" do
+ puts 'PostTest:FirstFilter'
+ assert true
+ end
+
+ test "second filter" do
+ puts 'PostTest:SecondFilter'
+ assert true
+ end
+
+ test "test line filter does not run this" do
+ assert true
+ end
+ end
+ RUBY
+
+ run_test_command('test/models/post_test.rb:4:9').tap do |output|
+ assert_match 'PostTest:FirstFilter', output
+ assert_match 'PostTest:SecondFilter', output
+ assert_match '2 runs, 2 assertions', output
+ end
+ end
+
+ def test_more_than_one_line_filter_with_multiple_files
+ app_file 'test/models/account_test.rb', <<-RUBY
+ require 'test_helper'
+
+ class AccountTest < ActiveSupport::TestCase
+ test "first filter" do
+ puts 'AccountTest:FirstFilter'
+ assert true
+ end
+
+ test "second filter" do
+ puts 'AccountTest:SecondFilter'
+ assert true
+ end
+
+ test "line filter does not run this" do
+ assert true
+ end
+ end
+ RUBY
+
+ app_file 'test/models/post_test.rb', <<-RUBY
+ require 'test_helper'
+
+ class PostTest < ActiveSupport::TestCase
+ test "first filter" do
+ puts 'PostTest:FirstFilter'
+ assert true
+ end
+
+ test "second filter" do
+ puts 'PostTest:SecondFilter'
+ assert true
+ end
+
+ test "line filter does not run this" do
+ assert true
+ end
+ end
+ RUBY
+
+ run_test_command('test/models/account_test.rb:4:9 test/models/post_test:4:9').tap do |output|
+ assert_match 'AccountTest:FirstFilter', output
+ assert_match 'AccountTest:SecondFilter', output
+ assert_match 'PostTest:FirstFilter', output
+ assert_match 'PostTest:SecondFilter', output
+ assert_match '4 runs, 4 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
+
+ def test_output_inline_by_default
+ create_test_file :models, 'post', pass: false
+
+ output = run_test_command('test/models/post_test.rb')
+ expect = %r{Running:\n\nPostTest\nF\n\nFailure:\nPostTest#test_truth:\nwups!\n\nbin/rails test test/models/post_test.rb:6\n\n\n\n}
+ assert_match expect, output
+ end
+
+ def test_only_inline_failure_output
+ create_test_file :models, 'post', pass: false
+
+ output = run_test_command('test/models/post_test.rb')
+ assert_match %r{Finished in.*\n\n1 runs, 1 assertions}, output
+ end
+
+ def test_fail_fast
+ create_test_file :models, 'post', pass: false
+
+ assert_match(/Interrupt/,
+ capture(:stderr) { run_test_command('test/models/post_test.rb --fail-fast') })
+ end
+
+ def test_raise_error_when_specified_file_does_not_exist
+ error = capture(:stderr) { run_test_command('test/not_exists.rb') }
+ assert_match(%r{cannot load such file.+test/not_exists\.rb}, error)
+ end
+
+ def test_pass_TEST_env_on_rake_test
+ create_test_file :models, 'account'
+ create_test_file :models, 'post', pass: false
+
+ output = Dir.chdir(app_path) { `bin/rake test TEST=test/models/post_test.rb` }
+
+ assert_match "PostTest", output, "passing TEST= should run selected test"
+ assert_no_match "AccountTest", output, "passing TEST= should only run selected test"
+ assert_match '1 runs, 1 assertions', output
end
private
@@ -284,18 +496,42 @@ 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
- def create_test_file(path = :unit, name = 'test')
+ def create_test_file(path = :unit, name = 'test', pass: true)
app_file "test/#{path}/#{name}_test.rb", <<-RUBY
require 'test_helper'
class #{name.camelize}Test < ActiveSupport::TestCase
def test_truth
puts "#{name.camelize}Test"
- assert true
+ assert #{pass}, 'wups!'
+ end
+ end
+ 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
@@ -307,8 +543,12 @@ module ApplicationTests
run_migration
end
+ def create_controller
+ script 'generate controller admin/dashboard index'
+ 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/code_statistics_calculator_test.rb b/railties/test/code_statistics_calculator_test.rb
index 46445a001a..cecc3908b3 100644
--- a/railties/test/code_statistics_calculator_test.rb
+++ b/railties/test/code_statistics_calculator_test.rb
@@ -299,6 +299,22 @@ class Animal
assert_equal 0, @code_statistics_calculator.methods
end
+ test 'count rake tasks' do
+ code = <<-'CODE'
+ task :test_task do
+ puts 'foo'
+ end
+
+ CODE
+
+ @code_statistics_calculator.add_by_io(StringIO.new(code), :rake)
+
+ assert_equal 4, @code_statistics_calculator.lines
+ assert_equal 3, @code_statistics_calculator.code_lines
+ assert_equal 0, @code_statistics_calculator.classes
+ assert_equal 0, @code_statistics_calculator.methods
+ end
+
private
def temp_file(name, content)
dir = File.expand_path '../fixtures/tmp', __FILE__
diff --git a/railties/test/commands/dbconsole_test.rb b/railties/test/commands/dbconsole_test.rb
index 7950ed6aa7..a5aa6c14a2 100644
--- a/railties/test/commands/dbconsole_test.rb
+++ b/railties/test/commands/dbconsole_test.rb
@@ -113,19 +113,19 @@ class Rails::DBConsoleTest < ActiveSupport::TestCase
end
def test_mysql
- start(adapter: 'mysql', database: 'db')
+ start(adapter: 'mysql2', database: 'db')
assert !aborted
assert_equal [%w[mysql mysql5], 'db'], dbconsole.find_cmd_and_exec_args
end
def test_mysql_full
- start(adapter: 'mysql', database: 'db', host: 'locahost', port: 1234, socket: 'socket', username: 'user', password: 'qwerty', encoding: 'UTF-8')
+ start(adapter: 'mysql2', database: 'db', host: 'locahost', port: 1234, socket: 'socket', username: 'user', password: 'qwerty', encoding: 'UTF-8')
assert !aborted
assert_equal [%w[mysql mysql5], '--host=locahost', '--port=1234', '--socket=socket', '--user=user', '--default-character-set=UTF-8', '-p', 'db'], dbconsole.find_cmd_and_exec_args
end
def test_mysql_include_password
- start({adapter: 'mysql', database: 'db', username: 'user', password: 'qwerty'}, ['-p'])
+ start({adapter: 'mysql2', database: 'db', username: 'user', password: 'qwerty'}, ['-p'])
assert !aborted
assert_equal [%w[mysql mysql5], '--user=user', '--password=qwerty', 'db'], dbconsole.find_cmd_and_exec_args
end
diff --git a/railties/test/commands/dev_cache_test.rb b/railties/test/commands/dev_cache_test.rb
new file mode 100644
index 0000000000..1b7a72e7fc
--- /dev/null
+++ b/railties/test/commands/dev_cache_test.rb
@@ -0,0 +1,32 @@
+require_relative '../isolation/abstract_unit'
+
+module CommandsTests
+ class DevCacheTest < ActiveSupport::TestCase
+ include ActiveSupport::Testing::Isolation
+
+ def setup
+ build_app
+ end
+
+ def teardown
+ teardown_app
+ end
+
+ test 'dev:cache creates file and outputs message' do
+ Dir.chdir(app_path) do
+ output = `rails dev:cache`
+ assert File.exist?('tmp/caching-dev.txt')
+ assert_match(%r{Development mode is now being cached}, output)
+ end
+ end
+
+ test 'dev:cache deletes file and outputs message' do
+ Dir.chdir(app_path) do
+ `rails dev:cache` # Create caching file.
+ output = `rails dev:cache` # Delete caching file.
+ assert_not File.exist?('tmp/caching-dev.txt')
+ assert_match(%r{Development mode is no longer being cached}, output)
+ end
+ end
+ end
+end
diff --git a/railties/test/commands/server_test.rb b/railties/test/commands/server_test.rb
index ba688f1e9e..3be4a74f74 100644
--- a/railties/test/commands/server_test.rb
+++ b/railties/test/commands/server_test.rb
@@ -44,6 +44,29 @@ class Rails::ServerTest < ActiveSupport::TestCase
end
end
+ def test_environment_with_port
+ switch_env "PORT", "1234" do
+ server = Rails::Server.new
+ assert_equal 1234, server.options[:Port]
+ 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..a1a17d90d8 100644
--- a/railties/test/generators/actions_test.rb
+++ b/railties/test/generators/actions_test.rb
@@ -1,7 +1,6 @@
require 'generators/generators_test_helper'
require 'rails/generators/rails/app/app_generator'
require 'env_helpers'
-require 'mocha/setup' # FIXME: stop using mocha
class ActionsTest < Rails::Generators::TestCase
include GeneratorsTestHelper
@@ -45,6 +44,23 @@ 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_add_source_with_block_adds_source_to_gemfile_after_gem
+ run_generator
+ action :gem, 'will-paginate'
+ action :add_source, 'http://gems.github.com' do
+ gem 'rspec-rails'
+ end
+ assert_file 'Gemfile', /gem 'will-paginate'\nsource '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 +156,15 @@ 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
+ assert_called_with(generator, :run, ['git init']) 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: '.'
+ assert_called_with(generator, :run, [ ["git rm README"], ["git add ."] ]) do
+ action :git, rm: 'README', add: '.'
+ end
end
def test_vendor_should_write_data_to_file_in_vendor
@@ -170,46 +188,53 @@ 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'
+ assert_called_with(generator, :run_ruby_script, ['bin/rails generate model MyModel', verbose: false]) 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'
+ assert_called_with(generator, :run, ["rake log:clear RAILS_ENV=development", verbose: false]) 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'
+ assert_called_with(generator, :run, ['rake log:clear RAILS_ENV=production', verbose: false]) 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'
+ assert_called_with(generator, :run, ['rake log:clear RAILS_ENV=production', verbose: false]) 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'
+ assert_called_with(generator, :run, ['rake log:clear RAILS_ENV=production', verbose: false]) 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
+ assert_called_with(generator, :run, ["sudo rake log:clear RAILS_ENV=development", verbose: false]) 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!
+ assert_called_with(generator, :run, ['capify .', verbose: false]) do
+ action :capify!
+ end
end
def test_route_should_add_data_to_the_routes_block_in_config_routes
@@ -219,6 +244,21 @@ class ActionsTest < Rails::Generators::TestCase
assert_file 'config/routes.rb', /#{Regexp.escape(route_command)}/
end
+ def test_route_should_be_idempotent
+ run_generator
+ route_path = File.expand_path('config/routes.rb', destination_root)
+
+ # runs first time, not asserting
+ action :route, "root 'welcome#index'"
+ content_1 = File.read(route_path)
+
+ # runs second time
+ action :route, "root 'welcome#index'"
+ content_2 = File.read(route_path)
+
+ assert_equal content_1, content_2
+ end
+
def test_route_should_add_data_with_an_new_line
run_generator
action :route, "root 'welcome#index'"
@@ -230,7 +270,14 @@ class ActionsTest < Rails::Generators::TestCase
content.gsub!(/^\n/, '')
File.open(route_path, "wb") { |file| file.write(content) }
- assert_file "config/routes.rb", /\.routes\.draw do\n root 'welcome#index'\nend\n\z/
+
+ routes = <<-F
+Rails.application.routes.draw do
+ root 'welcome#index'
+end
+F
+
+ assert_file "config/routes.rb", routes
action :route, "resources :product_lines"
@@ -245,15 +292,17 @@ 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")
+ assert_called(Rails::Generators::AppGenerator, :source_root, times: 2, returns: destination_root) 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")
+ assert_called(Rails::Generators::AppGenerator, :source_root, times: 2, returns: destination_root) 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..2c24a6e46a
--- /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 'web-console'/, content)
+ assert_match(/# gem 'jbuilder'/, 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
+ config/initializers/request_forgery_protection.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..e5480180ce 100644
--- a/railties/test/generators/app_generator_test.rb
+++ b/railties/test/generators/app_generator_test.rb
@@ -1,7 +1,6 @@
require 'generators/generators_test_helper'
require 'rails/generators/rails/app/app_generator'
require 'generators/shared_generator_tests'
-require 'mocha/setup' # FIXME: stop using mocha
DEFAULT_APP_FILES = %w(
.gitignore
@@ -44,6 +43,7 @@ DEFAULT_APP_FILES = %w(
vendor/assets
vendor/assets/stylesheets
vendor/assets/javascripts
+ tmp
tmp/cache
tmp/cache/assets
)
@@ -116,35 +116,33 @@ class AppGeneratorTest < Rails::Generators::TestCase
run_generator [app_root]
- Rails.application.config.root = app_moved_root
- Rails.application.class.stubs(:name).returns("Myapp")
- Rails.application.stubs(:is_a?).returns(Rails::Application)
+ stub_rails_application(app_moved_root) do
+ Rails.application.stub(:is_a?, -> *args { Rails::Application }) do
+ FileUtils.mv(app_root, app_moved_root)
- FileUtils.mv(app_root, app_moved_root)
+ # make sure we are in correct dir
+ FileUtils.cd(app_moved_root)
- # make sure we are in correct dir
- FileUtils.cd(app_moved_root)
-
- generator = Rails::Generators::AppGenerator.new ["rails"], { with_dispatchers: true },
- destination_root: app_moved_root, shell: @shell
- generator.send(:app_const)
- quietly { generator.send(:update_config_files) }
- assert_file "myapp_moved/config/environment.rb", /Rails\.application\.initialize!/
- assert_file "myapp_moved/config/initializers/session_store.rb", /_myapp_session/
+ generator = Rails::Generators::AppGenerator.new ["rails"], { with_dispatchers: true },
+ destination_root: app_moved_root, shell: @shell
+ generator.send(:app_const)
+ quietly { generator.send(:update_config_files) }
+ assert_file "myapp_moved/config/environment.rb", /Rails\.application\.initialize!/
+ assert_file "myapp_moved/config/initializers/session_store.rb", /_myapp_session/
+ end
+ end
end
def test_rails_update_generates_correct_session_key
app_root = File.join(destination_root, 'myapp')
run_generator [app_root]
- Rails.application.config.root = app_root
- Rails.application.class.stubs(:name).returns("Myapp")
- Rails.application.stubs(:is_a?).returns(Rails::Application)
-
- generator = Rails::Generators::AppGenerator.new ["rails"], { with_dispatchers: true }, destination_root: app_root, shell: @shell
- generator.send(:app_const)
- quietly { generator.send(:update_config_files) }
- assert_file "myapp/config/initializers/session_store.rb", /_myapp_session/
+ stub_rails_application(app_root) do
+ generator = Rails::Generators::AppGenerator.new ["rails"], { with_dispatchers: true }, destination_root: app_root, shell: @shell
+ generator.send(:app_const)
+ quietly { generator.send(:update_config_files) }
+ assert_file "myapp/config/initializers/session_store.rb", /_myapp_session/
+ end
end
def test_new_application_use_json_serialzier
@@ -153,18 +151,22 @@ class AppGeneratorTest < Rails::Generators::TestCase
assert_file("config/initializers/cookies_serializer.rb", /Rails\.application\.config\.action_dispatch\.cookies_serializer = :json/)
end
+ def test_new_application_not_include_api_initializers
+ run_generator
+
+ assert_no_file 'config/initializers/cors.rb'
+ end
+
def test_rails_update_keep_the_cookie_serializer_if_it_is_already_configured
app_root = File.join(destination_root, 'myapp')
run_generator [app_root]
- Rails.application.config.root = app_root
- Rails.application.class.stubs(:name).returns("Myapp")
- Rails.application.stubs(:is_a?).returns(Rails::Application)
-
- generator = Rails::Generators::AppGenerator.new ["rails"], { with_dispatchers: true }, destination_root: app_root, shell: @shell
- generator.send(:app_const)
- quietly { generator.send(:update_config_files) }
- assert_file("#{app_root}/config/initializers/cookies_serializer.rb", /Rails\.application\.config\.action_dispatch\.cookies_serializer = :json/)
+ stub_rails_application(app_root) do
+ generator = Rails::Generators::AppGenerator.new ["rails"], { with_dispatchers: true }, destination_root: app_root, shell: @shell
+ generator.send(:app_const)
+ quietly { generator.send(:update_config_files) }
+ assert_file("#{app_root}/config/initializers/cookies_serializer.rb", /Rails\.application\.config\.action_dispatch\.cookies_serializer = :json/)
+ end
end
def test_rails_update_does_not_create_callback_terminator_initializer
@@ -173,14 +175,12 @@ class AppGeneratorTest < Rails::Generators::TestCase
FileUtils.rm("#{app_root}/config/initializers/callback_terminator.rb")
- Rails.application.config.root = app_root
- Rails.application.class.stubs(:name).returns("Myapp")
- Rails.application.stubs(:is_a?).returns(Rails::Application)
-
- generator = Rails::Generators::AppGenerator.new ["rails"], { with_dispatchers: true }, destination_root: app_root, shell: @shell
- generator.send(:app_const)
- quietly { generator.send(:update_config_files) }
- assert_no_file "#{app_root}/config/initializers/callback_terminator.rb"
+ stub_rails_application(app_root) do
+ generator = Rails::Generators::AppGenerator.new ["rails"], { with_dispatchers: true }, destination_root: app_root, shell: @shell
+ generator.send(:app_const)
+ quietly { generator.send(:update_config_files) }
+ assert_no_file "#{app_root}/config/initializers/callback_terminator.rb"
+ end
end
def test_rails_update_does_not_remove_callback_terminator_initializer_if_already_present
@@ -189,14 +189,12 @@ class AppGeneratorTest < Rails::Generators::TestCase
FileUtils.touch("#{app_root}/config/initializers/callback_terminator.rb")
- Rails.application.config.root = app_root
- Rails.application.class.stubs(:name).returns("Myapp")
- Rails.application.stubs(:is_a?).returns(Rails::Application)
-
- generator = Rails::Generators::AppGenerator.new ["rails"], { with_dispatchers: true }, destination_root: app_root, shell: @shell
- generator.send(:app_const)
- quietly { generator.send(:update_config_files) }
- assert_file "#{app_root}/config/initializers/callback_terminator.rb"
+ stub_rails_application(app_root) do
+ generator = Rails::Generators::AppGenerator.new ["rails"], { with_dispatchers: true }, destination_root: app_root, shell: @shell
+ generator.send(:app_const)
+ quietly { generator.send(:update_config_files) }
+ assert_file "#{app_root}/config/initializers/callback_terminator.rb"
+ end
end
def test_rails_update_set_the_cookie_serializer_to_marchal_if_it_is_not_already_configured
@@ -205,14 +203,12 @@ class AppGeneratorTest < Rails::Generators::TestCase
FileUtils.rm("#{app_root}/config/initializers/cookies_serializer.rb")
- Rails.application.config.root = app_root
- Rails.application.class.stubs(:name).returns("Myapp")
- Rails.application.stubs(:is_a?).returns(Rails::Application)
-
- generator = Rails::Generators::AppGenerator.new ["rails"], { with_dispatchers: true }, destination_root: app_root, shell: @shell
- generator.send(:app_const)
- quietly { generator.send(:update_config_files) }
- assert_file("#{app_root}/config/initializers/cookies_serializer.rb", /Rails\.application\.config\.action_dispatch\.cookies_serializer = :marshal/)
+ stub_rails_application(app_root) do
+ generator = Rails::Generators::AppGenerator.new ["rails"], { with_dispatchers: true }, destination_root: app_root, shell: @shell
+ generator.send(:app_const)
+ quietly { generator.send(:update_config_files) }
+ assert_file("#{app_root}/config/initializers/cookies_serializer.rb", /Rails\.application\.config\.action_dispatch\.cookies_serializer = :marshal/)
+ end
end
def test_rails_update_does_not_create_active_record_belongs_to_required_by_default
@@ -221,14 +217,12 @@ class AppGeneratorTest < Rails::Generators::TestCase
FileUtils.rm("#{app_root}/config/initializers/active_record_belongs_to_required_by_default.rb")
- Rails.application.config.root = app_root
- Rails.application.class.stubs(:name).returns("Myapp")
- Rails.application.stubs(:is_a?).returns(Rails::Application)
-
- generator = Rails::Generators::AppGenerator.new ["rails"], { with_dispatchers: true }, destination_root: app_root, shell: @shell
- generator.send(:app_const)
- quietly { generator.send(:update_config_files) }
- assert_no_file "#{app_root}/config/initializers/active_record_belongs_to_required_by_default.rb"
+ stub_rails_application(app_root) do
+ generator = Rails::Generators::AppGenerator.new ["rails"], { with_dispatchers: true }, destination_root: app_root, shell: @shell
+ generator.send(:app_const)
+ quietly { generator.send(:update_config_files) }
+ assert_no_file "#{app_root}/config/initializers/active_record_belongs_to_required_by_default.rb"
+ end
end
def test_rails_update_does_not_remove_active_record_belongs_to_required_by_default_if_already_present
@@ -237,14 +231,12 @@ class AppGeneratorTest < Rails::Generators::TestCase
FileUtils.touch("#{app_root}/config/initializers/active_record_belongs_to_required_by_default.rb")
- Rails.application.config.root = app_root
- Rails.application.class.stubs(:name).returns("Myapp")
- Rails.application.stubs(:is_a?).returns(Rails::Application)
-
- generator = Rails::Generators::AppGenerator.new ["rails"], { with_dispatchers: true }, destination_root: app_root, shell: @shell
- generator.send(:app_const)
- quietly { generator.send(:update_config_files) }
- assert_file "#{app_root}/config/initializers/active_record_belongs_to_required_by_default.rb"
+ stub_rails_application(app_root) do
+ generator = Rails::Generators::AppGenerator.new ["rails"], { with_dispatchers: true }, destination_root: app_root, shell: @shell
+ generator.send(:app_const)
+ quietly { generator.send(:update_config_files) }
+ assert_file "#{app_root}/config/initializers/active_record_belongs_to_required_by_default.rb"
+ end
end
def test_application_names_are_not_singularized
@@ -278,7 +270,7 @@ class AppGeneratorTest < Rails::Generators::TestCase
if defined?(JRUBY_VERSION)
assert_gem "activerecord-jdbcmysql-adapter"
else
- assert_gem "mysql2"
+ assert_gem "mysql2", "'>= 0.3.18', '< 0.5'"
end
end
@@ -293,7 +285,7 @@ class AppGeneratorTest < Rails::Generators::TestCase
if defined?(JRUBY_VERSION)
assert_gem "activerecord-jdbcpostgresql-adapter"
else
- assert_gem "pg"
+ assert_gem "pg", "'~> 0.18'"
end
end
@@ -348,6 +340,7 @@ class AppGeneratorTest < Rails::Generators::TestCase
run_generator [destination_root, "--skip-active-record"]
assert_no_file "config/database.yml"
assert_no_file "config/initializers/active_record_belongs_to_required_by_default.rb"
+ assert_no_file "app/models/application_record.rb"
assert_file "config/application.rb", /#\s+require\s+["']active_record\/railtie["']/
assert_file "test/test_helper.rb" do |helper_content|
assert_no_match(/fixtures :all/, helper_content)
@@ -368,6 +361,13 @@ class AppGeneratorTest < Rails::Generators::TestCase
end
end
+ def test_generator_has_assets_gems
+ run_generator
+
+ assert_gem 'sass-rails'
+ assert_gem 'uglifier'
+ end
+
def test_generator_if_skip_sprockets_is_given
run_generator [destination_root, "--skip-sprockets"]
assert_no_file "config/initializers/assets.rb"
@@ -389,6 +389,14 @@ class AppGeneratorTest < Rails::Generators::TestCase
end
end
+ def test_generator_if_skip_action_cable_is_given
+ run_generator [destination_root, "--skip-action-cable"]
+ assert_file "config/application.rb", /#\s+require\s+["']action_cable\/engine["']/
+ assert_no_file "config/redis/cable.yml"
+ assert_no_file "app/assets/javascripts/cable.coffee"
+ assert_no_file "app/channels"
+ end
+
def test_inclusion_of_javascript_runtime
run_generator
if defined?(JRUBY_VERSION)
@@ -455,13 +463,15 @@ class AppGeneratorTest < Rails::Generators::TestCase
end
def test_usage_read_from_file
- File.expects(:read).returns("USAGE FROM FILE")
- assert_equal "USAGE FROM FILE", Rails::Generators::AppGenerator.desc
+ assert_called(File, :read, returns: "USAGE FROM FILE") do
+ assert_equal "USAGE FROM FILE", Rails::Generators::AppGenerator.desc
+ end
end
def test_default_usage
- Rails::Generators::AppGenerator.expects(:usage_path).returns(nil)
- assert_match(/Create rails files for app generator/, Rails::Generators::AppGenerator.desc)
+ assert_called(Rails::Generators::AppGenerator, :usage_path, returns: nil) do
+ assert_match(/Create rails files for app generator/, Rails::Generators::AppGenerator.desc)
+ end
end
def test_default_namespace
@@ -498,7 +508,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,8 +526,8 @@ 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_no_match(/gem 'web-console', '~> 2.0'/, content)
+ assert_match(/gem 'web-console',\s+github: 'rails\/web-console'/, content)
+ assert_no_match(/gem 'web-console', '~> 3.0'/, content)
end
end
@@ -525,8 +535,8 @@ 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_no_match(/gem 'web-console', '~> 2.0'/, content)
+ assert_match(/gem 'web-console',\s+github: 'rails\/web-console'/, content)
+ assert_no_match(/gem 'web-console', '~> 3.0'/, content)
end
end
@@ -537,18 +547,31 @@ class AppGeneratorTest < Rails::Generators::TestCase
def test_spring_binstubs
jruby_skip "spring doesn't run on JRuby"
- generator.stubs(:bundle_command).with('install')
- generator.expects(:bundle_command).with('exec spring binstub --all').once
- quietly { generator.invoke_all }
+ command_check = -> command do
+ @binstub_called ||= 0
+
+ case command
+ when 'install'
+ # Called when running bundle, we just want to stub it so nothing to do here.
+ when 'exec spring binstub --all'
+ @binstub_called += 1
+ assert_equal 1, @binstub_called, "exec spring binstub --all expected to be called once, but was called #{@install_called} times."
+ end
+ end
+
+ generator.stub :bundle_command, command_check do
+ quietly { generator.invoke_all }
+ end
end
def test_spring_no_fork
jruby_skip "spring doesn't run on JRuby"
- Process.stubs(:respond_to?).with(:fork).returns(false)
- run_generator
+ assert_called_with(Process, :respond_to?, [:fork], returns: false) do
+ run_generator
- assert_file "Gemfile" do |content|
- assert_no_match(/spring/, content)
+ assert_file "Gemfile" do |content|
+ assert_no_match(/spring/, content)
+ end
end
end
@@ -606,6 +629,30 @@ class AppGeneratorTest < Rails::Generators::TestCase
end
end
+ def test_create_keeps
+ run_generator
+ folders_with_keep = %w(
+ app/assets/images
+ 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/
@@ -624,23 +671,46 @@ class AppGeneratorTest < Rails::Generators::TestCase
template = %{ after_bundle { run 'echo ran after_bundle' } }
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)
+ check_open = -> *args do
+ assert_equal [ path, 'Accept' => 'application/x-thor-template' ], args
+ template
+ end
- bundler_first = sequence('bundle, binstubs, after_bundle')
- generator.expects(:bundle_command).with('install').once.in_sequence(bundler_first)
- generator.expects(:bundle_command).with('exec spring binstub --all').in_sequence(bundler_first)
- generator.expects(:run).with('echo ran after_bundle').in_sequence(bundler_first)
+ sequence = ['install', 'exec spring binstub --all', 'echo ran after_bundle']
+ ensure_bundler_first = -> command do
+ @sequence_step ||= 0
- quietly { generator.invoke_all }
+ assert_equal sequence[@sequence_step], command, "commands should be called in sequence #{sequence}"
+ @sequence_step += 1
+ end
+
+ generator([destination_root], template: path).stub(:open, check_open, template) do
+ generator.stub(:bundle_command, ensure_bundler_first) do
+ generator.stub(:run, ensure_bundler_first) do
+ quietly { generator.invoke_all }
+ end
+ end
+ end
end
protected
+ def stub_rails_application(root)
+ Rails.application.config.root = root
+ Rails.application.class.stub(:name, "Myapp") do
+ yield
+ end
+ end
+
def action(*args, &block)
capture(:stdout) { generator.send(*args, &block) }
end
- def assert_gem(gem)
- assert_file "Gemfile", /^\s*gem\s+["']#{gem}["']$*/
+ def assert_gem(gem, constraint = nil)
+ if constraint
+ assert_file "Gemfile", /^\s*gem\s+["']#{gem}["'], #{constraint}$*/
+ else
+ assert_file "Gemfile", /^\s*gem\s+["']#{gem}["']$*/
+ end
end
end
diff --git a/railties/test/generators/channel_generator_test.rb b/railties/test/generators/channel_generator_test.rb
new file mode 100644
index 0000000000..c1f0c03fbf
--- /dev/null
+++ b/railties/test/generators/channel_generator_test.rb
@@ -0,0 +1,29 @@
+require 'generators/generators_test_helper'
+require 'rails/generators/channel/channel_generator'
+
+class ChannelGeneratorTest < Rails::Generators::TestCase
+ include GeneratorsTestHelper
+ tests Rails::Generators::ChannelGenerator
+
+ def test_channel_is_created
+ run_generator ['chat']
+
+ assert_file "app/channels/chat_channel.rb" do |channel|
+ assert_match(/class ChatChannel < ApplicationCable::Channel/, channel)
+ end
+
+ assert_file "app/assets/javascripts/channels/chat.coffee" do |channel|
+ assert_match(/App.cable.subscriptions.create "ChatChannel"/, channel)
+ end
+ end
+
+ def test_channel_asset_is_not_created_when_skip_assets_is_passed
+ run_generator ['chat', '--skip-assets']
+
+ assert_file "app/channels/chat_channel.rb" do |channel|
+ assert_match(/class ChatChannel < ApplicationCable::Channel/, channel)
+ end
+
+ assert_no_file "app/assets/javascripts/channels/chat.coffee"
+ end
+end
diff --git a/railties/test/generators/generator_test.rb b/railties/test/generators/generator_test.rb
index 7871399dd7..8ef44a8dcb 100644
--- a/railties/test/generators/generator_test.rb
+++ b/railties/test/generators/generator_test.rb
@@ -80,6 +80,21 @@ module Rails
}
assert_equal gems.drop(2), generator.gemfile_entries
end
+
+ def test_recommended_rails_versions
+ klass = make_builder_class
+ generator = klass.start(['new', 'blah'])
+
+ specifier_for = -> v { generator.send(:rails_version_specifier, Gem::Version.new(v)) }
+
+ assert_equal '~> 4.1.13', specifier_for['4.1.13']
+ assert_equal ['>= 4.1.6.rc1', '< 4.2'], specifier_for['4.1.6.rc1']
+ assert_equal ['~> 4.1.7', '>= 4.1.7.1'], specifier_for['4.1.7.1']
+ assert_equal ['~> 4.1.7', '>= 4.1.7.1.2'], specifier_for['4.1.7.1.2']
+ assert_equal ['>= 4.1.7.1.rc2', '< 4.2'], specifier_for['4.1.7.1.rc2']
+ assert_equal ['>= 4.2.0.beta1', '< 4.3'], specifier_for['4.2.0.beta1']
+ assert_equal ['>= 5.0.0.beta1', '< 5.1'], specifier_for['5.0.0.beta1']
+ end
end
end
end
diff --git a/railties/test/generators/generators_test_helper.rb b/railties/test/generators/generators_test_helper.rb
index 62ca0ecb4b..b19a5a7144 100644
--- a/railties/test/generators/generators_test_helper.rb
+++ b/railties/test/generators/generators_test_helper.rb
@@ -1,6 +1,7 @@
require 'abstract_unit'
require 'active_support/core_ext/module/remove_method'
require 'active_support/testing/stream'
+require 'active_support/testing/method_call_assertions'
require 'rails/generators'
require 'rails/generators/test_case'
@@ -25,6 +26,7 @@ require 'action_view'
module GeneratorsTestHelper
include ActiveSupport::Testing::Stream
+ include ActiveSupport::Testing::MethodCallAssertions
def self.included(base)
base.class_eval do
diff --git a/railties/test/generators/mailer_generator_test.rb b/railties/test/generators/mailer_generator_test.rb
index f01e8cd2d9..f8d9ccacb4 100644
--- a/railties/test/generators/mailer_generator_test.rb
+++ b/railties/test/generators/mailer_generator_test.rb
@@ -14,15 +14,6 @@ class MailerGeneratorTest < Rails::Generators::TestCase
end
end
- def test_application_mailer_skeleton_is_created
- run_generator
- assert_file "app/mailers/application_mailer.rb" do |mailer|
- assert_match(/class ApplicationMailer < ActionMailer::Base/, mailer)
- assert_match(/default from: "from@example.com"/, mailer)
- assert_match(/layout 'mailer'/, mailer)
- end
- end
-
def test_mailer_with_i18n_helper
run_generator
assert_file "app/mailers/notifier_mailer.rb" do |mailer|
@@ -87,10 +78,6 @@ class MailerGeneratorTest < Rails::Generators::TestCase
assert_match(%r(\sapp/views/notifier_mailer/bar\.text\.erb), view)
assert_match(/<%= @greeting %>/, view)
end
-
- assert_file "app/views/layouts/mailer.text.erb" do |view|
- assert_match(/<%= yield %>/, view)
- end
end
def test_invokes_default_html_template_engine
@@ -104,17 +91,11 @@ class MailerGeneratorTest < Rails::Generators::TestCase
assert_match(%r(\sapp/views/notifier_mailer/bar\.html\.erb), view)
assert_match(/<%= @greeting %>/, view)
end
-
- assert_file "app/views/layouts/mailer.html.erb" do |view|
- assert_match(%r{<html>\n <body>\n <%= yield %>\n </body>\n</html>}, view)
- end
end
def test_invokes_default_template_engine_even_with_no_action
run_generator ["notifier"]
assert_file "app/views/notifier_mailer"
- assert_file "app/views/layouts/mailer.text.erb"
- assert_file "app/views/layouts/mailer.html.erb"
end
def test_logs_if_the_template_engine_cannot_be_found
@@ -162,10 +143,6 @@ class MailerGeneratorTest < Rails::Generators::TestCase
assert_no_file "app/views/notifier/bar.text.erb"
assert_no_file "app/views/notifier/foo.html.erb"
assert_no_file "app/views/notifier/bar.html.erb"
-
- assert_file "app/mailers/application_mailer.rb"
- assert_file "app/views/layouts/mailer.text.erb"
- assert_file "app/views/layouts/mailer.html.erb"
end
def test_mailer_suffix_is_not_duplicated
diff --git a/railties/test/generators/migration_generator_test.rb b/railties/test/generators/migration_generator_test.rb
index 57bc220558..80f284674d 100644
--- a/railties/test/generators/migration_generator_test.rb
+++ b/railties/test/generators/migration_generator_test.rb
@@ -7,7 +7,7 @@ class MigrationGeneratorTest < Rails::Generators::TestCase
def test_migration
migration = "change_title_body_from_posts"
run_generator [migration]
- assert_migration "db/migrate/#{migration}.rb", /class ChangeTitleBodyFromPosts < ActiveRecord::Migration/
+ assert_migration "db/migrate/#{migration}.rb", /class ChangeTitleBodyFromPosts < ActiveRecord::Migration\[[0-9.]+\]/
end
def test_migrations_generated_simultaneously
@@ -26,7 +26,7 @@ class MigrationGeneratorTest < Rails::Generators::TestCase
def test_migration_with_class_name
migration = "ChangeTitleBodyFromPosts"
run_generator [migration]
- assert_migration "db/migrate/change_title_body_from_posts.rb", /class #{migration} < ActiveRecord::Migration/
+ assert_migration "db/migrate/change_title_body_from_posts.rb", /class #{migration} < ActiveRecord::Migration\[[0-9.]+\]/
end
def test_migration_with_invalid_file_name
@@ -221,6 +221,15 @@ class MigrationGeneratorTest < Rails::Generators::TestCase
end
end
+ def test_add_uuid_to_create_table_migration
+ run_generator ["create_books", "--primary_key_type=uuid"]
+ assert_migration "db/migrate/create_books.rb" do |content|
+ assert_method :change, content do |change|
+ assert_match(/create_table :books, id: :uuid/, change)
+ end
+ end
+ end
+
def test_should_create_empty_migrations_if_name_not_start_with_add_or_remove_or_create
migration = "delete_books"
run_generator [migration, "title:string", "content:text"]
diff --git a/railties/test/generators/model_generator_test.rb b/railties/test/generators/model_generator_test.rb
index abd3ff50a4..fb502ec0c5 100644
--- a/railties/test/generators/model_generator_test.rb
+++ b/railties/test/generators/model_generator_test.rb
@@ -35,6 +35,17 @@ class ModelGeneratorTest < Rails::Generators::TestCase
assert_no_migration "db/migrate/create_accounts.rb"
end
+ def test_model_with_existent_application_record
+ mkdir_p "#{destination_root}/app/models"
+ touch "#{destination_root}/app/models/application_record.rb"
+
+ Dir.chdir(destination_root) do
+ run_generator ["account"]
+ end
+
+ assert_file "app/models/account.rb", /class Account < ApplicationRecord/
+ end
+
def test_plural_names_are_singularized
content = run_generator ["accounts".freeze]
assert_file "app/models/account.rb", /class Account < ActiveRecord::Base/
@@ -57,12 +68,12 @@ class ModelGeneratorTest < Rails::Generators::TestCase
def test_migration
run_generator
- assert_migration "db/migrate/create_accounts.rb", /class CreateAccounts < ActiveRecord::Migration/
+ assert_migration "db/migrate/create_accounts.rb", /class CreateAccounts < ActiveRecord::Migration\[[0-9.]+\]/
end
def test_migration_with_namespace
run_generator ["Gallery::Image"]
- assert_migration "db/migrate/create_gallery_images", /class CreateGalleryImages < ActiveRecord::Migration/
+ assert_migration "db/migrate/create_gallery_images", /class CreateGalleryImages < ActiveRecord::Migration\[[0-9.]+\]/
assert_no_migration "db/migrate/create_images"
end
@@ -70,7 +81,7 @@ class ModelGeneratorTest < Rails::Generators::TestCase
run_generator ["Admin::Gallery::Image"]
assert_no_migration "db/migrate/create_images"
assert_no_migration "db/migrate/create_gallery_images"
- assert_migration "db/migrate/create_admin_gallery_images", /class CreateAdminGalleryImages < ActiveRecord::Migration/
+ assert_migration "db/migrate/create_admin_gallery_images", /class CreateAdminGalleryImages < ActiveRecord::Migration\[[0-9.]+\]/
assert_migration "db/migrate/create_admin_gallery_images", /create_table :admin_gallery_images/
end
@@ -80,7 +91,7 @@ class ModelGeneratorTest < Rails::Generators::TestCase
assert_no_migration "db/migrate/create_images"
assert_no_migration "db/migrate/create_gallery_images"
assert_no_migration "db/migrate/create_admin_gallery_images"
- assert_migration "db/migrate/create_admin_gallery_image", /class CreateAdminGalleryImage < ActiveRecord::Migration/
+ assert_migration "db/migrate/create_admin_gallery_image", /class CreateAdminGalleryImage < ActiveRecord::Migration\[[0-9.]+\]/
assert_migration "db/migrate/create_admin_gallery_image", /create_table :admin_gallery_image/
ensure
ActiveRecord::Base.pluralize_table_names = true
@@ -89,7 +100,7 @@ class ModelGeneratorTest < Rails::Generators::TestCase
def test_migration_with_namespaces_in_model_name_without_plurization
ActiveRecord::Base.pluralize_table_names = false
run_generator ["Gallery::Image"]
- assert_migration "db/migrate/create_gallery_image", /class CreateGalleryImage < ActiveRecord::Migration/
+ assert_migration "db/migrate/create_gallery_image", /class CreateGalleryImage < ActiveRecord::Migration\[[0-9.]+\]/
assert_no_migration "db/migrate/create_gallery_images"
ensure
ActiveRecord::Base.pluralize_table_names = true
@@ -98,7 +109,7 @@ class ModelGeneratorTest < Rails::Generators::TestCase
def test_migration_without_pluralization
ActiveRecord::Base.pluralize_table_names = false
run_generator
- assert_migration "db/migrate/create_account", /class CreateAccount < ActiveRecord::Migration/
+ assert_migration "db/migrate/create_account", /class CreateAccount < ActiveRecord::Migration\[[0-9.]+\]/
assert_no_migration "db/migrate/create_accounts"
ensure
ActiveRecord::Base.pluralize_table_names = true
@@ -193,10 +204,10 @@ class ModelGeneratorTest < Rails::Generators::TestCase
def test_migration_without_timestamps
ActiveRecord::Base.timestamped_migrations = false
run_generator ["account"]
- assert_file "db/migrate/001_create_accounts.rb", /class CreateAccounts < ActiveRecord::Migration/
+ assert_file "db/migrate/001_create_accounts.rb", /class CreateAccounts < ActiveRecord::Migration\[[0-9.]+\]/
run_generator ["project"]
- assert_file "db/migrate/002_create_projects.rb", /class CreateProjects < ActiveRecord::Migration/
+ assert_file "db/migrate/002_create_projects.rb", /class CreateProjects < ActiveRecord::Migration\[[0-9.]+\]/
ensure
ActiveRecord::Base.timestamped_migrations = true
end
@@ -374,6 +385,15 @@ class ModelGeneratorTest < Rails::Generators::TestCase
end
end
+ def test_add_uuid_to_create_table_migration
+ run_generator ["account", "--primary_key_type=uuid"]
+ assert_migration "db/migrate/create_accounts.rb" do |content|
+ assert_method :change, content do |change|
+ assert_match(/create_table :accounts, id: :uuid/, change)
+ end
+ end
+ end
+
def test_required_belongs_to_adds_required_association
run_generator ["account", "supplier:references{required}"]
diff --git a/railties/test/generators/named_base_test.rb b/railties/test/generators/named_base_test.rb
index 1c32fc1bfd..291f5e06c3 100644
--- a/railties/test/generators/named_base_test.rb
+++ b/railties/test/generators/named_base_test.rb
@@ -1,6 +1,5 @@
require 'generators/generators_test_helper'
require 'rails/generators/rails/scaffold_controller/scaffold_controller_generator'
-require 'minitest/mock'
class NamedBaseTest < Rails::Generators::TestCase
include GeneratorsTestHelper
diff --git a/railties/test/generators/namespaced_generators_test.rb b/railties/test/generators/namespaced_generators_test.rb
index e839b67960..d76759a7d1 100644
--- a/railties/test/generators/namespaced_generators_test.rb
+++ b/railties/test/generators/namespaced_generators_test.rb
@@ -104,12 +104,12 @@ class NamespacedModelGeneratorTest < NamespacedGeneratorTestCase
def test_migration
run_generator
- assert_migration "db/migrate/create_test_app_accounts.rb", /create_table :test_app_accounts/, /class CreateTestAppAccounts < ActiveRecord::Migration/
+ assert_migration "db/migrate/create_test_app_accounts.rb", /create_table :test_app_accounts/, /class CreateTestAppAccounts < ActiveRecord::Migration\[[0-9.]+\]/
end
def test_migration_with_namespace
run_generator ["Gallery::Image"]
- assert_migration "db/migrate/create_test_app_gallery_images", /class CreateTestAppGalleryImages < ActiveRecord::Migration/
+ assert_migration "db/migrate/create_test_app_gallery_images", /class CreateTestAppGalleryImages < ActiveRecord::Migration\[[0-9.]+\]/
assert_no_migration "db/migrate/create_test_app_images"
end
@@ -117,7 +117,7 @@ class NamespacedModelGeneratorTest < NamespacedGeneratorTestCase
run_generator ["Admin::Gallery::Image"]
assert_no_migration "db/migrate/create_images"
assert_no_migration "db/migrate/create_gallery_images"
- assert_migration "db/migrate/create_test_app_admin_gallery_images", /class CreateTestAppAdminGalleryImages < ActiveRecord::Migration/
+ assert_migration "db/migrate/create_test_app_admin_gallery_images", /class CreateTestAppAdminGalleryImages < ActiveRecord::Migration\[[0-9.]+\]/
assert_migration "db/migrate/create_test_app_admin_gallery_images", /create_table :test_app_admin_gallery_images/
end
@@ -127,7 +127,7 @@ class NamespacedModelGeneratorTest < NamespacedGeneratorTestCase
assert_no_migration "db/migrate/create_images"
assert_no_migration "db/migrate/create_gallery_images"
assert_no_migration "db/migrate/create_test_app_admin_gallery_images"
- assert_migration "db/migrate/create_test_app_admin_gallery_image", /class CreateTestAppAdminGalleryImage < ActiveRecord::Migration/
+ assert_migration "db/migrate/create_test_app_admin_gallery_image", /class CreateTestAppAdminGalleryImage < ActiveRecord::Migration\[[0-9.]+\]/
assert_migration "db/migrate/create_test_app_admin_gallery_image", /create_table :test_app_admin_gallery_image/
ensure
ActiveRecord::Base.pluralize_table_names = true
@@ -218,7 +218,7 @@ class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase
/class ProductLinesController < ApplicationController/
assert_file "test/controllers/test_app/product_lines_controller_test.rb",
- /module TestApp\n class ProductLinesControllerTest < ActionController::TestCase/
+ /module TestApp\n class ProductLinesControllerTest < ActionDispatch::IntegrationTest/
# Views
%w(index edit new show _form).each do |view|
@@ -281,10 +281,11 @@ class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase
# Controller
assert_file "app/controllers/test_app/admin/roles_controller.rb" do |content|
assert_match(/module TestApp\n class Admin::RolesController < ApplicationController/, content)
+ assert_match(%r(require_dependency "test_app/application_controller"), content)
end
assert_file "test/controllers/test_app/admin/roles_controller_test.rb",
- /module TestApp\n class Admin::RolesControllerTest < ActionController::TestCase/
+ /module TestApp\n class Admin::RolesControllerTest < ActionDispatch::IntegrationTest/
# Views
%w(index edit new show _form).each do |view|
@@ -351,7 +352,7 @@ class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase
end
assert_file "test/controllers/test_app/admin/user/special/roles_controller_test.rb",
- /module TestApp\n class Admin::User::Special::RolesControllerTest < ActionController::TestCase/
+ /module TestApp\n class Admin::User::Special::RolesControllerTest < ActionDispatch::IntegrationTest/
# Views
%w(index edit new show _form).each do |view|
@@ -395,4 +396,28 @@ class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase
# Stylesheets (should not be removed)
assert_file "app/assets/stylesheets/scaffold.css"
end
+
+ def test_api_scaffold_with_namespace_on_invoke
+ run_generator [ "admin/role", "name:string", "description:string", "--api" ]
+
+ # Model
+ assert_file "app/models/test_app/admin.rb", /module TestApp\n module Admin/
+ assert_file "app/models/test_app/admin/role.rb", /module TestApp\n class Admin::Role < ActiveRecord::Base/
+ assert_file "test/models/test_app/admin/role_test.rb", /module TestApp\n class Admin::RoleTest < ActiveSupport::TestCase/
+ assert_file "test/fixtures/test_app/admin/roles.yml"
+ assert_migration "db/migrate/create_test_app_admin_roles.rb"
+
+ # Route
+ assert_file "config/routes.rb" do |route|
+ assert_match(/^ namespace :admin do\n resources :roles\n end$/, route)
+ end
+
+ # Controller
+ assert_file "app/controllers/test_app/admin/roles_controller.rb" do |content|
+ assert_match(/module TestApp\n class Admin::RolesController < ApplicationController/, content)
+ assert_match(%r(require_dependency "test_app/application_controller"), content)
+ end
+ assert_file "test/controllers/test_app/admin/roles_controller_test.rb",
+ /module TestApp\n class Admin::RolesControllerTest < ActionDispatch::IntegrationTest/
+ end
end
diff --git a/railties/test/generators/plugin_generator_test.rb b/railties/test/generators/plugin_generator_test.rb
index d6e5f4bd89..c5723e364d 100644
--- a/railties/test/generators/plugin_generator_test.rb
+++ b/railties/test/generators/plugin_generator_test.rb
@@ -1,13 +1,12 @@
require 'generators/generators_test_helper'
require 'rails/generators/rails/plugin/plugin_generator'
require 'generators/shared_generator_tests'
-require 'mocha/setup' # FIXME: stop using mocha
DEFAULT_PLUGIN_FILES = %w(
.gitignore
Gemfile
Rakefile
- README.rdoc
+ README.md
bukkits.gemspec
MIT-LICENSE
lib
@@ -38,7 +37,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
@@ -59,14 +58,18 @@ class PluginGeneratorTest < Rails::Generators::TestCase
def test_generating_without_options
run_generator
- assert_file "README.rdoc", /Bukkits/
+ assert_file "README.md", /Bukkits/
assert_no_file "config/routes.rb"
+ assert_no_file "app/assets/config/bukkits_manifest.js"
assert_file "test/test_helper.rb" do |content|
assert_match(/require.+test\/dummy\/config\/environment/, content)
assert_match(/ActiveRecord::Migrator\.migrations_paths.+test\/dummy\/db\/migrate/, content)
assert_match(/Minitest\.backtrace_filter = Minitest::BacktraceFilter\.new/, content)
+ assert_match(/Rails::TestUnitReporter\.executable = 'bin\/test'/, content)
end
assert_file "test/bukkits_test.rb", /assert_kind_of Module, Bukkits/
+ assert_file 'bin/test'
+ assert_no_file 'bin/rails'
end
def test_generating_test_files_in_full_mode
@@ -223,7 +226,7 @@ class PluginGeneratorTest < Rails::Generators::TestCase
run_generator
FileUtils.cd destination_root
quietly { system 'bundle install' }
- assert_match(/1 runs, 1 assertions, 0 failures, 0 errors/, `bundle exec rake test 2>&1`)
+ assert_match(/1 runs, 1 assertions, 0 failures, 0 errors/, `bin/test 2>&1`)
end
def test_ensure_that_tests_works_in_full_mode
@@ -304,6 +307,8 @@ class PluginGeneratorTest < Rails::Generators::TestCase
assert_file "lib/bukkits/engine.rb", /isolate_namespace Bukkits/
assert_file "test/dummy/config/routes.rb", /mount Bukkits::Engine => "\/bukkits"/
assert_file "app/controllers/bukkits/application_controller.rb", /module Bukkits\n class ApplicationController < ActionController::Base/
+ assert_file "app/models/bukkits/application_record.rb", /module Bukkits\n class ApplicationRecord < ActiveRecord::Base/
+ assert_file "app/jobs/bukkits/application_job.rb", /module Bukkits\n class ApplicationJob < ActiveJob::Base/
assert_file "app/helpers/bukkits/application_helper.rb", /module Bukkits\n module ApplicationHelper/
assert_file "app/views/layouts/bukkits/application.html.erb" do |contents|
assert_match "<title>Bukkits</title>", contents
@@ -313,7 +318,10 @@ 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)
+ assert_no_match(/Rails::TestUnitReporter\.executable = 'bin\/test'/, content)
end
+ assert_no_file 'bin/test'
end
def test_create_mountable_application_with_mountable_option_and_hypenated_name
@@ -322,11 +330,13 @@ 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"/
assert_file "hyphenated-name/app/controllers/hyphenated/name/application_controller.rb", /module Hyphenated\n module Name\n class ApplicationController < ActionController::Base\n end\n end\nend/
+ assert_file "hyphenated-name/app/models/hyphenated/name/application_record.rb", /module Hyphenated\n module Name\n class ApplicationRecord < ActiveRecord::Base\n self\.abstract_class = true\n end\n end\nend/
+ assert_file "hyphenated-name/app/jobs/hyphenated/name/application_job.rb", /module Hyphenated\n module Name\n class ApplicationJob < ActiveJob::Base/
assert_file "hyphenated-name/app/helpers/hyphenated/name/application_helper.rb", /module Hyphenated\n module Name\n module ApplicationHelper\n end\n end\nend/
assert_file "hyphenated-name/app/views/layouts/hyphenated/name/application.html.erb" do |contents|
assert_match "<title>Hyphenated name</title>", contents
@@ -341,11 +351,13 @@ 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"/
assert_file "my_hyphenated-name/app/controllers/my_hyphenated/name/application_controller.rb", /module MyHyphenated\n module Name\n class ApplicationController < ActionController::Base\n end\n end\nend/
+ assert_file "my_hyphenated-name/app/models/my_hyphenated/name/application_record.rb", /module MyHyphenated\n module Name\n class ApplicationRecord < ActiveRecord::Base\n self\.abstract_class = true\n end\n end\nend/
+ assert_file "my_hyphenated-name/app/jobs/my_hyphenated/name/application_job.rb", /module MyHyphenated\n module Name\n class ApplicationJob < ActiveJob::Base/
assert_file "my_hyphenated-name/app/helpers/my_hyphenated/name/application_helper.rb", /module MyHyphenated\n module Name\n module ApplicationHelper\n end\n end\nend/
assert_file "my_hyphenated-name/app/views/layouts/my_hyphenated/name/application.html.erb" do |contents|
assert_match "<title>My hyphenated name</title>", contents
@@ -360,11 +372,13 @@ 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"/
assert_file "deep-hyphenated-name/app/controllers/deep/hyphenated/name/application_controller.rb", /module Deep\n module Hyphenated\n module Name\n class ApplicationController < ActionController::Base\n end\n end\n end\nend/
+ assert_file "deep-hyphenated-name/app/models/deep/hyphenated/name/application_record.rb", /module Deep\n module Hyphenated\n module Name\n class ApplicationRecord < ActiveRecord::Base\n self\.abstract_class = true\n end\n end\n end\nend/
+ assert_file "deep-hyphenated-name/app/jobs/deep/hyphenated/name/application_job.rb", /module Deep\n module Hyphenated\n module Name\n class ApplicationJob < ActiveJob::Base/
assert_file "deep-hyphenated-name/app/helpers/deep/hyphenated/name/application_helper.rb", /module Deep\n module Hyphenated\n module Name\n module ApplicationHelper\n end\n end\n end\nend/
assert_file "deep-hyphenated-name/app/views/layouts/deep/hyphenated/name/application.html.erb" do |contents|
assert_match "<title>Deep hyphenated name</title>", contents
@@ -376,8 +390,7 @@ class PluginGeneratorTest < Rails::Generators::TestCase
def test_creating_gemspec
run_generator
assert_file "bukkits.gemspec", /s.name\s+= "bukkits"/
- assert_file "bukkits.gemspec", /s.files = Dir\["\{app,config,db,lib\}\/\*\*\/\*", "MIT-LICENSE", "Rakefile", "README\.rdoc"\]/
- assert_file "bukkits.gemspec", /s.test_files = Dir\["test\/\*\*\/\*"\]/
+ assert_file "bukkits.gemspec", /s.files = Dir\["\{app,config,db,lib\}\/\*\*\/\*", "MIT-LICENSE", "Rakefile", "README\.md"\]/
assert_file "bukkits.gemspec", /s.version\s+ = Bukkits::VERSION/
end
@@ -435,12 +448,22 @@ class PluginGeneratorTest < Rails::Generators::TestCase
end
end
+ def test_unnecessary_files_are_not_generated_in_dummy_application
+ run_generator
+ assert_no_file 'test/dummy/.gitignore'
+ assert_no_file 'test/dummy/db/seeds.rb'
+ assert_no_file 'test/dummy/Gemfile'
+ assert_no_file 'test/dummy/public/robots.txt'
+ assert_no_file 'test/dummy/README.md'
+ assert_no_directory 'test/dummy/lib/tasks'
+ assert_no_directory 'test/dummy/doc'
+ assert_no_directory 'test/dummy/test'
+ assert_no_directory 'test/dummy/vendor'
+ end
+
def test_skipping_test_files
run_generator [destination_root, "--skip-test"]
assert_no_file "test"
- assert_file "bukkits.gemspec" do |contents|
- assert_no_match(/s.test_files = Dir\["test\/\*\*\/\*"\]/, contents)
- end
assert_file '.gitignore' do |contents|
assert_no_match(/test\dummy/, contents)
end
@@ -451,7 +474,7 @@ class PluginGeneratorTest < Rails::Generators::TestCase
assert_no_file "bukkits.gemspec"
assert_file "Gemfile" do |contents|
assert_no_match('gemspec', contents)
- assert_match(/gem 'rails', '~> #{Rails.version}'/, contents)
+ assert_match(/gem 'rails'/, contents)
assert_match_sqlite3(contents)
assert_no_match(/# gem "jquery-rails"/, contents)
end
@@ -462,7 +485,7 @@ class PluginGeneratorTest < Rails::Generators::TestCase
assert_no_file "bukkits.gemspec"
assert_file "Gemfile" do |contents|
assert_no_match('gemspec', contents)
- assert_match(/gem 'rails', '~> #{Rails.version}'/, contents)
+ assert_match(/gem 'rails'/, contents)
assert_match_sqlite3(contents)
end
end
@@ -544,6 +567,69 @@ 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
+
+ def test_model_with_existent_application_record_in_mountable_engine
+ run_generator [destination_root, '--mountable']
+ capture(:stdout) do
+ `#{destination_root}/bin/rails g model article`
+ end
+
+ assert_file "app/models/bukkits/article.rb", /class Article < ApplicationRecord/
+ end
+
protected
def action(*args, &block)
silence(:stdout){ generator.send(*args, &block) }
diff --git a/railties/test/generators/plugin_test_helper.rb b/railties/test/generators/plugin_test_helper.rb
new file mode 100644
index 0000000000..96c1b1d31f
--- /dev/null
+++ b/railties/test/generators/plugin_test_helper.rb
@@ -0,0 +1,24 @@
+require 'abstract_unit'
+require 'tmpdir'
+
+module PluginTestHelper
+ def create_test_file(name, pass: true)
+ plugin_file "test/#{name}_test.rb", <<-RUBY
+ require 'test_helper'
+
+ class #{name.camelize}Test < ActiveSupport::TestCase
+ def test_truth
+ puts "#{name.camelize}Test"
+ assert #{pass}, 'wups!'
+ end
+ end
+ RUBY
+ end
+
+ def plugin_file(path, contents, mode: 'w')
+ FileUtils.mkdir_p File.dirname("#{plugin_path}/#{path}")
+ File.open("#{plugin_path}/#{path}", mode) do |f|
+ f.puts contents
+ end
+ end
+end
diff --git a/railties/test/generators/plugin_test_runner_test.rb b/railties/test/generators/plugin_test_runner_test.rb
new file mode 100644
index 0000000000..f0fb63c208
--- /dev/null
+++ b/railties/test/generators/plugin_test_runner_test.rb
@@ -0,0 +1,105 @@
+require 'generators/plugin_test_helper'
+
+class PluginTestRunnerTest < ActiveSupport::TestCase
+ include PluginTestHelper
+
+ def setup
+ @destination_root = Dir.mktmpdir('bukkits')
+ Dir.chdir(@destination_root) { `bundle exec rails plugin new bukkits --skip-bundle` }
+ plugin_file 'test/dummy/db/schema.rb', ''
+ end
+
+ def teardown
+ FileUtils.rm_rf(@destination_root)
+ end
+
+ def test_run_single_file
+ create_test_file 'foo'
+ create_test_file 'bar'
+ assert_match "1 runs, 1 assertions, 0 failures", run_test_command("test/foo_test.rb")
+ end
+
+ def test_run_multiple_files
+ create_test_file 'foo'
+ create_test_file 'bar'
+ assert_match "2 runs, 2 assertions, 0 failures", run_test_command("test/foo_test.rb test/bar_test.rb")
+ end
+
+ def test_mix_files_and_line_filters
+ create_test_file 'account'
+ plugin_file 'test/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/account_test.rb test/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 'account'
+ create_test_file 'post'
+
+ run_test_command('test/account_test.rb:4 test/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 'account'
+
+ run_test_command('test/account_test.rb:').tap do |output|
+ assert_match 'AccountTest', output
+ end
+ end
+
+ def test_output_inline_by_default
+ create_test_file 'post', pass: false
+
+ output = run_test_command('test/post_test.rb')
+ expect = %r{Running:\n\nPostTest\nF\n\nFailure:\nPostTest#test_truth:\nwups!\n\nbin/test (/private)?#{plugin_path}/test/post_test.rb:6}
+ assert_match expect, output
+ end
+
+ def test_only_inline_failure_output
+ create_test_file 'post', pass: false
+
+ output = run_test_command('test/post_test.rb')
+ assert_match %r{Finished in.*\n\n1 runs, 1 assertions}, output
+ end
+
+ def test_fail_fast
+ create_test_file 'post', pass: false
+
+ assert_match(/Interrupt/,
+ capture(:stderr) { run_test_command('test/post_test.rb --fail-fast') })
+ end
+
+ def test_raise_error_when_specified_file_does_not_exist
+ error = capture(:stderr) { run_test_command('test/not_exists.rb') }
+ assert_match(%r{cannot load such file.+test/not_exists\.rb}, error)
+ end
+
+ private
+ def plugin_path
+ "#{@destination_root}/bukkits"
+ end
+
+ def run_test_command(arguments)
+ Dir.chdir(plugin_path) { `bin/test #{arguments}` }
+ end
+end
diff --git a/railties/test/generators/resource_generator_test.rb b/railties/test/generators/resource_generator_test.rb
index 581d80d60e..addaf83bc8 100644
--- a/railties/test/generators/resource_generator_test.rb
+++ b/railties/test/generators/resource_generator_test.rb
@@ -33,7 +33,7 @@ class ResourceGeneratorTest < Rails::Generators::TestCase
def test_resource_controller_with_pluralized_class_name
run_generator
assert_file "app/controllers/accounts_controller.rb", /class AccountsController < ApplicationController/
- assert_file "test/controllers/accounts_controller_test.rb", /class AccountsControllerTest < ActionController::TestCase/
+ assert_file "test/controllers/accounts_controller_test.rb", /class AccountsControllerTest < ActionDispatch::IntegrationTest/
assert_file "app/helpers/accounts_helper.rb", /module AccountsHelper/
end
diff --git a/railties/test/generators/scaffold_controller_generator_test.rb b/railties/test/generators/scaffold_controller_generator_test.rb
index 34e752cea1..c37e289f4b 100644
--- a/railties/test/generators/scaffold_controller_generator_test.rb
+++ b/railties/test/generators/scaffold_controller_generator_test.rb
@@ -56,7 +56,7 @@ class ScaffoldControllerGeneratorTest < Rails::Generators::TestCase
assert_file "app/controllers/users_controller.rb" do |content|
assert_match(/def user_params/, content)
- assert_match(/params\[:user\]/, content)
+ assert_match(/params\.fetch\(:user, \{\}\)/, content)
end
end
@@ -104,10 +104,10 @@ class ScaffoldControllerGeneratorTest < Rails::Generators::TestCase
run_generator ["User", "name:string", "age:integer", "organization:references{polymorphic}"]
assert_file "test/controllers/users_controller_test.rb" do |content|
- assert_match(/class UsersControllerTest < ActionController::TestCase/, content)
+ assert_match(/class UsersControllerTest < ActionDispatch::IntegrationTest/, 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_match(/post users_url, params: \{ user: \{ age: @user\.age, name: @user\.name, organization_id: @user\.organization_id, organization_type: @user\.organization_type \} \}/, content)
+ assert_match(/patch user_url\(@user\), params: \{ user: \{ age: @user\.age, name: @user\.name, organization_id: @user\.organization_id, organization_type: @user\.organization_type \} \}/, content)
end
end
@@ -115,10 +115,10 @@ class ScaffoldControllerGeneratorTest < Rails::Generators::TestCase
run_generator ["User"]
assert_file "test/controllers/users_controller_test.rb" do |content|
- assert_match(/class UsersControllerTest < ActionController::TestCase/, content)
+ assert_match(/class UsersControllerTest < ActionDispatch::IntegrationTest/, content)
assert_match(/test "should get index"/, content)
- assert_match(/post :create, params: \{ user: \{ \} \}/, content)
- assert_match(/patch :update, params: \{ id: @user, user: \{ \} \}/, content)
+ assert_match(/post users_url, params: \{ user: \{ \} \}/, content)
+ assert_match(/patch user_url\(@user\), params: \{ user: \{ \} \}/, content)
end
end
@@ -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 < ActionDispatch::IntegrationTest/, content)
+ assert_match(/test "should get index"/, content)
+ assert_match(/post users_url, params: \{ user: \{ age: @user\.age, name: @user\.name, organization_id: @user\.organization_id, organization_type: @user\.organization_type \} \}/, content)
+ assert_match(/patch user_url\(@user\), params: \{ 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..eb81ea3d0e 100644
--- a/railties/test/generators/scaffold_generator_test.rb
+++ b/railties/test/generators/scaffold_generator_test.rb
@@ -57,9 +57,9 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase
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_match(/class ProductLinesControllerTest < ActionDispatch::IntegrationTest/, test)
+ assert_match(/post product_lines_url, params: \{ product_line: \{ product_id: @product_line\.product_id, title: @product_line\.title, user_id: @product_line\.user_id \} \}/, test)
+ assert_match(/patch product_line_url\(@product_line\), params: \{ product_line: \{ product_id: @product_line\.product_id, title: @product_line\.title, user_id: @product_line\.user_id \} \}/, test)
end
# Views
@@ -87,14 +87,84 @@ 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 < ActionDispatch::IntegrationTest/, test)
+ assert_match(/post product_lines_url, params: \{ product_line: \{ product_id: @product_line\.product_id, title: @product_line\.title, user_id: @product_line\.user_id \} \}/, test)
+ assert_match(/patch product_line_url\(@product_line\), params: \{ 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"]
assert_file "test/controllers/product_lines_controller_test.rb" do |content|
- assert_match(/class ProductLinesControllerTest < ActionController::TestCase/, content)
+ assert_match(/class ProductLinesControllerTest < ActionDispatch::IntegrationTest/, content)
assert_match(/test "should get index"/, content)
- assert_match(/post :create, params: \{ product_line: \{ \} \}/, content)
- assert_match(/patch :update, params: \{ id: @product_line, product_line: \{ \} \}/, content)
+ assert_match(/post product_lines_url, params: \{ product_line: \{ \} \}/, content)
+ assert_match(/patch product_line_url\(@product_line\), params: \{ product_line: \{ \} \}/, content)
end
end
@@ -180,7 +250,7 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase
end
assert_file "test/controllers/admin/roles_controller_test.rb",
- /class Admin::RolesControllerTest < ActionController::TestCase/
+ /class Admin::RolesControllerTest < ActionDispatch::IntegrationTest/
# Views
%w(index edit new show _form).each do |view|
@@ -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..e83d54890a 100644
--- a/railties/test/generators/shared_generator_tests.rb
+++ b/railties/test/generators/shared_generator_tests.rb
@@ -28,9 +28,22 @@ module SharedGeneratorTests
def assert_generates_with_bundler(options = {})
generator([destination_root], options)
- generator.expects(:bundle_command).with('install').once
- generator.stubs(:bundle_command).with('exec spring binstub --all')
- quietly { generator.invoke_all }
+
+ command_check = -> command do
+ @install_called ||= 0
+
+ case command
+ when 'install'
+ @install_called += 1
+ assert_equal 1, @install_called, "install expected to be called once, but was called #{@install_called} times"
+ when 'exec spring binstub --all'
+ # Called when running tests with spring, let through unscathed.
+ end
+ end
+
+ generator.stub :bundle_command, command_check do
+ quietly { generator.invoke_all }
+ end
end
def test_generation_runs_bundle_install
@@ -56,7 +69,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,22 +99,19 @@ 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!" }
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 }) }
+ check_open = -> *args do
+ assert_equal [ path, 'Accept' => 'application/x-thor-template' ], args
+ template
+ end
+
+ generator([destination_root], template: path).stub(:open, check_open, template) do
+ quietly { assert_match(/It works!/, capture(:stdout) { generator.invoke_all }) }
+ end
end
def test_dev_option
@@ -116,24 +126,24 @@ module SharedGeneratorTests
end
def test_skip_gemfile
- generator([destination_root], skip_gemfile: true).expects(:bundle_command).never
- quietly { generator.invoke_all }
- assert_no_file 'Gemfile'
+ assert_not_called(generator([destination_root], skip_gemfile: true), :bundle_command) do
+ quietly { generator.invoke_all }
+ assert_no_file 'Gemfile'
+ end
end
def test_skip_bundle
- generator([destination_root], skip_bundle: true).expects(:bundle_command).never
- quietly { generator.invoke_all }
-
- # skip_bundle is only about running bundle install, ensure the Gemfile is still
- # generated.
- assert_file 'Gemfile'
+ assert_not_called(generator([destination_root], skip_bundle: true), :bundle_command) do
+ quietly { generator.invoke_all }
+ # skip_bundle is only about running bundle install, ensure the Gemfile is still
+ # generated.
+ assert_file 'Gemfile'
+ end
end
def test_skip_git
run_generator [destination_root, '--skip-git', '--full']
assert_no_file('.gitignore')
- assert_file('app/mailers/.keep')
end
def test_skip_keeps
@@ -143,6 +153,6 @@ module SharedGeneratorTests
assert_no_match(/\.keep/, content)
end
- assert_no_file('app/mailers/.keep')
+ assert_no_file('app/models/concerns/.keep')
end
end
diff --git a/railties/test/generators/test_runner_in_engine_test.rb b/railties/test/generators/test_runner_in_engine_test.rb
new file mode 100644
index 0000000000..69906b962b
--- /dev/null
+++ b/railties/test/generators/test_runner_in_engine_test.rb
@@ -0,0 +1,32 @@
+require 'generators/plugin_test_helper'
+
+class TestRunnerInEngineTest < ActiveSupport::TestCase
+ include PluginTestHelper
+
+ def setup
+ @destination_root = Dir.mktmpdir('bukkits')
+ Dir.chdir(@destination_root) { `bundle exec rails plugin new bukkits --full --skip-bundle` }
+ plugin_file 'test/dummy/db/schema.rb', ''
+ end
+
+ def teardown
+ FileUtils.rm_rf(@destination_root)
+ end
+
+ def test_rerun_snippet_is_relative_path
+ create_test_file 'post', pass: false
+
+ output = run_test_command('test/post_test.rb')
+ expect = %r{Running:\n\nPostTest\nF\n\nFailure:\nPostTest#test_truth:\nwups!\n\nbin/rails test test/post_test.rb:6}
+ assert_match expect, output
+ end
+
+ private
+ def plugin_path
+ "#{@destination_root}/bukkits"
+ end
+
+ def run_test_command(arguments)
+ Dir.chdir(plugin_path) { `bin/rails test #{arguments}` }
+ end
+end
diff --git a/railties/test/generators_test.rb b/railties/test/generators_test.rb
index ce75aba4eb..291415858c 100644
--- a/railties/test/generators_test.rb
+++ b/railties/test/generators_test.rb
@@ -1,7 +1,6 @@
require 'generators/generators_test_helper'
require 'rails/generators/rails/model/model_generator'
require 'rails/generators/test_unit/model/model_generator'
-require 'mocha/setup' # FIXME: stop using mocha
class GeneratorsTest < Rails::Generators::TestCase
include GeneratorsTestHelper
@@ -17,8 +16,9 @@ class GeneratorsTest < Rails::Generators::TestCase
def test_simple_invoke
assert File.exist?(File.join(@path, 'generators', 'model_generator.rb'))
- TestUnit::Generators::ModelGenerator.expects(:start).with(["Account"], {})
- Rails::Generators.invoke("test_unit:model", ["Account"])
+ assert_called_with(TestUnit::Generators::ModelGenerator, :start, [["Account"], {}]) do
+ Rails::Generators.invoke("test_unit:model", ["Account"])
+ end
end
def test_invoke_when_generator_is_not_found
@@ -47,19 +47,22 @@ class GeneratorsTest < Rails::Generators::TestCase
def test_should_give_higher_preference_to_rails_generators
assert File.exist?(File.join(@path, 'generators', 'model_generator.rb'))
- Rails::Generators::ModelGenerator.expects(:start).with(["Account"], {})
- warnings = capture(:stderr){ Rails::Generators.invoke :model, ["Account"] }
- assert warnings.empty?
+ assert_called_with(Rails::Generators::ModelGenerator, :start, [["Account"], {}]) do
+ warnings = capture(:stderr){ Rails::Generators.invoke :model, ["Account"] }
+ assert warnings.empty?
+ end
end
def test_invoke_with_default_values
- Rails::Generators::ModelGenerator.expects(:start).with(["Account"], {})
- Rails::Generators.invoke :model, ["Account"]
+ assert_called_with(Rails::Generators::ModelGenerator, :start, [["Account"], {}]) do
+ Rails::Generators.invoke :model, ["Account"]
+ end
end
def test_invoke_with_config_values
- Rails::Generators::ModelGenerator.expects(:start).with(["Account"], behavior: :skip)
- Rails::Generators.invoke :model, ["Account"], behavior: :skip
+ assert_called_with(Rails::Generators::ModelGenerator, :start, [["Account"], behavior: :skip]) do
+ Rails::Generators.invoke :model, ["Account"], behavior: :skip
+ end
end
def test_find_by_namespace
@@ -103,11 +106,12 @@ class GeneratorsTest < Rails::Generators::TestCase
end
def test_invoke_with_nested_namespaces
- model_generator = mock('ModelGenerator') do
- expects(:start).with(["Account"], {})
+ model_generator = Minitest::Mock.new
+ model_generator.expect(:start, nil, [["Account"], {}])
+ assert_called_with(Rails::Generators, :find_by_namespace, ['namespace', 'my:awesome'], returns: model_generator) do
+ Rails::Generators.invoke 'my:awesome:namespace', ["Account"]
end
- Rails::Generators.expects(:find_by_namespace).with('namespace', 'my:awesome').returns(model_generator)
- Rails::Generators.invoke 'my:awesome:namespace', ["Account"]
+ model_generator.verify
end
def test_rails_generators_help_with_builtin_information
@@ -173,8 +177,9 @@ class GeneratorsTest < Rails::Generators::TestCase
def test_fallbacks_for_generators_on_invoke
Rails::Generators.fallbacks[:shoulda] = :test_unit
- TestUnit::Generators::ModelGenerator.expects(:start).with(["Account"], {})
- Rails::Generators.invoke "shoulda:model", ["Account"]
+ assert_called_with(TestUnit::Generators::ModelGenerator, :start, [["Account"], {}]) do
+ Rails::Generators.invoke "shoulda:model", ["Account"]
+ end
ensure
Rails::Generators.fallbacks.delete(:shoulda)
end
@@ -182,8 +187,9 @@ class GeneratorsTest < Rails::Generators::TestCase
def test_nested_fallbacks_for_generators
Rails::Generators.fallbacks[:shoulda] = :test_unit
Rails::Generators.fallbacks[:super_shoulda] = :shoulda
- TestUnit::Generators::ModelGenerator.expects(:start).with(["Account"], {})
- Rails::Generators.invoke "super_shoulda:model", ["Account"]
+ assert_called_with(TestUnit::Generators::ModelGenerator, :start, [["Account"], {}]) do
+ Rails::Generators.invoke "super_shoulda:model", ["Account"]
+ end
ensure
Rails::Generators.fallbacks.delete(:shoulda)
Rails::Generators.fallbacks.delete(:super_shoulda)
diff --git a/railties/test/isolation/abstract_unit.rb b/railties/test/isolation/abstract_unit.rb
index 65d8a55421..df3c2ca66d 100644
--- a/railties/test/isolation/abstract_unit.rb
+++ b/railties/test/isolation/abstract_unit.rb
@@ -51,7 +51,12 @@ module TestHelpers
old_env = ENV["RAILS_ENV"]
@app ||= begin
ENV["RAILS_ENV"] = env
- require "#{app_path}/config/environment"
+
+ # FIXME: shush Sass warning spam, not relevant to testing Railties
+ Kernel.silence_warnings do
+ require "#{app_path}/config/environment"
+ end
+
Rails.application
end
ensure
@@ -159,19 +164,20 @@ module TestHelpers
require "rails"
require "action_controller/railtie"
require "action_view/railtie"
+ require 'action_dispatch/middleware/flash'
- app = Class.new(Rails::Application)
- app.config.eager_load = false
- app.secrets.secret_key_base = "3b7cd727ee24e8444053437c36cc66c4"
- app.config.session_store :cookie_store, key: "_myapp_session"
- app.config.active_support.deprecation = :log
- app.config.active_support.test_order = :random
- app.config.log_level = :info
+ @app = Class.new(Rails::Application)
+ @app.config.eager_load = false
+ @app.secrets.secret_key_base = "3b7cd727ee24e8444053437c36cc66c4"
+ @app.config.session_store :cookie_store, key: "_myapp_session"
+ @app.config.active_support.deprecation = :log
+ @app.config.active_support.test_order = :random
+ @app.config.log_level = :info
- yield app if block_given?
- app.initialize!
+ yield @app if block_given?
+ @app.initialize!
- app.routes.draw do
+ @app.routes.draw do
get "/" => "omg#index"
end
@@ -296,7 +302,10 @@ module TestHelpers
end
def boot_rails
- require File.expand_path('../../../../load_paths', __FILE__)
+ # FIXME: shush Sass warning spam, not relevant to testing Railties
+ Kernel.silence_warnings do
+ require File.expand_path('../../../../load_paths', __FILE__)
+ end
end
end
end
diff --git a/railties/test/path_generation_test.rb b/railties/test/path_generation_test.rb
index 27e64b97b7..a16adc72a6 100644
--- a/railties/test/path_generation_test.rb
+++ b/railties/test/path_generation_test.rb
@@ -11,26 +11,26 @@ class PathGenerationTest < ActiveSupport::TestCase
super()
end
- class Dispatcher < ActionDispatch::Routing::RouteSet::Dispatcher
- def initialize(defaults, set, block)
- super(defaults)
+ class Request < DelegateClass(ActionDispatch::Request)
+ def initialize(target, url_helpers, block)
+ super(target)
+ @url_helpers = url_helpers
@block = block
- @set = set
end
- def controller_reference(controller_param)
+ def controller_class
+ url_helpers = @url_helpers
block = @block
- set = @set
Class.new(ActionController::Base) {
- include set.url_helpers
+ include url_helpers
define_method(:process) { |name| block.call(self) }
def to_a; [200, {}, []]; end
}
end
end
- def dispatcher defaults
- TestSet::Dispatcher.new defaults, self, @block
+ def make_request(env)
+ Request.new super, self.url_helpers, @block
end
end
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/engine_test.rb b/railties/test/railties/engine_test.rb
index 79bd7a8241..4a47ab32b4 100644
--- a/railties/test/railties/engine_test.rb
+++ b/railties/test/railties/engine_test.rb
@@ -63,22 +63,22 @@ module RailtiesTest
test "copying migrations" do
@plugin.write "db/migrate/1_create_users.rb", <<-RUBY
- class CreateUsers < ActiveRecord::Migration
+ class CreateUsers < ActiveRecord::Migration::Current
end
RUBY
@plugin.write "db/migrate/2_add_last_name_to_users.rb", <<-RUBY
- class AddLastNameToUsers < ActiveRecord::Migration
+ class AddLastNameToUsers < ActiveRecord::Migration::Current
end
RUBY
@plugin.write "db/migrate/3_create_sessions.rb", <<-RUBY
- class CreateSessions < ActiveRecord::Migration
+ class CreateSessions < ActiveRecord::Migration::Current
end
RUBY
app_file "db/migrate/1_create_sessions.rb", <<-RUBY
- class CreateSessions < ActiveRecord::Migration
+ class CreateSessions < ActiveRecord::Migration::Current
def up
end
end
@@ -123,12 +123,12 @@ module RailtiesTest
end
@plugin.write "db/migrate/1_create_users.rb", <<-RUBY
- class CreateUsers < ActiveRecord::Migration
+ class CreateUsers < ActiveRecord::Migration::Current
end
RUBY
@blog.write "db/migrate/2_create_blogs.rb", <<-RUBY
- class CreateBlogs < ActiveRecord::Migration
+ class CreateBlogs < ActiveRecord::Migration::Current
end
RUBY
@@ -163,11 +163,11 @@ module RailtiesTest
end
@core.write "db/migrate/1_create_users.rb", <<-RUBY
- class CreateUsers < ActiveRecord::Migration; end
+ class CreateUsers < ActiveRecord::Migration::Current; end
RUBY
@api.write "db/migrate/2_create_keys.rb", <<-RUBY
- class CreateKeys < ActiveRecord::Migration; end
+ class CreateKeys < ActiveRecord::Migration::Current; end
RUBY
boot_rails
@@ -190,7 +190,7 @@ module RailtiesTest
RUBY
@plugin.write "db/migrate/0_add_first_name_to_users.rb", <<-RUBY
- class AddFirstNameToUsers < ActiveRecord::Migration
+ class AddFirstNameToUsers < ActiveRecord::Migration::Current
end
RUBY
@@ -1205,7 +1205,7 @@ YAML
test "engine can be properly mounted at root" do
add_to_config("config.action_dispatch.show_exceptions = false")
- add_to_config("config.serve_static_files = false")
+ add_to_config("config.public_file_server.enabled = false")
@plugin.write "lib/bukkits.rb", <<-RUBY
module Bukkits
@@ -1304,6 +1304,55 @@ YAML
assert_equal '/foo/bukkits/bukkit', last_response.body
end
+ test "paths are properly generated when application is mounted at sub-path and relative_url_root is set" do
+ add_to_config "config.relative_url_root = '/foo'"
+
+ @plugin.write "lib/bukkits.rb", <<-RUBY
+ module Bukkits
+ class Engine < ::Rails::Engine
+ isolate_namespace Bukkits
+ end
+ end
+ RUBY
+
+ app_file "app/controllers/bar_controller.rb", <<-RUBY
+ class BarController < ApplicationController
+ def index
+ render text: bukkits.bukkit_path
+ end
+ end
+ RUBY
+
+ app_file "config/routes.rb", <<-RUBY
+ Rails.application.routes.draw do
+ get '/bar' => 'bar#index', :as => 'bar'
+ mount Bukkits::Engine => "/bukkits", :as => "bukkits"
+ end
+ RUBY
+
+ @plugin.write "config/routes.rb", <<-RUBY
+ Bukkits::Engine.routes.draw do
+ get '/bukkit' => 'bukkit#index'
+ end
+ RUBY
+
+ @plugin.write "app/controllers/bukkits/bukkit_controller.rb", <<-RUBY
+ class Bukkits::BukkitController < ActionController::Base
+ def index
+ render text: main_app.bar_path
+ end
+ end
+ RUBY
+
+ boot_rails
+
+ get("/bukkits/bukkit", {}, {'SCRIPT_NAME' => '/foo'})
+ assert_equal '/foo/bar', last_response.body
+
+ get("/bar", {}, {'SCRIPT_NAME' => '/foo'})
+ assert_equal '/foo/bukkits/bukkit', last_response.body
+ end
+
private
def app
Rails.application
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..2d08d4ec30 100644
--- a/railties/test/test_unit/reporter_test.rb
+++ b/railties/test/test_unit/reporter_test.rb
@@ -1,5 +1,6 @@
require 'abstract_unit'
require 'rails/test_unit/reporter'
+require 'minitest/mock'
class TestUnitReporterTest < ActiveSupport::TestCase
class ExampleTest < Minitest::Test
@@ -8,14 +9,14 @@ class TestUnitReporterTest < ActiveSupport::TestCase
setup do
@output = StringIO.new
- @reporter = Rails::TestUnitReporter.new @output
+ @reporter = Rails::TestUnitReporter.new @output, output_inline: true
end
test "prints rerun snippet to run a single failed test" do
@reporter.record(failed_test)
@reporter.report
- assert_match %r{^bin/rails test .*test/test_unit/reporter_test.rb:6$}, @output.string
+ assert_match %r{^bin/rails test .*test/test_unit/reporter_test.rb:\d+$}, @output.string
assert_rerun_snippet_count 1
end
@@ -32,6 +33,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 +45,105 @@ 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:\d+$}, @output.string
+ ensure
+ Rails::TestUnitReporter.executable = original_executable
+ end
+ end
+
+ test "outputs failures inline" do
+ @reporter.record(failed_test)
+ @reporter.report
+
+ expect = %r{\AF\n\nFailure:\nTestUnitReporterTest::ExampleTest#woot:\nboo\n\nbin/rails test test/test_unit/reporter_test.rb:\d+\n\n\z}
+ assert_match expect, @output.string
+ end
+
+ test "outputs errors inline" do
+ @reporter.record(errored_test)
+ @reporter.report
+
+ expect = %r{\AE\n\nError:\nTestUnitReporterTest::ExampleTest#woot:\nArgumentError: wups\n No backtrace\n\nbin/rails test .*test/test_unit/reporter_test.rb:\d+\n\n\z}
+ assert_match expect, @output.string
+ end
+
+ test "outputs skipped tests inline if verbose" do
+ verbose = Rails::TestUnitReporter.new @output, verbose: true, output_inline: true
+ verbose.record(skipped_test)
+ verbose.report
+
+ expect = %r{\ATestUnitReporterTest::ExampleTest#woot = 10\.00 s = S\n\n\nSkipped:\nTestUnitReporterTest::ExampleTest#woot:\nskipchurches, misstemples\n\nbin/rails test test/test_unit/reporter_test.rb:\d+\n\n\z}
+ assert_match expect, @output.string
+ end
+
+ test "does not output rerun snippets after run" do
+ @reporter.record(failed_test)
+ @reporter.report
+
+ assert_no_match 'Failed tests:', @output.string
+ end
+
+ test "fail fast interrupts run on failure" do
+ fail_fast = Rails::TestUnitReporter.new @output, fail_fast: true
+ interrupt_raised = false
+
+ # Minitest passes through Interrupt, catch it manually.
+ begin
+ fail_fast.record(failed_test)
+ rescue Interrupt
+ interrupt_raised = true
+ ensure
+ assert interrupt_raised, 'Expected Interrupt to be raised.'
+ end
+ end
+
+ test "fail fast does not interrupt run errors or skips" do
+ fail_fast = Rails::TestUnitReporter.new @output, fail_fast: true
+
+ fail_fast.record(errored_test)
+ assert_no_match 'Failed tests:', @output.string
+
+ fail_fast.record(skipped_test)
+ assert_no_match 'Failed tests:', @output.string
+ end
+
+ test "outputs colored passing results" do
+ @output.stub(:tty?, true) do
+ colored = Rails::TestUnitReporter.new @output, color: true, output_inline: true
+ colored.record(passing_test)
+
+ expect = %r{\e\[32m\.\e\[0m}
+ assert_match expect, @output.string
+ end
+ end
+
+ test "outputs colored skipped results" do
+ @output.stub(:tty?, true) do
+ colored = Rails::TestUnitReporter.new @output, color: true, output_inline: true
+ colored.record(skipped_test)
+
+ expect = %r{\e\[33mS\e\[0m}
+ assert_match expect, @output.string
+ end
+ end
+
+ test "outputs colored failed results" do
+ @output.stub(:tty?, true) do
+ colored = Rails::TestUnitReporter.new @output, color: true, output_inline: true
+ colored.record(errored_test)
+
+ expected = %r{\e\[31mE\e\[0m\n\n\e\[31mError:\nTestUnitReporterTest::ExampleTest#woot:\nArgumentError: wups\n No backtrace\n\e\[0m}
+ assert_match expected, @output.string
+ end
+ end
+
private
def assert_rerun_snippet_count(snippet_count)
assert_equal snippet_count, @output.string.scan(%r{^bin/rails test }).size
@@ -58,6 +159,12 @@ class TestUnitReporterTest < ActiveSupport::TestCase
ft
end
+ def errored_test
+ et = ExampleTest.new(:woot)
+ et.failures << Minitest::UnexpectedError.new(ArgumentError.new("wups"))
+ et
+ end
+
def passing_test
ExampleTest.new(:woot)
end
@@ -65,10 +172,11 @@ class TestUnitReporterTest < ActiveSupport::TestCase
def skipped_test
st = ExampleTest.new(:woot)
st.failures << begin
- raise Minitest::Skip
+ raise Minitest::Skip, "skipchurches, misstemples"
rescue Minitest::Assertion => e
e
end
+ st.time = 10
st
end
end
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