haml 4.0.6 → 5.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|