liquid 3.0.0.rc1 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +4 -0
  3. data/README.md +2 -2
  4. data/lib/liquid.rb +8 -0
  5. data/lib/liquid/block.rb +50 -46
  6. data/lib/liquid/block_body.rb +123 -0
  7. data/lib/liquid/condition.rb +12 -5
  8. data/lib/liquid/context.rb +75 -148
  9. data/lib/liquid/errors.rb +50 -2
  10. data/lib/liquid/expression.rb +33 -0
  11. data/lib/liquid/parser_switching.rb +31 -0
  12. data/lib/liquid/profiler.rb +159 -0
  13. data/lib/liquid/profiler/hooks.rb +23 -0
  14. data/lib/liquid/range_lookup.rb +22 -0
  15. data/lib/liquid/standardfilters.rb +29 -4
  16. data/lib/liquid/tag.rb +6 -25
  17. data/lib/liquid/tags/assign.rb +2 -1
  18. data/lib/liquid/tags/case.rb +1 -1
  19. data/lib/liquid/tags/if.rb +5 -5
  20. data/lib/liquid/tags/ifchanged.rb +1 -1
  21. data/lib/liquid/tags/include.rb +11 -1
  22. data/lib/liquid/tags/raw.rb +1 -4
  23. data/lib/liquid/tags/table_row.rb +1 -1
  24. data/lib/liquid/template.rb +55 -4
  25. data/lib/liquid/token.rb +18 -0
  26. data/lib/liquid/variable.rb +68 -41
  27. data/lib/liquid/variable_lookup.rb +78 -0
  28. data/lib/liquid/version.rb +1 -1
  29. data/test/integration/assign_test.rb +12 -1
  30. data/test/integration/blank_test.rb +1 -1
  31. data/test/integration/capture_test.rb +1 -1
  32. data/test/integration/context_test.rb +10 -11
  33. data/test/integration/drop_test.rb +29 -3
  34. data/test/integration/error_handling_test.rb +138 -41
  35. data/test/integration/filter_test.rb +7 -7
  36. data/test/integration/hash_ordering_test.rb +6 -8
  37. data/test/integration/output_test.rb +1 -1
  38. data/test/integration/parsing_quirks_test.rb +40 -18
  39. data/test/integration/render_profiling_test.rb +154 -0
  40. data/test/integration/security_test.rb +1 -1
  41. data/test/integration/standard_filter_test.rb +47 -1
  42. data/test/integration/tags/break_tag_test.rb +1 -1
  43. data/test/integration/tags/continue_tag_test.rb +1 -1
  44. data/test/integration/tags/for_tag_test.rb +2 -2
  45. data/test/integration/tags/if_else_tag_test.rb +23 -20
  46. data/test/integration/tags/include_tag_test.rb +24 -2
  47. data/test/integration/tags/increment_tag_test.rb +1 -1
  48. data/test/integration/tags/raw_tag_test.rb +1 -1
  49. data/test/integration/tags/standard_tag_test.rb +4 -4
  50. data/test/integration/tags/statements_test.rb +1 -1
  51. data/test/integration/tags/table_row_test.rb +1 -1
  52. data/test/integration/tags/unless_else_tag_test.rb +1 -1
  53. data/test/integration/template_test.rb +16 -4
  54. data/test/integration/variable_test.rb +11 -1
  55. data/test/test_helper.rb +59 -31
  56. data/test/unit/block_unit_test.rb +2 -5
  57. data/test/unit/condition_unit_test.rb +5 -1
  58. data/test/unit/context_unit_test.rb +13 -7
  59. data/test/unit/file_system_unit_test.rb +5 -5
  60. data/test/unit/i18n_unit_test.rb +3 -3
  61. data/test/unit/lexer_unit_test.rb +1 -1
  62. data/test/unit/module_ex_unit_test.rb +1 -1
  63. data/test/unit/parser_unit_test.rb +1 -1
  64. data/test/unit/regexp_unit_test.rb +1 -1
  65. data/test/unit/strainer_unit_test.rb +3 -2
  66. data/test/unit/tag_unit_test.rb +6 -1
  67. data/test/unit/tags/case_tag_unit_test.rb +1 -1
  68. data/test/unit/tags/for_tag_unit_test.rb +1 -1
  69. data/test/unit/tags/if_tag_unit_test.rb +1 -1
  70. data/test/unit/template_unit_test.rb +1 -1
  71. data/test/unit/tokenizer_unit_test.rb +10 -1
  72. data/test/unit/variable_unit_test.rb +49 -46
  73. metadata +71 -47
@@ -1,6 +1,6 @@
1
1
  require 'test_helper'
2
2
 
3
- class StandardTagTest < Test::Unit::TestCase
3
+ class StandardTagTest < Minitest::Test
4
4
  include Liquid
5
5
 
6
6
  def test_no_transform
@@ -66,7 +66,7 @@ class StandardTagTest < Test::Unit::TestCase
66
66
  end
67
67
 
68
68
  def test_capture_detects_bad_syntax
69
- assert_raise(SyntaxError) do
69
+ assert_raises(SyntaxError) do
70
70
  assert_template_result('content foo content foo ',
71
71
  '{{ var2 }}{% capture %}{{ var }} foo {% endcapture %}{{ var2 }}{{ var2 }}',
72
72
  {'var' => 'content' })
@@ -229,11 +229,11 @@ class StandardTagTest < Test::Unit::TestCase
229
229
  end
230
230
 
231
231
  def test_case_detects_bad_syntax
232
- assert_raise(SyntaxError) do
232
+ assert_raises(SyntaxError) do
233
233
  assert_template_result('', '{% case false %}{% when %}true{% endcase %}', {})
234
234
  end
235
235
 
236
- assert_raise(SyntaxError) do
236
+ assert_raises(SyntaxError) do
237
237
  assert_template_result('', '{% case false %}{% huh %}true{% endcase %}', {})
238
238
  end
239
239
 
@@ -1,6 +1,6 @@
1
1
  require 'test_helper'
2
2
 
3
- class StatementsTest < Test::Unit::TestCase
3
+ class StatementsTest < Minitest::Test
4
4
  include Liquid
5
5
 
6
6
  def test_true_eql_true
@@ -1,6 +1,6 @@
1
1
  require 'test_helper'
2
2
 
3
- class TableRowTest < Test::Unit::TestCase
3
+ class TableRowTest < Minitest::Test
4
4
  include Liquid
5
5
 
6
6
  class ArrayDrop < Liquid::Drop
@@ -1,6 +1,6 @@
1
1
  require 'test_helper'
2
2
 
3
- class UnlessElseTagTest < Test::Unit::TestCase
3
+ class UnlessElseTagTest < Minitest::Test
4
4
  include Liquid
5
5
 
6
6
  def test_unless
@@ -28,7 +28,7 @@ class ErroneousDrop < Liquid::Drop
28
28
  end
29
29
  end
30
30
 
31
- class TemplateTest < Test::Unit::TestCase
31
+ class TemplateTest < Minitest::Test
32
32
  include Liquid
33
33
 
34
34
  def test_instance_assigns_persist_on_same_template_object_between_parses
@@ -93,7 +93,7 @@ class TemplateTest < Test::Unit::TestCase
93
93
  assert t.resource_limits[:reached]
94
94
  t.resource_limits = { :render_length_limit => 10 }
95
95
  assert_equal "0123456789", t.render!()
96
- assert_not_nil t.resource_limits[:render_length_current]
96
+ refute_nil t.resource_limits[:render_length_current]
97
97
  end
98
98
 
99
99
  def test_resource_limits_render_score
@@ -107,7 +107,7 @@ class TemplateTest < Test::Unit::TestCase
107
107
  assert t.resource_limits[:reached]
108
108
  t.resource_limits = { :render_score_limit => 200 }
109
109
  assert_equal (" foo " * 100), t.render!()
110
- assert_not_nil t.resource_limits[:render_score_current]
110
+ refute_nil t.resource_limits[:render_score_current]
111
111
  end
112
112
 
113
113
  def test_resource_limits_assign_score
@@ -117,7 +117,7 @@ class TemplateTest < Test::Unit::TestCase
117
117
  assert t.resource_limits[:reached]
118
118
  t.resource_limits = { :assign_score_limit => 2 }
119
119
  assert_equal "", t.render!()
120
- assert_not_nil t.resource_limits[:assign_score_current]
120
+ refute_nil t.resource_limits[:assign_score_current]
121
121
  end
122
122
 
123
123
  def test_resource_limits_aborts_rendering_after_first_error
@@ -135,6 +135,18 @@ class TemplateTest < Test::Unit::TestCase
135
135
  assert t.resource_limits[:render_length_current] > 0
136
136
  end
137
137
 
138
+ def test_default_resource_limits_unaffected_by_render_with_context
139
+ context = Context.new
140
+ t = Template.parse("{% for a in (1..100) %} {% assign foo = 1 %} {% endfor %}")
141
+ t.render!(context)
142
+ assert context.resource_limits[:assign_score_current] > 0
143
+ assert context.resource_limits[:render_score_current] > 0
144
+ assert context.resource_limits[:render_length_current] > 0
145
+ refute Template.default_resource_limits.key?(:assign_score_current)
146
+ refute Template.default_resource_limits.key?(:render_score_current)
147
+ refute Template.default_resource_limits.key?(:render_length_current)
148
+ end
149
+
138
150
  def test_can_use_drop_as_context
139
151
  t = Template.new
140
152
  t.registers['lulz'] = 'haha'
@@ -1,6 +1,6 @@
1
1
  require 'test_helper'
2
2
 
3
- class VariableTest < Test::Unit::TestCase
3
+ class VariableTest < Minitest::Test
4
4
  include Liquid
5
5
 
6
6
  def test_simple_variable
@@ -9,6 +9,10 @@ class VariableTest < Test::Unit::TestCase
9
9
  assert_equal 'worked wonderfully', template.render!('test' => 'worked wonderfully')
10
10
  end
11
11
 
12
+ def test_variable_render_calls_to_liquid
13
+ assert_template_result 'foobar', '{{ foo }}', 'foo' => ThingWithToLiquid.new
14
+ end
15
+
12
16
  def test_simple_with_whitespaces
13
17
  template = Template.parse(%| {{ test }} |)
14
18
  assert_equal ' worked ', template.render!('test' => 'worked')
@@ -27,6 +31,12 @@ class VariableTest < Test::Unit::TestCase
27
31
 
28
32
  def test_false_renders_as_false
29
33
  assert_equal 'false', Template.parse("{{ foo }}").render!('foo' => false)
34
+ assert_equal 'false', Template.parse("{{ false }}").render!
35
+ end
36
+
37
+ def test_nil_renders_as_empty_string
38
+ assert_equal '', Template.parse("{{ nil }}").render!
39
+ assert_equal 'cat', Template.parse("{{ nil | append: 'cat' }}").render!
30
40
  end
31
41
 
32
42
  def test_preset_assigns
@@ -1,7 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'test/unit'
4
- require 'test/unit/assertions'
3
+ require 'minitest/autorun'
5
4
  require 'spy/integration'
6
5
 
7
6
  $:.unshift(File.join(File.expand_path(File.dirname(__FILE__)), '..', 'lib'))
@@ -14,41 +13,70 @@ if env_mode = ENV['LIQUID_PARSER_MODE']
14
13
  end
15
14
  Liquid::Template.error_mode = mode
16
15
 
16
+ if Minitest.const_defined?('Test')
17
+ # We're on Minitest 5+. Nothing to do here.
18
+ else
19
+ # Minitest 4 doesn't have Minitest::Test yet.
20
+ Minitest::Test = MiniTest::Unit::TestCase
21
+ end
17
22
 
18
- module Test
19
- module Unit
20
- class TestCase
21
- def fixture(name)
22
- File.join(File.expand_path(File.dirname(__FILE__)), "fixtures", name)
23
- end
23
+ module Minitest
24
+ class Test
25
+ def fixture(name)
26
+ File.join(File.expand_path(File.dirname(__FILE__)), "fixtures", name)
24
27
  end
28
+ end
25
29
 
26
- module Assertions
27
- include Liquid
30
+ module Assertions
31
+ include Liquid
28
32
 
29
- def assert_template_result(expected, template, assigns = {}, message = nil)
30
- assert_equal expected, Template.parse(template).render!(assigns)
31
- end
33
+ def assert_template_result(expected, template, assigns = {}, message = nil)
34
+ assert_equal expected, Template.parse(template).render!(assigns)
35
+ end
32
36
 
33
- def assert_template_result_matches(expected, template, assigns = {}, message = nil)
34
- return assert_template_result(expected, template, assigns, message) unless expected.is_a? Regexp
37
+ def assert_template_result_matches(expected, template, assigns = {}, message = nil)
38
+ return assert_template_result(expected, template, assigns, message) unless expected.is_a? Regexp
35
39
 
36
- assert_match expected, Template.parse(template).render!(assigns)
37
- end
40
+ assert_match expected, Template.parse(template).render!(assigns)
41
+ end
38
42
 
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
43
+ def assert_match_syntax_error(match, template, registers = {})
44
+ exception = assert_raises(Liquid::SyntaxError) {
45
+ Template.parse(template).render(assigns)
46
+ }
47
+ assert_match match, exception.message
48
+ end
45
49
 
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
50
+ def with_global_filter(*globals)
51
+ original_filters = Array.new(Liquid::Strainer.class_variable_get(:@@filters))
52
+ globals.each do |global|
53
+ Liquid::Template.register_filter(global)
51
54
  end
52
- end # Assertions
53
- end # Unit
54
- end # Test
55
+ yield
56
+ ensure
57
+ Liquid::Strainer.class_variable_set(:@@filters, original_filters)
58
+ end
59
+
60
+ def with_taint_mode(mode)
61
+ old_mode = Liquid::Template.taint_mode
62
+ Liquid::Template.taint_mode = mode
63
+ yield
64
+ ensure
65
+ Liquid::Template.taint_mode = old_mode
66
+ end
67
+
68
+ def with_error_mode(mode)
69
+ old_mode = Liquid::Template.error_mode
70
+ Liquid::Template.error_mode = mode
71
+ yield
72
+ ensure
73
+ Liquid::Template.error_mode = old_mode
74
+ end
75
+ end
76
+ end
77
+
78
+ class ThingWithToLiquid
79
+ def to_liquid
80
+ 'foobar'
81
+ end
82
+ end
@@ -1,6 +1,6 @@
1
1
  require 'test_helper'
2
2
 
3
- class BlockUnitTest < Test::Unit::TestCase
3
+ class BlockUnitTest < Minitest::Test
4
4
  include Liquid
5
5
 
6
6
  def test_blankspace
@@ -45,10 +45,7 @@ class BlockUnitTest < Test::Unit::TestCase
45
45
 
46
46
  def test_with_custom_tag
47
47
  Liquid::Template.register_tag("testtag", Block)
48
-
49
- assert_nothing_thrown do
50
- template = Liquid::Template.parse( "{% testtag %} {% endtesttag %}")
51
- end
48
+ assert Liquid::Template.parse( "{% testtag %} {% endtesttag %}")
52
49
  end
53
50
 
54
51
  private
@@ -1,6 +1,6 @@
1
1
  require 'test_helper'
2
2
 
3
- class ConditionUnitTest < Test::Unit::TestCase
3
+ class ConditionUnitTest < Minitest::Test
4
4
  include Liquid
5
5
 
6
6
  def test_basic_condition
@@ -80,6 +80,10 @@ class ConditionUnitTest < Test::Unit::TestCase
80
80
  assert_evalutes_false "0", 'contains', 'not_assigned'
81
81
  end
82
82
 
83
+ def test_contains_return_false_on_wrong_data_type
84
+ assert_evalutes_false "1", 'contains', '0'
85
+ end
86
+
83
87
  def test_or_condition
84
88
  condition = Condition.new('1', '==', '2')
85
89
 
@@ -63,7 +63,7 @@ class ArrayLike
63
63
  end
64
64
  end
65
65
 
66
- class ContextUnitTest < Test::Unit::TestCase
66
+ class ContextUnitTest < Minitest::Test
67
67
  include Liquid
68
68
 
69
69
  def setup
@@ -107,16 +107,14 @@ class ContextUnitTest < Test::Unit::TestCase
107
107
  end
108
108
 
109
109
  def test_scoping
110
- assert_nothing_raised do
111
- @context.push
112
- @context.pop
113
- end
110
+ @context.push
111
+ @context.pop
114
112
 
115
- assert_raise(Liquid::ContextError) do
113
+ assert_raises(Liquid::ContextError) do
116
114
  @context.pop
117
115
  end
118
116
 
119
- assert_raise(Liquid::ContextError) do
117
+ assert_raises(Liquid::ContextError) do
120
118
  @context.push
121
119
  @context.pop
122
120
  @context.pop
@@ -483,4 +481,12 @@ class ContextUnitTest < Test::Unit::TestCase
483
481
  assert_equal 1, mock_scan.calls.size
484
482
  end
485
483
 
484
+ def test_context_initialization_with_a_proc_in_environment
485
+ contx = Context.new([:test => lambda { |c| c['poutine']}], {:test => :foo})
486
+
487
+ assert contx
488
+ assert_nil contx['poutine']
489
+ end
490
+
491
+
486
492
  end # ContextTest
@@ -1,10 +1,10 @@
1
1
  require 'test_helper'
2
2
 
3
- class FileSystemUnitTest < Test::Unit::TestCase
3
+ class FileSystemUnitTest < Minitest::Test
4
4
  include Liquid
5
5
 
6
6
  def test_default
7
- assert_raise(FileSystemError) do
7
+ assert_raises(FileSystemError) do
8
8
  BlankFileSystem.new.read_template_file("dummy", {'dummy'=>'smarty'})
9
9
  end
10
10
  end
@@ -14,15 +14,15 @@ class FileSystemUnitTest < Test::Unit::TestCase
14
14
  assert_equal "/some/path/_mypartial.liquid" , file_system.full_path("mypartial")
15
15
  assert_equal "/some/path/dir/_mypartial.liquid", file_system.full_path("dir/mypartial")
16
16
 
17
- assert_raise(FileSystemError) do
17
+ assert_raises(FileSystemError) do
18
18
  file_system.full_path("../dir/mypartial")
19
19
  end
20
20
 
21
- assert_raise(FileSystemError) do
21
+ assert_raises(FileSystemError) do
22
22
  file_system.full_path("/dir/../../dir/mypartial")
23
23
  end
24
24
 
25
- assert_raise(FileSystemError) do
25
+ assert_raises(FileSystemError) do
26
26
  file_system.full_path("/etc/passwd")
27
27
  end
28
28
  end
@@ -1,6 +1,6 @@
1
1
  require 'test_helper'
2
2
 
3
- class I18nUnitTest < Test::Unit::TestCase
3
+ class I18nUnitTest < Minitest::Test
4
4
  include Liquid
5
5
 
6
6
  def setup
@@ -20,13 +20,13 @@ class I18nUnitTest < Test::Unit::TestCase
20
20
  end
21
21
 
22
22
  # def test_raises_translation_error_on_undefined_interpolation_key
23
- # assert_raise I18n::TranslationError do
23
+ # assert_raises I18n::TranslationError do
24
24
  # @i18n.translate("whatever", :oopstypos => "yes")
25
25
  # end
26
26
  # end
27
27
 
28
28
  def test_raises_unknown_translation
29
- assert_raise I18n::TranslationError do
29
+ assert_raises I18n::TranslationError do
30
30
  @i18n.translate("doesnt_exist")
31
31
  end
32
32
  end
@@ -1,6 +1,6 @@
1
1
  require 'test_helper'
2
2
 
3
- class LexerUnitTest < Test::Unit::TestCase
3
+ class LexerUnitTest < Minitest::Test
4
4
  include Liquid
5
5
 
6
6
  def test_strings
@@ -36,7 +36,7 @@ class TestClassC::LiquidDropClass
36
36
  end
37
37
  end
38
38
 
39
- class ModuleExUnitTest < Test::Unit::TestCase
39
+ class ModuleExUnitTest < Minitest::Test
40
40
  include Liquid
41
41
 
42
42
  def setup
@@ -1,6 +1,6 @@
1
1
  require 'test_helper'
2
2
 
3
- class ParserUnitTest < Test::Unit::TestCase
3
+ class ParserUnitTest < Minitest::Test
4
4
  include Liquid
5
5
 
6
6
  def test_consume
@@ -1,6 +1,6 @@
1
1
  require 'test_helper'
2
2
 
3
- class RegexpUnitTest < Test::Unit::TestCase
3
+ class RegexpUnitTest < Minitest::Test
4
4
  include Liquid
5
5
 
6
6
  def test_empty
@@ -1,6 +1,6 @@
1
1
  require 'test_helper'
2
2
 
3
- class StrainerUnitTest < Test::Unit::TestCase
3
+ class StrainerUnitTest < Minitest::Test
4
4
  include Liquid
5
5
 
6
6
  module AccessScopeFilters
@@ -57,7 +57,8 @@ class StrainerUnitTest < Test::Unit::TestCase
57
57
  end
58
58
 
59
59
  def test_strainer_uses_a_class_cache_to_avoid_method_cache_invalidation
60
- a, b = Module.new, Module.new
60
+ a = Module.new
61
+ b = Module.new
61
62
  strainer = Strainer.create(nil, [a,b])
62
63
  assert_kind_of Strainer, strainer
63
64
  assert_kind_of a, strainer
@@ -1,6 +1,6 @@
1
1
  require 'test_helper'
2
2
 
3
- class TagUnitTest < Test::Unit::TestCase
3
+ class TagUnitTest < Minitest::Test
4
4
  include Liquid
5
5
 
6
6
  def test_tag
@@ -8,4 +8,9 @@ class TagUnitTest < Test::Unit::TestCase
8
8
  assert_equal 'liquid::tag', tag.name
9
9
  assert_equal '', tag.render(Context.new)
10
10
  end
11
+
12
+ def test_return_raw_text_of_tag
13
+ tag = Tag.parse("long_tag", "param1, param2, param3", [], {})
14
+ assert_equal("long_tag param1, param2, param3", tag.raw)
15
+ end
11
16
  end