liquid 2.6.1 → 4.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (130) hide show
  1. checksums.yaml +5 -5
  2. data/History.md +194 -29
  3. data/{MIT-LICENSE → LICENSE} +0 -0
  4. data/README.md +60 -2
  5. data/lib/liquid.rb +25 -14
  6. data/lib/liquid/block.rb +47 -96
  7. data/lib/liquid/block_body.rb +143 -0
  8. data/lib/liquid/condition.rb +70 -39
  9. data/lib/liquid/context.rb +116 -157
  10. data/lib/liquid/document.rb +19 -9
  11. data/lib/liquid/drop.rb +31 -14
  12. data/lib/liquid/errors.rb +54 -10
  13. data/lib/liquid/expression.rb +49 -0
  14. data/lib/liquid/extensions.rb +19 -7
  15. data/lib/liquid/file_system.rb +25 -14
  16. data/lib/liquid/forloop_drop.rb +42 -0
  17. data/lib/liquid/i18n.rb +39 -0
  18. data/lib/liquid/interrupts.rb +2 -3
  19. data/lib/liquid/lexer.rb +55 -0
  20. data/lib/liquid/locales/en.yml +26 -0
  21. data/lib/liquid/parse_context.rb +38 -0
  22. data/lib/liquid/parse_tree_visitor.rb +42 -0
  23. data/lib/liquid/parser.rb +90 -0
  24. data/lib/liquid/parser_switching.rb +31 -0
  25. data/lib/liquid/profiler.rb +158 -0
  26. data/lib/liquid/profiler/hooks.rb +23 -0
  27. data/lib/liquid/range_lookup.rb +37 -0
  28. data/lib/liquid/resource_limits.rb +23 -0
  29. data/lib/liquid/standardfilters.rb +311 -77
  30. data/lib/liquid/strainer.rb +39 -26
  31. data/lib/liquid/tablerowloop_drop.rb +62 -0
  32. data/lib/liquid/tag.rb +28 -11
  33. data/lib/liquid/tags/assign.rb +34 -10
  34. data/lib/liquid/tags/break.rb +1 -4
  35. data/lib/liquid/tags/capture.rb +11 -9
  36. data/lib/liquid/tags/case.rb +37 -22
  37. data/lib/liquid/tags/comment.rb +10 -3
  38. data/lib/liquid/tags/continue.rb +1 -4
  39. data/lib/liquid/tags/cycle.rb +20 -14
  40. data/lib/liquid/tags/decrement.rb +4 -8
  41. data/lib/liquid/tags/for.rb +121 -60
  42. data/lib/liquid/tags/if.rb +73 -30
  43. data/lib/liquid/tags/ifchanged.rb +3 -5
  44. data/lib/liquid/tags/include.rb +77 -46
  45. data/lib/liquid/tags/increment.rb +4 -8
  46. data/lib/liquid/tags/raw.rb +35 -10
  47. data/lib/liquid/tags/table_row.rb +62 -0
  48. data/lib/liquid/tags/unless.rb +6 -9
  49. data/lib/liquid/template.rb +130 -32
  50. data/lib/liquid/tokenizer.rb +31 -0
  51. data/lib/liquid/truffle.rb +5 -0
  52. data/lib/liquid/utils.rb +57 -4
  53. data/lib/liquid/variable.rb +121 -30
  54. data/lib/liquid/variable_lookup.rb +88 -0
  55. data/lib/liquid/version.rb +2 -1
  56. data/test/fixtures/en_locale.yml +9 -0
  57. data/test/integration/assign_test.rb +48 -0
  58. data/test/integration/blank_test.rb +106 -0
  59. data/test/integration/block_test.rb +12 -0
  60. data/test/{liquid → integration}/capture_test.rb +13 -3
  61. data/test/integration/context_test.rb +32 -0
  62. data/test/integration/document_test.rb +19 -0
  63. data/test/integration/drop_test.rb +273 -0
  64. data/test/integration/error_handling_test.rb +260 -0
  65. data/test/integration/filter_test.rb +178 -0
  66. data/test/integration/hash_ordering_test.rb +23 -0
  67. data/test/integration/output_test.rb +123 -0
  68. data/test/integration/parse_tree_visitor_test.rb +247 -0
  69. data/test/integration/parsing_quirks_test.rb +122 -0
  70. data/test/integration/render_profiling_test.rb +154 -0
  71. data/test/integration/security_test.rb +80 -0
  72. data/test/integration/standard_filter_test.rb +776 -0
  73. data/test/{liquid → integration}/tags/break_tag_test.rb +2 -3
  74. data/test/{liquid → integration}/tags/continue_tag_test.rb +1 -2
  75. data/test/integration/tags/for_tag_test.rb +410 -0
  76. data/test/integration/tags/if_else_tag_test.rb +188 -0
  77. data/test/integration/tags/include_tag_test.rb +253 -0
  78. data/test/integration/tags/increment_tag_test.rb +23 -0
  79. data/test/{liquid → integration}/tags/raw_tag_test.rb +9 -2
  80. data/test/integration/tags/standard_tag_test.rb +296 -0
  81. data/test/integration/tags/statements_test.rb +111 -0
  82. data/test/{liquid/tags/html_tag_test.rb → integration/tags/table_row_test.rb} +25 -24
  83. data/test/integration/tags/unless_else_tag_test.rb +26 -0
  84. data/test/integration/template_test.rb +332 -0
  85. data/test/integration/trim_mode_test.rb +529 -0
  86. data/test/integration/variable_test.rb +96 -0
  87. data/test/test_helper.rb +106 -19
  88. data/test/truffle/truffle_test.rb +9 -0
  89. data/test/{liquid/block_test.rb → unit/block_unit_test.rb} +9 -9
  90. data/test/unit/condition_unit_test.rb +166 -0
  91. data/test/{liquid/context_test.rb → unit/context_unit_test.rb} +85 -74
  92. data/test/unit/file_system_unit_test.rb +35 -0
  93. data/test/unit/i18n_unit_test.rb +37 -0
  94. data/test/unit/lexer_unit_test.rb +51 -0
  95. data/test/unit/parser_unit_test.rb +82 -0
  96. data/test/{liquid/regexp_test.rb → unit/regexp_unit_test.rb} +4 -4
  97. data/test/unit/strainer_unit_test.rb +164 -0
  98. data/test/unit/tag_unit_test.rb +21 -0
  99. data/test/unit/tags/case_tag_unit_test.rb +10 -0
  100. data/test/unit/tags/for_tag_unit_test.rb +13 -0
  101. data/test/unit/tags/if_tag_unit_test.rb +8 -0
  102. data/test/unit/template_unit_test.rb +78 -0
  103. data/test/unit/tokenizer_unit_test.rb +55 -0
  104. data/test/unit/variable_unit_test.rb +162 -0
  105. metadata +157 -77
  106. data/lib/extras/liquid_view.rb +0 -51
  107. data/lib/liquid/htmltags.rb +0 -74
  108. data/lib/liquid/module_ex.rb +0 -62
  109. data/test/liquid/assign_test.rb +0 -21
  110. data/test/liquid/condition_test.rb +0 -127
  111. data/test/liquid/drop_test.rb +0 -180
  112. data/test/liquid/error_handling_test.rb +0 -81
  113. data/test/liquid/file_system_test.rb +0 -29
  114. data/test/liquid/filter_test.rb +0 -125
  115. data/test/liquid/hash_ordering_test.rb +0 -25
  116. data/test/liquid/module_ex_test.rb +0 -87
  117. data/test/liquid/output_test.rb +0 -116
  118. data/test/liquid/parsing_quirks_test.rb +0 -52
  119. data/test/liquid/security_test.rb +0 -64
  120. data/test/liquid/standard_filter_test.rb +0 -251
  121. data/test/liquid/strainer_test.rb +0 -52
  122. data/test/liquid/tags/for_tag_test.rb +0 -297
  123. data/test/liquid/tags/if_else_tag_test.rb +0 -166
  124. data/test/liquid/tags/include_tag_test.rb +0 -166
  125. data/test/liquid/tags/increment_tag_test.rb +0 -24
  126. data/test/liquid/tags/standard_tag_test.rb +0 -295
  127. data/test/liquid/tags/statements_test.rb +0 -134
  128. data/test/liquid/tags/unless_else_tag_test.rb +0 -26
  129. data/test/liquid/template_test.rb +0 -146
  130. data/test/liquid/variable_test.rb +0 -186
@@ -1,81 +0,0 @@
1
- require 'test_helper'
2
-
3
- class ErrorDrop < Liquid::Drop
4
- def standard_error
5
- raise Liquid::StandardError, 'standard error'
6
- end
7
-
8
- def argument_error
9
- raise Liquid::ArgumentError, 'argument error'
10
- end
11
-
12
- def syntax_error
13
- raise Liquid::SyntaxError, 'syntax error'
14
- end
15
-
16
- def exception
17
- raise Exception, 'exception'
18
- end
19
-
20
- end
21
-
22
- class ErrorHandlingTest < Test::Unit::TestCase
23
- include Liquid
24
-
25
- def test_standard_error
26
- assert_nothing_raised do
27
- template = Liquid::Template.parse( ' {{ errors.standard_error }} ' )
28
- assert_equal ' Liquid error: standard error ', template.render('errors' => ErrorDrop.new)
29
-
30
- assert_equal 1, template.errors.size
31
- assert_equal StandardError, template.errors.first.class
32
- end
33
- end
34
-
35
- def test_syntax
36
-
37
- assert_nothing_raised do
38
-
39
- template = Liquid::Template.parse( ' {{ errors.syntax_error }} ' )
40
- assert_equal ' Liquid syntax error: syntax error ', template.render('errors' => ErrorDrop.new)
41
-
42
- assert_equal 1, template.errors.size
43
- assert_equal SyntaxError, template.errors.first.class
44
-
45
- end
46
- end
47
-
48
- def test_argument
49
- assert_nothing_raised do
50
-
51
- template = Liquid::Template.parse( ' {{ errors.argument_error }} ' )
52
- assert_equal ' Liquid error: argument error ', template.render('errors' => ErrorDrop.new)
53
-
54
- assert_equal 1, template.errors.size
55
- assert_equal ArgumentError, template.errors.first.class
56
- end
57
- end
58
-
59
- def test_missing_endtag_parse_time_error
60
- assert_raise(Liquid::SyntaxError) do
61
- template = Liquid::Template.parse(' {% for a in b %} ... ')
62
- end
63
- end
64
-
65
- def test_unrecognized_operator
66
- assert_nothing_raised do
67
- template = Liquid::Template.parse(' {% if 1 =! 2 %}ok{% endif %} ')
68
- assert_equal ' Liquid error: Unknown operator =! ', template.render
69
- assert_equal 1, template.errors.size
70
- assert_equal Liquid::ArgumentError, template.errors.first.class
71
- end
72
- end
73
-
74
- # Liquid should not catch Exceptions that are not subclasses of StandardError, like Interrupt and NoMemoryError
75
- def test_exceptions_propagate
76
- assert_raise Exception do
77
- template = Liquid::Template.parse( ' {{ errors.exception }} ' )
78
- template.render('errors' => ErrorDrop.new)
79
- end
80
- end
81
- end # ErrorHandlingTest
@@ -1,29 +0,0 @@
1
- require 'test_helper'
2
-
3
- class FileSystemTest < Test::Unit::TestCase
4
- include Liquid
5
-
6
- def test_default
7
- assert_raise(FileSystemError) do
8
- BlankFileSystem.new.read_template_file("dummy", {'dummy'=>'smarty'})
9
- end
10
- end
11
-
12
- def test_local
13
- file_system = Liquid::LocalFileSystem.new("/some/path")
14
- assert_equal "/some/path/_mypartial.liquid" , file_system.full_path("mypartial")
15
- assert_equal "/some/path/dir/_mypartial.liquid", file_system.full_path("dir/mypartial")
16
-
17
- assert_raise(FileSystemError) do
18
- file_system.full_path("../dir/mypartial")
19
- end
20
-
21
- assert_raise(FileSystemError) do
22
- file_system.full_path("/dir/../../dir/mypartial")
23
- end
24
-
25
- assert_raise(FileSystemError) do
26
- file_system.full_path("/etc/passwd")
27
- end
28
- end
29
- end # FileSystemTest
@@ -1,125 +0,0 @@
1
- require 'test_helper'
2
-
3
- module MoneyFilter
4
- def money(input)
5
- sprintf(' %d$ ', input)
6
- end
7
-
8
- def money_with_underscore(input)
9
- sprintf(' %d$ ', input)
10
- end
11
- end
12
-
13
- module CanadianMoneyFilter
14
- def money(input)
15
- sprintf(' %d$ CAD ', input)
16
- end
17
- end
18
-
19
- module SubstituteFilter
20
- def substitute(input, params={})
21
- input.gsub(/%\{(\w+)\}/) { |match| params[$1] }
22
- end
23
- end
24
-
25
- class FiltersTest < Test::Unit::TestCase
26
- include Liquid
27
-
28
- def setup
29
- @context = Context.new
30
- end
31
-
32
- def test_local_filter
33
- @context['var'] = 1000
34
- @context.add_filters(MoneyFilter)
35
-
36
- assert_equal ' 1000$ ', Variable.new("var | money").render(@context)
37
- end
38
-
39
- def test_underscore_in_filter_name
40
- @context['var'] = 1000
41
- @context.add_filters(MoneyFilter)
42
- assert_equal ' 1000$ ', Variable.new("var | money_with_underscore").render(@context)
43
- end
44
-
45
- def test_second_filter_overwrites_first
46
- @context['var'] = 1000
47
- @context.add_filters(MoneyFilter)
48
- @context.add_filters(CanadianMoneyFilter)
49
-
50
- assert_equal ' 1000$ CAD ', Variable.new("var | money").render(@context)
51
- end
52
-
53
- def test_size
54
- @context['var'] = 'abcd'
55
- @context.add_filters(MoneyFilter)
56
-
57
- assert_equal 4, Variable.new("var | size").render(@context)
58
- end
59
-
60
- def test_join
61
- @context['var'] = [1,2,3,4]
62
-
63
- assert_equal "1 2 3 4", Variable.new("var | join").render(@context)
64
- end
65
-
66
- def test_sort
67
- @context['value'] = 3
68
- @context['numbers'] = [2,1,4,3]
69
- @context['words'] = ['expected', 'as', 'alphabetic']
70
- @context['arrays'] = [['flattened'], ['are']]
71
-
72
- assert_equal [1,2,3,4], Variable.new("numbers | sort").render(@context)
73
- assert_equal ['alphabetic', 'as', 'expected'], Variable.new("words | sort").render(@context)
74
- assert_equal [3], Variable.new("value | sort").render(@context)
75
- assert_equal ['are', 'flattened'], Variable.new("arrays | sort").render(@context)
76
- end
77
-
78
- def test_strip_html
79
- @context['var'] = "<b>bla blub</a>"
80
-
81
- assert_equal "bla blub", Variable.new("var | strip_html").render(@context)
82
- end
83
-
84
- def test_strip_html_ignore_comments_with_html
85
- @context['var'] = "<!-- split and some <ul> tag --><b>bla blub</a>"
86
-
87
- assert_equal "bla blub", Variable.new("var | strip_html").render(@context)
88
- end
89
-
90
- def test_capitalize
91
- @context['var'] = "blub"
92
-
93
- assert_equal "Blub", Variable.new("var | capitalize").render(@context)
94
- end
95
-
96
- def test_nonexistent_filter_is_ignored
97
- @context['var'] = 1000
98
-
99
- assert_equal 1000, Variable.new("var | xyzzy").render(@context)
100
- end
101
-
102
- def test_filter_with_keyword_arguments
103
- @context['surname'] = 'john'
104
- @context.add_filters(SubstituteFilter)
105
- output = Variable.new(%! 'hello %{first_name}, %{last_name}' | substitute: first_name: surname, last_name: 'doe' !).render(@context)
106
- assert_equal 'hello john, doe', output
107
- end
108
- end
109
-
110
- class FiltersInTemplate < Test::Unit::TestCase
111
- include Liquid
112
-
113
- def test_local_global
114
- Template.register_filter(MoneyFilter)
115
-
116
- assert_equal " 1000$ ", Template.parse("{{1000 | money}}").render(nil, nil)
117
- assert_equal " 1000$ CAD ", Template.parse("{{1000 | money}}").render(nil, :filters => CanadianMoneyFilter)
118
- assert_equal " 1000$ CAD ", Template.parse("{{1000 | money}}").render(nil, :filters => [CanadianMoneyFilter])
119
- end
120
-
121
- def test_local_filter_with_deprecated_syntax
122
- assert_equal " 1000$ CAD ", Template.parse("{{1000 | money}}").render(nil, CanadianMoneyFilter)
123
- assert_equal " 1000$ CAD ", Template.parse("{{1000 | money}}").render(nil, [CanadianMoneyFilter])
124
- end
125
- end # FiltersTest
@@ -1,25 +0,0 @@
1
- require 'test_helper'
2
-
3
- module MoneyFilter
4
- def money(input)
5
- sprintf(' %d$ ', input)
6
- end
7
- end
8
-
9
- module CanadianMoneyFilter
10
- def money(input)
11
- sprintf(' %d$ CAD ', input)
12
- end
13
- end
14
-
15
- class HashOrderingTest < Test::Unit::TestCase
16
- include Liquid
17
-
18
- def test_global_register_order
19
- Template.register_filter(MoneyFilter)
20
- Template.register_filter(CanadianMoneyFilter)
21
-
22
- assert_equal " 1000$ CAD ", Template.parse("{{1000 | money}}").render(nil, nil)
23
- end
24
-
25
- end
@@ -1,87 +0,0 @@
1
- require 'test_helper'
2
-
3
- class TestClassA
4
- liquid_methods :allowedA, :chainedB
5
- def allowedA
6
- 'allowedA'
7
- end
8
- def restrictedA
9
- 'restrictedA'
10
- end
11
- def chainedB
12
- TestClassB.new
13
- end
14
- end
15
-
16
- class TestClassB
17
- liquid_methods :allowedB, :chainedC
18
- def allowedB
19
- 'allowedB'
20
- end
21
- def chainedC
22
- TestClassC.new
23
- end
24
- end
25
-
26
- class TestClassC
27
- liquid_methods :allowedC
28
- def allowedC
29
- 'allowedC'
30
- end
31
- end
32
-
33
- class TestClassC::LiquidDropClass
34
- def another_allowedC
35
- 'another_allowedC'
36
- end
37
- end
38
-
39
- class ModuleExTest < Test::Unit::TestCase
40
- include Liquid
41
-
42
- def setup
43
- @a = TestClassA.new
44
- @b = TestClassB.new
45
- @c = TestClassC.new
46
- end
47
-
48
- def test_should_create_LiquidDropClass
49
- assert TestClassA::LiquidDropClass
50
- assert TestClassB::LiquidDropClass
51
- assert TestClassC::LiquidDropClass
52
- end
53
-
54
- def test_should_respond_to_liquid
55
- assert @a.respond_to?(:to_liquid)
56
- assert @b.respond_to?(:to_liquid)
57
- assert @c.respond_to?(:to_liquid)
58
- end
59
-
60
- def test_should_return_LiquidDropClass_object
61
- assert @a.to_liquid.is_a?(TestClassA::LiquidDropClass)
62
- assert @b.to_liquid.is_a?(TestClassB::LiquidDropClass)
63
- assert @c.to_liquid.is_a?(TestClassC::LiquidDropClass)
64
- end
65
-
66
- def test_should_respond_to_liquid_methods
67
- assert @a.to_liquid.respond_to?(:allowedA)
68
- assert @a.to_liquid.respond_to?(:chainedB)
69
- assert @b.to_liquid.respond_to?(:allowedB)
70
- assert @b.to_liquid.respond_to?(:chainedC)
71
- assert @c.to_liquid.respond_to?(:allowedC)
72
- assert @c.to_liquid.respond_to?(:another_allowedC)
73
- end
74
-
75
- def test_should_not_respond_to_restricted_methods
76
- assert ! @a.to_liquid.respond_to?(:restricted)
77
- end
78
-
79
- def test_should_use_regular_objects_as_drops
80
- assert_equal 'allowedA', Liquid::Template.parse("{{ a.allowedA }}").render('a'=>@a)
81
- assert_equal 'allowedB', Liquid::Template.parse("{{ a.chainedB.allowedB }}").render('a'=>@a)
82
- assert_equal 'allowedC', Liquid::Template.parse("{{ a.chainedB.chainedC.allowedC }}").render('a'=>@a)
83
- assert_equal 'another_allowedC', Liquid::Template.parse("{{ a.chainedB.chainedC.another_allowedC }}").render('a'=>@a)
84
- assert_equal '', Liquid::Template.parse("{{ a.restricted }}").render('a'=>@a)
85
- assert_equal '', Liquid::Template.parse("{{ a.unknown }}").render('a'=>@a)
86
- end
87
- end # ModuleExTest
@@ -1,116 +0,0 @@
1
- require 'test_helper'
2
-
3
- module FunnyFilter
4
- def make_funny(input)
5
- 'LOL'
6
- end
7
-
8
- def cite_funny(input)
9
- "LOL: #{input}"
10
- end
11
-
12
- def add_smiley(input, smiley = ":-)")
13
- "#{input} #{smiley}"
14
- end
15
-
16
- def add_tag(input, tag = "p", id = "foo")
17
- %|<#{tag} id="#{id}">#{input}</#{tag}>|
18
- end
19
-
20
- def paragraph(input)
21
- "<p>#{input}</p>"
22
- end
23
-
24
- def link_to(name, url)
25
- %|<a href="#{url}">#{name}</a>|
26
- end
27
-
28
- end
29
-
30
- class OutputTest < Test::Unit::TestCase
31
- include Liquid
32
-
33
- def setup
34
- @assigns = {
35
- 'best_cars' => 'bmw',
36
- 'car' => {'bmw' => 'good', 'gm' => 'bad'}
37
- }
38
- end
39
-
40
- def test_variable
41
- text = %| {{best_cars}} |
42
-
43
- expected = %| bmw |
44
- assert_equal expected, Template.parse(text).render(@assigns)
45
- end
46
-
47
- def test_variable_traversing
48
- text = %| {{car.bmw}} {{car.gm}} {{car.bmw}} |
49
-
50
- expected = %| good bad good |
51
- assert_equal expected, Template.parse(text).render(@assigns)
52
- end
53
-
54
- def test_variable_piping
55
- text = %( {{ car.gm | make_funny }} )
56
- expected = %| LOL |
57
-
58
- assert_equal expected, Template.parse(text).render(@assigns, :filters => [FunnyFilter])
59
- end
60
-
61
- def test_variable_piping_with_input
62
- text = %( {{ car.gm | cite_funny }} )
63
- expected = %| LOL: bad |
64
-
65
- assert_equal expected, Template.parse(text).render(@assigns, :filters => [FunnyFilter])
66
- end
67
-
68
- def test_variable_piping_with_args
69
- text = %! {{ car.gm | add_smiley : ':-(' }} !
70
- expected = %| bad :-( |
71
-
72
- assert_equal expected, Template.parse(text).render(@assigns, :filters => [FunnyFilter])
73
- end
74
-
75
- def test_variable_piping_with_no_args
76
- text = %! {{ car.gm | add_smiley }} !
77
- expected = %| bad :-) |
78
-
79
- assert_equal expected, Template.parse(text).render(@assigns, :filters => [FunnyFilter])
80
- end
81
-
82
- def test_multiple_variable_piping_with_args
83
- text = %! {{ car.gm | add_smiley : ':-(' | add_smiley : ':-('}} !
84
- expected = %| bad :-( :-( |
85
-
86
- assert_equal expected, Template.parse(text).render(@assigns, :filters => [FunnyFilter])
87
- end
88
-
89
- def test_variable_piping_with_args
90
- text = %! {{ car.gm | add_tag : 'span', 'bar'}} !
91
- expected = %| <span id="bar">bad</span> |
92
-
93
- assert_equal expected, Template.parse(text).render(@assigns, :filters => [FunnyFilter])
94
- end
95
-
96
- def test_variable_piping_with_variable_args
97
- text = %! {{ car.gm | add_tag : 'span', car.bmw}} !
98
- expected = %| <span id="good">bad</span> |
99
-
100
- assert_equal expected, Template.parse(text).render(@assigns, :filters => [FunnyFilter])
101
- end
102
-
103
- def test_multiple_pipings
104
- text = %( {{ best_cars | cite_funny | paragraph }} )
105
- expected = %| <p>LOL: bmw</p> |
106
-
107
- assert_equal expected, Template.parse(text).render(@assigns, :filters => [FunnyFilter])
108
- end
109
-
110
- def test_link_to
111
- text = %( {{ 'Typo' | link_to: 'http://typo.leetsoft.com' }} )
112
- expected = %| <a href="http://typo.leetsoft.com">Typo</a> |
113
-
114
- assert_equal expected, Template.parse(text).render(@assigns, :filters => [FunnyFilter])
115
- end
116
- end # OutputTest