diff options
author | Rafael Mendonça França <rafaelmfranca@gmail.com> | 2014-08-12 11:10:42 -0300 |
---|---|---|
committer | Rafael Mendonça França <rafaelmfranca@gmail.com> | 2014-08-12 11:10:42 -0300 |
commit | a2400308eab88b5eff27e05d1f7624345fb33b54 (patch) | |
tree | 38630de37ac59c50061734d9f353ebb798ba2023 /railties | |
parent | 045d7173167043389dbe8bd961425c1b1cc86d48 (diff) | |
parent | 82e28492e7c581cdeea904464a18eb11118f4ac0 (diff) | |
download | rails-a2400308eab88b5eff27e05d1f7624345fb33b54.tar.gz rails-a2400308eab88b5eff27e05d1f7624345fb33b54.tar.bz2 rails-a2400308eab88b5eff27e05d1f7624345fb33b54.zip |
Merge branch 'master' into loofah
Conflicts:
actionpack/CHANGELOG.md
actionpack/test/controller/integration_test.rb
actionview/CHANGELOG.md
Diffstat (limited to 'railties')
59 files changed, 977 insertions, 294 deletions
diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md index c33a4ed192..1ccdfb6589 100644 --- a/railties/CHANGELOG.md +++ b/railties/CHANGELOG.md @@ -1,4 +1,51 @@ -* Deprecate `Rails::Rack::LogTailer` with not replacement. +* Add `after_bundle` callbacks in Rails templates. Useful for allowing the + generated binstubs to be added to version control. + + Fixes #16292. + + *Stefan Kanev* + +* Pull in the custom configuration concept from dhh/custom_configuration, which allows you to + configure your own code through the Rails configuration object with custom configuration: + + # config/environments/production.rb + config.x.payment_processing.schedule = :daily + config.x.payment_processing.retries = 3 + config.x.super_debugger = true + + These configuration points are then available through the configuration object: + + Rails.configuration.x.payment_processing.schedule # => :daily + Rails.configuration.x.payment_processing.retries # => 3 + Rails.configuration.x.super_debugger # => true + Rails.configuration.x.super_debugger.not_set # => nil + + *DHH* + +* Scaffold generator `_form` partial adds `class="field"` for password + confirmation fields. + + *noinkling* + +* Add `Rails::Application.config_for` to load a configuration for the current + environment. + + # config/exception_notification.yml: + production: + url: http://127.0.0.1:8080 + namespace: my_app_production + development: + url: http://localhost:3001 + namespace: my_app_development + + # config/production.rb + MyApp::Application.configure do + config.middleware.use ExceptionNotifier, config_for(:exception_notification) + end + + *Rafael Mendonça França*, *DHH* + +* Deprecate `Rails::Rack::LogTailer` without replacement. *Rafael Mendonça França* diff --git a/railties/lib/rails.rb b/railties/lib/rails.rb index ecd8c22dd8..e7172e491f 100644 --- a/railties/lib/rails.rb +++ b/railties/lib/rails.rb @@ -29,7 +29,13 @@ module Rails autoload :WelcomeController class << self - attr_accessor :application, :cache, :logger + @application = @app_class = nil + + attr_writer :application + attr_accessor :app_class, :cache, :logger + def application + @application ||= (app_class.instance if app_class) + end delegate :initialize!, :initialized?, to: :application diff --git a/railties/lib/rails/app_rails_loader.rb b/railties/lib/rails/app_rails_loader.rb index 56f05b3844..39d8007333 100644 --- a/railties/lib/rails/app_rails_loader.rb +++ b/railties/lib/rails/app_rails_loader.rb @@ -2,6 +2,8 @@ require 'pathname' module Rails module AppRailsLoader + extend self + RUBY = Gem.ruby EXECUTABLES = ['bin/rails', 'script/rails'] BUNDLER_WARNING = <<EOS @@ -26,7 +28,7 @@ generate it and add it to source control: EOS - def self.exec_app_rails + def exec_app_rails original_cwd = Dir.pwd loop do @@ -54,7 +56,7 @@ EOS end end - def self.find_executable + def find_executable EXECUTABLES.find { |exe| File.file?(exe) } end end diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb index 362713eb75..61639be7c6 100644 --- a/railties/lib/rails/application.rb +++ b/railties/lib/rails/application.rb @@ -87,7 +87,15 @@ module Rails class << self def inherited(base) super - base.instance + Rails.app_class = base + end + + def instance + super.run_load_hooks! + end + + def create(initial_variable_values = {}, &block) + new(initial_variable_values, &block).run_load_hooks! end # Makes the +new+ method public. @@ -116,24 +124,33 @@ module Rails @ordered_railties = nil @railties = nil @message_verifiers = {} + @ran_load_hooks = false - Rails.application ||= self + # are these actually used? + @initial_variable_values = initial_variable_values + @block = block add_lib_to_load_path! + end + + # Returns true if the application is initialized. + def initialized? + @initialized + end + + def run_load_hooks! # :nodoc: + return self if @ran_load_hooks + @ran_load_hooks = true ActiveSupport.run_load_hooks(:before_configuration, self) - initial_variable_values.each do |variable_name, value| + @initial_variable_values.each do |variable_name, value| if INITIAL_VARIABLES.include?(variable_name) instance_variable_set("@#{variable_name}", value) end end - instance_eval(&block) if block_given? - end - - # Returns true if the application is initialized. - def initialized? - @initialized + instance_eval(&@block) if @block + self end # Implements call according to the Rack API. It simply @@ -187,6 +204,38 @@ module Rails end end + # Convenience for loading config/foo.yml for the current Rails env. + # + # Example: + # + # # config/exception_notification.yml: + # production: + # url: http://127.0.0.1:8080 + # namespace: my_app_production + # development: + # url: http://localhost:3001 + # namespace: my_app_development + # + # # config/production.rb + # MyApp::Application.configure do + # config.middleware.use ExceptionNotifier, config_for(:exception_notification) + # end + def config_for(name) + yaml = Pathname.new("#{paths["config"].existent.first}/#{name}.yml") + + if yaml.exist? + require "yaml" + require "erb" + (YAML.load(ERB.new(yaml.read).result) || {})[Rails.env] || {} + else + raise "Could not load configuration. No such file - #{yaml}" + end + rescue Psych::SyntaxError => e + raise "YAML syntax error occurred while parsing #{yaml}. " \ + "Please note that YAML must be consistently indented using spaces. Tabs are not allowed. " \ + "Error: #{e.message}" + end + # Stores some of the Rails initial environment parameters which # will be used by middlewares and engines to configure themselves. def env_config diff --git a/railties/lib/rails/application/configuration.rb b/railties/lib/rails/application/configuration.rb index 5e8f4de847..782bc4b0f1 100644 --- a/railties/lib/rails/application/configuration.rb +++ b/railties/lib/rails/application/configuration.rb @@ -13,7 +13,7 @@ module Rails :railties_order, :relative_url_root, :secret_key_base, :secret_token, :serve_static_assets, :ssl_options, :static_cache_control, :session_options, :time_zone, :reload_classes_only_on_change, - :beginning_of_week, :filter_redirect + :beginning_of_week, :filter_redirect, :x attr_writer :log_level attr_reader :encoding @@ -48,6 +48,7 @@ module Rails @eager_load = nil @secret_token = nil @secret_key_base = nil + @x = Custom.new @assets = ActiveSupport::OrderedOptions.new @assets.enabled = true @@ -154,6 +155,17 @@ module Rails def annotations SourceAnnotationExtractor::Annotation end + + private + class Custom + def initialize + @configurations = Hash.new + end + + def method_missing(method, *args) + @configurations[method] ||= ActiveSupport::OrderedOptions.new + end + end end end end diff --git a/railties/lib/rails/commands/server.rb b/railties/lib/rails/commands/server.rb index 6146b6c1db..c3b7bb6f84 100644 --- a/railties/lib/rails/commands/server.rb +++ b/railties/lib/rails/commands/server.rb @@ -9,7 +9,17 @@ module Rails def parse!(args) args, options = args.dup, {} - opt_parser = OptionParser.new do |opts| + option_parser(options).parse! args + + options[:log_stdout] = options[:daemonize].blank? && (options[:environment] || Rails.env) == "development" + options[:server] = args.shift + options + end + + private + + def option_parser(options) + OptionParser.new do |opts| opts.banner = "Usage: rails server [mongrel, thin, etc] [options]" opts.on("-p", "--port=port", Integer, "Runs Rails on the specified port.", "Default: 3000") { |v| options[:Port] = v } @@ -37,12 +47,6 @@ module Rails opts.on("-h", "--help", "Show this help message.") { puts opts; exit } end - - opt_parser.parse! args - - options[:log_stdout] = options[:daemonize].blank? && (options[:environment] || Rails.env) == "development" - options[:server] = args.shift - options end end diff --git a/railties/lib/rails/engine.rb b/railties/lib/rails/engine.rb index b36ab3d0d5..dc3da1eb41 100644 --- a/railties/lib/rails/engine.rb +++ b/railties/lib/rails/engine.rb @@ -395,7 +395,7 @@ module Rails end unless mod.respond_to?(:railtie_routes_url_helpers) - define_method(:railtie_routes_url_helpers) { railtie.routes.url_helpers } + define_method(:railtie_routes_url_helpers) {|include_path_helpers = true| railtie.routes.url_helpers(include_path_helpers) } end end end @@ -509,7 +509,7 @@ module Rails def call(env) env.merge!(env_config) if env['SCRIPT_NAME'] - env.merge! "ROUTES_#{routes.object_id}_SCRIPT_NAME" => env['SCRIPT_NAME'].dup + env["ROUTES_#{routes.object_id}_SCRIPT_NAME"] = env['SCRIPT_NAME'].dup end app.call(env) end diff --git a/railties/lib/rails/generators/actions.rb b/railties/lib/rails/generators/actions.rb index a239874df0..4709914947 100644 --- a/railties/lib/rails/generators/actions.rb +++ b/railties/lib/rails/generators/actions.rb @@ -7,6 +7,7 @@ module Rails def initialize(*) # :nodoc: super @in_group = nil + @after_bundle_callbacks = [] end # Adds an entry into +Gemfile+ for the supplied gem. @@ -232,6 +233,16 @@ module Rails log File.read(find_in_source_paths(path)) end + # Registers a callback to be executed after bundle and spring binstubs + # have run. + # + # after_bundle do + # git add: '.' + # end + def after_bundle(&block) + @after_bundle_callbacks << block + end + protected # Define log for backwards compatibility. If just one argument is sent, diff --git a/railties/lib/rails/generators/actions/create_migration.rb b/railties/lib/rails/generators/actions/create_migration.rb index cf3b7acfff..682092fdf2 100644 --- a/railties/lib/rails/generators/actions/create_migration.rb +++ b/railties/lib/rails/generators/actions/create_migration.rb @@ -55,7 +55,8 @@ module Rails else say_status :conflict, :red raise Error, "Another migration is already named #{migration_file_name}: " + - "#{existing_migration}. Use --force to replace this migration file." + "#{existing_migration}. Use --force to replace this migration " + + "or --skip to ignore conflicted file." end end diff --git a/railties/lib/rails/generators/app_base.rb b/railties/lib/rails/generators/app_base.rb index 20e512a7ff..caaaae09e6 100644 --- a/railties/lib/rails/generators/app_base.rb +++ b/railties/lib/rails/generators/app_base.rb @@ -113,7 +113,7 @@ module Rails javascript_gemfile_entry, jbuilder_gemfile_entry, sdoc_gemfile_entry, - spring_gemfile_entry, + psych_gemfile_entry, @extra_entries].flatten.find_all(&@gem_filter) end @@ -194,21 +194,19 @@ module Rails def self.path(name, path, comment = nil) new(name, nil, comment, path: path) end - - def padding(max_width) - ' ' * (max_width - name.length + 2) - end end def rails_gemfile_entry if options.dev? [GemfileEntry.path('rails', Rails::Generators::RAILS_DEV_PATH), GemfileEntry.github('arel', 'rails/arel'), - GemfileEntry.github('rack', 'rack/rack')] + GemfileEntry.github('rack', 'rack/rack'), + GemfileEntry.github('i18n', 'svenfuchs/i18n')] elsif options.edge? [GemfileEntry.github('rails', 'rails/rails'), GemfileEntry.github('arel', 'rails/arel'), - GemfileEntry.github('rack', 'rack/rack')] + GemfileEntry.github('rack', 'rack/rack'), + GemfileEntry.github('i18n', 'svenfuchs/i18n')] else [GemfileEntry.version('rails', Rails::VERSION::STRING, @@ -307,10 +305,12 @@ module Rails end end - def spring_gemfile_entry - return [] unless spring_install? - comment = 'Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring' - GemfileEntry.new('spring', nil, comment, group: :development) + def psych_gemfile_entry + return [] unless defined?(Rubinius) + + comment = 'Use Psych as the YAML engine, instead of Syck, so serialized ' \ + 'data can be read safely from different rubies (see http://git.io/uuLVag)' + GemfileEntry.new('psych', '~> 2.0', comment, platforms: :rbx) 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 da99e74435..bba9141fb8 100644 --- a/railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb +++ b/railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb @@ -17,7 +17,7 @@ <%%= f.label :password %><br> <%%= f.password_field :password %> </div> - <div> + <div class="field"> <%%= f.label :password_confirmation %><br> <%%= f.password_field :password_confirmation %> <% else -%> diff --git a/railties/lib/rails/generators/rails/app/app_generator.rb b/railties/lib/rails/generators/rails/app/app_generator.rb index 188e62b6c8..9110c129d1 100644 --- a/railties/lib/rails/generators/rails/app/app_generator.rb +++ b/railties/lib/rails/generators/rails/app/app_generator.rb @@ -259,6 +259,12 @@ module Rails public_task :apply_rails_template, :run_bundle public_task :generate_spring_binstubs + def run_after_bundle_callbacks + @after_bundle_callbacks.each do |callback| + callback.call + end + end + protected def self.banner diff --git a/railties/lib/rails/generators/rails/app/templates/Gemfile b/railties/lib/rails/generators/rails/app/templates/Gemfile index 5bdbd58097..8b51fda359 100644 --- a/railties/lib/rails/generators/rails/app/templates/Gemfile +++ b/railties/lib/rails/generators/rails/app/templates/Gemfile @@ -1,6 +1,5 @@ source 'https://rubygems.org' -<% max_width = gemfile_entries.map { |g| g.name.length }.max -%> <% gemfile_entries.each do |gem| -%> <% if gem.comment -%> @@ -8,7 +7,7 @@ source 'https://rubygems.org' <% end -%> <%= gem.commented_out ? '# ' : '' %>gem '<%= gem.name %>'<%= %(, '#{gem.version}') if gem.version -%> <% if gem.options.any? -%> -,<%= gem.padding(max_width) %><%= gem.options.map { |k,v| +, <%= gem.options.map { |k,v| "#{k}: #{v.inspect}" }.join(', ') %> <% end -%> <% end -%> @@ -22,14 +21,23 @@ source 'https://rubygems.org' # Use Capistrano for deployment # gem 'capistrano-rails', group: :development +group :development, :test do <% unless defined?(JRUBY_VERSION) -%> -# To use a debugger + # Call 'debugger' anywhere in the code to stop execution and get a debugger console <%- if RUBY_VERSION < '2.0.0' -%> -# gem 'debugger', group: [:development, :test] + gem 'debugger' <%- else -%> -# gem 'byebug', group: [:development, :test] + gem 'byebug' <%- end -%> + + # Access an IRB console on exceptions page and /console in development + gem 'web-console' +<%- if spring_install? %> + # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring + gem 'spring' +<% end -%> <% end -%> +end <% if RUBY_PLATFORM.match(/bccwin|cygwin|emx|mingw|mswin|wince/) -%> # Windows does not include zoneinfo files, so bundle the tzinfo-data gem 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 bbb409616d..35e3035a0b 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 @@ -30,7 +30,8 @@ Rails.application.configure do # number of complex assets. config.assets.debug = true - # Generate digests for assets URLs. + # Asset digests allow you to set far-future HTTP expiration dates on all assets, + # yet still be able to expire them through the digest params. config.assets.digest = true # Adds additional error checking when serving assets at runtime. 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 5e52f97249..277fe01e89 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 @@ -30,7 +30,8 @@ Rails.application.configure do # Do not fallback to assets pipeline if a precompiled asset is missed. config.assets.compile = false - # Generate digests for assets URLs. + # Asset digests allow you to set far-future HTTP expiration dates on all assets, + # yet still be able to expire them through the digest params. config.assets.digest = true # `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb @@ -43,8 +44,8 @@ Rails.application.configure do # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. # config.force_ssl = true - # Set to :debug to see everything in the log. - config.log_level = :info + # Set to :info to decrease the log volume. + config.log_level = :debug # Prepend all log lines with the following tags. # config.log_tags = [ :subdomain, :uuid ] diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/assets.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/initializers/assets.rb.tt index d2f4ec33a6..01ef3e6630 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/initializers/assets.rb.tt +++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/assets.rb.tt @@ -3,6 +3,9 @@ # Version of your assets, change this if you want to expire all your assets. Rails.application.config.assets.version = '1.0' +# Add additional assets to the asset load path +# Rails.application.config.assets.paths << Emoji.images_path + # Precompile additional assets. # application.js, application.css, and all non-JS/CSS in app/assets folder are already added. # Rails.application.config.assets.precompile += %w( search.js ) diff --git a/railties/lib/rails/generators/rails/controller/USAGE b/railties/lib/rails/generators/rails/controller/USAGE index de33900e0a..64239ad599 100644 --- a/railties/lib/rails/generators/rails/controller/USAGE +++ b/railties/lib/rails/generators/rails/controller/USAGE @@ -16,4 +16,3 @@ Example: Test: test/controllers/credit_cards_controller_test.rb Views: app/views/credit_cards/debit.html.erb [...] Helper: app/helpers/credit_cards_helper.rb - Test: test/helpers/credit_cards_helper_test.rb diff --git a/railties/lib/rails/generators/rails/helper/USAGE b/railties/lib/rails/generators/rails/helper/USAGE index 30e323a858..8855ef3b01 100644 --- a/railties/lib/rails/generators/rails/helper/USAGE +++ b/railties/lib/rails/generators/rails/helper/USAGE @@ -5,13 +5,9 @@ Description: To create a helper within a module, specify the helper name as a path like 'parent_module/helper_name'. - This generates a helper class in app/helpers and invokes the configured - test framework. - Example: `rails generate helper CreditCard` Credit card helper. Helper: app/helpers/credit_card_helper.rb - Test: test/helpers/credit_card_helper_test.rb diff --git a/railties/lib/rails/generators/rails/model/USAGE b/railties/lib/rails/generators/rails/model/USAGE index 833b7beb7f..2a6b8700e3 100644 --- a/railties/lib/rails/generators/rails/model/USAGE +++ b/railties/lib/rails/generators/rails/model/USAGE @@ -6,6 +6,11 @@ Description: model's attributes. Timestamps are added by default, so you don't have to specify them by hand as 'created_at:datetime updated_at:datetime'. + As a special case, specifying 'password:digest' will generate a + password_digest field of string type, and configure your generated model and + tests for use with ActiveModel has_secure_password (assuming the default ORM + and test framework are being used). + You don't have to think up every attribute up front, but it helps to sketch out a few so you can start working with the model immediately. @@ -27,7 +32,8 @@ Available field types: `rails generate model post title:string body:text` will generate a title column with a varchar type and a body column with a text - type. You can use the following types: + type. If no type is specified the string type will be used by default. + You can use the following types: integer primary_key @@ -73,6 +79,10 @@ Available field types: `rails generate model user username:string{30}:uniq` `rails generate model product supplier:references{polymorphic}:index` + If you require a `password_digest` string column for use with + has_secure_password, you should specify `password:digest`: + + `rails generate model user password:digest` Examples: `rails generate model account` diff --git a/railties/lib/rails/generators/rails/plugin/templates/Gemfile b/railties/lib/rails/generators/rails/plugin/templates/Gemfile index 796587f316..35ad9fbf9e 100644 --- a/railties/lib/rails/generators/rails/plugin/templates/Gemfile +++ b/railties/lib/rails/generators/rails/plugin/templates/Gemfile @@ -31,7 +31,7 @@ end <% end -%> <%= gem.commented_out ? '# ' : '' %>gem '<%= gem.name %>'<%= %(, '#{gem.version}') if gem.version -%> <% if gem.options.any? -%> -,<%= gem.padding(max_width) %><%= gem.options.map { |k,v| +, <%= gem.options.map { |k,v| "#{k}: #{v.inspect}" }.join(', ') %> <% end -%> <% end -%> diff --git a/railties/lib/rails/generators/rails/scaffold/USAGE b/railties/lib/rails/generators/rails/scaffold/USAGE index 4a3eb2c7c7..1b2a944103 100644 --- a/railties/lib/rails/generators/rails/scaffold/USAGE +++ b/railties/lib/rails/generators/rails/scaffold/USAGE @@ -9,11 +9,16 @@ Description: Attributes are field arguments specifying the model's attributes. You can optionally pass the type and an index to each field. For instance: - "title body:text tracking_id:integer:uniq" will generate a title field of + 'title body:text tracking_id:integer:uniq' will generate a title field of string type, a body with text type and a tracking_id as an integer with an unique index. "index" could also be given instead of "uniq" if one desires a non unique index. + As a special case, specifying 'password:digest' will generate a + password_digest field of string type, and configure your generated model, + controller, views, and test suite for use with ActiveModel + has_secure_password (assuming they are using Rails defaults). + Timestamps are added by default, so you don't have to specify them by hand as 'created_at:datetime updated_at:datetime'. @@ -33,3 +38,4 @@ Examples: `rails generate scaffold post` `rails generate scaffold post title body:text published:boolean` `rails generate scaffold purchase amount:decimal tracking_id:integer:uniq` + `rails generate scaffold user email:uniq password:digest` diff --git a/railties/lib/rails/generators/test_unit/helper/helper_generator.rb b/railties/lib/rails/generators/test_unit/helper/helper_generator.rb index 0db76f9eaf..bde4e88915 100644 --- a/railties/lib/rails/generators/test_unit/helper/helper_generator.rb +++ b/railties/lib/rails/generators/test_unit/helper/helper_generator.rb @@ -3,11 +3,7 @@ require 'rails/generators/test_unit' module TestUnit # :nodoc: module Generators # :nodoc: class HelperGenerator < Base # :nodoc: - check_class_collision suffix: "HelperTest" - - def create_helper_files - template 'helper_test.rb', File.join('test/helpers', class_path, "#{file_name}_helper_test.rb") - end + # Rails does not generate anything here. end end end diff --git a/railties/lib/rails/generators/test_unit/helper/templates/helper_test.rb b/railties/lib/rails/generators/test_unit/helper/templates/helper_test.rb deleted file mode 100644 index 7d37bda0f9..0000000000 --- a/railties/lib/rails/generators/test_unit/helper/templates/helper_test.rb +++ /dev/null @@ -1,6 +0,0 @@ -require 'test_helper' - -<% module_namespacing do -%> -class <%= class_name %>HelperTest < ActionView::TestCase -end -<% end -%> diff --git a/railties/lib/rails/generators/testing/behaviour.rb b/railties/lib/rails/generators/testing/behaviour.rb index 7576eba6e0..e0600d0b59 100644 --- a/railties/lib/rails/generators/testing/behaviour.rb +++ b/railties/lib/rails/generators/testing/behaviour.rb @@ -100,6 +100,23 @@ module Rails dirname, file_name = File.dirname(absolute), File.basename(absolute).sub(/\.rb$/, '') Dir.glob("#{dirname}/[0-9]*_*.rb").grep(/\d+_#{file_name}.rb$/).first end + + def capture(stream) + stream = stream.to_s + captured_stream = Tempfile.new(stream) + stream_io = eval("$#{stream}") + origin_stream = stream_io.dup + stream_io.reopen(captured_stream) + + yield + + stream_io.rewind + return captured_stream.read + ensure + captured_stream.close + captured_stream.unlink + stream_io.reopen(origin_stream) + end end end end diff --git a/railties/lib/rails/rack/logger.rb b/railties/lib/rails/rack/logger.rb index 3b35798679..9962e6d943 100644 --- a/railties/lib/rails/rack/logger.rb +++ b/railties/lib/rails/rack/logger.rb @@ -34,7 +34,7 @@ module Rails instrumenter = ActiveSupport::Notifications.instrumenter instrumenter.start 'request.action_dispatch', request: request - logger.info started_request_message(request) + logger.info { started_request_message(request) } resp = @app.call(env) resp[2] = ::Rack::BodyProxy.new(resp[2]) { finish(request) } resp diff --git a/railties/test/abstract_unit.rb b/railties/test/abstract_unit.rb index 9ccc286b4e..d8800eaa0f 100644 --- a/railties/test/abstract_unit.rb +++ b/railties/test/abstract_unit.rb @@ -26,3 +26,30 @@ end def jruby_skip(message = '') skip message if defined?(JRUBY_VERSION) end + +class ActiveSupport::TestCase + # FIXME: we have tests that depend on run order, we should fix that and + # remove this method call. + self.my_tests_are_order_dependent! + + private + + unless defined?(:capture) + def capture(stream) + stream = stream.to_s + captured_stream = Tempfile.new(stream) + stream_io = eval("$#{stream}") + origin_stream = stream_io.dup + stream_io.reopen(captured_stream) + + yield + + stream_io.rewind + return captured_stream.read + ensure + captured_stream.close + captured_stream.unlink + stream_io.reopen(origin_stream) + end + end +end diff --git a/railties/test/app_rails_loader_test.rb b/railties/test/app_rails_loader_test.rb index 1d3b80253a..d4885447e6 100644 --- a/railties/test/app_rails_loader_test.rb +++ b/railties/test/app_rails_loader_test.rb @@ -3,13 +3,27 @@ require 'abstract_unit' require 'rails/app_rails_loader' class AppRailsLoaderTest < ActiveSupport::TestCase + def loader + @loader ||= Class.new do + extend Rails::AppRailsLoader + + def self.exec_arguments + @exec_arguments + end + + def self.exec(*args) + @exec_arguments = args + end + end + end + def write(filename, contents=nil) FileUtils.mkdir_p(File.dirname(filename)) File.write(filename, contents) end def expects_exec(exe) - Rails::AppRailsLoader.expects(:exec).with(Rails::AppRailsLoader::RUBY, exe) + assert_equal [Rails::AppRailsLoader::RUBY, exe], loader.exec_arguments end setup do @@ -22,30 +36,30 @@ class AppRailsLoaderTest < ActiveSupport::TestCase exe = "#{script_dir}/rails" test "is not in a Rails application if #{exe} is not found in the current or parent directories" do - File.stubs(:file?).with('bin/rails').returns(false) - File.stubs(:file?).with('script/rails').returns(false) + def loader.find_executables; end - assert !Rails::AppRailsLoader.exec_app_rails + assert !loader.exec_app_rails end test "is not in a Rails application if #{exe} exists but is a folder" do FileUtils.mkdir_p(exe) - assert !Rails::AppRailsLoader.exec_app_rails + assert !loader.exec_app_rails end ['APP_PATH', 'ENGINE_PATH'].each do |keyword| test "is in a Rails application if #{exe} exists and contains #{keyword}" do write exe, keyword + loader.exec_app_rails + expects_exec exe - Rails::AppRailsLoader.exec_app_rails end test "is not in a Rails application if #{exe} exists but doesn't contain #{keyword}" do write exe - assert !Rails::AppRailsLoader.exec_app_rails + assert !loader.exec_app_rails end test "is in a Rails application if parent directory has #{exe} containing #{keyword} and chdirs to the root directory" do @@ -54,8 +68,9 @@ class AppRailsLoaderTest < ActiveSupport::TestCase Dir.chdir('foo/bar') + loader.exec_app_rails + expects_exec exe - Rails::AppRailsLoader.exec_app_rails # Compare the realpath in case either of them has symlinks. # diff --git a/railties/test/application/configuration/base_test.rb b/railties/test/application/configuration/base_test.rb new file mode 100644 index 0000000000..d6a82b139d --- /dev/null +++ b/railties/test/application/configuration/base_test.rb @@ -0,0 +1,37 @@ +require 'isolation/abstract_unit' +require 'rack/test' +require 'env_helpers' + +module ApplicationTests + module ConfigurationTests + class BaseTest < ActiveSupport::TestCase + def setup + build_app + boot_rails + FileUtils.rm_rf("#{app_path}/config/environments") + end + + def teardown + teardown_app + FileUtils.rm_rf(new_app) if File.directory?(new_app) + end + + private + def new_app + File.expand_path("#{app_path}/../new_app") + end + + def copy_app + FileUtils.cp_r(app_path, new_app) + end + + def app + @app ||= Rails.application + end + + def require_environment + require "#{app_path}/config/environment" + end + end + end +end
\ No newline at end of file diff --git a/railties/test/application/configuration/custom_test.rb b/railties/test/application/configuration/custom_test.rb new file mode 100644 index 0000000000..045537fc28 --- /dev/null +++ b/railties/test/application/configuration/custom_test.rb @@ -0,0 +1,15 @@ +require 'application/configuration/base_test' + +class ApplicationTests::ConfigurationTests::CustomTest < ApplicationTests::ConfigurationTests::BaseTest + test 'access custom configuration point' do + add_to_config <<-RUBY + config.x.resque.inline_jobs = :always + config.x.resque.timeout = 60 + RUBY + require_environment + + assert_equal :always, Rails.configuration.x.resque.inline_jobs + assert_equal 60, Rails.configuration.x.resque.timeout + assert_nil Rails.configuration.x.resque.nothing + end +end diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb index 2e056be561..e661b6f4cc 100644 --- a/railties/test/application/configuration_test.rb +++ b/railties/test/application/configuration_test.rb @@ -66,13 +66,25 @@ module ApplicationTests config.action_dispatch.show_exceptions = true RUBY + app_file 'db/migrate/20140708012246_create_user.rb', <<-RUBY + class CreateUser < ActiveRecord::Migration + def change + create_table :users + end + end + RUBY + require "#{app_path}/config/environment" - ActiveRecord::Migrator.stubs(:needs_migration?).returns(true) - ActiveRecord::NullMigration.any_instance.stubs(:mtime).returns(1) - get "/foo" - assert_equal 500, last_response.status - assert_match "ActiveRecord::PendingMigrationError", last_response.body + ActiveRecord::Migrator.migrations_paths = ["#{app_path}/db/migrate"] + + begin + get "/foo" + assert_equal 500, last_response.status + assert_match "ActiveRecord::PendingMigrationError", last_response.body + ensure + ActiveRecord::Migrator.migrations_paths = nil + end end test "Rails.groups returns available groups" do @@ -372,6 +384,8 @@ module ApplicationTests end RUBY + token = "cf50faa3fe97702ca1ae" + app_file 'app/controllers/posts_controller.rb', <<-RUBY class PostsController < ApplicationController def show @@ -381,6 +395,10 @@ module ApplicationTests def update render text: "update" end + + private + + def form_authenticity_token; token; end # stub the authenticy token end RUBY @@ -392,8 +410,6 @@ module ApplicationTests require "#{app_path}/config/environment" - token = "cf50faa3fe97702ca1ae" - PostsController.any_instance.stubs(:form_authenticity_token).returns(token) params = {authenticity_token: token} get "/posts/1" @@ -424,7 +440,7 @@ module ApplicationTests end get "/" - assert last_response.body =~ /_xsrf_token_here/ + assert_match "_xsrf_token_here", last_response.body end test "sets ActionDispatch.test_app" do @@ -875,79 +891,79 @@ module ApplicationTests end test "rake_tasks block works at instance level" do - $ran_block = false - app_file "config/environments/development.rb", <<-RUBY Rails.application.configure do + config.ran_block = false + rake_tasks do - $ran_block = true + config.ran_block = true end end RUBY require "#{app_path}/config/environment" + assert_not Rails.configuration.ran_block - assert !$ran_block require 'rake' require 'rake/testtask' require 'rdoc/task' Rails.application.load_tasks - assert $ran_block + assert Rails.configuration.ran_block end test "generators block works at instance level" do - $ran_block = false - app_file "config/environments/development.rb", <<-RUBY Rails.application.configure do + config.ran_block = false + generators do - $ran_block = true + config.ran_block = true end end RUBY require "#{app_path}/config/environment" + assert_not Rails.configuration.ran_block - assert !$ran_block Rails.application.load_generators - assert $ran_block + assert Rails.configuration.ran_block end test "console block works at instance level" do - $ran_block = false - app_file "config/environments/development.rb", <<-RUBY Rails.application.configure do + config.ran_block = false + console do - $ran_block = true + config.ran_block = true end end RUBY require "#{app_path}/config/environment" + assert_not Rails.configuration.ran_block - assert !$ran_block Rails.application.load_console - assert $ran_block + assert Rails.configuration.ran_block end test "runner block works at instance level" do - $ran_block = false - app_file "config/environments/development.rb", <<-RUBY Rails.application.configure do + config.ran_block = false + runner do - $ran_block = true + config.ran_block = true end end RUBY require "#{app_path}/config/environment" + assert_not Rails.configuration.ran_block - assert !$ran_block Rails.application.load_runner - assert $ran_block + assert Rails.configuration.ran_block end test "loading the first existing database configuration available" do @@ -961,9 +977,7 @@ module ApplicationTests require "#{app_path}/config/environment" - db_config = Rails.application.config.database_configuration - - assert db_config.is_a?(Hash) + assert_kind_of Hash, Rails.application.config.database_configuration end test 'config.action_mailer.show_previews defaults to true in development' do @@ -977,7 +991,7 @@ module ApplicationTests Rails.env = "production" require "#{app_path}/config/environment" - assert_equal Rails.application.config.action_mailer.show_previews, false + assert_equal false, Rails.application.config.action_mailer.show_previews end test 'config.action_mailer.show_previews can be set in the configuration file' do @@ -987,7 +1001,91 @@ module ApplicationTests RUBY require "#{app_path}/config/environment" - assert_equal Rails.application.config.action_mailer.show_previews, true + assert_equal true, Rails.application.config.action_mailer.show_previews + end + + test "config_for loads custom configuration from yaml files" do + app_file 'config/custom.yml', <<-RUBY + development: + key: 'custom key' + RUBY + + add_to_config <<-RUBY + config.my_custom_config = config_for('custom') + RUBY + + require "#{app_path}/config/environment" + + assert_equal 'custom key', Rails.application.config.my_custom_config['key'] + end + + test "config_for raises an exception if the file does not exist" do + add_to_config <<-RUBY + config.my_custom_config = config_for('custom') + RUBY + + exception = assert_raises(RuntimeError) do + require "#{app_path}/config/environment" + end + + assert_equal "Could not load configuration. No such file - #{app_path}/config/custom.yml", exception.message + end + + test "config_for without the environment configured returns an empty hash" do + app_file 'config/custom.yml', <<-RUBY + test: + key: 'custom key' + RUBY + + add_to_config <<-RUBY + config.my_custom_config = config_for('custom') + RUBY + require "#{app_path}/config/environment" + + assert_equal({}, Rails.application.config.my_custom_config) + end + + test "config_for with empty file returns an empty hash" do + app_file 'config/custom.yml', <<-RUBY + RUBY + + add_to_config <<-RUBY + config.my_custom_config = config_for('custom') + RUBY + require "#{app_path}/config/environment" + + assert_equal({}, Rails.application.config.my_custom_config) + end + + test "config_for containing ERB tags should evaluate" do + app_file 'config/custom.yml', <<-RUBY + development: + key: <%= 'custom key' %> + RUBY + + add_to_config <<-RUBY + config.my_custom_config = config_for('custom') + RUBY + require "#{app_path}/config/environment" + + assert_equal 'custom key', Rails.application.config.my_custom_config['key'] + end + + test "config_for with syntax error show a more descritive exception" do + app_file 'config/custom.yml', <<-RUBY + development: + key: foo: + RUBY + + add_to_config <<-RUBY + config.my_custom_config = config_for('custom') + RUBY + + exception = assert_raises(RuntimeError) do + require "#{app_path}/config/environment" + end + + assert_match 'YAML syntax error occurred while parsing', exception.message end end end diff --git a/railties/test/application/initializers/frameworks_test.rb b/railties/test/application/initializers/frameworks_test.rb index 8e76bf27f3..ae550331bd 100644 --- a/railties/test/application/initializers/frameworks_test.rb +++ b/railties/test/application/initializers/frameworks_test.rb @@ -50,7 +50,7 @@ module ApplicationTests assert_equal "test.rails", ActionMailer::Base.default_url_options[:host] end - test "does not include url helpers as action methods" do + test "includes url helpers as action methods" do app_file "config/routes.rb", <<-RUBY Rails.application.routes.draw do get "/foo", :to => lambda { |env| [200, {}, []] }, :as => :foo @@ -66,8 +66,8 @@ module ApplicationTests require "#{app_path}/config/environment" assert Foo.method_defined?(:foo_path) + assert Foo.method_defined?(:foo_url) assert Foo.method_defined?(:main_app) - assert_equal Set.new(["notify"]), Foo.action_methods end test "allows to not load all helpers for controllers" do diff --git a/railties/test/application/initializers/i18n_test.rb b/railties/test/application/initializers/i18n_test.rb index bc34897cdf..9ee54796a4 100644 --- a/railties/test/application/initializers/i18n_test.rb +++ b/railties/test/application/initializers/i18n_test.rb @@ -184,28 +184,13 @@ en: assert_fallbacks ca: [:ca, :"es-ES", :es, :'en-US', :en] end - test "config.i18n.enforce_available_locales is set to true by default and avoids I18n warnings" do - add_to_config <<-RUBY - config.i18n.default_locale = :it - RUBY - - output = capture(:stderr) { load_app } - assert_no_match %r{deprecated.*enforce_available_locales}, output - assert_equal true, I18n.enforce_available_locales - - assert_raise I18n::InvalidLocale do - I18n.locale = :es - end - end - test "disable config.i18n.enforce_available_locales" do add_to_config <<-RUBY config.i18n.enforce_available_locales = false config.i18n.default_locale = :fr RUBY - output = capture(:stderr) { load_app } - assert_no_match %r{deprecated.*enforce_available_locales}, output + load_app assert_equal false, I18n.enforce_available_locales assert_nothing_raised do @@ -220,8 +205,7 @@ en: config.i18n.default_locale = :fr RUBY - output = capture(:stderr) { load_app } - assert_no_match %r{deprecated.*enforce_available_locales}, output + load_app assert_equal false, I18n.enforce_available_locales assert_nothing_raised do diff --git a/railties/test/application/mailer_previews_test.rb b/railties/test/application/mailer_previews_test.rb index 8b91a1171f..55e917c3ec 100644 --- a/railties/test/application/mailer_previews_test.rb +++ b/railties/test/application/mailer_previews_test.rb @@ -417,6 +417,58 @@ module ApplicationTests assert_match '<option selected value="?part=text%2Fplain">View as plain-text email</option>', last_response.body end + test "*_path helpers emit a deprecation" do + + app_file "config/routes.rb", <<-RUBY + Rails.application.routes.draw do + get 'foo', to: 'foo#index' + end + RUBY + + mailer 'notifier', <<-RUBY + class Notifier < ActionMailer::Base + default from: "from@example.com" + + def path_in_view + mail to: "to@example.org" + end + + def path_in_mailer + @url = foo_path + mail to: "to@example.org" + end + end + RUBY + + html_template 'notifier/path_in_view', "<%= link_to 'foo', foo_path %>" + + mailer_preview 'notifier', <<-RUBY + class NotifierPreview < ActionMailer::Preview + def path_in_view + Notifier.path_in_view + end + + def path_in_mailer + Notifier.path_in_mailer + end + end + RUBY + + app('development') + + assert_deprecated do + get "/rails/mailers/notifier/path_in_view.html" + assert_equal 200, last_response.status + end + + html_template 'notifier/path_in_mailer', "No ERB in here" + + assert_deprecated do + get "/rails/mailers/notifier/path_in_mailer.html" + assert_equal 200, last_response.status + end + end + private def build_app super diff --git a/railties/test/application/middleware_test.rb b/railties/test/application/middleware_test.rb index 1557b90d27..33eb034b1c 100644 --- a/railties/test/application/middleware_test.rb +++ b/railties/test/application/middleware_test.rb @@ -188,7 +188,7 @@ module ApplicationTests end end - etag = "5af83e3196bf99f440f31f2e1a6c9afe".inspect + etag = "W/" + "5af83e3196bf99f440f31f2e1a6c9afe".inspect get "/" assert_equal 200, last_response.status diff --git a/railties/test/application/multiple_applications_test.rb b/railties/test/application/multiple_applications_test.rb index f8d8a673ae..9ebf163671 100644 --- a/railties/test/application/multiple_applications_test.rb +++ b/railties/test/application/multiple_applications_test.rb @@ -36,23 +36,23 @@ module ApplicationTests end def test_initialization_of_application_with_previous_config - application1 = AppTemplate::Application.new(config: Rails.application.config) - application2 = AppTemplate::Application.new + application1 = AppTemplate::Application.create(config: Rails.application.config) + application2 = AppTemplate::Application.create assert_equal Rails.application.config, application1.config, "Creating a new application while setting an initial config should result in the same config" assert_not_equal Rails.application.config, application2.config, "New applications without setting an initial config should not have the same config" end def test_initialization_of_application_with_previous_railties - application1 = AppTemplate::Application.new(railties: Rails.application.railties) - application2 = AppTemplate::Application.new + application1 = AppTemplate::Application.create(railties: Rails.application.railties) + application2 = AppTemplate::Application.create assert_equal Rails.application.railties, application1.railties assert_not_equal Rails.application.railties, application2.railties end def test_initialize_new_application_with_all_previous_initialization_variables - application1 = AppTemplate::Application.new( + application1 = AppTemplate::Application.create( config: Rails.application.config, railties: Rails.application.railties, routes_reloader: Rails.application.routes_reloader, @@ -72,26 +72,26 @@ module ApplicationTests end def test_rake_tasks_defined_on_different_applications_go_to_the_same_class - $run_count = 0 + run_count = 0 application1 = AppTemplate::Application.new application1.rake_tasks do - $run_count += 1 + run_count += 1 end application2 = AppTemplate::Application.new application2.rake_tasks do - $run_count += 1 + run_count += 1 end require "#{app_path}/config/environment" - assert_equal 0, $run_count, "The count should stay at zero without any calls to the rake tasks" + assert_equal 0, run_count, "The count should stay at zero without any calls to the rake tasks" require 'rake' require 'rake/testtask' require 'rdoc/task' Rails.application.load_tasks - assert_equal 2, $run_count, "Calling a rake task should result in two increments to the count" + assert_equal 2, run_count, "Calling a rake task should result in two increments to the count" end def test_multiple_applications_can_be_initialized @@ -100,56 +100,56 @@ module ApplicationTests def test_initializers_run_on_different_applications_go_to_the_same_class application1 = AppTemplate::Application.new - $run_count = 0 + run_count = 0 AppTemplate::Application.initializer :init0 do - $run_count += 1 + run_count += 1 end application1.initializer :init1 do - $run_count += 1 + run_count += 1 end AppTemplate::Application.new.initializer :init2 do - $run_count += 1 + run_count += 1 end - assert_equal 0, $run_count, "Without loading the initializers, the count should be 0" + assert_equal 0, run_count, "Without loading the initializers, the count should be 0" # Set config.eager_load to false so that an eager_load warning doesn't pop up AppTemplate::Application.new { config.eager_load = false }.initialize! - assert_equal 3, $run_count, "There should have been three initializers that incremented the count" + assert_equal 3, run_count, "There should have been three initializers that incremented the count" end def test_consoles_run_on_different_applications_go_to_the_same_class - $run_count = 0 - AppTemplate::Application.console { $run_count += 1 } - AppTemplate::Application.new.console { $run_count += 1 } + run_count = 0 + AppTemplate::Application.console { run_count += 1 } + AppTemplate::Application.new.console { run_count += 1 } - assert_equal 0, $run_count, "Without loading the consoles, the count should be 0" + assert_equal 0, run_count, "Without loading the consoles, the count should be 0" Rails.application.load_console - assert_equal 2, $run_count, "There should have been two consoles that increment the count" + assert_equal 2, run_count, "There should have been two consoles that increment the count" end def test_generators_run_on_different_applications_go_to_the_same_class - $run_count = 0 - AppTemplate::Application.generators { $run_count += 1 } - AppTemplate::Application.new.generators { $run_count += 1 } + run_count = 0 + AppTemplate::Application.generators { run_count += 1 } + AppTemplate::Application.new.generators { run_count += 1 } - assert_equal 0, $run_count, "Without loading the generators, the count should be 0" + assert_equal 0, run_count, "Without loading the generators, the count should be 0" Rails.application.load_generators - assert_equal 2, $run_count, "There should have been two generators that increment the count" + assert_equal 2, run_count, "There should have been two generators that increment the count" end def test_runners_run_on_different_applications_go_to_the_same_class - $run_count = 0 - AppTemplate::Application.runner { $run_count += 1 } - AppTemplate::Application.new.runner { $run_count += 1 } + run_count = 0 + AppTemplate::Application.runner { run_count += 1 } + AppTemplate::Application.new.runner { run_count += 1 } - assert_equal 0, $run_count, "Without loading the runners, the count should be 0" + assert_equal 0, run_count, "Without loading the runners, the count should be 0" Rails.application.load_runner - assert_equal 2, $run_count, "There should have been two runners that increment the count" + assert_equal 2, run_count, "There should have been two runners that increment the count" end def test_isolate_namespace_on_an_application diff --git a/railties/test/application/rack/logger_test.rb b/railties/test/application/rack/logger_test.rb index 701843a6fd..0082ec9cd2 100644 --- a/railties/test/application/rack/logger_test.rb +++ b/railties/test/application/rack/logger_test.rb @@ -11,10 +11,12 @@ module ApplicationTests def setup build_app + add_to_config <<-RUBY + config.logger = ActiveSupport::LogSubscriber::TestHelper::MockLogger.new + RUBY + require "#{app_path}/config/environment" super - @logger = MockLogger.new - Rails.stubs(:logger).returns(@logger) end def teardown @@ -23,7 +25,7 @@ module ApplicationTests end def logs - @logs ||= @logger.logged(:info).join("\n") + @logs ||= Rails.logger.logged(:info).join("\n") end test "logger logs proper HTTP GET verb and path" do diff --git a/railties/test/application/test_test.rb b/railties/test/application/test_test.rb index a223180169..c724c867ec 100644 --- a/railties/test/application/test_test.rb +++ b/railties/test/application/test_test.rb @@ -67,7 +67,7 @@ module ApplicationTests assert_match %r{/app/test/unit/failing_test\.rb}, output end - test "migrations" do + test "ruby schema migrations" do output = script('generate model user name:string') version = output.match(/(\d+)_create_users\.rb/)[1] @@ -104,6 +104,95 @@ module ApplicationTests assert !result.include?("create_table(:users)") end + test "sql structure migrations" do + output = script('generate model user name:string') + version = output.match(/(\d+)_create_users\.rb/)[1] + + app_file 'test/models/user_test.rb', <<-RUBY + require 'test_helper' + + class UserTest < ActiveSupport::TestCase + test "user" do + User.create! name: "Jon" + end + end + RUBY + + app_file 'db/structure.sql', '' + app_file 'config/initializers/enable_sql_schema_format.rb', <<-RUBY + Rails.application.config.active_record.schema_format = :sql + RUBY + + assert_unsuccessful_run "models/user_test.rb", "Migrations are pending" + + app_file 'db/structure.sql', <<-SQL + CREATE TABLE "schema_migrations" ("version" varchar(255) NOT NULL); + CREATE UNIQUE INDEX "unique_schema_migrations" ON "schema_migrations" ("version"); + CREATE TABLE "users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255)); + INSERT INTO schema_migrations (version) VALUES ('#{version}'); + SQL + + app_file 'config/initializers/disable_maintain_test_schema.rb', <<-RUBY + Rails.application.config.active_record.maintain_test_schema = false + RUBY + + assert_unsuccessful_run "models/user_test.rb", "Could not find table 'users'" + + File.delete "#{app_path}/config/initializers/disable_maintain_test_schema.rb" + + assert_successful_test_run('models/user_test.rb') + end + + test "sql structure migrations when adding column to existing table" do + output_1 = script('generate model user name:string') + version_1 = output_1.match(/(\d+)_create_users\.rb/)[1] + + app_file 'test/models/user_test.rb', <<-RUBY + require 'test_helper' + class UserTest < ActiveSupport::TestCase + test "user" do + User.create! name: "Jon" + end + end + RUBY + + app_file 'config/initializers/enable_sql_schema_format.rb', <<-RUBY + Rails.application.config.active_record.schema_format = :sql + RUBY + + app_file 'db/structure.sql', <<-SQL + CREATE TABLE "schema_migrations" ("version" varchar(255) NOT NULL); + CREATE UNIQUE INDEX "unique_schema_migrations" ON "schema_migrations" ("version"); + CREATE TABLE "users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255)); + INSERT INTO schema_migrations (version) VALUES ('#{version_1}'); + SQL + + assert_successful_test_run('models/user_test.rb') + + output_2 = script('generate migration add_email_to_users') + version_2 = output_2.match(/(\d+)_add_email_to_users\.rb/)[1] + + app_file 'test/models/user_test.rb', <<-RUBY + require 'test_helper' + + class UserTest < ActiveSupport::TestCase + test "user" do + User.create! name: "Jon", email: "jon@doe.com" + end + end + RUBY + + app_file 'db/structure.sql', <<-SQL + CREATE TABLE "schema_migrations" ("version" varchar(255) NOT NULL); + CREATE UNIQUE INDEX "unique_schema_migrations" ON "schema_migrations" ("version"); + CREATE TABLE "users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255), "email" varchar(255)); + INSERT INTO schema_migrations (version) VALUES ('#{version_1}'); + INSERT INTO schema_migrations (version) VALUES ('#{version_2}'); + SQL + + assert_successful_test_run('models/user_test.rb') + end + private def assert_unsuccessful_run(name, message) result = run_test_file(name) diff --git a/railties/test/commands/console_test.rb b/railties/test/commands/console_test.rb index 1273f9d4c2..4aea3e980f 100644 --- a/railties/test/commands/console_test.rb +++ b/railties/test/commands/console_test.rb @@ -6,7 +6,13 @@ class Rails::ConsoleTest < ActiveSupport::TestCase include EnvHelpers class FakeConsole - def self.start; end + def self.started? + @started + end + + def self.start + @started = true + end end def test_sandbox_option @@ -25,17 +31,18 @@ class Rails::ConsoleTest < ActiveSupport::TestCase end def test_start - FakeConsole.expects(:start) start + + assert app.console.started? assert_match(/Loading \w+ environment \(Rails/, output) end def test_start_with_sandbox - app.expects(:sandbox=).with(true) - FakeConsole.expects(:start) - start ["--sandbox"] + + assert app.console.started? + assert app.sandbox assert_match(/Loading \w+ environment in sandbox \(Rails/, output) end @@ -51,9 +58,12 @@ class Rails::ConsoleTest < ActiveSupport::TestCase end def test_start_with_debugger - rails_console = Rails::Console.new(app, parse_arguments(["--debugger"])) - rails_console.expects(:require_debugger).returns(nil) + stubbed_console = Class.new(Rails::Console) do + def require_debugger + end + end + rails_console = stubbed_console.new(app, parse_arguments(["--debugger"])) silence_stream(STDOUT) { rails_console.start } end end @@ -64,7 +74,7 @@ class Rails::ConsoleTest < ActiveSupport::TestCase end def test_console_defaults_to_IRB - app = build_app(console: nil) + app = build_app(nil) assert_equal IRB, Rails::Console.new(app).console end @@ -115,8 +125,12 @@ class Rails::ConsoleTest < ActiveSupport::TestCase end def test_rails_env_is_dev_when_argument_is_dev_and_dev_env_is_present - Rails::Console.stubs(:available_environments).returns(['dev']) - options = Rails::Console.parse_arguments(['dev']) + stubbed_console = Class.new(Rails::Console) do + def available_environments + ['dev'] + end + end + options = stubbed_console.parse_arguments(['dev']) assert_match('dev', options[:environment]) end @@ -131,15 +145,29 @@ class Rails::ConsoleTest < ActiveSupport::TestCase end def app - @app ||= build_app(console: FakeConsole) + @app ||= build_app(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 + def build_app(console) + mocked_console = Class.new do + attr_reader :sandbox, :console + + def initialize(console) + @console = console + end + + def config + self + end + + def sandbox=(arg) + @sandbox = arg + end + + def load_console + end + end + mocked_console.new(console) end def parse_arguments(args) diff --git a/railties/test/commands/dbconsole_test.rb b/railties/test/commands/dbconsole_test.rb index 24db395e6e..ede08e7b86 100644 --- a/railties/test/commands/dbconsole_test.rb +++ b/railties/test/commands/dbconsole_test.rb @@ -1,4 +1,5 @@ require 'abstract_unit' +require 'minitest/mock' require 'rails/commands/dbconsole' class Rails::DBConsoleTest < ActiveSupport::TestCase @@ -26,20 +27,21 @@ class Rails::DBConsoleTest < ActiveSupport::TestCase "timeout"=> "3000" } } - app_db_config(config_sample) - assert_equal Rails::DBConsole.new.config, config_sample["test"] + app_db_config(config_sample) do + assert_equal Rails::DBConsole.new.config, config_sample["test"] + end end def test_config_with_no_db_config - app_db_config(nil) - assert_raise(ActiveRecord::AdapterNotSpecified) { - Rails::DBConsole.new.config - } + app_db_config(nil) do + assert_raise(ActiveRecord::AdapterNotSpecified) { + Rails::DBConsole.new.config + } + end end def test_config_with_database_url_only ENV['DATABASE_URL'] = 'postgresql://foo:bar@localhost:9000/foo_test?pool=5&timeout=3000' - app_db_config(nil) expected = { "adapter" => "postgresql", "host" => "localhost", @@ -50,7 +52,10 @@ class Rails::DBConsoleTest < ActiveSupport::TestCase "pool" => "5", "timeout" => "3000" }.sort - assert_equal expected, Rails::DBConsole.new.config.sort + + app_db_config(nil) do + assert_equal expected, Rails::DBConsole.new.config.sort + end end def test_config_choose_database_url_if_exists @@ -68,8 +73,9 @@ class Rails::DBConsoleTest < ActiveSupport::TestCase "timeout" => "3000" } } - app_db_config(sample_config) - assert_equal host, Rails::DBConsole.new.config["host"] + app_db_config(sample_config) do + assert_equal host, Rails::DBConsole.new.config["host"] + end end def test_env @@ -78,58 +84,65 @@ class Rails::DBConsoleTest < ActiveSupport::TestCase ENV['RAILS_ENV'] = nil ENV['RACK_ENV'] = nil - Rails.stubs(:respond_to?).with(:env).returns(false) - assert_equal Rails::DBConsole.new.environment, "development" + Rails.stub(:respond_to?, false) do + assert_equal Rails::DBConsole.new.environment, "development" - ENV['RACK_ENV'] = "rack_env" - assert_equal Rails::DBConsole.new.environment, "rack_env" + ENV['RACK_ENV'] = "rack_env" + assert_equal Rails::DBConsole.new.environment, "rack_env" - ENV['RAILS_ENV'] = "rails_env" - assert_equal Rails::DBConsole.new.environment, "rails_env" + ENV['RAILS_ENV'] = "rails_env" + assert_equal Rails::DBConsole.new.environment, "rails_env" + end ensure ENV['RAILS_ENV'] = "test" end def test_rails_env_is_development_when_argument_is_dev - Rails::DBConsole.stubs(:available_environments).returns(['development', 'test']) - options = Rails::DBConsole.new.send(:parse_arguments, ['dev']) - assert_match('development', options[:environment]) + dbconsole = Rails::DBConsole.new + + dbconsole.stub(:available_environments, ['development', 'test']) do + options = dbconsole.send(:parse_arguments, ['dev']) + assert_match('development', options[:environment]) + end end def test_rails_env_is_dev_when_argument_is_dev_and_dev_env_is_present - Rails::DBConsole.stubs(:available_environments).returns(['dev']) - options = Rails::DBConsole.new.send(:parse_arguments, ['dev']) - assert_match('dev', options[:environment]) + dbconsole = Rails::DBConsole.new + + dbconsole.stub(:available_environments, ['dev']) do + options = dbconsole.send(:parse_arguments, ['dev']) + assert_match('dev', options[:environment]) + end end def test_mysql - dbconsole.expects(:find_cmd_and_exec).with(%w[mysql mysql5], 'db') start(adapter: 'mysql', database: 'db') assert !aborted + assert_equal [%w[mysql mysql5], 'db'], dbconsole.find_cmd_and_exec_args end def test_mysql_full - dbconsole.expects(:find_cmd_and_exec).with(%w[mysql mysql5], '--host=locahost', '--port=1234', '--socket=socket', '--user=user', '--default-character-set=UTF-8', '-p', 'db') start(adapter: 'mysql', database: 'db', host: 'locahost', port: 1234, socket: 'socket', username: 'user', password: 'qwerty', encoding: 'UTF-8') assert !aborted + assert_equal [%w[mysql mysql5], '--host=locahost', '--port=1234', '--socket=socket', '--user=user', '--default-character-set=UTF-8', '-p', 'db'], dbconsole.find_cmd_and_exec_args end def test_mysql_include_password - dbconsole.expects(:find_cmd_and_exec).with(%w[mysql mysql5], '--user=user', '--password=qwerty', 'db') start({adapter: 'mysql', database: 'db', username: 'user', password: 'qwerty'}, ['-p']) assert !aborted + assert_equal [%w[mysql mysql5], '--user=user', '--password=qwerty', 'db'], dbconsole.find_cmd_and_exec_args end def test_postgresql - dbconsole.expects(:find_cmd_and_exec).with('psql', 'db') start(adapter: 'postgresql', database: 'db') assert !aborted + assert_equal ['psql', 'db'], dbconsole.find_cmd_and_exec_args end def test_postgresql_full - dbconsole.expects(:find_cmd_and_exec).with('psql', 'db') start(adapter: 'postgresql', database: 'db', username: 'user', password: 'q1w2e3', host: 'host', port: 5432) assert !aborted + assert_equal ['psql', 'db'], dbconsole.find_cmd_and_exec_args assert_equal 'user', ENV['PGUSER'] assert_equal 'host', ENV['PGHOST'] assert_equal '5432', ENV['PGPORT'] @@ -137,60 +150,60 @@ class Rails::DBConsoleTest < ActiveSupport::TestCase end def test_postgresql_include_password - dbconsole.expects(:find_cmd_and_exec).with('psql', 'db') start({adapter: 'postgresql', database: 'db', username: 'user', password: 'q1w2e3'}, ['-p']) assert !aborted + assert_equal ['psql', 'db'], dbconsole.find_cmd_and_exec_args assert_equal 'user', ENV['PGUSER'] assert_equal 'q1w2e3', ENV['PGPASSWORD'] end def test_sqlite - dbconsole.expects(:find_cmd_and_exec).with('sqlite', 'db') start(adapter: 'sqlite', database: 'db') assert !aborted + assert_equal ['sqlite', 'db'], dbconsole.find_cmd_and_exec_args end def test_sqlite3 - dbconsole.expects(:find_cmd_and_exec).with('sqlite3', Rails.root.join('db.sqlite3').to_s) start(adapter: 'sqlite3', database: 'db.sqlite3') assert !aborted + assert_equal ['sqlite3', Rails.root.join('db.sqlite3').to_s], dbconsole.find_cmd_and_exec_args end def test_sqlite3_mode - dbconsole.expects(:find_cmd_and_exec).with('sqlite3', '-html', Rails.root.join('db.sqlite3').to_s) start({adapter: 'sqlite3', database: 'db.sqlite3'}, ['--mode', 'html']) assert !aborted + assert_equal ['sqlite3', '-html', Rails.root.join('db.sqlite3').to_s], dbconsole.find_cmd_and_exec_args end def test_sqlite3_header - dbconsole.expects(:find_cmd_and_exec).with('sqlite3', '-header', Rails.root.join('db.sqlite3').to_s) start({adapter: 'sqlite3', database: 'db.sqlite3'}, ['--header']) + assert_equal ['sqlite3', '-header', Rails.root.join('db.sqlite3').to_s], dbconsole.find_cmd_and_exec_args end def test_sqlite3_db_absolute_path - dbconsole.expects(:find_cmd_and_exec).with('sqlite3', '/tmp/db.sqlite3') start(adapter: 'sqlite3', database: '/tmp/db.sqlite3') assert !aborted + assert_equal ['sqlite3', '/tmp/db.sqlite3'], dbconsole.find_cmd_and_exec_args end def test_sqlite3_db_without_defined_rails_root - Rails.stubs(:respond_to?) - Rails.expects(:respond_to?).with(:root).once.returns(false) - dbconsole.expects(:find_cmd_and_exec).with('sqlite3', Rails.root.join('../config/db.sqlite3').to_s) - start(adapter: 'sqlite3', database: 'config/db.sqlite3') - assert !aborted + Rails.stub(:respond_to?, false) do + start(adapter: 'sqlite3', database: 'config/db.sqlite3') + assert !aborted + assert_equal ['sqlite3', Rails.root.join('../config/db.sqlite3').to_s], dbconsole.find_cmd_and_exec_args + end end def test_oracle - dbconsole.expects(:find_cmd_and_exec).with('sqlplus', 'user@db') start(adapter: 'oracle', database: 'db', username: 'user', password: 'secret') assert !aborted + assert_equal ['sqlplus', 'user@db'], dbconsole.find_cmd_and_exec_args end def test_oracle_include_password - dbconsole.expects(:find_cmd_and_exec).with('sqlplus', 'user/secret@db') start({adapter: 'oracle', database: 'db', username: 'user', password: 'secret'}, ['-p']) assert !aborted + assert_equal ['sqlplus', 'user/secret@db'], dbconsole.find_cmd_and_exec_args end def test_unknown_command_line_client @@ -223,16 +236,27 @@ class Rails::DBConsoleTest < ActiveSupport::TestCase private def app_db_config(results) - Rails.application.config.stubs(:database_configuration).returns(results || {}) + Rails.application.config.stub(:database_configuration, results || {}) do + yield + end end def dbconsole - @dbconsole ||= Rails::DBConsole.new(nil) + @dbconsole ||= Class.new(Rails::DBConsole) do + attr_reader :find_cmd_and_exec_args + + def find_cmd_and_exec(*args) + @find_cmd_and_exec_args = args + end + end.new(nil) end def start(config = {}, argv = []) - dbconsole.stubs(config: config.stringify_keys, arguments: argv) - capture_abort { dbconsole.start } + dbconsole.stub(:config, config.stringify_keys) do + dbconsole.stub(:arguments, argv) do + capture_abort { dbconsole.start } + end + end end def capture_abort diff --git a/railties/test/engine_test.rb b/railties/test/engine_test.rb index 7970913d21..f46fb748f5 100644 --- a/railties/test/engine_test.rb +++ b/railties/test/engine_test.rb @@ -11,4 +11,15 @@ class EngineTest < ActiveSupport::TestCase assert !engine.routes? end + + def test_application_can_be_subclassed + klass = Class.new(Rails::Application) do + attr_reader :hello + def initialize + @hello = "world" + super + end + end + assert_equal "world", klass.instance.hello + end end diff --git a/railties/test/generators/actions_test.rb b/railties/test/generators/actions_test.rb index 6d6de0fb52..a4337926d1 100644 --- a/railties/test/generators/actions_test.rb +++ b/railties/test/generators/actions_test.rb @@ -1,6 +1,7 @@ require 'generators/generators_test_helper' require 'rails/generators/rails/app/app_generator' require 'env_helpers' +require 'mocha/setup' # FIXME: stop using mocha class ActionsTest < Rails::Generators::TestCase include GeneratorsTestHelper @@ -242,7 +243,7 @@ class ActionsTest < Rails::Generators::TestCase protected def action(*args, &block) - silence(:stdout){ generator.send(*args, &block) } + capture(:stdout){ generator.send(*args, &block) } end end diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb index 2ac5410960..70c439672f 100644 --- a/railties/test/generators/app_generator_test.rb +++ b/railties/test/generators/app_generator_test.rb @@ -1,6 +1,7 @@ require 'generators/generators_test_helper' require 'rails/generators/rails/app/app_generator' require 'generators/shared_generator_tests' +require 'mocha/setup' # FIXME: stop using mocha DEFAULT_APP_FILES = %w( .gitignore @@ -193,20 +194,20 @@ class AppGeneratorTest < Rails::Generators::TestCase def test_config_database_is_added_by_default run_generator assert_file "config/database.yml", /sqlite3/ - unless defined?(JRUBY_VERSION) - assert_gem "sqlite3" - else + if defined?(JRUBY_VERSION) assert_gem "activerecord-jdbcsqlite3-adapter" + else + assert_gem "sqlite3" end end def test_config_another_database run_generator([destination_root, "-d", "mysql"]) assert_file "config/database.yml", /mysql/ - unless defined?(JRUBY_VERSION) - assert_gem "mysql2" - else + if defined?(JRUBY_VERSION) assert_gem "activerecord-jdbcmysql-adapter" + else + assert_gem "mysql2" end end @@ -218,10 +219,10 @@ class AppGeneratorTest < Rails::Generators::TestCase def test_config_postgresql_database run_generator([destination_root, "-d", "postgresql"]) assert_file "config/database.yml", /postgresql/ - unless defined?(JRUBY_VERSION) - assert_gem "pg" - else + if defined?(JRUBY_VERSION) assert_gem "activerecord-jdbcpostgresql-adapter" + else + assert_gem "pg" end end @@ -250,9 +251,9 @@ class AppGeneratorTest < Rails::Generators::TestCase assert_gem "activerecord-jdbc-adapter" end - def test_config_jdbc_database_when_no_option_given - if defined?(JRUBY_VERSION) - run_generator([destination_root]) + if defined?(JRUBY_VERSION) + def test_config_jdbc_database_when_no_option_given + run_generator assert_file "config/database.yml", /sqlite3/ assert_gem "activerecord-jdbcsqlite3-adapter" end @@ -294,11 +295,11 @@ class AppGeneratorTest < Rails::Generators::TestCase end def test_inclusion_of_javascript_runtime - run_generator([destination_root]) + run_generator if defined?(JRUBY_VERSION) assert_gem "therubyrhino" else - assert_file "Gemfile", /# gem\s+["']therubyracer["']+, \s+platforms: :ruby$/ + assert_file "Gemfile", /# gem 'therubyracer', platforms: :ruby/ end end @@ -339,7 +340,7 @@ class AppGeneratorTest < Rails::Generators::TestCase def test_inclusion_of_jbuilder run_generator - assert_file "Gemfile", /gem 'jbuilder'/ + assert_gem 'jbuilder' end def test_inclusion_of_a_debugger @@ -350,9 +351,9 @@ class AppGeneratorTest < Rails::Generators::TestCase assert_no_match(/debugger/, content) end elsif RUBY_VERSION < '2.0.0' - assert_file "Gemfile", /# gem 'debugger'/ + assert_gem 'debugger' else - assert_file "Gemfile", /# gem 'byebug'/ + assert_gem 'byebug' end end @@ -397,7 +398,7 @@ class AppGeneratorTest < Rails::Generators::TestCase end def test_new_hash_style - run_generator [destination_root] + run_generator assert_file "config/initializers/session_store.rb" do |file| assert_match(/config.session_store :cookie_store, key: '_.+_session'/, file) end @@ -418,9 +419,14 @@ class AppGeneratorTest < Rails::Generators::TestCase assert_file "foo bar/config/initializers/session_store.rb", /key: '_foo_bar/ end + def test_web_console + run_generator + assert_gem 'web-console' + end + def test_spring run_generator - assert_file "Gemfile", /gem 'spring', \s+group: :development/ + assert_gem 'spring' end def test_spring_binstubs @@ -487,13 +493,41 @@ class AppGeneratorTest < Rails::Generators::TestCase end end + def test_psych_gem + run_generator + gem_regex = /gem 'psych',\s+'~> 2.0', \s+platforms: :rbx/ + + assert_file "Gemfile" do |content| + if defined?(Rubinius) + assert_match(gem_regex, content) + else + assert_no_match(gem_regex, content) + end + end + end + + def test_after_bundle_callback + path = 'http://example.org/rails_template' + template = %{ after_bundle { run 'echo ran after_bundle' } } + template.instance_eval "def read; self; end" # Make the string respond to read + + generator([destination_root], template: path).expects(:open).with(path, 'Accept' => 'application/x-thor-template').returns(template) + + bundler_first = sequence('bundle, binstubs, after_bundle') + generator.expects(:bundle_command).with('install').once.in_sequence(bundler_first) + generator.expects(:bundle_command).with('exec spring binstub --all').in_sequence(bundler_first) + generator.expects(:run).with('echo ran after_bundle').in_sequence(bundler_first) + + quietly { generator.invoke_all } + end + protected def action(*args, &block) - silence(:stdout) { generator.send(*args, &block) } + capture(:stdout) { generator.send(*args, &block) } end def assert_gem(gem) - assert_file "Gemfile", /^gem\s+["']#{gem}["']$/ + assert_file "Gemfile", /^\s*gem\s+["']#{gem}["']$*/ end end diff --git a/railties/test/generators/argv_scrubber_test.rb b/railties/test/generators/argv_scrubber_test.rb index 31c2d846e2..31e07bc8da 100644 --- a/railties/test/generators/argv_scrubber_test.rb +++ b/railties/test/generators/argv_scrubber_test.rb @@ -1,5 +1,5 @@ -require 'active_support/testing/autorun' require 'active_support/test_case' +require 'active_support/testing/autorun' require 'rails/generators/rails/app/app_generator' require 'tempfile' diff --git a/railties/test/generators/controller_generator_test.rb b/railties/test/generators/controller_generator_test.rb index 28b527cb0e..a7d56dd352 100644 --- a/railties/test/generators/controller_generator_test.rb +++ b/railties/test/generators/controller_generator_test.rb @@ -28,13 +28,11 @@ class ControllerGeneratorTest < Rails::Generators::TestCase def test_invokes_helper run_generator assert_file "app/helpers/account_helper.rb" - assert_file "test/helpers/account_helper_test.rb" end def test_does_not_invoke_helper_if_required run_generator ["account", "--skip-helper"] assert_no_file "app/helpers/account_helper.rb" - assert_no_file "test/helpers/account_helper_test.rb" end def test_invokes_assets diff --git a/railties/test/generators/generator_test.rb b/railties/test/generators/generator_test.rb index b136239795..7871399dd7 100644 --- a/railties/test/generators/generator_test.rb +++ b/railties/test/generators/generator_test.rb @@ -1,5 +1,5 @@ -require 'active_support/testing/autorun' require 'active_support/test_case' +require 'active_support/testing/autorun' require 'rails/generators/app_base' module Rails diff --git a/railties/test/generators/generators_test_helper.rb b/railties/test/generators/generators_test_helper.rb index 77ec2f1c0c..e7990de754 100644 --- a/railties/test/generators/generators_test_helper.rb +++ b/railties/test/generators/generators_test_helper.rb @@ -7,7 +7,7 @@ module Rails class << self remove_possible_method :root def root - @root ||= File.expand_path(File.join(File.dirname(__FILE__), '..', 'fixtures')) + @root ||= File.expand_path('../../fixtures', __FILE__) end end end @@ -41,4 +41,12 @@ module GeneratorsTestHelper FileUtils.mkdir_p(destination) FileUtils.cp routes, destination end + + def quietly + silence_stream(STDOUT) do + silence_stream(STDERR) do + yield + end + end + end end diff --git a/railties/test/generators/helper_generator_test.rb b/railties/test/generators/helper_generator_test.rb index 81d4fcb129..add04f21a4 100644 --- a/railties/test/generators/helper_generator_test.rb +++ b/railties/test/generators/helper_generator_test.rb @@ -13,26 +13,11 @@ class HelperGeneratorTest < Rails::Generators::TestCase assert_file "app/helpers/admin_helper.rb", /module AdminHelper/ end - def test_invokes_default_test_framework - run_generator - assert_file "test/helpers/admin_helper_test.rb", /class AdminHelperTest < ActionView::TestCase/ - end - - def test_logs_if_the_test_framework_cannot_be_found - content = run_generator ["admin", "--test-framework=rspec"] - assert_match(/rspec \[not found\]/, content) - end - def test_check_class_collision content = capture(:stderr){ run_generator ["object"] } assert_match(/The name 'ObjectHelper' is either already used in your application or reserved/, content) end - def test_check_class_collision_on_tests - content = capture(:stderr){ run_generator ["another_object"] } - assert_match(/The name 'AnotherObjectHelperTest' is either already used in your application or reserved/, content) - end - def test_namespaced_and_not_namespaced_helpers run_generator ["products"] diff --git a/railties/test/generators/named_base_test.rb b/railties/test/generators/named_base_test.rb index ac5cfff229..4199e00b0d 100644 --- a/railties/test/generators/named_base_test.rb +++ b/railties/test/generators/named_base_test.rb @@ -1,5 +1,6 @@ require 'generators/generators_test_helper' require 'rails/generators/rails/scaffold_controller/scaffold_controller_generator' +require 'mocha/setup' # FIXME: stop using mocha # Mock out what we need from AR::Base. module ActiveRecord diff --git a/railties/test/generators/namespaced_generators_test.rb b/railties/test/generators/namespaced_generators_test.rb index d677c21f15..7eeb084eab 100644 --- a/railties/test/generators/namespaced_generators_test.rb +++ b/railties/test/generators/namespaced_generators_test.rb @@ -47,7 +47,6 @@ class NamespacedControllerGeneratorTest < NamespacedGeneratorTestCase def test_helper_is_also_namespaced run_generator assert_file "app/helpers/test_app/account_helper.rb", /module TestApp/, / module AccountHelper/ - assert_file "test/helpers/test_app/account_helper_test.rb", /module TestApp/, / class AccountHelperTest/ end def test_invokes_default_test_framework @@ -229,7 +228,6 @@ class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase # Helpers assert_file "app/helpers/test_app/product_lines_helper.rb" - assert_file "test/helpers/test_app/product_lines_helper_test.rb" # Stylesheets assert_file "app/assets/stylesheets/scaffold.css" @@ -260,7 +258,6 @@ class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase # Helpers assert_no_file "app/helpers/test_app/product_lines_helper.rb" - assert_no_file "test/helpers/test_app/product_lines_helper_test.rb" # Stylesheets (should not be removed) assert_file "app/assets/stylesheets/scaffold.css" @@ -297,7 +294,6 @@ class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase # Helpers assert_file "app/helpers/test_app/admin/roles_helper.rb" - assert_file "test/helpers/test_app/admin/roles_helper_test.rb" # Stylesheets assert_file "app/assets/stylesheets/scaffold.css" @@ -329,7 +325,6 @@ class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase # Helpers assert_no_file "app/helpers/test_app/admin/roles_helper.rb" - assert_no_file "test/helpers/test_app/admin/roles_helper_test.rb" # Stylesheets (should not be removed) assert_file "app/assets/stylesheets/scaffold.css" @@ -366,7 +361,6 @@ class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase # Helpers assert_file "app/helpers/test_app/admin/user/special/roles_helper.rb" - assert_file "test/helpers/test_app/admin/user/special/roles_helper_test.rb" # Stylesheets assert_file "app/assets/stylesheets/scaffold.css" @@ -397,7 +391,6 @@ class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase # Helpers assert_no_file "app/helpers/test_app/admin/user/special/roles_helper.rb" - assert_no_file "test/helpers/test_app/admin/user/special/roles_helper_test.rb" # Stylesheets (should not be removed) assert_file "app/assets/stylesheets/scaffold.css" diff --git a/railties/test/generators/plugin_generator_test.rb b/railties/test/generators/plugin_generator_test.rb index 7180efee41..985644e8af 100644 --- a/railties/test/generators/plugin_generator_test.rb +++ b/railties/test/generators/plugin_generator_test.rb @@ -1,6 +1,7 @@ require 'generators/generators_test_helper' require 'rails/generators/rails/plugin/plugin_generator' require 'generators/shared_generator_tests' +require 'mocha/setup' # FIXME: stop using mocha DEFAULT_PLUGIN_FILES = %w( .gitignore @@ -94,7 +95,7 @@ class PluginGeneratorTest < Rails::Generators::TestCase end def test_generating_adds_dummy_app_without_javascript_and_assets_deps - run_generator [destination_root] + run_generator assert_file "test/dummy/app/assets/stylesheets/application.css" @@ -334,7 +335,7 @@ class PluginGeneratorTest < Rails::Generators::TestCase Object.const_set('APP_PATH', Rails.root) FileUtils.touch gemfile_path - run_generator [destination_root] + run_generator assert_file gemfile_path, /gem 'bukkits', path: 'tmp\/bukkits'/ ensure @@ -375,19 +376,19 @@ class PluginGeneratorTest < Rails::Generators::TestCase name = `git config user.name`.chomp rescue "TODO: Write your name" email = `git config user.email`.chomp rescue "TODO: Write your email address" - run_generator [destination_root] + run_generator assert_file "bukkits.gemspec" do |contents| - assert_match(/#{Regexp.escape(name)}/, contents) - assert_match(/#{Regexp.escape(email)}/, contents) + assert_match name, contents + assert_match email, contents end end def test_git_name_in_license_file name = `git config user.name`.chomp rescue "TODO: Write your name" - run_generator [destination_root] + run_generator assert_file "MIT-LICENSE" do |contents| - assert_match(/#{Regexp.escape(name)}/, contents) + assert_match name, contents end end @@ -397,11 +398,11 @@ class PluginGeneratorTest < Rails::Generators::TestCase run_generator [destination_root, '--skip-git'] assert_file "MIT-LICENSE" do |contents| - assert_match(/#{Regexp.escape(name)}/, contents) + assert_match name, contents end assert_file "bukkits.gemspec" do |contents| - assert_match(/#{Regexp.escape(name)}/, contents) - assert_match(/#{Regexp.escape(email)}/, contents) + assert_match name, contents + assert_match email, contents end end @@ -415,10 +416,10 @@ protected end def assert_match_sqlite3(contents) - unless defined?(JRUBY_VERSION) - assert_match(/group :development do\n gem 'sqlite3'\nend/, contents) - else + if defined?(JRUBY_VERSION) assert_match(/group :development do\n gem 'activerecord-jdbcsqlite3-adapter'\nend/, contents) + else + assert_match(/group :development do\n gem 'sqlite3'\nend/, contents) end end end diff --git a/railties/test/generators/resource_generator_test.rb b/railties/test/generators/resource_generator_test.rb index dcdff22152..581d80d60e 100644 --- a/railties/test/generators/resource_generator_test.rb +++ b/railties/test/generators/resource_generator_test.rb @@ -36,7 +36,6 @@ class ResourceGeneratorTest < Rails::Generators::TestCase assert_file "test/controllers/accounts_controller_test.rb", /class AccountsControllerTest < ActionController::TestCase/ assert_file "app/helpers/accounts_helper.rb", /module AccountsHelper/ - assert_file "test/helpers/accounts_helper_test.rb", /class AccountsHelperTest < ActionView::TestCase/ end def test_resource_controller_with_actions diff --git a/railties/test/generators/scaffold_controller_generator_test.rb b/railties/test/generators/scaffold_controller_generator_test.rb index 46eacd2845..ca972a3bdd 100644 --- a/railties/test/generators/scaffold_controller_generator_test.rb +++ b/railties/test/generators/scaffold_controller_generator_test.rb @@ -81,7 +81,6 @@ class ScaffoldControllerGeneratorTest < Rails::Generators::TestCase def test_helper_are_invoked_with_a_pluralized_name run_generator assert_file "app/helpers/users_helper.rb", /module UsersHelper/ - assert_file "test/helpers/users_helper_test.rb", /class UsersHelperTest < ActionView::TestCase/ end def test_views_are_generated @@ -126,7 +125,6 @@ class ScaffoldControllerGeneratorTest < Rails::Generators::TestCase def test_skip_helper_if_required run_generator ["User", "name:string", "age:integer", "--no-helper"] assert_no_file "app/helpers/users_helper.rb" - assert_no_file "test/helpers/users_helper_test.rb" end def test_skip_layout_if_required diff --git a/railties/test/generators/scaffold_generator_test.rb b/railties/test/generators/scaffold_generator_test.rb index 524bbde2b7..637bde2a44 100644 --- a/railties/test/generators/scaffold_generator_test.rb +++ b/railties/test/generators/scaffold_generator_test.rb @@ -70,7 +70,6 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase # Helpers assert_file "app/helpers/product_lines_helper.rb" - assert_file "test/helpers/product_lines_helper_test.rb" # Assets assert_file "app/assets/stylesheets/scaffold.css" @@ -114,7 +113,6 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase # Helpers assert_no_file "app/helpers/product_lines_helper.rb" - assert_no_file "test/helpers/product_lines_helper_test.rb" # Assets assert_file "app/assets/stylesheets/scaffold.css", /:visited/ @@ -182,7 +180,6 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase # Helpers assert_file "app/helpers/admin/roles_helper.rb" - assert_file "test/helpers/admin/roles_helper_test.rb" # Assets assert_file "app/assets/stylesheets/scaffold.css", /:visited/ @@ -216,7 +213,6 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase # Helpers assert_no_file "app/helpers/admin/roles_helper.rb" - assert_no_file "test/helpers/admin/roles_helper_test.rb" # Assets assert_file "app/assets/stylesheets/scaffold.css" diff --git a/railties/test/generators_test.rb b/railties/test/generators_test.rb index 0b4edafaca..b5765c391e 100644 --- a/railties/test/generators_test.rb +++ b/railties/test/generators_test.rb @@ -1,6 +1,7 @@ require 'generators/generators_test_helper' require 'rails/generators/rails/model/model_generator' require 'rails/generators/test_unit/model/model_generator' +require 'mocha/setup' # FIXME: stop using mocha class GeneratorsTest < Rails::Generators::TestCase include GeneratorsTestHelper diff --git a/railties/test/isolation/abstract_unit.rb b/railties/test/isolation/abstract_unit.rb index 6c50911666..92d6a1729c 100644 --- a/railties/test/isolation/abstract_unit.rb +++ b/railties/test/isolation/abstract_unit.rb @@ -291,6 +291,33 @@ class ActiveSupport::TestCase include TestHelpers::Paths include TestHelpers::Rack include TestHelpers::Generation + + private + + def capture(stream) + stream = stream.to_s + captured_stream = Tempfile.new(stream) + stream_io = eval("$#{stream}") + origin_stream = stream_io.dup + stream_io.reopen(captured_stream) + + yield + + stream_io.rewind + return captured_stream.read + ensure + captured_stream.close + captured_stream.unlink + stream_io.reopen(origin_stream) + end + + def quietly + silence_stream(STDOUT) do + silence_stream(STDERR) do + yield + end + end + end end # Create a scope and build a fixture rails app diff --git a/railties/test/path_generation_test.rb b/railties/test/path_generation_test.rb new file mode 100644 index 0000000000..13bf29d3c3 --- /dev/null +++ b/railties/test/path_generation_test.rb @@ -0,0 +1,88 @@ +# encoding: utf-8 +require 'abstract_unit' +require 'active_support/core_ext/object/with_options' +require 'active_support/core_ext/object/json' +require 'rails' +require 'rails/application' + +ROUTING = ActionDispatch::Routing + +class PathGenerationTest < ActiveSupport::TestCase + attr_reader :app + + class TestSet < ROUTING::RouteSet + def initialize(block) + @block = block + super() + end + + class Dispatcher < ROUTING::RouteSet::Dispatcher + def initialize(defaults, set, block) + super(defaults) + @block = block + @set = set + end + + def controller_reference(controller_param) + block = @block + set = @set + Class.new(ActionController::Base) { + include set.url_helpers + define_method(:process) { |name| block.call(self) } + def to_a; [200, {}, []]; end + } + end + end + + def dispatcher defaults + TestSet::Dispatcher.new defaults, self, @block + end + end + + def send_request(uri_or_host, method, path, script_name = nil) + host = uri_or_host.host unless path + path ||= uri_or_host.path + + params = {'PATH_INFO' => path, + 'REQUEST_METHOD' => method, + 'HTTP_HOST' => host } + + params['SCRIPT_NAME'] = script_name if script_name + + status, headers, body = app.call(params) + new_body = [] + body.each { |part| new_body << part } + body.close if body.respond_to? :close + [status, headers, new_body] + end + + def test_original_script_name + original_logger = Rails.logger + Rails.logger = Logger.new nil + + app = Class.new(Rails::Application) { + attr_accessor :controller + def initialize + super + app = self + @routes = TestSet.new ->(c) { app.controller = c } + secrets.secret_key_base = "foo" + secrets.secret_token = "foo" + end + def app; routes; end + } + + @app = app + app.routes.draw { resource :blogs } + + url = URI("http://example.org/blogs") + + send_request(url, 'GET', nil, '/FOO') + assert_equal '/FOO/blogs', app.instance.controller.blogs_path + + send_request(url, 'GET', nil) + assert_equal '/blogs', app.instance.controller.blogs_path + ensure + Rails.logger = original_logger + end +end diff --git a/railties/test/paths_test.rb b/railties/test/paths_test.rb index ed4559ec6f..1aeb9ec339 100644 --- a/railties/test/paths_test.rb +++ b/railties/test/paths_test.rb @@ -1,5 +1,6 @@ require 'abstract_unit' require 'rails/paths' +require 'mocha/setup' # FIXME: stop using mocha class PathsTest < ActiveSupport::TestCase def setup diff --git a/railties/test/rack_logger_test.rb b/railties/test/rack_logger_test.rb index 6ebd47fff9..fcc79b57fb 100644 --- a/railties/test/rack_logger_test.rb +++ b/railties/test/rack_logger_test.rb @@ -39,11 +39,11 @@ module Rails def setup @subscriber = Subscriber.new @notifier = ActiveSupport::Notifications.notifier - notifier.subscribe 'request.action_dispatch', subscriber + @subscription = notifier.subscribe 'request.action_dispatch', subscriber end def teardown - notifier.unsubscribe subscriber + notifier.unsubscribe @subscription end def test_notification diff --git a/railties/test/rails_info_controller_test.rb b/railties/test/rails_info_controller_test.rb index a9b237d0a5..8d61af4972 100644 --- a/railties/test/rails_info_controller_test.rb +++ b/railties/test/rails_info_controller_test.rb @@ -1,4 +1,5 @@ require 'abstract_unit' +require 'mocha/setup' # FIXME: stop using mocha module ActionController class Base |