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,12 +0,0 @@
1
- <h2>This is a pretty complicated partial</h2>
2
- <div class="partial">
3
- <p>It has several nested partials,</p>
4
- <ul>
5
- <% 5.times do %>
6
- <li>
7
- <strong>Partial:</strong>
8
- <% @nesting = 5 %>
9
- <%= render :partial => 'erb/av_partial_2' %>
10
- <% end %>
11
- </ul>
12
- </div>
@@ -1,8 +0,0 @@
1
- <% @nesting -= 1 %>
2
- <div class="partial" level="<%= @nesting %>">
3
- <h3>This is a crazy deep-nested partial.</h3>
4
- <p>Nesting level <%= @nesting %></p>
5
- <% if @nesting > 0 %>
6
- <%= render :partial => 'erb/av_partial_2' %>
7
- <% end %>
8
- </div>
@@ -1,62 +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 xmlns='http://www.w3.org/1999/xhtml' xml:lang='en-US'>
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
- <h1>
9
- This is very much like the standard template,
10
- except that it has some ActionView-specific stuff.
11
- It's only used for benchmarking.
12
- </h1>
13
- <div class="crazy_partials">
14
- <%= render :partial => 'erb/av_partial_1' %>
15
- </div>
16
- <!-- You're In my house now! -->
17
- <div class='header'>
18
- Yes, ladies and gentileman. He is just that egotistical.
19
- Fantastic! This should be multi-line output
20
- The question is if this would translate! Ahah!
21
- <%= 1 + 9 + 8 + 2 %>
22
- <%# numbers should work and this should be ignored %>
23
- </div>
24
- <% 120.times do |number| -%>
25
- <%= number %>
26
- <% end -%>
27
- <div id='body'><%= " Quotes should be loved! Just like people!" %></div>
28
- Wow.
29
- <p>
30
- <%= "Holy cow " +
31
- "multiline " +
32
- "tags! " +
33
- "A pipe (|) even!" %>
34
- <%= [1, 2, 3].collect { |n| "PipesIgnored|" } %>
35
- <%= [1, 2, 3].collect { |n|
36
- n.to_s
37
- }.join("|") %>
38
- </p>
39
- <div class='silent'>
40
- <% foo = String.new
41
- foo << "this"
42
- foo << " shouldn't"
43
- foo << " evaluate" %>
44
- <%= foo + "but now it should!" %>
45
- <%# Woah crap a comment! %>
46
- </div>
47
- <ul class='really cool'>
48
- <% ('a'..'f').each do |a|%>
49
- <li><%= a %>
50
- <% end %>
51
- <div class='of_divs_with_underscore' id='combo'><%= @should_eval = "with this text" %></div>
52
- <%= [ 104, 101, 108, 108, 111 ].map do |byte|
53
- byte.chr
54
- end %>
55
- <div class='footer'>
56
- <strong class='shout'>
57
- <%= "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.\n" +
58
- " So, I'm just making it *really* long. God, I hope this works" %>
59
- </strong>
60
- </div>
61
- </body>
62
- </html>
@@ -1,55 +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 xmlns='http://www.w3.org/1999/xhtml' xml:lang='en-US' lang='en-US'>
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
- <%= 1 + 9 + 8 + 2 %>
14
- <%# numbers should work and this should be ignored %>
15
- </div>
16
- <% 120.times do |number| -%>
17
- <%= number %>
18
- <% end -%>
19
- <div id='body'><%= " Quotes should be loved! Just like people!" %></div>
20
- Wow.
21
- <p code="<%= 1 + 2 %>">
22
- <%= "Holy cow " +
23
- "multiline " +
24
- "tags! " +
25
- "A pipe (|) even!" %>
26
- <%= [1, 2, 3].collect { |n| "PipesIgnored|" }.join %>
27
- <%= [1, 2, 3].collect { |n|
28
- n.to_s
29
- }.join("|") %>
30
- </p>
31
- <% bar = 17 %>
32
- <div class='silent' foo="<%= bar %>">
33
- <% foo = String.new
34
- foo << "this"
35
- foo << " shouldn't"
36
- foo << " evaluate" %>
37
- <%= foo + "but now it should!" %>
38
- <%# Woah crap a comment! %>
39
- </div>
40
- <ul class='really cool'>
41
- <% ('a'..'f').each do |a|%>
42
- <li><%= a %></li>
43
- <% end %>
44
- <div class='of_divs_with_underscore' id='combo'><%= @should_eval = "with this text" %></div>
45
- <%= "foo".each_line do |line|
46
- nil
47
- end %>
48
- <div class='footer'>
49
- <strong class='shout'>
50
- <%= "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.\n" +
51
- " So, I'm just making it *really* long. God, I hope this works" %>
52
- </strong>
53
- </div>
54
- </body>
55
- </html>
data/test/filters_test.rb DELETED
@@ -1,254 +0,0 @@
1
- require 'test_helper'
2
-
3
- class FiltersTest < MiniTest::Unit::TestCase
4
- test "should be registered as filters when including Haml::Filters::Base" do
5
- begin
6
- refute Haml::Filters.defined.has_key? "bar"
7
- Module.new {def self.name; "Foo::Bar"; end; include Haml::Filters::Base}
8
- assert Haml::Filters.defined.has_key? "bar"
9
- ensure
10
- Haml::Filters.remove_filter "Bar"
11
- end
12
- end
13
-
14
- test "should raise error when attempting to register a defined Tilt filter" do
15
- begin
16
- assert_raises RuntimeError do
17
- 2.times do
18
- Haml::Filters.register_tilt_filter "Foo"
19
- end
20
- end
21
- ensure
22
- Haml::Filters.remove_filter "Foo"
23
- end
24
- end
25
-
26
- test "should raise error when a Tilt filters dependencies are unavailable for extension" do
27
- begin
28
- assert_raises Haml::Error do
29
- Haml::Filters.register_tilt_filter "Textile"
30
- Haml::Filters.defined["textile"].template_class
31
- end
32
- ensure
33
- Haml::Filters.remove_filter "Textile"
34
- end
35
- end
36
-
37
- test "should raise error when a Tilt filters dependencies are unavailable for filter without extension" do
38
- begin
39
- assert_raises Haml::Error do
40
- Haml::Filters.register_tilt_filter "Maruku"
41
- Haml::Filters.defined["maruku"].template_class
42
- end
43
- ensure
44
- Haml::Filters.remove_filter "Maruku"
45
- end
46
- end
47
-
48
- test "should raise informative error about Maruku being moved to haml-contrib" do
49
- begin
50
- render(":maruku\n # foo")
51
- flunk("Should have raised error with message about the haml-contrib gem.")
52
- rescue Haml::Error => e
53
- assert_equal e.message, Haml::Error.message(:install_haml_contrib, "maruku")
54
- end
55
- end
56
-
57
- test "should raise informative error about Textile being moved to haml-contrib" do
58
- begin
59
- render(":textile\n h1. foo")
60
- flunk("Should have raised error with message about the haml-contrib gem.")
61
- rescue Haml::Error => e
62
- assert_equal e.message, Haml::Error.message(:install_haml_contrib, "textile")
63
- end
64
- end
65
-
66
- test "should respect escaped newlines and interpolation" do
67
- html = "\\n\n"
68
- haml = ":plain\n \\n\#{""}"
69
- assert_equal(html, render(haml))
70
- end
71
-
72
- test "should process an filter with no content" do
73
- assert_equal("\n", render(':plain'))
74
- end
75
-
76
- test "should be compatible with ugly mode" do
77
- expectation = "foo\n"
78
- assert_equal(expectation, render(":plain\n foo", :ugly => true))
79
- end
80
-
81
- test "should pass options to Tilt filters that precompile" do
82
- haml = ":erb\n <%= 'foo' %>"
83
- refute_match('TEST_VAR', Haml::Engine.new(haml).compiler.precompiled)
84
- Haml::Filters::Erb.options = {:outvar => 'TEST_VAR'}
85
- assert_match('TEST_VAR', Haml::Engine.new(haml).compiler.precompiled)
86
- end
87
-
88
- test "should pass options to Tilt filters that don't precompile" do
89
- begin
90
- filter = Class.new(Tilt::Template) do
91
- def self.name
92
- "Foo"
93
- end
94
-
95
- def prepare
96
- @engine = {:data => data, :options => options}
97
- end
98
-
99
- def evaluate(scope, locals, &block)
100
- @output = @engine[:options].to_a.join
101
- end
102
- end
103
- Haml::Filters.register_tilt_filter "Foo", :template_class => filter
104
- Haml::Filters::Foo.options[:foo] = "bar"
105
- haml = ":foo"
106
- assert_equal "foobar\n", render(haml)
107
- ensure
108
- Haml::Filters.remove_filter "Foo"
109
- end
110
- end
111
-
112
- end
113
-
114
- class ErbFilterTest < MiniTest::Unit::TestCase
115
- test "multiline expressions should work" do
116
- html = "foobarbaz\n"
117
- haml = %Q{:erb\n <%= "foo" +\n "bar" +\n "baz" %>}
118
- assert_equal(html, render(haml))
119
- end
120
-
121
- test "should evaluate in the same context as Haml" do
122
- haml = ":erb\n <%= foo %>"
123
- html = "bar\n"
124
- scope = Object.new.instance_eval {foo = "bar"; nil if foo; binding}
125
- assert_equal(html, render(haml, :scope => scope))
126
- end
127
-
128
- test "should use Rails's XSS safety features" do
129
- assert_equal("&lt;img&gt;\n", render(":erb\n <%= '<img>' %>"))
130
- assert_equal("<img>\n", render(":erb\n <%= '<img>'.html_safe %>"))
131
- end
132
-
133
- end
134
-
135
- class JavascriptFilterTest < MiniTest::Unit::TestCase
136
- test "should interpolate" do
137
- scope = Object.new.instance_eval {foo = "bar"; nil if foo; binding}
138
- haml = ":javascript\n \#{foo}"
139
- html = render(haml, :scope => scope)
140
- assert_match(/bar/, html)
141
- end
142
-
143
- test "should never HTML-escape ampersands" do
144
- html = "<script>\n & < > &\n</script>\n"
145
- haml = %Q{:javascript\n & < > \#{"&"}}
146
- assert_equal(html, render(haml, :escape_html => true))
147
- end
148
-
149
- test "should not include type in HTML 5 output" do
150
- html = "<script>\n foo bar\n</script>\n"
151
- haml = ":javascript\n foo bar"
152
- assert_equal(html, render(haml, :format => :html5))
153
- end
154
-
155
- test "should always include CDATA when format is xhtml" do
156
- html = "<script type='text/javascript'>\n //<![CDATA[\n foo bar\n //]]>\n</script>\n"
157
- haml = ":javascript\n foo bar"
158
- assert_equal(html, render(haml, :format => :xhtml, :cdata => false))
159
- end
160
-
161
- test "should omit CDATA when cdata option is false" do
162
- html = "<script>\n foo bar\n</script>\n"
163
- haml = ":javascript\n foo bar"
164
- assert_equal(html, render(haml, :format => :html5, :cdata => false))
165
- end
166
-
167
- test "should include CDATA when cdata option is true" do
168
- html = "<script>\n //<![CDATA[\n foo bar\n //]]>\n</script>\n"
169
- haml = ":javascript\n foo bar"
170
- assert_equal(html, render(haml, :format => :html5, :cdata => true))
171
- end
172
-
173
- test "should default to no CDATA when format is html5" do
174
- haml = ":javascript\n foo bar"
175
- out = render(haml, :format => :html5)
176
- refute_match('//<![CDATA[', out)
177
- refute_match('//]]>', out)
178
- end
179
- end
180
-
181
- class CSSFilterTest < MiniTest::Unit::TestCase
182
- test "should wrap output in CDATA and a CSS tag when output is XHTML" do
183
- html = "<style type='text/css'>\n /*<![CDATA[*/\n foo\n /*]]>*/\n</style>\n"
184
- haml = ":css\n foo"
185
- assert_equal(html, render(haml, :format => :xhtml))
186
- end
187
-
188
- test "should not include type in HTML 5 output" do
189
- html = "<style>\n foo bar\n</style>\n"
190
- haml = ":css\n foo bar"
191
- assert_equal(html, render(haml, :format => :html5))
192
- end
193
-
194
- test "should always include CDATA when format is xhtml" do
195
- html = "<style type='text/css'>\n /*<![CDATA[*/\n foo bar\n /*]]>*/\n</style>\n"
196
- haml = ":css\n foo bar"
197
- assert_equal(html, render(haml, :format => :xhtml, :cdata => false))
198
- end
199
-
200
- test "should omit CDATA when cdata option is false" do
201
- html = "<style>\n foo bar\n</style>\n"
202
- haml = ":css\n foo bar"
203
- assert_equal(html, render(haml, :format => :html5, :cdata => false))
204
- end
205
-
206
- test "should include CDATA when cdata option is true" do
207
- html = "<style>\n /*<![CDATA[*/\n foo bar\n /*]]>*/\n</style>\n"
208
- haml = ":css\n foo bar"
209
- assert_equal(html, render(haml, :format => :html5, :cdata => true))
210
- end
211
-
212
- test "should default to no CDATA when format is html5" do
213
- haml = ":css\n foo bar"
214
- out = render(haml, :format => :html5)
215
- refute_match('<![CDATA[', out)
216
- refute_match(']]>', out)
217
- end
218
- end
219
-
220
- class CDATAFilterTest < MiniTest::Unit::TestCase
221
- test "should wrap output in CDATA tag" do
222
- html = "<![CDATA[\n foo\n]]>\n"
223
- haml = ":cdata\n foo"
224
- assert_equal(html, render(haml))
225
- end
226
- end
227
-
228
- class EscapedFilterTest < MiniTest::Unit::TestCase
229
- test "should escape ampersands" do
230
- html = "&amp;\n"
231
- haml = ":escaped\n &"
232
- assert_equal(html, render(haml))
233
- end
234
- end
235
-
236
- class RubyFilterTest < MiniTest::Unit::TestCase
237
- test "can write to haml_io" do
238
- haml = ":ruby\n haml_io.puts 'hello'\n"
239
- html = "hello\n"
240
- assert_equal(html, render(haml))
241
- end
242
-
243
- test "haml_io appends to output" do
244
- haml = "hello\n:ruby\n haml_io.puts 'hello'\n"
245
- html = "hello\nhello\n"
246
- assert_equal(html, render(haml))
247
- end
248
-
249
- test "can create local variables" do
250
- haml = ":ruby\n a = 7\n=a"
251
- html = "7\n"
252
- assert_equal(html, render(haml))
253
- end
254
- end
@@ -1,5 +0,0 @@
1
- source "http://rubygems.org"
2
-
3
- gem 'rails', '>= 3.0.0', '< 3.1.0'
4
- gemspec :path => "../.."
5
-
@@ -1,6 +0,0 @@
1
- source "http://rubygems.org"
2
-
3
- gem 'rails', '>= 3.1.0', '< 3.2.0'
4
- gemspec :path => "../.."
5
-
6
-
@@ -1,5 +0,0 @@
1
- source "http://rubygems.org"
2
-
3
- gem 'rails', '>= 3.2.0', '< 3.3.0'
4
- gemspec :path => "../.."
5
-
@@ -1,5 +0,0 @@
1
- source "http://rubygems.org"
2
-
3
- gem 'bundler', '~> 1.3.0'
4
- gem 'rails', '~> 4.0.0.rc1'
5
- gemspec :path => '../..'
@@ -1,14 +0,0 @@
1
- DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
2
- Version 2, December 2004
3
-
4
- Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
5
-
6
- Everyone is permitted to copy and distribute verbatim or modified
7
- copies of this license document, and changing it is allowed as long
8
- as the name is changed.
9
-
10
- DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
11
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
12
-
13
- 0. You just DO WHAT THE FUCK YOU WANT TO.
14
-
@@ -1,106 +0,0 @@
1
- # Haml Spec #
2
-
3
- Haml Spec provides a basic suite of tests for Haml interpreters.
4
-
5
- It is intented for developers who are creating or maintaining an implementation
6
- of the [Haml](http://haml-lang.com) markup language.
7
-
8
- At the moment, there are test runners for the [original
9
- Haml](http://github.com/nex3/haml) in Ruby, [Lua
10
- Haml](http://github.com/norman/lua-haml) and the
11
- [Text::Haml](http://github.com/vti/text-haml) Perl port. Support for other
12
- versions of Haml will be added if their developers/maintainers are interested in
13
- using it.
14
-
15
- ## The Tests ##
16
-
17
- The tests are kept in JSON format for portability across languages. Each test
18
- is a JSON object with expected input, output, local variables and configuration
19
- parameters (see below). The test suite only provides tests for features which
20
- are portable, therefore no tests for script are provided, nor for external
21
- filters such as :markdown or :textile.
22
-
23
- The one major exception to this are the tests for interpolation, which you may
24
- need to modify with a regular expression to run under PHP or Perl, which
25
- require a sigil before variable names. These tests are included despite being
26
- less than 100% portable because interpolation is an important part of Haml and
27
- can be tricky to implement. These tests are flagged as "optional" so that you
28
- can avoid running them if your implementation of Haml will not support this
29
- feature.
30
-
31
- ## Running the Tests ##
32
-
33
- ### Ruby ###
34
-
35
- The Ruby test runner uses minitest, the same as the Ruby Haml implementation.
36
- To run the tests you probably only need to install `haml`, `minitest` and
37
- possibly `ruby` if your platform doesn't come with it by default. If you're
38
- using Ruby 1.8.x, you'll also need to install `json`:
39
-
40
- sudo gem install haml
41
- sudo gem install minitest
42
- # for Ruby 1.8.x; check using "ruby --version" if unsure
43
- sudo gem install json
44
-
45
- Then, running the Ruby test suite is easy:
46
-
47
- ruby ruby_haml_test.rb
48
-
49
- At the moment, running the tests with Ruby 1.8.7 fails because of issues with
50
- the JSON library. Please use 1.9.2 until this is resolved.
51
-
52
- ### Lua ###
53
-
54
- The Lua test depends on
55
- [Penlight](http://stevedonovan.github.com/Penlight/),
56
- [Telescope](http://github.com/norman/telescope),
57
- [jason4lua](http://json.luaforge.net/), and
58
- [Lua Haml](http://github.com/norman/lua-haml). Install and run `tsc
59
- lua_haml_spec.lua`.
60
-
61
- ### Getting it ###
62
-
63
- You can access the [Git repository](http://github.com/norman/haml-spec) at:
64
-
65
- git://github.com/norman/haml-spec.git
66
-
67
- Patches are *very* welcome, as are test runners for your Haml implementation.
68
-
69
- As long as any test you add run against Ruby Haml and are not redundant, I'll
70
- be very happy to add them.
71
-
72
- ### Test JSON format ###
73
-
74
- "test name" : {
75
- "haml" : "haml input",
76
- "html" : "expected html output",
77
- "result" : "expected test result",
78
- "locals" : "local vars",
79
- "config" : "config params",
80
- "optional" : true|false
81
- }
82
-
83
- * test name: This should be a *very* brief description of what's being tested. It can
84
- be used by the test runners to name test methods, or to exclude certain tests from being
85
- run.
86
- * haml: The Haml code to be evaluated. Always required.
87
- * html: The HTML output that should be generated. Required unless "result" is "error".
88
- * result: Can be "pass" or "error". If it's absent, then "pass" is assumed. If it's "error",
89
- then the goal of the test is to make sure that malformed Haml code generates an error.
90
- * locals: An object containing local variables needed for the test.
91
- * config: An object containing configuration parameters used to run the test.
92
- The configuration parameters should be usable directly by Ruby's Haml with no
93
- modification. If your implementation uses config parameters with different
94
- names, you may need to process them to make them match your implementation.
95
- If your implementation has options that do not exist in Ruby's Haml, then you
96
- should add tests for this in your implementation's test rather than here.
97
- * optional: whether or not the test is optional
98
-
99
- ## License ##
100
-
101
- This project is released under the [WTFPL](http://sam.zoy.org/wtfpl/) in order
102
- to be as usable as possible in any project, commercial or free.
103
-
104
- ## Author ##
105
-
106
- [Norman Clarke](mailto:norman@njclarke.com)
@@ -1,38 +0,0 @@
1
- local dir = require 'pl.dir'
2
- local haml = require 'haml'
3
- local json = require 'json'
4
- local path = require 'pl.path'
5
- local telescope = require 'telescope'
6
- local assert = assert
7
- local describe = telescope.describe
8
- local getinfo = debug.getinfo
9
- local it = telescope.it
10
- local open = io.open
11
- local pairs = pairs
12
-
13
- module('hamlspec')
14
-
15
- local function get_tests(filename)
16
- local me = path.abspath(getinfo(1).source:match("@(.*)$"))
17
- return path.join(path.dirname(me), filename)
18
- end
19
-
20
- local json_file = get_tests("tests.json")
21
- local file = assert(open(json_file))
22
- local input = file:read '*a'
23
- file:close()
24
-
25
- local contexts = json.decode(input)
26
-
27
- describe("LuaHaml", function()
28
- for context, expectations in pairs(contexts) do
29
- describe("When handling " .. context, function()
30
- for name, exp in pairs(expectations) do
31
- it(("should correctly render %s"):format(name), function()
32
- local engine = haml.new(exp.config)
33
- assert_equal(engine:render(exp.haml, exp.locals), exp.html)
34
- end)
35
- end
36
- end)
37
- end
38
- end)
@@ -1,81 +0,0 @@
1
- #!/usr/bin/env perl
2
-
3
- use strict;
4
- use warnings;
5
-
6
- use Test::More 'no_plan';
7
- use Text::Haml;
8
- use FindBin;
9
- use JSON 'from_json';
10
-
11
- our $VERSION = 0.990101;
12
-
13
- my $tests;
14
-
15
- open FILE, "< $FindBin::Bin/tests.json" or die $!;
16
- $tests = from_json(join("\n", <FILE>));
17
- close FILE;
18
-
19
- while (my ($section_name, $section) = each %$tests) {
20
- diag $section_name;
21
-
22
- while (my ($test_name, $test) = each %$section) {
23
- is( Text::Haml->new(%{$test->{config}}, vars_as_subs => 1)
24
- ->render($test->{haml}, %{$test->{locals}}),
25
- $test->{html}, $test_name
26
- );
27
- }
28
- }
29
- __END__
30
-
31
- =head1 NAME
32
-
33
- perl_haml_test.pl - Text::Haml spec tests runner
34
-
35
- =head1 SYNOPSIS
36
-
37
- $ perl perl_haml_test.pl
38
-
39
- # conditional comments
40
- ok 1 - a conditional comment
41
- # tags with nested content
42
- ok 2 - a tag with CSS
43
-
44
- ...
45
-
46
- ok 81 - an inline comment
47
- ok 82 - a nested comment
48
- 1..82
49
-
50
- =head1 DESCRIPTION
51
-
52
- This file is a part of Haml spec tests envorinment. It tests Perl
53
- implementation using <Text::Haml>.
54
-
55
- =head1 DEPENDENCIES
56
-
57
- =over
58
-
59
- * Text::Haml (available via CPAN or http://github.com/vti/text-haml)
60
- * JSON (available on CPAN)
61
- * Test::More (included in Perl core)
62
- * FindBin (included in Perl core)
63
-
64
- =back
65
-
66
- =head1 SEE ALSO
67
-
68
- L<Text::Haml>
69
-
70
- =head1 AUTHOR
71
-
72
- Viacheslav Tykhanovskyi, C<vti@cpan.org>.
73
-
74
- =head1 COPYRIGHT AND LICENSE
75
-
76
- Copyright (C) 2009, Viacheslav Tykhanovskyi
77
-
78
- This program is free software, you can redistribute it and/or modify it under
79
- the terms of the Artistic License version 2.0.
80
-
81
- =cut