提交 20ec1e92 编写于 作者: J Jeremy Daer

Eliminate overlapping `app/assets` load path

* Move `app/assets/manifest.js` to `app/assets/config/manifest.js`.
  Avoid the suggestion that you can/should deep-link `stylesheets/foo`.
* Pull in all toplevel stylesheets and JavaScripts, not just
  `application.js` and `.css`. Demonstrate how to use `link_directory`
  with a specified `.js`/`.css` type.
* Fix RAILS_ENV handling in assets tests.
* Shush warnings spam from third-party libs that distract from tests.
上级 eb73c580
......@@ -5,6 +5,10 @@ gemspec
# We need a newish Rake since Active Job sets its test tasks' descriptions.
gem 'rake', '>= 10.3'
# Active Support depends on a prerelease concurrent-ruby 1.0.0, so track
# latest master as it approaches release.
gem 'concurrent-ruby', '~> 1.0.0.pre2', github: 'ruby-concurrency/concurrent-ruby'
# Active Job depends on the URI::GID::MissingModelIDError, which isn't released yet.
gem 'globalid', github: 'rails/globalid', branch: 'master'
gem 'rack', github: 'rack/rack', branch: 'master'
......@@ -21,8 +25,8 @@ gem 'turbolinks', github: 'rails/turbolinks', branch: 'master'
gem 'arel', github: 'rails/arel', branch: 'master'
gem 'mail', github: 'mikel/mail', branch: 'master'
gem 'sprockets', github: 'rails/sprockets', branch: 'master'
gem 'sprockets-rails', github: 'rails/sprockets-rails', branch: 'master'
gem 'sprockets', '~> 4.0', github: 'rails/sprockets', branch: 'master'
gem 'sprockets-rails', '~> 3.0.0.beta3', github: 'rails/sprockets-rails', branch: 'master'
gem 'sass-rails', github: 'rails/sass-rails', branch: 'master'
# require: false so bcrypt is loaded only when has_secure_password is used.
......
......@@ -73,10 +73,10 @@ GIT
GIT
remote: git://github.com/rails/sprockets-rails.git
revision: 600f981fe79ff2d4179baf84bd18fac5acb58b5e
revision: 77098c5acd9f27613875097ce6587aff9d871d7f
branch: master
specs:
sprockets-rails (3.0.0.beta2)
sprockets-rails (3.0.0.beta3)
actionpack (>= 4.0)
activesupport (>= 4.0)
sprockets (>= 3.0.0)
......@@ -97,6 +97,12 @@ GIT
turbolinks (3.0.0)
coffee-rails
GIT
remote: git://github.com/ruby-concurrency/concurrent-ruby.git
revision: d15c5d624612c07dc6d2bf4af27b5c00eb6ae12b
specs:
concurrent-ruby (1.0.0.pre2)
PATH
remote: .
specs:
......@@ -179,7 +185,6 @@ GEM
coffee-script-source
execjs
coffee-script-source (1.9.1.1)
concurrent-ruby (1.0.0.pre2)
connection_pool (2.2.0)
dalli (2.7.4)
dante (0.2.0)
......@@ -309,6 +314,7 @@ DEPENDENCIES
benchmark-ips
byebug
coffee-rails (~> 4.1.0)
concurrent-ruby (~> 1.0.0.pre2)!
dalli (>= 2.2.1)
delayed_job
delayed_job_active_record
......@@ -342,8 +348,8 @@ DEPENDENCIES
sequel
sidekiq
sneakers
sprockets!
sprockets-rails!
sprockets (~> 4.0)!
sprockets-rails (~> 3.0.0.beta3)!
sqlite3 (~> 1.3.6)
stackprof
sucker_punch
......
<% unless options.api? -%>
//= link_tree ./images
//= link_tree ../images
<% end -%>
<% unless options.skip_javascript -%>
//= link ./javascripts/application.js
//= link_directory ../javascripts .js
<% end -%>
//= link ./stylesheets/application.css
//= link_directory ../stylesheets .css
......@@ -106,7 +106,7 @@ def test_dummy_config
def test_dummy_assets
template "rails/javascripts.js", "#{dummy_path}/app/assets/javascripts/application.js", force: true
template "rails/stylesheets.css", "#{dummy_path}/app/assets/stylesheets/application.css", force: true
template "rails/dummy_manifest.js", "#{dummy_path}/app/assets/manifest.js", force: true
template "rails/dummy_manifest.js", "#{dummy_path}/app/assets/config/manifest.js", force: true
end
def test_dummy_clean
......@@ -124,7 +124,7 @@ def test_dummy_clean
end
def assets_manifest
template "rails/engine_manifest.js", "app/assets/#{underscored_name}_manifest.js"
template "rails/engine_manifest.js", "app/assets/config/#{underscored_name}_manifest.js"
end
def stylesheets
......
<% unless api? -%>
//= link_tree ./images
//= link_tree ../images
<% end -%>
<% unless options.skip_javascript -%>
//= link ./javascripts/application.js
//= link_directory ../javascripts .js
<% end -%>
//= link ./stylesheets/application.css
//= link_directory ../stylesheets .css
<% if mountable? && !api? -%>
//= link <%= underscored_name %>_manifest.js
<% end -%>
<% if mountable? -%>
<% unless options.skip_javascript -%>
//= link ./javascripts/<%= namespaced_name %>/application.js
<% if !options.skip_javascript -%>
//= link_directory ../javascripts/<%= namespaced_name %> .js
<% end -%>
//= link ./stylesheets/<%= namespaced_name %>/application.css
//= link_directory ../stylesheets/<%= namespaced_name %> .css
<% end -%>
......@@ -7,7 +7,10 @@ class AssetDebuggingTest < ActiveSupport::TestCase
include Rack::Test::Methods
def setup
build_app(initializers: true)
# FIXME: shush Sass warning spam, not relevant to testing Railties
Kernel.silence_warnings do
build_app(initializers: true)
end
app_file "app/assets/javascripts/application.js", "//= require_tree ."
app_file "app/assets/javascripts/xmlhr.js", "function f1() { alert(); }"
......@@ -33,12 +36,19 @@ def teardown
teardown_app
end
# FIXME: shush Sass warning spam, not relevant to testing Railties
def get(*)
Kernel.silence_warnings { super }
end
test "assets are concatenated when debug is off and compile is off either if debug_assets param is provided" do
# config.assets.debug and config.assets.compile are false for production environment
ENV["RAILS_ENV"] = "production"
output = Dir.chdir(app_path){ `bin/rake assets:precompile --trace 2>&1` }
assert $?.success?, output
require "#{app_path}/config/environment"
# Load app env
app "production"
class ::PostsController < ActionController::Base ; end
......@@ -51,8 +61,8 @@ class ::PostsController < ActionController::Base ; end
test "assets are served with sourcemaps when compile is true and debug_assets params is true" do
add_to_env_config "production", "config.assets.compile = true"
ENV["RAILS_ENV"] = "production"
require "#{app_path}/config/environment"
# Load app env
app "production"
class ::PostsController < ActionController::Base ; end
......
......@@ -17,14 +17,23 @@ def teardown
end
def precompile!(env = nil)
quietly do
precompile_task = "bin/rake assets:precompile #{env} --trace 2>&1"
output = Dir.chdir(app_path) { %x[ #{precompile_task} ] }
assert $?.success?, output
output
with_env env.to_h do
quietly do
precompile_task = "bin/rake assets:precompile --trace 2>&1"
output = Dir.chdir(app_path) { %x[ #{precompile_task} ] }
assert $?.success?, output
output
end
end
end
def with_env(env)
env.each { |k, v| ENV[k.to_s] = v }
yield
ensure
env.each_key { |k| ENV.delete k.to_s }
end
def clean_assets!
quietly do
assert Dir.chdir(app_path) { system('bin/rake assets:clobber') }
......@@ -32,7 +41,8 @@ def clean_assets!
end
def assert_file_exists(filename)
assert Dir[filename].first, "missing #{filename}"
globbed = Dir[filename]
assert globbed.one?, "Found #{globbed.size} files matching #{filename}. All files in the directory: #{Dir.entries(File.dirname(filename)).inspect}"
end
def assert_no_file_exists(filename)
......@@ -51,7 +61,10 @@ def assert_no_file_exists(filename)
add_to_env_config "development", "config.assets.digest = false"
require "#{app_path}/config/environment"
# FIXME: shush Sass warning spam, not relevant to testing Railties
Kernel.silence_warnings do
require "#{app_path}/config/environment"
end
get "/assets/demo.js"
assert_equal 'a = "/assets/rails.png";', last_response.body.strip
......@@ -62,8 +75,8 @@ def assert_no_file_exists(filename)
add_to_env_config "production", "config.assets.compile = true"
add_to_env_config "production", "config.assets.precompile = []"
ENV["RAILS_ENV"] = "production"
require "#{app_path}/config/environment"
# Load app env
app "production"
assert !defined?(Uglifier)
get "/assets/demo.js"
......@@ -72,11 +85,10 @@ def assert_no_file_exists(filename)
end
test "precompile creates the file, gives it the original asset's content and run in production as default" do
app_file "app/assets/manifest.js", "//= link_tree ./javascripts"
app_file "app/assets/config/manifest.js", "//= link_tree ../javascripts"
app_file "app/assets/javascripts/application.js", "alert();"
app_file "app/assets/javascripts/foo/application.js", "alert();"
ENV["RAILS_ENV"] = nil
precompile!
files = Dir["#{app_path}/public/assets/application-*.js"]
......@@ -88,7 +100,7 @@ def assert_no_file_exists(filename)
end
def test_precompile_does_not_hit_the_database
app_file "app/assets/manifest.js", "//= link_tree ./javascripts"
app_file "app/assets/config/manifest.js", "//= link_tree ../javascripts"
app_file "app/assets/javascripts/application.js", "alert();"
app_file "app/assets/javascripts/foo/application.js", "alert();"
app_file "app/controllers/users_controller.rb", <<-eoruby
......@@ -98,10 +110,9 @@ class UsersController < ApplicationController; end
class User < ActiveRecord::Base; raise 'should not be reached'; end
eoruby
ENV['RAILS_ENV'] = 'production'
ENV['DATABASE_URL'] = 'postgresql://baduser:badpass@127.0.0.1/dbname'
precompile!
precompile! \
RAILS_ENV: 'production',
DATABASE_URL: 'postgresql://baduser:badpass@127.0.0.1/dbname'
files = Dir["#{app_path}/public/assets/application-*.js"]
files << Dir["#{app_path}/public/assets/foo/application-*.js"].first
......@@ -109,9 +120,6 @@ class User < ActiveRecord::Base; raise 'should not be reached'; end
assert_not_nil file, "Expected application.js asset to be generated, but none found"
assert_equal "alert();".strip, File.read(file).strip
end
ensure
ENV.delete 'RAILS_ENV'
ENV.delete 'DATABASE_URL'
end
test "precompile application.js and application.css and all other non JS/CSS files" do
......@@ -171,10 +179,9 @@ class User < ActiveRecord::Base; raise 'should not be reached'; end
test 'precompile use assets defined in app env config' do
add_to_env_config 'production', 'config.assets.precompile = [ "something.js" ]'
app_file 'app/assets/javascripts/something.js.erb', 'alert();'
precompile! 'RAILS_ENV=production'
precompile! RAILS_ENV: 'production'
assert_file_exists("#{app_path}/public/assets/something-*.js")
end
......@@ -183,15 +190,17 @@ class User < ActiveRecord::Base; raise 'should not be reached'; end
add_to_config 'config.assets.precompile = [ "something_manifest.js" ]'
add_to_env_config 'production', 'config.assets.precompile += [ "another_manifest.js" ]'
app_file 'app/assets/something_manifest.js', '//= link ./javascripts/something.js'
app_file 'app/assets/another_manifest.js', '//= link ./javascripts/another.js'
app_file 'app/assets/config/something_manifest.js', '//= link something.js'
app_file 'app/assets/config/another_manifest.js', '//= link another.js'
app_file 'app/assets/javascripts/something.js.erb', 'alert();'
app_file 'app/assets/javascripts/another.js.erb', 'alert();'
precompile! 'RAILS_ENV=production'
precompile! RAILS_ENV: 'production'
assert_file_exists("#{app_path}/public/assets/something_manifest-*.js")
assert_file_exists("#{app_path}/public/assets/something-*.js")
assert_file_exists("#{app_path}/public/assets/another_manifest-*.js")
assert_file_exists("#{app_path}/public/assets/another-*.js")
end
......@@ -199,8 +208,8 @@ class User < ActiveRecord::Base; raise 'should not be reached'; end
add_to_config "config.action_controller.perform_caching = false"
add_to_env_config "production", "config.assets.compile = true"
ENV["RAILS_ENV"] = "production"
require "#{app_path}/config/environment"
# Load app env
app "production"
assert_equal Sprockets::CachedEnvironment, Rails.application.assets.class
end
......@@ -211,8 +220,8 @@ class User < ActiveRecord::Base; raise 'should not be reached'; end
app_file "app/assets/javascripts/application.js", "alert();"
precompile!
manifest = Dir["#{app_path}/public/assets/.sprockets-manifest-*.json"].first
manifest = Dir["#{app_path}/public/assets/.sprockets-manifest-*.json"].first
assets = ActiveSupport::JSON.decode(File.read(manifest))
assert_match(/application-([0-z]+)\.js/, assets["assets"]["application.js"])
assert_match(/application-([0-z]+)\.css/, assets["assets"]["application.css"])
......@@ -233,14 +242,14 @@ class User < ActiveRecord::Base; raise 'should not be reached'; end
app_file "app/assets/javascripts/application.js", "alert();"
add_to_env_config "production", "config.serve_static_files = true"
ENV["RAILS_ENV"] = "production"
precompile!
precompile! RAILS_ENV: 'production'
manifest = Dir["#{app_path}/public/assets/.sprockets-manifest-*.json"].first
assets = ActiveSupport::JSON.decode(File.read(manifest))
asset_path = assets["assets"]["application.js"]
require "#{app_path}/config/environment"
# Load app env
app "production"
# Checking if Uglifier is defined we can know if Sprockets was reached or not
assert !defined?(Uglifier)
......@@ -249,12 +258,11 @@ class User < ActiveRecord::Base; raise 'should not be reached'; end
assert !defined?(Uglifier)
end
test "precompile properly refers files referenced with asset_path and runs in the provided RAILS_ENV" do
test "precompile properly refers files referenced with asset_path" do
app_file "app/assets/images/rails.png", "notactuallyapng"
app_file "app/assets/stylesheets/application.css.erb", "p { background-image: url(<%= asset_path('rails.png') %>) }"
add_to_env_config "test", "config.assets.digest = true"
precompile!('RAILS_ENV=test')
precompile!
file = Dir["#{app_path}/public/assets/application-*.css"].first
assert_match(/\/assets\/rails-([0-z]+)\.png/, File.read(file))
......@@ -265,8 +273,7 @@ class User < ActiveRecord::Base; raise 'should not be reached'; end
app_file "app/assets/stylesheets/application.css.erb", "p { background-image: url(<%= asset_path('rails.png') %>) }"
ENV["RAILS_ENV"] = "production"
precompile!
precompile! RAILS_ENV: 'production'
manifest = Dir["#{app_path}/public/assets/.sprockets-manifest-*.json"].first
assets = ActiveSupport::JSON.decode(File.read(manifest))
......@@ -275,8 +282,8 @@ class User < ActiveRecord::Base; raise 'should not be reached'; end
app_file "app/assets/images/rails.png", "p { url: change }"
precompile!
assets = ActiveSupport::JSON.decode(File.read(manifest))
assets = ActiveSupport::JSON.decode(File.read(manifest))
assert_not_equal asset_path, assets["assets"]["application.css"]
end
......@@ -284,8 +291,7 @@ class User < ActiveRecord::Base; raise 'should not be reached'; end
app_file "app/assets/images/rails.png", "notactuallyapng"
app_file "app/assets/stylesheets/application.css.erb", "p { background-image: url(<%= asset_path('rails.png') %>) }"
ENV["RAILS_ENV"] = "production"
precompile!
precompile! RAILS_ENV: 'production'
file = Dir["#{app_path}/public/assets/application-*.css"].first
assert_match(/\/assets\/rails-([0-z]+)\.png/, File.read(file))
......@@ -294,7 +300,7 @@ class User < ActiveRecord::Base; raise 'should not be reached'; end
test "precompile should handle utf8 filenames" do
filename = "レイルズ.png"
app_file "app/assets/images/#{filename}", "not an image really"
app_file "app/assets/manifest.js", "//= link_tree ./images"
app_file "app/assets/config/manifest.js", "//= link_tree ../images"
add_to_config "config.assets.precompile = %w(manifest.js)"
precompile!
......@@ -303,7 +309,8 @@ class User < ActiveRecord::Base; raise 'should not be reached'; end
assets = ActiveSupport::JSON.decode(File.read(manifest))
assert asset_path = assets["assets"].find { |(k, _)| k && k =~ /.png/ }[1]
require "#{app_path}/config/environment"
# Load app env
app "development"
get "/assets/#{URI.parser.escape(asset_path)}"
assert_match "not an image really", last_response.body
......@@ -326,8 +333,8 @@ class User < ActiveRecord::Base; raise 'should not be reached'; end
app_file "app/assets/javascripts/demo.js.erb", "<%= :alert %>();"
add_to_config "config.assets.compile = false"
ENV["RAILS_ENV"] = "production"
require "#{app_path}/config/environment"
# Load app env
app "production"
get "/assets/demo.js"
assert_equal 404, last_response.status
......@@ -344,7 +351,8 @@ class User < ActiveRecord::Base; raise 'should not be reached'; end
add_to_env_config "development", "config.assets.digest = false"
require "#{app_path}/config/environment"
# Load app env
app "development"
class ::OmgController < ActionController::Base
def index
......@@ -370,7 +378,8 @@ def index
add_to_env_config "development", "config.assets.digest = false"
require "#{app_path}/config/environment"
# Load app env
app "development"
get "/assets/demo.js"
assert_match "alert();", last_response.body
......@@ -381,10 +390,10 @@ def index
app_with_assets_in_view
# config.assets.debug and config.assets.compile are false for production environment
ENV["RAILS_ENV"] = "production"
precompile!
precompile! RAILS_ENV: 'production'
require "#{app_path}/config/environment"
# Load app env
app "production"
class ::PostsController < ActionController::Base ; end
......@@ -400,6 +409,7 @@ class ::PostsController < ActionController::Base ; end
app_file "app/assets/javascripts/xmlhr.js.erb", "<%= Post.name %>"
precompile!
assert_equal "Post\n;\n", File.read(Dir["#{app_path}/public/assets/application-*.js"].first)
end
......@@ -441,7 +451,10 @@ class ::PostsController < ActionController::Base ; end
app_with_assets_in_view
add_to_config "config.asset_host = 'example.com'"
add_to_env_config "development", "config.assets.digest = false"
require "#{app_path}/config/environment"
# Load app env
app "development"
class ::PostsController < ActionController::Base; end
get '/posts', {}, {'HTTPS'=>'off'}
......@@ -456,6 +469,7 @@ class ::PostsController < ActionController::Base; end
add_to_config "config.assets.precompile = %w{rails.png image_loader.js}"
add_to_config "config.asset_host = 'example.com'"
add_to_env_config "development", "config.assets.digest = false"
precompile!
assert_match "src='//example.com/assets/rails.png'", File.read(Dir["#{app_path}/public/assets/image_loader-*.js"].first)
......@@ -467,6 +481,7 @@ class ::PostsController < ActionController::Base; end
app_file "app/assets/javascripts/app.js.erb", "var src='<%= image_path('rails.png') %>';"
add_to_config "config.assets.precompile = %w{rails.png app.js}"
add_to_env_config "development", "config.assets.digest = false"
precompile!
assert_match "src='/sub/uri/assets/rails.png'", File.read(Dir["#{app_path}/public/assets/app-*.js"].first)
......
......@@ -51,7 +51,12 @@ def app(env = "production")
old_env = ENV["RAILS_ENV"]
@app ||= begin
ENV["RAILS_ENV"] = env
require "#{app_path}/config/environment"
# FIXME: shush Sass warning spam, not relevant to testing Railties
Kernel.silence_warnings do
require "#{app_path}/config/environment"
end
Rails.application
end
ensure
......@@ -161,18 +166,18 @@ def make_basic_app
require "action_view/railtie"
require 'action_dispatch/middleware/flash'
app = Class.new(Rails::Application)
app.config.eager_load = false
app.secrets.secret_key_base = "3b7cd727ee24e8444053437c36cc66c4"
app.config.session_store :cookie_store, key: "_myapp_session"
app.config.active_support.deprecation = :log
app.config.active_support.test_order = :random
app.config.log_level = :info
@app = Class.new(Rails::Application)
@app.config.eager_load = false
@app.secrets.secret_key_base = "3b7cd727ee24e8444053437c36cc66c4"
@app.config.session_store :cookie_store, key: "_myapp_session"
@app.config.active_support.deprecation = :log
@app.config.active_support.test_order = :random
@app.config.log_level = :info
yield app if block_given?
app.initialize!
yield @app if block_given?
@app.initialize!
app.routes.draw do
@app.routes.draw do
get "/" => "omg#index"
end
......@@ -297,7 +302,10 @@ def use_frameworks(arr)
end
def boot_rails
require File.expand_path('../../../../load_paths', __FILE__)
# FIXME: shush Sass warning spam, not relevant to testing Railties
Kernel.silence_warnings do
require File.expand_path('../../../../load_paths', __FILE__)
end
end
end
end
......@@ -327,5 +335,9 @@ class ActiveSupport::TestCase
File.open("#{app_template_path}/config/boot.rb", 'w') do |f|
f.puts "require '#{environment}'"
f.puts "require 'rails/all'"
# Preempt the Bundler.require in config/application.rb and silence warning
# spam from our gem dependencies (👋 hello Sass 😁)
f.puts "Kernel.silence_warnings { Bundler.require(*Rails.groups) }"
end
end unless defined?(RAILS_ISOLATED_ENGINE)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册