<file_sep>
This file, public/javascripts/asset.js, should be rendered
taking precedence over app/views/javascripts/asset.js.erb
<file_sep>require File.dirname(__FILE__) + '/../spec_helper'

describe ImagesController do
  before do
    add_fixture_views(ImagesController)
  end

  describe "when a matching file is found in app" do
    it "renders the file" do
      get "app_asset", :format => "txt"
      response.should render_template('images/app_asset')
    end
  end
  
  describe "when a matching file is not found" do
    it "raises" do
      lambda {
        get "bogus", :format => "txt"
      }.should raise_error
    end
  end
end<file_sep>namespace :desert_assets do
  desc "Renders plugin-provided assets to RAILS_ROOT/public."
  task :render_all => :environment do
    Rake::Task[ "desert_assets:render_js" ].invoke
    Rake::Task[ "desert_assets:render_css" ].invoke
  end
  
  desc "Renders plugin-provided app/views/javascripts/**/* files to public/javascripts."
  task :render_js => :environment do
    render('javascripts', 'js')
  end
  
  desc "Renders plugin-provided app/views/stylesheets/**/* files to public/stylesheets."
  task :render_css => :environment do
    render('stylesheets', 'css')
  end
  
  def render(dirname, extension)
    Desert::Manager.plugins_and_app.each do |plugin|
      load_path = "#{plugin.templates_path}/#{dirname}"
      templates = Dir["#{load_path}/**/*"]
      
      unless templates.empty?
        templates.each do |template_path|
          relative_path = template_path.gsub(plugin.templates_path, '')
          target_path = File.join(RAILS_ROOT, 'public', relative_path.gsub(Regexp.new("\.#{extension}\.[a-z]+$"), ".#{extension}"))
          
          view = ActionView::Base.new(File.join(RAILS_ROOT, 'app', 'views'))
          content = view.render(relative_path)
          File.open(target_path, 'w') {|f| f.write(content) }
        end
      end
    end
  end
end
<file_sep>ENV["RAILS_ENV"] = "test"
require File.expand_path(File.dirname(__FILE__) + "/../../../../config/environment")
require 'spec'
require 'spec/rails'

Spec::Runner.configure do |config|
  config.fixture_path = "#{File.dirname(__FILE__)}/../spec/fixtures"
end

def add_fixture_views(controller_class)
  controller_class.prepend_view_path(File.join(File.dirname(__FILE__), 'fixtures', 'app', 'views'))
  controller_class.prepend_view_path(File.join(File.dirname(__FILE__), 'fixtures', 'public'))
end
<file_sep>class SpecSuite
  def files
    dir = File.dirname(__FILE__)
    Dir["#{dir}/../spec/**/*_spec.rb"]
  end

  def run
    dir = File.dirname(__FILE__)
    ARGV.concat ["--options", "#{dir}/spec.opts"]

    files.each do |file|
      require file
    end
    result = ::Spec::Runner::CommandLine.run
    exit result
  end
end

if $0 == __FILE__
  SpecSuite.new.run
end
<file_sep>class JavascriptsController < AssetsController

  private

  def set_headers
    headers['Content-Type'] = 'text/javascript; charset=utf-8'
  end
end
<file_sep>require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')

describe JavascriptsController do
  describe "route generation" do
    it "should map #asset" do
      route_for(:controller => "javascripts", :action => "asset", :format => "js").should == "/javascripts/asset.js"
    end
  end

  describe "route recognition" do
    it "should generate params for #asset" do
      params_from(:get, "/javascripts/asset.js").should == {:controller => "javascripts", :action => "asset", :format => "js"}
    end
  end
end
<file_sep>require File.dirname(__FILE__) + '/../spec_helper'

describe JavascriptsController do
  before do
    add_fixture_views(JavascriptsController)
  end

  describe "when a matching file is found in app" do
    it "renders the file" do
      get "app_asset", :format => "js"
      response.should render_template('javascripts/app_asset')
    end
  end
  
  describe "when a matching file is not found" do
    it "raises" do
      lambda {
        get "bogus", :format => "txt"
      }.should raise_error
    end
  end
end
<file_sep>class ImagesController < AssetsController
  def render_with_image_view(options = nil, extra_options = {}, &block)
    params = request.parameters
    format = params[:format]
    options = {
      :status => 200,
      :filename => "#{params[:action]}.#{format}",
      :disposition => 'inline',
      :type => "image/#{format}"
    }
    
    data = render_to_string
    send_file_headers! options.merge(:text => data, :length => data.size)
    @performed_render = false
    render_without_image_view options
  end
  alias_method_chain :render, :image_view
  
  def render_to_string(options = nil, &block)
    render_without_image_view(options, &block)
  ensure
    erase_render_results
    forget_variables_added_to_assigns
    reset_variables_added_to_assigns
  end
end
<file_sep>images 'images/:action.:format', :controller => 'images'
javascripts 'javascripts/:action.:format', :controller => 'javascripts'
stylesheets 'stylesheets/:action.:format', :controller => 'stylesheets'
<file_sep>require File.dirname(__FILE__) + '/../spec_helper'

describe StylesheetsController do
  before do
    add_fixture_views(StylesheetsController)
  end

  describe "when a matching file is found in app" do
    it "renders the file" do
      get "app_asset", :format => "css"
      response.should render_template('stylesheets/app_asset')
    end
  end
  
  describe "when a matching file is not found" do
    it "raises" do
      lambda {
        get "bogus", :format => "css"
      }.should raise_error
    end
  end
end
<file_sep>= Desert Assets


== About Desert
Desert is a Rails plugin framework that makes it easy to share models, views,
controllers, helpers, routes, and migrations across your applications.

With Desert, reusability doesn't come at the cost of extensibility: it's trivial to extend
the functionality of a plugin - both in your application _and_ in other plugins.

Classes are automatically mixed in with your own or other plugins' classes.
This allows you to make full featured composable components.

Check it out: http://github.com/pivotal/desert


== About Desert Assets
TODO: Stuff about how Desert Assets allows your Desert plugin to provide assets
(javascripts, stylesheets, images) without a need to copy them to the application.

== Installation and Configuration

* Install and configure Desert

* Generate your Desert plugin

    script/generate desert_plugin my_plugin

* Configure your plugin to depend on Desert Assets

    # File: vendor/plugin/my_plugin/init.rb
    
    require_plugin 'desert_assets'

* Configure your application to load routes from Desert Assets

    # File: config/routes.rb
    
    ActionController::Routing::Routes.draw do |map|
      map.routes_from_plugin(:desert_assets)
      
      # ...
    end


== Usage

* Javascripts:

    # Example file: vendor/plugins/my_plugin/app/views/javascripts/sahara.js.erb
    
    function find_oasis() {
    
    }

* Stylesheets (TODO):

* Images (TODO):


== Running Specs
In order to run any of the provided RSpec specs, you need a Rails application with 
these plugins installed:

* desert
* desert_assets
* rspec
* rspec-rails

Copyright (c) 2010 Pivotal Labs. This software is licensed under the MIT License.
<file_sep>class AssetsController < ApplicationController
  before_filter :set_headers
  after_filter { |controller| controller.cache_page }
  session :off
  layout nil
  
  private
  
  def set_headers
    # optionally override
  end
end
