haml 4.0.7 → 5.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (124) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/test.yml +36 -0
  3. data/.gitignore +19 -0
  4. data/.gitmodules +3 -0
  5. data/.yardopts +2 -3
  6. data/CHANGELOG.md +146 -4
  7. data/FAQ.md +4 -14
  8. data/Gemfile +16 -0
  9. data/MIT-LICENSE +2 -2
  10. data/README.md +90 -47
  11. data/REFERENCE.md +160 -74
  12. data/Rakefile +44 -63
  13. data/TODO +24 -0
  14. data/benchmark.rb +70 -0
  15. data/haml.gemspec +45 -0
  16. data/lib/haml/.gitattributes +1 -0
  17. data/lib/haml/attribute_builder.rb +219 -0
  18. data/lib/haml/attribute_compiler.rb +237 -0
  19. data/lib/haml/attribute_parser.rb +150 -0
  20. data/lib/haml/buffer.rb +12 -175
  21. data/lib/haml/compiler.rb +110 -320
  22. data/lib/haml/engine.rb +34 -41
  23. data/lib/haml/error.rb +28 -24
  24. data/lib/haml/escapable.rb +77 -0
  25. data/lib/haml/exec.rb +38 -20
  26. data/lib/haml/filters.rb +22 -27
  27. data/lib/haml/generator.rb +42 -0
  28. data/lib/haml/helpers/action_view_extensions.rb +4 -2
  29. data/lib/haml/helpers/action_view_mods.rb +45 -60
  30. data/lib/haml/helpers/action_view_xss_mods.rb +2 -0
  31. data/lib/haml/helpers/safe_erubi_template.rb +20 -0
  32. data/lib/haml/helpers/safe_erubis_template.rb +5 -1
  33. data/lib/haml/helpers/xss_mods.rb +23 -13
  34. data/lib/haml/helpers.rb +134 -89
  35. data/lib/haml/options.rb +63 -69
  36. data/lib/haml/parser.rb +319 -227
  37. data/lib/haml/plugin.rb +54 -0
  38. data/lib/haml/railtie.rb +43 -12
  39. data/lib/haml/sass_rails_filter.rb +18 -4
  40. data/lib/haml/template/options.rb +13 -2
  41. data/lib/haml/template.rb +13 -6
  42. data/lib/haml/temple_engine.rb +124 -0
  43. data/lib/haml/temple_line_counter.rb +30 -0
  44. data/lib/haml/util.rb +83 -202
  45. data/lib/haml/version.rb +3 -1
  46. data/lib/haml.rb +2 -0
  47. data/yard/default/.gitignore +1 -0
  48. data/yard/default/fulldoc/html/css/common.sass +15 -0
  49. data/yard/default/layout/html/footer.erb +12 -0
  50. metadata +73 -115
  51. data/lib/haml/template/plugin.rb +0 -41
  52. data/test/engine_test.rb +0 -2013
  53. data/test/erb/_av_partial_1.erb +0 -12
  54. data/test/erb/_av_partial_2.erb +0 -8
  55. data/test/erb/action_view.erb +0 -62
  56. data/test/erb/standard.erb +0 -55
  57. data/test/filters_test.rb +0 -254
  58. data/test/gemfiles/Gemfile.rails-3.0.x +0 -5
  59. data/test/gemfiles/Gemfile.rails-3.1.x +0 -6
  60. data/test/gemfiles/Gemfile.rails-3.2.x +0 -5
  61. data/test/gemfiles/Gemfile.rails-4.0.x +0 -5
  62. data/test/haml-spec/LICENSE +0 -14
  63. data/test/haml-spec/README.md +0 -106
  64. data/test/haml-spec/lua_haml_spec.lua +0 -38
  65. data/test/haml-spec/perl_haml_test.pl +0 -81
  66. data/test/haml-spec/ruby_haml_test.rb +0 -23
  67. data/test/haml-spec/tests.json +0 -660
  68. data/test/helper_test.rb +0 -583
  69. data/test/markaby/standard.mab +0 -52
  70. data/test/mocks/article.rb +0 -6
  71. data/test/parser_test.rb +0 -105
  72. data/test/results/content_for_layout.xhtml +0 -12
  73. data/test/results/eval_suppressed.xhtml +0 -9
  74. data/test/results/helpers.xhtml +0 -70
  75. data/test/results/helpful.xhtml +0 -10
  76. data/test/results/just_stuff.xhtml +0 -70
  77. data/test/results/list.xhtml +0 -12
  78. data/test/results/nuke_inner_whitespace.xhtml +0 -40
  79. data/test/results/nuke_outer_whitespace.xhtml +0 -148
  80. data/test/results/original_engine.xhtml +0 -20
  81. data/test/results/partial_layout.xhtml +0 -5
  82. data/test/results/partial_layout_erb.xhtml +0 -5
  83. data/test/results/partials.xhtml +0 -21
  84. data/test/results/render_layout.xhtml +0 -3
  85. data/test/results/silent_script.xhtml +0 -74
  86. data/test/results/standard.xhtml +0 -162
  87. data/test/results/tag_parsing.xhtml +0 -23
  88. data/test/results/very_basic.xhtml +0 -5
  89. data/test/results/whitespace_handling.xhtml +0 -90
  90. data/test/template_test.rb +0 -354
  91. data/test/templates/_av_partial_1.haml +0 -9
  92. data/test/templates/_av_partial_1_ugly.haml +0 -9
  93. data/test/templates/_av_partial_2.haml +0 -5
  94. data/test/templates/_av_partial_2_ugly.haml +0 -5
  95. data/test/templates/_layout.erb +0 -3
  96. data/test/templates/_layout_for_partial.haml +0 -3
  97. data/test/templates/_partial.haml +0 -8
  98. data/test/templates/_text_area.haml +0 -3
  99. data/test/templates/_text_area_helper.html.haml +0 -4
  100. data/test/templates/action_view.haml +0 -47
  101. data/test/templates/action_view_ugly.haml +0 -47
  102. data/test/templates/breakage.haml +0 -8
  103. data/test/templates/content_for_layout.haml +0 -8
  104. data/test/templates/eval_suppressed.haml +0 -11
  105. data/test/templates/helpers.haml +0 -55
  106. data/test/templates/helpful.haml +0 -11
  107. data/test/templates/just_stuff.haml +0 -85
  108. data/test/templates/list.haml +0 -12
  109. data/test/templates/nuke_inner_whitespace.haml +0 -32
  110. data/test/templates/nuke_outer_whitespace.haml +0 -144
  111. data/test/templates/original_engine.haml +0 -17
  112. data/test/templates/partial_layout.haml +0 -3
  113. data/test/templates/partial_layout_erb.erb +0 -4
  114. data/test/templates/partialize.haml +0 -1
  115. data/test/templates/partials.haml +0 -12
  116. data/test/templates/render_layout.haml +0 -2
  117. data/test/templates/silent_script.haml +0 -45
  118. data/test/templates/standard.haml +0 -43
  119. data/test/templates/standard_ugly.haml +0 -43
  120. data/test/templates/tag_parsing.haml +0 -21
  121. data/test/templates/very_basic.haml +0 -4
  122. data/test/templates/whitespace_handling.haml +0 -87
  123. data/test/test_helper.rb +0 -81
  124. data/test/util_test.rb +0 -63
@@ -1,162 +0,0 @@
1
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2
- <html lang='en-US' xml:lang='en-US' xmlns='http://www.w3.org/1999/xhtml'>
3
- <head>
4
- <title>Hampton Catlin Is Totally Awesome</title>
5
- <meta content='text/html; charset=utf-8' http-equiv='Content-Type' />
6
- </head>
7
- <body>
8
- <!-- You're In my house now! -->
9
- <div class='header'>
10
- Yes, ladies and gentileman. He is just that egotistical.
11
- Fantastic! This should be multi-line output
12
- The question is if this would translate! Ahah!
13
- 20
14
- </div>
15
- <div id='body'> Quotes should be loved! Just like people!</div>
16
- 0
17
- 1
18
- 2
19
- 3
20
- 4
21
- 5
22
- 6
23
- 7
24
- 8
25
- 9
26
- 10
27
- 11
28
- 12
29
- 13
30
- 14
31
- 15
32
- 16
33
- 17
34
- 18
35
- 19
36
- 20
37
- 21
38
- 22
39
- 23
40
- 24
41
- 25
42
- 26
43
- 27
44
- 28
45
- 29
46
- 30
47
- 31
48
- 32
49
- 33
50
- 34
51
- 35
52
- 36
53
- 37
54
- 38
55
- 39
56
- 40
57
- 41
58
- 42
59
- 43
60
- 44
61
- 45
62
- 46
63
- 47
64
- 48
65
- 49
66
- 50
67
- 51
68
- 52
69
- 53
70
- 54
71
- 55
72
- 56
73
- 57
74
- 58
75
- 59
76
- 60
77
- 61
78
- 62
79
- 63
80
- 64
81
- 65
82
- 66
83
- 67
84
- 68
85
- 69
86
- 70
87
- 71
88
- 72
89
- 73
90
- 74
91
- 75
92
- 76
93
- 77
94
- 78
95
- 79
96
- 80
97
- 81
98
- 82
99
- 83
100
- 84
101
- 85
102
- 86
103
- 87
104
- 88
105
- 89
106
- 90
107
- 91
108
- 92
109
- 93
110
- 94
111
- 95
112
- 96
113
- 97
114
- 98
115
- 99
116
- 100
117
- 101
118
- 102
119
- 103
120
- 104
121
- 105
122
- 106
123
- 107
124
- 108
125
- 109
126
- 110
127
- 111
128
- 112
129
- 113
130
- 114
131
- 115
132
- 116
133
- 117
134
- 118
135
- 119
136
- Wow.|
137
- <p code='3'>
138
- Holy cow multiline tags! A pipe (|) even!
139
- PipesIgnored|PipesIgnored|PipesIgnored|
140
- 1|2|3
141
- </p>
142
- <div class='silent' foo='17'>
143
- this shouldn't evaluate but now it should!
144
- </div>
145
- <ul class='really cool'>
146
- <li>a</li>
147
- <li>b</li>
148
- <li>c</li>
149
- <li>d</li>
150
- <li>e</li>
151
- <li>f</li>
152
- </ul>
153
- <div class='of_divs_with_underscore' id='combo'>with this text</div>
154
- foo
155
- <div class='footer'>
156
- <strong class='shout'>
157
- This is a really long ruby quote. It should be loved and wrapped because its more than 50 characters. This value may change in the future and this test may look stupid.
158
- So, I'm just making it *really* long. God, I hope this works
159
- </strong>
160
- </div>
161
- </body>
162
- </html>
@@ -1,23 +0,0 @@
1
- <div class='tags'>
2
- <foo>1</foo>
3
- <FOO>2</FOO>
4
- <fooBAR>3</fooBAR>
5
- <fooBar>4</fooBar>
6
- <foo_bar>5</foo_bar>
7
- <foo-bar>6</foo-bar>
8
- <foo:bar>7</foo:bar>
9
- <foo class='bar'>8</foo>
10
- <fooBAr_baz:boom_bar>9</fooBAr_baz:boom_bar>
11
- <foo13>10</foo13>
12
- <foo2u>11</foo2u>
13
- </div>
14
- <div class='classes'>
15
- <p class='foo bar' id='boom'></p>
16
- <div class='fooBar'>a</div>
17
- <div class='foo-bar'>b</div>
18
- <div class='foo_bar'>c</div>
19
- <div class='FOOBAR'>d</div>
20
- <div class='foo16'>e</div>
21
- <div class='123'>f</div>
22
- <div class='foo2u'>g</div>
23
- </div>
@@ -1,5 +0,0 @@
1
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2
- <html>
3
- <head></head>
4
- <body></body>
5
- </html>
@@ -1,90 +0,0 @@
1
- <div id='whitespace_test'>
2
- <div class='text_area_test_area'>
3
- <textarea>Oneline</textarea>
4
- </div>
5
- <textarea>BLAH
6
- </textarea>
7
- <div class='text_area_test_area'>
8
- <textarea>Two&#x000A;lines</textarea>
9
- </div>
10
- <textarea>BLAH
11
- </textarea>
12
- <div class='text_area_test_area'>
13
- <textarea>Oneline</textarea>
14
- </div>
15
- <textarea>BLAH</textarea>
16
- <div class='text_area_test_area'>
17
- <textarea>Two&#x000A;lines</textarea>
18
- </div>
19
- <textarea>BLAH</textarea>
20
- <div id='flattened'>
21
- <div class='text_area_test_area'>
22
- <textarea>Two&#x000A;lines</textarea>
23
- </div>
24
- <textarea>BLAH</textarea>
25
- </div>
26
- </div>
27
- <div class='hithere'>
28
- Foo bar
29
- <pre>foo bar</pre>
30
- <pre>foo&#x000A;bar</pre>
31
- <p><pre>foo&#x000A;bar</pre></p>
32
- <p>
33
- foo
34
- bar
35
- </p>
36
- </div>
37
- <div class='foo'>
38
- 13
39
- <textarea>
40
- a
41
- </textarea>
42
- <textarea>
43
- a</textarea>
44
- </div>
45
- <div id='whitespace_test'>
46
- <div class='text_area_test_area'>
47
- <textarea>Oneline</textarea>
48
- </div>
49
- <textarea>BLAH
50
- </textarea>
51
- <div class='text_area_test_area'>
52
- <textarea>Two&#x000A;lines</textarea>
53
- </div>
54
- <textarea>BLAH
55
- </textarea>
56
- <div class='text_area_test_area'>
57
- <textarea>Oneline</textarea>
58
- </div>
59
- <textarea>BLAH</textarea>
60
- <div class='text_area_test_area'>
61
- <textarea>Two&#x000A;lines</textarea>
62
- </div>
63
- <textarea>BLAH</textarea>
64
- <div id='flattened'>
65
- <div class='text_area_test_area'>
66
- <textarea>Two&#x000A;lines</textarea>
67
- </div>
68
- <textarea>BLAH</textarea>
69
- </div>
70
- </div>
71
- <div class='hithere'>
72
- Foo bar
73
- <pre>foo bar</pre>
74
- <pre>foo&#x000A;bar</pre>
75
- <p><pre>foo&#x000A;bar</pre></p>
76
- <p>
77
- foo
78
- bar
79
- </p>
80
- <pre> ___&#x000A; ,o88888&#x000A; ,o8888888'&#x000A; ,:o:o:oooo. ,8O88Pd8888"&#x000A; ,.::.::o:ooooOoOoO. ,oO8O8Pd888'"&#x000A; ,.:.::o:ooOoOoOO8O8OOo.8OOPd8O8O"&#x000A; , ..:.::o:ooOoOOOO8OOOOo.FdO8O8"&#x000A; , ..:.::o:ooOoOO8O888O8O,COCOO"&#x000A; , . ..:.::o:ooOoOOOO8OOOOCOCO"&#x000A; . ..:.::o:ooOoOoOO8O8OCCCC"o&#x000A; . ..:.::o:ooooOoCoCCC"o:o&#x000A; . ..:.::o:o:,cooooCo"oo:o:&#x000A; ` . . ..:.:cocoooo"'o:o:::'&#x000A; .` . ..::ccccoc"'o:o:o:::'&#x000A; :.:. ,c:cccc"':.:.:.:.:.'&#x000A; ..:.:"'`::::c:"'..:.:.:.:.:.' http://www.chris.com/ASCII/&#x000A; ...:.'.:.::::"' . . . . .'&#x000A; .. . ....:."' ` . . . ''&#x000A; . . . ...."'&#x000A; .. . ."' -hrr-&#x000A; .&#x000A;&#x000A;&#x000A; It's a planet!&#x000A;%strong This shouldn't be bold!</pre>
81
- <strong>This should!</strong>
82
- <textarea> ___ ___ ___ ___ &#x000A; /\__\ /\ \ /\__\ /\__\&#x000A; /:/ / /::\ \ /::| | /:/ /&#x000A; /:/__/ /:/\:\ \ /:|:| | /:/ / &#x000A; /::\ \ ___ /::\~\:\ \ /:/|:|__|__ /:/ / &#x000A; /:/\:\ /\__\ /:/\:\ \:\__\ /:/ |::::\__\ /:/__/ &#x000A; \/__\:\/:/ / \/__\:\/:/ / \/__/~~/:/ / \:\ \ &#x000A; \::/ / \::/ / /:/ / \:\ \ &#x000A; /:/ / /:/ / /:/ / \:\ \ &#x000A; /:/ / /:/ / /:/ / \:\__\&#x000A; \/__/ \/__/ \/__/ \/__/&#x000A; &#x000A; Many&#x000A; thanks&#x000A; to&#x000A; http://www.network-science.de/ascii/
83
- <strong>indeed!</strong></textarea>
84
- </div>
85
- <div class='foo'>
86
- 13
87
- </div>
88
- <pre> __ ______ __ ______&#x000A;.----.| |--.|__ |.----.| |--..--------.| __ |&#x000A;| __|| ||__ || __|| < | || __ |&#x000A;|____||__|__||______||____||__|__||__|__|__||______|</pre>
89
- <pre>foo
90
- bar</pre>
@@ -1,354 +0,0 @@
1
- require 'test_helper'
2
- require 'mocks/article'
3
-
4
- require 'action_pack/version'
5
-
6
- module Haml::Filters::Test
7
- include Haml::Filters::Base
8
-
9
- def render(text)
10
- "TESTING HAHAHAHA!"
11
- end
12
- end
13
-
14
- module Haml::Helpers
15
- def test_partial(name, locals = {})
16
- Haml::Engine.new(File.read(File.join(TemplateTest::TEMPLATE_PATH, "_#{name}.haml"))).render(self, locals)
17
- end
18
- end
19
-
20
- class Egocentic
21
- def method_missing(*args)
22
- self
23
- end
24
- end
25
-
26
- class DummyController
27
- attr_accessor :logger
28
- def initialize
29
- @logger = Egocentic.new
30
- end
31
-
32
- def self.controller_path
33
- ''
34
- end
35
-
36
- def controller_path
37
- ''
38
- end
39
- end
40
-
41
- class TemplateTest < MiniTest::Unit::TestCase
42
- TEMPLATE_PATH = File.join(File.dirname(__FILE__), "templates")
43
- TEMPLATES = %w{ very_basic standard helpers
44
- whitespace_handling original_engine list helpful
45
- silent_script tag_parsing just_stuff partials
46
- nuke_outer_whitespace nuke_inner_whitespace
47
- render_layout partial_layout partial_layout_erb}
48
-
49
- def setup
50
- @base = create_base
51
-
52
- # filters template uses :sass
53
- # Sass::Plugin.options.update(:line_comments => true, :style => :compact)
54
- end
55
-
56
- def create_base
57
- vars = { 'article' => Article.new, 'foo' => 'value one' }
58
-
59
- base = ActionView::Base.new(TEMPLATE_PATH, vars)
60
-
61
- # This is needed by RJS in (at least) Rails 3
62
- base.instance_variable_set('@template', base)
63
-
64
- # This is used by form_for.
65
- # It's usually provided by ActionController::Base.
66
- def base.protect_against_forgery?; false; end
67
-
68
- base
69
- end
70
-
71
- def render(text, options = {})
72
- return @base.render(:inline => text, :type => :haml) if options == :action_view
73
- options = options.merge(:format => :xhtml)
74
- super(text, options, @base)
75
- end
76
-
77
- def load_result(name)
78
- @result = ''
79
- File.new(File.dirname(__FILE__) + "/results/#{name}.xhtml").each_line { |l| @result += l }
80
- @result
81
- end
82
-
83
- def assert_renders_correctly(name, &render_method)
84
- old_options = Haml::Template.options.dup
85
- Haml::Template.options[:escape_html] = false
86
- if ActionPack::VERSION::MAJOR < 2 ||
87
- (ActionPack::VERSION::MAJOR == 2 && ActionPack::VERSION::MINOR < 2)
88
- render_method ||= proc { |n| @base.render(n) }
89
- else
90
- render_method ||= proc { |n| @base.render(:file => n) }
91
- end
92
-
93
- silence_warnings do
94
- load_result(name).split("\n").zip(render_method[name].split("\n")).each_with_index do |pair, line|
95
- message = "template: #{name}\nline: #{line}"
96
- assert_equal(pair.first, pair.last, message)
97
- end
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
-
109
- def test_empty_render_should_remain_empty
110
- assert_equal('', render(''))
111
- end
112
-
113
- TEMPLATES.each do |template|
114
- define_method "test_template_should_render_correctly [template: #{template}]" do
115
- assert_renders_correctly template
116
- end
117
- end
118
-
119
- def test_render_method_returning_null_with_ugly
120
- @base.instance_eval do
121
- def empty
122
- nil
123
- end
124
- def render_something(&block)
125
- capture(self, &block)
126
- end
127
- end
128
-
129
- content_to_render = "%h1 This is part of the broken view.\n= render_something do |thing|\n = thing.empty do\n = 'test'"
130
- result = render(content_to_render, :ugly => true)
131
- expected_result = "<h1>This is part of the broken view.</h1>\n"
132
- assert_equal(expected_result, result)
133
- end
134
-
135
- def test_simple_rendering_with_ugly
136
- content_to_render = "%p test\n= capture { 'foo' }"
137
- result = render(content_to_render, :ugly => true)
138
- expected_result = "<p>test</p>\nfoo\n"
139
- assert_equal(expected_result, result)
140
- end
141
-
142
- def test_templates_should_render_correctly_with_render_proc
143
- assert_renders_correctly("standard") do |name|
144
- engine = Haml::Engine.new(File.read(File.dirname(__FILE__) + "/templates/#{name}.haml"), :format => :xhtml)
145
- engine.render_proc(@base).call
146
- end
147
- end
148
-
149
- def test_templates_should_render_correctly_with_def_method
150
- assert_renders_correctly("standard") do |name|
151
- engine = Haml::Engine.new(File.read(File.dirname(__FILE__) + "/templates/#{name}.haml"), :format => :xhtml)
152
- engine.def_method(@base, "render_standard")
153
- @base.render_standard
154
- end
155
- end
156
-
157
- def test_instance_variables_should_work_inside_templates
158
- @base.instance_variable_set("@content_for_layout", 'something')
159
- assert_equal("<p>something</p>", render("%p= @content_for_layout").chomp)
160
-
161
- @base.instance_eval("@author = 'Hampton Catlin'")
162
- assert_equal("<div class='author'>Hampton Catlin</div>", render(".author= @author").chomp)
163
-
164
- @base.instance_eval("@author = 'Hampton'")
165
- assert_equal("Hampton", render("= @author").chomp)
166
-
167
- @base.instance_eval("@author = 'Catlin'")
168
- assert_equal("Catlin", render("= @author").chomp)
169
- end
170
-
171
- def test_instance_variables_should_work_inside_attributes
172
- @base.instance_eval("@author = 'hcatlin'")
173
- assert_equal("<p class='hcatlin'>foo</p>", render("%p{:class => @author} foo").chomp)
174
- end
175
-
176
- def test_template_renders_should_eval
177
- assert_equal("2\n", render("= 1+1"))
178
- end
179
-
180
- def test_haml_options
181
- old_options = Haml::Template.options.dup
182
- Haml::Template.options[:suppress_eval] = true
183
- old_base, @base = @base, create_base
184
- assert_renders_correctly("eval_suppressed")
185
- ensure
186
- @base = old_base
187
- Haml::Template.options = old_options
188
- end
189
-
190
- def test_with_output_buffer_with_ugly
191
- assert_equal(<<HTML, render(<<HAML, :ugly => true))
192
- <p>
193
- foo
194
- baz
195
- </p>
196
- HTML
197
- %p
198
- foo
199
- -# Parenthesis required due to Rails 3.0 deprecation of block helpers
200
- -# that return strings.
201
- - (with_output_buffer do
202
- bar
203
- = "foo".gsub(/./) do |s|
204
- - "flup"
205
- - end)
206
- baz
207
- HAML
208
- end
209
-
210
- def test_exceptions_should_work_correctly
211
- begin
212
- render("- raise 'oops!'")
213
- rescue Exception => e
214
- assert_equal("oops!", e.message)
215
- assert_match(/^\(haml\):1/, e.backtrace[0])
216
- else
217
- assert false
218
- end
219
-
220
- template = <<END
221
- %p
222
- %h1 Hello!
223
- = "lots of lines"
224
- = "even more!"
225
- - raise 'oh no!'
226
- %p
227
- this is after the exception
228
- %strong yes it is!
229
- ho ho ho.
230
- END
231
-
232
- begin
233
- render(template.chomp)
234
- rescue Exception => e
235
- assert_match(/^\(haml\):5/, e.backtrace[0])
236
- else
237
- assert false
238
- end
239
- end
240
-
241
- def test_form_builder_label_with_block
242
- output = render(<<HAML, :action_view)
243
- = form_for @article, :as => :article, :html => {:class => nil, :id => nil}, :url => '' do |f|
244
- = f.label :title do
245
- Block content
246
- HAML
247
- fragment = Nokogiri::HTML.fragment output
248
- assert_equal "Block content", fragment.css('form label').first.content.strip
249
- end
250
-
251
- ## XSS Protection Tests
252
-
253
- def test_escape_html_option_set
254
- assert Haml::Template.options[:escape_html]
255
- end
256
-
257
- def test_xss_protection
258
- assert_equal("Foo &amp; Bar\n", render('= "Foo & Bar"', :action_view))
259
- end
260
-
261
- def test_xss_protection_with_safe_strings
262
- assert_equal("Foo & Bar\n", render('= Haml::Util.html_safe("Foo & Bar")', :action_view))
263
- end
264
-
265
- def test_xss_protection_with_bang
266
- assert_equal("Foo & Bar\n", render('!= "Foo & Bar"', :action_view))
267
- end
268
-
269
- def test_xss_protection_in_interpolation
270
- assert_equal("Foo &amp; Bar\n", render('Foo #{"&"} Bar', :action_view))
271
- end
272
-
273
- def test_xss_protection_in_attributes
274
- assert_equal("<div data-html='&lt;foo&gt;bar&lt;/foo&gt;'></div>\n", render('%div{ "data-html" => "<foo>bar</foo>" }', :action_view))
275
- end
276
-
277
- def test_xss_protection_in_attributes_with_safe_strings
278
- assert_equal("<div data-html='<foo>bar</foo>'></div>\n", render('%div{ "data-html" => "<foo>bar</foo>".html_safe }', :action_view))
279
- end
280
-
281
- def test_xss_protection_with_bang_in_interpolation
282
- assert_equal("Foo & Bar\n", render('! Foo #{"&"} Bar', :action_view))
283
- end
284
-
285
- def test_xss_protection_with_safe_strings_in_interpolation
286
- assert_equal("Foo & Bar\n", render('Foo #{Haml::Util.html_safe("&")} Bar', :action_view))
287
- end
288
-
289
- def test_xss_protection_with_mixed_strings_in_interpolation
290
- assert_equal("Foo & Bar &amp; Baz\n", render('Foo #{Haml::Util.html_safe("&")} Bar #{"&"} Baz', :action_view))
291
- end
292
-
293
- def test_rendered_string_is_html_safe
294
- assert(render("Foo").html_safe?)
295
- end
296
-
297
- def test_rendered_string_is_html_safe_with_action_view
298
- assert(render("Foo", :action_view).html_safe?)
299
- end
300
-
301
- def test_xss_html_escaping_with_non_strings
302
- assert_equal("4\n", render("= html_escape(4)"))
303
- end
304
-
305
- def test_xss_protection_with_concat
306
- assert_equal("Foo &amp; Bar", render('- concat "Foo & Bar"', :action_view))
307
- end
308
-
309
- def test_xss_protection_with_concat_with_safe_string
310
- assert_equal("Foo & Bar", render('- concat(Haml::Util.html_safe("Foo & Bar"))', :action_view))
311
- end
312
-
313
- def test_xss_protection_with_safe_concat
314
- assert_equal("Foo & Bar", render('- safe_concat "Foo & Bar"', :action_view))
315
- end
316
-
317
- ## Regression
318
-
319
- def test_xss_protection_with_nested_haml_tag
320
- assert_equal(<<HTML, render(<<HAML, :action_view))
321
- <div>
322
- <ul>
323
- <li>Content!</li>
324
- </ul>
325
- </div>
326
- HTML
327
- - haml_tag :div do
328
- - haml_tag :ul do
329
- - haml_tag :li, "Content!"
330
- HAML
331
- end
332
-
333
- if defined?(ActionView::Helpers::PrototypeHelper)
334
- def test_rjs
335
- assert_equal(<<HTML, render(<<HAML, :action_view))
336
- window.location.reload();
337
- HTML
338
- = update_page do |p|
339
- - p.reload
340
- HAML
341
- end
342
- end
343
-
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
@@ -1,9 +0,0 @@
1
- %h2 This is a pretty complicated partial
2
- .partial
3
- %p It has several nested partials,
4
- %ul
5
- - 5.times do
6
- %li
7
- %strong Partial:
8
- - @nesting = 5
9
- = render :partial => 'templates/av_partial_2'
@@ -1,9 +0,0 @@
1
- %h2 This is a pretty complicated partial
2
- .partial
3
- %p It has several nested partials,
4
- %ul
5
- - 5.times do
6
- %li
7
- %strong Partial:
8
- - @nesting = 5
9
- = render :partial => 'templates/av_partial_2_ugly'
@@ -1,5 +0,0 @@
1
- - @nesting -= 1
2
- .partial{:level => @nesting}
3
- %h3 This is a crazy deep-nested partial.
4
- %p== Nesting level #{@nesting}
5
- = render :partial => 'templates/av_partial_2' if @nesting > 0
@@ -1,5 +0,0 @@
1
- - @nesting -= 1
2
- .partial{:level => @nesting}
3
- %h3 This is a crazy deep-nested partial.
4
- %p== Nesting level #{@nesting}
5
- = render :partial => 'templates/av_partial_2_ugly' if @nesting > 0
@@ -1,3 +0,0 @@
1
- Before
2
- <%= yield -%>
3
- After
@@ -1,3 +0,0 @@
1
- .partial-layout
2
- %h2 This is inside a partial layout
3
- = yield
@@ -1,8 +0,0 @@
1
- %p
2
- @foo =
3
- = @foo
4
- - @foo = 'value three'
5
- == Toplevel? #{haml_buffer.toplevel?}
6
- %p
7
- @foo =
8
- = @foo
@@ -1,3 +0,0 @@
1
- .text_area_test_area
2
- ~ "<textarea>" + value + "</textarea>"
3
- = "<textarea>BLAH\n</textarea>"