require File.expand_path("#{File.dirname(__FILE__)}/../spec_helper") require 'benchmark' require 'active_support' # for Symbol#to_proc module ExternalsSpec describe "adding dependencies" do before do @args = [:what, :ever, :is, :passed] @result = Erector::Dependency.new :js, '/foo.js' @result2 = Erector::Dependency.new :css, '/foo.css' end after do Erector::Widget.my_dependencies.clear end it "calls #interpret_args with given arguments and passes result to #push_dependency" do mock(Erector::Widget).interpret_args(*@args).returns(@result) Erector::Widget.depends_on *@args end it "starts out with no items in @_dependencies" do class Quesadilla < Erector::Widget end Quesadilla.my_dependencies.should == [] end describe '#interpret_args' do class Test include Erector::Externals end it "will infer that a .js extension is javascript" do x = Test.send :interpret_args, ('/path/to/a.js') x.text.should == '/path/to/a.js' x.type.should == :js end it "will infer that a .css extension is a stylesheet" do x = Test.send :interpret_args, ('/path/to/a.css') x.text.should == '/path/to/a.css' x.type.should == :css end it "will capture render options when just a file is mentioned" do x = Test.send(:interpret_args, '/path/to/a.css', :render=>:link) x.text.should == '/path/to/a.css' x.type.should == :css x.options.should == {:render=>:link} # could also be "embed" end it "embeds javascript" do x = Test.send :interpret_args, :js, "alert('foo')" x.text.should == "alert('foo')" x.type.should == :js end it "guesses Javascript type from .js" do x = Test.send :interpret_args, "/script/foo.js" x.text.should == "/script/foo.js" x.type.should == :js end it "guesses CSS type from .css" do x = Test.send :interpret_args, "/script/foo.css" x.text.should == "/script/foo.css" x.type.should == :css end it "add multiple files without an options hash" do x = Test.send :interpret_args, :js, "/script/foo.js", "/script/bar.js" x.size.should == 2 x[0].text.should == "/script/foo.js" x[0].type.should == :js x[1].text.should == "/script/bar.js" x[1].type.should == :js end it "add multiple files with an options hash" do x = Test.send :interpret_args, :js, "/script/foo.js", "/script/bar.js", :embed=>true x.size.should == 2 x[0].text.should == "/script/foo.js" x[0].type.should == :js x[0].options[:embed].should == true x[1].text.should == "/script/bar.js" x[1].type.should == :js x[1].options[:embed].should == true end it "adds multiple files from hash" do x = Test.send :interpret_args, :js => ["foo.js", "bar.js"] x.size.should == 2 x[0].text.should == "foo.js" x[0].type.should == :js x[1].text.should == "bar.js" x[1].type.should == :js end it "adds multiple files from hash of different types" do x = Test.send :interpret_args, :js => ["foo.js", "bar.js"], :css=>'file.css' x.size.should == 3 x.map(&:text).include?('foo.js') x.map(&:text).include?('bar.js') x.map(&:text).include?('file.css') end it "adds multiple files from hash and preserves the options" do x = Test.send :interpret_args, :js => ["foo.js", "bar.js"], :foo=>false x.size.should == 2 x[0].text.should == "foo.js" x[0].type.should == :js x[0].options.should == {:foo=>false} x[1].text.should == "bar.js" x[1].type.should == :js x[1].options.should == {:foo=>false} end end end describe 'extracting the dependencies (integration tests)' do attr_reader :HotSauce, :SourCream, :Tabasco before do @HotSauce = Class.new(Erector::Widget) do depends_on :css, "/css/tapatio.css", :media => "print" depends_on :css, "/css/salsa_picante.css" depends_on :js, "/lib/jquery.js" depends_on :js, "/lib/picante.js" end @SourCream = Class.new(Erector::Widget) do depends_on :css, "/css/sourcream.css" depends_on :js, "/lib/jquery.js" depends_on :js, "/lib/dairy.js" end @Tabasco = Class.new(self.HotSauce) do depends_on :js, "tabasco.js" depends_on :css, "/css/salsa_picante.css" end end it "can be fetched via the type" do self.HotSauce.dependencies(:css).map(&:text).should == [ "/css/tapatio.css", "/css/salsa_picante.css", ] end it "can be filtered via the class" do self.SourCream.dependencies(:css).map(&:text).should == [ "/css/sourcream.css", ] end it "grabs dependencies from superclasses too" do self.Tabasco.dependencies(:js).map(&:text).should == ["/lib/jquery.js", "/lib/picante.js", "tabasco.js"] end it "retains the options" do self.HotSauce.dependencies(:css).map(&:options).should == [ {:media => "print"}, {} ] end it "removes duplicates" do self.Tabasco.dependencies(:css).map(&:text).should == [ "/css/tapatio.css", "/css/salsa_picante.css", ] end it "works with strings or symbols" do self.HotSauce.dependencies("css").map(&:text).should == [ "/css/tapatio.css", "/css/salsa_picante.css", ] end class Taco < Erector::Widget depends_on :filling, "beef" depends_on :filling, "beef", :media => "print" end it "considers options when removing duplicates" do Taco.dependencies(:filling).map(&:text).should == ["beef", "beef"] end end describe "rendering with externals" do class Dinner < Erector::Widget external :js, "/dinner.js" def content span "dinner" widget Dessert end end class Dessert < Erector::Widget external :js, "/dessert.js" external :css, "/dessert.css" def content span "dessert" end end it "#render_with_externals sticks the externals for all its rendered sub-widgets at the end of the output buffer" do s = Dinner.new.render_with_externals s.to_s.should == "dinner" + "dessert" + "" + "" + "" end it "#render_externals returns externals for all rendered sub-widgets to an output buffer" do widget = Dinner.new widget.to_html widget.render_externals.to_s.should == "" + "" + "" end end end