liquid 2.6.3 → 3.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +42 -13
  3. data/README.md +27 -2
  4. data/lib/liquid.rb +11 -11
  5. data/lib/liquid/block.rb +75 -45
  6. data/lib/liquid/condition.rb +15 -11
  7. data/lib/liquid/context.rb +68 -29
  8. data/lib/liquid/document.rb +3 -3
  9. data/lib/liquid/drop.rb +17 -1
  10. data/lib/liquid/file_system.rb +17 -6
  11. data/lib/liquid/i18n.rb +39 -0
  12. data/lib/liquid/interrupts.rb +1 -1
  13. data/lib/liquid/lexer.rb +51 -0
  14. data/lib/liquid/locales/en.yml +22 -0
  15. data/lib/liquid/parser.rb +90 -0
  16. data/lib/liquid/standardfilters.rb +115 -52
  17. data/lib/liquid/strainer.rb +14 -4
  18. data/lib/liquid/tag.rb +42 -7
  19. data/lib/liquid/tags/assign.rb +10 -8
  20. data/lib/liquid/tags/break.rb +1 -1
  21. data/lib/liquid/tags/capture.rb +10 -8
  22. data/lib/liquid/tags/case.rb +13 -13
  23. data/lib/liquid/tags/comment.rb +9 -2
  24. data/lib/liquid/tags/continue.rb +1 -4
  25. data/lib/liquid/tags/cycle.rb +5 -7
  26. data/lib/liquid/tags/decrement.rb +3 -4
  27. data/lib/liquid/tags/for.rb +69 -36
  28. data/lib/liquid/tags/if.rb +52 -25
  29. data/lib/liquid/tags/ifchanged.rb +2 -2
  30. data/lib/liquid/tags/include.rb +8 -7
  31. data/lib/liquid/tags/increment.rb +4 -8
  32. data/lib/liquid/tags/raw.rb +3 -3
  33. data/lib/liquid/tags/table_row.rb +73 -0
  34. data/lib/liquid/tags/unless.rb +2 -4
  35. data/lib/liquid/template.rb +69 -10
  36. data/lib/liquid/utils.rb +13 -4
  37. data/lib/liquid/variable.rb +59 -8
  38. data/lib/liquid/version.rb +1 -1
  39. data/test/fixtures/en_locale.yml +9 -0
  40. data/test/{liquid → integration}/assign_test.rb +6 -0
  41. data/test/integration/blank_test.rb +106 -0
  42. data/test/{liquid → integration}/capture_test.rb +2 -2
  43. data/test/integration/context_test.rb +33 -0
  44. data/test/integration/drop_test.rb +245 -0
  45. data/test/{liquid → integration}/error_handling_test.rb +31 -2
  46. data/test/{liquid → integration}/filter_test.rb +7 -7
  47. data/test/{liquid → integration}/hash_ordering_test.rb +0 -0
  48. data/test/{liquid → integration}/output_test.rb +12 -12
  49. data/test/integration/parsing_quirks_test.rb +94 -0
  50. data/test/{liquid → integration}/security_test.rb +9 -9
  51. data/test/{liquid → integration}/standard_filter_test.rb +103 -33
  52. data/test/{liquid → integration}/tags/break_tag_test.rb +0 -0
  53. data/test/{liquid → integration}/tags/continue_tag_test.rb +0 -0
  54. data/test/{liquid → integration}/tags/for_tag_test.rb +78 -0
  55. data/test/{liquid → integration}/tags/if_else_tag_test.rb +1 -1
  56. data/test/integration/tags/include_tag_test.rb +212 -0
  57. data/test/{liquid → integration}/tags/increment_tag_test.rb +0 -0
  58. data/test/{liquid → integration}/tags/raw_tag_test.rb +1 -0
  59. data/test/{liquid → integration}/tags/standard_tag_test.rb +24 -22
  60. data/test/integration/tags/statements_test.rb +113 -0
  61. data/test/{liquid/tags/html_tag_test.rb → integration/tags/table_row_test.rb} +5 -5
  62. data/test/{liquid → integration}/tags/unless_else_tag_test.rb +0 -0
  63. data/test/{liquid → integration}/template_test.rb +66 -42
  64. data/test/integration/variable_test.rb +72 -0
  65. data/test/test_helper.rb +32 -7
  66. data/test/{liquid/block_test.rb → unit/block_unit_test.rb} +1 -1
  67. data/test/{liquid/condition_test.rb → unit/condition_unit_test.rb} +19 -1
  68. data/test/{liquid/context_test.rb → unit/context_unit_test.rb} +27 -19
  69. data/test/{liquid/file_system_test.rb → unit/file_system_unit_test.rb} +7 -1
  70. data/test/unit/i18n_unit_test.rb +37 -0
  71. data/test/unit/lexer_unit_test.rb +48 -0
  72. data/test/{liquid/module_ex_test.rb → unit/module_ex_unit_test.rb} +7 -7
  73. data/test/unit/parser_unit_test.rb +82 -0
  74. data/test/{liquid/regexp_test.rb → unit/regexp_unit_test.rb} +3 -3
  75. data/test/{liquid/strainer_test.rb → unit/strainer_unit_test.rb} +19 -1
  76. data/test/unit/tag_unit_test.rb +11 -0
  77. data/test/unit/tags/case_tag_unit_test.rb +10 -0
  78. data/test/unit/tags/for_tag_unit_test.rb +13 -0
  79. data/test/unit/tags/if_tag_unit_test.rb +8 -0
  80. data/test/unit/template_unit_test.rb +69 -0
  81. data/test/unit/tokenizer_unit_test.rb +29 -0
  82. data/test/{liquid/variable_test.rb → unit/variable_unit_test.rb} +17 -67
  83. metadata +117 -73
  84. data/lib/extras/liquid_view.rb +0 -51
  85. data/lib/liquid/htmltags.rb +0 -73
  86. data/test/liquid/drop_test.rb +0 -180
  87. data/test/liquid/parsing_quirks_test.rb +0 -52
  88. data/test/liquid/tags/include_tag_test.rb +0 -166
  89. data/test/liquid/tags/statements_test.rb +0 -134
@@ -1,6 +1,6 @@
1
1
  require 'test_helper'
2
2
 
3
- class HtmlTagTest < Test::Unit::TestCase
3
+ class TableRowTest < Test::Unit::TestCase
4
4
  include Liquid
5
5
 
6
6
  class ArrayDrop < Liquid::Drop
@@ -15,7 +15,7 @@ class HtmlTagTest < Test::Unit::TestCase
15
15
  end
16
16
  end
17
17
 
18
- def test_html_table
18
+ def test_table_row
19
19
 
20
20
  assert_template_result("<tr class=\"row1\">\n<td class=\"col1\"> 1 </td><td class=\"col2\"> 2 </td><td class=\"col3\"> 3 </td></tr>\n<tr class=\"row2\"><td class=\"col1\"> 4 </td><td class=\"col2\"> 5 </td><td class=\"col3\"> 6 </td></tr>\n",
21
21
  '{% tablerow n in numbers cols:3%} {{n}} {% endtablerow %}',
@@ -26,14 +26,14 @@ class HtmlTagTest < Test::Unit::TestCase
26
26
  'numbers' => [])
27
27
  end
28
28
 
29
- def test_html_table_with_different_cols
29
+ def test_table_row_with_different_cols
30
30
  assert_template_result("<tr class=\"row1\">\n<td class=\"col1\"> 1 </td><td class=\"col2\"> 2 </td><td class=\"col3\"> 3 </td><td class=\"col4\"> 4 </td><td class=\"col5\"> 5 </td></tr>\n<tr class=\"row2\"><td class=\"col1\"> 6 </td></tr>\n",
31
31
  '{% tablerow n in numbers cols:5%} {{n}} {% endtablerow %}',
32
32
  'numbers' => [1,2,3,4,5,6])
33
33
 
34
34
  end
35
35
 
36
- def test_html_col_counter
36
+ def test_table_col_counter
37
37
  assert_template_result("<tr class=\"row1\">\n<td class=\"col1\">1</td><td class=\"col2\">2</td></tr>\n<tr class=\"row2\"><td class=\"col1\">1</td><td class=\"col2\">2</td></tr>\n<tr class=\"row3\"><td class=\"col1\">1</td><td class=\"col2\">2</td></tr>\n",
38
38
  '{% tablerow n in numbers cols:2%}{{tablerowloop.col}}{% endtablerow %}',
39
39
  'numbers' => [1,2,3,4,5,6])
@@ -60,4 +60,4 @@ class HtmlTagTest < Test::Unit::TestCase
60
60
  '{% tablerow n in numbers cols:3 offset:1 limit:6%} {{n}} {% endtablerow %}',
61
61
  'numbers' => [0,1,2,3,4,5,6,7])
62
62
  end
63
- end # HtmlTagTest
63
+ end
@@ -14,85 +14,85 @@ class TemplateContextDrop < Liquid::Drop
14
14
  end
15
15
  end
16
16
 
17
- class TemplateTest < Test::Unit::TestCase
18
- include Liquid
19
-
20
- def test_tokenize_strings
21
- assert_equal [' '], Template.new.send(:tokenize, ' ')
22
- assert_equal ['hello world'], Template.new.send(:tokenize, 'hello world')
23
- end
24
-
25
- def test_tokenize_variables
26
- assert_equal ['{{funk}}'], Template.new.send(:tokenize, '{{funk}}')
27
- assert_equal [' ', '{{funk}}', ' '], Template.new.send(:tokenize, ' {{funk}} ')
28
- assert_equal [' ', '{{funk}}', ' ', '{{so}}', ' ', '{{brother}}', ' '], Template.new.send(:tokenize, ' {{funk}} {{so}} {{brother}} ')
29
- assert_equal [' ', '{{ funk }}', ' '], Template.new.send(:tokenize, ' {{ funk }} ')
17
+ class SomethingWithLength
18
+ def length
19
+ nil
30
20
  end
31
21
 
32
- def test_tokenize_blocks
33
- assert_equal ['{%comment%}'], Template.new.send(:tokenize, '{%comment%}')
34
- assert_equal [' ', '{%comment%}', ' '], Template.new.send(:tokenize, ' {%comment%} ')
22
+ liquid_methods :length
23
+ end
35
24
 
36
- assert_equal [' ', '{%comment%}', ' ', '{%endcomment%}', ' '], Template.new.send(:tokenize, ' {%comment%} {%endcomment%} ')
37
- assert_equal [' ', '{% comment %}', ' ', '{% endcomment %}', ' '], Template.new.send(:tokenize, " {% comment %} {% endcomment %} ")
25
+ class ErroneousDrop < Liquid::Drop
26
+ def bad_method
27
+ raise 'ruby error in drop'
38
28
  end
29
+ end
30
+
31
+ class TemplateTest < Test::Unit::TestCase
32
+ include Liquid
39
33
 
40
34
  def test_instance_assigns_persist_on_same_template_object_between_parses
41
35
  t = Template.new
42
- assert_equal 'from instance assigns', t.parse("{% assign foo = 'from instance assigns' %}{{ foo }}").render
43
- assert_equal 'from instance assigns', t.parse("{{ foo }}").render
36
+ assert_equal 'from instance assigns', t.parse("{% assign foo = 'from instance assigns' %}{{ foo }}").render!
37
+ assert_equal 'from instance assigns', t.parse("{{ foo }}").render!
44
38
  end
45
39
 
46
40
  def test_instance_assigns_persist_on_same_template_parsing_between_renders
47
41
  t = Template.new.parse("{{ foo }}{% assign foo = 'foo' %}{{ foo }}")
48
- assert_equal 'foo', t.render
49
- assert_equal 'foofoo', t.render
42
+ assert_equal 'foo', t.render!
43
+ assert_equal 'foofoo', t.render!
50
44
  end
51
45
 
52
46
  def test_custom_assigns_do_not_persist_on_same_template
53
47
  t = Template.new
54
- assert_equal 'from custom assigns', t.parse("{{ foo }}").render('foo' => 'from custom assigns')
55
- assert_equal '', t.parse("{{ foo }}").render
48
+ assert_equal 'from custom assigns', t.parse("{{ foo }}").render!('foo' => 'from custom assigns')
49
+ assert_equal '', t.parse("{{ foo }}").render!
56
50
  end
57
51
 
58
52
  def test_custom_assigns_squash_instance_assigns
59
53
  t = Template.new
60
- assert_equal 'from instance assigns', t.parse("{% assign foo = 'from instance assigns' %}{{ foo }}").render
61
- assert_equal 'from custom assigns', t.parse("{{ foo }}").render('foo' => 'from custom assigns')
54
+ assert_equal 'from instance assigns', t.parse("{% assign foo = 'from instance assigns' %}{{ foo }}").render!
55
+ assert_equal 'from custom assigns', t.parse("{{ foo }}").render!('foo' => 'from custom assigns')
62
56
  end
63
57
 
64
58
  def test_persistent_assigns_squash_instance_assigns
65
59
  t = Template.new
66
- assert_equal 'from instance assigns', t.parse("{% assign foo = 'from instance assigns' %}{{ foo }}").render
60
+ assert_equal 'from instance assigns', t.parse("{% assign foo = 'from instance assigns' %}{{ foo }}").render!
67
61
  t.assigns['foo'] = 'from persistent assigns'
68
- assert_equal 'from persistent assigns', t.parse("{{ foo }}").render
62
+ assert_equal 'from persistent assigns', t.parse("{{ foo }}").render!
69
63
  end
70
64
 
71
65
  def test_lambda_is_called_once_from_persistent_assigns_over_multiple_parses_and_renders
72
66
  t = Template.new
73
67
  t.assigns['number'] = lambda { @global ||= 0; @global += 1 }
74
- assert_equal '1', t.parse("{{number}}").render
75
- assert_equal '1', t.parse("{{number}}").render
76
- assert_equal '1', t.render
68
+ assert_equal '1', t.parse("{{number}}").render!
69
+ assert_equal '1', t.parse("{{number}}").render!
70
+ assert_equal '1', t.render!
77
71
  @global = nil
78
72
  end
79
73
 
80
74
  def test_lambda_is_called_once_from_custom_assigns_over_multiple_parses_and_renders
81
75
  t = Template.new
82
76
  assigns = {'number' => lambda { @global ||= 0; @global += 1 }}
83
- assert_equal '1', t.parse("{{number}}").render(assigns)
84
- assert_equal '1', t.parse("{{number}}").render(assigns)
85
- assert_equal '1', t.render(assigns)
77
+ assert_equal '1', t.parse("{{number}}").render!(assigns)
78
+ assert_equal '1', t.parse("{{number}}").render!(assigns)
79
+ assert_equal '1', t.render!(assigns)
86
80
  @global = nil
87
81
  end
88
82
 
83
+ def test_resource_limits_works_with_custom_length_method
84
+ t = Template.parse("{% assign foo = bar %}")
85
+ t.resource_limits = { :render_length_limit => 42 }
86
+ assert_equal "", t.render!("bar" => SomethingWithLength.new)
87
+ end
88
+
89
89
  def test_resource_limits_render_length
90
90
  t = Template.parse("0123456789")
91
91
  t.resource_limits = { :render_length_limit => 5 }
92
92
  assert_equal "Liquid error: Memory limits exceeded", t.render()
93
93
  assert t.resource_limits[:reached]
94
94
  t.resource_limits = { :render_length_limit => 10 }
95
- assert_equal "0123456789", t.render()
95
+ assert_equal "0123456789", t.render!()
96
96
  assert_not_nil t.resource_limits[:render_length_current]
97
97
  end
98
98
 
@@ -106,7 +106,7 @@ class TemplateTest < Test::Unit::TestCase
106
106
  assert_equal "Liquid error: Memory limits exceeded", t.render()
107
107
  assert t.resource_limits[:reached]
108
108
  t.resource_limits = { :render_score_limit => 200 }
109
- assert_equal (" foo " * 100), t.render()
109
+ assert_equal (" foo " * 100), t.render!()
110
110
  assert_not_nil t.resource_limits[:render_score_current]
111
111
  end
112
112
 
@@ -116,7 +116,7 @@ class TemplateTest < Test::Unit::TestCase
116
116
  assert_equal "Liquid error: Memory limits exceeded", t.render()
117
117
  assert t.resource_limits[:reached]
118
118
  t.resource_limits = { :assign_score_limit => 2 }
119
- assert_equal "", t.render()
119
+ assert_equal "", t.render!()
120
120
  assert_not_nil t.resource_limits[:assign_score_current]
121
121
  end
122
122
 
@@ -129,7 +129,7 @@ class TemplateTest < Test::Unit::TestCase
129
129
 
130
130
  def test_resource_limits_hash_in_template_gets_updated_even_if_no_limits_are_set
131
131
  t = Template.parse("{% for a in (1..100) %} {% assign foo = 1 %} {% endfor %}")
132
- t.render()
132
+ t.render!()
133
133
  assert t.resource_limits[:assign_score_current] > 0
134
134
  assert t.resource_limits[:render_score_current] > 0
135
135
  assert t.resource_limits[:render_length_current] > 0
@@ -139,8 +139,32 @@ class TemplateTest < Test::Unit::TestCase
139
139
  t = Template.new
140
140
  t.registers['lulz'] = 'haha'
141
141
  drop = TemplateContextDrop.new
142
- assert_equal 'fizzbuzz', t.parse('{{foo}}').render(drop)
143
- assert_equal 'bar', t.parse('{{bar}}').render(drop)
144
- assert_equal 'haha', t.parse("{{baz}}").render(drop)
142
+ assert_equal 'fizzbuzz', t.parse('{{foo}}').render!(drop)
143
+ assert_equal 'bar', t.parse('{{bar}}').render!(drop)
144
+ assert_equal 'haha', t.parse("{{baz}}").render!(drop)
145
+ end
146
+
147
+ def test_render_bang_force_rethrow_errors_on_passed_context
148
+ context = Context.new({'drop' => ErroneousDrop.new})
149
+ t = Template.new.parse('{{ drop.bad_method }}')
150
+
151
+ e = assert_raises RuntimeError do
152
+ t.render!(context)
153
+ end
154
+ assert_equal 'ruby error in drop', e.message
145
155
  end
146
- end # TemplateTest
156
+
157
+ def test_exception_handler_doesnt_reraise_if_it_returns_false
158
+ exception = nil
159
+ Template.parse("{{ 1 | divided_by: 0 }}").render({}, exception_handler: ->(e) { exception = e; false })
160
+ assert exception.is_a?(ZeroDivisionError)
161
+ end
162
+
163
+ def test_exception_handler_does_reraise_if_it_returns_true
164
+ exception = nil
165
+ assert_raises(ZeroDivisionError) do
166
+ Template.parse("{{ 1 | divided_by: 0 }}").render({}, exception_handler: ->(e) { exception = e; true })
167
+ end
168
+ assert exception.is_a?(ZeroDivisionError)
169
+ end
170
+ end
@@ -0,0 +1,72 @@
1
+ require 'test_helper'
2
+
3
+ class VariableTest < Test::Unit::TestCase
4
+ include Liquid
5
+
6
+ def test_simple_variable
7
+ template = Template.parse(%|{{test}}|)
8
+ assert_equal 'worked', template.render!('test' => 'worked')
9
+ assert_equal 'worked wonderfully', template.render!('test' => 'worked wonderfully')
10
+ end
11
+
12
+ def test_simple_with_whitespaces
13
+ template = Template.parse(%| {{ test }} |)
14
+ assert_equal ' worked ', template.render!('test' => 'worked')
15
+ assert_equal ' worked wonderfully ', template.render!('test' => 'worked wonderfully')
16
+ end
17
+
18
+ def test_ignore_unknown
19
+ template = Template.parse(%|{{ test }}|)
20
+ assert_equal '', template.render!
21
+ end
22
+
23
+ def test_hash_scoping
24
+ template = Template.parse(%|{{ test.test }}|)
25
+ assert_equal 'worked', template.render!('test' => {'test' => 'worked'})
26
+ end
27
+
28
+ def test_false_renders_as_false
29
+ assert_equal 'false', Template.parse("{{ foo }}").render!('foo' => false)
30
+ end
31
+
32
+ def test_preset_assigns
33
+ template = Template.parse(%|{{ test }}|)
34
+ template.assigns['test'] = 'worked'
35
+ assert_equal 'worked', template.render!
36
+ end
37
+
38
+ def test_reuse_parsed_template
39
+ template = Template.parse(%|{{ greeting }} {{ name }}|)
40
+ template.assigns['greeting'] = 'Goodbye'
41
+ assert_equal 'Hello Tobi', template.render!('greeting' => 'Hello', 'name' => 'Tobi')
42
+ assert_equal 'Hello ', template.render!('greeting' => 'Hello', 'unknown' => 'Tobi')
43
+ assert_equal 'Hello Brian', template.render!('greeting' => 'Hello', 'name' => 'Brian')
44
+ assert_equal 'Goodbye Brian', template.render!('name' => 'Brian')
45
+ assert_equal({'greeting'=>'Goodbye'}, template.assigns)
46
+ end
47
+
48
+ def test_assigns_not_polluted_from_template
49
+ template = Template.parse(%|{{ test }}{% assign test = 'bar' %}{{ test }}|)
50
+ template.assigns['test'] = 'baz'
51
+ assert_equal 'bazbar', template.render!
52
+ assert_equal 'bazbar', template.render!
53
+ assert_equal 'foobar', template.render!('test' => 'foo')
54
+ assert_equal 'bazbar', template.render!
55
+ end
56
+
57
+ def test_hash_with_default_proc
58
+ template = Template.parse(%|Hello {{ test }}|)
59
+ assigns = Hash.new { |h,k| raise "Unknown variable '#{k}'" }
60
+ assigns['test'] = 'Tobi'
61
+ assert_equal 'Hello Tobi', template.render!(assigns)
62
+ assigns.delete('test')
63
+ e = assert_raises(RuntimeError) {
64
+ template.render!(assigns)
65
+ }
66
+ assert_equal "Unknown variable 'test'", e.message
67
+ end
68
+
69
+ def test_multiline_variable
70
+ assert_equal 'worked', Template.parse("{{\ntest\n}}").render!('test' => 'worked')
71
+ end
72
+ end
data/test/test_helper.rb CHANGED
@@ -2,27 +2,52 @@
2
2
 
3
3
  require 'test/unit'
4
4
  require 'test/unit/assertions'
5
- begin
6
- require 'ruby-debug'
7
- rescue LoadError
8
- puts "Couldn't load ruby-debug. gem install ruby-debug if you need it."
5
+ require 'spy/integration'
6
+
7
+ $:.unshift(File.join(File.expand_path(File.dirname(__FILE__)), '..', 'lib'))
8
+ require 'liquid.rb'
9
+
10
+ mode = :strict
11
+ if env_mode = ENV['LIQUID_PARSER_MODE']
12
+ puts "-- #{env_mode.upcase} ERROR MODE"
13
+ mode = env_mode.to_sym
9
14
  end
10
- require File.join(File.dirname(__FILE__), '..', 'lib', 'liquid')
15
+ Liquid::Template.error_mode = mode
11
16
 
12
17
 
13
18
  module Test
14
19
  module Unit
20
+ class TestCase
21
+ def fixture(name)
22
+ File.join(File.expand_path(File.dirname(__FILE__)), "fixtures", name)
23
+ end
24
+ end
25
+
15
26
  module Assertions
16
27
  include Liquid
17
28
 
18
29
  def assert_template_result(expected, template, assigns = {}, message = nil)
19
- assert_equal expected, Template.parse(template).render(assigns)
30
+ assert_equal expected, Template.parse(template).render!(assigns)
20
31
  end
21
32
 
22
33
  def assert_template_result_matches(expected, template, assigns = {}, message = nil)
23
34
  return assert_template_result(expected, template, assigns, message) unless expected.is_a? Regexp
24
35
 
25
- assert_match expected, Template.parse(template).render(assigns)
36
+ assert_match expected, Template.parse(template).render!(assigns)
37
+ end
38
+
39
+ def assert_match_syntax_error(match, template, registers = {})
40
+ exception = assert_raise(Liquid::SyntaxError) {
41
+ Template.parse(template).render(assigns)
42
+ }
43
+ assert_match match, exception.message
44
+ end
45
+
46
+ def with_error_mode(mode)
47
+ old_mode = Liquid::Template.error_mode
48
+ Liquid::Template.error_mode = mode
49
+ yield
50
+ Liquid::Template.error_mode = old_mode
26
51
  end
27
52
  end # Assertions
28
53
  end # Unit
@@ -1,6 +1,6 @@
1
1
  require 'test_helper'
2
2
 
3
- class BlockTest < Test::Unit::TestCase
3
+ class BlockUnitTest < Test::Unit::TestCase
4
4
  include Liquid
5
5
 
6
6
  def test_blankspace
@@ -1,6 +1,6 @@
1
1
  require 'test_helper'
2
2
 
3
- class ConditionTest < Test::Unit::TestCase
3
+ class ConditionUnitTest < Test::Unit::TestCase
4
4
  include Liquid
5
5
 
6
6
  def test_basic_condition
@@ -49,6 +49,17 @@ class ConditionTest < Test::Unit::TestCase
49
49
  assert_evalutes_false "'bob'", 'contains', "'---'"
50
50
  end
51
51
 
52
+ def test_invalid_comparation_operator
53
+ assert_evaluates_argument_error "1", '~~', '0'
54
+ end
55
+
56
+ def test_comparation_of_int_and_str
57
+ assert_evaluates_argument_error "'1'", '>', '0'
58
+ assert_evaluates_argument_error "'1'", '<', '0'
59
+ assert_evaluates_argument_error "'1'", '>=', '0'
60
+ assert_evaluates_argument_error "'1'", '<=', '0'
61
+ end
62
+
52
63
  def test_contains_works_on_arrays
53
64
  @context = Liquid::Context.new
54
65
  @context['array'] = [1,2,3,4,5]
@@ -124,4 +135,11 @@ class ConditionTest < Test::Unit::TestCase
124
135
  assert !Condition.new(left, op, right).evaluate(@context || Liquid::Context.new),
125
136
  "Evaluated true: #{left} #{op} #{right}"
126
137
  end
138
+
139
+ def assert_evaluates_argument_error(left, op, right)
140
+ assert_raises(Liquid::ArgumentError) do
141
+ Condition.new(left, op, right).evaluate(@context || Liquid::Context.new)
142
+ end
143
+ end
144
+
127
145
  end # ConditionTest
@@ -63,13 +63,17 @@ class ArrayLike
63
63
  end
64
64
  end
65
65
 
66
- class ContextTest < Test::Unit::TestCase
66
+ class ContextUnitTest < Test::Unit::TestCase
67
67
  include Liquid
68
68
 
69
69
  def setup
70
70
  @context = Liquid::Context.new
71
71
  end
72
72
 
73
+ def teardown
74
+ Spy.teardown
75
+ end
76
+
73
77
  def test_variables
74
78
  @context['string'] = 'string'
75
79
  assert_equal 'string', @context['string']
@@ -162,24 +166,6 @@ class ContextTest < Test::Unit::TestCase
162
166
 
163
167
  end
164
168
 
165
- def test_override_global_filter
166
- global = Module.new do
167
- def notice(output)
168
- "Global #{output}"
169
- end
170
- end
171
-
172
- local = Module.new do
173
- def notice(output)
174
- "Local #{output}"
175
- end
176
- end
177
-
178
- Template.register_filter(global)
179
- assert_equal 'Global test', Template.parse("{{'test' | notice }}").render
180
- assert_equal 'Local test', Template.parse("{{'test' | notice }}").render({}, :filters => [local])
181
- end
182
-
183
169
  def test_only_intended_filters_make_it_there
184
170
 
185
171
  filter = Module.new do
@@ -475,4 +461,26 @@ class ContextTest < Test::Unit::TestCase
475
461
  assert_kind_of CategoryDrop, @context['category']
476
462
  assert_equal @context, @context['category'].context
477
463
  end
464
+
465
+ def test_use_empty_instead_of_any_in_interrupt_handling_to_avoid_lots_of_unnecessary_object_allocations
466
+ mock_any = Spy.on_instance_method(Array, :any?)
467
+ mock_empty = Spy.on_instance_method(Array, :empty?)
468
+ mock_has_interrupt = Spy.on(@context, :has_interrupt?).and_call_through
469
+
470
+ @context.has_interrupt?
471
+
472
+ refute mock_any.has_been_called?
473
+ assert mock_empty.has_been_called?
474
+ end
475
+
476
+ def test_variable_lookup_caches_markup
477
+ mock_scan = Spy.on_instance_method(String, :scan).and_return(["string"])
478
+
479
+ @context['string'] = 'string'
480
+ @context['string']
481
+ @context['string']
482
+
483
+ assert_equal 1, mock_scan.calls.size
484
+ end
485
+
478
486
  end # ContextTest