diff options
Diffstat (limited to 'railties')
65 files changed, 1534 insertions, 529 deletions
diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md index 4f7cb8254f..ae13c3ccc9 100644 --- a/railties/CHANGELOG.md +++ b/railties/CHANGELOG.md @@ -1,21 +1,94 @@ ## Rails 4.0.0 (unreleased) ## +* Move rails.png into a data-uri. One less file to get generated into a new + application. This is also consistent with the removal of index.html. + + *Steve Klabnik* + +* The application rake task `doc:rails` generates now an API like the + official one (except for the links to GitHub). + + *Xavier Noria* + +* Allow vanilla apps to render CoffeeScript templates in production + + Vanilla apps already render CoffeeScript templates in development and test + environments. With this change, the production behavior matches that of + the other environments. + + Effectively, this meant moving coffee-rails (and the JavaScript runtime on + which it is dependent) from the :assets group to the top-level of the + generated Gemfile. + + *Gabe Kopley* + +* Don't generate a scaffold.css when --no-assets is specified + + *Kevin Glowacz* + +* Add support for generate scaffold password:digest + + * adds password_digest attribute to the migration + * adds has_secure_password to the model + * adds password and password_confirmation password_fields to _form.html + * omits password from index.html and show.html + * adds password and password_confirmation to the controller + * adds unencrypted password and password_confirmation to the controller test + * adds encrypted password_digest to the fixture + + *Sam Ruby* + +* Rails now generates a `test/test_helper.rb` file with `fixtures :all` commented out by default, + since we don't want to force loading all fixtures for user when a single test is run. However, + fixtures are still going to be loaded automatically for test suites. + + To force all fixtures to be create in your database, use `rails test -f` to run your test. + + *Prem Sichanugrist* + +* Add `rails test` command for running tests + + To run all tests: + + $ rails test + + To run a test suite + + $ rails test [models,helpers,units,controllers,mailers,...] + + To run a selected test file(s): + + $ rails test test/unit/foo_test.rb [test/unit/bar_test.rb ...] + + To run a single test from a test file + + $ rails test test/unit/foo_test.rb -n test_the_truth + + For more information, see `rails test --help`. + + This command will eventually replace `rake test:*` and `rake test` tasks. + + *Prem Sichanugrist and Chris Toomey* + +* Improve service pages with new layout (404, etc). + + *Stanislav Sobolev* + ## Rails 4.0.0.beta1 (February 25, 2013) ## -* Change Service pages(404, etc). *Stanislav Sobolev* * Improve `rake stats` for JavaScript and CoffeeScript: ignore block comments and calculates number of functions. *Hendy Tanata* -* Ability to use a custom builder by passing `--builder` (or `-b`) has been removed. Consider - using application template instead. See this guide for more detail: +* Ability to use a custom builder by passing `--builder` (or `-b`) has been removed. + Consider using application template instead. See this guide for more detail: http://guides.rubyonrails.org/rails_application_templates.html *Prem Sichanugrist* -* fix rake db:* tasks to work with DATABASE_URL and without config/database.yml +* Fix `rake db:*` tasks to work with `DATABASE_URL` and without `config/database.yml`. *Terence Lee* @@ -39,13 +112,13 @@ *Amparo Luna* * Fixes database.yml when creating a new rails application with '.' - Fix #8304 + Fixes #8304. *Jeremy W. Rowe* * Restore Rails::Engine::Railties#engines with deprecation to ensure compatibility with gems such as Thinking Sphinx - Fix #8551 + Fixes #8551. *Tim Raymond* @@ -119,7 +192,7 @@ * Environment name can be a start substring of the default environment names (production, development, test). For example: tes, pro, prod, dev, devel. - Fix #8628. + Fixes #8628. *Mykola Kyryk* @@ -129,7 +202,7 @@ * Quote column names in generates fixture files. This prevents conflicts with reserved YAML keywords such as 'yes' and 'no' - Fix #8612. + Fixes #8612. *Yves Senn* @@ -162,19 +235,19 @@ * Add `db` to list of folders included by `rake notes` and `rake notes:custom`. *Antonio Cangiano* * Engines with a dummy app include the rake tasks of dependencies in the app namespace. - Fix #8229 + Fixes #8229. *Yves Senn* * Add `sqlserver.yml` template file to satisfy `-d sqlserver` being passed to `rails new`. - Fix #6882 + Fixes #6882. *Robert Nesius* * Rake test:uncommitted finds git directory in ancestors *Nicolas Despres* * Add dummy app Rake tasks when `--skip-test-unit` and `--dummy-path` is passed to the plugin generator. - Fix #8121 + Fixes #8121. *Yves Senn* @@ -216,17 +289,25 @@ *Derek Prior & Francesco Rodriguez* -* Fixed support for DATABASE_URL environment variable for rake db tasks. *Grace Liu* +* Fixed support for `DATABASE_URL` environment variable for rake db tasks. + + *Grace Liu* -* rails dbconsole now can use SSL for MySQL. The database.yml options sslca, sslcert, sslcapath, sslcipher, - and sslkey now affect rails dbconsole. *Jim Kingdon and Lars Petrus* +* `rails dbconsole` now can use SSL for MySQL. The `database.yml` options sslca, sslcert, sslcapath, sslcipher + and sslkey now affect `rails dbconsole`. + + *Jim Kingdon and Lars Petrus* * Correctly handle SCRIPT_NAME when generating routes to engine in application that's mounted at a sub-uri. With this behavior, you *should not* use - default_url_options[:script_name] to set proper application's mount point by - yourself. *Piotr Sarnacki* + `default_url_options[:script_name]` to set proper application's mount point by + yourself. + + *Piotr Sarnacki* + +* `config.threadsafe!` is deprecated in favor of `config.eager_load` which provides a more fine grained control on what is eager loaded . -* `config.threadsafe!` is deprecated in favor of `config.eager_load` which provides a more fine grained control on what is eager loaded *José Valim* + *José Valim* * The migration generator will now produce AddXXXToYYY/RemoveXXXFromYYY migrations with references statements, for instance @@ -249,21 +330,35 @@ *Aleksey Magusev* -* Set `config.active_record.migration_error` to `:page_load` for development *Richard Schneeman* +* Set `config.active_record.migration_error` to `:page_load` for development. -* Add runner to Rails::Railtie as a hook called just after runner starts. *José Valim & kennyj* + *Richard Schneeman* -* Add `/rails/info/routes` path, displays same information as `rake routes` *Richard Schneeman & Andrew White* +* Add runner to `Rails::Railtie` as a hook called just after runner starts. -* Improved `rake routes` output for redirects *Łukasz Strzałkowski & Andrew White* + *José Valim & kennyj* -* Load all environments available in `config.paths["config/environments"]`. *Piotr Sarnacki* +* Add `/rails/info/routes` path, displays same information as `rake routes` . -* Remove Rack::SSL in favour of ActionDispatch::SSL. *Rafael Mendonça França* + *Richard Schneeman & Andrew White* -* Remove Active Resource from Rails framework. *Prem Sichangrist* +* Improved `rake routes` output for redirects. -* Allow to set class that will be used to run as a console, other than IRB, with `Rails.application.config.console=`. It's best to add it to `console` block. *Piotr Sarnacki* + *Łukasz Strzałkowski & Andrew White* + +* Load all environments available in `config.paths["config/environments"]`. + + *Piotr Sarnacki* + +* Remove `Rack::SSL` in favour of `ActionDispatch::SSL`. + + *Rafael Mendonça França* + +* Remove Active Resource from Rails framework. + + *Prem Sichangrist* + +* Allow to set class that will be used to run as a console, other than IRB, with `Rails.application.config.console=`. It's best to add it to `console` block. Example: @@ -275,12 +370,20 @@ config.console = Pry end + *Piotr Sarnacki* + * Add convenience `hide!` method to Rails generators to hide current generator - namespace from showing when running `rails generate`. *Carlos Antonio da Silva* + namespace from showing when running `rails generate`. + + *Carlos Antonio da Silva* -* Rails::Plugin has gone. Instead of adding plugins to vendor/plugins use gems or bundler with path or git dependencies. *Santiago Pastorino* +* Rails::Plugin has gone. Instead of adding plugins to vendor/plugins use gems or bundler with path or git dependencies. + + *Santiago Pastorino* * Set config.action_mailer.async = true to turn on asynchronous - message delivery *Brian Cardarella* + message delivery. + + *Brian Cardarella* Please check [3-2-stable](https://github.com/rails/rails/blob/3-2-stable/railties/CHANGELOG.md) for previous changes. diff --git a/railties/RDOC_MAIN.rdoc b/railties/RDOC_MAIN.rdoc new file mode 100644 index 0000000000..cadf0fb43e --- /dev/null +++ b/railties/RDOC_MAIN.rdoc @@ -0,0 +1,73 @@ +== Welcome to \Rails + +\Rails is a web-application framework that includes everything needed to create +database-backed web applications according to the {Model-View-Controller (MVC)}[http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller] pattern. + +Understanding the MVC pattern is key to understanding \Rails. MVC divides your application +into three layers, each with a specific responsibility. + +The View layer is composed of "templates" that are responsible for providing +appropriate representations of your application's resources. Templates +can come in a variety of formats, but most view templates are \HTML with embedded Ruby +code (.erb files). + +The Model layer represents your domain model (such as Account, Product, Person, Post) +and encapsulates the business logic that is specific to your application. In \Rails, +database-backed model classes are derived from ActiveRecord::Base. Active Record allows +you to present the data from database rows as objects and embellish these data objects +with business logic methods. Although most \Rails models are backed by a database, models +can also be ordinary Ruby classes, or Ruby classes that implement a set of interfaces as +provided by the ActiveModel module. You can read more about Active Record in its +{README}[link:/activerecord/README.rdoc]. + +The Controller layer is responsible for handling incoming HTTP requests and providing a +suitable response. Usually this means returning \HTML, but \Rails controllers can also +generate XML, JSON, PDFs, mobile-specific views, and more. Controllers manipulate models +and render view templates in order to generate the appropriate HTTP response. + +In \Rails, the Controller and View layers are handled together by Action Pack. +These two layers are bundled in a single package due to their heavy interdependence. +This is unlike the relationship between Active Record and Action Pack, which are +independent. Each of these packages can be used independently outside of \Rails. You +can read more about Action Pack in its {README}[link:/actionpack/README.rdoc]. + +== Getting Started + +1. Install \Rails at the command prompt if you haven't yet: + + gem install rails + +2. At the command prompt, create a new \Rails application: + + rails new myapp + + where "myapp" is the application name. + +3. Change directory to +myapp+ and start the web server: + + cd myapp; rails server + + Run with <tt>--help</tt> or <tt>-h</tt> for options. + +4. Go to http://localhost:3000 and you'll see: + + "Welcome aboard: You're riding Ruby on Rails!" + +5. Follow the guidelines to start developing your application. You may find the following resources handy: + +* 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 Guides}[http://guides.rubyonrails.org]. +* {The API Documentation}[http://api.rubyonrails.org]. + +== Contributing + +We encourage you to contribute to Ruby on \Rails! Please check out the {Contributing to Rails +guide}[http://edgeguides.rubyonrails.org/contributing_to_ruby_on_rails.html] for guidelines about how +to proceed. {Join us}[http://contributors.rubyonrails.org]! + + +== License + +Ruby on \Rails is released under the {MIT License}[http://www.opensource.org/licenses/MIT]. diff --git a/railties/Rakefile b/railties/Rakefile index 8576275aea..a9cb37776d 100644 --- a/railties/Rakefile +++ b/railties/Rakefile @@ -6,6 +6,8 @@ require 'rbconfig' task :default => :test + +desc "Run all unit tests" task :test => 'test:isolated' namespace :test do @@ -20,7 +22,7 @@ namespace :test do "#{File.dirname(__FILE__)}/../actionpack/lib", "#{File.dirname(__FILE__)}/../activemodel/lib" ] - ruby "-I#{dash_i.join ':'}", file + ruby "-w", "-I#{dash_i.join ':'}", file end end end diff --git a/railties/lib/rails/all.rb b/railties/lib/rails/all.rb index 6c9c53fc69..19c2226619 100644 --- a/railties/lib/rails/all.rb +++ b/railties/lib/rails/all.rb @@ -1,5 +1,9 @@ require "rails" +if defined?(Rake) && Rake.application.top_level_tasks.grep(/^test(?::|$)/).any? + ENV['RAILS_ENV'] ||= 'test' +end + %w( active_record action_controller diff --git a/railties/lib/rails/api/task.rb b/railties/lib/rails/api/task.rb new file mode 100644 index 0000000000..c829873da4 --- /dev/null +++ b/railties/lib/rails/api/task.rb @@ -0,0 +1,158 @@ +require 'rdoc/task' + +module Rails + module API + class Task < RDoc::Task + RDOC_FILES = { + 'activesupport' => { + :include => %w( + README.rdoc + CHANGELOG.md + lib/active_support/**/*.rb + ), + :exclude => 'lib/active_support/vendor/*' + }, + + 'activerecord' => { + :include => %w( + README.rdoc + CHANGELOG.md + lib/active_record/**/*.rb + ), + :exclude => 'lib/active_record/vendor/*' + }, + + 'activemodel' => { + :include => %w( + README.rdoc + CHANGELOG.md + lib/active_model/**/*.rb + ) + }, + + 'actionpack' => { + :include => %w( + README.rdoc + CHANGELOG.md + lib/abstract_controller/**/*.rb + lib/action_controller/**/*.rb + lib/action_dispatch/**/*.rb + lib/action_view/**/*.rb + ), + :exclude => 'lib/action_controller/vendor/*' + }, + + 'actionmailer' => { + :include => %w( + README.rdoc + CHANGELOG.md + lib/action_mailer/**/*.rb + ), + :exclude => 'lib/action_mailer/vendor/*' + }, + + 'railties' => { + :include => %w( + README.rdoc + CHANGELOG.md + MIT-LICENSE + lib/**/*.rb + ), + :exclude => 'lib/rails/generators/rails/**/templates/**/*.rb' + } + } + + def initialize(name) + super + + # Every time rake runs this task is instantiated as all the rest. + # Be lazy computing stuff to have as light impact as possible to + # the rest of tasks. + before_running_rdoc do + load_and_configure_sdoc + configure_rdoc_files + setup_horo_variables + end + end + + # Hack, ignore the desc calls performed by the original initializer. + def desc(description) + # no-op + end + + def load_and_configure_sdoc + require 'sdoc' + + self.title = 'Ruby on Rails API' + self.rdoc_dir = api_dir + + options << '-m' << api_main + options << '-e' << 'UTF-8' + + options << '-f' << 'sdoc' + options << '-T' << 'rails' + rescue LoadError + $stderr.puts %(Unable to load SDoc, please add\n\n gem 'sdoc', require: false\n\nto the Gemfile.) + exit 1 + end + + def configure_rdoc_files + rdoc_files.include(api_main) + + RDOC_FILES.each do |component, cfg| + cdr = component_root_dir(component) + + Array(cfg[:include]).each do |pattern| + rdoc_files.include("#{cdr}/#{pattern}") + end + + Array(cfg[:exclude]).each do |pattern| + rdoc_files.exclude("#{cdr}/#{pattern}") + end + end + end + + def setup_horo_variables + ENV['HORO_PROJECT_NAME'] = 'Ruby on Rails' + ENV['HORO_PROJECT_VERSION'] = rails_version + end + + def api_main + component_root_dir('railties') + '/RDOC_MAIN.rdoc' + end + end + + class RepoTask < Task + def load_and_configure_sdoc + super + options << '-g' # link to GitHub, SDoc flag + end + + def component_root_dir(component) + component + end + + def api_dir + 'doc/rdoc' + end + + def rails_version + "master@#{`git rev-parse HEAD`[0, 7]}" + end + end + + class AppTask < Task + def component_root_dir(gem_name) + $:.grep(%r{#{gem_name}[\w.-]*/lib\z}).first[0..-5] + end + + def api_dir + 'doc/api' + end + + def rails_version + Rails::VERSION::STRING + end + end + end +end diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb index 25cc36ff5d..2d5aa9d952 100644 --- a/railties/lib/rails/application.rb +++ b/railties/lib/rails/application.rb @@ -1,5 +1,5 @@ require 'fileutils' -# FIXME remove DummyKeyGenerator and this require in 4.1 +require 'active_support/core_ext/object/blank' require 'active_support/key_generator' require 'rails/engine' @@ -46,10 +46,10 @@ module Rails # 6) Run config.before_initialize callbacks # 7) Run Railtie#initializer defined by railties, engines and application. # One by one, each engine sets up its load paths, routes and runs its config/initializers/* files. - # 9) Custom Railtie#initializers added by railties, engines and applications are executed - # 10) Build the middleware stack and run to_prepare callbacks - # 11) Run config.before_eager_load and eager_load! if eager_load is true - # 12) Run config.after_initialize callbacks + # 8) Custom Railtie#initializers added by railties, engines and applications are executed + # 9) Build the middleware stack and run to_prepare callbacks + # 10) Run config.before_eager_load and eager_load! if eager_load is true + # 11) Run config.after_initialize callbacks # class Application < Engine autoload :Bootstrap, 'rails/application/bootstrap' @@ -79,7 +79,7 @@ module Rails @initialized = false @reloaders = [] @routes_reloader = nil - @env_config = nil + @app_env_config = nil @ordered_railties = nil @railties = nil end @@ -111,7 +111,7 @@ module Rails key_generator = ActiveSupport::KeyGenerator.new(config.secret_key_base, iterations: 1000) ActiveSupport::CachingKeyGenerator.new(key_generator) else - ActiveSupport::DummyKeyGenerator.new(config.secret_token) + ActiveSupport::LegacyKeyGenerator.new(config.secret_token) end end end @@ -122,7 +122,8 @@ module Rails # # * "action_dispatch.parameter_filter" => config.filter_parameters # * "action_dispatch.redirect_filter" => config.filter_redirect - # * "action_dispatch.secret_token" => config.secret_token, + # * "action_dispatch.secret_token" => config.secret_token + # * "action_dispatch.secret_key_base" => config.secret_key_base # * "action_dispatch.show_exceptions" => config.action_dispatch.show_exceptions # * "action_dispatch.show_detailed_exceptions" => config.consider_all_requests_local # * "action_dispatch.logger" => Rails.logger @@ -134,14 +135,13 @@ module Rails # * "action_dispatch.encrypted_signed_cookie_salt" => config.action_dispatch.encrypted_signed_cookie_salt # def env_config - @env_config ||= begin - if config.secret_key_base.nil? - ActiveSupport::Deprecation.warn "You didn't set config.secret_key_base in config/initializers/secret_token.rb file. " + - "This should be used instead of the old deprecated config.secret_token in order to use the new EncryptedCookieStore. " + - "To convert safely to the encrypted store (without losing existing cookies and sessions), see http://guides.rubyonrails.org/upgrading_ruby_on_rails.html#action-pack" + @app_env_config ||= begin + if config.secret_key_base.blank? + ActiveSupport::Deprecation.warn "You didn't set config.secret_key_base. " + + "Read the upgrade documentation to learn more about this new config option." if config.secret_token.blank? - raise "You must set config.secret_key_base in your app's config" + raise "You must set config.secret_key_base in your app's config." end end @@ -149,6 +149,7 @@ module Rails "action_dispatch.parameter_filter" => config.filter_parameters, "action_dispatch.redirect_filter" => config.filter_redirect, "action_dispatch.secret_token" => config.secret_token, + "action_dispatch.secret_key_base" => config.secret_key_base, "action_dispatch.show_exceptions" => config.action_dispatch.show_exceptions, "action_dispatch.show_detailed_exceptions" => config.consider_all_requests_local, "action_dispatch.logger" => Rails.logger, diff --git a/railties/lib/rails/commands.rb b/railties/lib/rails/commands.rb index aacde52cfc..41d3722c18 100644 --- a/railties/lib/rails/commands.rb +++ b/railties/lib/rails/commands.rb @@ -5,6 +5,7 @@ aliases = { "d" => "destroy", "c" => "console", "s" => "server", + "t" => "test", "db" => "dbconsole", "r" => "runner" } @@ -16,6 +17,7 @@ The most common rails commands are: generate Generate new code (short-cut alias: "g") console Start the Rails console (short-cut alias: "c") server Start the Rails server (short-cut alias: "s") + test Running the test file (short-cut alias: "t") dbconsole Start a console for the database specified in config/database.yml (short-cut alias: "db") new Create a new Rails application. "rails new my_app" creates a @@ -78,6 +80,15 @@ when 'server' server.start end +when 'test' + $LOAD_PATH.unshift("./test") + require 'rails/commands/test_runner' + options = Rails::TestRunner.parse_arguments(ARGV) + ENV['RAILS_ENV'] ||= options[:environment] || 'test' + + require APP_PATH + Rails::TestRunner.start(ARGV, options) + when 'dbconsole' require 'rails/commands/dbconsole' Rails::DBConsole.start diff --git a/railties/lib/rails/commands/console.rb b/railties/lib/rails/commands/console.rb index 86ab1aabbf..96229bb4f6 100644 --- a/railties/lib/rails/commands/console.rb +++ b/railties/lib/rails/commands/console.rb @@ -46,7 +46,10 @@ module Rails def initialize(app, options={}) @app = app @options = options + + app.sandbox = sandbox? app.load_console + @console = app.config.console || IRB end @@ -71,7 +74,6 @@ module Rails end def start - app.sandbox = sandbox? require_debugger if debugger? set_environment! if environment? diff --git a/railties/lib/rails/commands/server.rb b/railties/lib/rails/commands/server.rb index cdb29a8156..e3119ecf22 100644 --- a/railties/lib/rails/commands/server.rb +++ b/railties/lib/rails/commands/server.rb @@ -42,8 +42,12 @@ module Rails set_environment end + # TODO: this is no longer required but we keep it for the moment to support older config.ru files. def app - @app ||= super.respond_to?(:to_app) ? super.to_app : super + @app ||= begin + app = super + app.respond_to?(:to_app) ? app.to_app : app + end end def opt_parser @@ -58,7 +62,7 @@ module Rails url = "#{options[:SSLEnable] ? 'https' : 'http'}://#{options[:Host]}:#{options[:Port]}" puts "=> Booting #{ActiveSupport::Inflector.demodulize(server)}" puts "=> Rails #{Rails.version} application starting in #{Rails.env} on #{url}" - puts "=> Call with -d to detach" unless options[:daemonize] + puts "=> Run `rails server -h` for more startup options" trap(:INT) { exit } puts "=> Ctrl-C to shutdown server" unless options[:daemonize] diff --git a/railties/lib/rails/commands/test_runner.rb b/railties/lib/rails/commands/test_runner.rb new file mode 100644 index 0000000000..d8857bd183 --- /dev/null +++ b/railties/lib/rails/commands/test_runner.rb @@ -0,0 +1,146 @@ +require 'optparse' +require 'minitest/unit' + +module Rails + # Handles all logic behind +rails test+ command. + class TestRunner + class << self + # Creates a new +TestRunner+ object with an array of test files to run + # based on the arguments. When no arguments are provided, it runs all test + # files. When a suite argument is provided, it runs only the test files in + # that suite. Otherwise, it runs the specified test file(s). + def start(files, options = {}) + original_fixtures_options = options.delete(:fixtures) + options[:fixtures] = true + + case files.first + when nil + new(Dir['test/**/*_test.rb'], options).run + when 'models' + new(Dir['test/models/**/*_test.rb'], options).run + when 'helpers' + new(Dir['test/helpers/**/*_test.rb'], options).run + when 'units' + new(Dir['test/{models,helpers,unit}/**/*_test.rb'], options).run + when 'controllers' + new(Dir['test/controllers/**/*_test.rb'], options).run + when 'mailers' + new(Dir['test/mailers/**/*_test.rb'], options).run + when 'functionals' + new(Dir['test/{controllers,mailers,functional}/**/*_test.rb'], options).run + when 'integration' + new(Dir['test/integration/**/*_test.rb'], options).run + else + options[:fixtures] = original_fixtures_options + new(files, options).run + end + end + + # Parses arguments and sets them as option flags + def parse_arguments(arguments) + options = {} + orig_arguments = arguments.dup + + OptionParser.new do |opts| + opts.banner = "Usage: rails test [path to test file(s) or test suite]" + + opts.separator "" + opts.separator "Run a specific test file(s) or a test suite, under Rails'" + opts.separator "environment. If the file name(s) or suit name is omitted," + opts.separator "Rails will run all tests." + opts.separator "" + opts.separator "Specific options:" + + opts.on '-h', '--help', 'Display this help.' do + puts opts + exit + end + + opts.on '-e', '--environment NAME', String, 'Specifies the environment to run this test under' do |e| + options[:environment] = e + end + + opts.on '-f', '--fixtures', 'Load fixtures in test/fixtures/ before running the tests' do + options[:fixtures] = true + end + + opts.on '-s', '--seed SEED', Integer, "Sets random seed" do |m| + options[:seed] = m.to_i + end + + opts.on '-v', '--verbose', "Verbose. Show progress processing files." do + options[:verbose] = true + end + + opts.on '-n', '--name PATTERN', "Filter test names on pattern (e.g. /foo/)" do |n| + options[:filter] = n + end + + opts.separator "" + opts.separator "Support types of test suites:" + opts.separator "-------------------------------------------------------------" + opts.separator "* models (test/models/**/*)" + opts.separator "* helpers (test/helpers/**/*)" + opts.separator "* units (test/{models,helpers,unit}/**/*" + opts.separator "* controllers (test/controllers/**/*)" + opts.separator "* mailers (test/mailers/**/*)" + opts.separator "* functionals (test/{controllers,mailers,functional}/**/*)" + opts.separator "* integration (test/integration/**/*)" + opts.separator "-------------------------------------------------------------" + + opts.parse! arguments + orig_arguments -= arguments + end + options + end + end + + # Creates a new +TestRunner+ object with a list of test file paths. + def initialize(files, options) + @files = files + + Rails.application.load_tasks + Rake::Task['db:test:load'].invoke + + if options.delete(:fixtures) + if defined?(ActiveRecord::Base) + ActiveSupport::TestCase.send :include, ActiveRecord::TestFixtures + ActiveSupport::TestCase.fixture_path = "#{Rails.root}/test/fixtures/" + ActiveSupport::TestCase.fixtures :all + end + end + + MiniTest::Unit.runner.options = options + MiniTest::Unit.output = SilentUntilSyncStream.new(MiniTest::Unit.output) + end + + # Runs test files by evaluating each of them. + def run + @files.each { |filename| load(filename) } + end + + # A null stream object which ignores everything until +sync+ has been set + # to true. This is only used to silence unnecessary output from MiniTest, + # as MiniTest calls +output.sync = true+ right before it outputs the first + # test result. + class SilentUntilSyncStream < File + # Creates a +SilentUntilSyncStream+ object by giving it a target stream + # object that will be assigned to +MiniTest::Unit.output+ after +sync+ is + # set to true. + def initialize(target_stream) + @target_stream = target_stream + super(File::NULL, 'w') + end + + # Swaps +MiniTest::Unit.output+ to another stream when +sync+ is true. + def sync=(sync) + if sync + @target_stream.sync = true + MiniTest::Unit.output = @target_stream + end + + super + end + end + end +end diff --git a/railties/lib/rails/engine.rb b/railties/lib/rails/engine.rb index 579af8c6a5..93504b3b35 100644 --- a/railties/lib/rails/engine.rb +++ b/railties/lib/rails/engine.rb @@ -107,7 +107,7 @@ module Rails # # The <tt>Application</tt> class adds a couple more paths to this set. And as in your # <tt>Application</tt>, all folders under +app+ are automatically added to the load path. - # If you have an <tt>app/services/tt> folder for example, it will be added by default. + # If you have an <tt>app/services</tt> folder for example, it will be added by default. # # == Endpoint # diff --git a/railties/lib/rails/generators/app_base.rb b/railties/lib/rails/generators/app_base.rb index 4e703151ba..de14186a09 100644 --- a/railties/lib/rails/generators/app_base.rb +++ b/railties/lib/rails/generators/app_base.rb @@ -178,31 +178,46 @@ module Rails return if options[:skip_sprockets] gemfile = if options.dev? || options.edge? - <<-GEMFILE - # Gems used only for assets and not required - # in production environments by default. - group :assets do - gem 'sprockets-rails', github: 'rails/sprockets-rails' - gem 'sass-rails', github: 'rails/sass-rails' - gem 'coffee-rails', github: 'rails/coffee-rails' - - # See https://github.com/sstephenson/execjs#readme for more supported runtimes - #{javascript_runtime_gemfile_entry} - gem 'uglifier', '>= 1.0.3' - end + <<-GEMFILE.gsub(/^ {12}/, '') + # Use edge version of sprockets-rails + gem 'sprockets-rails', github: 'rails/sprockets-rails' + + # Use SCSS for stylesheets + gem 'sass-rails', github: 'rails/sass-rails' + + # To use Uglifier as compressor for JavaScript assets + gem 'uglifier', '>= 1.3.0' + GEMFILE + else + <<-GEMFILE.gsub(/^ {12}/, '') + # Use SCSS for stylesheets + gem 'sass-rails', '~> 4.0.0.beta1' + + # To use Uglifier as compressor for JavaScript assets + gem 'uglifier', '>= 1.3.0' + GEMFILE + end + + if options[:skip_javascript] + gemfile += <<-GEMFILE.gsub(/^ {12}/, '') + #{coffee_gemfile_entry} + #{javascript_runtime_gemfile_entry} + GEMFILE + end + + gemfile.strip_heredoc.gsub(/^[ \t]*$/, '') + end + + def coffee_gemfile_entry + gemfile = if options.dev? || options.edge? + <<-GEMFILE.gsub(/^ {12}/, '') + # Use CoffeeScript for .js.coffee assets and views + gem 'coffee-rails', github: 'rails/coffee-rails' GEMFILE else - <<-GEMFILE - # Gems used only for assets and not required - # in production environments by default. - group :assets do - gem 'sass-rails', '~> 4.0.0.beta1' - gem 'coffee-rails', '~> 4.0.0.beta1' - - # See https://github.com/sstephenson/execjs#readme for more supported runtimes - #{javascript_runtime_gemfile_entry} - gem 'uglifier', '>= 1.0.3' - end + <<-GEMFILE.gsub(/^ {12}/, '') + # Use CoffeeScript for .js.coffee assets and views + gem 'coffee-rails', '~> 4.0.0.beta1' GEMFILE end @@ -211,7 +226,10 @@ module Rails def javascript_gemfile_entry unless options[:skip_javascript] - <<-GEMFILE.strip_heredoc + <<-GEMFILE.gsub(/^ {12}/, '').strip_heredoc + #{coffee_gemfile_entry} + #{javascript_runtime_gemfile_entry} + gem '#{options[:javascript]}-rails' # Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks @@ -221,11 +239,15 @@ module Rails end def javascript_runtime_gemfile_entry - if defined?(JRUBY_VERSION) - "gem 'therubyrhino'\n" + runtime = if defined?(JRUBY_VERSION) + "gem 'therubyrhino'" else - "# gem 'therubyracer', platforms: :ruby\n" + "# gem 'therubyracer', platforms: :ruby" end + <<-GEMFILE.gsub(/^ {10}/, '') + # See https://github.com/sstephenson/execjs#readme for more supported runtimes + #{runtime} + GEMFILE end def bundle_command(command) 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 32546936e3..85a1b01cc6 100644 --- a/railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb +++ b/railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb @@ -13,8 +13,17 @@ <% attributes.each do |attribute| -%> <div class="field"> +<% if attribute.password_digest? -%> + <%%= f.label :password %><br /> + <%%= f.password_field :password %> + </div> + <div> + <%%= f.label :password_confirmation %><br /> + <%%= f.password_field :password_confirmation %> +<% else -%> <%%= f.label :<%= attribute.name %> %><br /> <%%= f.<%= attribute.field_type %> :<%= attribute.name %> %> +<% end -%> </div> <% end -%> <div class="actions"> 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 90d8db1df5..d2fd99fdcb 100644 --- a/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb +++ b/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb @@ -3,7 +3,7 @@ <table> <thead> <tr> -<% attributes.each do |attribute| -%> +<% attributes.reject(&:password_digest?).each do |attribute| -%> <th><%= attribute.human_name %></th> <% end -%> <th></th> @@ -15,7 +15,7 @@ <tbody> <%% @<%= plural_table_name %>.each do |<%= singular_table_name %>| %> <tr> -<% attributes.each do |attribute| -%> +<% attributes.reject(&:password_digest?).each do |attribute| -%> <td><%%= <%= singular_table_name %>.<%= attribute.name %> %></td> <% end -%> <td><%%= link_to 'Show', <%= singular_table_name %> %></td> diff --git a/railties/lib/rails/generators/erb/scaffold/templates/show.html.erb b/railties/lib/rails/generators/erb/scaffold/templates/show.html.erb index daae72270f..5e634153be 100644 --- a/railties/lib/rails/generators/erb/scaffold/templates/show.html.erb +++ b/railties/lib/rails/generators/erb/scaffold/templates/show.html.erb @@ -1,6 +1,6 @@ <p id="notice"><%%= notice %></p> -<% attributes.each do |attribute| -%> +<% attributes.reject(&:password_digest?).each do |attribute| -%> <p> <strong><%= attribute.human_name %>:</strong> <%%= @<%= singular_table_name %>.<%= attribute.name %> %> diff --git a/railties/lib/rails/generators/generated_attribute.rb b/railties/lib/rails/generators/generated_attribute.rb index 4ae8756ed0..5e2784c4b0 100644 --- a/railties/lib/rails/generators/generated_attribute.rb +++ b/railties/lib/rails/generators/generated_attribute.rb @@ -130,6 +130,10 @@ module Rails @has_uniq_index end + def password_digest? + name == 'password' && type == :digest + end + def inject_options "".tap { |s| @attr_options.each { |k,v| s << ", #{k}: #{v.inspect}" } } end diff --git a/railties/lib/rails/generators/named_base.rb b/railties/lib/rails/generators/named_base.rb index 9965db98de..d891ba1215 100644 --- a/railties/lib/rails/generators/named_base.rb +++ b/railties/lib/rails/generators/named_base.rb @@ -40,7 +40,7 @@ module Rails def indent(content, multiplier = 2) spaces = " " * multiplier - content = content.each_line.map {|line| line.blank? ? line : "#{spaces}#{line}" }.join + content.each_line.map {|line| line.blank? ? line : "#{spaces}#{line}" }.join end def wrap_with_namespace(content) @@ -163,6 +163,7 @@ module Rails def attributes_names @attributes_names ||= attributes.each_with_object([]) do |a, names| names << a.column_name + names << 'password_confirmation' if a.password_digest? names << "#{a.name}_type" if a.polymorphic? end end diff --git a/railties/lib/rails/generators/rails/app/templates/Gemfile b/railties/lib/rails/generators/rails/app/templates/Gemfile index b5db3d2187..07cf31dd83 100644 --- a/railties/lib/rails/generators/rails/app/templates/Gemfile +++ b/railties/lib/rails/generators/rails/app/templates/Gemfile @@ -9,6 +9,11 @@ source 'https://rubygems.org' <%= assets_gemfile_entry %> <%= javascript_gemfile_entry -%> +group :doc do + # bundle exec rake doc:rails generates the API under doc/api. + gem 'sdoc', require: false +end + # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder gem 'jbuilder', '~> 1.0.1' @@ -23,5 +28,5 @@ gem 'jbuilder', '~> 1.0.1' <% unless defined?(JRUBY_VERSION) -%> # To use debugger -# gem 'debugger' +# gem 'debugger', group: [:development, :test] <% end -%> diff --git a/railties/lib/rails/generators/rails/app/templates/app/assets/images/.keep b/railties/lib/rails/generators/rails/app/templates/app/assets/images/.keep new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/railties/lib/rails/generators/rails/app/templates/app/assets/images/.keep diff --git a/railties/lib/rails/generators/rails/app/templates/app/assets/images/rails.png b/railties/lib/rails/generators/rails/app/templates/app/assets/images/rails.png Binary files differdeleted file mode 100644 index d5edc04e65..0000000000 --- a/railties/lib/rails/generators/rails/app/templates/app/assets/images/rails.png +++ /dev/null diff --git a/railties/lib/rails/generators/rails/app/templates/config.ru b/railties/lib/rails/generators/rails/app/templates/config.ru index fcfbc6b07a..5bc2a619e8 100644 --- a/railties/lib/rails/generators/rails/app/templates/config.ru +++ b/railties/lib/rails/generators/rails/app/templates/config.ru @@ -1,4 +1,4 @@ # This file is used by Rack-based servers to start the application. require ::File.expand_path('../config/environment', __FILE__) -run <%= app_const %> +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 daf399a538..ceb2bdf371 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/application.rb +++ b/railties/lib/rails/generators/rails/app/templates/config/application.rb @@ -11,8 +11,9 @@ require "action_mailer/railtie" <%= comment_if :skip_test_unit %>require "rails/test_unit/railtie" <% end -%> -# Assets should be precompiled for production (so we don't need the gems loaded then) -Bundler.require(*Rails.groups(assets: %w(development test))) +# Require the gems listed in Gemfile, including any gems +# you've limited to :test, :development, or :production. +Bundler.require(:default, Rails.env) module <%= app_const_base %> class Application < Rails::Application 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 d0e62d09cc..8b64881dbc 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 @@ -26,6 +26,8 @@ <%- unless options.skip_sprockets? -%> # Debug mode disables concatenation and preprocessing of assets. + # This option may cause significant delays in view rendering with a large + # number of complex assets. config.assets.debug = true <%- end -%> 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 5669fe6d64..c40eef145f 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 @@ -24,10 +24,10 @@ <%- unless options.skip_sprockets? -%> # Compress JavaScripts and CSS. - config.assets.js_compressor = :uglifier + config.assets.js_compressor = :uglifier # config.assets.css_compressor = :sass - # Whether to fallback to assets pipeline if a precompiled asset is missed. + # Do not fallback to assets pipeline if a precompiled asset is missed. config.assets.compile = false # Generate digests for assets URLs. diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/secret_token.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/initializers/secret_token.rb.tt index e5caab3672..efccf72d3d 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/initializers/secret_token.rb.tt +++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/secret_token.rb.tt @@ -1,6 +1,6 @@ # Be sure to restart your server when you modify this file. -# Your secret key for verifying the integrity of signed cookies. +# Your secret key is used for verifying the integrity of signed cookies. # If you change this key, all old signed cookies will become invalid! # Make sure the secret is at least 30 characters and all random, diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/session_store.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/initializers/session_store.rb.tt index df07de9922..4a099a4ce2 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/initializers/session_store.rb.tt +++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/session_store.rb.tt @@ -1,3 +1,3 @@ # Be sure to restart your server when you modify this file. -<%= app_const %>.config.session_store :encrypted_cookie_store, key: <%= "'_#{app_name}_session'" %> +<%= app_const %>.config.session_store :cookie_store, key: <%= "'_#{app_name}_session'" %> diff --git a/railties/lib/rails/generators/rails/app/templates/public/404.html b/railties/lib/rails/generators/rails/app/templates/public/404.html index 0ee82d3722..a0daa0c156 100644 --- a/railties/lib/rails/generators/rails/app/templates/public/404.html +++ b/railties/lib/rails/generators/rails/app/templates/public/404.html @@ -2,16 +2,15 @@ <html> <head> <title>The page you were looking for doesn't exist (404)</title> - <style> - body - { - background-color: #efefef; + <style> + body { + background-color: #EFEFEF; color: #2E2F30; text-align: center; - font-family: arial,sans-serif; + font-family: arial, sans-serif; } - div.dialog - { + + div.dialog { width: 25em; margin: 4em auto 0 auto; border: 1px solid #CCC; @@ -24,17 +23,18 @@ background-color: white; padding: 7px 4em 0 4em; } - h1{ + + h1 { font-size: 100%; color: #730E15; line-height: 1.5em; } - body>p - { - width: 33em; + + body > p { + width: 33em; margin: 0 auto 1em; padding: 1em 0; - background-color: #f7f7f7; + background-color: #F7F7F7; border: 1px solid #CCC; border-right-color: #999; border-bottom-color: #999; @@ -42,7 +42,7 @@ border-bottom-right-radius: 4px; border-top-color: #DADADA; color: #666; - box-shadow:0 3px 8px rgba(50,50,50,0.17); + box-shadow:0 3px 8px rgba(50, 50, 50, 0.17); } </style> </head> diff --git a/railties/lib/rails/generators/rails/app/templates/public/422.html b/railties/lib/rails/generators/rails/app/templates/public/422.html index f1f32b83ae..fbb4b84d72 100644 --- a/railties/lib/rails/generators/rails/app/templates/public/422.html +++ b/railties/lib/rails/generators/rails/app/templates/public/422.html @@ -2,16 +2,15 @@ <html> <head> <title>The change you wanted was rejected (422)</title> - <style> - body - { - background-color: #efefef; + <style> + body { + background-color: #EFEFEF; color: #2E2F30; text-align: center; - font-family: arial,sans-serif; + font-family: arial, sans-serif; } - div.dialog - { + + div.dialog { width: 25em; margin: 4em auto 0 auto; border: 1px solid #CCC; @@ -24,17 +23,18 @@ background-color: white; padding: 7px 4em 0 4em; } - h1{ + + h1 { font-size: 100%; color: #730E15; line-height: 1.5em; } - body>p - { + + body > p { width: 33em; margin: 0 auto 1em; padding: 1em 0; - background-color: #f7f7f7; + background-color: #F7F7F7; border: 1px solid #CCC; border-right-color: #999; border-bottom-color: #999; @@ -42,7 +42,7 @@ border-bottom-right-radius: 4px; border-top-color: #DADADA; color: #666; - box-shadow:0 3px 8px rgba(50,50,50,0.17); + box-shadow:0 3px 8px rgba(50, 50, 50, 0.17); } </style> </head> diff --git a/railties/lib/rails/generators/rails/app/templates/public/500.html b/railties/lib/rails/generators/rails/app/templates/public/500.html index 9417de0cc0..e9052d35bf 100644 --- a/railties/lib/rails/generators/rails/app/templates/public/500.html +++ b/railties/lib/rails/generators/rails/app/templates/public/500.html @@ -2,16 +2,15 @@ <html> <head> <title>We're sorry, but something went wrong (500)</title> - <style> - body - { - background-color: #efefef; + <style> + body { + background-color: #EFEFEF; color: #2E2F30; text-align: center; - font-family: arial,sans-serif; + font-family: arial, sans-serif; } - div.dialog - { + + div.dialog { width: 25em; margin: 4em auto 0 auto; border: 1px solid #CCC; @@ -24,17 +23,18 @@ background-color: white; padding: 7px 4em 0 4em; } - h1{ + + h1 { font-size: 100%; color: #730E15; line-height: 1.5em; } - body>p - { - width: 33em; + + body > p { + width: 33em; margin: 0 auto 1em; padding: 1em 0; - background-color: #f7f7f7; + background-color: #F7F7F7; border: 1px solid #CCC; border-right-color: #999; border-bottom-color: #999; @@ -42,7 +42,7 @@ border-bottom-right-radius: 4px; border-top-color: #DADADA; color: #666; - box-shadow:0 3px 8px rgba(50,50,50,0.17); + box-shadow:0 3px 8px rgba(50, 50, 50, 0.17); } </style> </head> diff --git a/railties/lib/rails/generators/rails/app/templates/test/test_helper.rb b/railties/lib/rails/generators/rails/app/templates/test/test_helper.rb index 9afda2d0df..ca40914d3b 100644 --- a/railties/lib/rails/generators/rails/app/templates/test/test_helper.rb +++ b/railties/lib/rails/generators/rails/app/templates/test/test_helper.rb @@ -1,4 +1,4 @@ -ENV["RAILS_ENV"] = "test" +ENV["RAILS_ENV"] ||= "test" require File.expand_path('../../config/environment', __FILE__) require 'rails/test_help' @@ -6,11 +6,12 @@ class ActiveSupport::TestCase <% unless options[:skip_active_record] -%> ActiveRecord::Migration.check_pending! - # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order. + # Uncomment the `fixtures :all` line below to setup all fixtures in test/fixtures/*.yml + # for all tests in alphabetical order. # # Note: You'll currently still have to declare fixtures explicitly in integration tests # -- they do not yet inherit this setting - fixtures :all + # fixtures :all <% end -%> # Add more helper methods to be used by all tests here... diff --git a/railties/lib/rails/generators/rails/model/USAGE b/railties/lib/rails/generators/rails/model/USAGE index 6574200fbf..1998a392aa 100644 --- a/railties/lib/rails/generators/rails/model/USAGE +++ b/railties/lib/rails/generators/rails/model/USAGE @@ -52,20 +52,26 @@ Available field types: `rails generate model product supplier:references{polymorphic}` - You can also specify some options just after the field type. You can use the - following options: + For integer, string, text and binary fields an integer in curly braces will + be set as the limit: - limit Set the maximum size of the field giving a number between curly braces - default Set a default value for the field - precision Defines the precision for the decimal fields - scale Defines the scale for the decimal fields - uniq Defines the field values as unique - index Will add an index on the field + `rails generate model user pseudo:string{30}` - Examples: + For decimal two integers separated by a comma in curly braces will be used + for precision and scale: + + `rails generate model product price:decimal{10,2}` + + You can add a `:uniq` or `:index` suffix for unique or standard indexes + respectively: - `rails generate model user pseudo:string{30}` `rails generate model user pseudo:string:uniq` + `rails generate model user pseudo:string:index` + + You can combine any single curly brace option with the index options: + + `rails generate model user username:string{30}:uniq` + `rails generate model product supplier:references{polymorphic}:index` Examples: diff --git a/railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb b/railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb index 5fe01d0961..850c9d5c0d 100644 --- a/railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb +++ b/railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb @@ -106,8 +106,6 @@ task default: :test remove_file "doc" remove_file "Gemfile" remove_file "lib/tasks" - remove_file "app/assets/images/rails.png" - remove_file "public/index.html" remove_file "public/robots.txt" remove_file "README" remove_file "test" diff --git a/railties/lib/rails/generators/rails/scaffold/scaffold_generator.rb b/railties/lib/rails/generators/rails/scaffold/scaffold_generator.rb index 36589d65e2..2a0522e81c 100644 --- a/railties/lib/rails/generators/rails/scaffold/scaffold_generator.rb +++ b/railties/lib/rails/generators/rails/scaffold/scaffold_generator.rb @@ -10,6 +10,7 @@ module Rails class_option :stylesheet_engine, desc: "Engine for Stylesheets" def handle_skip + @options = @options.merge(stylesheets: false) unless options[:assets] @options = @options.merge(stylesheet_engine: false) unless options[:stylesheets] end diff --git a/railties/lib/rails/generators/test_case.rb b/railties/lib/rails/generators/test_case.rb index 85a8914ccc..58592b4f8e 100644 --- a/railties/lib/rails/generators/test_case.rb +++ b/railties/lib/rails/generators/test_case.rb @@ -1,8 +1,7 @@ -require 'active_support/core_ext/class/attribute' -require 'active_support/core_ext/module/delegation' -require 'active_support/core_ext/hash/reverse_merge' -require 'active_support/core_ext/kernel/reporting' require 'rails/generators' +require 'rails/generators/testing/behaviour' +require 'rails/generators/testing/setup_and_teardown' +require 'rails/generators/testing/assertions' require 'fileutils' module Rails @@ -27,215 +26,11 @@ module Rails # setup :prepare_destination # end class TestCase < ActiveSupport::TestCase + include Rails::Generators::Testing::Behaviour + include Rails::Generators::Testing::SetupAndTeardown + include Rails::Generators::Testing::Assertions include FileUtils - class_attribute :destination_root, :current_path, :generator_class, :default_arguments - - # Generators frequently change the current path using +FileUtils.cd+. - # So we need to store the path at file load and revert back to it after each test. - self.current_path = File.expand_path(Dir.pwd) - self.default_arguments = [] - - def setup # :nodoc: - destination_root_is_set? - ensure_current_path - super - end - - def teardown # :nodoc: - ensure_current_path - super - end - - # Sets which generator should be tested: - # - # tests AppGenerator - def self.tests(klass) - self.generator_class = klass - end - - # Sets default arguments on generator invocation. This can be overwritten when - # invoking it. - # - # arguments %w(app_name --skip-active-record) - def self.arguments(array) - self.default_arguments = array - end - - # Sets the destination of generator files: - # - # destination File.expand_path("../tmp", File.dirname(__FILE__)) - def self.destination(path) - self.destination_root = path - end - - # Asserts a given file exists. You need to supply an absolute path or a path relative - # to the configured destination: - # - # assert_file "config/environment.rb" - # - # You can also give extra arguments. If the argument is a regexp, it will check if the - # regular expression matches the given file content. If it's a string, it compares the - # file with the given string: - # - # assert_file "config/environment.rb", /initialize/ - # - # Finally, when a block is given, it yields the file content: - # - # assert_file "app/controllers/products_controller.rb" do |controller| - # assert_instance_method :index, controller do |index| - # assert_match(/Product\.all/, index) - # end - # end - def assert_file(relative, *contents) - absolute = File.expand_path(relative, destination_root) - assert File.exists?(absolute), "Expected file #{relative.inspect} to exist, but does not" - - read = File.read(absolute) if block_given? || !contents.empty? - yield read if block_given? - - contents.each do |content| - case content - when String - assert_equal content, read - when Regexp - assert_match content, read - end - end - end - alias :assert_directory :assert_file - - # Asserts a given file does not exist. You need to supply an absolute path or a - # path relative to the configured destination: - # - # assert_no_file "config/random.rb" - def assert_no_file(relative) - absolute = File.expand_path(relative, destination_root) - assert !File.exists?(absolute), "Expected file #{relative.inspect} to not exist, but does" - end - alias :assert_no_directory :assert_no_file - - # Asserts a given migration exists. You need to supply an absolute path or a - # path relative to the configured destination: - # - # assert_migration "db/migrate/create_products.rb" - # - # This method manipulates the given path and tries to find any migration which - # matches the migration name. For example, the call above is converted to: - # - # assert_file "db/migrate/003_create_products.rb" - # - # Consequently, assert_migration accepts the same arguments has assert_file. - def assert_migration(relative, *contents, &block) - file_name = migration_file_name(relative) - assert file_name, "Expected migration #{relative} to exist, but was not found" - assert_file file_name, *contents, &block - end - - # Asserts a given migration does not exist. You need to supply an absolute path or a - # path relative to the configured destination: - # - # assert_no_migration "db/migrate/create_products.rb" - def assert_no_migration(relative) - file_name = migration_file_name(relative) - assert_nil file_name, "Expected migration #{relative} to not exist, but found #{file_name}" - end - - # Asserts the given class method exists in the given content. This method does not detect - # class methods inside (class << self), only class methods which starts with "self.". - # When a block is given, it yields the content of the method. - # - # assert_migration "db/migrate/create_products.rb" do |migration| - # assert_class_method :up, migration do |up| - # assert_match(/create_table/, up) - # end - # end - def assert_class_method(method, content, &block) - assert_instance_method "self.#{method}", content, &block - end - - # Asserts the given method exists in the given content. When a block is given, - # it yields the content of the method. - # - # assert_file "app/controllers/products_controller.rb" do |controller| - # assert_instance_method :index, controller do |index| - # assert_match(/Product\.all/, index) - # end - # end - def assert_instance_method(method, content) - assert content =~ /(\s+)def #{method}(\(.+\))?(.*?)\n\1end/m, "Expected to have method #{method}" - yield $3.strip if block_given? - end - alias :assert_method :assert_instance_method - - # Asserts the given attribute type gets translated to a field type - # properly: - # - # assert_field_type :date, :date_select - def assert_field_type(attribute_type, field_type) - assert_equal(field_type, create_generated_attribute(attribute_type).field_type) - end - - # Asserts the given attribute type gets a proper default value: - # - # assert_field_default_value :string, "MyString" - def assert_field_default_value(attribute_type, value) - assert_equal(value, create_generated_attribute(attribute_type).default) - end - - # Runs the generator configured for this class. The first argument is an array like - # command line arguments: - # - # class AppGeneratorTest < Rails::Generators::TestCase - # tests AppGenerator - # destination File.expand_path("../tmp", File.dirname(__FILE__)) - # teardown :cleanup_destination_root - # - # test "database.yml is not created when skipping Active Record" do - # run_generator %w(myapp --skip-active-record) - # assert_no_file "config/database.yml" - # end - # end - # - # You can provide a configuration hash as second argument. This method returns the output - # printed by the generator. - def run_generator(args=self.default_arguments, config={}) - capture(:stdout) { self.generator_class.start(args, config.reverse_merge(destination_root: destination_root)) } - end - - # Instantiate the generator. - def generator(args=self.default_arguments, options={}, config={}) - @generator ||= self.generator_class.new(args, options, config.reverse_merge(destination_root: destination_root)) - end - - # Create a Rails::Generators::GeneratedAttribute by supplying the - # attribute type and, optionally, the attribute name: - # - # create_generated_attribute(:string, 'name') - def create_generated_attribute(attribute_type, name = 'test', index = nil) - Rails::Generators::GeneratedAttribute.parse([name, attribute_type, index].compact.join(':')) - end - - protected - - def destination_root_is_set? # :nodoc: - raise "You need to configure your Rails::Generators::TestCase destination root." unless destination_root - end - - def ensure_current_path # :nodoc: - cd current_path - end - - def prepare_destination # :nodoc: - rm_rf(destination_root) - mkdir_p(destination_root) - end - - def migration_file_name(relative) # :nodoc: - absolute = File.expand_path(relative, destination_root) - dirname, file_name = File.dirname(absolute), File.basename(absolute).sub(/\.rb$/, '') - Dir.glob("#{dirname}/[0-9]*_*.rb").grep(/\d+_#{file_name}.rb$/).first - end end end 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 c9d505c84a..90a92e6982 100644 --- a/railties/lib/rails/generators/test_unit/model/templates/fixtures.yml +++ b/railties/lib/rails/generators/test_unit/model/templates/fixtures.yml @@ -1,22 +1,20 @@ # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html - <% unless attributes.empty? -%> -one: +<% %w(one two).each do |name| %> +<%= name %>: <% attributes.each do |attribute| -%> + <%- if attribute.password_digest? -%> + password_digest: <%%= BCrypt::Password.create('secret') %> + <%- else -%> <%= yaml_key_value(attribute.column_name, attribute.default) %> - <%- if attribute.polymorphic? -%> - <%= yaml_key_value("#{attribute.name}_type", attribute.human_name) %> <%- end -%> -<% end -%> - -two: -<% attributes.each do |attribute| -%> - <%= yaml_key_value(attribute.column_name, attribute.default) %> <%- if attribute.polymorphic? -%> <%= yaml_key_value("#{attribute.name}_type", attribute.human_name) %> <%- end -%> <% end -%> +<% end -%> <% else -%> + # 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 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 8f3ecaadea..2e1f55f2a6 100644 --- a/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb +++ b/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb @@ -21,7 +21,11 @@ module TestUnit # :nodoc: return if attributes_names.empty? attributes_names.map do |name| - "#{name}: @#{singular_table_name}.#{name}" + if %w(password password_confirmation).include?(name) && attributes.any?(&:password_digest?) + "#{name}: 'secret'" + else + "#{name}: @#{singular_table_name}.#{name}" + end end.sort.join(', ') end end diff --git a/railties/lib/rails/generators/testing/assertions.rb b/railties/lib/rails/generators/testing/assertions.rb new file mode 100644 index 0000000000..6267b2f2ee --- /dev/null +++ b/railties/lib/rails/generators/testing/assertions.rb @@ -0,0 +1,121 @@ +module Rails + module Generators + module Testing + module Assertions + # Asserts a given file exists. You need to supply an absolute path or a path relative + # to the configured destination: + # + # assert_file "config/environment.rb" + # + # You can also give extra arguments. If the argument is a regexp, it will check if the + # regular expression matches the given file content. If it's a string, it compares the + # file with the given string: + # + # assert_file "config/environment.rb", /initialize/ + # + # Finally, when a block is given, it yields the file content: + # + # assert_file "app/controllers/products_controller.rb" do |controller| + # assert_instance_method :index, controller do |index| + # assert_match(/Product\.all/, index) + # end + # end + def assert_file(relative, *contents) + absolute = File.expand_path(relative, destination_root) + assert File.exists?(absolute), "Expected file #{relative.inspect} to exist, but does not" + + read = File.read(absolute) if block_given? || !contents.empty? + yield read if block_given? + + contents.each do |content| + case content + when String + assert_equal content, read + when Regexp + assert_match content, read + end + end + end + alias :assert_directory :assert_file + + # Asserts a given file does not exist. You need to supply an absolute path or a + # path relative to the configured destination: + # + # assert_no_file "config/random.rb" + def assert_no_file(relative) + absolute = File.expand_path(relative, destination_root) + assert !File.exists?(absolute), "Expected file #{relative.inspect} to not exist, but does" + end + alias :assert_no_directory :assert_no_file + + # Asserts a given migration exists. You need to supply an absolute path or a + # path relative to the configured destination: + # + # assert_migration "db/migrate/create_products.rb" + # + # This method manipulates the given path and tries to find any migration which + # matches the migration name. For example, the call above is converted to: + # + # assert_file "db/migrate/003_create_products.rb" + # + # Consequently, assert_migration accepts the same arguments has assert_file. + def assert_migration(relative, *contents, &block) + file_name = migration_file_name(relative) + assert file_name, "Expected migration #{relative} to exist, but was not found" + assert_file file_name, *contents, &block + end + + # Asserts a given migration does not exist. You need to supply an absolute path or a + # path relative to the configured destination: + # + # assert_no_migration "db/migrate/create_products.rb" + def assert_no_migration(relative) + file_name = migration_file_name(relative) + assert_nil file_name, "Expected migration #{relative} to not exist, but found #{file_name}" + end + + # Asserts the given class method exists in the given content. This method does not detect + # class methods inside (class << self), only class methods which starts with "self.". + # When a block is given, it yields the content of the method. + # + # assert_migration "db/migrate/create_products.rb" do |migration| + # assert_class_method :up, migration do |up| + # assert_match(/create_table/, up) + # end + # end + def assert_class_method(method, content, &block) + assert_instance_method "self.#{method}", content, &block + end + + # Asserts the given method exists in the given content. When a block is given, + # it yields the content of the method. + # + # assert_file "app/controllers/products_controller.rb" do |controller| + # assert_instance_method :index, controller do |index| + # assert_match(/Product\.all/, index) + # end + # end + def assert_instance_method(method, content) + assert content =~ /(\s+)def #{method}(\(.+\))?(.*?)\n\1end/m, "Expected to have method #{method}" + yield $3.strip if block_given? + end + alias :assert_method :assert_instance_method + + # Asserts the given attribute type gets translated to a field type + # properly: + # + # assert_field_type :date, :date_select + def assert_field_type(attribute_type, field_type) + assert_equal(field_type, create_generated_attribute(attribute_type).field_type) + end + + # Asserts the given attribute type gets a proper default value: + # + # assert_field_default_value :string, "MyString" + def assert_field_default_value(attribute_type, value) + assert_equal(value, create_generated_attribute(attribute_type).default) + end + end + end + end +end diff --git a/railties/lib/rails/generators/testing/behaviour.rb b/railties/lib/rails/generators/testing/behaviour.rb new file mode 100644 index 0000000000..7576eba6e0 --- /dev/null +++ b/railties/lib/rails/generators/testing/behaviour.rb @@ -0,0 +1,106 @@ +require 'active_support/core_ext/class/attribute' +require 'active_support/core_ext/module/delegation' +require 'active_support/core_ext/hash/reverse_merge' +require 'active_support/core_ext/kernel/reporting' +require 'active_support/concern' +require 'rails/generators' + +module Rails + module Generators + module Testing + module Behaviour + extend ActiveSupport::Concern + + included do + class_attribute :destination_root, :current_path, :generator_class, :default_arguments + + # Generators frequently change the current path using +FileUtils.cd+. + # So we need to store the path at file load and revert back to it after each test. + self.current_path = File.expand_path(Dir.pwd) + self.default_arguments = [] + end + + module ClassMethods + # Sets which generator should be tested: + # + # tests AppGenerator + def tests(klass) + self.generator_class = klass + end + + # Sets default arguments on generator invocation. This can be overwritten when + # invoking it. + # + # arguments %w(app_name --skip-active-record) + def arguments(array) + self.default_arguments = array + end + + # Sets the destination of generator files: + # + # destination File.expand_path("../tmp", File.dirname(__FILE__)) + def destination(path) + self.destination_root = path + end + end + + # Runs the generator configured for this class. The first argument is an array like + # command line arguments: + # + # class AppGeneratorTest < Rails::Generators::TestCase + # tests AppGenerator + # destination File.expand_path("../tmp", File.dirname(__FILE__)) + # teardown :cleanup_destination_root + # + # test "database.yml is not created when skipping Active Record" do + # run_generator %w(myapp --skip-active-record) + # assert_no_file "config/database.yml" + # end + # end + # + # You can provide a configuration hash as second argument. This method returns the output + # printed by the generator. + def run_generator(args=self.default_arguments, config={}) + capture(:stdout) do + args += ['--skip-bundle'] unless args.include? '--dev' + self.generator_class.start(args, config.reverse_merge(destination_root: destination_root)) + end + end + + # Instantiate the generator. + def generator(args=self.default_arguments, options={}, config={}) + @generator ||= self.generator_class.new(args, options, config.reverse_merge(destination_root: destination_root)) + end + + # Create a Rails::Generators::GeneratedAttribute by supplying the + # attribute type and, optionally, the attribute name: + # + # create_generated_attribute(:string, 'name') + def create_generated_attribute(attribute_type, name = 'test', index = nil) + Rails::Generators::GeneratedAttribute.parse([name, attribute_type, index].compact.join(':')) + end + + protected + + def destination_root_is_set? # :nodoc: + raise "You need to configure your Rails::Generators::TestCase destination root." unless destination_root + end + + def ensure_current_path # :nodoc: + cd current_path + end + + def prepare_destination # :nodoc: + rm_rf(destination_root) + mkdir_p(destination_root) + end + + def migration_file_name(relative) # :nodoc: + absolute = File.expand_path(relative, destination_root) + dirname, file_name = File.dirname(absolute), File.basename(absolute).sub(/\.rb$/, '') + Dir.glob("#{dirname}/[0-9]*_*.rb").grep(/\d+_#{file_name}.rb$/).first + end + end + end + end +end diff --git a/railties/lib/rails/generators/testing/setup_and_teardown.rb b/railties/lib/rails/generators/testing/setup_and_teardown.rb new file mode 100644 index 0000000000..73102a283f --- /dev/null +++ b/railties/lib/rails/generators/testing/setup_and_teardown.rb @@ -0,0 +1,18 @@ +module Rails + module Generators + module Testing + module SetupAndTeardown + def setup # :nodoc: + destination_root_is_set? + ensure_current_path + super + end + + def teardown # :nodoc: + ensure_current_path + super + end + end + end + end +end diff --git a/railties/lib/rails/info.rb b/railties/lib/rails/info.rb index 592e74726e..f06ce659c5 100644 --- a/railties/lib/rails/info.rb +++ b/railties/lib/rails/info.rb @@ -29,7 +29,7 @@ module Rails def framework_version(framework) if Object.const_defined?(framework.classify) require "#{framework}/version" - "#{framework.classify}::VERSION::STRING".constantize + framework.classify.constantize.version.to_s end end @@ -75,7 +75,7 @@ module Rails # The Rails version. property 'Rails version' do - Rails::VERSION::STRING + Rails.version.to_s end property 'JavaScript Runtime' do diff --git a/railties/lib/rails/tasks/documentation.rake b/railties/lib/rails/tasks/documentation.rake index 0057b0f887..1c3426028d 100644 --- a/railties/lib/rails/tasks/documentation.rake +++ b/railties/lib/rails/tasks/documentation.rake @@ -1,4 +1,5 @@ require 'rdoc/task' +require 'rails/api/task' # Monkey-patch to remove redoc'ing and clobber descriptions to cut down on rake -T noise class RDocTaskWithoutDescriptions < RDoc::Task @@ -52,52 +53,7 @@ namespace :doc do Rake::Task['doc:app'].comment = "Generate docs for the app -- also available doc:rails, doc:guides (options: TEMPLATE=/rdoc-template.rb, TITLE=\"Custom Title\")" # desc 'Generate documentation for the Rails framework.' - RDocTaskWithoutDescriptions.new("rails") { |rdoc| - rdoc.rdoc_dir = 'doc/api' - rdoc.template = "#{ENV['template']}.rb" if ENV['template'] - rdoc.title = "Rails Framework Documentation" - rdoc.options << '--line-numbers' - - gem_path('rails') do |rails| - rdoc.options << '-m' << "#{rails}/README.rdoc" - end - - gem_path('actionmailer') do |actionmailer| - %w(README.rdoc CHANGELOG.md MIT-LICENSE lib/action_mailer/base.rb).each do |file| - rdoc.rdoc_files.include("#{actionmailer}/#{file}") - end - end - - gem_path('actionpack') do |actionpack| - %w(README.rdoc CHANGELOG.md MIT-LICENSE lib/action_controller/**/*.rb lib/action_view/**/*.rb).each do |file| - rdoc.rdoc_files.include("#{actionpack}/#{file}") - end - end - - gem_path('activemodel') do |activemodel| - %w(README.rdoc CHANGELOG.md MIT-LICENSE lib/active_model/**/*.rb).each do |file| - rdoc.rdoc_files.include("#{activemodel}/#{file}") - end - end - - gem_path('activerecord') do |activerecord| - %w(README.rdoc CHANGELOG.md lib/active_record/**/*.rb).each do |file| - rdoc.rdoc_files.include("#{activerecord}/#{file}") - end - end - - gem_path('activesupport') do |activesupport| - %w(README.rdoc CHANGELOG.md lib/active_support/**/*.rb).each do |file| - rdoc.rdoc_files.include("#{activesupport}/#{file}") - end - end - - gem_path('railties') do |railties| - %w(README.rdoc CHANGELOG.md lib/{*.rb,commands/*.rb,generators/*.rb}).each do |file| - rdoc.rdoc_files.include("#{railties}/#{file}") - end - end - } + Rails::API::AppTask.new('rails') # desc "Generate Rails Guides" task :guides do diff --git a/railties/lib/rails/templates/rails/welcome/index.html.erb b/railties/lib/rails/templates/rails/welcome/index.html.erb index e239e1695e..4c4c80ecda 100644 --- a/railties/lib/rails/templates/rails/welcome/index.html.erb +++ b/railties/lib/rails/templates/rails/welcome/index.html.erb @@ -59,7 +59,7 @@ #header { - background-image: url("/assets/rails.png"); + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAABACAYAAABY1SR7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAGZhJREFUeNqsWwmUXGWV/t5Sr9aurl6qO0l3Z9/DEoJh18gZQGAUxPHIyQHH7eioZ8bjnAFHZ0RndNxxRBhGcUbxoKIHBkTEcUYREIHIGpKQjUDS6U660/tSVV3Lq/fefPf/Xy2dBFGYx3npqvde/e/e/97v3u/e/8e4Lt2L8DCCAFcGwF8ZBjYbgM1rAZoO+WLwZhDMu9y4+YcOozbAqzwXNA3GdzX/5hV+KnKO2+GXFj/AvzmW8e72iG202CYiphbY403f9/k3QHZtJ9oWtyCQe7wGX79TKVb7rP9pXJPDVxf0Rz+oyxm4HNWrahFNixdk3EAJbERMWOm4ulctVODNVeEVK0DeRVDgb1wfJgcqUo6duaKnFOH7bm6JmH+5LOEgZprwRIHAV3JYfLjKM55Noz3bBqdcgt0Wg52Kq/cHHkXns0qIukKBlltk9rU2QaiouiefPQ+RdBuseAJeqYTK1CTH8mE4NsyIpRWu8nssCs+xULWpjGVwTvieKl/sV6mIXzOib/OftzuG8d6l8SiVMODyRb46oazg8YPP2Wnvy9ISNqplzsxYAW6hjGhHEmYiBoPC+hRMfFMrESgrBC5n0KS+lq1nPahZh2OXymg9bSNWX/u3FKyKI//7Exx96B4Y8RiCEseq8t0VznyxjMDidFIJ8QSf3hJEOFbZEAHVhIkFTX54fxtnIW5pJUQIeZ8ooZShkInuDOLpFIX1ldtCBix7KI/k4E7OwbTjcNIdiCQzsONp2LEk7GgUnZsuQN9lW2En45xlukrUghWzeZq8FsXsi8+gND6MSCqD9k3nwulIUShKZxt0LYPWortRSY0NXreC8J6pZNDChEDh53PT1NIPLaEnLbQKNTETEaR7sycA0jD1INXZAnzObjTbiWh7Vr1A3Knn4nciu+lCvstUig09cp96cVCtcELoFpEIFUjjyIM/osWIg+IMXS3DcfNwZ3NQHmmKU9OqroX2jWdgatduuPkpmA4ViZrK9RqKABEBtg9tDeW+oUIyTIYuFaX7eCG4aqbU+hhKocD3UBoZISBLiC9cpAQKyq5SQo6OjVswtec5VHLTiHUuIN4WonXlqUj2riS0DIUXwZlERFHSK+SQGzqI3MHdmNm7CzMvvowF527B8qvejZ3/+iXk9vVTao5tiTKN0OUHISZEGS/8W6UbRdoTSHe3E1f+CRaR3xhBLVJSIQ7qleZQGBigZYoYdR+ElUjBaW3H6JMPIrV0Hdo2bEayZ7my0KsdLctPBS64EuWZMYw/9wTGnvod0mtzWH71Vuz66o10bVpK8FIx6orUMejpCKYBTvfM9HXBJtA8z3/1BKDivaksVJmaYsgsYPDnd6LzzAuw8I1XUIGleC1HtDWLnguv5BiX4+jDD2D4sQeV1bQvNXBi6vAb1MGtrEEHjRPgqfZ0qMRJElYYSudfq12nmzAvtJ2yib69iRadRGnySD0Uv5bDtCPou/gqnPY3N6DnLRczgtHxCf4aVnUeUdgw6i6FqM1w292Ujo/TJdB5wHcJ2iDCaBTRmVfw4rkw4yksuvQyJJf0YvrgNiayvBLESS9AYuFqJLLLCPb4SQWulosojhxmeCeoDeaQSoVuy8lPtSKxYKnC2Bmf+DwtvBgv3/qfTI6uEtGuJV7PCBTIq5zNtt5uxBgyvap30pf55TISfX1Y/PatGPrVvcgPvEyAJ1GenaPZLSy//G2IL+qki43CNCMwk620iovy9FGUJgYwm8gwpK/guRJOS5dyD688h+n9z2L28F4Ujx2ia04jEl8Ad3oGVTePaGcnQ3sKLb1rkD3nIqx594dRIh733n6PmmrrvGj671sjVlxczRWAkxZ0r+rTrhfMJ0uEM8xKUYXONR+5nr57BdpP24TCsX6M/f5F5AYLWPauK9F11htUwjOIL8GNZH1qpKwiyVGELk0OoDj2EtziFOaODSN3aC/v24xmZzAU51TgcJKd/DktHo9jyRXvg0Or7PvejTj22KPKiyafew6zg8MYypVLNsLkJ2bxaZXM4i5EmCBPsEaoWJUUpfeSK7DgvEtQmh4ihTDQdf5FOHDHr7HqPVeh99KL4OVzpE50N18CtqnCdBCY6rsEcTsqIGUGD6rY9e3bMPzIHmTWLsbqa7ai84wL6YrTqEyOqEmwonEExSoO//R7dLcJWiWCueF+7P7mjZAUY8YdJZqySMo24j5zQSybQdeyhdrX5imho4NhEEnkRbkDQyjSRVJLeziCgef/6avIrFuOtR95P2lJNSSshg4l6rdm+Ht9inWsqIOX7voN+u/eRoEM5PvHMbbjGcwcfg7jO3YxbCcRiaaYQOXnpEaFGeahGQaMCidJRidt8RghS6Q344XQIowmFq2QXdLNdwsx8zUFqCOQNIECVqdp8pESB53Fvhdux9T2FxBb1AWX4XbjDX/HFzjEmgedB4XYKT5D4T0VTLRCtIiTwOBvfovpvS8T+Bm4MyW6jw13tIIDt/9G/TTWk8HKvzgbmd4+YldYQIdixgHJYkC82Ul6UDnQSbEGdsFGZlEWyUyLyiEyYwajRVAoAXNlEjR+pjUCUmiDQcKOORwwgpFfP4cg5mPzTZ9FoqePdGVWuZRPYQNPcgrd0/dCpqpdy3DIsQ4fxtiTu7Hxkx8iRXkcB+94iM86/K0Jx4opi5aOzGJs14toWeLAdYXWxFQCtJlkA+LUq+bI7QR3mj3YoqVNgGcXd5NWUOiZAk9GH86S4jK25jWBLVREl1uK5Voywz6WXf1WLHjTm0lPigSyxoUpnEqU8c26Wyk/Y24RMjhw/yMoj+cQbWvH0isuwuijL6BwaJwcyq7XUTaBP7N3HOU3ke7HSONJb8RTBGoGKZPFyTE8saTZyCPtrC2coxOoTuY5+x4UTzHNsNjR6d6Qa8JJ5BIV8ksVtKzpwcr3v5dyOrzHKMWXizsZAnK6k1ImPDmAqjOmdr9AwXcodzr4kwfQfuY6VKbzyhpGU96S75WxIqb2DaPnvNWKklQD4WSuzB+sVILjOYjm/VARSWKTBQQzlZCFmErYeubzVJJR14SlQtVQMjO0xrXvoulXkq3OKnxAXqSsoSmNUbOM/BV35RjDDz9JrBXpnnEM3vsYjj38LLyZihI8QNAgQhITOCmTO46i+6w1MPm86RVIiC09/RJUGcECCe2UU0G6QIyUjEC5hGaCNd4RqHKU6VuDylQlI2N8hfXDWibEdyhCKXREuZUVUX8lyhh2+Jl5Q/6akSgT4izGn3wBFu+JwYOKj8qwtsbJaYmJuYEZ5AYmFOWXPCN1jTodzeuqM0WtSI1rzXrV0LSNKRFuZLYQ2EYVPjEQVuQUMsCya65GvL1HWUwJS+FNUcBsUiZUQv7aLGlndr+I8ug4XUMVAJw4U7FmI8SFETTmUaGK2gas1SeeP8znoizIEso9DaUIy2FWkNU5V0VYs/azWXKncuCHqgQq1CHiY831H8TGr34erRvXKdD6LD3b+HnRn12qGgdqlmxHZe2aRcy6NbQScl8y8dSOfWQE1yK9YYmqXYww3xhNObemUI2IWraF2d1HMTeeh83MbkUiylKiiMdy2wjzXBjxWYdRiSkhfDVVKGSstxM9l16JxZe/E2+848c49bPXK9D2vPUyEsBOVZMINmpCW6HgEOuIQjXF6FYuAV2aHsWyrVfj9C9er5SR5Kms0PTf8QoZtIo7WSJW+mmRJLGSpDK2ipzV2bK6X6fxtWOCicYVqyhGXkXn+WeTcfape5ZDsPGM91C5iy8LI0s445bd9FkrAFHICt1N8DE+gdyeQczs34+uzeei68LNLGfdea50st6VbiyYmHq+nxTFRSSRVsD3ii7xyeQbdt/M5h/MERMT4i6GjlAWeUxh6HCN8+LIz+5H5zlUbtHSOnVp4MCa51JaIQ16i0kwP9CP0uExPP+JL2DggfuYN8jTJClYxnH4aNimdpp0r7nDkyx9h5gE0+RqSVTyZXXTsMz5FaJyMJrrGLNopyWUIImj//1LjPzuUZLCC5gzVqMwPIglV7/rxCaihFaCPCDOxDUl1EoylFP4mUlFCgPDStLKWB47PnUjrSSsNqrJsa/zR02ZwGjYRoVkEZh0ZHzbfmTPXE85SWrnKip6GeFE2I1iKVBCzNK9pmiVhS1x+Axx7myRJesvgHvvR3rNKmQ3n/OKPVGND1MVXTqHiFK6qVFiwlXgTVDhkq+ChhnyJCW9GeaoIGQOdV0M9YhYZWbvUXrIJJ+rKL6lJ9CYj5Fai0iKqyPkx0HcUsJYrBbtREIJ2H72GxTI/2CL1zAbLkZ8WIxYgUvsKebq6Zl3rEZvymx6echo1N+au9XcS3oHsxWMPrGTFH+CLhsmbhMNRWrNB4SZVSwyJ5WDFRb3DAAmaXf2rPP+6BpbkmStkBLAWwkHmdNWKfYqFaZRp2GGdo+mhpv6bBkNhepRzERpdASeW1aKSZ5RidpoUsRAvQ+NJCnJHHl+bcZ80vjkij661vo/rWMQSitWskgnNv7LP+MNN38NadYuCPtYCItIFTjMRgfeqClkhkFZ+FXCQmpFuyKXii7xNI93LT9szdrUMsNZnJkuwZX6zlKdaqRXrESiq/e19kBC3NisLt+Gc/7jW0gtZ51Bl1MCmUaoM//aRv0aapnF0l362KIUnI6EyuhCUOuWrIVfAZcRAj5NJWJ0C5epP19y1awJLWhdt/a1t3KcGF8Yxb5bbsLItoeYmxZRkRWq46IrR9StX/tcw4oKsYH+nlrZpmbcZQ7R1tDPBvMbdIwofLpVKIfcJy5nCa5WRhnDFkVOx+s5kr29GPzpfUxsuxg0zlQUxSZudG/CqNOSIJxYCclGCA7fDRDpiCK6gIVfidVmWXrHRh0fmBd+eSYIIEcWdRhdJJsWp+aQT1vI9nYjnl3wuhSJLuhAJJ1WQWDisadUELCi0bD1WlscMpq6lrV1Ft0riC9tVcFD8odfDVS9bod5pNGgC3+XFnxsXA2rsw25/gHMTcwiRxdbvLgPsY7s61IktWSZinw6l8SbupNGvUlphB1yZY3aIhfZtRmz4XS3oMoA5JP6BywdvBIr24ytMdzsWjHaMcnI0nXRG5FkdCrnS6gy6QzccxeMZDsJW+r1KbJ4pbKAVy6huXoyauVUaAUjRK5WjN9cH05PCiZl84VfsXaSVTKf191C6F61qCXjtjAORtvTSPb0sgYoEi/UmEmnMj6JkpXA6z2cTAbxxV26GdEEZB12DVVV63BrIuwYaWpCGZyuJBWSFSxPLTB5PH1+rhDDKlQbuvajNUzE+UVyRTTdQt+zWIrGWIJOozo8hjmashq8PkXsZAoty1Yqi/gVnq6ru+p1pUKFTM3dENJzu421TiqKKq3hhUp45apSyM1VGMH0xOi+liz0yOxUyijs2w2DlRjI+8tHB3XUIP+fGBxA9+LFr1kRgwV769p1fPkEQ+9KRq+dKE9MsGKc1BmxltEC7W6CEdW0aUtocIvw0tcSt5JGu3R4OA+zIxW1uKoUOUZzFxmxRp/ai+iz+xi9CK5EVJGdqBNBlG4xdvBlRq9eTQteawhm0MgPLsSGj92gVqjKk8ew/TOfxPjjz8BKxhvLFGHjWUBuJh0Cu6pqD7WCTGz4BDqKpE30rIlj05rw6sKFxuCXPP9O8MEjxQqOTuQwNjJLa1mItaRRGB3GLHnO6znaNmxC/nA/cocPKNoS61iEZVdfEy5LBHVKUieCLY5eeKIiXp6RapJuNVJFMCamYGnOUFyslBo0Xronai0dIfXmnZIqtKhgNIaj/F3ULSLx4j60dnXXy8s/OZe0dyGW7cLOL34arevXI9rayWgYhZPtoJtNqsTbyPKUgwzamyCw867MtG5NBUF9bSBXLCkeKOzDroUutaZODax52yUk5sfgsyrL897+PXtQHTmK7vWnomPpCkSTf3pI7j7/Qmz/5HWY3r5LNziYeC3WPlYsovOJJ7VKVbuPENcgXEyvuV3IbKXpPlcqqh0acqGe2S1oq1jzqmZ+b0mGDJNaM2bnjrHuPnYUifZOtDMKda9ah1RnZ30F99WO9jM2MzouZw0vLdJIuCsiUInOz0vbiVNa9DSBtITyWo3VAV/XG/KmPEuBKrmard7rNxKiyCoN7EBnpXlLCiYTmfibuEHSSSkLV4uzGNr5NEYP7EZb31J0rd6AzMIevtf+g4oIg+7e8iYM3H03J5muw9n3ZquqfwU3aGDdMBqdztr+lXBbhyg+R2xYTb5jN7YG6SKnyh870r8Ki6Py0CiO3fcTNWaCBU3E8FVDr7ZPRjbcDLHO30N/TmazdLk+JFMxVoZh6errUrcmnDQp5o4MocrI4o3N6dmXhp1hoHkOFV2R5CXtVwm3Qc0aBip8Z6lY0HtRpJ8GYz5pVFgxgkaHiaCuDE1gfOAhFdNbJIKxplCKNJqqyoqi0CT9tp9/IyyPE2SryYyDKD9LVKxKUqXbuFOM+yVDN/Rq+0ia1mLmtYNqK8rhTiSpLLNbLkDLuZvQ0X8QBoG+//5fIMjP4AQ/kJkuM+vW+sS1wkgiVSTi0Fq2XqoLFfFYMMkyHSFL2mOpHQmy+aU4xXHoLk6rrIkYiE1JNpZOJjO1ivduOLSkZeuk6/YBwR54jaVv6chXpmZQmJnEssveQjwVcPCXv1IWt4//sUVB7K4WpGTREqhvJCrO5MhtGLMTKWU5pUSpDKs1glhbB4W3VCSpTM6gOl2GQzxJt+RQUMFcOoENrXG0FEhESSvMmIVIZ6uaHL9QZn6Y067VNJueV4bdmYDdktJ7pAJNKKfG+pG/cz8GH/gfGLIARF4o9fs8RWSrUmZxN7Z+9za0sooTPiRuI22bsUMHsevWW1B+iFnYdOgqFWTPPxWnXPdxtK5eV8fB9IH92Pn1m1hz7MQh00Xm/C34+K23MiOXsPvLX8bgbXej5bz1OPs7tzIhduHgnXfghX/8OplEsr6U4ZtV9G69HMvf8wEkKUfgaUeWbs4zX/8Sxm/+AbzxCRVF1VpFM9hrvS2ZmZbuRUh2LpxPw7t60EWK8vgHPoCZ5w4i1pvBps99Bu2nbJ73XLyzB4kvLcAPt27F2LFR9MTjSKbb1L1h4mIq4iNL14u2ZRFJysazZCNHqA0DZXRcuBGnf+bz6v4JLDqVgk3r247DnMdJDkOzffJtDfoY2b0dg08/gbZlq7BiyyWk+MuQ2bAGU9v2snTtQnxBj3pu9OnfYXr/Hiq1EZ0bz0ZsUS+sFUvgDB+DFfh1v3X9Kg4xknfLRNZ21h2/RYTX29avU0pUSwUcuP07KLw0oBZrA5bGozt2MlA5updgzGuJnYyp6rt7778HP37fX+OJW77ZaKzKoo5eOdfRhMehO3+EbXzu8H/dXW/SOTwj0gZqeoVck+h3xES9LDjpVp3QXeRdqSVLkDllrepy5oeHMPH0brq2qdteRmNJwj7pYKFVlr75YrztKw6ya9aFTzF8Tk+pBZrmXRGRdCsSLMiQbKlfE7PLrjarCcSSA0QZvQQevGKncnrfXpVwZTde3+XvqN9b8d4PYfuNn8O+b9zO56K6oGpOiMYreNfSc7eoE+FO00P334XJx3fQzM685zd8/Hqs/uCHGGEy9QEslaT0Cm9t7rVyYqnGWogEGIl+nqUTmyxwTj62HTs/91ks3XqN2u8VBLKZoVt14pe/42oc/O6dzB2+qnEMNGHEPHHbSfiSqloakGP7D7+Dpz79BfT6cRXu5rHatk51Nh9aEaOJu2mOZIf36uDu6EDi3PVoIQGV5efiwSG1Rjny8COY3P4sI1WM2HKx4bpPYdEFlzA9RMOlhCAsLJssYqGxRbcZI8//9MfIrliDvjPOwqqL/xwD996P6rY9zGHWPNMNPf8UJl9+Cdm169G9YWOdapjB8auShsJMc85YdekVWL7lQgroKHd68qMfRcAEu+lrX1GdSdmBKjQn0aOrU9lso5bK53uSLiyscNu10tAy66FganAQD9zwD6jM5ZBe2IeLbvoGWs5YofZQyfKXxbpejl133omfXfth7P/Fz8NRLbXgb0nGNe26GhGST5MzFmEYll2oCl+sd2IZCcWtTKxd6rokwdYVpyK9fB1z1KnIrD0NDt1WiNGB738X3kxJVapiWVmR5pCurc2iSaIkmNJ0Hr+9+WYkMu0YfHI7Dv9+J+766Eew8vSNiFP4WGsGBanhh6bw1K3fRjSdwfSel5FikTT67At4+t9vgVssojA0Rp6VwOyhfjx9262qABrfw1KaJW15YprXvsVcEG1sT5eCji40fXSURVyAvTd9TSmv6nTVifQx/uwzmHiU7kb3Clu+GC27MsY247p07+SihN0m/Kgc6EXRIjmMgDvCF9mcsXJxDgniZSnN3xFLIcc6Yormd1mhCX2QpWc7SteolNUpNUQkIUvJpDkUrsrfqy1L8ZjaFSTrJKLsCbvz6BqxaBwdBReWbJmF3kTa2NYRVYFGHEYKqqFKFXtzMg6uUhaJyzZyQ/d/FdUm8LwmAuYwO/vhQBU+m+ddmy+NpBKNWpIzF7EdRSxrOygMMl6LruUw2tQXOTy1akNFk/XtU/V70H3g6YyNNk5GtOIp/DYvlKp9LoJLWuIl2fADfJ/X71PQ8Jo2Vzbv620OAFI9jtIqCQ7tnfC/JxhNT4dShds4UKvB66s1ftPnRqOh/l13hDDqWGhxqUgTsIV1Fzg5Y7TEpKsK+B/w+sdqUWuqv1CxUN8K/MqHLMnhj/g/J/4/juDky9VSg0kh/zQj322897Pao/8nwAC+AZicLeuzngAAAABJRU5ErkJggg==); background-repeat: no-repeat; background-position: top left; height: 64px; diff --git a/railties/lib/rails/test_unit/testing.rake b/railties/lib/rails/test_unit/testing.rake index 44485d9b14..3c247f32c0 100644 --- a/railties/lib/rails/test_unit/testing.rake +++ b/railties/lib/rails/test_unit/testing.rake @@ -1,6 +1,7 @@ require 'rbconfig' require 'rake/testtask' require 'rails/test_unit/sub_test_task' +require 'active_support/deprecation' TEST_CHANGES_SINCE = Time.now - 600 @@ -47,7 +48,11 @@ task default: :test desc 'Runs test:units, test:functionals, test:integration together' task :test do - Rake::Task[ENV['TEST'] ? 'test:single' : 'test:run'].invoke + if ENV['TEST'] + exec "bundle exec rails test #{ENV['TEST'].inspect}" + else + exec 'bundle exec rails test' + end end namespace :test do @@ -56,19 +61,8 @@ namespace :test do end task :run do - errors = %w(test:units test:functionals test:integration).collect do |task| - begin - Rake::Task[task].invoke - nil - rescue => e - { task: task, exception: e } - end - end.compact - - if errors.any? - puts errors.map { |e| "Errors running #{e[:task]}! #{e[:exception].inspect}" }.join("\n") - abort - end + ActiveSupport::Deprecation.warn "`rake test:run` is deprecated. Please use `rails test`." + exec 'bundle exec rails test' end # Inspired by: http://ngauthier.com/2012/02/quick-tests-with-bash.html @@ -83,7 +77,12 @@ namespace :test do task :db => %w[db:test:prepare test:all] end - Rake::TestTask.new(recent: "test:prepare") do |t| + # Display deprecation message + task :deprecated do + ActiveSupport::Deprecation.warn "`rake #{ARGV.first}` is deprecated with no replacement." + end + + Rake::TestTask.new(recent: ["test:deprecated", "test:prepare"]) do |t| since = TEST_CHANGES_SINCE touched = FileList['test/**/*_test.rb'].select { |path| File.mtime(path) > since } + recent_tests('app/models/**/*.rb', 'test/models', since) + @@ -94,9 +93,9 @@ namespace :test do t.libs << 'test' t.test_files = touched.uniq end - Rake::Task['test:recent'].comment = "Test recent changes" + Rake::Task['test:recent'].comment = "Deprecated; Test recent changes" - Rake::TestTask.new(uncommitted: "test:prepare") do |t| + Rake::TestTask.new(uncommitted: ["test:deprecated", "test:prepare"]) do |t| def t.file_list if File.directory?(".svn") changed_since_checkin = silence_stderr { `svn status` }.split.map { |path| path.chomp[7 .. -1] } @@ -118,44 +117,20 @@ namespace :test do t.libs << 'test' end - Rake::Task['test:uncommitted'].comment = "Test changes since last checkin (only Subversion and Git)" - - Rake::TestTask.new(single: "test:prepare") do |t| - t.libs << "test" - end - - Rails::SubTestTask.new(models: "test:prepare") do |t| - t.libs << "test" - t.pattern = 'test/models/**/*_test.rb' - end - - Rails::SubTestTask.new(helpers: "test:prepare") do |t| - t.libs << "test" - t.pattern = 'test/helpers/**/*_test.rb' - end + Rake::Task['test:uncommitted'].comment = "Deprecated; Test changes since last checkin (only Subversion and Git)" - Rails::SubTestTask.new(units: "test:prepare") do |t| - t.libs << "test" - t.pattern = 'test/{models,helpers,unit}/**/*_test.rb' + desc "Deprecated; Please use `rails test \"#{ENV['TEST']}\"`" + task :single do + ActiveSupport::Deprecation.warn "`rake test:single` is deprecated. Please use `rails test \"#{ENV['TEST']}\"`." + exec "bundle exec rails test #{test_suit_name}" end - Rails::SubTestTask.new(controllers: "test:prepare") do |t| - t.libs << "test" - t.pattern = 'test/controllers/**/*_test.rb' - end + [:models, :helpers, :units, :controllers, :functionals, :integration].each do |test_suit_name| + desc "Deprecated; Please use `rails test #{test_suit_name}`" + task test_suit_name do + ActiveSupport::Deprecation.warn "`rake test:#{test_suit_name}` is deprecated. Please use `rails test #{test_suit_name}`." - Rails::SubTestTask.new(mailers: "test:prepare") do |t| - t.libs << "test" - t.pattern = 'test/mailers/**/*_test.rb' - end - - Rails::SubTestTask.new(functionals: "test:prepare") do |t| - t.libs << "test" - t.pattern = 'test/{controllers,mailers,functional}/**/*_test.rb' - end - - Rails::SubTestTask.new(integration: "test:prepare") do |t| - t.libs << "test" - t.pattern = 'test/integration/**/*_test.rb' + exec "bundle exec rails test #{test_suit_name}" + end end end diff --git a/railties/lib/rails/version.rb b/railties/lib/rails/version.rb index 87fc7690ac..fee352db5a 100644 --- a/railties/lib/rails/version.rb +++ b/railties/lib/rails/version.rb @@ -1,10 +1,10 @@ module Rails - module VERSION #:nodoc: + module VERSION MAJOR = 4 MINOR = 0 TINY = 0 PRE = "beta1" - STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.') + STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".") end end diff --git a/railties/railties.gemspec b/railties/railties.gemspec index a55bf012da..45968052a8 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', 'bin/**/*', 'lib/**/{*,.[a-z]*}'] + s.files = Dir['CHANGELOG.md', 'README.rdoc', 'RDOC_MAIN.rdoc', 'bin/**/*', 'lib/**/{*,.[a-z]*}'] s.require_path = 'lib' s.bindir = 'bin' @@ -27,6 +27,5 @@ Gem::Specification.new do |s| s.add_dependency 'actionpack', version s.add_dependency 'rake', '>= 0.8.7' - s.add_dependency 'thor', '>= 0.17.0', '< 2.0' - s.add_dependency 'rdoc', '~> 3.4' + s.add_dependency 'thor', '>= 0.18.1', '< 2.0' end diff --git a/railties/test/application/asset_debugging_test.rb b/railties/test/application/asset_debugging_test.rb index 1eddfac664..b3b40448c0 100644 --- a/railties/test/application/asset_debugging_test.rb +++ b/railties/test/application/asset_debugging_test.rb @@ -48,7 +48,7 @@ module ApplicationTests assert_no_match(/<script src="\/assets\/xmlhr-([0-z]+)\.js"><\/script>/, last_response.body) end - test "assets aren't concatened when compile is true is on and debug_assets params is true" do + 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" diff --git a/railties/test/application/assets_test.rb b/railties/test/application/assets_test.rb index 638df8ca23..34432eac3a 100644 --- a/railties/test/application/assets_test.rb +++ b/railties/test/application/assets_test.rb @@ -41,6 +41,7 @@ module ApplicationTests end test "assets routes have higher priority" do + app_file "app/assets/images/rails.png", "notactuallyapng" app_file "app/assets/javascripts/demo.js.erb", "a = <%= image_path('rails.png').inspect %>;" app_file 'config/routes.rb', <<-RUBY @@ -86,8 +87,8 @@ module ApplicationTests def test_precompile_does_not_hit_the_database app_file "app/assets/javascripts/application.js", "alert();" app_file "app/assets/javascripts/foo/application.js", "alert();" - app_file "app/controllers/user_controller.rb", <<-eoruby - class UserController < ApplicationController; end + app_file "app/controllers/users_controller.rb", <<-eoruby + class UsersController < ApplicationController; end eoruby app_file "app/models/user.rb", <<-eoruby class User < ActiveRecord::Base; end @@ -221,7 +222,8 @@ module ApplicationTests assert !defined?(Uglifier) end - test "precompile properly refers files referenced with asset_path and and run in the provided RAILS_ENV" do + test "precompile properly refers files referenced with asset_path and runs in the provided RAILS_ENV" do + app_file "app/assets/images/rails.png", "notactuallyapng" app_file "app/assets/stylesheets/application.css.erb", "<%= asset_path('rails.png') %>" # digest is default in false, we must enable it for test environment add_to_env_config "test", "config.assets.digest = true" @@ -233,6 +235,8 @@ module ApplicationTests end test "precompile shouldn't use the digests present in manifest.json" do + app_file "app/assets/images/rails.png", "notactuallyapng" + app_file "app/assets/stylesheets/application.css.erb", "//= depend_on rails.png\np { url: <%= asset_path('rails.png') %> }" ENV["RAILS_ENV"] = "production" @@ -251,6 +255,7 @@ module ApplicationTests 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') %>" add_to_config "config.assets.compile = true" add_to_config "config.assets.digest = true" @@ -272,7 +277,7 @@ module ApplicationTests manifest = Dir["#{app_path}/public/assets/manifest-*.json"].first assets = ActiveSupport::JSON.decode(File.read(manifest)) - assert asset_path = assets["assets"].find { |(k, _)| k !~ /rails.png/ && k =~ /.png/ }[1] + assert asset_path = assets["assets"].find { |(k, _)| k && k =~ /.png/ }[1] require "#{app_path}/config/environment" @@ -431,6 +436,7 @@ module ApplicationTests end test "asset urls should be protocol-relative if no request is in scope" do + app_file "app/assets/images/rails.png", "notreallyapng" app_file "app/assets/javascripts/image_loader.js.erb", 'var src="<%= image_path("rails.png") %>";' add_to_config "config.assets.precompile = %w{image_loader.js}" add_to_config "config.asset_host = 'example.com'" @@ -441,6 +447,7 @@ module ApplicationTests test "asset paths should use RAILS_RELATIVE_URL_ROOT by default" do ENV["RAILS_RELATIVE_URL_ROOT"] = "/sub/uri" + app_file "app/assets/images/rails.png", "notreallyapng" app_file "app/assets/javascripts/app.js.erb", 'var src="<%= image_path("rails.png") %>";' add_to_config "config.assets.precompile = %w{app.js}" diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb index 7b45623f6c..1acf03f35a 100644 --- a/railties/test/application/configuration_test.rb +++ b/railties/test/application/configuration_test.rb @@ -599,7 +599,7 @@ module ApplicationTests assert_equal :log, ActionController::Parameters.action_on_unpermitted_parameters end - test "config.action_controller.action_on_unpermitted_parameters is :log by defaul on test" do + test "config.action_controller.action_on_unpermitted_parameters is :log by default on test" do ENV["RAILS_ENV"] = "test" require "#{app_path}/config/environment" diff --git a/railties/test/application/console_test.rb b/railties/test/application/console_test.rb index 3cb3643e3a..31bc003dcb 100644 --- a/railties/test/application/console_test.rb +++ b/railties/test/application/console_test.rb @@ -81,18 +81,73 @@ class ConsoleTest < ActiveSupport::TestCase assert_equal 'Once upon a time in a world...', helper.truncate('Once upon a time in a world far far away') end +end + +begin + require "pty" +rescue LoadError +end + +class FullStackConsoleTest < ActiveSupport::TestCase + def setup + skip "PTY unavailable" unless defined?(PTY) && PTY.respond_to?(:open) + + build_app + app_file 'app/models/post.rb', <<-CODE + class Post < ActiveRecord::Base + end + CODE + system "#{app_path}/bin/rails runner 'Post.connection.create_table :posts'" + + @master, @slave = PTY.open + end + + def teardown + teardown_app + end - def test_with_sandbox - require 'rails/all' - value = false + def assert_output(expected, timeout = 1) + timeout = Time.now + timeout - Class.new(Rails::Railtie) do - console do |app| - value = app.sandbox? + output = "" + until output.include?(expected) || Time.now > timeout + if IO.select([@master], [], [], 0.1) + output << @master.read(1) end end - load_environment(true) - assert value + assert output.include?(expected), "#{expected.inspect} expected, but got:\n\n#{output}" + end + + def write_prompt(command, expected_output = nil) + @master.puts command + assert_output command + assert_output expected_output if expected_output + assert_output "> " + end + + def spawn_console + Process.spawn( + "#{app_path}/bin/rails console --sandbox", + in: @slave, out: @slave, err: @slave + ) + + assert_output "> ", 30 + end + + def test_sandbox + spawn_console + + write_prompt "Post.count", "=> 0" + write_prompt "Post.create" + write_prompt "Post.count", "=> 1" + @master.puts "quit" + + spawn_console + + write_prompt "Post.count", "=> 0" + write_prompt "Post.transaction { Post.create; raise }" + write_prompt "Post.count", "=> 0" + @master.puts "quit" end end diff --git a/railties/test/application/initializers/i18n_test.rb b/railties/test/application/initializers/i18n_test.rb index 489b7ddb92..17d0b10b70 100644 --- a/railties/test/application/initializers/i18n_test.rb +++ b/railties/test/application/initializers/i18n_test.rb @@ -45,7 +45,7 @@ module ApplicationTests end # Load paths - test "no config locales dir present should return empty load path" do + test "no config locales directory present should return empty load path" do FileUtils.rm_rf "#{app_path}/config/locales" load_app assert_equal [], Rails.application.config.i18n.load_path diff --git a/railties/test/application/initializers/load_path_test.rb b/railties/test/application/initializers/load_path_test.rb index 31811e7f92..9b18c329ec 100644 --- a/railties/test/application/initializers/load_path_test.rb +++ b/railties/test/application/initializers/load_path_test.rb @@ -23,7 +23,7 @@ module ApplicationTests assert $:.include?("#{app_path}/app/models") end - test "initializing an application allows to load code on lib path inside application class definitation" do + test "initializing an application allows to load code on lib path inside application class definition" do app_file "lib/foo.rb", <<-RUBY module Foo; end RUBY diff --git a/railties/test/application/middleware/cookies_test.rb b/railties/test/application/middleware/cookies_test.rb index 18af7abafc..bbb7627be9 100644 --- a/railties/test/application/middleware/cookies_test.rb +++ b/railties/test/application/middleware/cookies_test.rb @@ -33,7 +33,7 @@ module ApplicationTests assert_equal false, ActionDispatch::Cookies::CookieJar.always_write_cookie end - test 'always_write_cookie can be overrided' do + test 'always_write_cookie can be overridden' do add_to_config <<-RUBY config.action_dispatch.always_write_cookie = false RUBY diff --git a/railties/test/application/middleware/remote_ip_test.rb b/railties/test/application/middleware/remote_ip_test.rb index f0d3438aa4..91c5807379 100644 --- a/railties/test/application/middleware/remote_ip_test.rb +++ b/railties/test/application/middleware/remote_ip_test.rb @@ -1,5 +1,4 @@ require 'isolation/abstract_unit' -# FIXME remove DummyKeyGenerator and this require in 4.1 require 'active_support/key_generator' module ApplicationTests @@ -10,7 +9,7 @@ module ApplicationTests remote_ip = nil env = Rack::MockRequest.env_for("/").merge(env).merge!( 'action_dispatch.show_exceptions' => false, - 'action_dispatch.key_generator' => ActiveSupport::DummyKeyGenerator.new('b3c631c314c0bbca50c1b2843150fe33') + 'action_dispatch.key_generator' => ActiveSupport::LegacyKeyGenerator.new('b3c631c314c0bbca50c1b2843150fe33') ) endpoint = Proc.new do |e| diff --git a/railties/test/application/middleware/session_test.rb b/railties/test/application/middleware/session_test.rb index a5fdfbf887..8cb0dfeb63 100644 --- a/railties/test/application/middleware/session_test.rb +++ b/railties/test/application/middleware/session_test.rb @@ -157,10 +157,6 @@ module ApplicationTests end RUBY - add_to_config <<-RUBY - config.session_store :encrypted_cookie_store, key: '_myapp_session' - RUBY - require "#{app_path}/config/environment" get '/foo/write_session' @@ -178,7 +174,7 @@ module ApplicationTests assert_equal 1, encryptor.decrypt_and_verify(last_response.body)['foo'] end - test "session using upgrade signature to encryption cookie store works the same way as encrypted cookie store" do + test "session upgrading signature to encryption cookie store works the same way as encrypted cookie store" do app_file 'config/routes.rb', <<-RUBY AppTemplate::Application.routes.draw do get ':controller(/:action)' @@ -208,7 +204,6 @@ module ApplicationTests add_to_config <<-RUBY config.secret_token = "3b7cd727ee24e8444053437c36cc66c4" - config.session_store :upgrade_signature_to_encryption_cookie_store, key: '_myapp_session' RUBY require "#{app_path}/config/environment" @@ -228,7 +223,7 @@ module ApplicationTests assert_equal 1, encryptor.decrypt_and_verify(last_response.body)['foo'] end - test "session using upgrade signature to encryption cookie store upgrades session to encrypted mode" do + test "session upgrading signature to encryption cookie store upgrades session to encrypted mode" do app_file 'config/routes.rb', <<-RUBY AppTemplate::Application.routes.draw do get ':controller(/:action)' @@ -264,7 +259,6 @@ module ApplicationTests add_to_config <<-RUBY config.secret_token = "3b7cd727ee24e8444053437c36cc66c4" - config.session_store :upgrade_signature_to_encryption_cookie_store, key: '_myapp_session' RUBY require "#{app_path}/config/environment" @@ -287,5 +281,63 @@ module ApplicationTests get '/foo/read_raw_cookie' assert_equal 2, encryptor.decrypt_and_verify(last_response.body)['foo'] end + + test "session upgrading legacy signed cookies to new signed cookies" do + app_file 'config/routes.rb', <<-RUBY + AppTemplate::Application.routes.draw do + get ':controller(/:action)' + end + RUBY + + controller :foo, <<-RUBY + class FooController < ActionController::Base + def write_raw_session + # {"session_id"=>"1965d95720fffc123941bdfb7d2e6870", "foo"=>1} + cookies[:_myapp_session] = "BAh7B0kiD3Nlc3Npb25faWQGOgZFRkkiJTE5NjVkOTU3MjBmZmZjMTIzOTQxYmRmYjdkMmU2ODcwBjsAVEkiCGZvbwY7AEZpBg==--315fb9931921a87ae7421aec96382f0294119749" + render nothing: true + end + + def write_session + session[:foo] = session[:foo] + 1 + render nothing: true + end + + def read_session + render text: session[:foo] + end + + def read_signed_cookie + render text: cookies.signed[:_myapp_session]['foo'] + end + + def read_raw_cookie + render text: cookies[:_myapp_session] + end + end + RUBY + + add_to_config <<-RUBY + config.secret_token = "3b7cd727ee24e8444053437c36cc66c4" + config.secret_key_base = nil + RUBY + + require "#{app_path}/config/environment" + + get '/foo/write_raw_session' + get '/foo/read_session' + assert_equal '1', last_response.body + + get '/foo/write_session' + get '/foo/read_session' + assert_equal '2', last_response.body + + get '/foo/read_signed_cookie' + assert_equal '2', last_response.body + + verifier = ActiveSupport::MessageVerifier.new(app.config.secret_token) + + get '/foo/read_raw_cookie' + assert_equal 2, verifier.verify(last_response.body)['foo'] + end end end diff --git a/railties/test/application/rake_test.rb b/railties/test/application/rake_test.rb index 09f2ad1209..4b8e813105 100644 --- a/railties/test/application/rake_test.rb +++ b/railties/test/application/rake_test.rb @@ -91,19 +91,9 @@ module ApplicationTests raise 'models' RUBY - app_file "test/controllers/one_controller_test.rb", <<-RUBY - raise 'controllers' - RUBY - - app_file "test/integration/one_integration_test.rb", <<-RUBY - raise 'integration' - RUBY - silence_stderr do output = Dir.chdir(app_path) { `rake test 2>&1` } assert_match 'models', output - assert_match 'controllers', output - assert_match 'integration', output end end @@ -135,6 +125,19 @@ module ApplicationTests end end + def test_rake_test_deprecation_messages + Dir.chdir(app_path){ `rails generate scaffold user name:string` } + Dir.chdir(app_path){ `rake db:migrate` } + + %w(run recent uncommitted models helpers units controllers functionals integration).each do |test_suit_name| + output = Dir.chdir(app_path) { `rake test:#{test_suit_name} 2>&1` } + assert_match(/DEPRECATION WARNING: `rake test:#{test_suit_name}` is deprecated/, output) + end + + assert_match(/DEPRECATION WARNING: `rake test:single` is deprecated/, + Dir.chdir(app_path) { `rake test:single TEST=test/models/user_test.rb 2>&1` }) + end + def test_rake_routes_calls_the_route_inspector app_file "config/routes.rb", <<-RUBY AppTemplate::Application.routes.draw do diff --git a/railties/test/application/test_runner_test.rb b/railties/test/application/test_runner_test.rb new file mode 100644 index 0000000000..56ca3bc1a9 --- /dev/null +++ b/railties/test/application/test_runner_test.rb @@ -0,0 +1,312 @@ +require 'isolation/abstract_unit' +require 'active_support/core_ext/string/strip' + +module ApplicationTests + class TestRunnerTest < ActiveSupport::TestCase + include ActiveSupport::Testing::Isolation + + def setup + build_app + ENV['RAILS_ENV'] = nil + create_schema + end + + def teardown + teardown_app + end + + def test_should_not_display_heading + create_test_file + run_test_command.tap do |output| + assert_no_match "Run options:", output + assert_no_match "Running tests:", output + end + 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_shortcut + create_test_file :models, 'foo' + output = Dir.chdir(app_path) { `bundle exec rails t test/models/foo_test.rb` } + assert_match "1 tests, 1 assertions, 0 failures", output + end + + def test_run_single_file + create_test_file :models, 'foo' + assert_match "1 tests, 1 assertions, 0 failures", run_test_command("test/models/foo_test.rb") + end + + def test_run_multiple_files + create_test_file :models, 'foo' + create_test_file :models, 'bar' + assert_match "2 tests, 2 assertions, 0 failures", run_test_command("test/models/foo_test.rb test/models/bar_test.rb") + end + + def test_run_file_with_syntax_error + app_file 'test/models/error_test.rb', <<-RUBY + require 'test_helper' + def; end + RUBY + + error_stream = Tempfile.new('error') + redirect_stderr(error_stream) { run_test_command('test/models/error_test.rb') } + assert_match "SyntaxError", error_stream.read + end + + def test_invoke_rake_db_test_load + app_file "lib/tasks/test.rake", <<-RUBY + task 'db:test:load' do + puts "Hello World" + end + RUBY + create_test_file + assert_match "Hello World", run_test_command + end + + def test_run_models + create_test_file :models, 'foo' + create_test_file :models, 'bar' + create_test_file :controllers, 'foobar_controller' + run_test_command("models").tap do |output| + assert_match "FooTest", output + assert_match "BarTest", output + assert_match "2 tests, 2 assertions, 0 failures", output + end + end + + def test_run_helpers + create_test_file :helpers, 'foo_helper' + create_test_file :helpers, 'bar_helper' + create_test_file :controllers, 'foobar_controller' + run_test_command('helpers').tap do |output| + assert_match "FooHelperTest", output + assert_match "BarHelperTest", output + assert_match "2 tests, 2 assertions, 0 failures", output + end + end + + def test_run_units + create_test_file :models, 'foo' + create_test_file :helpers, 'bar_helper' + create_test_file :unit, 'baz_unit' + create_test_file :controllers, 'foobar_controller' + run_test_command('units').tap do |output| + assert_match "FooTest", output + assert_match "BarHelperTest", output + assert_match "BazUnitTest", output + assert_match "3 tests, 3 assertions, 0 failures", output + end + end + + def test_run_controllers + create_test_file :controllers, 'foo_controller' + create_test_file :controllers, 'bar_controller' + create_test_file :models, 'foo' + run_test_command('controllers').tap do |output| + assert_match "FooControllerTest", output + assert_match "BarControllerTest", output + assert_match "2 tests, 2 assertions, 0 failures", output + end + end + + def test_run_mailers + create_test_file :mailers, 'foo_mailer' + create_test_file :mailers, 'bar_mailer' + create_test_file :models, 'foo' + run_test_command('mailers').tap do |output| + assert_match "FooMailerTest", output + assert_match "BarMailerTest", output + assert_match "2 tests, 2 assertions, 0 failures", output + end + end + + def test_run_functionals + create_test_file :mailers, 'foo_mailer' + create_test_file :controllers, 'bar_controller' + create_test_file :functional, 'baz_functional' + create_test_file :models, 'foo' + run_test_command('functionals').tap do |output| + assert_match "FooMailerTest", output + assert_match "BarControllerTest", output + assert_match "BazFunctionalTest", output + assert_match "3 tests, 3 assertions, 0 failures", output + end + end + + def test_run_integration + create_test_file :integration, 'foo_integration' + create_test_file :models, 'foo' + run_test_command('integration').tap do |output| + assert_match "FooIntegration", output + assert_match "1 tests, 1 assertions, 0 failures", output + end + end + + def test_run_all_suites + suites = [:models, :helpers, :unit, :controllers, :mailers, :functional, :integration] + suites.each { |suite| create_test_file suite, "foo_#{suite}" } + run_test_command('') .tap do |output| + suites.each { |suite| assert_match "Foo#{suite.to_s.camelize}Test", output } + assert_match "7 tests, 7 assertions, 0 failures", output + end + end + + def test_run_named_test + app_file 'test/unit/chu_2_koi_test.rb', <<-RUBY + require 'test_helper' + + class Chu2KoiTest < ActiveSupport::TestCase + def test_rikka + puts 'Rikka' + end + + def test_sanae + puts 'Sanae' + end + end + RUBY + + run_test_command('test/unit/chu_2_koi_test.rb -n test_rikka').tap do |output| + assert_match "Rikka", output + assert_no_match "Sanae", output + end + end + + def test_not_load_fixtures_when_running_single_test + create_model_with_fixture + create_fixture_test :models, 'user' + assert_match "0 users", run_test_command('test/models/user_test.rb') + assert_match "3 users", run_test_command('test/models/user_test.rb -f') + end + + def test_load_fixtures_when_running_test_suites + create_model_with_fixture + suites = [:models, :helpers, [:units, :unit], :controllers, :mailers, + [:functionals, :functional], :integration] + + suites.each do |suite, directory| + directory ||= suite + create_fixture_test directory + assert_match "3 users", run_test_command(suite) + Dir.chdir(app_path) { FileUtils.rm_f "test/#{directory}" } + end + end + + def test_run_different_environment_using_env_var + app_file 'test/unit/env_test.rb', <<-RUBY + require 'test_helper' + + class EnvTest < ActiveSupport::TestCase + def test_env + puts Rails.env + end + end + RUBY + + ENV['RAILS_ENV'] = 'development' + assert_match "development", run_test_command('test/unit/env_test.rb') + end + + def test_run_different_environment_using_e_tag + app_file 'test/unit/env_test.rb', <<-RUBY + require 'test_helper' + + class EnvTest < ActiveSupport::TestCase + def test_env + puts Rails.env + end + end + RUBY + + assert_match "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 + + private + def run_test_command(arguments = 'test/unit/test_test.rb') + Dir.chdir(app_path) { `bundle exec rails test #{arguments}` } + end + + def create_model_with_fixture + script 'generate model user name:string' + + app_file 'test/fixtures/users.yml', <<-YAML.strip_heredoc + vampire: + id: 1 + name: Koyomi Araragi + crab: + id: 2 + name: Senjougahara Hitagi + cat: + id: 3 + name: Tsubasa Hanekawa + YAML + + run_migration + end + + def create_fixture_test(path = :unit, name = 'test') + app_file "test/#{path}/#{name}_test.rb", <<-RUBY + require 'test_helper' + + class #{name.camelize}Test < ActiveSupport::TestCase + def test_fixture + puts "\#{User.count} users (\#{__FILE__})" + end + end + RUBY + end + + def create_schema + app_file 'db/schema.rb', '' + end + + def redirect_stderr(target_stream) + previous_stderr = STDERR.dup + $stderr.reopen(target_stream) + yield + target_stream.rewind + ensure + $stderr = previous_stderr + end + + def create_test_file(path = :unit, name = 'test') + 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 + end + end + RUBY + end + + def create_scaffold + script 'generate scaffold user name:string' + Dir.chdir(app_path) { File.exist?('app/models/user.rb') } + run_migration + end + + def run_migration + Dir.chdir(app_path) { `bundle exec rake db:migrate` } + end + end +end diff --git a/railties/test/commands/console_test.rb b/railties/test/commands/console_test.rb index 6be4a5fe89..a34beaedb3 100644 --- a/railties/test/commands/console_test.rb +++ b/railties/test/commands/console_test.rb @@ -58,10 +58,7 @@ class Rails::ConsoleTest < ActiveSupport::TestCase end def test_console_defaults_to_IRB - config = mock("config", console: nil) - app = mock("app", config: config) - app.expects(:load_console).returns(nil) - + app = build_app(console: nil) assert_equal IRB, Rails::Console.new(app).console end @@ -117,9 +114,10 @@ class Rails::ConsoleTest < ActiveSupport::TestCase assert_match('dev', options[:environment]) end - private - attr_reader :output + private :output + + private def start(argv = []) rails_console = Rails::Console.new(app, parse_arguments(argv)) @@ -127,13 +125,15 @@ class Rails::ConsoleTest < ActiveSupport::TestCase end def app - @app ||= begin - config = mock("config", console: FakeConsole) - app = mock("app", config: config) - app.stubs(:sandbox=).returns(nil) - app.expects(:load_console) - app - end + @app ||= build_app(console: FakeConsole) + end + + def build_app(config) + config = mock("config", config) + app = mock("app", config: config) + app.stubs(:sandbox=).returns(nil) + app.expects(:load_console) + app end def parse_arguments(args) diff --git a/railties/test/commands/dbconsole_test.rb b/railties/test/commands/dbconsole_test.rb index 38fe8ca544..edb92b3aa2 100644 --- a/railties/test/commands/dbconsole_test.rb +++ b/railties/test/commands/dbconsole_test.rb @@ -172,8 +172,10 @@ class Rails::DBConsoleTest < ActiveSupport::TestCase assert_match(/Usage:.*dbconsole/, stdout) end - private attr_reader :aborted, :output + private :aborted, :output + + private def dbconsole @dbconsole ||= Rails::DBConsole.new(nil) diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb index 0697035871..5fdf58c8ee 100644 --- a/railties/test/generators/app_generator_test.rb +++ b/railties/test/generators/app_generator_test.rb @@ -232,8 +232,8 @@ class AppGeneratorTest < Rails::Generators::TestCase end assert_file "Gemfile" do |content| assert_no_match(/sass-rails/, content) - assert_no_match(/coffee-rails/, content) assert_no_match(/uglifier/, content) + assert_match(/coffee-rails/, content) end assert_file "config/environments/development.rb" do |content| assert_no_match(/config\.assets\.debug = true/, content) @@ -276,7 +276,7 @@ class AppGeneratorTest < Rails::Generators::TestCase assert_match %r{^//= require jquery}, contents assert_match %r{^//= require jquery_ujs}, contents end - assert_gem "jquery-rails" + assert_file "Gemfile", /^gem 'jquery-rails'/ end def test_other_javascript_libraries @@ -293,6 +293,9 @@ class AppGeneratorTest < Rails::Generators::TestCase assert_file "app/assets/javascripts/application.js" do |contents| assert_no_match %r{^//=\s+require\s}, contents end + assert_file "Gemfile" do |content| + assert_match(/coffee-rails/, content) + end end def test_inclusion_of_debugger @@ -300,6 +303,11 @@ class AppGeneratorTest < Rails::Generators::TestCase assert_file "Gemfile", /# gem 'debugger'/ end + def test_inclusion_of_lazy_loaded_sdoc + run_generator + assert_file 'Gemfile', /gem 'sdoc', require: false/ + end + def test_template_from_dir_pwd FileUtils.cd(Rails.root) assert_match(/It works from file!/, run_generator([destination_root, "-m", "lib/template.rb"])) @@ -338,7 +346,7 @@ class AppGeneratorTest < Rails::Generators::TestCase def test_new_hash_style run_generator [destination_root] assert_file "config/initializers/session_store.rb" do |file| - assert_match(/config.session_store :encrypted_cookie_store, key: '_.+_session'/, file) + assert_match(/config.session_store :cookie_store, key: '_.+_session'/, file) end end diff --git a/railties/test/generators/plugin_new_generator_test.rb b/railties/test/generators/plugin_new_generator_test.rb index 34441ef679..ac71fb5884 100644 --- a/railties/test/generators/plugin_new_generator_test.rb +++ b/railties/test/generators/plugin_new_generator_test.rb @@ -124,7 +124,7 @@ class PluginNewGeneratorTest < Rails::Generators::TestCase run_generator [destination_root, "--skip_active_record"] assert_no_file "test/dummy/config/database.yml" assert_file "test/test_helper.rb" do |contents| - assert_no_match /ActiveRecord/, contents + assert_no_match(/ActiveRecord/, contents) end end @@ -292,7 +292,7 @@ class PluginNewGeneratorTest < Rails::Generators::TestCase assert_no_file "bukkits.gemspec" assert_file "Gemfile" do |contents| assert_no_match('gemspec', contents) - assert_match(/gem "rails", "~> #{Rails::VERSION::STRING}"/, contents) + assert_match(/gem "rails", "~> #{Rails.version}"/, contents) assert_match(/group :development do\n gem "sqlite3"\nend/, contents) assert_no_match(/# gem "jquery-rails"/, contents) end @@ -303,7 +303,7 @@ class PluginNewGeneratorTest < Rails::Generators::TestCase assert_no_file "bukkits.gemspec" assert_file "Gemfile" do |contents| assert_no_match('gemspec', contents) - assert_match(/gem "rails", "~> #{Rails::VERSION::STRING}"/, contents) + assert_match(/gem "rails", "~> #{Rails.version}"/, contents) assert_match(/group :development do\n gem "sqlite3"\nend/, contents) end end diff --git a/railties/test/generators/scaffold_generator_test.rb b/railties/test/generators/scaffold_generator_test.rb index 357f472a3f..25f299118c 100644 --- a/railties/test/generators/scaffold_generator_test.rb +++ b/railties/test/generators/scaffold_generator_test.rb @@ -241,7 +241,7 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase def test_scaffold_generator_no_assets run_generator [ "posts", "--no-assets" ] - assert_file "app/assets/stylesheets/scaffold.css" + assert_no_file "app/assets/stylesheets/scaffold.css" assert_no_file "app/assets/javascripts/posts.js" assert_no_file "app/assets/stylesheets/posts.css" end @@ -271,4 +271,45 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase end end end + + def test_scaffold_generator_password_digest + run_generator ["user", "name", "password:digest"] + + assert_file "app/models/user.rb", /has_secure_password/ + + assert_migration "db/migrate/create_users.rb" do |m| + assert_method :change, m do |up| + assert_match(/t\.string :name/, up) + assert_match(/t\.string :password_digest/, up) + end + end + + assert_file "app/controllers/users_controller.rb" do |content| + assert_instance_method :user_params, content do |m| + assert_match(/permit\(:name, :password, :password_confirmation\)/, m) + end + end + + assert_file "app/views/users/_form.html.erb" do |content| + assert_match(/<%= f\.password_field :password %>/, content) + assert_match(/<%= f\.password_field :password_confirmation %>/, content) + end + + assert_file "app/views/users/index.html.erb" do |content| + assert_no_match(/password/, content) + end + + assert_file "app/views/users/show.html.erb" do |content| + assert_no_match(/password/, content) + end + + assert_file "test/controllers/users_controller_test.rb" do |content| + assert_match(/password: 'secret'/, content) + assert_match(/password_confirmation: 'secret'/, content) + end + + assert_file "test/fixtures/users.yml" do |content| + assert_match(/password_digest: <%= BCrypt::Password.create\('secret'\) %>/, content) + end + end end diff --git a/railties/test/generators_test.rb b/railties/test/generators_test.rb index 9953aa929b..361784f509 100644 --- a/railties/test/generators_test.rb +++ b/railties/test/generators_test.rb @@ -164,7 +164,7 @@ class GeneratorsTest < Rails::Generators::TestCase Rails::Generators.invoke "super_shoulda:model", ["Account"] end - def test_developer_options_are_overwriten_by_user_options + def test_developer_options_are_overwritten_by_user_options Rails::Generators.options[:with_options] = { generate: false } self.class.class_eval(<<-end_eval, __FILE__, __LINE__ + 1) diff --git a/railties/test/rails_info_test.rb b/railties/test/rails_info_test.rb index b9fb071d23..5b9088cb64 100644 --- a/railties/test/rails_info_test.rb +++ b/railties/test/rails_info_test.rb @@ -38,7 +38,7 @@ class InfoTest < ActiveSupport::TestCase end def test_framework_version - assert_property 'Active Support version', ActiveSupport::VERSION::STRING + assert_property 'Active Support version', ActiveSupport.version.to_s end def test_frameworks_exist diff --git a/railties/test/railties/engine_test.rb b/railties/test/railties/engine_test.rb index 37d0be107c..01fa2c6864 100644 --- a/railties/test/railties/engine_test.rb +++ b/railties/test/railties/engine_test.rb @@ -105,7 +105,7 @@ module RailtiesTest assert_not_nil bukkits_migration_order, "Expected migration to be skipped" migrations_count = Dir["#{app_path}/db/migrate/*.rb"].length - output = `bundle exec rake railties:install:migrations` + `bundle exec rake railties:install:migrations` assert_equal migrations_count, Dir["#{app_path}/db/migrate/*.rb"].length end @@ -187,7 +187,7 @@ module RailtiesTest assert_equal "Hello bukkits\n", response[2].body end - test "adds its views to view paths with lower proriority than app ones" do + test "adds its views to view paths with lower priority than app ones" do @plugin.write "app/controllers/bukkit_controller.rb", <<-RUBY class BukkitController < ActionController::Base def index diff --git a/railties/test/railties/railtie_test.rb b/railties/test/railties/railtie_test.rb index c80b0f63af..0786b8f8c7 100644 --- a/railties/test/railties/railtie_test.rb +++ b/railties/test/railties/railtie_test.rb @@ -32,7 +32,7 @@ module RailtiesTest end end - test "railtie_name can be set manualy" do + test "railtie_name can be set manually" do class Foo < Rails::Railtie railtie_name "bar" end |