PageRenderTime 26ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/test/haml/helper_test.rb

https://github.com/BinaryMuse/haml
Ruby | 450 lines | 362 code | 77 blank | 11 comment | 6 complexity | b1248c30bce706af35d0146ac255b517 MD5 | raw file
  1. #!/usr/bin/env ruby
  2. require File.dirname(__FILE__) + '/../test_helper'
  3. class ActionView::Base
  4. def nested_tag
  5. content_tag(:span) {content_tag(:div) {"something"}}
  6. end
  7. def wacky_form
  8. form_tag("/foo") {"bar"}
  9. end
  10. end
  11. module Haml::Helpers
  12. def something_that_uses_haml_concat
  13. haml_concat('foo').to_s
  14. end
  15. end
  16. class HelperTest < Test::Unit::TestCase
  17. Post = Struct.new('Post', :body, :error_field, :errors)
  18. class PostErrors
  19. def on(name)
  20. return unless name == 'error_field'
  21. ["Really bad error"]
  22. end
  23. alias_method :full_messages, :on
  24. def [](name)
  25. on(name) || []
  26. end
  27. end
  28. def setup
  29. @base = ActionView::Base.new
  30. @base.controller = ActionController::Base.new
  31. if defined?(ActionController::Response)
  32. # This is needed for >=3.0.0
  33. @base.controller.response = ActionController::Response.new
  34. end
  35. @base.instance_variable_set('@post', Post.new("Foo bar\nbaz", nil, PostErrors.new))
  36. end
  37. def render(text, options = {})
  38. if options == :action_view
  39. @base.render :inline => text, :type => :haml
  40. else
  41. scope = options.delete :scope_object
  42. Haml::Engine.new(text, options).to_html(scope ? scope : Object.new)
  43. end
  44. end
  45. def test_flatten
  46. assert_equal("FooBar", Haml::Helpers.flatten("FooBar"))
  47. assert_equal("FooBar", Haml::Helpers.flatten("Foo\rBar"))
  48. assert_equal("Foo&#x000A;Bar", Haml::Helpers.flatten("Foo\nBar"))
  49. assert_equal("Hello&#x000A;World!&#x000A;YOU ARE FLAT?&#x000A;OMGZ!",
  50. Haml::Helpers.flatten("Hello\nWorld!\nYOU ARE \rFLAT?\n\rOMGZ!"))
  51. end
  52. def test_list_of_should_render_correctly
  53. assert_equal("<li>1</li>\n<li>2</li>\n", render("= list_of([1, 2]) do |i|\n = i"))
  54. assert_equal("<li>[1]</li>\n", render("= list_of([[1]]) do |i|\n = i.inspect"))
  55. assert_equal("<li>\n <h1>Fee</h1>\n <p>A word!</p>\n</li>\n<li>\n <h1>Fi</h1>\n <p>A word!</p>\n</li>\n<li>\n <h1>Fo</h1>\n <p>A word!</p>\n</li>\n<li>\n <h1>Fum</h1>\n <p>A word!</p>\n</li>\n",
  56. render("= list_of(['Fee', 'Fi', 'Fo', 'Fum']) do |title|\n %h1= title\n %p A word!"))
  57. end
  58. def test_buffer_access
  59. assert(render("= buffer") =~ /#<Haml::Buffer:0x[a-z0-9]+>/)
  60. assert_equal(render("= (buffer == _hamlout)"), "true\n")
  61. end
  62. def test_tabs
  63. assert_equal("foo\n bar\nbaz\n", render("foo\n- tab_up\nbar\n- tab_down\nbaz"))
  64. assert_equal(" <p>tabbed</p>\n", render("- buffer.tabulation=5\n%p tabbed"))
  65. end
  66. def test_with_tabs
  67. assert_equal(<<HTML, render(<<HAML))
  68. Foo
  69. Bar
  70. Baz
  71. Baz
  72. HTML
  73. Foo
  74. - with_tabs 2 do
  75. = "Bar\\nBaz"
  76. Baz
  77. HAML
  78. end
  79. def test_helpers_dont_leak
  80. # Haml helpers shouldn't be accessible from ERB
  81. render("foo")
  82. proper_behavior = false
  83. begin
  84. ActionView::Base.new.render(:inline => "<%= flatten('Foo\\nBar') %>")
  85. rescue NoMethodError, Haml::Util.av_template_class(:Error)
  86. proper_behavior = true
  87. end
  88. assert(proper_behavior)
  89. begin
  90. ActionView::Base.new.render(:inline => "<%= concat('foo') %>")
  91. rescue ArgumentError, NameError
  92. proper_behavior = true
  93. end
  94. assert(proper_behavior)
  95. end
  96. def test_action_view_included
  97. assert(Haml::Helpers.action_view?)
  98. end
  99. def test_form_tag
  100. # This is usually provided by ActionController::Base.
  101. def @base.protect_against_forgery?; false; end
  102. assert_equal(<<HTML, render(<<HAML, :action_view))
  103. <form #{rails_form_attr}action="foo" method="post">#{rails_form_opener}
  104. <p>bar</p>
  105. <strong>baz</strong>
  106. </form>
  107. HTML
  108. #{rails_block_helper_char} form_tag 'foo' do
  109. %p bar
  110. %strong baz
  111. HAML
  112. end
  113. def test_text_area
  114. assert_equal(%(<textarea id="body" name="body">Foo&#x000A;Bar&#x000A; Baz&#x000A; Boom</textarea>\n),
  115. render('= text_area_tag "body", "Foo\nBar\n Baz\n Boom"', :action_view))
  116. assert_equal(%(<textarea cols="40" id="post_body" name="post[body]" rows="20">Foo bar&#x000A;baz</textarea>\n),
  117. render('= text_area :post, :body', :action_view))
  118. assert_equal(%(<pre>Foo bar&#x000A; baz</pre>\n),
  119. render('= content_tag "pre", "Foo bar\n baz"', :action_view))
  120. end
  121. def test_capture_haml
  122. assert_equal(<<HTML, render(<<HAML))
  123. "<p>13</p>\\n"
  124. HTML
  125. - (foo = capture_haml(13) do |a|
  126. %p= a
  127. - end; nil)
  128. = foo.dump
  129. HAML
  130. end
  131. def test_content_tag_block
  132. assert_equal(<<HTML.strip, render(<<HAML, :action_view).strip)
  133. <div><p>bar</p>
  134. <strong>bar</strong>
  135. </div>
  136. HTML
  137. #{rails_block_helper_char} content_tag :div do
  138. %p bar
  139. %strong bar
  140. HAML
  141. end
  142. def test_content_tag_error_wrapping
  143. def @base.protect_against_forgery?; false; end
  144. error_class = Haml::Util.ap_geq_3? ? "field_with_errors" : "fieldWithErrors"
  145. assert_equal(<<HTML, render(<<HAML, :action_view))
  146. <form #{rails_form_attr}action="" method="post">#{rails_form_opener}
  147. <div class="#{error_class}"><label for="post_error_field">Error field</label></div>
  148. </form>
  149. HTML
  150. #{rails_block_helper_char} form_for #{form_for_calling_convention('post')}, :url => '' do |f|
  151. = f.label 'error_field'
  152. HAML
  153. end
  154. def test_form_tag_in_helper_with_string_block
  155. def @base.protect_against_forgery?; false; end
  156. assert_equal(<<HTML, render(<<HAML, :action_view))
  157. <form #{rails_form_attr}action="/foo" method="post">#{rails_form_opener}bar</form>
  158. HTML
  159. #{rails_block_helper_char} wacky_form
  160. HAML
  161. end
  162. def test_haml_tag_name_attribute_with_id
  163. assert_equal("<p id='some_id'></p>\n", render("- haml_tag 'p#some_id'"))
  164. end
  165. def test_haml_tag_name_attribute_with_colon_id
  166. assert_equal("<p id='some:id'></p>\n", render("- haml_tag 'p#some:id'"))
  167. end
  168. def test_haml_tag_without_name_but_with_id
  169. assert_equal("<div id='some_id'></div>\n", render("- haml_tag '#some_id'"))
  170. end
  171. def test_haml_tag_without_name_but_with_class
  172. assert_equal("<div class='foo'></div>\n", render("- haml_tag '.foo'"))
  173. end
  174. def test_haml_tag_without_name_but_with_colon_class
  175. assert_equal("<div class='foo:bar'></div>\n", render("- haml_tag '.foo:bar'"))
  176. end
  177. def test_haml_tag_name_with_id_and_class
  178. assert_equal("<p class='foo' id='some_id'></p>\n", render("- haml_tag 'p#some_id.foo'"))
  179. end
  180. def test_haml_tag_name_with_class
  181. assert_equal("<p class='foo'></p>\n", render("- haml_tag 'p.foo'"))
  182. end
  183. def test_haml_tag_name_with_class_and_id
  184. assert_equal("<p class='foo' id='some_id'></p>\n", render("- haml_tag 'p.foo#some_id'"))
  185. end
  186. def test_haml_tag_name_with_id_and_multiple_classes
  187. assert_equal("<p class='foo bar' id='some_id'></p>\n", render("- haml_tag 'p#some_id.foo.bar'"))
  188. end
  189. def test_haml_tag_name_with_multiple_classes_and_id
  190. assert_equal("<p class='foo bar' id='some_id'></p>\n", render("- haml_tag 'p.foo.bar#some_id'"))
  191. end
  192. def test_haml_tag_name_and_attribute_classes_merging
  193. assert_equal("<p class='foo bar' id='some_id'></p>\n", render("- haml_tag 'p#some_id.foo', :class => 'bar'"))
  194. end
  195. def test_haml_tag_name_and_attribute_classes_merging
  196. assert_equal("<p class='bar foo'></p>\n", render("- haml_tag 'p.foo', :class => 'bar'"))
  197. end
  198. def test_haml_tag_name_merges_id_and_attribute_id
  199. assert_equal("<p id='foo_bar'></p>\n", render("- haml_tag 'p#foo', :id => 'bar'"))
  200. end
  201. def test_haml_tag_attribute_html_escaping
  202. assert_equal("<p id='foo&amp;bar'>baz</p>\n", render("%p{:id => 'foo&bar'} baz", :escape_html => true))
  203. end
  204. def test_haml_tag_autoclosed_tags_are_closed
  205. assert_equal("<br class='foo' />\n", render("- haml_tag :br, :class => 'foo'"))
  206. end
  207. def test_haml_tag_with_class_array
  208. assert_equal("<p class='a b'>foo</p>\n", render("- haml_tag :p, 'foo', :class => %w[a b]"))
  209. assert_equal("<p class='a b c d'>foo</p>\n", render("- haml_tag 'p.c.d', 'foo', :class => %w[a b]"))
  210. end
  211. def test_haml_tag_with_id_array
  212. assert_equal("<p id='a_b'>foo</p>\n", render("- haml_tag :p, 'foo', :id => %w[a b]"))
  213. assert_equal("<p id='c_a_b'>foo</p>\n", render("- haml_tag 'p#c', 'foo', :id => %w[a b]"))
  214. end
  215. def test_haml_tag_with_data_hash
  216. assert_equal("<p data-baz='data-baz' data-foo='bar'>foo</p>\n",
  217. render("- haml_tag :p, 'foo', :data => {:foo => 'bar', :baz => true}"))
  218. end
  219. def test_haml_tag_non_autoclosed_tags_arent_closed
  220. assert_equal("<p></p>\n", render("- haml_tag :p"))
  221. end
  222. def test_haml_tag_renders_text_on_a_single_line
  223. assert_equal("<p>#{'a' * 100}</p>\n", render("- haml_tag :p, 'a' * 100"))
  224. end
  225. def test_haml_tag_raises_error_for_multiple_content
  226. assert_raise(Haml::Error) { render("- haml_tag :p, 'foo' do\n bar") }
  227. end
  228. def test_haml_tag_flags
  229. assert_equal("<p />\n", render("- haml_tag :p, :/"))
  230. assert_equal("<p>kumquat</p>\n", render("- haml_tag :p, :< do\n kumquat"))
  231. assert_raise(Haml::Error) { render("- haml_tag :p, 'foo', :/") }
  232. assert_raise(Haml::Error) { render("- haml_tag :p, :/ do\n foo") }
  233. end
  234. def test_haml_tag_error_return
  235. assert_raise(Haml::Error) { render("= haml_tag :p") }
  236. end
  237. def test_haml_tag_with_multiline_string
  238. assert_equal(<<HTML, render(<<HAML))
  239. <p>
  240. foo
  241. bar
  242. baz
  243. </p>
  244. HTML
  245. - haml_tag :p, "foo\\nbar\\nbaz"
  246. HAML
  247. end
  248. def test_haml_concat_with_multiline_string
  249. assert_equal(<<HTML, render(<<HAML))
  250. <p>
  251. foo
  252. bar
  253. baz
  254. </p>
  255. HTML
  256. %p
  257. - haml_concat "foo\\nbar\\nbaz"
  258. HAML
  259. end
  260. def test_haml_tag_with_ugly
  261. assert_equal(<<HTML, render(<<HAML, :ugly => true))
  262. <p>
  263. <strong>Hi!</strong>
  264. </p>
  265. HTML
  266. - haml_tag :p do
  267. - haml_tag :strong, "Hi!"
  268. HAML
  269. end
  270. def test_is_haml
  271. assert(!ActionView::Base.new.is_haml?)
  272. assert_equal("true\n", render("= is_haml?"))
  273. assert_equal("true\n", render("= is_haml?", :action_view))
  274. assert_equal("false", @base.render(:inline => '<%= is_haml? %>'))
  275. assert_equal("false\n", render("= render :inline => '<%= is_haml? %>'", :action_view))
  276. end
  277. def test_page_class
  278. controller = Struct.new(:controller_name, :action_name).new('troller', 'tion')
  279. scope = Struct.new(:controller).new(controller)
  280. result = render("%div{:class => page_class} MyDiv", :scope_object => scope)
  281. expected = "<div class='troller tion'>MyDiv</div>\n"
  282. assert_equal expected, result
  283. end
  284. def test_indented_capture
  285. prior = Haml::Util.ap_geq_3? ? "" : " \n"
  286. assert_equal("#{prior} Foo\n ", @base.render(:inline => " <% res = capture do %>\n Foo\n <% end %><%= res %>"))
  287. end
  288. def test_capture_deals_properly_with_collections
  289. Haml::Helpers.module_eval do
  290. def trc(collection, &block)
  291. collection.each do |record|
  292. haml_concat capture_haml(record, &block)
  293. end
  294. end
  295. end
  296. assert_equal("1\n\n2\n\n3\n\n", render("- trc([1, 2, 3]) do |i|\n = i.inspect"))
  297. end
  298. def test_find_and_preserve_with_block
  299. assert_equal("<pre>Foo&#x000A;Bar</pre>\nFoo\nBar\n",
  300. render("= find_and_preserve do\n %pre\n Foo\n Bar\n Foo\n Bar"))
  301. end
  302. def test_find_and_preserve_with_block_and_tags
  303. assert_equal("<pre>Foo\nBar</pre>\nFoo\nBar\n",
  304. render("= find_and_preserve([]) do\n %pre\n Foo\n Bar\n Foo\n Bar"))
  305. end
  306. def test_preserve_with_block
  307. assert_equal("<pre>Foo&#x000A;Bar</pre>&#x000A;Foo&#x000A;Bar\n",
  308. render("= preserve do\n %pre\n Foo\n Bar\n Foo\n Bar"))
  309. end
  310. def test_init_haml_helpers
  311. context = Object.new
  312. class << context
  313. include Haml::Helpers
  314. end
  315. context.init_haml_helpers
  316. result = context.capture_haml do
  317. context.haml_tag :p, :attr => "val" do
  318. context.haml_concat "Blah"
  319. end
  320. end
  321. assert_equal("<p attr='val'>\n Blah\n</p>\n", result)
  322. end
  323. def test_non_haml
  324. assert_equal("false\n", render("= non_haml { is_haml? }"))
  325. end
  326. def test_content_tag_nested
  327. assert_equal "<span><div>something</div></span>", render("= nested_tag", :action_view).strip
  328. end
  329. def test_error_return
  330. assert_raise(Haml::Error, <<MESSAGE) {render("= haml_concat 'foo'")}
  331. haml_concat outputs directly to the Haml template.
  332. Disregard its return value and use the - operator,
  333. or use capture_haml to get the value as a String.
  334. MESSAGE
  335. end
  336. def test_error_return_line
  337. render("%p foo\n= haml_concat 'foo'\n%p bar")
  338. assert false, "Expected Haml::Error"
  339. rescue Haml::Error => e
  340. assert_equal 2, e.backtrace[1].scan(/:(\d+)/).first.first.to_i
  341. end
  342. def test_error_return_line_in_helper
  343. render("- something_that_uses_haml_concat")
  344. assert false, "Expected Haml::Error"
  345. rescue Haml::Error => e
  346. assert_equal 16, e.backtrace[0].scan(/:(\d+)/).first.first.to_i
  347. end
  348. class ActsLikeTag
  349. # We want to be able to have people include monkeypatched ActionView helpers
  350. # without redefining is_haml?.
  351. # This is accomplished via Object#is_haml?, and this is a test for it.
  352. include ActionView::Helpers::TagHelper
  353. def to_s
  354. content_tag :p, 'some tag content'
  355. end
  356. end
  357. def test_random_class_includes_tag_helper
  358. assert_equal "<p>some tag content</p>", ActsLikeTag.new.to_s
  359. end
  360. def test_capture_with_nuke_outer
  361. assert_equal "<div></div>\n*<div>hi there!</div>\n", render(<<HAML)
  362. %div
  363. = precede("*") do
  364. %div> hi there!
  365. HAML
  366. assert_equal "<div></div>\n*<div>hi there!</div>\n", render(<<HAML)
  367. %div
  368. = precede("*") do
  369. = " "
  370. %div> hi there!
  371. HAML
  372. end
  373. end