haml 4.0.0 → 5.0.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 +7 -0
- data/.yardopts +1 -1
- data/CHANGELOG.md +117 -5
- data/FAQ.md +7 -17
- data/MIT-LICENSE +1 -1
- data/README.md +85 -42
- data/REFERENCE.md +181 -86
- data/Rakefile +47 -51
- data/lib/haml/attribute_builder.rb +163 -0
- data/lib/haml/attribute_compiler.rb +215 -0
- data/lib/haml/attribute_parser.rb +144 -0
- data/lib/haml/buffer.rb +38 -128
- data/lib/haml/compiler.rb +88 -295
- data/lib/haml/engine.rb +25 -41
- data/lib/haml/error.rb +3 -0
- data/lib/haml/escapable.rb +49 -0
- data/lib/haml/exec.rb +33 -19
- data/lib/haml/filters.rb +20 -24
- data/lib/haml/generator.rb +41 -0
- data/lib/haml/helpers/action_view_extensions.rb +3 -2
- data/lib/haml/helpers/action_view_mods.rb +44 -66
- data/lib/haml/helpers/action_view_xss_mods.rb +1 -0
- data/lib/haml/helpers/safe_erubi_template.rb +27 -0
- data/lib/haml/helpers/safe_erubis_template.rb +16 -4
- data/lib/haml/helpers/xss_mods.rb +18 -12
- data/lib/haml/helpers.rb +122 -58
- data/lib/haml/options.rb +39 -46
- data/lib/haml/parser.rb +278 -217
- data/lib/haml/{template/plugin.rb → plugin.rb} +8 -15
- data/lib/haml/railtie.rb +21 -11
- data/lib/haml/sass_rails_filter.rb +17 -4
- data/lib/haml/template/options.rb +12 -2
- data/lib/haml/template.rb +12 -6
- data/lib/haml/temple_engine.rb +120 -0
- data/lib/haml/temple_line_counter.rb +29 -0
- data/lib/haml/util.rb +80 -199
- data/lib/haml/version.rb +2 -1
- data/lib/haml.rb +2 -1
- data/test/attribute_parser_test.rb +101 -0
- data/test/engine_test.rb +306 -176
- data/test/filters_test.rb +32 -19
- data/test/gemfiles/Gemfile.rails-4.0.x +11 -0
- data/test/gemfiles/Gemfile.rails-4.0.x.lock +87 -0
- data/test/gemfiles/Gemfile.rails-4.1.x +5 -0
- data/test/gemfiles/Gemfile.rails-4.2.x +5 -0
- data/test/gemfiles/Gemfile.rails-5.0.x +4 -0
- data/test/helper_test.rb +282 -96
- data/test/options_test.rb +22 -0
- data/test/parser_test.rb +71 -4
- data/test/results/bemit.xhtml +4 -0
- data/test/results/eval_suppressed.xhtml +4 -4
- data/test/results/helpers.xhtml +43 -41
- data/test/results/helpful.xhtml +6 -3
- data/test/results/just_stuff.xhtml +21 -20
- data/test/results/list.xhtml +9 -9
- data/test/results/nuke_inner_whitespace.xhtml +22 -22
- data/test/results/nuke_outer_whitespace.xhtml +84 -92
- data/test/results/original_engine.xhtml +17 -17
- data/test/results/partial_layout.xhtml +4 -3
- data/test/results/partial_layout_erb.xhtml +4 -3
- data/test/results/partials.xhtml +11 -10
- data/test/results/silent_script.xhtml +63 -63
- data/test/results/standard.xhtml +156 -159
- data/test/results/tag_parsing.xhtml +19 -19
- data/test/results/very_basic.xhtml +2 -2
- data/test/results/whitespace_handling.xhtml +56 -50
- data/test/template_test.rb +44 -53
- data/test/template_test_helper.rb +38 -0
- data/test/templates/_text_area_helper.html.haml +4 -0
- data/test/templates/bemit.haml +3 -0
- data/test/templates/just_stuff.haml +1 -0
- data/test/templates/partial_layout_erb.erb +1 -1
- data/test/templates/standard_ugly.haml +1 -0
- data/test/templates/with_bom.haml +1 -0
- data/test/temple_line_counter_test.rb +40 -0
- data/test/test_helper.rb +26 -12
- data/test/util_test.rb +6 -47
- metadata +88 -106
- data/lib/haml/helpers/rails_323_textarea_fix.rb +0 -24
- 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-master +0 -4
- data/test/templates/_av_partial_1_ugly.haml +0 -9
- data/test/templates/_av_partial_2_ugly.haml +0 -5
- data/test/templates/action_view_ugly.haml +0 -47
- data/test/templates/standard_ugly.haml +0 -43
data/test/engine_test.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
require 'test_helper'
|
3
3
|
|
4
|
-
class EngineTest <
|
4
|
+
class EngineTest < Haml::TestCase
|
5
5
|
# A map of erroneous Haml documents to the error messages they should produce.
|
6
6
|
# The error messages may be arrays;
|
7
7
|
# if so, the second element should be the line number that should be reported for the error.
|
@@ -113,13 +113,11 @@ class EngineTest < MiniTest::Unit::TestCase
|
|
113
113
|
end
|
114
114
|
|
115
115
|
def setup
|
116
|
-
return if RUBY_VERSION < "1.9"
|
117
116
|
@old_default_internal = Encoding.default_internal
|
118
117
|
silence_warnings{Encoding.default_internal = nil}
|
119
118
|
end
|
120
119
|
|
121
120
|
def teardown
|
122
|
-
return if RUBY_VERSION < "1.9"
|
123
121
|
silence_warnings{Encoding.default_internal = @old_default_internal}
|
124
122
|
end
|
125
123
|
|
@@ -128,11 +126,11 @@ class EngineTest < MiniTest::Unit::TestCase
|
|
128
126
|
end
|
129
127
|
|
130
128
|
def test_flexible_tabulation
|
131
|
-
assert_equal("<p>\
|
129
|
+
assert_equal("<p>\nfoo\n</p>\n<q>\nbar\n<a>\nbaz\n</a>\n</q>\n",
|
132
130
|
render("%p\n foo\n%q\n bar\n %a\n baz"))
|
133
|
-
assert_equal("<p>\
|
131
|
+
assert_equal("<p>\nfoo\n</p>\n<q>\nbar\n<a>\nbaz\n</a>\n</q>\n",
|
134
132
|
render("%p\n\tfoo\n%q\n\tbar\n\t%a\n\t\tbaz"))
|
135
|
-
assert_equal("<p>\n
|
133
|
+
assert_equal("<p>\n \t \t bar\n baz\n</p>\n",
|
136
134
|
render("%p\n :plain\n \t \t bar\n baz"))
|
137
135
|
end
|
138
136
|
|
@@ -187,7 +185,7 @@ class EngineTest < MiniTest::Unit::TestCase
|
|
187
185
|
def test_dynamic_attributes_with_no_content
|
188
186
|
assert_equal(<<HTML, render(<<HAML))
|
189
187
|
<p>
|
190
|
-
|
188
|
+
<a href='http://haml.info'></a>
|
191
189
|
</p>
|
192
190
|
HTML
|
193
191
|
%p
|
@@ -224,7 +222,7 @@ HAML
|
|
224
222
|
end
|
225
223
|
|
226
224
|
def test_one_liner_with_newline_shouldnt_be_one_line
|
227
|
-
assert_equal("<p
|
225
|
+
assert_equal("<p>foo\nbar</p>", render('%p= "foo\nbar"').chomp)
|
228
226
|
end
|
229
227
|
|
230
228
|
def test_multi_render
|
@@ -235,8 +233,31 @@ HAML
|
|
235
233
|
end
|
236
234
|
|
237
235
|
def test_interpolation
|
238
|
-
assert_equal("<p>Hello World</p>\n", render('%p Hello #{who}', :
|
239
|
-
assert_equal("<p>\
|
236
|
+
assert_equal("<p>Hello World</p>\n", render('%p Hello #{who}', locals: {who: 'World'}, escape_html: false))
|
237
|
+
assert_equal("<p>\nHello World\n</p>\n", render("%p\n Hello \#{who}", locals: {who: 'World'}, escape_html: false))
|
238
|
+
assert_equal("<p>Hello World</p>\n", render('%p Hello #{who}', locals: {who: 'World'}, escape_html: true))
|
239
|
+
assert_equal("<p>\nHello World\n</p>\n", render("%p\n Hello \#{who}", locals: {who: 'World'}, escape_html: true))
|
240
|
+
end
|
241
|
+
|
242
|
+
def test_interpolation_with_instance_var
|
243
|
+
scope = Object.new
|
244
|
+
scope.instance_variable_set(:@who, 'World')
|
245
|
+
|
246
|
+
assert_equal("<p>Hello World</p>\n", render('%p Hello #@who', scope: scope, escape_html: false))
|
247
|
+
assert_equal("<p>\nHello World\n</p>\n", render("%p\n Hello \#@who", scope: scope, escape_html: false))
|
248
|
+
assert_equal("<p>Hello World</p>\n", render('%p Hello #@who', scope: scope, escape_html: true))
|
249
|
+
assert_equal("<p>\nHello World\n</p>\n", render("%p\n Hello \#@who", scope: scope, escape_html: true))
|
250
|
+
end
|
251
|
+
|
252
|
+
def test_interpolation_with_global
|
253
|
+
$global_var_for_testing = 'World'
|
254
|
+
|
255
|
+
assert_equal("<p>Hello World</p>\n", render('%p Hello #$global_var_for_testing', escape_html: false))
|
256
|
+
assert_equal("<p>\nHello World\n</p>\n", render("%p\n Hello \#$global_var_for_testing", escape_html: false))
|
257
|
+
assert_equal("<p>Hello World</p>\n", render('%p Hello #$global_var_for_testing', escape_html: true))
|
258
|
+
assert_equal("<p>\nHello World\n</p>\n", render("%p\n Hello \#$global_var_for_testing", escape_html: true))
|
259
|
+
ensure
|
260
|
+
$global_var_for_testing = nil
|
240
261
|
end
|
241
262
|
|
242
263
|
def test_interpolation_in_the_middle_of_a_string
|
@@ -244,9 +265,43 @@ HAML
|
|
244
265
|
render("\"title '\#{\"Title\"}'. \""))
|
245
266
|
end
|
246
267
|
|
268
|
+
def test_interpolation_with_instance_var_in_the_middle_of_a_string
|
269
|
+
scope = Object.new
|
270
|
+
scope.instance_variable_set(:@title, 'Title')
|
271
|
+
|
272
|
+
assert_equal("\"title 'Title'. \"\n",
|
273
|
+
render("\"title '\#@title'. \"", :scope => scope))
|
274
|
+
end
|
275
|
+
|
276
|
+
def test_interpolation_with_global_in_the_middle_of_a_string
|
277
|
+
$global_var_for_testing = 'Title'
|
278
|
+
|
279
|
+
assert_equal("\"title 'Title'. \"\n",
|
280
|
+
render("\"title '\#$global_var_for_testing'. \""))
|
281
|
+
ensure
|
282
|
+
$global_var_for_testing = nil
|
283
|
+
end
|
284
|
+
|
247
285
|
def test_interpolation_at_the_beginning_of_a_line
|
248
286
|
assert_equal("<p>2</p>\n", render('%p #{1 + 1}'))
|
249
|
-
assert_equal("<p>\
|
287
|
+
assert_equal("<p>\n2\n</p>\n", render("%p\n \#{1 + 1}"))
|
288
|
+
end
|
289
|
+
|
290
|
+
def test_interpolation_with_instance_var_at_the_beginning_of_a_line
|
291
|
+
scope = Object.new
|
292
|
+
scope.instance_variable_set(:@foo, 2)
|
293
|
+
|
294
|
+
assert_equal("<p>2</p>\n", render('%p #@foo', :scope => scope))
|
295
|
+
assert_equal("<p>\n2\n</p>\n", render("%p\n \#@foo", :scope => scope))
|
296
|
+
end
|
297
|
+
|
298
|
+
def test_interpolation_with_global_at_the_beginning_of_a_line
|
299
|
+
$global_var_for_testing = 2
|
300
|
+
|
301
|
+
assert_equal("<p>2</p>\n", render('%p #$global_var_for_testing'))
|
302
|
+
assert_equal("<p>\n2\n</p>\n", render("%p\n \#$global_var_for_testing"))
|
303
|
+
ensure
|
304
|
+
$global_var_for_testing = nil
|
250
305
|
end
|
251
306
|
|
252
307
|
def test_escaped_interpolation
|
@@ -271,7 +326,7 @@ HAML
|
|
271
326
|
|
272
327
|
def test_attribute_hash_with_newlines
|
273
328
|
assert_equal("<p a='b' c='d'>foop</p>\n", render("%p{:a => 'b',\n :c => 'd'} foop"))
|
274
|
-
assert_equal("<p a='b' c='d'>\
|
329
|
+
assert_equal("<p a='b' c='d'>\nfoop\n</p>\n", render("%p{:a => 'b',\n :c => 'd'}\n foop"))
|
275
330
|
assert_equal("<p a='b' c='d'>\n", render("%p{:a => 'b',\n :c => 'd'}/"))
|
276
331
|
assert_equal("<p a='b' c='d' e='f'></p>\n", render("%p{:a => 'b',\n :c => 'd',\n :e => 'f'}"))
|
277
332
|
end
|
@@ -290,8 +345,8 @@ HAML
|
|
290
345
|
assert_equal(hash, {:color => 'red'})
|
291
346
|
end
|
292
347
|
|
293
|
-
def
|
294
|
-
assert_equal(<<HTML, render(<<HAML
|
348
|
+
def test_semi_prerendered_tags
|
349
|
+
assert_equal(<<HTML, render(<<HAML))
|
295
350
|
<p a='2'></p>
|
296
351
|
<p a='2'>foo</p>
|
297
352
|
<p a='2'>
|
@@ -333,7 +388,7 @@ HAML
|
|
333
388
|
assert_equal("<textarea>#{'a' * 100}</textarea>\n",
|
334
389
|
render("%textarea #{'a' * 100}"))
|
335
390
|
|
336
|
-
assert_equal("<p>\n
|
391
|
+
assert_equal("<p>\n<textarea>Foo\nBar\nBaz</textarea>\n</p>\n", render(<<SOURCE))
|
337
392
|
%p
|
338
393
|
%textarea
|
339
394
|
Foo
|
@@ -380,7 +435,7 @@ HAML
|
|
380
435
|
def test_both_whitespace_nukes_work_together
|
381
436
|
assert_equal(<<RESULT, render(<<SOURCE))
|
382
437
|
<p><q>Foo
|
383
|
-
|
438
|
+
Bar</q></p>
|
384
439
|
RESULT
|
385
440
|
%p
|
386
441
|
%q><= "Foo\\nBar"
|
@@ -389,6 +444,7 @@ SOURCE
|
|
389
444
|
|
390
445
|
def test_nil_option
|
391
446
|
assert_equal("<p foo='bar'></p>\n", render('%p{:foo => "bar"}', :attr_wrapper => nil))
|
447
|
+
assert_equal("<p foo='bar'></p>\n", render('%p{foo: "bar"}', :attr_wrapper => nil))
|
392
448
|
end
|
393
449
|
|
394
450
|
def test_comment_with_crazy_nesting
|
@@ -407,15 +463,14 @@ HAML
|
|
407
463
|
|
408
464
|
# Regression tests
|
409
465
|
|
410
|
-
|
411
|
-
|
412
|
-
assert_equal(<<HTML, render(<<HAML))
|
466
|
+
def test_indentation_after_dynamic_attr_hash
|
467
|
+
assert_equal(<<HTML, render(<<HAML))
|
413
468
|
<html>
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
469
|
+
<body>
|
470
|
+
<img src='test'>
|
471
|
+
foo
|
472
|
+
bar
|
473
|
+
</body>
|
419
474
|
</html>
|
420
475
|
HTML
|
421
476
|
%html
|
@@ -423,14 +478,15 @@ HTML
|
|
423
478
|
%img{:src => 'te'+'st'}
|
424
479
|
= "foo\\nbar"
|
425
480
|
HAML
|
426
|
-
end
|
427
481
|
end
|
428
482
|
|
429
483
|
def test_whitespace_nuke_with_both_newlines
|
430
|
-
assert_equal("<p
|
484
|
+
assert_equal("<p>\nfoo\n</p>\n", render('%p<= "\nfoo\n"'))
|
431
485
|
assert_equal(<<HTML, render(<<HAML))
|
432
486
|
<p>
|
433
|
-
|
487
|
+
<p>
|
488
|
+
foo
|
489
|
+
</p>
|
434
490
|
</p>
|
435
491
|
HTML
|
436
492
|
%p
|
@@ -441,7 +497,7 @@ HAML
|
|
441
497
|
def test_whitespace_nuke_with_tags_and_else
|
442
498
|
assert_equal(<<HTML, render(<<HAML))
|
443
499
|
<a>
|
444
|
-
|
500
|
+
<b>foo</b>
|
445
501
|
</a>
|
446
502
|
HTML
|
447
503
|
%a
|
@@ -454,9 +510,9 @@ HAML
|
|
454
510
|
|
455
511
|
assert_equal(<<HTML, render(<<HAML))
|
456
512
|
<a>
|
457
|
-
|
458
|
-
|
459
|
-
|
513
|
+
<b>
|
514
|
+
foo
|
515
|
+
</b>
|
460
516
|
</a>
|
461
517
|
HTML
|
462
518
|
%a
|
@@ -471,7 +527,7 @@ HAML
|
|
471
527
|
def test_outer_whitespace_nuke_with_empty_script
|
472
528
|
assert_equal(<<HTML, render(<<HAML))
|
473
529
|
<p>
|
474
|
-
|
530
|
+
foo <a></a></p>
|
475
531
|
HTML
|
476
532
|
%p
|
477
533
|
foo
|
@@ -483,7 +539,7 @@ HAML
|
|
483
539
|
def test_both_case_indentation_work_with_deeply_nested_code
|
484
540
|
result = <<RESULT
|
485
541
|
<h2>
|
486
|
-
|
542
|
+
other
|
487
543
|
</h2>
|
488
544
|
RESULT
|
489
545
|
assert_equal(result, render(<<HAML))
|
@@ -506,15 +562,15 @@ HAML
|
|
506
562
|
HAML
|
507
563
|
end
|
508
564
|
|
509
|
-
def
|
510
|
-
assert_equal("foo\n", render(<<HAML
|
565
|
+
def test_equals_block
|
566
|
+
assert_equal("foo\n", render(<<HAML))
|
511
567
|
= capture_haml do
|
512
568
|
foo
|
513
569
|
HAML
|
514
570
|
end
|
515
571
|
|
516
|
-
def
|
517
|
-
assert_equal("foo\nbar\n", render(<<HAML
|
572
|
+
def test_plain_equals
|
573
|
+
assert_equal("foo\nbar\n", render(<<HAML))
|
518
574
|
= "foo"
|
519
575
|
bar
|
520
576
|
HAML
|
@@ -532,10 +588,7 @@ HAML
|
|
532
588
|
end
|
533
589
|
|
534
590
|
def test_end_with_method_call
|
535
|
-
assert_equal(
|
536
|
-
2|3|4
|
537
|
-
b-a-r
|
538
|
-
HTML
|
591
|
+
assert_equal("2|3|4b-a-r", render(<<HAML))
|
539
592
|
= [1, 2, 3].map do |i|
|
540
593
|
- i + 1
|
541
594
|
- end.join("|")
|
@@ -549,9 +602,7 @@ HAML
|
|
549
602
|
def test_nested_end_with_method_call
|
550
603
|
assert_equal(<<HTML, render(<<HAML))
|
551
604
|
<p>
|
552
|
-
|
553
|
-
b-a-r
|
554
|
-
</p>
|
605
|
+
2|3|4b-a-r</p>
|
555
606
|
HTML
|
556
607
|
%p
|
557
608
|
= [1, 2, 3].map do |i|
|
@@ -633,7 +684,7 @@ HAML
|
|
633
684
|
def test_escape_attrs_false
|
634
685
|
assert_equal(<<HTML, render(<<HAML, :escape_attrs => false))
|
635
686
|
<div class='<?php echo """ ?>' id='foo'>
|
636
|
-
|
687
|
+
bar
|
637
688
|
</div>
|
638
689
|
HTML
|
639
690
|
#foo{:class => '<?php echo """ ?>'}
|
@@ -642,9 +693,9 @@ HAML
|
|
642
693
|
end
|
643
694
|
|
644
695
|
def test_escape_attrs_always
|
645
|
-
assert_equal(<<HTML, render(<<HAML, :escape_attrs =>
|
646
|
-
<div class='
|
647
|
-
|
696
|
+
assert_equal(<<HTML, render(<<HAML, :escape_attrs => true))
|
697
|
+
<div class='"&lt;&gt;&amp;"' id='foo'>
|
698
|
+
bar
|
648
699
|
</div>
|
649
700
|
HTML
|
650
701
|
#foo{:class => '"<>&"'}
|
@@ -764,7 +815,7 @@ HAML
|
|
764
815
|
assert_equal("<a href='#'>Foo</a>\n",
|
765
816
|
render('%a(href="#") #{"Foo"}'))
|
766
817
|
|
767
|
-
assert_equal("<a href='
|
818
|
+
assert_equal("<a href='#"'></a>\n", render('%a(href="#\\"")'))
|
768
819
|
end
|
769
820
|
|
770
821
|
def test_case_assigned_to_var
|
@@ -893,7 +944,7 @@ HAML
|
|
893
944
|
# HTML escaping tests
|
894
945
|
|
895
946
|
def test_ampersand_equals_should_escape
|
896
|
-
assert_equal("<p>\
|
947
|
+
assert_equal("<p>\nfoo & bar\n</p>\n", render("%p\n &= 'foo & bar'", :escape_html => false))
|
897
948
|
end
|
898
949
|
|
899
950
|
def test_ampersand_equals_inline_should_escape
|
@@ -905,7 +956,7 @@ HAML
|
|
905
956
|
end
|
906
957
|
|
907
958
|
def test_bang_equals_should_not_escape
|
908
|
-
assert_equal("<p>\
|
959
|
+
assert_equal("<p>\nfoo & bar\n</p>\n", render("%p\n != 'foo & bar'", :escape_html => true))
|
909
960
|
end
|
910
961
|
|
911
962
|
def test_bang_equals_inline_should_not_escape
|
@@ -919,8 +970,6 @@ HAML
|
|
919
970
|
render(".atlantis{:style => 'ugly&stupid'} foo"))
|
920
971
|
assert_equal("<p class='atlantis' style='ugly&stupid'>foo</p>\n",
|
921
972
|
render("%p.atlantis{:style => 'ugly&stupid'}= 'foo'"))
|
922
|
-
assert_equal("<p class='atlantis' style='ugly
stupid'></p>\n",
|
923
|
-
render("%p.atlantis{:style => \"ugly\\nstupid\"}"))
|
924
973
|
end
|
925
974
|
|
926
975
|
def test_dynamic_attributes_should_be_escaped
|
@@ -930,8 +979,6 @@ HAML
|
|
930
979
|
render("%p{:width => nil, :src => '&foo.png', :alt => String.new} foo"))
|
931
980
|
assert_equal("<div alt='' src='&foo.png'>foo</div>\n",
|
932
981
|
render("%div{:width => nil, :src => '&foo.png', :alt => String.new}= 'foo'"))
|
933
|
-
assert_equal("<img alt='' src='foo
.png'>\n",
|
934
|
-
render("%img{:width => nil, :src => \"foo\\n.png\", :alt => String.new}"))
|
935
982
|
end
|
936
983
|
|
937
984
|
def test_string_double_equals_should_be_esaped
|
@@ -950,13 +997,13 @@ HAML
|
|
950
997
|
end
|
951
998
|
|
952
999
|
def test_escaped_string_double_equals
|
953
|
-
assert_equal("<p>\
|
954
|
-
assert_equal("<p>\
|
1000
|
+
assert_equal("<p>\n4&<\n</p>\n", render("%p\n &== \#{2+2}&\#{'<'}", :escape_html => true))
|
1001
|
+
assert_equal("<p>\n4&<\n</p>\n", render("%p\n &== \#{2+2}&\#{'<'}", :escape_html => false))
|
955
1002
|
end
|
956
1003
|
|
957
1004
|
def test_unescaped_string_double_equals
|
958
|
-
assert_equal("<p>\
|
959
|
-
assert_equal("<p>\
|
1005
|
+
assert_equal("<p>\n4&<\n</p>\n", render("%p\n !== \#{2+2}&\#{'<'}", :escape_html => true))
|
1006
|
+
assert_equal("<p>\n4&<\n</p>\n", render("%p\n !== \#{2+2}&\#{'<'}", :escape_html => false))
|
960
1007
|
end
|
961
1008
|
|
962
1009
|
def test_string_interpolation_should_be_esaped
|
@@ -975,18 +1022,28 @@ HAML
|
|
975
1022
|
end
|
976
1023
|
|
977
1024
|
def test_escaped_string_interpolation
|
978
|
-
assert_equal("<p>\
|
979
|
-
assert_equal("<p>\
|
1025
|
+
assert_equal("<p>\n4&<\n</p>\n", render("%p\n & \#{2+2}&\#{'<'}", :escape_html => true))
|
1026
|
+
assert_equal("<p>\n4&<\n</p>\n", render("%p\n & \#{2+2}&\#{'<'}", :escape_html => false))
|
1027
|
+
end
|
1028
|
+
|
1029
|
+
def test_escaped_string_interpolation_with_no_space
|
1030
|
+
assert_equal("<br>\n", render('&#{"<br>"}'))
|
1031
|
+
assert_equal("<span><br></span>\n", render('%span&#{"<br>"}'))
|
980
1032
|
end
|
981
1033
|
|
982
1034
|
def test_unescaped_string_interpolation
|
983
|
-
assert_equal("<p>\
|
984
|
-
assert_equal("<p>\
|
1035
|
+
assert_equal("<p>\n4&<\n</p>\n", render("%p\n ! \#{2+2}&\#{'<'}", :escape_html => true))
|
1036
|
+
assert_equal("<p>\n4&<\n</p>\n", render("%p\n ! \#{2+2}&\#{'<'}", :escape_html => false))
|
1037
|
+
end
|
1038
|
+
|
1039
|
+
def test_unescaped_string_interpolation_with_no_space
|
1040
|
+
assert_equal("<br>\n", render('!#{"<br>"}'))
|
1041
|
+
assert_equal("<span><br></span>\n", render('%span!#{"<br>"}'))
|
985
1042
|
end
|
986
1043
|
|
987
1044
|
def test_scripts_should_respect_escape_html_option
|
988
|
-
assert_equal("<p>\
|
989
|
-
assert_equal("<p>\
|
1045
|
+
assert_equal("<p>\nfoo & bar\n</p>\n", render("%p\n = 'foo & bar'", :escape_html => true))
|
1046
|
+
assert_equal("<p>\nfoo & bar\n</p>\n", render("%p\n = 'foo & bar'", :escape_html => false))
|
990
1047
|
end
|
991
1048
|
|
992
1049
|
def test_inline_scripts_should_respect_escape_html_option
|
@@ -1065,9 +1122,9 @@ HAML
|
|
1065
1122
|
|
1066
1123
|
def test_attr_wrapper
|
1067
1124
|
assert_equal("<p strange=*attrs*></p>\n", render("%p{ :strange => 'attrs'}", :attr_wrapper => '*'))
|
1068
|
-
assert_equal("<p escaped
|
1069
|
-
assert_equal("<p escaped=\"quo
|
1070
|
-
assert_equal("<p escaped=\"q
|
1125
|
+
assert_equal("<p escaped=\"quo"te\"></p>\n", render("%p{ :escaped => 'quo\"te'}", :attr_wrapper => '"'))
|
1126
|
+
assert_equal("<p escaped=\"quo'te\"></p>\n", render("%p{ :escaped => 'quo\\'te'}", :attr_wrapper => '"'))
|
1127
|
+
assert_equal("<p escaped=\"q'uo"te\"></p>\n", render("%p{ :escaped => 'q\\'uo\"te'}", :attr_wrapper => '"'))
|
1071
1128
|
assert_equal("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n", render("!!! XML", :attr_wrapper => '"', :format => :xhtml))
|
1072
1129
|
end
|
1073
1130
|
|
@@ -1085,9 +1142,7 @@ HAML
|
|
1085
1142
|
end
|
1086
1143
|
|
1087
1144
|
def test_attrs_parsed_correctly
|
1088
|
-
assert_equal("<p boom=>biddly='bar => baz'></p>\n", render("%p{'boom=>biddly' => 'bar => baz'}"))
|
1089
1145
|
assert_equal("<p foo,bar='baz, qux'></p>\n", render("%p{'foo,bar' => 'baz, qux'}"))
|
1090
|
-
assert_equal("<p escaped='quo
te'></p>\n", render("%p{ :escaped => \"quo\\nte\"}"))
|
1091
1146
|
assert_equal("<p escaped='quo4te'></p>\n", render("%p{ :escaped => \"quo\#{2 + 2}te\"}"))
|
1092
1147
|
end
|
1093
1148
|
|
@@ -1193,10 +1248,10 @@ HAML
|
|
1193
1248
|
def test_compile_error
|
1194
1249
|
render("a\nb\n- fee)\nc")
|
1195
1250
|
rescue Exception => e
|
1196
|
-
assert_match(/\(test_compile_error\):3
|
1251
|
+
assert_match(/\(test_compile_error\):3:/i, e.message)
|
1252
|
+
assert_match(/(syntax error|expecting \$end)/i, e.message)
|
1197
1253
|
else
|
1198
|
-
assert(false,
|
1199
|
-
'"a\nb\n- fee)\nc" doesn\'t produce an exception!')
|
1254
|
+
assert(false, '"a\nb\n- fee)\nc" doesn\'t produce an exception!')
|
1200
1255
|
end
|
1201
1256
|
|
1202
1257
|
def test_unbalanced_brackets
|
@@ -1205,14 +1260,39 @@ HAML
|
|
1205
1260
|
assert_equal(Haml::Error.message(:unbalanced_brackets), e.message)
|
1206
1261
|
end
|
1207
1262
|
|
1263
|
+
def test_single_line_comments_are_interpolated
|
1264
|
+
assert_equal("<!-- Hello 2 -->\n",
|
1265
|
+
render('/ Hello #{1 + 1}'))
|
1266
|
+
end
|
1267
|
+
|
1268
|
+
def test_single_line_comments_are_not_interpolated_with_suppress_eval
|
1269
|
+
assert_equal("<!-- -->\n",
|
1270
|
+
render('/ Hello #{1 + 1}', :suppress_eval => true))
|
1271
|
+
end
|
1272
|
+
|
1273
|
+
def test_single_line_comments_with_interpolation_dont_break_tabulation
|
1274
|
+
assert_equal("<!-- Hello 2 -->\nconcatted\n",
|
1275
|
+
render("/ Hello \#{1 + 1}\n- haml_concat 'concatted'"))
|
1276
|
+
end
|
1277
|
+
|
1208
1278
|
def test_balanced_conditional_comments
|
1209
1279
|
assert_equal("<!--[if !(IE 6)|(IE 7)]> Bracket: ] <![endif]-->\n",
|
1210
1280
|
render("/[if !(IE 6)|(IE 7)] Bracket: ]"))
|
1211
1281
|
end
|
1212
1282
|
|
1283
|
+
def test_downlevel_revealed_conditional_comments
|
1284
|
+
assert_equal("<!--[if !IE]><!--> A comment <!--<![endif]-->\n",
|
1285
|
+
render("/![if !IE] A comment"))
|
1286
|
+
end
|
1287
|
+
|
1288
|
+
def test_downlevel_revealed_conditional_comments_block
|
1289
|
+
assert_equal("<!--[if !IE]><!-->\nA comment\n<!--<![endif]-->\n",
|
1290
|
+
render("/![if !IE]\n A comment"))
|
1291
|
+
end
|
1292
|
+
|
1213
1293
|
def test_local_assigns_dont_modify_class
|
1214
1294
|
assert_equal("bar\n", render("= foo", :locals => {:foo => 'bar'}))
|
1215
|
-
|
1295
|
+
assert_nil(defined?(foo))
|
1216
1296
|
end
|
1217
1297
|
|
1218
1298
|
def test_object_ref_with_nil_id
|
@@ -1247,7 +1327,7 @@ HAML
|
|
1247
1327
|
|
1248
1328
|
def test_render_should_accept_a_binding_as_scope
|
1249
1329
|
string = "This is a string!"
|
1250
|
-
string.instance_variable_set(
|
1330
|
+
string.instance_variable_set(:@var, "Instance variable")
|
1251
1331
|
b = string.instance_eval do
|
1252
1332
|
var = "Local variable"
|
1253
1333
|
# Silence unavoidable warning; Ruby doesn't know we're going to use this
|
@@ -1328,15 +1408,15 @@ HAML
|
|
1328
1408
|
end
|
1329
1409
|
end
|
1330
1410
|
|
1331
|
-
def
|
1411
|
+
def test_spacing_inside_tag
|
1332
1412
|
assert_equal("<div id='outer'>\n<div id='inner'>\n<p>hello world</p>\n</div>\n</div>\n",
|
1333
|
-
render("#outer\n #inner\n %p hello world"
|
1413
|
+
render("#outer\n #inner\n %p hello world"))
|
1334
1414
|
|
1335
1415
|
assert_equal("<p>#{'s' * 75}</p>\n",
|
1336
|
-
render("%p #{'s' * 75}"
|
1416
|
+
render("%p #{'s' * 75}"))
|
1337
1417
|
|
1338
1418
|
assert_equal("<p>#{'s' * 75}</p>\n",
|
1339
|
-
render("%p= 's' * 75"
|
1419
|
+
render("%p= 's' * 75"))
|
1340
1420
|
end
|
1341
1421
|
|
1342
1422
|
def test_remove_whitespace_true
|
@@ -1353,15 +1433,13 @@ HAML
|
|
1353
1433
|
render('%div <span>foo</span> <span>bar</span>', :remove_whitespace => true))
|
1354
1434
|
end
|
1355
1435
|
|
1356
|
-
def
|
1436
|
+
def test_auto_preserve
|
1357
1437
|
assert_equal("<pre>foo
bar</pre>\n", render('%pre="foo\nbar"'))
|
1358
1438
|
assert_equal("<pre>foo\nbar</pre>\n", render("%pre\n foo\n bar"))
|
1359
|
-
assert_equal("<pre>foo\nbar</pre>\n", render('%pre="foo\nbar"', :ugly => true))
|
1360
|
-
assert_equal("<pre>foo\nbar</pre>\n", render("%pre\n foo\n bar", :ugly => true))
|
1361
1439
|
end
|
1362
1440
|
|
1363
1441
|
def test_xhtml_output_option
|
1364
|
-
assert_equal "<p>\n
|
1442
|
+
assert_equal "<p>\n<br />\n</p>\n", render("%p\n %br", :format => :xhtml)
|
1365
1443
|
assert_equal "<a />\n", render("%a/", :format => :xhtml)
|
1366
1444
|
end
|
1367
1445
|
|
@@ -1376,12 +1454,28 @@ HAML
|
|
1376
1454
|
assert_equal("<a b='a, b'></a>\n", render("%a{:b => 'a, b'}", :suppress_eval => true))
|
1377
1455
|
assert_equal("<a b='a\tb'></a>\n", render('%a{:b => "a\tb"}', :suppress_eval => true))
|
1378
1456
|
assert_equal("<a b='a\#{foo}b'></a>\n", render('%a{:b => "a\\#{foo}b"}', :suppress_eval => true))
|
1457
|
+
assert_equal("<a b='#f00'></a>\n", render("%a{:b => '#f00'}", :suppress_eval => true))
|
1379
1458
|
end
|
1380
1459
|
|
1381
1460
|
def test_dynamic_hashes_with_suppress_eval
|
1382
1461
|
assert_equal("<a></a>\n", render('%a{:b => "a #{1 + 1} b", :c => "d"}', :suppress_eval => true))
|
1383
1462
|
end
|
1384
1463
|
|
1464
|
+
def test_interpolates_instance_vars_in_attribute_values
|
1465
|
+
scope = Object.new
|
1466
|
+
scope.instance_variable_set :@foo, 'bar'
|
1467
|
+
assert_equal("<a b='a bar b'></a>\n", render('%a{:b => "a #@foo b"}', :scope => scope))
|
1468
|
+
end
|
1469
|
+
|
1470
|
+
def test_interpolates_global_vars_in_attribute_values
|
1471
|
+
# make sure the value isn't just interpolated in during template compilation
|
1472
|
+
engine = Haml::Engine.new('%a{:b => "a #$global_var_for_testing b"}')
|
1473
|
+
$global_var_for_testing = 'bar'
|
1474
|
+
assert_equal("<a b='a bar b'></a>\n", engine.to_html)
|
1475
|
+
ensure
|
1476
|
+
$global_var_for_testing = nil
|
1477
|
+
end
|
1478
|
+
|
1385
1479
|
def test_utf8_attrs
|
1386
1480
|
assert_equal("<a href='héllo'></a>\n", render("%a{:href => 'héllo'}"))
|
1387
1481
|
assert_equal("<a href='héllo'></a>\n", render("%a(href='héllo')"))
|
@@ -1390,7 +1484,7 @@ HAML
|
|
1390
1484
|
# HTML 4.0
|
1391
1485
|
|
1392
1486
|
def test_html_has_no_self_closing_tags
|
1393
|
-
assert_equal "<p>\n
|
1487
|
+
assert_equal "<p>\n<br>\n</p>\n", render("%p\n %br", :format => :html4)
|
1394
1488
|
assert_equal "<br>\n", render("%br/", :format => :html4)
|
1395
1489
|
end
|
1396
1490
|
|
@@ -1434,7 +1528,7 @@ HAML
|
|
1434
1528
|
render("%div{:data => {:one_plus_one => 1+1}}",
|
1435
1529
|
:hyphenate_data_attrs => false))
|
1436
1530
|
|
1437
|
-
assert_equal("<div data-foo='Here&#
|
1531
|
+
assert_equal("<div data-foo='Here's a "quoteful" string.'></div>\n",
|
1438
1532
|
render(%{%div{:data => {:foo => %{Here's a "quoteful" string.}}}},
|
1439
1533
|
:hyphenate_data_attrs => false)) #'
|
1440
1534
|
end
|
@@ -1453,6 +1547,21 @@ HAML
|
|
1453
1547
|
render("%div{:foo => {:baz => 'bang'}}"))
|
1454
1548
|
end
|
1455
1549
|
|
1550
|
+
def test_arbitrary_attribute_hash_merging
|
1551
|
+
assert_equal(%Q{<a aria-baz='qux' aria-foo='bar'></a>\n}, render(<<-HAML))
|
1552
|
+
- h1 = {:aria => {:foo => :bar}}
|
1553
|
+
- h2 = {:baz => :qux}
|
1554
|
+
%a{h1, :aria => h2}
|
1555
|
+
HAML
|
1556
|
+
end
|
1557
|
+
|
1558
|
+
def test_hash_method_call_in_attributes
|
1559
|
+
assert_equal(%Q{<a foo='bar' hoge='fuga'></a>\n}, render(<<-HAML))
|
1560
|
+
- hash = {:hoge => :fuga}
|
1561
|
+
%a{{foo: 'bar'}.merge(hash)}
|
1562
|
+
HAML
|
1563
|
+
end
|
1564
|
+
|
1456
1565
|
def test_html5_data_attributes_with_nested_hash
|
1457
1566
|
assert_equal("<div data-a-b='c'></div>\n", render(<<-HAML))
|
1458
1567
|
- hash = {:a => {:b => 'c'}}
|
@@ -1478,32 +1587,36 @@ HAML
|
|
1478
1587
|
end
|
1479
1588
|
|
1480
1589
|
def test_html5_data_attributes_with_attr_method
|
1481
|
-
|
1482
|
-
|
1483
|
-
|
1484
|
-
|
1590
|
+
obj = Object.new
|
1591
|
+
def obj.data_hash
|
1592
|
+
{:data => {:foo => "bar", :baz => "bang"}}
|
1593
|
+
end
|
1485
1594
|
|
1486
|
-
|
1487
|
-
|
1488
|
-
end
|
1595
|
+
def obj.data_val
|
1596
|
+
{:data => "dat"}
|
1489
1597
|
end
|
1490
1598
|
|
1491
1599
|
assert_equal("<div data-baz='bang' data-brat='wurst' data-foo='blip'></div>\n",
|
1492
|
-
render("%div{data_hash, :data => {:foo => 'blip', :brat => 'wurst'}}"))
|
1600
|
+
render("%div{data_hash, :data => {:foo => 'blip', :brat => 'wurst'}}", scope: obj))
|
1493
1601
|
assert_equal("<div data-baz='bang' data-foo='blip'></div>\n",
|
1494
|
-
render("%div{data_hash, 'data-foo' => 'blip'}"))
|
1602
|
+
render("%div{data_hash, 'data-foo' => 'blip'}", scope: obj))
|
1495
1603
|
assert_equal("<div data-baz='bang' data-foo='bar' data='dat'></div>\n",
|
1496
|
-
render("%div{data_hash, :data => 'dat'}"))
|
1604
|
+
render("%div{data_hash, :data => 'dat'}", scope: obj))
|
1497
1605
|
assert_equal("<div data-brat='wurst' data-foo='blip' data='dat'></div>\n",
|
1498
|
-
render("%div{data_val, :data => {:foo => 'blip', :brat => 'wurst'}}"))
|
1606
|
+
render("%div{data_val, :data => {:foo => 'blip', :brat => 'wurst'}}", scope: obj))
|
1607
|
+
end
|
1608
|
+
|
1609
|
+
def test_html5_data_attributes_with_identical_attribute_values
|
1610
|
+
assert_equal("<div data-x='50' data-y='50'></div>\n",
|
1611
|
+
render("%div{:data => {:x => 50, :y => 50}}"))
|
1499
1612
|
end
|
1500
1613
|
|
1501
1614
|
def test_xml_doc_using_html5_format_and_mime_type
|
1502
1615
|
assert_equal(<<XML, render(<<HAML, { :format => :html5, :mime_type => 'text/xml' }))
|
1503
1616
|
<?xml version='1.0' encoding='utf-8' ?>
|
1504
1617
|
<root>
|
1505
|
-
|
1506
|
-
|
1618
|
+
<element />
|
1619
|
+
<hr />
|
1507
1620
|
</root>
|
1508
1621
|
XML
|
1509
1622
|
!!! XML
|
@@ -1517,8 +1630,8 @@ HAML
|
|
1517
1630
|
assert_equal(<<XML, render(<<HAML, { :format => :html4, :mime_type => 'text/xml' }))
|
1518
1631
|
<?xml version='1.0' encoding='utf-8' ?>
|
1519
1632
|
<root>
|
1520
|
-
|
1521
|
-
|
1633
|
+
<element />
|
1634
|
+
<hr />
|
1522
1635
|
</root>
|
1523
1636
|
XML
|
1524
1637
|
!!! XML
|
@@ -1584,10 +1697,10 @@ HAML
|
|
1584
1697
|
|
1585
1698
|
def test_new_attribute_parsing
|
1586
1699
|
assert_equal("<a a2='b2'>bar</a>\n", render("%a(a2=b2) bar", :locals => {:b2 => 'b2'}))
|
1587
|
-
assert_equal(%Q{<a a='foo
|
1588
|
-
assert_equal(%Q{<a a=
|
1589
|
-
assert_equal(%Q{<a a='foo
|
1590
|
-
assert_equal(%Q{<a a=
|
1700
|
+
assert_equal(%Q{<a a='foo"bar'>bar</a>\n}, render(%q{%a(a="#{'foo"bar'}") bar})) #'
|
1701
|
+
assert_equal(%Q{<a a='foo'bar'>bar</a>\n}, render(%q{%a(a="#{"foo'bar"}") bar})) #'
|
1702
|
+
assert_equal(%Q{<a a='foo"bar'>bar</a>\n}, render(%q{%a(a='foo"bar') bar}))
|
1703
|
+
assert_equal(%Q{<a a='foo'bar'>bar</a>\n}, render(%q{%a(a="foo'bar") bar}))
|
1591
1704
|
assert_equal("<a a:b='foo'>bar</a>\n", render("%a(a:b='foo') bar"))
|
1592
1705
|
assert_equal("<a a='foo' b='bar'>bar</a>\n", render("%a(a = 'foo' b = 'bar') bar"))
|
1593
1706
|
assert_equal("<a a='foo' b='bar'>bar</a>\n", render("%a(a = foo b = bar) bar", :locals => {:foo => 'foo', :bar => 'bar'}))
|
@@ -1597,11 +1710,11 @@ HAML
|
|
1597
1710
|
end
|
1598
1711
|
|
1599
1712
|
def test_new_attribute_escaping
|
1600
|
-
assert_equal(%Q{<a a='foo
|
1601
|
-
assert_equal(%Q{<a a='foo
|
1713
|
+
assert_equal(%Q{<a a='foo " bar'>bar</a>\n}, render(%q{%a(a="foo \" bar") bar}))
|
1714
|
+
assert_equal(%Q{<a a='foo \\" bar'>bar</a>\n}, render(%q{%a(a="foo \\\\\" bar") bar}))
|
1602
1715
|
|
1603
|
-
assert_equal(%Q{<a a=
|
1604
|
-
assert_equal(%Q{<a a=
|
1716
|
+
assert_equal(%Q{<a a='foo ' bar'>bar</a>\n}, render(%q{%a(a='foo \' bar') bar}))
|
1717
|
+
assert_equal(%Q{<a a='foo \\' bar'>bar</a>\n}, render(%q{%a(a='foo \\\\\' bar') bar}))
|
1605
1718
|
|
1606
1719
|
assert_equal(%Q{<a a='foo \\ bar'>bar</a>\n}, render(%q{%a(a="foo \\\\ bar") bar}))
|
1607
1720
|
assert_equal(%Q{<a a='foo \#{1 + 1} bar'>bar</a>\n}, render(%q{%a(a="foo \#{1 + 1} bar") bar}))
|
@@ -1630,6 +1743,8 @@ HAML
|
|
1630
1743
|
locals = {:b => 'b', :d => 'd'}
|
1631
1744
|
assert_equal("<p a='b' c='d'></p>\n", render("%p{:a => b}(c=d)", :locals => locals))
|
1632
1745
|
assert_equal("<p a='b' c='d'></p>\n", render("%p(a=b){:c => d}", :locals => locals))
|
1746
|
+
|
1747
|
+
assert_equal("<p id='b_d'></p>\n<p id='b_d'></p>\n", render("%p(id=b){id:d}\n%p(id=b){id:d}", locals: locals))
|
1633
1748
|
end
|
1634
1749
|
|
1635
1750
|
# Ruby Multiline
|
@@ -1677,11 +1792,7 @@ HAML
|
|
1677
1792
|
end
|
1678
1793
|
|
1679
1794
|
def test_ruby_character_literals_are_not_continuation
|
1680
|
-
html =
|
1681
|
-
"44\n44\n<p>foo</p>\n"
|
1682
|
-
else
|
1683
|
-
",\n,\n<p>foo</p>\n"
|
1684
|
-
end
|
1795
|
+
html = ",\n,\n<p>foo</p>\n"
|
1685
1796
|
assert_equal(html, render(<<HAML))
|
1686
1797
|
= ?,
|
1687
1798
|
= ?\,
|
@@ -1733,8 +1844,7 @@ HAML
|
|
1733
1844
|
|
1734
1845
|
def test_loud_ruby_multiline_with_block
|
1735
1846
|
assert_equal(<<HTML, render(<<HAML))
|
1736
|
-
#{%w[far faz fang]}
|
1737
|
-
<p>foo</p>
|
1847
|
+
#{%w[far faz fang]}<p>foo</p>
|
1738
1848
|
<p>bar</p>
|
1739
1849
|
HTML
|
1740
1850
|
= ["bar",
|
@@ -1847,7 +1957,7 @@ HAML
|
|
1847
1957
|
def test_utf_8_bom
|
1848
1958
|
assert_equal <<HTML, render(<<HAML)
|
1849
1959
|
<div class='foo'>
|
1850
|
-
|
1960
|
+
<p>baz</p>
|
1851
1961
|
</div>
|
1852
1962
|
HTML
|
1853
1963
|
\xEF\xBB\xBF.foo
|
@@ -1855,60 +1965,59 @@ HTML
|
|
1855
1965
|
HAML
|
1856
1966
|
end
|
1857
1967
|
|
1858
|
-
|
1859
|
-
|
1860
|
-
assert_equal(Encoding.find("utf-8"), render(<<HAML.encode("us-ascii")).encoding)
|
1968
|
+
def test_default_encoding
|
1969
|
+
assert_equal(Encoding.find("utf-8"), render(<<HAML.encode("us-ascii")).encoding)
|
1861
1970
|
%p bar
|
1862
1971
|
%p foo
|
1863
1972
|
HAML
|
1864
|
-
|
1973
|
+
end
|
1865
1974
|
|
1866
|
-
|
1867
|
-
|
1975
|
+
def test_fake_ascii_encoding
|
1976
|
+
assert_encoded_equal(<<HTML.force_encoding("ascii-8bit"), render(<<HAML, :encoding => "ascii-8bit"))
|
1868
1977
|
<p>bâr</p>
|
1869
1978
|
<p>föö</p>
|
1870
1979
|
HTML
|
1871
1980
|
%p bâr
|
1872
1981
|
%p föö
|
1873
1982
|
HAML
|
1874
|
-
|
1983
|
+
end
|
1875
1984
|
|
1876
|
-
|
1877
|
-
|
1878
|
-
|
1985
|
+
def test_convert_template_render_proc
|
1986
|
+
assert_converts_template_properly {|e| e.render_proc.call}
|
1987
|
+
end
|
1879
1988
|
|
1880
|
-
|
1881
|
-
|
1882
|
-
|
1989
|
+
def test_convert_template_render
|
1990
|
+
assert_converts_template_properly {|e| e.render}
|
1991
|
+
end
|
1883
1992
|
|
1884
|
-
|
1885
|
-
|
1886
|
-
|
1887
|
-
|
1888
|
-
|
1889
|
-
end
|
1993
|
+
def test_convert_template_def_method
|
1994
|
+
assert_converts_template_properly do |e|
|
1995
|
+
o = Object.new
|
1996
|
+
e.def_method(o, :render)
|
1997
|
+
o.render
|
1890
1998
|
end
|
1999
|
+
end
|
1891
2000
|
|
1892
|
-
|
1893
|
-
|
1894
|
-
|
1895
|
-
|
1896
|
-
|
1897
|
-
|
1898
|
-
|
2001
|
+
def test_encoding_error
|
2002
|
+
render("foo\nbar\nb\xFEaz".force_encoding("utf-8"))
|
2003
|
+
assert(false, "Expected exception")
|
2004
|
+
rescue Haml::Error => e
|
2005
|
+
assert_equal(3, e.line)
|
2006
|
+
assert_match(/Invalid .* character/, e.message)
|
2007
|
+
end
|
1899
2008
|
|
1900
|
-
|
1901
|
-
|
1902
|
-
|
1903
|
-
|
1904
|
-
|
1905
|
-
|
1906
|
-
|
1907
|
-
|
1908
|
-
|
2009
|
+
def test_ascii_incompatible_encoding_error
|
2010
|
+
template = "foo\nbar\nb_z".encode("utf-16le")
|
2011
|
+
template[9] = "\xFE".force_encoding("utf-16le")
|
2012
|
+
render(template)
|
2013
|
+
assert(false, "Expected exception")
|
2014
|
+
rescue Haml::Error => e
|
2015
|
+
assert_equal(3, e.line)
|
2016
|
+
assert_match(/Invalid .* character/, e.message)
|
2017
|
+
end
|
1909
2018
|
|
1910
|
-
|
1911
|
-
|
2019
|
+
def test_same_coding_comment_as_encoding
|
2020
|
+
assert_renders_encoded(<<HTML, <<HAML)
|
1912
2021
|
<p>bâr</p>
|
1913
2022
|
<p>föö</p>
|
1914
2023
|
HTML
|
@@ -1916,34 +2025,33 @@ HTML
|
|
1916
2025
|
%p bâr
|
1917
2026
|
%p föö
|
1918
2027
|
HAML
|
1919
|
-
|
1920
|
-
|
1921
|
-
def test_coding_comments
|
1922
|
-
assert_valid_encoding_comment("-# coding: ibm866")
|
1923
|
-
assert_valid_encoding_comment("-# CodINg: IbM866")
|
1924
|
-
assert_valid_encoding_comment("-#coding:ibm866")
|
1925
|
-
assert_valid_encoding_comment("-# CodINg= ibm866")
|
1926
|
-
assert_valid_encoding_comment("-# foo BAR FAOJcoding: ibm866")
|
1927
|
-
assert_valid_encoding_comment("-# coding: ibm866 ASFJ (&(&#!$")
|
1928
|
-
assert_valid_encoding_comment("-# -*- coding: ibm866")
|
1929
|
-
assert_valid_encoding_comment("-# coding: ibm866 -*- coding: blah")
|
1930
|
-
assert_valid_encoding_comment("-# -*- coding: ibm866 -*-")
|
1931
|
-
assert_valid_encoding_comment("-# -*- encoding: ibm866 -*-")
|
1932
|
-
assert_valid_encoding_comment('-# -*- coding: "ibm866" -*-')
|
1933
|
-
assert_valid_encoding_comment("-#-*-coding:ibm866-*-")
|
1934
|
-
assert_valid_encoding_comment("-#-*-coding:ibm866-*-")
|
1935
|
-
assert_valid_encoding_comment("-# -*- foo: bar; coding: ibm866; baz: bang -*-")
|
1936
|
-
assert_valid_encoding_comment("-# foo bar coding: baz -*- coding: ibm866 -*-")
|
1937
|
-
assert_valid_encoding_comment("-# -*- coding: ibm866 -*- foo bar coding: baz")
|
1938
|
-
end
|
2028
|
+
end
|
1939
2029
|
|
1940
|
-
|
1941
|
-
|
2030
|
+
def test_coding_comments
|
2031
|
+
assert_valid_encoding_comment("-# coding: ibm866")
|
2032
|
+
assert_valid_encoding_comment("-# CodINg: IbM866")
|
2033
|
+
assert_valid_encoding_comment("-#coding:ibm866")
|
2034
|
+
assert_valid_encoding_comment("-# CodINg= ibm866")
|
2035
|
+
assert_valid_encoding_comment("-# foo BAR FAOJcoding: ibm866")
|
2036
|
+
assert_valid_encoding_comment("-# coding: ibm866 ASFJ (&(&#!$")
|
2037
|
+
assert_valid_encoding_comment("-# -*- coding: ibm866")
|
2038
|
+
assert_valid_encoding_comment("-# coding: ibm866 -*- coding: blah")
|
2039
|
+
assert_valid_encoding_comment("-# -*- coding: ibm866 -*-")
|
2040
|
+
assert_valid_encoding_comment("-# -*- encoding: ibm866 -*-")
|
2041
|
+
assert_valid_encoding_comment('-# -*- coding: "ibm866" -*-')
|
2042
|
+
assert_valid_encoding_comment("-#-*-coding:ibm866-*-")
|
2043
|
+
assert_valid_encoding_comment("-#-*-coding:ibm866-*-")
|
2044
|
+
assert_valid_encoding_comment("-# -*- foo: bar; coding: ibm866; baz: bang -*-")
|
2045
|
+
assert_valid_encoding_comment("-# foo bar coding: baz -*- coding: ibm866 -*-")
|
2046
|
+
assert_valid_encoding_comment("-# -*- coding: ibm866 -*- foo bar coding: baz")
|
2047
|
+
end
|
2048
|
+
|
2049
|
+
def test_different_coding_than_system
|
2050
|
+
assert_renders_encoded(<<HTML.encode("IBM866"), <<HAML.encode("IBM866"))
|
1942
2051
|
<p>тАЬ</p>
|
1943
2052
|
HTML
|
1944
2053
|
%p тАЬ
|
1945
2054
|
HAML
|
1946
|
-
end
|
1947
2055
|
end
|
1948
2056
|
|
1949
2057
|
def test_block_spacing
|
@@ -1958,6 +2066,28 @@ HAML
|
|
1958
2066
|
end
|
1959
2067
|
end
|
1960
2068
|
|
2069
|
+
def test_tracing
|
2070
|
+
result = render('%p{:class => "hello"}', :trace => true, :filename => 'foo').strip
|
2071
|
+
assert_equal "<p class='hello' data-trace='foo:1'></p>", result
|
2072
|
+
end
|
2073
|
+
|
2074
|
+
def test_unsafe_dynamic_attribute_name_raises_invalid_attribute_name_error
|
2075
|
+
assert_raises(Haml::InvalidAttributeNameError) do
|
2076
|
+
render(<<-HAML)
|
2077
|
+
- params = { 'x /><script>alert(1);</script><div x' => 'hello' }
|
2078
|
+
%div{ data: params }
|
2079
|
+
HAML
|
2080
|
+
end
|
2081
|
+
end
|
2082
|
+
|
2083
|
+
def test_unsafe_static_attribute_name_raises_invalid_attribute_name_error
|
2084
|
+
assert_raises(Haml::InvalidAttributeNameError) do
|
2085
|
+
render(<<-HAML)
|
2086
|
+
%div{ 'x /><script>alert(1);</script><div x' => 'hello' }
|
2087
|
+
HAML
|
2088
|
+
end
|
2089
|
+
end
|
2090
|
+
|
1961
2091
|
private
|
1962
2092
|
|
1963
2093
|
def assert_valid_encoding_comment(comment)
|