Skip to content

Commit

Permalink
[padrino-core] Moved rendering tests to separate file
Browse files Browse the repository at this point in the history
[padrino-core] Add additional rendering tests for layout and format
[padrino-core] Allow weaker format restrictions for rendering templates
  • Loading branch information
nesquena committed Mar 24, 2010
1 parent 8fd27f3 commit 83309d6
Show file tree
Hide file tree
Showing 5 changed files with 326 additions and 283 deletions.
1 change: 1 addition & 0 deletions CHANGES.rdoc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
* Improved Padrino Admin Generator, now admin_page accepts multiple models
* Fixed Padrino Admin Account where the accounts password field is in plain text (text_field)
* Added layouts folder back into application skeleton
* Fixed an issue with not being able to render erb or haml properly in a js response
* Added support for forcing render of specified template (i.e render 'foo.haml' in js request)

== 0.9.7
Expand Down
14 changes: 10 additions & 4 deletions padrino-core/lib/padrino-core/application/rendering.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module Padrino
##
# Padrino enhances the Sinatra ‘render’ method to have support for automatic template engine detection,
# among other more advanced features.
# enhanced layout functionality, locale enabled rendering, among other features.
#
module Rendering
def self.registered(app)
Expand Down Expand Up @@ -78,26 +78,31 @@ def resolved_layout
layout_var = self.class.instance_variable_get(:@_layout) || :application
has_layout_at_root = Dir["#{self.options.views}/#{layout_var}.*"].any?
layout_path = has_layout_at_root ? layout_var.to_sym : File.join('layouts', layout_var.to_s).to_sym
resolve_template(layout_path)[0] rescue nil
resolve_template(layout_path, :strict_format => true)[0] rescue nil
end

##
# Returns the template path and engine that match content_type (if present), I18n.locale.
#
# === Options
#
# :strict_format:: The resolved template must match the content_type of the request (defaults to false)
#
# ==== Example
#
# get "/foo", :respond_to => [:html, :js] do; render 'path/to/foo'; end
# # If you request "/foo.js" with I18n.locale == :ru => [:"/path/to/foo.ru.js", :erb]
# # If you request "/foo" with I18n.locale == :de => [:"/path/to/foo.de.haml", :haml]
#
def resolve_template(template_path, options={})
options.reverse_merge!(:strict_format => false)
view_path = options.delete(:views) || self.options.views || self.class.views || "./views"
template_path = "/#{template_path}" unless template_path.to_s =~ /^\//
target_extension = File.extname(template_path)[1..-1] || "none" # retrieves explicit template extension
template_path = template_path.chomp(".#{target_extension}")

templates = Dir[File.join(view_path, template_path) + ".*"].map do |file|
template_engine = options[:engine] || File.extname(file)[1..-1].to_sym # retrieves engine extension
template_engine = File.extname(file)[1..-1].to_sym # retrieves engine extension
template_file = file.sub(view_path, '').chomp(".#{template_engine}").to_sym # retrieves template filename
[template_file, template_engine]
end
Expand All @@ -107,7 +112,8 @@ def resolve_template(template_path, options={})
templates.find { |file, e| defined?(I18n) && file.to_s == "#{template_path}.#{I18n.locale}" && content_type == :html } ||
templates.find { |file, e| File.extname(file.to_s) == ".#{target_extension}" or e.to_s == target_extension.to_s } ||
templates.find { |file, e| file.to_s == "#{template_path}.#{content_type}" } ||
templates.find { |file, e| file.to_s == "#{template_path}" && content_type == :html }
templates.find { |file, e| file.to_s == "#{template_path}" && content_type == :html } ||
templates.any? && !options[:strict_format] && templates.first # If not strict, fall back to the first located template

raise "Template path '#{template_path}' could not be located and rendered!" unless located_template
located_template
Expand Down
31 changes: 31 additions & 0 deletions padrino-core/test/helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,35 @@ def method_missing(name, *args, &block)
end

alias :response :last_response

def create_template(name, content, options={})
FileUtils.mkdir_p(File.dirname(__FILE__) + "/views")
FileUtils.mkdir_p(File.dirname(__FILE__) + "/views/layouts")
path = "/views/#{name}"
path += ".#{options.delete(:locale)}" if options[:locale].present?
path += ".#{options[:format]}" if options[:format].present?
path += ".erb" unless options[:format].to_s =~ /haml|rss|atom/
path += ".builder" if options[:format].to_s =~ /rss|atom/
file = File.dirname(__FILE__) + path
File.open(file, 'w') { |io| io.write content }
file
end
alias :create_view :create_template
alias :create_layout :create_template

def remove_views
FileUtils.rm_rf(File.dirname(__FILE__) + "/views")
end

def with_template(name, content, options={})
# Build a temp layout
template = create_template(name, content, options)
yield
ensure
# Remove temp layout
File.unlink(template) rescue nil
remove_views
end
alias :with_view :with_template
alias :with_layout :with_template
end
280 changes: 1 addition & 279 deletions padrino-core/test/test_application.rb
Original file line number Diff line number Diff line change
@@ -1,38 +1,6 @@
require File.dirname(__FILE__) + '/helper'

class TestApplication < Test::Unit::TestCase

def create_template(name, content, options={})
FileUtils.mkdir_p(File.dirname(__FILE__) + "/views")
FileUtils.mkdir_p(File.dirname(__FILE__) + "/views/layouts")
path = "/views/#{name}"
path += ".#{options.delete(:locale)}" if options[:locale].present?
path += ".#{options[:format]}" if options[:format].present?
path += ".erb" unless options[:format].to_s =~ /haml|rss|atom/
path += ".builder" if options[:format].to_s =~ /rss|atom/
file = File.dirname(__FILE__) + path
File.open(file, 'w') { |io| io.write content }
file
end
alias :create_view :create_template
alias :create_layout :create_template

def remove_views
FileUtils.rm_rf(File.dirname(__FILE__) + "/views")
end

def with_template(name, content, options={})
# Build a temp layout
template = create_template(name, content, options)
yield
ensure
# Remove temp layout
File.unlink(template) rescue nil
remove_views
end
alias :with_view :with_template
alias :with_layout :with_template

def teardown
remove_views
end
Expand Down Expand Up @@ -64,250 +32,4 @@ class PadrinoTestApp < Padrino::Application; end
assert !PadrinoTestApp.padrino_helpers
end
end

context 'for application layout functionality' do

should 'get no layout' do
mock_app do
get("/"){ "no layout" }
end

get "/"
assert_equal "no layout", body
end

should 'be compatible with sinatra layout' do
mock_app do
layout do
"this is a <%= yield %>"
end

get("/"){ render :erb, "sinatra layout" }
end

get "/"
assert_equal "this is a sinatra layout", body
end

should 'use rails way layout' do
with_layout :application, "this is a <%= yield %>" do
mock_app do
get("/"){ render :erb, "rails way layout" }
end

get "/"
assert_equal "this is a rails way layout", body
end
end

should 'use rails way for a custom layout' do
with_layout "layouts/custom", "this is a <%= yield %>" do
mock_app do
layout :custom
get("/"){ render :erb, "rails way custom layout" }
end

get "/"
assert_equal "this is a rails way custom layout", body
end
end

should 'not use layout' do
with_layout :application, "this is a <%= yield %>" do
with_view :index, "index" do
mock_app do
get("/with/layout"){ render :index }
get("/without/layout"){ render :index, :layout => false }
end
get "/with/layout"
assert_equal "this is a index", body
get "/without/layout"
assert_equal "index", body
end
end
end
end

context 'for application render functionality' do

should 'be compatible with sinatra render' do
mock_app do
get("/"){ render :erb, "<%= 1+2 %>" }
end
get "/"
assert_equal "3", body
end

should 'be compatible with sinatra views' do
with_view :index, "<%= 1+2 %>" do
mock_app do
get("/foo") { render :erb, :index }
get("/bar") { erb :index }
get("/dir") { "3" }
get("/inj") { erb "<%= 2+1 %>" }
get("/rnj") { render :erb, "<%= 2+1 %>" }
end
get "/foo"
assert_equal "3", body
get "/bar"
assert_equal "3", body
get "/dir"
assert_equal "3", body
get "/inj"
assert_equal "3", body
get "/rnj"
assert_equal "3", body
end
end

should 'resolve template engine' do
with_view :index, "<%= 1+2 %>" do
mock_app do
get("/foo") { render :index }
get("/bar") { render "/index" }
end
get "/foo"
assert_equal "3", body
get "/bar"
assert_equal "3", body
end
end

should 'resolve template content type' do
create_view :foo, "Im Js", :format => :js
create_view :foo, "Im Erb"
mock_app do
get("/foo", :respond_to => :js) { render :foo }
get("/bar.js") { render :foo }
end
get "/foo.js"
assert_equal "Im Js", body
get "/bar.js"
assert_equal "Im Js", body
remove_views
end

should 'resolve with explicit template format' do
create_view :foo, "Im Js", :format => :js
create_view :foo, "Im Haml", :format => :haml
create_view :foo, "Im Xml", :format => :xml
mock_app do
get("/foo_normal", :respond_to => :js) { render 'foo' }
get("/foo_haml", :respond_to => :js) { render 'foo.haml' }
get("/foo_xml", :respond_to => :js) { render 'foo.xml' }
end
get "/foo_normal.js"
assert_equal "Im Js", body
get "/foo_haml.js"
assert_equal "Im Haml\n", body
get "/foo_xml.js"
assert_equal "Im Xml", body
remove_views
end

should 'resolve template locale' do
create_view :foo, "Im English", :locale => :en
create_view :foo, "Im Italian", :locale => :it
mock_app do
get("/foo") { render :foo }
end
I18n.locale = :en
get "/foo"
assert_equal "Im English", body
I18n.locale = :it
get "/foo"
assert_equal "Im Italian", body
end

should 'resolve template content_type and locale' do
create_view :foo, "Im Js", :format => :js
create_view :foo, "Im Erb"
create_view :foo, "Im English Erb", :locale => :en
create_view :foo, "Im Italian Erb", :locale => :it
create_view :foo, "Im English Js", :format => :js, :locale => :en
create_view :foo, "Im Italian Js", :format => :js, :locale => :it
mock_app do
get("/foo", :respond_to => [:html, :js]) { render :foo }
end
I18n.locale = :none
get "/foo.js"
assert_equal "Im Js", body
get "/foo"
assert_equal "Im Erb", body
I18n.locale = :en
get "/foo"
assert_equal "Im English Erb", body
I18n.locale = :it
get "/foo"
assert_equal "Im Italian Erb", body
I18n.locale = :en
get "/foo.js"
assert_equal "Im English Js", body
I18n.locale = :it
get "/foo.js"
assert_equal "Im Italian Js", body
I18n.locale = :en
get "/foo.pk"
assert_equal 404, status
end

should 'resolve template content_type and locale with layout' do
create_layout :foo, "Hello <%= yield %> in a Js layout", :format => :js
create_layout :foo, "Hello <%= yield %> in a Js-En layout", :format => :js, :locale => :en
create_layout :foo, "Hello <%= yield %> in a Js-It layout", :format => :js, :locale => :it
create_layout :foo, "Hello <%= yield %> in a Erb-En layout", :locale => :en
create_layout :foo, "Hello <%= yield %> in a Erb-It layout", :locale => :it
create_layout :foo, "Hello <%= yield %> in a Erb layout"
create_view :bar, "Im Js", :format => :js
create_view :bar, "Im Erb"
create_view :bar, "Im English Erb", :locale => :en
create_view :bar, "Im Italian Erb", :locale => :it
create_view :bar, "Im English Js", :format => :js, :locale => :en
create_view :bar, "Im Italian Js", :format => :js, :locale => :it
create_view :bar, "Im a json", :format => :json
mock_app do
layout :foo
get("/bar", :respond_to => [:html, :js, :json]) { render :bar }
end
I18n.locale = :none
get "/bar.js"
assert_equal "Hello Im Js in a Js layout", body
get "/bar"
assert_equal "Hello Im Erb in a Erb layout", body
I18n.locale = :en
get "/bar"
assert_equal "Hello Im English Erb in a Erb-En layout", body
I18n.locale = :it
get "/bar"
assert_equal "Hello Im Italian Erb in a Erb-It layout", body
I18n.locale = :en
get "/bar.js"
assert_equal "Hello Im English Js in a Js-En layout", body
I18n.locale = :it
get "/bar.js"
assert_equal "Hello Im Italian Js in a Js-It layout", body
I18n.locale = :en
get "/bar.json"
assert_equal "Im a json", body
get "/bar.pk"
assert_equal 404, status
end

should 'renders erb with blocks' do
mock_app do
def container
@_out_buf << "THIS."
yield
@_out_buf << "SPARTA!"
end
def is; "IS."; end
get '/' do
render :erb, '<% container do %> <%= is %> <% end %>'
end
end
get '/'
assert ok?
assert_equal 'THIS. IS. SPARTA!', body
end
end
end
end
Loading

0 comments on commit 83309d6

Please sign in to comment.