PageRenderTime 55ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 1ms

/vendor/gems/haml-3.0.10/test/haml/template_test.rb

https://github.com/michaelkirk/freehub
Ruby | 417 lines | 336 code | 62 blank | 19 comment | 15 complexity | 14620e0ee6444cbea8c9e1ce3679550b MD5 | raw file
  1. #!/usr/bin/env ruby
  2. require File.dirname(__FILE__) + '/../test_helper'
  3. require 'sass/plugin'
  4. require File.dirname(__FILE__) + '/mocks/article'
  5. require 'action_pack/version'
  6. module Haml::Filters::Test
  7. include Haml::Filters::Base
  8. def render(text)
  9. "TESTING HAHAHAHA!"
  10. end
  11. end
  12. module Haml::Helpers
  13. def test_partial(name, locals = {})
  14. Haml::Engine.new(File.read(File.join(TemplateTest::TEMPLATE_PATH, "_#{name}.haml"))).render(self, locals)
  15. end
  16. end
  17. class Egocentic
  18. def method_missing(*args)
  19. self
  20. end
  21. end
  22. class DummyController
  23. attr_accessor :logger
  24. def initialize
  25. @logger = Egocentic.new
  26. end
  27. def self.controller_path
  28. ''
  29. end
  30. def controller_path
  31. ''
  32. end
  33. end
  34. class TemplateTest < Test::Unit::TestCase
  35. TEMPLATE_PATH = File.join(File.dirname(__FILE__), "templates")
  36. TEMPLATES = %w{ very_basic standard helpers
  37. whitespace_handling original_engine list helpful
  38. silent_script tag_parsing just_stuff partials
  39. filters nuke_outer_whitespace nuke_inner_whitespace
  40. render_layout }
  41. # partial layouts were introduced in 2.0.0
  42. TEMPLATES << 'partial_layout' unless ActionPack::VERSION::MAJOR < 2
  43. def setup
  44. @base = create_base
  45. # filters template uses :sass
  46. Sass::Plugin.options.update(:line_comments => true, :style => :compact)
  47. end
  48. def create_base
  49. vars = { 'article' => Article.new, 'foo' => 'value one' }
  50. unless Haml::Util.has?(:instance_method, ActionView::Base, :finder)
  51. base = ActionView::Base.new(TEMPLATE_PATH, vars)
  52. else
  53. # Rails 2.1.0
  54. base = ActionView::Base.new([], vars)
  55. base.finder.append_view_path(TEMPLATE_PATH)
  56. end
  57. if Haml::Util.has?(:private_method, base, :evaluate_assigns)
  58. # Rails < 3.0
  59. base.send(:evaluate_assigns)
  60. elsif Haml::Util.has?(:private_method, base, :_evaluate_assigns_and_ivars)
  61. # Rails 2.2
  62. base.send(:_evaluate_assigns_and_ivars)
  63. end
  64. # This is needed by RJS in (at least) Rails 3
  65. base.instance_variable_set('@template', base)
  66. # This is used by form_for.
  67. # It's usually provided by ActionController::Base.
  68. def base.protect_against_forgery?; false; end
  69. # In Rails <= 2.1, a fake controller object was needed
  70. # to provide the controller path.
  71. if ActionPack::VERSION::MAJOR < 2 ||
  72. (ActionPack::VERSION::MAJOR == 2 && ActionPack::VERSION::MINOR < 2)
  73. base.controller = DummyController.new
  74. end
  75. base
  76. end
  77. def render(text, opts = {})
  78. return @base.render(:inline => text, :type => :haml) if opts == :action_view
  79. Haml::Engine.new(text, opts).to_html(@base)
  80. end
  81. def load_result(name)
  82. @result = ''
  83. File.new(File.dirname(__FILE__) + "/results/#{name}.xhtml").each_line { |l| @result += l }
  84. @result
  85. end
  86. def assert_renders_correctly(name, &render_method)
  87. old_options = Haml::Template.options.dup
  88. Haml::Template.options[:escape_html] = false
  89. if ActionPack::VERSION::MAJOR < 2 ||
  90. (ActionPack::VERSION::MAJOR == 2 && ActionPack::VERSION::MINOR < 2)
  91. render_method ||= proc { |name| @base.render(name) }
  92. else
  93. render_method ||= proc { |name| @base.render(:file => name) }
  94. end
  95. load_result(name).split("\n").zip(render_method[name].split("\n")).each_with_index do |pair, line|
  96. message = "template: #{name}\nline: #{line}"
  97. assert_equal(pair.first, pair.last, message)
  98. end
  99. rescue Haml::Util.av_template_class(:Error) => e
  100. if e.message =~ /Can't run [\w:]+ filter; required (one of|file) ((?:'\w+'(?: or )?)+)(, but none were found| not found)/
  101. puts "\nCouldn't require #{$2}; skipping a test."
  102. else
  103. raise e
  104. end
  105. ensure
  106. Haml::Template.options = old_options
  107. end
  108. def test_empty_render_should_remain_empty
  109. assert_equal('', render(''))
  110. end
  111. TEMPLATES.each do |template|
  112. define_method "test_template_should_render_correctly [template: #{template}] " do
  113. assert_renders_correctly template
  114. end
  115. end
  116. def test_templates_should_render_correctly_with_render_proc
  117. assert_renders_correctly("standard") do |name|
  118. engine = Haml::Engine.new(File.read(File.dirname(__FILE__) + "/templates/#{name}.haml"))
  119. engine.render_proc(@base).call
  120. end
  121. end
  122. def test_templates_should_render_correctly_with_def_method
  123. assert_renders_correctly("standard") do |name|
  124. engine = Haml::Engine.new(File.read(File.dirname(__FILE__) + "/templates/#{name}.haml"))
  125. engine.def_method(@base, "render_standard")
  126. @base.render_standard
  127. end
  128. end
  129. if ActionPack::VERSION::MAJOR < 3
  130. # Rails 3.0.0 deprecates the use of yield with a layout
  131. # for calls to render :file
  132. def test_action_view_templates_render_correctly
  133. proc = lambda do
  134. @base.content_for(:layout) {'Lorem ipsum dolor sit amet'}
  135. assert_renders_correctly 'content_for_layout'
  136. end
  137. if @base.respond_to?(:with_output_buffer)
  138. @base.with_output_buffer("", &proc)
  139. else
  140. proc.call
  141. end
  142. end
  143. end
  144. def test_instance_variables_should_work_inside_templates
  145. @base.instance_variable_set("@content_for_layout", 'something')
  146. assert_equal("<p>something</p>", render("%p= @content_for_layout").chomp)
  147. @base.instance_eval("@author = 'Hampton Catlin'")
  148. assert_equal("<div class='author'>Hampton Catlin</div>", render(".author= @author").chomp)
  149. @base.instance_eval("@author = 'Hampton'")
  150. assert_equal("Hampton", render("= @author").chomp)
  151. @base.instance_eval("@author = 'Catlin'")
  152. assert_equal("Catlin", render("= @author").chomp)
  153. end
  154. def test_instance_variables_should_work_inside_attributes
  155. @base.instance_eval("@author = 'hcatlin'")
  156. assert_equal("<p class='hcatlin'>foo</p>", render("%p{:class => @author} foo").chomp)
  157. end
  158. def test_template_renders_should_eval
  159. assert_equal("2\n", render("= 1+1"))
  160. end
  161. unless Haml::Util.ap_geq_3?
  162. def test_form_for_error_return
  163. assert_raise(Haml::Error) { render(<<HAML) }
  164. = form_for :article, @article, :url => '' do |f|
  165. Title:
  166. = f.text_field :title
  167. Body:
  168. = f.text_field :body
  169. HAML
  170. end
  171. def test_form_tag_error_return
  172. assert_raise(Haml::Error) { render(<<HAML) }
  173. = form_tag '' do
  174. Title:
  175. Body:
  176. HAML
  177. end
  178. end
  179. def test_haml_options
  180. old_options = Haml::Template.options.dup
  181. Haml::Template.options[:suppress_eval] = true
  182. old_base, @base = @base, create_base
  183. assert_renders_correctly("eval_suppressed")
  184. ensure
  185. @base = old_base
  186. Haml::Template.options = old_options
  187. end
  188. def test_with_output_buffer_with_ugly
  189. return unless Haml::Util.has?(:instance_method, ActionView::Base, :with_output_buffer)
  190. assert_equal(<<HTML, render(<<HAML, :ugly => true))
  191. <p>
  192. foo
  193. baz
  194. </p>
  195. HTML
  196. %p
  197. foo
  198. -# Parenthesis required due to Rails 3.0 deprecation of block helpers
  199. -# that return strings.
  200. - (with_output_buffer do
  201. bar
  202. = "foo".gsub(/./) do |s|
  203. - "flup"
  204. - end; nil)
  205. baz
  206. HAML
  207. end
  208. def test_exceptions_should_work_correctly
  209. begin
  210. render("- raise 'oops!'")
  211. rescue Exception => e
  212. assert_equal("oops!", e.message)
  213. assert_match(/^\(haml\):1/, e.backtrace[0])
  214. else
  215. assert false
  216. end
  217. template = <<END
  218. %p
  219. %h1 Hello!
  220. = "lots of lines"
  221. = "even more!"
  222. - raise 'oh no!'
  223. %p
  224. this is after the exception
  225. %strong yes it is!
  226. ho ho ho.
  227. END
  228. begin
  229. render(template.chomp)
  230. rescue Exception => e
  231. assert_match(/^\(haml\):5/, e.backtrace[0])
  232. else
  233. assert false
  234. end
  235. end
  236. if defined?(ActionView::OutputBuffer) &&
  237. Haml::Util.has?(:instance_method, ActionView::OutputBuffer, :append_if_string=)
  238. def test_av_block_deprecation_warning
  239. assert_warning(/^DEPRECATION WARNING: - style block helpers are deprecated\. Please use =\./) do
  240. assert_equal <<HTML, render(<<HAML, :action_view)
  241. <form action="" method="post">
  242. Title:
  243. <input id="article_title" name="article[title]" size="30" type="text" value="Hello" />
  244. Body:
  245. <input id="article_body" name="article[body]" size="30" type="text" value="World" />
  246. </form>
  247. HTML
  248. - form_for #{form_for_calling_convention(:article)}, :url => '' do |f|
  249. Title:
  250. = f.text_field :title
  251. Body:
  252. = f.text_field :body
  253. HAML
  254. end
  255. end
  256. end
  257. ## XSS Protection Tests
  258. # In order to enable these, either test against Rails 3.0
  259. # or test against Rails 2.2.5+ with the rails_xss plugin
  260. # (http://github.com/NZKoz/rails_xss) in test/plugins.
  261. if Haml::Util.rails_xss_safe?
  262. def test_escape_html_option_set
  263. assert Haml::Template.options[:escape_html]
  264. end
  265. def test_xss_protection
  266. assert_equal("Foo &amp; Bar\n", render('= "Foo & Bar"', :action_view))
  267. end
  268. def test_xss_protection_with_safe_strings
  269. assert_equal("Foo & Bar\n", render('= Haml::Util.html_safe("Foo & Bar")', :action_view))
  270. end
  271. def test_xss_protection_with_bang
  272. assert_equal("Foo & Bar\n", render('!= "Foo & Bar"', :action_view))
  273. end
  274. def test_xss_protection_in_interpolation
  275. assert_equal("Foo &amp; Bar\n", render('Foo #{"&"} Bar', :action_view))
  276. end
  277. def test_xss_protection_with_bang_in_interpolation
  278. assert_equal("Foo & Bar\n", render('! Foo #{"&"} Bar', :action_view))
  279. end
  280. def test_xss_protection_with_safe_strings_in_interpolation
  281. assert_equal("Foo & Bar\n", render('Foo #{Haml::Util.html_safe("&")} Bar', :action_view))
  282. end
  283. def test_xss_protection_with_mixed_strings_in_interpolation
  284. assert_equal("Foo & Bar &amp; Baz\n", render('Foo #{Haml::Util.html_safe("&")} Bar #{"&"} Baz', :action_view))
  285. end
  286. def test_rendered_string_is_html_safe
  287. assert(render("Foo").html_safe?)
  288. end
  289. def test_rendered_string_is_html_safe_with_action_view
  290. assert(render("Foo", :action_view).html_safe?)
  291. end
  292. def test_xss_html_escaping_with_non_strings
  293. assert_equal("4\n", render("= html_escape(4)"))
  294. end
  295. def test_xss_protection_with_concat
  296. assert_equal("Foo &amp; Bar", render('- concat "Foo & Bar"', :action_view))
  297. end
  298. def test_xss_protection_with_concat_with_safe_string
  299. assert_equal("Foo & Bar", render('- concat(Haml::Util.html_safe("Foo & Bar"))', :action_view))
  300. end
  301. if Haml::Util.has?(:instance_method, ActionView::Helpers::TextHelper, :safe_concat)
  302. def test_xss_protection_with_safe_concat
  303. assert_equal("Foo & Bar", render('- safe_concat "Foo & Bar"', :action_view))
  304. end
  305. end
  306. ## Regression
  307. def test_xss_protection_with_nested_haml_tag
  308. assert_equal(<<HTML, render(<<HAML, :action_view))
  309. <div>
  310. <ul>
  311. <li>Content!</li>
  312. </ul>
  313. </div>
  314. HTML
  315. - haml_tag :div do
  316. - haml_tag :ul do
  317. - haml_tag :li, "Content!"
  318. HAML
  319. end
  320. def test_xss_protection_with_form_for
  321. assert_equal(<<HTML, render(<<HAML, :action_view))
  322. <form action="" method="post">
  323. Title:
  324. <input id="article_title" name="article[title]" size="30" type="text" value="Hello" />
  325. Body:
  326. <input id="article_body" name="article[body]" size="30" type="text" value="World" />
  327. </form>
  328. HTML
  329. #{rails_block_helper_char} form_for #{form_for_calling_convention(:article)}, :url => '' do |f|
  330. Title:
  331. = f.text_field :title
  332. Body:
  333. = f.text_field :body
  334. HAML
  335. end
  336. def test_rjs
  337. assert_equal(<<HTML, render(<<HAML, :action_view))
  338. window.location.reload();
  339. HTML
  340. = update_page do |p|
  341. - p.reload
  342. HAML
  343. end
  344. def test_cache
  345. @base.controller = ActionController::Base.new
  346. @base.controller.perform_caching = false
  347. assert_equal(<<HTML, render(<<HAML, :action_view))
  348. Test
  349. HTML
  350. - cache do
  351. Test
  352. HAML
  353. end
  354. end
  355. end