haml 4.0.6 → 5.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.gitignore +19 -0
- data/.gitmodules +3 -0
- data/.travis.yml +72 -0
- data/.yardopts +2 -3
- data/CHANGELOG.md +138 -4
- data/FAQ.md +4 -14
- data/Gemfile +16 -0
- data/MIT-LICENSE +2 -2
- data/README.md +79 -42
- data/REFERENCE.md +142 -67
- data/Rakefile +44 -63
- data/TODO +24 -0
- data/benchmark.rb +70 -0
- data/haml.gemspec +45 -0
- data/lib/haml.rb +2 -0
- data/lib/haml/.gitattributes +1 -0
- data/lib/haml/attribute_builder.rb +164 -0
- data/lib/haml/attribute_compiler.rb +235 -0
- data/lib/haml/attribute_parser.rb +150 -0
- data/lib/haml/buffer.rb +29 -136
- data/lib/haml/compiler.rb +110 -320
- data/lib/haml/engine.rb +34 -41
- data/lib/haml/error.rb +28 -24
- data/lib/haml/escapable.rb +77 -0
- data/lib/haml/exec.rb +38 -20
- data/lib/haml/filters.rb +22 -27
- data/lib/haml/generator.rb +42 -0
- data/lib/haml/helpers.rb +134 -89
- data/lib/haml/helpers/action_view_extensions.rb +4 -2
- data/lib/haml/helpers/action_view_mods.rb +45 -60
- data/lib/haml/helpers/action_view_xss_mods.rb +2 -0
- data/lib/haml/helpers/safe_erubi_template.rb +20 -0
- data/lib/haml/helpers/safe_erubis_template.rb +5 -1
- data/lib/haml/helpers/xss_mods.rb +23 -13
- data/lib/haml/options.rb +63 -69
- data/lib/haml/parser.rb +292 -228
- data/lib/haml/plugin.rb +37 -0
- data/lib/haml/railtie.rb +38 -12
- data/lib/haml/sass_rails_filter.rb +18 -4
- data/lib/haml/template.rb +13 -6
- data/lib/haml/template/options.rb +13 -2
- data/lib/haml/temple_engine.rb +123 -0
- data/lib/haml/temple_line_counter.rb +30 -0
- data/lib/haml/util.rb +83 -202
- data/lib/haml/version.rb +3 -1
- data/yard/default/.gitignore +1 -0
- data/yard/default/fulldoc/html/css/common.sass +15 -0
- data/yard/default/layout/html/footer.erb +12 -0
- metadata +73 -108
- data/lib/haml/template/plugin.rb +0 -41
- data/test/engine_test.rb +0 -2013
- data/test/erb/_av_partial_1.erb +0 -12
- data/test/erb/_av_partial_2.erb +0 -8
- data/test/erb/action_view.erb +0 -62
- data/test/erb/standard.erb +0 -55
- data/test/filters_test.rb +0 -254
- data/test/gemfiles/Gemfile.rails-3.0.x +0 -5
- data/test/gemfiles/Gemfile.rails-3.1.x +0 -6
- data/test/gemfiles/Gemfile.rails-3.2.x +0 -5
- data/test/gemfiles/Gemfile.rails-4.0.x +0 -5
- data/test/helper_test.rb +0 -583
- data/test/markaby/standard.mab +0 -52
- data/test/mocks/article.rb +0 -6
- data/test/parser_test.rb +0 -105
- data/test/results/content_for_layout.xhtml +0 -12
- data/test/results/eval_suppressed.xhtml +0 -9
- data/test/results/helpers.xhtml +0 -70
- data/test/results/helpful.xhtml +0 -10
- data/test/results/just_stuff.xhtml +0 -70
- data/test/results/list.xhtml +0 -12
- data/test/results/nuke_inner_whitespace.xhtml +0 -40
- data/test/results/nuke_outer_whitespace.xhtml +0 -148
- data/test/results/original_engine.xhtml +0 -20
- data/test/results/partial_layout.xhtml +0 -5
- data/test/results/partial_layout_erb.xhtml +0 -5
- data/test/results/partials.xhtml +0 -21
- data/test/results/render_layout.xhtml +0 -3
- data/test/results/silent_script.xhtml +0 -74
- data/test/results/standard.xhtml +0 -162
- data/test/results/tag_parsing.xhtml +0 -23
- data/test/results/very_basic.xhtml +0 -5
- data/test/results/whitespace_handling.xhtml +0 -90
- data/test/template_test.rb +0 -354
- data/test/templates/_av_partial_1.haml +0 -9
- data/test/templates/_av_partial_1_ugly.haml +0 -9
- data/test/templates/_av_partial_2.haml +0 -5
- data/test/templates/_av_partial_2_ugly.haml +0 -5
- data/test/templates/_layout.erb +0 -3
- data/test/templates/_layout_for_partial.haml +0 -3
- data/test/templates/_partial.haml +0 -8
- data/test/templates/_text_area.haml +0 -3
- data/test/templates/_text_area_helper.html.haml +0 -4
- data/test/templates/action_view.haml +0 -47
- data/test/templates/action_view_ugly.haml +0 -47
- data/test/templates/breakage.haml +0 -8
- data/test/templates/content_for_layout.haml +0 -8
- data/test/templates/eval_suppressed.haml +0 -11
- data/test/templates/helpers.haml +0 -55
- data/test/templates/helpful.haml +0 -11
- data/test/templates/just_stuff.haml +0 -85
- data/test/templates/list.haml +0 -12
- data/test/templates/nuke_inner_whitespace.haml +0 -32
- data/test/templates/nuke_outer_whitespace.haml +0 -144
- data/test/templates/original_engine.haml +0 -17
- data/test/templates/partial_layout.haml +0 -3
- data/test/templates/partial_layout_erb.erb +0 -4
- data/test/templates/partialize.haml +0 -1
- data/test/templates/partials.haml +0 -12
- data/test/templates/render_layout.haml +0 -2
- data/test/templates/silent_script.haml +0 -45
- data/test/templates/standard.haml +0 -43
- data/test/templates/standard_ugly.haml +0 -43
- data/test/templates/tag_parsing.haml +0 -21
- data/test/templates/very_basic.haml +0 -4
- data/test/templates/whitespace_handling.haml +0 -87
- data/test/test_helper.rb +0 -81
- data/test/util_test.rb +0 -63
|
@@ -1,20 +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>
|
|
4
|
-
<title>Stop. haml time</title>
|
|
5
|
-
<div id='content'>
|
|
6
|
-
<h1>This is a title!</h1>
|
|
7
|
-
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit</p>
|
|
8
|
-
<p class='foo'>Cigarettes!</p>
|
|
9
|
-
<h2>Man alive!</h2>
|
|
10
|
-
<ul class='things'>
|
|
11
|
-
<li>Slippers</li>
|
|
12
|
-
<li>Shoes</li>
|
|
13
|
-
<li>Bathrobe</li>
|
|
14
|
-
<li>Coffee</li>
|
|
15
|
-
</ul>
|
|
16
|
-
<pre>This is some text that's in a pre block!
|
|
17
|
-
Let's see what happens when it's rendered! What about now, since we're on a new line?</pre>
|
|
18
|
-
</div>
|
|
19
|
-
</head>
|
|
20
|
-
</html>
|
data/test/results/partials.xhtml
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
<div>
|
|
2
|
-
<h1>I can count!</h1>
|
|
3
|
-
1
|
|
4
|
-
2
|
|
5
|
-
3
|
|
6
|
-
4
|
|
7
|
-
5
|
|
8
|
-
6
|
|
9
|
-
7
|
|
10
|
-
8
|
|
11
|
-
9
|
|
12
|
-
10
|
|
13
|
-
11
|
|
14
|
-
12
|
|
15
|
-
13
|
|
16
|
-
14
|
|
17
|
-
15
|
|
18
|
-
16
|
|
19
|
-
17
|
|
20
|
-
18
|
|
21
|
-
19
|
|
22
|
-
20
|
|
23
|
-
<h1>I know my ABCs!</h1>
|
|
24
|
-
<ul>
|
|
25
|
-
<li>a</li>
|
|
26
|
-
<li>b</li>
|
|
27
|
-
<li>c</li>
|
|
28
|
-
<li>d</li>
|
|
29
|
-
<li>e</li>
|
|
30
|
-
<li>f</li>
|
|
31
|
-
<li>g</li>
|
|
32
|
-
<li>h</li>
|
|
33
|
-
<li>i</li>
|
|
34
|
-
<li>j</li>
|
|
35
|
-
<li>k</li>
|
|
36
|
-
<li>l</li>
|
|
37
|
-
<li>m</li>
|
|
38
|
-
<li>n</li>
|
|
39
|
-
<li>o</li>
|
|
40
|
-
<li>p</li>
|
|
41
|
-
<li>q</li>
|
|
42
|
-
<li>r</li>
|
|
43
|
-
<li>s</li>
|
|
44
|
-
<li>t</li>
|
|
45
|
-
<li>u</li>
|
|
46
|
-
<li>v</li>
|
|
47
|
-
<li>w</li>
|
|
48
|
-
<li>x</li>
|
|
49
|
-
<li>y</li>
|
|
50
|
-
<li>z</li>
|
|
51
|
-
</ul>
|
|
52
|
-
<h1>I can catch errors!</h1>
|
|
53
|
-
Oh no! "foo" happened!
|
|
54
|
-
<p>
|
|
55
|
-
"false" is:
|
|
56
|
-
false
|
|
57
|
-
</p>
|
|
58
|
-
Even!
|
|
59
|
-
Odd!
|
|
60
|
-
Even!
|
|
61
|
-
Odd!
|
|
62
|
-
Even!
|
|
63
|
-
</div>
|
|
64
|
-
<div class='foo'>
|
|
65
|
-
<strong>foobar</strong>
|
|
66
|
-
</div>
|
|
67
|
-
<strong>0</strong>
|
|
68
|
-
<strong>1</strong>
|
|
69
|
-
<strong>2</strong>
|
|
70
|
-
<strong>3</strong>
|
|
71
|
-
<strong>4</strong>
|
|
72
|
-
<div class='test'>
|
|
73
|
-
<p>boom</p>
|
|
74
|
-
</div>
|
data/test/results/standard.xhtml
DELETED
|
@@ -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,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
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
lines</textarea>
|
|
18
|
-
</div>
|
|
19
|
-
<textarea>BLAH</textarea>
|
|
20
|
-
<div id='flattened'>
|
|
21
|
-
<div class='text_area_test_area'>
|
|
22
|
-
<textarea>Two
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
bar</pre>
|
|
31
|
-
<p><pre>foo
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
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
lines</textarea>
|
|
62
|
-
</div>
|
|
63
|
-
<textarea>BLAH</textarea>
|
|
64
|
-
<div id='flattened'>
|
|
65
|
-
<div class='text_area_test_area'>
|
|
66
|
-
<textarea>Two
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
bar</pre>
|
|
75
|
-
<p><pre>foo
bar</pre></p>
|
|
76
|
-
<p>
|
|
77
|
-
foo
|
|
78
|
-
bar
|
|
79
|
-
</p>
|
|
80
|
-
<pre> ___
 ,o88888
 ,o8888888'
 ,:o:o:oooo. ,8O88Pd8888"
 ,.::.::o:ooooOoOoO. ,oO8O8Pd888'"
 ,.:.::o:ooOoOoOO8O8OOo.8OOPd8O8O"
 , ..:.::o:ooOoOOOO8OOOOo.FdO8O8"
 , ..:.::o:ooOoOO8O888O8O,COCOO"
 , . ..:.::o:ooOoOOOO8OOOOCOCO"
 . ..:.::o:ooOoOoOO8O8OCCCC"o
 . ..:.::o:ooooOoCoCCC"o:o
 . ..:.::o:o:,cooooCo"oo:o:
 ` . . ..:.:cocoooo"'o:o:::'
 .` . ..::ccccoc"'o:o:o:::'
 :.:. ,c:cccc"':.:.:.:.:.'
 ..:.:"'`::::c:"'..:.:.:.:.:.' http://www.chris.com/ASCII/
 ...:.'.:.::::"' . . . . .'
 .. . ....:."' ` . . . ''
 . . . ...."'
 .. . ."' -hrr-
 .


 It's a planet!
%strong This shouldn't be bold!</pre>
|
|
81
|
-
<strong>This should!</strong>
|
|
82
|
-
<textarea> ___ ___ ___ ___ 
 /\__\ /\ \ /\__\ /\__\
 /:/ / /::\ \ /::| | /:/ /
 /:/__/ /:/\:\ \ /:|:| | /:/ / 
 /::\ \ ___ /::\~\:\ \ /:/|:|__|__ /:/ / 
 /:/\:\ /\__\ /:/\:\ \:\__\ /:/ |::::\__\ /:/__/ 
 \/__\:\/:/ / \/__\:\/:/ / \/__/~~/:/ / \:\ \ 
 \::/ / \::/ / /:/ / \:\ \ 
 /:/ / /:/ / /:/ / \:\ \ 
 /:/ / /:/ / /:/ / \:\__\
 \/__/ \/__/ \/__/ \/__/
 
 Many
 thanks
 to
 http://www.network-science.de/ascii/
|
|
83
|
-
<strong>indeed!</strong></textarea>
|
|
84
|
-
</div>
|
|
85
|
-
<div class='foo'>
|
|
86
|
-
13
|
|
87
|
-
</div>
|
|
88
|
-
<pre> __ ______ __ ______
.----.| |--.|__ |.----.| |--..--------.| __ |
| __|| ||__ || __|| < | || __ |
|____||__|__||______||____||__|__||__|__|__||______|</pre>
|
|
89
|
-
<pre>foo
|
|
90
|
-
bar</pre>
|
data/test/template_test.rb
DELETED
|
@@ -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 & 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 & Bar\n", render('Foo #{"&"} Bar', :action_view))
|
|
271
|
-
end
|
|
272
|
-
|
|
273
|
-
def test_xss_protection_in_attributes
|
|
274
|
-
assert_equal("<div data-html='<foo>bar</foo>'></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 & 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 & 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
|