Merge pull request #5409 from rails/sprockets-rails

Remove sprockets integration from actionpack
This commit is contained in:
José Valim 2012-03-13 16:08:13 -07:00
commit c1f397f82c
31 changed files with 15 additions and 985 deletions

@ -22,6 +22,8 @@ end
# it being automatically loaded by sprockets
gem 'uglifier', '>= 1.0.3', :require => false
gem 'sprockets-rails', :git => "git://github.com/rails/sprockets-rails.git"
gem 'rake', '>= 0.8.7'
gem 'mocha', '>= 0.9.8'

@ -23,7 +23,6 @@
s.add_dependency('rack', '~> 1.4.1')
s.add_dependency('rack-test', '~> 0.6.1')
s.add_dependency('journey', '~> 1.0.1')
s.add_dependency('sprockets', '~> 2.2.0')
s.add_dependency('erubis', '~> 2.7.0')
s.add_development_dependency('tzinfo', '~> 0.3.29')

@ -1,105 +0,0 @@
require "fileutils"
namespace :assets do
def ruby_rake_task(task, fork = true)
env = ENV['RAILS_ENV'] || 'production'
groups = ENV['RAILS_GROUPS'] || 'assets'
args = [$0, task,"RAILS_ENV=#{env}","RAILS_GROUPS=#{groups}"]
args << "--trace" if Rake.application.options.trace
if $0 =~ /rake\.bat\Z/i
Kernel.exec $0, *args
else
fork ? ruby(*args) : Kernel.exec(FileUtils::RUBY, *args)
end
end
# We are currently running with no explicit bundler group
# and/or no explicit environment - we have to reinvoke rake to
# execute this task.
def invoke_or_reboot_rake_task(task)
if ENV['RAILS_GROUPS'].to_s.empty? || ENV['RAILS_ENV'].to_s.empty?
ruby_rake_task task
else
Rake::Task[task].invoke
end
end
desc "Compile all the assets named in config.assets.precompile"
task :precompile do
invoke_or_reboot_rake_task "assets:precompile:all"
end
namespace :precompile do
def internal_precompile(digest=nil)
unless Rails.application.config.assets.enabled
warn "Cannot precompile assets if sprockets is disabled. Please set config.assets.enabled to true"
exit
end
# Ensure that action view is loaded and the appropriate
# sprockets hooks get executed
_ = ActionView::Base
config = Rails.application.config
config.assets.compile = true
config.assets.digest = digest unless digest.nil?
config.assets.digests = {}
env = Rails.application.assets
target = File.join(Rails.public_path, config.assets.prefix)
compiler = Sprockets::StaticCompiler.new(env,
target,
config.assets.precompile,
:manifest_path => config.assets.manifest,
:digest => config.assets.digest,
:manifest => digest.nil?)
compiler.compile
end
task :all do
Rake::Task["assets:precompile:primary"].invoke
# We need to reinvoke in order to run the secondary digestless
# asset compilation run - a fresh Sprockets environment is
# required in order to compile digestless assets as the
# environment has already cached the assets on the primary
# run.
ruby_rake_task("assets:precompile:nondigest", false) if Rails.application.config.assets.digest
end
task :primary => ["assets:cache:clean"] do
internal_precompile
end
task :nondigest => ["assets:cache:clean"] do
internal_precompile(false)
end
end
desc "Remove compiled assets"
task :clean do
invoke_or_reboot_rake_task "assets:clean:all"
end
namespace :clean do
task :all => ["assets:cache:clean"] do
config = Rails.application.config
public_asset_path = File.join(Rails.public_path, config.assets.prefix)
rm_rf public_asset_path, :secure => true
end
end
namespace :cache do
task :clean => ["assets:environment"] do
Rails.application.assets.cache.clear
end
end
task :environment do
if Rails.application.config.assets.initialize_on_precompile
Rake::Task["environment"].invoke
else
Rails.application.initialize!(:assets)
Sprockets::Bootstrap.new(Rails.application).run
end
end
end

@ -1,37 +0,0 @@
module Sprockets
class Bootstrap
def initialize(app)
@app = app
end
# TODO: Get rid of config.assets.enabled
def run
app, config = @app, @app.config
return unless app.assets
config.assets.paths.each { |path| app.assets.append_path(path) }
if config.assets.compress
# temporarily hardcode default JS compressor to uglify. Soon, it will work
# the same as SCSS, where a default plugin sets the default.
unless config.assets.js_compressor == false
app.assets.js_compressor = LazyCompressor.new { Sprockets::Compressors.registered_js_compressor(config.assets.js_compressor || :uglifier) }
end
unless config.assets.css_compressor == false
app.assets.css_compressor = LazyCompressor.new { Sprockets::Compressors.registered_css_compressor(config.assets.css_compressor) }
end
end
if config.assets.compile
app.routes.prepend do
mount app.assets => config.assets.prefix
end
end
if config.assets.digest
app.assets = app.assets.index
end
end
end
end

@ -1,85 +0,0 @@
module Sprockets
module Compressors
extend self
@@css_compressors = {}
@@js_compressors = {}
@@default_css_compressor = nil
@@default_js_compressor = nil
def register_css_compressor(name, klass, options = {})
@@default_css_compressor = name.to_sym if options[:default] || @@default_css_compressor.nil?
@@css_compressors[name.to_sym] = { :klass => klass.to_s, :require => options[:require] }
end
def register_js_compressor(name, klass, options = {})
@@default_js_compressor = name.to_sym if options[:default] || @@default_js_compressor.nil?
@@js_compressors[name.to_sym] = { :klass => klass.to_s, :require => options[:require] }
end
def registered_css_compressor(name)
find_registered_compressor name, @@css_compressors, @@default_css_compressor
end
def registered_js_compressor(name)
find_registered_compressor name, @@js_compressors, @@default_js_compressor
end
# The default compressors must be registered in default plugins (ex. Sass-Rails)
register_css_compressor(:scss, 'Sass::Rails::Compressor', :require => 'sass/rails/compressor', :default => true)
register_js_compressor(:uglifier, 'Uglifier', :require => 'uglifier', :default => true)
# Automaticaly register some compressors
register_css_compressor(:yui, 'YUI::CssCompressor', :require => 'yui/compressor')
register_js_compressor(:closure, 'Closure::Compiler', :require => 'closure-compiler')
register_js_compressor(:yui, 'YUI::JavaScriptCompressor', :require => 'yui/compressor')
private
def find_registered_compressor(name, compressors_hash, default_compressor_name)
if name.respond_to?(:to_sym)
compressor = compressors_hash[name.to_sym] || compressors_hash[default_compressor_name]
require compressor[:require] if compressor[:require]
compressor[:klass].constantize.new
else
name
end
end
end
# An asset compressor which does nothing.
#
# This compressor simply returns the asset as-is, without any compression
# whatsoever. It is useful in development mode, when compression isn't
# needed but using the same asset pipeline as production is desired.
class NullCompressor #:nodoc:
def compress(content)
content
end
end
# An asset compressor which only initializes the underlying compression
# engine when needed.
#
# This postpones the initialization of the compressor until
# <code>#compress</code> is called the first time.
class LazyCompressor #:nodoc:
# Initializes a new LazyCompressor.
#
# The block should return a compressor when called, i.e. an object
# which responds to <code>#compress</code>.
def initialize(&block)
@block = block
end
def compress(content)
compressor.compress(content)
end
private
def compressor
@compressor ||= (@block.call || NullCompressor.new)
end
end
end

@ -1,6 +0,0 @@
module Sprockets
module Helpers
autoload :RailsHelper, "sprockets/helpers/rails_helper"
autoload :IsolatedHelper, "sprockets/helpers/isolated_helper"
end
end

@ -1,13 +0,0 @@
module Sprockets
module Helpers
module IsolatedHelper
def controller
nil
end
def config
Rails.application.config.action_controller
end
end
end
end

@ -1,167 +0,0 @@
require "action_view"
module Sprockets
module Helpers
module RailsHelper
extend ActiveSupport::Concern
include ActionView::Helpers::AssetTagHelper
def asset_paths
@asset_paths ||= begin
paths = RailsHelper::AssetPaths.new(config, controller)
paths.asset_environment = asset_environment
paths.asset_digests = asset_digests
paths.compile_assets = compile_assets?
paths.digest_assets = digest_assets?
paths
end
end
def javascript_include_tag(*sources)
options = sources.extract_options!
debug = options.delete(:debug) { debug_assets? }
body = options.delete(:body) { false }
digest = options.delete(:digest) { digest_assets? }
sources.collect do |source|
if debug && asset = asset_paths.asset_for(source, 'js')
asset.to_a.map { |dep|
super(dep.pathname.to_s, { :src => path_to_asset(dep, :ext => 'js', :body => true, :digest => digest) }.merge!(options))
}
else
super(source.to_s, { :src => path_to_asset(source, :ext => 'js', :body => body, :digest => digest) }.merge!(options))
end
end.join("\n").html_safe
end
def stylesheet_link_tag(*sources)
options = sources.extract_options!
debug = options.delete(:debug) { debug_assets? }
body = options.delete(:body) { false }
digest = options.delete(:digest) { digest_assets? }
sources.collect do |source|
if debug && asset = asset_paths.asset_for(source, 'css')
asset.to_a.map { |dep|
super(dep.pathname.to_s, { :href => path_to_asset(dep, :ext => 'css', :body => true, :protocol => :request, :digest => digest) }.merge!(options))
}
else
super(source.to_s, { :href => path_to_asset(source, :ext => 'css', :body => body, :protocol => :request, :digest => digest) }.merge!(options))
end
end.join("\n").html_safe
end
def asset_path(source, options = {})
source = source.logical_path if source.respond_to?(:logical_path)
path = asset_paths.compute_public_path(source, asset_prefix, options.merge(:body => true))
options[:body] ? "#{path}?body=1" : path
end
alias_method :path_to_asset, :asset_path # aliased to avoid conflicts with an asset_path named route
def image_path(source)
path_to_asset(source)
end
alias_method :path_to_image, :image_path # aliased to avoid conflicts with an image_path named route
def font_path(source)
path_to_asset(source)
end
alias_method :path_to_font, :font_path # aliased to avoid conflicts with an font_path named route
def javascript_path(source)
path_to_asset(source, :ext => 'js')
end
alias_method :path_to_javascript, :javascript_path # aliased to avoid conflicts with an javascript_path named route
def stylesheet_path(source)
path_to_asset(source, :ext => 'css')
end
alias_method :path_to_stylesheet, :stylesheet_path # aliased to avoid conflicts with an stylesheet_path named route
private
def debug_assets?
compile_assets? && (Rails.application.config.assets.debug || params[:debug_assets])
rescue NoMethodError
false
end
# Override to specify an alternative prefix for asset path generation.
# When combined with a custom +asset_environment+, this can be used to
# implement themes that can take advantage of the asset pipeline.
#
# If you only want to change where the assets are mounted, refer to
# +config.assets.prefix+ instead.
def asset_prefix
Rails.application.config.assets.prefix
end
def asset_digests
Rails.application.config.assets.digests
end
def compile_assets?
Rails.application.config.assets.compile
end
def digest_assets?
Rails.application.config.assets.digest
end
# Override to specify an alternative asset environment for asset
# path generation. The environment should already have been mounted
# at the prefix returned by +asset_prefix+.
def asset_environment
Rails.application.assets
end
class AssetPaths < ::ActionView::AssetPaths #:nodoc:
attr_accessor :asset_environment, :asset_prefix, :asset_digests, :compile_assets, :digest_assets
class AssetNotPrecompiledError < StandardError; end
def asset_for(source, ext)
source = source.to_s
return nil if is_uri?(source)
source = rewrite_extension(source, nil, ext)
asset_environment[source]
rescue Sprockets::FileOutsidePaths
nil
end
def digest_for(logical_path)
if digest_assets && asset_digests && (digest = asset_digests[logical_path])
return digest
end
if compile_assets
if digest_assets && asset = asset_environment[logical_path]
return asset.digest_path
end
return logical_path
else
raise AssetNotPrecompiledError.new("#{logical_path} isn't precompiled")
end
end
def rewrite_asset_path(source, dir, options = {})
if source[0] == ?/
source
else
source = digest_for(source) unless options[:digest] == false
source = File.join(dir, source)
source = "/#{source}" unless source =~ /^\//
source
end
end
def rewrite_extension(source, dir, ext)
if ext && File.extname(source) != ".#{ext}"
"#{source}.#{ext}"
else
source
end
end
end
end
end
end

@ -1,62 +0,0 @@
require "action_controller/railtie"
module Sprockets
autoload :Bootstrap, "sprockets/bootstrap"
autoload :Helpers, "sprockets/helpers"
autoload :Compressors, "sprockets/compressors"
autoload :LazyCompressor, "sprockets/compressors"
autoload :NullCompressor, "sprockets/compressors"
autoload :StaticCompiler, "sprockets/static_compiler"
# TODO: Get rid of config.assets.enabled
class Railtie < ::Rails::Railtie
rake_tasks do
load "sprockets/assets.rake"
end
initializer "sprockets.environment", :group => :all do |app|
config = app.config
next unless config.assets.enabled
require 'sprockets'
app.assets = Sprockets::Environment.new(app.root.to_s) do |env|
env.version = ::Rails.env + "-#{config.assets.version}"
if config.assets.logger != false
env.logger = config.assets.logger || ::Rails.logger
end
if config.assets.cache_store != false
env.cache = ActiveSupport::Cache.lookup_store(config.assets.cache_store) || ::Rails.cache
end
end
if config.assets.manifest
path = File.join(config.assets.manifest, "manifest.yml")
else
path = File.join(Rails.public_path, config.assets.prefix, "manifest.yml")
end
if File.exist?(path)
config.assets.digests = YAML.load_file(path)
end
ActiveSupport.on_load(:action_view) do
include ::Sprockets::Helpers::RailsHelper
app.assets.context_class.instance_eval do
include ::Sprockets::Helpers::IsolatedHelper
include ::Sprockets::Helpers::RailsHelper
end
end
end
# We need to configure this after initialization to ensure we collect
# paths from all engines. This hook is invoked exactly before routes
# are compiled, and so that other Railties have an opportunity to
# register compressors.
config.after_initialize do |app|
Sprockets::Bootstrap.new(app).run
end
end
end

@ -1,62 +0,0 @@
require 'fileutils'
module Sprockets
class StaticCompiler
attr_accessor :env, :target, :paths
def initialize(env, target, paths, options = {})
@env = env
@target = target
@paths = paths
@digest = options.fetch(:digest, true)
@manifest = options.fetch(:manifest, true)
@manifest_path = options.delete(:manifest_path) || target
@zip_files = options.delete(:zip_files) || /\.(?:css|html|js|svg|txt|xml)$/
end
def compile
manifest = {}
env.each_logical_path do |logical_path|
next unless compile_path?(logical_path)
if asset = env.find_asset(logical_path)
manifest[logical_path] = write_asset(asset)
end
end
write_manifest(manifest) if @manifest
end
def write_manifest(manifest)
FileUtils.mkdir_p(@manifest_path)
File.open("#{@manifest_path}/manifest.yml", 'wb') do |f|
YAML.dump(manifest, f)
end
end
def write_asset(asset)
path_for(asset).tap do |path|
filename = File.join(target, path)
FileUtils.mkdir_p File.dirname(filename)
asset.write_to(filename)
asset.write_to("#{filename}.gz") if filename.to_s =~ @zip_files
end
end
def compile_path?(logical_path)
paths.each do |path|
case path
when Regexp
return true if path.match(logical_path)
when Proc
return true if path.call(logical_path)
else
return true if File.fnmatch(path.to_s, logical_path)
end
end
false
end
def path_for(asset)
@digest ? asset.digest_path : asset.logical_path
end
end
end

@ -1 +0,0 @@
/* Different from other style.css */

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

@ -1 +0,0 @@
//= require xmlhr

@ -1 +0,0 @@
/*= require style */

@ -1,28 +0,0 @@
require 'abstract_unit'
require 'sprockets/compressors'
class CompressorsTest < ActiveSupport::TestCase
def test_register_css_compressor
Sprockets::Compressors.register_css_compressor(:null, Sprockets::NullCompressor)
compressor = Sprockets::Compressors.registered_css_compressor(:null)
assert_kind_of Sprockets::NullCompressor, compressor
end
def test_register_js_compressor
Sprockets::Compressors.register_js_compressor(:uglifier, 'Uglifier', :require => 'uglifier')
compressor = Sprockets::Compressors.registered_js_compressor(:uglifier)
assert_kind_of Uglifier, compressor
end
def test_register_default_css_compressor
Sprockets::Compressors.register_css_compressor(:null, Sprockets::NullCompressor, :default => true)
compressor = Sprockets::Compressors.registered_css_compressor(:default)
assert_kind_of Sprockets::NullCompressor, compressor
end
def test_register_default_js_compressor
Sprockets::Compressors.register_js_compressor(:null, Sprockets::NullCompressor, :default => true)
compressor = Sprockets::Compressors.registered_js_compressor(:default)
assert_kind_of Sprockets::NullCompressor, compressor
end
end

@ -1,349 +0,0 @@
require 'abstract_unit'
require 'sprockets'
require 'sprockets/helpers/rails_helper'
require 'mocha'
class SprocketsHelperTest < ActionView::TestCase
include Sprockets::Helpers::RailsHelper
attr_accessor :assets
class MockRequest
def protocol() 'http://' end
def ssl?() false end
def host_with_port() 'localhost' end
def script_name() nil end
end
def setup
super
@controller = BasicController.new
@controller.request = MockRequest.new
@assets = Sprockets::Environment.new
@assets.append_path(FIXTURES.join("sprockets/app/javascripts"))
@assets.append_path(FIXTURES.join("sprockets/app/stylesheets"))
@assets.append_path(FIXTURES.join("sprockets/app/images"))
@assets.append_path(FIXTURES.join("sprockets/app/fonts"))
application = Struct.new(:config, :assets).new(config, @assets)
Rails.stubs(:application).returns(application)
@config = config
@config.perform_caching = true
@config.assets.digest = true
@config.assets.compile = true
end
def url_for(*args)
"http://www.example.com"
end
def config
@controller ? @controller.config : @config
end
def compute_host(source, request, options = {})
raise "Should never get here"
end
test "asset_path" do
assert_match %r{/assets/logo-[0-9a-f]+.png},
asset_path("logo.png")
assert_match %r{/assets/logo-[0-9a-f]+.png},
asset_path("logo.png", :digest => true)
assert_match %r{/assets/logo.png},
asset_path("logo.png", :digest => false)
end
test "custom_asset_path" do
@config.assets.prefix = '/s'
assert_match %r{/s/logo-[0-9a-f]+.png},
asset_path("logo.png")
assert_match %r{/s/logo-[0-9a-f]+.png},
asset_path("logo.png", :digest => true)
assert_match %r{/s/logo.png},
asset_path("logo.png", :digest => false)
end
test "asset_path with root relative assets" do
assert_equal "/images/logo",
asset_path("/images/logo")
assert_equal "/images/logo.gif",
asset_path("/images/logo.gif")
assert_equal "/dir/audio",
asset_path("/dir/audio")
end
test "asset_path with absolute urls" do
assert_equal "http://www.example.com/video/play",
asset_path("http://www.example.com/video/play")
assert_equal "http://www.example.com/video/play.mp4",
asset_path("http://www.example.com/video/play.mp4")
end
test "with a simple asset host the url should default to protocol relative" do
@controller.config.default_asset_host_protocol = :relative
@controller.config.asset_host = "assets-%d.example.com"
assert_match %r{^//assets-\d.example.com/assets/logo-[0-9a-f]+.png},
asset_path("logo.png")
end
test "with a simple asset host the url can be changed to use the request protocol" do
@controller.config.asset_host = "assets-%d.example.com"
@controller.config.default_asset_host_protocol = :request
assert_match %r{http://assets-\d.example.com/assets/logo-[0-9a-f]+.png},
asset_path("logo.png")
end
test "With a proc asset host that returns no protocol the url should be protocol relative" do
@controller.config.default_asset_host_protocol = :relative
@controller.config.asset_host = Proc.new do |asset|
"assets-999.example.com"
end
assert_match %r{^//assets-999.example.com/assets/logo-[0-9a-f]+.png},
asset_path("logo.png")
end
test "with a proc asset host that returns a protocol the url use it" do
@controller.config.asset_host = Proc.new do |asset|
"http://assets-999.example.com"
end
assert_match %r{http://assets-999.example.com/assets/logo-[0-9a-f]+.png},
asset_path("logo.png")
end
test "stylesheets served with a controller in scope can access the request" do
config.asset_host = Proc.new do |asset, request|
assert_not_nil request
"http://assets-666.example.com"
end
assert_match %r{http://assets-666.example.com/assets/logo-[0-9a-f]+.png},
asset_path("logo.png")
end
test "stylesheets served without a controller in scope cannot access the request" do
@controller = nil
@config.asset_host = Proc.new do |asset, request|
fail "This should not have been called."
end
assert_raises ActionController::RoutingError do
asset_path("logo.png")
end
@config.asset_host = method :compute_host
assert_raises ActionController::RoutingError do
asset_path("logo.png")
end
end
test "image_tag" do
assert_dom_equal '<img alt="Xml" src="/assets/xml.png" />', image_tag("xml.png")
end
test "image_path" do
assert_match %r{/assets/logo-[0-9a-f]+.png},
image_path("logo.png")
assert_match %r{/assets/logo-[0-9a-f]+.png},
path_to_image("logo.png")
end
test "font_path" do
assert_match %r{/assets/font-[0-9a-f]+.ttf},
font_path("font.ttf")
assert_match %r{/assets/font-[0-9a-f]+.ttf},
path_to_font("font.ttf")
end
test "javascript_path" do
assert_match %r{/assets/application-[0-9a-f]+.js},
javascript_path("application")
assert_match %r{/assets/application-[0-9a-f]+.js},
javascript_path("application.js")
assert_match %r{/assets/application-[0-9a-f]+.js},
path_to_javascript("application.js")
end
test "stylesheet_path" do
assert_match %r{/assets/application-[0-9a-f]+.css},
stylesheet_path("application")
assert_match %r{/assets/application-[0-9a-f]+.css},
stylesheet_path("application.css")
assert_match %r{/assets/application-[0-9a-f]+.css},
path_to_stylesheet("application.css")
end
test "stylesheets served without a controller in do not use asset hosts when the default protocol is :request" do
@controller = nil
@config.asset_host = "assets-%d.example.com"
@config.default_asset_host_protocol = :request
@config.perform_caching = true
assert_match %r{/assets/logo-[0-9a-f]+.png},
asset_path("logo.png")
end
test "asset path with relative url root" do
@controller.config.relative_url_root = "/collaboration/hieraki"
assert_equal "/collaboration/hieraki/images/logo.gif",
asset_path("/images/logo.gif")
end
test "asset path with relative url root when controller isn't present but relative_url_root is" do
@controller = nil
@config.relative_url_root = "/collaboration/hieraki"
assert_equal "/collaboration/hieraki/images/logo.gif",
asset_path("/images/logo.gif")
end
test "font path through asset_path" do
assert_match %r{/assets/font-[0-9a-f]+.ttf},
asset_path('font.ttf')
assert_match %r{/assets/dir/font-[0-9a-f]+.ttf},
asset_path("dir/font.ttf")
assert_equal "http://www.example.com/fonts/font.ttf",
asset_path("http://www.example.com/fonts/font.ttf")
end
test "javascript path through asset_path" do
assert_match %r{/assets/application-[0-9a-f]+.js},
asset_path(:application, :ext => "js")
assert_match %r{/assets/xmlhr-[0-9a-f]+.js},
asset_path("xmlhr", :ext => "js")
assert_match %r{/assets/dir/xmlhr-[0-9a-f]+.js},
asset_path("dir/xmlhr.js", :ext => "js")
assert_equal "/dir/xmlhr.js",
asset_path("/dir/xmlhr", :ext => "js")
assert_equal "http://www.example.com/js/xmlhr",
asset_path("http://www.example.com/js/xmlhr", :ext => "js")
assert_equal "http://www.example.com/js/xmlhr.js",
asset_path("http://www.example.com/js/xmlhr.js", :ext => "js")
end
test "javascript include tag" do
assert_match %r{<script src="/assets/application-[0-9a-f]+.js" type="text/javascript"></script>},
javascript_include_tag(:application)
assert_match %r{<script src="/assets/application-[0-9a-f]+.js" type="text/javascript"></script>},
javascript_include_tag(:application, :digest => true)
assert_match %r{<script src="/assets/application.js" type="text/javascript"></script>},
javascript_include_tag(:application, :digest => false)
assert_match %r{<script src="/assets/xmlhr-[0-9a-f]+.js" type="text/javascript"></script>},
javascript_include_tag("xmlhr")
assert_match %r{<script src="/assets/xmlhr-[0-9a-f]+.js" type="text/javascript"></script>},
javascript_include_tag("xmlhr.js")
assert_equal '<script src="http://www.example.com/xmlhr" type="text/javascript"></script>',
javascript_include_tag("http://www.example.com/xmlhr")
assert_match %r{<script src=\"/assets/xmlhr-[0-9a-f]+.js" type=\"text/javascript\"></script>\n<script src=\"/assets/extra-[0-9a-f]+.js" type=\"text/javascript\"></script>},
javascript_include_tag("xmlhr", "extra")
assert_match %r{<script src="/assets/xmlhr-[0-9a-f]+.js\?body=1" type="text/javascript"></script>\n<script src="/assets/application-[0-9a-f]+.js\?body=1" type="text/javascript"></script>},
javascript_include_tag(:application, :debug => true)
assert_match %r{<script src="/assets/jquery.plugin.js" type="text/javascript"></script>},
javascript_include_tag('jquery.plugin', :digest => false)
@config.assets.compile = true
@config.assets.debug = true
assert_match %r{<script src="/javascripts/application.js" type="text/javascript"></script>},
javascript_include_tag('/javascripts/application')
assert_match %r{<script src="/assets/xmlhr-[0-9a-f]+.js\?body=1" type="text/javascript"></script>\n<script src="/assets/application-[0-9a-f]+.js\?body=1" type="text/javascript"></script>},
javascript_include_tag(:application)
end
test "stylesheet path through asset_path" do
assert_match %r{/assets/application-[0-9a-f]+.css}, asset_path(:application, :ext => "css")
assert_match %r{/assets/style-[0-9a-f]+.css}, asset_path("style", :ext => "css")
assert_match %r{/assets/dir/style-[0-9a-f]+.css}, asset_path("dir/style.css", :ext => "css")
assert_equal "/dir/style.css", asset_path("/dir/style.css", :ext => "css")
assert_equal "http://www.example.com/css/style",
asset_path("http://www.example.com/css/style", :ext => "css")
assert_equal "http://www.example.com/css/style.css",
asset_path("http://www.example.com/css/style.css", :ext => "css")
end
test "stylesheet link tag" do
assert_match %r{<link href="/assets/application-[0-9a-f]+.css" media="screen" rel="stylesheet" type="text/css" />},
stylesheet_link_tag(:application)
assert_match %r{<link href="/assets/application-[0-9a-f]+.css" media="screen" rel="stylesheet" type="text/css" />},
stylesheet_link_tag(:application, :digest => true)
assert_match %r{<link href="/assets/application.css" media="screen" rel="stylesheet" type="text/css" />},
stylesheet_link_tag(:application, :digest => false)
assert_match %r{<link href="/assets/style-[0-9a-f]+.css" media="screen" rel="stylesheet" type="text/css" />},
stylesheet_link_tag("style")
assert_match %r{<link href="/assets/style-[0-9a-f]+.css" media="screen" rel="stylesheet" type="text/css" />},
stylesheet_link_tag("style.css")
assert_equal '<link href="http://www.example.com/style.css" media="screen" rel="stylesheet" type="text/css" />',
stylesheet_link_tag("http://www.example.com/style.css")
assert_match %r{<link href="/assets/style-[0-9a-f]+.css" media="all" rel="stylesheet" type="text/css" />},
stylesheet_link_tag("style", :media => "all")
assert_match %r{<link href="/assets/style-[0-9a-f]+.css" media="print" rel="stylesheet" type="text/css" />},
stylesheet_link_tag("style", :media => "print")
assert_match %r{<link href="/assets/style-[0-9a-f]+.css" media="screen" rel="stylesheet" type="text/css" />\n<link href="/assets/extra-[0-9a-f]+.css" media="screen" rel="stylesheet" type="text/css" />},
stylesheet_link_tag("style", "extra")
assert_match %r{<link href="/assets/style-[0-9a-f]+.css\?body=1" media="screen" rel="stylesheet" type="text/css" />\n<link href="/assets/application-[0-9a-f]+.css\?body=1" media="screen" rel="stylesheet" type="text/css" />},
stylesheet_link_tag(:application, :debug => true)
@config.assets.compile = true
@config.assets.debug = true
assert_match %r{<link href="/stylesheets/application.css" media="screen" rel="stylesheet" type="text/css" />},
stylesheet_link_tag('/stylesheets/application')
assert_match %r{<link href="/assets/style-[0-9a-f]+.css\?body=1" media="screen" rel="stylesheet" type="text/css" />\n<link href="/assets/application-[0-9a-f]+.css\?body=1" media="screen" rel="stylesheet" type="text/css" />},
stylesheet_link_tag(:application)
assert_match %r{<link href="/assets/style-[0-9a-f]+.css\?body=1" media="print" rel="stylesheet" type="text/css" />\n<link href="/assets/application-[0-9a-f]+.css\?body=1" media="print" rel="stylesheet" type="text/css" />},
stylesheet_link_tag(:application, :media => "print")
end
test "alternate asset prefix" do
stubs(:asset_prefix).returns("/themes/test")
assert_match %r{/themes/test/style-[0-9a-f]+.css}, asset_path("style", :ext => "css")
end
test "alternate asset environment" do
assets = Sprockets::Environment.new
assets.append_path(FIXTURES.join("sprockets/alternate/stylesheets"))
stubs(:asset_environment).returns(assets)
assert_match %r{/assets/style-[0-9a-f]+.css}, asset_path("style", :ext => "css")
end
test "alternate hash based on environment" do
assets = Sprockets::Environment.new
assets.version = 'development'
assets.append_path(FIXTURES.join("sprockets/alternate/stylesheets"))
stubs(:asset_environment).returns(assets)
dev_path = asset_path("style", :ext => "css")
assets.version = 'production'
prod_path = asset_path("style", :ext => "css")
assert_not_equal prod_path, dev_path
end
test "precedence of `config.digest = false` over manifest.yml asset digests" do
Rails.application.config.assets.digests = {'logo.png' => 'logo-d1g3st.png'}
@config.assets.digest = false
assert_equal '/assets/logo.png',
asset_path("logo.png")
end
end

@ -1,57 +0,0 @@
require 'abstract_unit'
require 'sprockets'
require 'sprockets/helpers/rails_helper'
require 'mocha'
class SprocketsHelperWithRoutesTest < ActionView::TestCase
include Sprockets::Helpers::RailsHelper
# Let's bring in some named routes to test namespace conflicts with potential *_paths.
# We have to do this after we bring in the Sprockets RailsHelper so if there are conflicts,
# they'll fail in the way we expect in a real live Rails app.
routes = ActionDispatch::Routing::RouteSet.new
routes.draw do
resources :assets
end
include routes.url_helpers
def setup
super
@controller = BasicController.new
@assets = Sprockets::Environment.new
@assets.append_path(FIXTURES.join("sprockets/app/javascripts"))
@assets.append_path(FIXTURES.join("sprockets/app/stylesheets"))
@assets.append_path(FIXTURES.join("sprockets/app/images"))
application = Struct.new(:config, :assets).new(config, @assets)
Rails.stubs(:application).returns(application)
@config = config
@config.perform_caching = true
@config.assets.digest = true
@config.assets.compile = true
end
test "namespace conflicts on a named route called asset_path" do
# Testing this for sanity - asset_path is now a named route!
assert_equal asset_path('test_asset'), '/assets/test_asset'
assert_match %r{/assets/logo-[0-9a-f]+.png},
path_to_asset("logo.png")
assert_match %r{/assets/logo-[0-9a-f]+.png},
path_to_asset("logo.png", :digest => true)
assert_match %r{/assets/logo.png},
path_to_asset("logo.png", :digest => false)
end
test "javascript_include_tag with a named_route named asset_path" do
assert_match %r{<script src="/assets/application-[0-9a-f]+.js" type="text/javascript"></script>},
javascript_include_tag(:application)
end
test "stylesheet_link_tag with a named_route named asset_path" do
assert_match %r{<link href="/assets/application-[0-9a-f]+.css" media="screen" rel="stylesheet" type="text/css" />},
stylesheet_link_tag(:application)
end
end

@ -17,10 +17,11 @@
s.bindir = 'bin'
s.executables = []
s.add_dependency('activesupport', version)
s.add_dependency('actionpack', version)
s.add_dependency('activerecord', version)
s.add_dependency('actionmailer', version)
s.add_dependency('railties', version)
s.add_dependency('bundler', '~> 1.1')
s.add_dependency('activesupport', version)
s.add_dependency('actionpack', version)
s.add_dependency('activerecord', version)
s.add_dependency('actionmailer', version)
s.add_dependency('railties', version)
s.add_dependency('bundler', '~> 1.1')
s.add_dependency('sprockets-rails', '~> 1.0')
end

@ -5,7 +5,7 @@
action_controller
action_mailer
rails/test_unit
sprockets
sprockets/rails
).each do |framework|
begin
require "#{framework}/railtie"

@ -189,6 +189,7 @@ def assets_gemfile_entry
# Gems used only for assets and not required
# in production environments by default.
group :assets do
gem 'sprockets-rails', :git => 'https://github.com/rails/sprockets-rails.git'
gem 'sass-rails', :git => 'https://github.com/rails/sass-rails.git'
gem 'coffee-rails', :git => 'https://github.com/rails/coffee-rails.git'
@ -202,6 +203,7 @@ def assets_gemfile_entry
# Gems used only for assets and not required
# in production environments by default.
group :assets do
gem 'sprockets-rails', :git => 'https://github.com/rails/sprockets-rails.git'
gem 'sass-rails', '~> 4.0.0.beta'
gem 'coffee-rails', '~> 4.0.0.beta'

@ -7,7 +7,7 @@
<%= comment_if :skip_active_record %>require "active_record/railtie"
require "action_controller/railtie"
require "action_mailer/railtie"
<%= comment_if :skip_sprockets %>require "sprockets/railtie"
<%= comment_if :skip_sprockets %>require "sprockets/rails/railtie"
<%= comment_if :skip_test_unit %>require "rails/test_unit/railtie"
<% end -%>

@ -7,7 +7,7 @@
<%= comment_if :skip_active_record %>require "active_record/railtie"
require "action_controller/railtie"
require "action_mailer/railtie"
<%= comment_if :skip_sprockets %>require "sprockets/railtie"
<%= comment_if :skip_sprockets %>require "sprockets/rails/railtie"
<%= comment_if :skip_test_unit %>require "rails/test_unit/railtie"
<% end -%>

@ -213,7 +213,7 @@ def test_generator_if_skip_active_record_is_given
def test_generator_if_skip_sprockets_is_given
run_generator [destination_root, "--skip-sprockets"]
assert_file "config/application.rb" do |content|
assert_match(/#\s+require\s+["']sprockets\/railtie["']/, content)
assert_match(/#\s+require\s+["']sprockets\/rails\/railtie["']/, content)
assert_no_match(/config\.assets\.enabled = true/, content)
end
assert_file "Gemfile" do |content|