require 'spec_helper' #require_relative "../lib/sinatra/exstatic_assets.rb" require_relative "../lib/sinatra/exstatic_assets/formats.rb" module Sinatra module Exstatic shared_context "mtime timestamp" do before(:each) do File.expects(:"exists?").with(fullpath) .at_least_once .returns(true) File.expects(:mtime).with(fullpath) .returns(time) end end describe Asset, :time_sensitive do shared_examples "for Asset file" do its(:fullpath) { should == fullpath } its(:"is_uri?") { should be_falsy } it { should_not be_nil } it { should == expected } end let(:asset_dir) { "app/public" } let(:time) { Time.now } subject(:asset){ Asset.new filename, asset_dir, timestamp_format } context "Given a file" do let(:filename) { "image.jpg" } let(:expected) { "image.jpg" } let(:fullpath) { File.join asset_dir, filename } context "Using mtime as the timestamp" do let(:timestamp_format) { :mtime_int } context "" do include_context "mtime timestamp" its(:timestamp) { should == Time.now.to_i } its(:querystring) { should == "?ts=#{Time.now.to_i}" } end include_examples "for Asset file" end context "Using sha1 as the timestamp" do let(:timestamp_format) { :sha1 } context "" do before do digest_mock = mock() digest_mock.expects(:hexdigest).returns( "871cb4397c5f5f146cc5583088b12c7d0a8ddc97" ) File.expects(:"exists?").with(fullpath).returns(true) Digest::SHA1.expects(:file).with(fullpath).returns(digest_mock) end its(:timestamp) { should == "871cb4397c5f5f146cc5583088b12c7d0a8ddc97" } its(:querystring) { should == %Q!?ts=#{"871cb4397c5f5f146cc5583088b12c7d0a8ddc97"}! } end include_examples "for Asset file" end end context "Given a url" do let(:filename) { "http://code.jquery.com/jquery-1.9.1.min.js" } let(:expected) { "http://code.jquery.com/jquery-1.9.1.min.js" } let(:timestamp_format) { :mtime_int } it { should_not be_nil } it { should == expected } its(:fullpath) { should be_nil } its(:timestamp) { should == false } its(:"is_uri?") { should be_truthy } its(:querystring) { should be_nil } end end describe Tag do subject { tag } context "Given a group of options" do let(:tag) { Tag.new "link", { :type => "text/css", :charset => "utf-8", :media => "projection", :rel => "stylesheet", :href => "/bar/stylesheets/winter.css" } } let(:expected) { %Q!! } it { should == expected } context "That include closed=false" do let(:tag) { Tag.new "link", { :type => "text/css", :charset => "utf-8", :media => "projection", :rel => "stylesheet", :href => "/bar/stylesheets/winter.css", :closed => false } } let(:expected) { %Q!! } it { should == expected } end end end class FakeObject include Sinatra::Exstatic::Private def initialize script_name=nil @script_name = script_name || public_folder end def uri( addr, absolute, script_name ) script_name ? File.join( @script_name, addr) : addr end def settings self end def public_folder "app/public" end def xhtml @xhtml ||= false end end describe "Private methods", :time_sensitive do let(:script_name) { "/bar" } let(:fullpath) { File.join asset_dir, filename } let(:asset_dir) { "app/public/" } let(:time) { Time.now.to_i } let(:timestamp_format) { :mtime_int } let(:o) { # A double, I couldn't get RSpec's to work with this # probably because they're not well documented # hint hint RSpec team o = FakeObject.new script_name } context "Favicon" do let(:url) { "/favicon.ico" } let(:filename) { "favicon.ico" } let(:expected) { %Q!! } subject { o.send :sss_favicon_tag, url, {asset_dir: asset_dir}, {} } it { should == expected } end context "Accessing the file system" do include_context "mtime timestamp" do end context "Stylesheets" do before do ENV["SCRIPT_NAME"] = script_name end let(:url) { "/stylesheets/winter.css" } let(:filename) { "/stylesheets/winter.css" } context "Given a filename" do context "But no options" do let(:expected) { %Q!! } subject { o.send :sss_stylesheet_tag, url, {asset_dir: asset_dir, timestamp_format: timestamp_format}, {} } it { should == expected } end context "with options" do context "media=print" do let(:expected) { %Q!! } subject { o.send :sss_stylesheet_tag, url, {asset_dir: asset_dir,media: "print", timestamp_format: timestamp_format}, {} } it { should == expected } end end end end context "Javascripts" do let(:url) { "/js/get_stuff.js" } let(:filename) { "/js/get_stuff.js" } let(:expected) { %Q!! } subject { o.send :sss_javascript_tag, url, {asset_dir: asset_dir, timestamp_format: timestamp_format}, {} } it { should_not be_nil } it { should == expected } end end context "Images" do context "Local" do let(:url) { "/images/foo.png" } let(:filename) { "/images/foo.png" } let(:expected) { %Q!! } subject { o.send :sss_image_tag, url, {asset_dir: asset_dir, timestamp_format: :mtime_int}, {} } context "Using mtime as the timestamp" do include_context "mtime timestamp" it { should_not be_nil } it { should == expected } end end context "Remote" do let(:url) { "http://example.org/images/foo.png" } let(:filename) { "/images/foo.png" } let(:expected) { %Q!! } subject { o.send :sss_image_tag, url, {asset_dir: asset_dir}, {} } it { should_not be_nil } it { should == expected } end context "Remote and secure" do let(:url) { "https://example.org/images/foo.png" } let(:filename) { "/images/foo.png" } let(:expected) { %Q!! } subject { o.send :sss_image_tag, url, {asset_dir: asset_dir}, {} } it { should_not be_nil } it { should == expected } end end end end # Exstatic end # Sinatra describe "Using them with a Sinatra app", :time_sensitive do include_context "All routes" let(:expected) { File.read File.expand_path(fixture_file, File.dirname(__FILE__)) } before do Sinatra::Exstatic::Asset.any_instance .expects(:exists?) .at_least_once .returns(true) Sinatra::Exstatic::Asset.any_instance .expects(:mtime_int) .at_least_once .returns(1367612251) end context "Main" do context "/" do let(:fixture_file) { "./support/fixtures/main.html" } before do get "/" end it_should_behave_like "Any route" subject { last_response.body } it { should == expected } end context "/deeper" do let(:fixture_file) { "./support/fixtures/app-deeper.html" } before do get "/deeper" end it_should_behave_like "Any route" subject { last_response.body } it { should == expected } end end context "Sub" do context "/app2/" do let(:fixture_file) { "./support/fixtures/app2.html" } before do get "/app2" end it_should_behave_like "Any route" subject { last_response.body } it { should == expected } end context "/app2/deeper" do let(:fixture_file) { "./support/fixtures/app2-deeper.html" } before do get "/app2/deeper" end it_should_behave_like "Any route" subject { last_response.body } it { should == expected } end context "/app2/deeper" do let(:fixture_file) { "./support/fixtures/app2-deeper.html" } before do get "/app2/deeper/and-deeper" end it_should_behave_like "Any route" subject { last_response.body } it { should == expected } end end end