require 'template/spec_helper' describe "Template" do Template = Crystal::Template delegate :render, :to => Template with_environment :development before :all do @dir = "#{File.expand_path(File.dirname(__FILE__))}/template_spec" $LOAD_PATH << @dir ::RenderResult = OpenObject.new class ::SomeObject attr_accessor :ivariable end end after :all do $LOAD_PATH.delete @dir remove_constants %w(SomeObject RenderResult) end describe 'special' do it "read" do Template.read('/other/template').should == %{<% "ruby code" %> content} end it "exist?" do Template.should exist('/other/template') Template.should_not exist('/other/non-existing-template') end it "template prefixes" do Template.exist?('/prefixes/underscored', :prefixes => ['']).should be_false render('/prefixes/underscored', :prefixes => ['_', '']).should == "underscored" render('/prefixes/underscored.erb', :prefixes => ['_', '']).should == "underscored" Template.exist?('/prefixes/without_prefix', :prefixes => ['_']).should be_false render('/prefixes/without_prefix', :prefixes => ['']).should == "whthout prefix" end it "should not use prefixes for :action" do Template.exist?('/prefixes/underscored').should be_true Template.exist?('/prefixes/underscored', :action => true).should be_false end end describe 'basic' do it "general" do some_object = SomeObject.new some_object.ivariable = "instance variable value" options = { :instance_variables => [some_object, {:ivariable2 => "instance variable value 2"}], :object => OpenObject.new.update(:value => 'object value'), :locals => {:lvariable => 'local value'}, :format => :html } result = render("/basic/general", options){|content_name| "content for :#{content_name}"} check = %{\ Instance variable: instance variable value Instance variable 2: instance variable value 2 Object value: object value Locals value: local value Yield: content for :content} result.should == check end it "should not render wrong format" do Template.exist?('/basic/non_existing_format', :format => :html).should be_true Template.exist?('/basic/non_existing_format', :format => :invalid).should be_false # from error Template.exist?('non_existing_format', :format => :invalid, :current_dir => "#{@dir}/views/basic").should be_false end it "extension" do render('/basic/extension').should == "some content" render('/basic/extension.erb').should == "some content" end it "must support custom context" do class CustomTemplateContext < Crystal::TemplateContext def custom_helper 'custom helper' end end render('/basic/custom_context', :context_class => CustomTemplateContext).should == "content from custom helper" end it "no template" do lambda{render('/non-existing-template')}.should raise_error(/No template/) end it "should render arbitrary file" do render(:file => "#{@dir}/file.erb").should == "file template" end end describe 'format' do it "basic" do render('/format/format', :format => :html).should == "html format" render('/format/format', :format => :js).should == "js format" render('/format/format', :format => :non_existing).should == "universal format" render('/format/format.html', :format => :js).should == "html format" render('/format/format.html.erb', :format => :js).should == "html format" end it "nesting different formats" do render('/nesting_format/dialog', :format => :js).should == "$.showDialog(dialog, dialog form)" end end describe 'nested' do it "should render relative templates" do render('/nested/relative/a').should == "template a, template b" lambda{render('b')}.should raise_error(/You can't use relative template path/) current_dir = "#{@dir}/views/nested/relative" render('b', :current_dir => current_dir).should == "template b" end it "should render relative templates with complex path (../../xxx)" do render('/nested/relative/c').should == "template c, shared template" end it "nested templates should use the same format" do render('/nested/format/a', :format => :js).should == "js format, js format" end end describe "layout" do def render_with_layout template, options, layout content, context = Template.basic_render(Template.parse_arguments(template, options)) Template.render_layout(layout, :content => content, :context => context) end it "templates and layout must share the same context" do render_with_layout( '/layout/same_context/a', {:instance_variables => {:ivariable => "ivariable"}}, '/layout/same_context/layout' ).should == "layout ivariable content a ivariable content b ivariable" end it "content_for" do render_with_layout( '/layout/content_for/content', {}, '/layout/content_for/layout' ).should == %{\ head content bottom} end it "basic" do render_with_layout( '/layout/basic/content', {}, '/layout/basic/layout' ).should == "layotu begin content end" end it "layout with format" do render_with_layout( '/layout/format/content', {:format => :html}, '/layout/format/layout' ).should == "html layout begin html content end" render_with_layout( '/layout/format/content', {:format => :js}, '/layout/format/layout' ).should == "js layout begin js content end" end it "layout should support yield in partials (from error)" do render_with_layout( '/layout/nested_yield/a', {}, '/layout/nested_yield/layout' ).should == "some content" end end end