liquid 4.0.3 → 5.4.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.
Files changed (115) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +89 -0
  3. data/README.md +10 -4
  4. data/lib/liquid/block.rb +31 -14
  5. data/lib/liquid/block_body.rb +169 -57
  6. data/lib/liquid/condition.rb +48 -21
  7. data/lib/liquid/context.rb +111 -52
  8. data/lib/liquid/document.rb +47 -9
  9. data/lib/liquid/drop.rb +4 -2
  10. data/lib/liquid/errors.rb +20 -18
  11. data/lib/liquid/expression.rb +28 -32
  12. data/lib/liquid/extensions.rb +2 -0
  13. data/lib/liquid/file_system.rb +6 -4
  14. data/lib/liquid/forloop_drop.rb +54 -4
  15. data/lib/liquid/i18n.rb +5 -3
  16. data/lib/liquid/interrupts.rb +3 -1
  17. data/lib/liquid/lexer.rb +30 -23
  18. data/lib/liquid/locales/en.yml +8 -5
  19. data/lib/liquid/parse_context.rb +20 -4
  20. data/lib/liquid/parse_tree_visitor.rb +2 -2
  21. data/lib/liquid/parser.rb +30 -18
  22. data/lib/liquid/parser_switching.rb +17 -3
  23. data/lib/liquid/partial_cache.rb +24 -0
  24. data/lib/liquid/profiler/hooks.rb +26 -14
  25. data/lib/liquid/profiler.rb +67 -86
  26. data/lib/liquid/range_lookup.rb +13 -3
  27. data/lib/liquid/registers.rb +51 -0
  28. data/lib/liquid/resource_limits.rb +47 -8
  29. data/lib/liquid/standardfilters.rb +551 -114
  30. data/lib/liquid/strainer_factory.rb +41 -0
  31. data/lib/liquid/strainer_template.rb +62 -0
  32. data/lib/liquid/tablerowloop_drop.rb +64 -5
  33. data/lib/liquid/tag/disableable.rb +22 -0
  34. data/lib/liquid/tag/disabler.rb +21 -0
  35. data/lib/liquid/tag.rb +28 -6
  36. data/lib/liquid/tags/assign.rb +36 -18
  37. data/lib/liquid/tags/break.rb +16 -3
  38. data/lib/liquid/tags/capture.rb +24 -18
  39. data/lib/liquid/tags/case.rb +61 -27
  40. data/lib/liquid/tags/comment.rb +18 -3
  41. data/lib/liquid/tags/continue.rb +16 -12
  42. data/lib/liquid/tags/cycle.rb +37 -25
  43. data/lib/liquid/tags/decrement.rb +22 -20
  44. data/lib/liquid/tags/echo.rb +41 -0
  45. data/lib/liquid/tags/for.rb +90 -87
  46. data/lib/liquid/tags/if.rb +50 -32
  47. data/lib/liquid/tags/ifchanged.rb +11 -10
  48. data/lib/liquid/tags/include.rb +49 -60
  49. data/lib/liquid/tags/increment.rb +23 -17
  50. data/lib/liquid/tags/inline_comment.rb +43 -0
  51. data/lib/liquid/tags/raw.rb +25 -11
  52. data/lib/liquid/tags/render.rb +109 -0
  53. data/lib/liquid/tags/table_row.rb +45 -19
  54. data/lib/liquid/tags/unless.rb +38 -19
  55. data/lib/liquid/template.rb +52 -72
  56. data/lib/liquid/template_factory.rb +9 -0
  57. data/lib/liquid/tokenizer.rb +18 -10
  58. data/lib/liquid/usage.rb +8 -0
  59. data/lib/liquid/utils.rb +13 -3
  60. data/lib/liquid/variable.rb +49 -44
  61. data/lib/liquid/variable_lookup.rb +18 -10
  62. data/lib/liquid/version.rb +2 -1
  63. data/lib/liquid.rb +18 -6
  64. metadata +20 -108
  65. data/lib/liquid/strainer.rb +0 -66
  66. data/lib/liquid/truffle.rb +0 -5
  67. data/test/fixtures/en_locale.yml +0 -9
  68. data/test/integration/assign_test.rb +0 -48
  69. data/test/integration/blank_test.rb +0 -106
  70. data/test/integration/block_test.rb +0 -12
  71. data/test/integration/capture_test.rb +0 -50
  72. data/test/integration/context_test.rb +0 -32
  73. data/test/integration/document_test.rb +0 -19
  74. data/test/integration/drop_test.rb +0 -273
  75. data/test/integration/error_handling_test.rb +0 -260
  76. data/test/integration/filter_test.rb +0 -178
  77. data/test/integration/hash_ordering_test.rb +0 -23
  78. data/test/integration/output_test.rb +0 -123
  79. data/test/integration/parse_tree_visitor_test.rb +0 -247
  80. data/test/integration/parsing_quirks_test.rb +0 -122
  81. data/test/integration/render_profiling_test.rb +0 -154
  82. data/test/integration/security_test.rb +0 -80
  83. data/test/integration/standard_filter_test.rb +0 -776
  84. data/test/integration/tags/break_tag_test.rb +0 -15
  85. data/test/integration/tags/continue_tag_test.rb +0 -15
  86. data/test/integration/tags/for_tag_test.rb +0 -410
  87. data/test/integration/tags/if_else_tag_test.rb +0 -188
  88. data/test/integration/tags/include_tag_test.rb +0 -253
  89. data/test/integration/tags/increment_tag_test.rb +0 -23
  90. data/test/integration/tags/raw_tag_test.rb +0 -31
  91. data/test/integration/tags/standard_tag_test.rb +0 -296
  92. data/test/integration/tags/statements_test.rb +0 -111
  93. data/test/integration/tags/table_row_test.rb +0 -64
  94. data/test/integration/tags/unless_else_tag_test.rb +0 -26
  95. data/test/integration/template_test.rb +0 -332
  96. data/test/integration/trim_mode_test.rb +0 -529
  97. data/test/integration/variable_test.rb +0 -96
  98. data/test/test_helper.rb +0 -116
  99. data/test/truffle/truffle_test.rb +0 -9
  100. data/test/unit/block_unit_test.rb +0 -58
  101. data/test/unit/condition_unit_test.rb +0 -166
  102. data/test/unit/context_unit_test.rb +0 -489
  103. data/test/unit/file_system_unit_test.rb +0 -35
  104. data/test/unit/i18n_unit_test.rb +0 -37
  105. data/test/unit/lexer_unit_test.rb +0 -51
  106. data/test/unit/parser_unit_test.rb +0 -82
  107. data/test/unit/regexp_unit_test.rb +0 -44
  108. data/test/unit/strainer_unit_test.rb +0 -164
  109. data/test/unit/tag_unit_test.rb +0 -21
  110. data/test/unit/tags/case_tag_unit_test.rb +0 -10
  111. data/test/unit/tags/for_tag_unit_test.rb +0 -13
  112. data/test/unit/tags/if_tag_unit_test.rb +0 -8
  113. data/test/unit/template_unit_test.rb +0 -78
  114. data/test/unit/tokenizer_unit_test.rb +0 -55
  115. data/test/unit/variable_unit_test.rb +0 -162
@@ -1,44 +0,0 @@
1
- require 'test_helper'
2
-
3
- class RegexpUnitTest < Minitest::Test
4
- include Liquid
5
-
6
- def test_empty
7
- assert_equal [], ''.scan(QuotedFragment)
8
- end
9
-
10
- def test_quote
11
- assert_equal ['"arg 1"'], '"arg 1"'.scan(QuotedFragment)
12
- end
13
-
14
- def test_words
15
- assert_equal ['arg1', 'arg2'], 'arg1 arg2'.scan(QuotedFragment)
16
- end
17
-
18
- def test_tags
19
- assert_equal ['<tr>', '</tr>'], '<tr> </tr>'.scan(QuotedFragment)
20
- assert_equal ['<tr></tr>'], '<tr></tr>'.scan(QuotedFragment)
21
- assert_equal ['<style', 'class="hello">', '</style>'], %(<style class="hello">' </style>).scan(QuotedFragment)
22
- end
23
-
24
- def test_double_quoted_words
25
- assert_equal ['arg1', 'arg2', '"arg 3"'], 'arg1 arg2 "arg 3"'.scan(QuotedFragment)
26
- end
27
-
28
- def test_single_quoted_words
29
- assert_equal ['arg1', 'arg2', "'arg 3'"], 'arg1 arg2 \'arg 3\''.scan(QuotedFragment)
30
- end
31
-
32
- def test_quoted_words_in_the_middle
33
- assert_equal ['arg1', 'arg2', '"arg 3"', 'arg4'], 'arg1 arg2 "arg 3" arg4 '.scan(QuotedFragment)
34
- end
35
-
36
- def test_variable_parser
37
- assert_equal ['var'], 'var'.scan(VariableParser)
38
- assert_equal ['var', 'method'], 'var.method'.scan(VariableParser)
39
- assert_equal ['var', '[method]'], 'var[method]'.scan(VariableParser)
40
- assert_equal ['var', '[method]', '[0]'], 'var[method][0]'.scan(VariableParser)
41
- assert_equal ['var', '["method"]', '[0]'], 'var["method"][0]'.scan(VariableParser)
42
- assert_equal ['var', '[method]', '[0]', 'method'], 'var[method][0].method'.scan(VariableParser)
43
- end
44
- end # RegexpTest
@@ -1,164 +0,0 @@
1
- require 'test_helper'
2
-
3
- class StrainerUnitTest < Minitest::Test
4
- include Liquid
5
-
6
- module AccessScopeFilters
7
- def public_filter
8
- "public"
9
- end
10
-
11
- def private_filter
12
- "private"
13
- end
14
- private :private_filter
15
- end
16
-
17
- Strainer.global_filter(AccessScopeFilters)
18
-
19
- def test_strainer
20
- strainer = Strainer.create(nil)
21
- assert_equal 5, strainer.invoke('size', 'input')
22
- assert_equal "public", strainer.invoke("public_filter")
23
- end
24
-
25
- def test_stainer_raises_argument_error
26
- strainer = Strainer.create(nil)
27
- assert_raises(Liquid::ArgumentError) do
28
- strainer.invoke("public_filter", 1)
29
- end
30
- end
31
-
32
- def test_stainer_argument_error_contains_backtrace
33
- strainer = Strainer.create(nil)
34
- begin
35
- strainer.invoke("public_filter", 1)
36
- rescue Liquid::ArgumentError => e
37
- assert_match(
38
- /\ALiquid error: wrong number of arguments \((1 for 0|given 1, expected 0)\)\z/,
39
- e.message)
40
- assert_equal e.backtrace[0].split(':')[0], __FILE__
41
- end
42
- end
43
-
44
- def test_strainer_only_invokes_public_filter_methods
45
- strainer = Strainer.create(nil)
46
- assert_equal false, strainer.class.invokable?('__test__')
47
- assert_equal false, strainer.class.invokable?('test')
48
- assert_equal false, strainer.class.invokable?('instance_eval')
49
- assert_equal false, strainer.class.invokable?('__send__')
50
- assert_equal true, strainer.class.invokable?('size') # from the standard lib
51
- end
52
-
53
- def test_strainer_returns_nil_if_no_filter_method_found
54
- strainer = Strainer.create(nil)
55
- assert_nil strainer.invoke("private_filter")
56
- assert_nil strainer.invoke("undef_the_filter")
57
- end
58
-
59
- def test_strainer_returns_first_argument_if_no_method_and_arguments_given
60
- strainer = Strainer.create(nil)
61
- assert_equal "password", strainer.invoke("undef_the_method", "password")
62
- end
63
-
64
- def test_strainer_only_allows_methods_defined_in_filters
65
- strainer = Strainer.create(nil)
66
- assert_equal "1 + 1", strainer.invoke("instance_eval", "1 + 1")
67
- assert_equal "puts", strainer.invoke("__send__", "puts", "Hi Mom")
68
- assert_equal "has_method?", strainer.invoke("invoke", "has_method?", "invoke")
69
- end
70
-
71
- def test_strainer_uses_a_class_cache_to_avoid_method_cache_invalidation
72
- a = Module.new
73
- b = Module.new
74
- strainer = Strainer.create(nil, [a, b])
75
- assert_kind_of Strainer, strainer
76
- assert_kind_of a, strainer
77
- assert_kind_of b, strainer
78
- assert_kind_of Liquid::StandardFilters, strainer
79
- end
80
-
81
- def test_add_filter_when_wrong_filter_class
82
- c = Context.new
83
- s = c.strainer
84
- wrong_filter = ->(v) { v.reverse }
85
-
86
- assert_raises ArgumentError do
87
- s.class.add_filter(wrong_filter)
88
- end
89
- end
90
-
91
- module PrivateMethodOverrideFilter
92
- private
93
-
94
- def public_filter
95
- "overriden as private"
96
- end
97
- end
98
-
99
- def test_add_filter_raises_when_module_privately_overrides_registered_public_methods
100
- strainer = Context.new.strainer
101
-
102
- error = assert_raises(Liquid::MethodOverrideError) do
103
- strainer.class.add_filter(PrivateMethodOverrideFilter)
104
- end
105
- assert_equal 'Liquid error: Filter overrides registered public methods as non public: public_filter', error.message
106
- end
107
-
108
- module ProtectedMethodOverrideFilter
109
- protected
110
-
111
- def public_filter
112
- "overriden as protected"
113
- end
114
- end
115
-
116
- def test_add_filter_raises_when_module_overrides_registered_public_method_as_protected
117
- strainer = Context.new.strainer
118
-
119
- error = assert_raises(Liquid::MethodOverrideError) do
120
- strainer.class.add_filter(ProtectedMethodOverrideFilter)
121
- end
122
- assert_equal 'Liquid error: Filter overrides registered public methods as non public: public_filter', error.message
123
- end
124
-
125
- module PublicMethodOverrideFilter
126
- def public_filter
127
- "public"
128
- end
129
- end
130
-
131
- def test_add_filter_does_not_raise_when_module_overrides_previously_registered_method
132
- strainer = Context.new.strainer
133
- strainer.class.add_filter(PublicMethodOverrideFilter)
134
- assert strainer.class.filter_methods.include?('public_filter')
135
- end
136
-
137
- module LateAddedFilter
138
- def late_added_filter(input)
139
- "filtered"
140
- end
141
- end
142
-
143
- def test_global_filter_clears_cache
144
- assert_equal 'input', Strainer.create(nil).invoke('late_added_filter', 'input')
145
- Strainer.global_filter(LateAddedFilter)
146
- assert_equal 'filtered', Strainer.create(nil).invoke('late_added_filter', 'input')
147
- end
148
-
149
- def test_add_filter_does_not_include_already_included_module
150
- mod = Module.new do
151
- class << self
152
- attr_accessor :include_count
153
- def included(mod)
154
- self.include_count += 1
155
- end
156
- end
157
- self.include_count = 0
158
- end
159
- strainer = Context.new.strainer
160
- strainer.class.add_filter(mod)
161
- strainer.class.add_filter(mod)
162
- assert_equal 1, mod.include_count
163
- end
164
- end # StrainerTest
@@ -1,21 +0,0 @@
1
- require 'test_helper'
2
-
3
- class TagUnitTest < Minitest::Test
4
- include Liquid
5
-
6
- def test_tag
7
- tag = Tag.parse('tag', "", Tokenizer.new(""), ParseContext.new)
8
- assert_equal 'liquid::tag', tag.name
9
- assert_equal '', tag.render(Context.new)
10
- end
11
-
12
- def test_return_raw_text_of_tag
13
- tag = Tag.parse("long_tag", "param1, param2, param3", Tokenizer.new(""), ParseContext.new)
14
- assert_equal("long_tag param1, param2, param3", tag.raw)
15
- end
16
-
17
- def test_tag_name_should_return_name_of_the_tag
18
- tag = Tag.parse("some_tag", "", Tokenizer.new(""), ParseContext.new)
19
- assert_equal 'some_tag', tag.tag_name
20
- end
21
- end
@@ -1,10 +0,0 @@
1
- require 'test_helper'
2
-
3
- class CaseTagUnitTest < Minitest::Test
4
- include Liquid
5
-
6
- def test_case_nodelist
7
- template = Liquid::Template.parse('{% case var %}{% when true %}WHEN{% else %}ELSE{% endcase %}')
8
- assert_equal ['WHEN', 'ELSE'], template.root.nodelist[0].nodelist.map(&:nodelist).flatten
9
- end
10
- end
@@ -1,13 +0,0 @@
1
- require 'test_helper'
2
-
3
- class ForTagUnitTest < Minitest::Test
4
- def test_for_nodelist
5
- template = Liquid::Template.parse('{% for item in items %}FOR{% endfor %}')
6
- assert_equal ['FOR'], template.root.nodelist[0].nodelist.map(&:nodelist).flatten
7
- end
8
-
9
- def test_for_else_nodelist
10
- template = Liquid::Template.parse('{% for item in items %}FOR{% else %}ELSE{% endfor %}')
11
- assert_equal ['FOR', 'ELSE'], template.root.nodelist[0].nodelist.map(&:nodelist).flatten
12
- end
13
- end
@@ -1,8 +0,0 @@
1
- require 'test_helper'
2
-
3
- class IfTagUnitTest < Minitest::Test
4
- def test_if_nodelist
5
- template = Liquid::Template.parse('{% if true %}IF{% else %}ELSE{% endif %}')
6
- assert_equal ['IF', 'ELSE'], template.root.nodelist[0].nodelist.map(&:nodelist).flatten
7
- end
8
- end
@@ -1,78 +0,0 @@
1
- require 'test_helper'
2
-
3
- class TemplateUnitTest < Minitest::Test
4
- include Liquid
5
-
6
- def test_sets_default_localization_in_document
7
- t = Template.new
8
- t.parse('{%comment%}{%endcomment%}')
9
- assert_instance_of I18n, t.root.nodelist[0].options[:locale]
10
- end
11
-
12
- def test_sets_default_localization_in_context_with_quick_initialization
13
- t = Template.new
14
- t.parse('{%comment%}{%endcomment%}', locale: I18n.new(fixture("en_locale.yml")))
15
-
16
- locale = t.root.nodelist[0].options[:locale]
17
- assert_instance_of I18n, locale
18
- assert_equal fixture("en_locale.yml"), locale.path
19
- end
20
-
21
- def test_with_cache_classes_tags_returns_the_same_class
22
- original_cache_setting = Liquid.cache_classes
23
- Liquid.cache_classes = true
24
-
25
- original_klass = Class.new
26
- Object.send(:const_set, :CustomTag, original_klass)
27
- Template.register_tag('custom', CustomTag)
28
-
29
- Object.send(:remove_const, :CustomTag)
30
-
31
- new_klass = Class.new
32
- Object.send(:const_set, :CustomTag, new_klass)
33
-
34
- assert Template.tags['custom'].equal?(original_klass)
35
- ensure
36
- Object.send(:remove_const, :CustomTag)
37
- Template.tags.delete('custom')
38
- Liquid.cache_classes = original_cache_setting
39
- end
40
-
41
- def test_without_cache_classes_tags_reloads_the_class
42
- original_cache_setting = Liquid.cache_classes
43
- Liquid.cache_classes = false
44
-
45
- original_klass = Class.new
46
- Object.send(:const_set, :CustomTag, original_klass)
47
- Template.register_tag('custom', CustomTag)
48
-
49
- Object.send(:remove_const, :CustomTag)
50
-
51
- new_klass = Class.new
52
- Object.send(:const_set, :CustomTag, new_klass)
53
-
54
- assert Template.tags['custom'].equal?(new_klass)
55
- ensure
56
- Object.send(:remove_const, :CustomTag)
57
- Template.tags.delete('custom')
58
- Liquid.cache_classes = original_cache_setting
59
- end
60
-
61
- class FakeTag; end
62
-
63
- def test_tags_delete
64
- Template.register_tag('fake', FakeTag)
65
- assert_equal FakeTag, Template.tags['fake']
66
-
67
- Template.tags.delete('fake')
68
- assert_nil Template.tags['fake']
69
- end
70
-
71
- def test_tags_can_be_looped_over
72
- Template.register_tag('fake', FakeTag)
73
- result = Template.tags.map { |name, klass| [name, klass] }
74
- assert result.include?(["fake", "TemplateUnitTest::FakeTag"])
75
- ensure
76
- Template.tags.delete('fake')
77
- end
78
- end
@@ -1,55 +0,0 @@
1
- require 'test_helper'
2
-
3
- class TokenizerTest < Minitest::Test
4
- def test_tokenize_strings
5
- assert_equal [' '], tokenize(' ')
6
- assert_equal ['hello world'], tokenize('hello world')
7
- end
8
-
9
- def test_tokenize_variables
10
- assert_equal ['{{funk}}'], tokenize('{{funk}}')
11
- assert_equal [' ', '{{funk}}', ' '], tokenize(' {{funk}} ')
12
- assert_equal [' ', '{{funk}}', ' ', '{{so}}', ' ', '{{brother}}', ' '], tokenize(' {{funk}} {{so}} {{brother}} ')
13
- assert_equal [' ', '{{ funk }}', ' '], tokenize(' {{ funk }} ')
14
- end
15
-
16
- def test_tokenize_blocks
17
- assert_equal ['{%comment%}'], tokenize('{%comment%}')
18
- assert_equal [' ', '{%comment%}', ' '], tokenize(' {%comment%} ')
19
-
20
- assert_equal [' ', '{%comment%}', ' ', '{%endcomment%}', ' '], tokenize(' {%comment%} {%endcomment%} ')
21
- assert_equal [' ', '{% comment %}', ' ', '{% endcomment %}', ' '], tokenize(" {% comment %} {% endcomment %} ")
22
- end
23
-
24
- def test_calculate_line_numbers_per_token_with_profiling
25
- assert_equal [1], tokenize_line_numbers("{{funk}}")
26
- assert_equal [1, 1, 1], tokenize_line_numbers(" {{funk}} ")
27
- assert_equal [1, 2, 2], tokenize_line_numbers("\n{{funk}}\n")
28
- assert_equal [1, 1, 3], tokenize_line_numbers(" {{\n funk \n}} ")
29
- end
30
-
31
- private
32
-
33
- def tokenize(source)
34
- tokenizer = Liquid::Tokenizer.new(source)
35
- tokens = []
36
- while t = tokenizer.shift
37
- tokens << t
38
- end
39
- tokens
40
- end
41
-
42
- def tokenize_line_numbers(source)
43
- tokenizer = Liquid::Tokenizer.new(source, true)
44
- line_numbers = []
45
- loop do
46
- line_number = tokenizer.line_number
47
- if tokenizer.shift
48
- line_numbers << line_number
49
- else
50
- break
51
- end
52
- end
53
- line_numbers
54
- end
55
- end
@@ -1,162 +0,0 @@
1
- require 'test_helper'
2
-
3
- class VariableUnitTest < Minitest::Test
4
- include Liquid
5
-
6
- def test_variable
7
- var = create_variable('hello')
8
- assert_equal VariableLookup.new('hello'), var.name
9
- end
10
-
11
- def test_filters
12
- var = create_variable('hello | textileze')
13
- assert_equal VariableLookup.new('hello'), var.name
14
- assert_equal [['textileze', []]], var.filters
15
-
16
- var = create_variable('hello | textileze | paragraph')
17
- assert_equal VariableLookup.new('hello'), var.name
18
- assert_equal [['textileze', []], ['paragraph', []]], var.filters
19
-
20
- var = create_variable(%( hello | strftime: '%Y'))
21
- assert_equal VariableLookup.new('hello'), var.name
22
- assert_equal [['strftime', ['%Y']]], var.filters
23
-
24
- var = create_variable(%( 'typo' | link_to: 'Typo', true ))
25
- assert_equal 'typo', var.name
26
- assert_equal [['link_to', ['Typo', true]]], var.filters
27
-
28
- var = create_variable(%( 'typo' | link_to: 'Typo', false ))
29
- assert_equal 'typo', var.name
30
- assert_equal [['link_to', ['Typo', false]]], var.filters
31
-
32
- var = create_variable(%( 'foo' | repeat: 3 ))
33
- assert_equal 'foo', var.name
34
- assert_equal [['repeat', [3]]], var.filters
35
-
36
- var = create_variable(%( 'foo' | repeat: 3, 3 ))
37
- assert_equal 'foo', var.name
38
- assert_equal [['repeat', [3, 3]]], var.filters
39
-
40
- var = create_variable(%( 'foo' | repeat: 3, 3, 3 ))
41
- assert_equal 'foo', var.name
42
- assert_equal [['repeat', [3, 3, 3]]], var.filters
43
-
44
- var = create_variable(%( hello | strftime: '%Y, okay?'))
45
- assert_equal VariableLookup.new('hello'), var.name
46
- assert_equal [['strftime', ['%Y, okay?']]], var.filters
47
-
48
- var = create_variable(%( hello | things: "%Y, okay?", 'the other one'))
49
- assert_equal VariableLookup.new('hello'), var.name
50
- assert_equal [['things', ['%Y, okay?', 'the other one']]], var.filters
51
- end
52
-
53
- def test_filter_with_date_parameter
54
- var = create_variable(%( '2006-06-06' | date: "%m/%d/%Y"))
55
- assert_equal '2006-06-06', var.name
56
- assert_equal [['date', ['%m/%d/%Y']]], var.filters
57
- end
58
-
59
- def test_filters_without_whitespace
60
- var = create_variable('hello | textileze | paragraph')
61
- assert_equal VariableLookup.new('hello'), var.name
62
- assert_equal [['textileze', []], ['paragraph', []]], var.filters
63
-
64
- var = create_variable('hello|textileze|paragraph')
65
- assert_equal VariableLookup.new('hello'), var.name
66
- assert_equal [['textileze', []], ['paragraph', []]], var.filters
67
-
68
- var = create_variable("hello|replace:'foo','bar'|textileze")
69
- assert_equal VariableLookup.new('hello'), var.name
70
- assert_equal [['replace', ['foo', 'bar']], ['textileze', []]], var.filters
71
- end
72
-
73
- def test_symbol
74
- var = create_variable("http://disney.com/logo.gif | image: 'med' ", error_mode: :lax)
75
- assert_equal VariableLookup.new('http://disney.com/logo.gif'), var.name
76
- assert_equal [['image', ['med']]], var.filters
77
- end
78
-
79
- def test_string_to_filter
80
- var = create_variable("'http://disney.com/logo.gif' | image: 'med' ")
81
- assert_equal 'http://disney.com/logo.gif', var.name
82
- assert_equal [['image', ['med']]], var.filters
83
- end
84
-
85
- def test_string_single_quoted
86
- var = create_variable(%( "hello" ))
87
- assert_equal 'hello', var.name
88
- end
89
-
90
- def test_string_double_quoted
91
- var = create_variable(%( 'hello' ))
92
- assert_equal 'hello', var.name
93
- end
94
-
95
- def test_integer
96
- var = create_variable(%( 1000 ))
97
- assert_equal 1000, var.name
98
- end
99
-
100
- def test_float
101
- var = create_variable(%( 1000.01 ))
102
- assert_equal 1000.01, var.name
103
- end
104
-
105
- def test_dashes
106
- assert_equal VariableLookup.new('foo-bar'), create_variable('foo-bar').name
107
- assert_equal VariableLookup.new('foo-bar-2'), create_variable('foo-bar-2').name
108
-
109
- with_error_mode :strict do
110
- assert_raises(Liquid::SyntaxError) { create_variable('foo - bar') }
111
- assert_raises(Liquid::SyntaxError) { create_variable('-foo') }
112
- assert_raises(Liquid::SyntaxError) { create_variable('2foo') }
113
- end
114
- end
115
-
116
- def test_string_with_special_chars
117
- var = create_variable(%( 'hello! $!@.;"ddasd" ' ))
118
- assert_equal 'hello! $!@.;"ddasd" ', var.name
119
- end
120
-
121
- def test_string_dot
122
- var = create_variable(%( test.test ))
123
- assert_equal VariableLookup.new('test.test'), var.name
124
- end
125
-
126
- def test_filter_with_keyword_arguments
127
- var = create_variable(%( hello | things: greeting: "world", farewell: 'goodbye'))
128
- assert_equal VariableLookup.new('hello'), var.name
129
- assert_equal [['things', [], { 'greeting' => 'world', 'farewell' => 'goodbye' }]], var.filters
130
- end
131
-
132
- def test_lax_filter_argument_parsing
133
- var = create_variable(%( number_of_comments | pluralize: 'comment': 'comments' ), error_mode: :lax)
134
- assert_equal VariableLookup.new('number_of_comments'), var.name
135
- assert_equal [['pluralize', ['comment', 'comments']]], var.filters
136
- end
137
-
138
- def test_strict_filter_argument_parsing
139
- with_error_mode(:strict) do
140
- assert_raises(SyntaxError) do
141
- create_variable(%( number_of_comments | pluralize: 'comment': 'comments' ))
142
- end
143
- end
144
- end
145
-
146
- def test_output_raw_source_of_variable
147
- var = create_variable(%( name_of_variable | upcase ))
148
- assert_equal " name_of_variable | upcase ", var.raw
149
- end
150
-
151
- def test_variable_lookup_interface
152
- lookup = VariableLookup.new('a.b.c')
153
- assert_equal 'a', lookup.name
154
- assert_equal ['b', 'c'], lookup.lookups
155
- end
156
-
157
- private
158
-
159
- def create_variable(markup, options = {})
160
- Variable.new(markup, ParseContext.new(options))
161
- end
162
- end