liquid 3.0.6 → 4.0.3
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 +5 -5
- data/History.md +154 -58
- data/{MIT-LICENSE → LICENSE} +0 -0
- data/README.md +33 -0
- data/lib/liquid/block.rb +42 -125
- data/lib/liquid/block_body.rb +99 -79
- data/lib/liquid/condition.rb +52 -32
- data/lib/liquid/context.rb +57 -51
- data/lib/liquid/document.rb +19 -9
- data/lib/liquid/drop.rb +17 -16
- data/lib/liquid/errors.rb +20 -24
- data/lib/liquid/expression.rb +26 -10
- data/lib/liquid/extensions.rb +19 -7
- data/lib/liquid/file_system.rb +11 -11
- data/lib/liquid/forloop_drop.rb +42 -0
- data/lib/liquid/i18n.rb +6 -6
- data/lib/liquid/interrupts.rb +1 -2
- data/lib/liquid/lexer.rb +12 -8
- data/lib/liquid/locales/en.yml +6 -2
- data/lib/liquid/parse_context.rb +38 -0
- data/lib/liquid/parse_tree_visitor.rb +42 -0
- data/lib/liquid/parser_switching.rb +4 -4
- data/lib/liquid/profiler/hooks.rb +7 -7
- data/lib/liquid/profiler.rb +18 -19
- data/lib/liquid/range_lookup.rb +16 -1
- data/lib/liquid/resource_limits.rb +23 -0
- data/lib/liquid/standardfilters.rb +207 -61
- data/lib/liquid/strainer.rb +15 -8
- data/lib/liquid/tablerowloop_drop.rb +62 -0
- data/lib/liquid/tag.rb +9 -8
- data/lib/liquid/tags/assign.rb +25 -4
- data/lib/liquid/tags/break.rb +0 -3
- data/lib/liquid/tags/capture.rb +1 -1
- data/lib/liquid/tags/case.rb +27 -12
- data/lib/liquid/tags/comment.rb +2 -2
- data/lib/liquid/tags/cycle.rb +16 -8
- data/lib/liquid/tags/decrement.rb +1 -4
- data/lib/liquid/tags/for.rb +103 -75
- data/lib/liquid/tags/if.rb +60 -44
- data/lib/liquid/tags/ifchanged.rb +0 -2
- data/lib/liquid/tags/include.rb +71 -51
- data/lib/liquid/tags/raw.rb +32 -4
- data/lib/liquid/tags/table_row.rb +21 -31
- data/lib/liquid/tags/unless.rb +3 -4
- data/lib/liquid/template.rb +42 -54
- data/lib/liquid/tokenizer.rb +31 -0
- data/lib/liquid/truffle.rb +5 -0
- data/lib/liquid/utils.rb +52 -8
- data/lib/liquid/variable.rb +59 -46
- data/lib/liquid/variable_lookup.rb +14 -6
- data/lib/liquid/version.rb +2 -1
- data/lib/liquid.rb +10 -7
- data/test/integration/assign_test.rb +8 -8
- data/test/integration/blank_test.rb +14 -14
- data/test/integration/block_test.rb +12 -0
- data/test/integration/context_test.rb +2 -2
- data/test/integration/document_test.rb +19 -0
- data/test/integration/drop_test.rb +42 -40
- data/test/integration/error_handling_test.rb +96 -43
- data/test/integration/filter_test.rb +60 -20
- data/test/integration/hash_ordering_test.rb +9 -9
- data/test/integration/output_test.rb +26 -27
- data/test/integration/parse_tree_visitor_test.rb +247 -0
- data/test/integration/parsing_quirks_test.rb +19 -13
- data/test/integration/render_profiling_test.rb +20 -20
- data/test/integration/security_test.rb +23 -7
- data/test/integration/standard_filter_test.rb +426 -46
- data/test/integration/tags/break_tag_test.rb +1 -2
- data/test/integration/tags/continue_tag_test.rb +0 -1
- data/test/integration/tags/for_tag_test.rb +135 -100
- data/test/integration/tags/if_else_tag_test.rb +75 -77
- data/test/integration/tags/include_tag_test.rb +50 -31
- data/test/integration/tags/increment_tag_test.rb +10 -11
- data/test/integration/tags/raw_tag_test.rb +7 -1
- data/test/integration/tags/standard_tag_test.rb +121 -122
- data/test/integration/tags/statements_test.rb +3 -5
- data/test/integration/tags/table_row_test.rb +20 -19
- data/test/integration/tags/unless_else_tag_test.rb +6 -6
- data/test/integration/template_test.rb +199 -49
- data/test/integration/trim_mode_test.rb +529 -0
- data/test/integration/variable_test.rb +27 -13
- data/test/test_helper.rb +33 -6
- data/test/truffle/truffle_test.rb +9 -0
- data/test/unit/block_unit_test.rb +8 -5
- data/test/unit/condition_unit_test.rb +94 -77
- data/test/unit/context_unit_test.rb +69 -72
- data/test/unit/file_system_unit_test.rb +3 -3
- data/test/unit/i18n_unit_test.rb +2 -2
- data/test/unit/lexer_unit_test.rb +12 -9
- data/test/unit/parser_unit_test.rb +2 -2
- data/test/unit/regexp_unit_test.rb +1 -1
- data/test/unit/strainer_unit_test.rb +96 -1
- data/test/unit/tag_unit_test.rb +7 -2
- data/test/unit/tags/case_tag_unit_test.rb +1 -1
- data/test/unit/tags/for_tag_unit_test.rb +2 -2
- data/test/unit/tags/if_tag_unit_test.rb +1 -1
- data/test/unit/template_unit_test.rb +14 -5
- data/test/unit/tokenizer_unit_test.rb +24 -7
- data/test/unit/variable_unit_test.rb +60 -43
- metadata +62 -50
- data/lib/liquid/module_ex.rb +0 -62
- data/lib/liquid/token.rb +0 -18
- data/test/unit/module_ex_unit_test.rb +0 -87
| @@ -34,7 +34,7 @@ class BlockUnitTest < Minitest::Test | |
| 34 34 | 
             
                template = Liquid::Template.parse("  {{funk}} {{so}} {{brother}} ")
         | 
| 35 35 | 
             
                assert_equal 7, template.root.nodelist.size
         | 
| 36 36 | 
             
                assert_equal [String, Variable, String, Variable, String, Variable, String],
         | 
| 37 | 
            -
             | 
| 37 | 
            +
                  block_types(template.root.nodelist)
         | 
| 38 38 | 
             
              end
         | 
| 39 39 |  | 
| 40 40 | 
             
              def test_with_block
         | 
| @@ -45,11 +45,14 @@ class BlockUnitTest < Minitest::Test | |
| 45 45 |  | 
| 46 46 | 
             
              def test_with_custom_tag
         | 
| 47 47 | 
             
                Liquid::Template.register_tag("testtag", Block)
         | 
| 48 | 
            -
                assert Liquid::Template.parse( | 
| 48 | 
            +
                assert Liquid::Template.parse("{% testtag %} {% endtesttag %}")
         | 
| 49 | 
            +
              ensure
         | 
| 50 | 
            +
                Liquid::Template.tags.delete('testtag')
         | 
| 49 51 | 
             
              end
         | 
| 50 52 |  | 
| 51 53 | 
             
              private
         | 
| 52 | 
            -
             | 
| 53 | 
            -
             | 
| 54 | 
            -
                 | 
| 54 | 
            +
             | 
| 55 | 
            +
              def block_types(nodelist)
         | 
| 56 | 
            +
                nodelist.collect(&:class)
         | 
| 57 | 
            +
              end
         | 
| 55 58 | 
             
            end # VariableTest
         | 
| @@ -3,147 +3,164 @@ require 'test_helper' | |
| 3 3 | 
             
            class ConditionUnitTest < Minitest::Test
         | 
| 4 4 | 
             
              include Liquid
         | 
| 5 5 |  | 
| 6 | 
            +
              def setup
         | 
| 7 | 
            +
                @context = Liquid::Context.new
         | 
| 8 | 
            +
              end
         | 
| 9 | 
            +
             | 
| 6 10 | 
             
              def test_basic_condition
         | 
| 7 | 
            -
                assert_equal false, Condition.new( | 
| 8 | 
            -
                assert_equal true,  Condition.new( | 
| 11 | 
            +
                assert_equal false, Condition.new(1, '==', 2).evaluate
         | 
| 12 | 
            +
                assert_equal true,  Condition.new(1, '==', 1).evaluate
         | 
| 9 13 | 
             
              end
         | 
| 10 14 |  | 
| 11 15 | 
             
              def test_default_operators_evalute_true
         | 
| 12 | 
            -
                 | 
| 13 | 
            -
                 | 
| 14 | 
            -
                 | 
| 15 | 
            -
                 | 
| 16 | 
            -
                 | 
| 17 | 
            -
                 | 
| 18 | 
            -
                 | 
| 19 | 
            -
                 | 
| 20 | 
            -
                 | 
| 16 | 
            +
                assert_evaluates_true 1, '==', 1
         | 
| 17 | 
            +
                assert_evaluates_true 1, '!=', 2
         | 
| 18 | 
            +
                assert_evaluates_true 1, '<>', 2
         | 
| 19 | 
            +
                assert_evaluates_true 1, '<', 2
         | 
| 20 | 
            +
                assert_evaluates_true 2, '>', 1
         | 
| 21 | 
            +
                assert_evaluates_true 1, '>=', 1
         | 
| 22 | 
            +
                assert_evaluates_true 2, '>=', 1
         | 
| 23 | 
            +
                assert_evaluates_true 1, '<=', 2
         | 
| 24 | 
            +
                assert_evaluates_true 1, '<=', 1
         | 
| 21 25 | 
             
                # negative numbers
         | 
| 22 | 
            -
                 | 
| 23 | 
            -
                 | 
| 24 | 
            -
                 | 
| 25 | 
            -
                 | 
| 26 | 
            +
                assert_evaluates_true 1, '>', -1
         | 
| 27 | 
            +
                assert_evaluates_true -1, '<', 1
         | 
| 28 | 
            +
                assert_evaluates_true 1.0, '>', -1.0
         | 
| 29 | 
            +
                assert_evaluates_true -1.0, '<', 1.0
         | 
| 26 30 | 
             
              end
         | 
| 27 31 |  | 
| 28 32 | 
             
              def test_default_operators_evalute_false
         | 
| 29 | 
            -
                 | 
| 30 | 
            -
                 | 
| 31 | 
            -
                 | 
| 32 | 
            -
                 | 
| 33 | 
            -
                 | 
| 34 | 
            -
                 | 
| 35 | 
            -
                 | 
| 36 | 
            -
                 | 
| 37 | 
            -
                 | 
| 33 | 
            +
                assert_evaluates_false 1, '==', 2
         | 
| 34 | 
            +
                assert_evaluates_false 1, '!=', 1
         | 
| 35 | 
            +
                assert_evaluates_false 1, '<>', 1
         | 
| 36 | 
            +
                assert_evaluates_false 1, '<', 0
         | 
| 37 | 
            +
                assert_evaluates_false 2, '>', 4
         | 
| 38 | 
            +
                assert_evaluates_false 1, '>=', 3
         | 
| 39 | 
            +
                assert_evaluates_false 2, '>=', 4
         | 
| 40 | 
            +
                assert_evaluates_false 1, '<=', 0
         | 
| 41 | 
            +
                assert_evaluates_false 1, '<=', 0
         | 
| 38 42 | 
             
              end
         | 
| 39 43 |  | 
| 40 44 | 
             
              def test_contains_works_on_strings
         | 
| 41 | 
            -
                 | 
| 42 | 
            -
                 | 
| 43 | 
            -
                 | 
| 44 | 
            -
                 | 
| 45 | 
            -
                 | 
| 46 | 
            -
             | 
| 47 | 
            -
                 | 
| 48 | 
            -
                 | 
| 49 | 
            -
                 | 
| 45 | 
            +
                assert_evaluates_true 'bob', 'contains', 'o'
         | 
| 46 | 
            +
                assert_evaluates_true 'bob', 'contains', 'b'
         | 
| 47 | 
            +
                assert_evaluates_true 'bob', 'contains', 'bo'
         | 
| 48 | 
            +
                assert_evaluates_true 'bob', 'contains', 'ob'
         | 
| 49 | 
            +
                assert_evaluates_true 'bob', 'contains', 'bob'
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                assert_evaluates_false 'bob', 'contains', 'bob2'
         | 
| 52 | 
            +
                assert_evaluates_false 'bob', 'contains', 'a'
         | 
| 53 | 
            +
                assert_evaluates_false 'bob', 'contains', '---'
         | 
| 50 54 | 
             
              end
         | 
| 51 55 |  | 
| 52 56 | 
             
              def test_invalid_comparation_operator
         | 
| 53 | 
            -
                assert_evaluates_argument_error  | 
| 57 | 
            +
                assert_evaluates_argument_error 1, '~~', 0
         | 
| 54 58 | 
             
              end
         | 
| 55 59 |  | 
| 56 60 | 
             
              def test_comparation_of_int_and_str
         | 
| 57 | 
            -
                assert_evaluates_argument_error  | 
| 58 | 
            -
                assert_evaluates_argument_error  | 
| 59 | 
            -
                assert_evaluates_argument_error  | 
| 60 | 
            -
                assert_evaluates_argument_error  | 
| 61 | 
            +
                assert_evaluates_argument_error '1', '>', 0
         | 
| 62 | 
            +
                assert_evaluates_argument_error '1', '<', 0
         | 
| 63 | 
            +
                assert_evaluates_argument_error '1', '>=', 0
         | 
| 64 | 
            +
                assert_evaluates_argument_error '1', '<=', 0
         | 
| 65 | 
            +
              end
         | 
| 66 | 
            +
             | 
| 67 | 
            +
              def test_hash_compare_backwards_compatibility
         | 
| 68 | 
            +
                assert_nil Condition.new({}, '>', 2).evaluate
         | 
| 69 | 
            +
                assert_nil Condition.new(2, '>', {}).evaluate
         | 
| 70 | 
            +
                assert_equal false, Condition.new({}, '==', 2).evaluate
         | 
| 71 | 
            +
                assert_equal true, Condition.new({ 'a' => 1 }, '==', { 'a' => 1 }).evaluate
         | 
| 72 | 
            +
                assert_equal true, Condition.new({ 'a' => 2 }, 'contains', 'a').evaluate
         | 
| 61 73 | 
             
              end
         | 
| 62 74 |  | 
| 63 75 | 
             
              def test_contains_works_on_arrays
         | 
| 64 76 | 
             
                @context = Liquid::Context.new
         | 
| 65 | 
            -
                @context['array'] = [1,2,3,4,5]
         | 
| 66 | 
            -
             | 
| 67 | 
            -
             | 
| 68 | 
            -
                 | 
| 69 | 
            -
                 | 
| 70 | 
            -
                 | 
| 71 | 
            -
                 | 
| 72 | 
            -
                 | 
| 73 | 
            -
                 | 
| 74 | 
            -
                 | 
| 77 | 
            +
                @context['array'] = [1, 2, 3, 4, 5]
         | 
| 78 | 
            +
                array_expr = VariableLookup.new("array")
         | 
| 79 | 
            +
             | 
| 80 | 
            +
                assert_evaluates_false array_expr, 'contains', 0
         | 
| 81 | 
            +
                assert_evaluates_true array_expr, 'contains', 1
         | 
| 82 | 
            +
                assert_evaluates_true array_expr, 'contains', 2
         | 
| 83 | 
            +
                assert_evaluates_true array_expr, 'contains', 3
         | 
| 84 | 
            +
                assert_evaluates_true array_expr, 'contains', 4
         | 
| 85 | 
            +
                assert_evaluates_true array_expr, 'contains', 5
         | 
| 86 | 
            +
                assert_evaluates_false array_expr, 'contains', 6
         | 
| 87 | 
            +
                assert_evaluates_false array_expr, 'contains', "1"
         | 
| 75 88 | 
             
              end
         | 
| 76 89 |  | 
| 77 90 | 
             
              def test_contains_returns_false_for_nil_operands
         | 
| 78 91 | 
             
                @context = Liquid::Context.new
         | 
| 79 | 
            -
                 | 
| 80 | 
            -
                 | 
| 92 | 
            +
                assert_evaluates_false VariableLookup.new('not_assigned'), 'contains', '0'
         | 
| 93 | 
            +
                assert_evaluates_false 0, 'contains', VariableLookup.new('not_assigned')
         | 
| 81 94 | 
             
              end
         | 
| 82 95 |  | 
| 83 96 | 
             
              def test_contains_return_false_on_wrong_data_type
         | 
| 84 | 
            -
                 | 
| 97 | 
            +
                assert_evaluates_false 1, 'contains', 0
         | 
| 98 | 
            +
              end
         | 
| 99 | 
            +
             | 
| 100 | 
            +
              def test_contains_with_string_left_operand_coerces_right_operand_to_string
         | 
| 101 | 
            +
                assert_evaluates_true ' 1 ', 'contains', 1
         | 
| 102 | 
            +
                assert_evaluates_false ' 1 ', 'contains', 2
         | 
| 85 103 | 
             
              end
         | 
| 86 104 |  | 
| 87 105 | 
             
              def test_or_condition
         | 
| 88 | 
            -
                condition = Condition.new( | 
| 106 | 
            +
                condition = Condition.new(1, '==', 2)
         | 
| 89 107 |  | 
| 90 108 | 
             
                assert_equal false, condition.evaluate
         | 
| 91 109 |  | 
| 92 | 
            -
                condition.or Condition.new( | 
| 110 | 
            +
                condition.or Condition.new(2, '==', 1)
         | 
| 93 111 |  | 
| 94 112 | 
             
                assert_equal false, condition.evaluate
         | 
| 95 113 |  | 
| 96 | 
            -
                condition.or Condition.new( | 
| 114 | 
            +
                condition.or Condition.new(1, '==', 1)
         | 
| 97 115 |  | 
| 98 116 | 
             
                assert_equal true, condition.evaluate
         | 
| 99 117 | 
             
              end
         | 
| 100 118 |  | 
| 101 119 | 
             
              def test_and_condition
         | 
| 102 | 
            -
                condition = Condition.new( | 
| 120 | 
            +
                condition = Condition.new(1, '==', 1)
         | 
| 103 121 |  | 
| 104 122 | 
             
                assert_equal true, condition.evaluate
         | 
| 105 123 |  | 
| 106 | 
            -
                condition.and Condition.new( | 
| 124 | 
            +
                condition.and Condition.new(2, '==', 2)
         | 
| 107 125 |  | 
| 108 126 | 
             
                assert_equal true, condition.evaluate
         | 
| 109 127 |  | 
| 110 | 
            -
                condition.and Condition.new( | 
| 128 | 
            +
                condition.and Condition.new(2, '==', 1)
         | 
| 111 129 |  | 
| 112 130 | 
             
                assert_equal false, condition.evaluate
         | 
| 113 131 | 
             
              end
         | 
| 114 132 |  | 
| 115 133 | 
             
              def test_should_allow_custom_proc_operator
         | 
| 116 | 
            -
                Condition.operators['starts_with'] =  | 
| 134 | 
            +
                Condition.operators['starts_with'] = proc { |cond, left, right| left =~ %r{^#{right}} }
         | 
| 117 135 |  | 
| 118 | 
            -
                 | 
| 119 | 
            -
                 | 
| 120 | 
            -
             | 
| 121 | 
            -
                 | 
| 122 | 
            -
                  Condition.operators.delete 'starts_with'
         | 
| 136 | 
            +
                assert_evaluates_true 'bob', 'starts_with', 'b'
         | 
| 137 | 
            +
                assert_evaluates_false 'bob', 'starts_with', 'o'
         | 
| 138 | 
            +
              ensure
         | 
| 139 | 
            +
                Condition.operators.delete 'starts_with'
         | 
| 123 140 | 
             
              end
         | 
| 124 141 |  | 
| 125 142 | 
             
              def test_left_or_right_may_contain_operators
         | 
| 126 143 | 
             
                @context = Liquid::Context.new
         | 
| 127 144 | 
             
                @context['one'] = @context['another'] = "gnomeslab-and-or-liquid"
         | 
| 128 145 |  | 
| 129 | 
            -
                 | 
| 146 | 
            +
                assert_evaluates_true VariableLookup.new("one"), '==', VariableLookup.new("another")
         | 
| 130 147 | 
             
              end
         | 
| 131 148 |  | 
| 132 149 | 
             
              private
         | 
| 133 | 
            -
                def assert_evalutes_true(left, op, right)
         | 
| 134 | 
            -
                  assert Condition.new(left, op, right).evaluate(@context || Liquid::Context.new),
         | 
| 135 | 
            -
                         "Evaluated false: #{left} #{op} #{right}"
         | 
| 136 | 
            -
                end
         | 
| 137 150 |  | 
| 138 | 
            -
             | 
| 139 | 
            -
             | 
| 140 | 
            -
             | 
| 141 | 
            -
             | 
| 151 | 
            +
              def assert_evaluates_true(left, op, right)
         | 
| 152 | 
            +
                assert Condition.new(left, op, right).evaluate(@context),
         | 
| 153 | 
            +
                  "Evaluated false: #{left} #{op} #{right}"
         | 
| 154 | 
            +
              end
         | 
| 142 155 |  | 
| 143 | 
            -
             | 
| 144 | 
            -
             | 
| 145 | 
            -
             | 
| 146 | 
            -
             | 
| 147 | 
            -
                end
         | 
| 156 | 
            +
              def assert_evaluates_false(left, op, right)
         | 
| 157 | 
            +
                assert !Condition.new(left, op, right).evaluate(@context),
         | 
| 158 | 
            +
                  "Evaluated true: #{left} #{op} #{right}"
         | 
| 159 | 
            +
              end
         | 
| 148 160 |  | 
| 161 | 
            +
              def assert_evaluates_argument_error(left, op, right)
         | 
| 162 | 
            +
                assert_raises(Liquid::ArgumentError) do
         | 
| 163 | 
            +
                  Condition.new(left, op, right).evaluate(@context)
         | 
| 164 | 
            +
                end
         | 
| 165 | 
            +
              end
         | 
| 149 166 | 
             
            end # ConditionTest
         | 
| @@ -70,10 +70,6 @@ class ContextUnitTest < Minitest::Test | |
| 70 70 | 
             
                @context = Liquid::Context.new
         | 
| 71 71 | 
             
              end
         | 
| 72 72 |  | 
| 73 | 
            -
              def teardown
         | 
| 74 | 
            -
                Spy.teardown
         | 
| 75 | 
            -
              end
         | 
| 76 | 
            -
             | 
| 77 73 | 
             
              def test_variables
         | 
| 78 74 | 
             
                @context['string'] = 'string'
         | 
| 79 75 | 
             
                assert_equal 'string', @context['string']
         | 
| @@ -98,12 +94,12 @@ class ContextUnitTest < Minitest::Test | |
| 98 94 | 
             
                assert_equal false, @context['bool']
         | 
| 99 95 |  | 
| 100 96 | 
             
                @context['nil'] = nil
         | 
| 101 | 
            -
                 | 
| 102 | 
            -
                 | 
| 97 | 
            +
                assert_nil @context['nil']
         | 
| 98 | 
            +
                assert_nil @context['nil']
         | 
| 103 99 | 
             
              end
         | 
| 104 100 |  | 
| 105 101 | 
             
              def test_variables_not_existing
         | 
| 106 | 
            -
                 | 
| 102 | 
            +
                assert_nil @context['does_not_exist']
         | 
| 107 103 | 
             
              end
         | 
| 108 104 |  | 
| 109 105 | 
             
              def test_scoping
         | 
| @@ -122,30 +118,25 @@ class ContextUnitTest < Minitest::Test | |
| 122 118 | 
             
              end
         | 
| 123 119 |  | 
| 124 120 | 
             
              def test_length_query
         | 
| 125 | 
            -
             | 
| 126 | 
            -
                @context['numbers'] = [1,2,3,4]
         | 
| 121 | 
            +
                @context['numbers'] = [1, 2, 3, 4]
         | 
| 127 122 |  | 
| 128 123 | 
             
                assert_equal 4, @context['numbers.size']
         | 
| 129 124 |  | 
| 130 | 
            -
                @context['numbers'] = {1 => 1,2 => 2,3 => 3,4 => 4}
         | 
| 125 | 
            +
                @context['numbers'] = { 1 => 1, 2 => 2, 3 => 3, 4 => 4 }
         | 
| 131 126 |  | 
| 132 127 | 
             
                assert_equal 4, @context['numbers.size']
         | 
| 133 128 |  | 
| 134 | 
            -
                @context['numbers'] = {1 => 1,2 => 2,3 => 3,4 => 4, 'size' => 1000}
         | 
| 129 | 
            +
                @context['numbers'] = { 1 => 1, 2 => 2, 3 => 3, 4 => 4, 'size' => 1000 }
         | 
| 135 130 |  | 
| 136 131 | 
             
                assert_equal 1000, @context['numbers.size']
         | 
| 137 | 
            -
             | 
| 138 132 | 
             
              end
         | 
| 139 133 |  | 
| 140 134 | 
             
              def test_hyphenated_variable
         | 
| 141 | 
            -
             | 
| 142 135 | 
             
                @context['oh-my'] = 'godz'
         | 
| 143 136 | 
             
                assert_equal 'godz', @context['oh-my']
         | 
| 144 | 
            -
             | 
| 145 137 | 
             
              end
         | 
| 146 138 |  | 
| 147 139 | 
             
              def test_add_filter
         | 
| 148 | 
            -
             | 
| 149 140 | 
             
                filter = Module.new do
         | 
| 150 141 | 
             
                  def hi(output)
         | 
| 151 142 | 
             
                    output + ' hi!'
         | 
| @@ -161,11 +152,9 @@ class ContextUnitTest < Minitest::Test | |
| 161 152 |  | 
| 162 153 | 
             
                context.add_filters(filter)
         | 
| 163 154 | 
             
                assert_equal 'hi? hi!', context.invoke(:hi, 'hi?')
         | 
| 164 | 
            -
             | 
| 165 155 | 
             
              end
         | 
| 166 156 |  | 
| 167 157 | 
             
              def test_only_intended_filters_make_it_there
         | 
| 168 | 
            -
             | 
| 169 158 | 
             
                filter = Module.new do
         | 
| 170 159 | 
             
                  def hi(output)
         | 
| 171 160 | 
             
                    output + ' hi!'
         | 
| @@ -192,11 +181,11 @@ class ContextUnitTest < Minitest::Test | |
| 192 181 | 
             
                @context['test'] = 'test'
         | 
| 193 182 | 
             
                assert_equal 'test', @context['test']
         | 
| 194 183 | 
             
                @context.pop
         | 
| 195 | 
            -
                 | 
| 184 | 
            +
                assert_nil @context['test']
         | 
| 196 185 | 
             
              end
         | 
| 197 186 |  | 
| 198 187 | 
             
              def test_hierachical_data
         | 
| 199 | 
            -
                @context['hash'] = {"name" => 'tobi'}
         | 
| 188 | 
            +
                @context['hash'] = { "name" => 'tobi' }
         | 
| 200 189 | 
             
                assert_equal 'tobi', @context['hash.name']
         | 
| 201 190 | 
             
                assert_equal 'tobi', @context['hash["name"]']
         | 
| 202 191 | 
             
              end
         | 
| @@ -225,7 +214,7 @@ class ContextUnitTest < Minitest::Test | |
| 225 214 | 
             
              end
         | 
| 226 215 |  | 
| 227 216 | 
             
              def test_array_notation
         | 
| 228 | 
            -
                @context['test'] = [1,2,3,4,5]
         | 
| 217 | 
            +
                @context['test'] = [1, 2, 3, 4, 5]
         | 
| 229 218 |  | 
| 230 219 | 
             
                assert_equal 1, @context['test[0]']
         | 
| 231 220 | 
             
                assert_equal 2, @context['test[1]']
         | 
| @@ -235,21 +224,21 @@ class ContextUnitTest < Minitest::Test | |
| 235 224 | 
             
              end
         | 
| 236 225 |  | 
| 237 226 | 
             
              def test_recoursive_array_notation
         | 
| 238 | 
            -
                @context['test'] = {'test' => [1,2,3,4,5]}
         | 
| 227 | 
            +
                @context['test'] = { 'test' => [1, 2, 3, 4, 5] }
         | 
| 239 228 |  | 
| 240 229 | 
             
                assert_equal 1, @context['test.test[0]']
         | 
| 241 230 |  | 
| 242 | 
            -
                @context['test'] = [{'test' => 'worked'}]
         | 
| 231 | 
            +
                @context['test'] = [{ 'test' => 'worked' }]
         | 
| 243 232 |  | 
| 244 233 | 
             
                assert_equal 'worked', @context['test[0].test']
         | 
| 245 234 | 
             
              end
         | 
| 246 235 |  | 
| 247 236 | 
             
              def test_hash_to_array_transition
         | 
| 248 237 | 
             
                @context['colors'] = {
         | 
| 249 | 
            -
                  'Blue'    => ['003366','336699', '6699CC', '99CCFF'],
         | 
| 250 | 
            -
                  'Green'   => ['003300','336633', '669966', '99CC99'],
         | 
| 251 | 
            -
                  'Yellow'  => ['CC9900','FFCC00', 'FFFF99', 'FFFFCC'],
         | 
| 252 | 
            -
                  'Red'     => ['660000','993333', 'CC6666', 'FF9999']
         | 
| 238 | 
            +
                  'Blue'    => ['003366', '336699', '6699CC', '99CCFF'],
         | 
| 239 | 
            +
                  'Green'   => ['003300', '336633', '669966', '99CC99'],
         | 
| 240 | 
            +
                  'Yellow'  => ['CC9900', 'FFCC00', 'FFFF99', 'FFFFCC'],
         | 
| 241 | 
            +
                  'Red'     => ['660000', '993333', 'CC6666', 'FF9999']
         | 
| 253 242 | 
             
                }
         | 
| 254 243 |  | 
| 255 244 | 
             
                assert_equal '003366', @context['colors.Blue[0]']
         | 
| @@ -257,12 +246,12 @@ class ContextUnitTest < Minitest::Test | |
| 257 246 | 
             
              end
         | 
| 258 247 |  | 
| 259 248 | 
             
              def test_try_first
         | 
| 260 | 
            -
                @context['test'] = [1,2,3,4,5]
         | 
| 249 | 
            +
                @context['test'] = [1, 2, 3, 4, 5]
         | 
| 261 250 |  | 
| 262 251 | 
             
                assert_equal 1, @context['test.first']
         | 
| 263 252 | 
             
                assert_equal 5, @context['test.last']
         | 
| 264 253 |  | 
| 265 | 
            -
                @context['test'] = {'test' => [1,2,3,4,5]}
         | 
| 254 | 
            +
                @context['test'] = { 'test' => [1, 2, 3, 4, 5] }
         | 
| 266 255 |  | 
| 267 256 | 
             
                assert_equal 1, @context['test.test.first']
         | 
| 268 257 | 
             
                assert_equal 5, @context['test.test.last']
         | 
| @@ -273,8 +262,8 @@ class ContextUnitTest < Minitest::Test | |
| 273 262 | 
             
              end
         | 
| 274 263 |  | 
| 275 264 | 
             
              def test_access_hashes_with_hash_notation
         | 
| 276 | 
            -
                @context['products'] = {'count' => 5, 'tags' => ['deepsnow', 'freestyle'] }
         | 
| 277 | 
            -
                @context['product'] = {'variants' => [ {'title' => 'draft151cm'}, {'title' => 'element151cm'} | 
| 265 | 
            +
                @context['products'] = { 'count' => 5, 'tags' => ['deepsnow', 'freestyle'] }
         | 
| 266 | 
            +
                @context['product'] = { 'variants' => [ { 'title' => 'draft151cm' }, { 'title' => 'element151cm' } ] }
         | 
| 278 267 |  | 
| 279 268 | 
             
                assert_equal 5, @context['products["count"]']
         | 
| 280 269 | 
             
                assert_equal 'deepsnow', @context['products["tags"][0]']
         | 
| @@ -294,85 +283,82 @@ class ContextUnitTest < Minitest::Test | |
| 294 283 | 
             
              end
         | 
| 295 284 |  | 
| 296 285 | 
             
              def test_access_hashes_with_hash_access_variables
         | 
| 297 | 
            -
             | 
| 298 286 | 
             
                @context['var'] = 'tags'
         | 
| 299 | 
            -
                @context['nested'] = {'var' => 'tags'}
         | 
| 300 | 
            -
                @context['products'] = {'count' => 5, 'tags' => ['deepsnow', 'freestyle'] }
         | 
| 287 | 
            +
                @context['nested'] = { 'var' => 'tags' }
         | 
| 288 | 
            +
                @context['products'] = { 'count' => 5, 'tags' => ['deepsnow', 'freestyle'] }
         | 
| 301 289 |  | 
| 302 290 | 
             
                assert_equal 'deepsnow', @context['products[var].first']
         | 
| 303 291 | 
             
                assert_equal 'freestyle', @context['products[nested.var].last']
         | 
| 304 292 | 
             
              end
         | 
| 305 293 |  | 
| 306 294 | 
             
              def test_hash_notation_only_for_hash_access
         | 
| 307 | 
            -
                @context['array'] = [1,2,3,4,5]
         | 
| 308 | 
            -
                @context['hash'] = {'first' => 'Hello'}
         | 
| 295 | 
            +
                @context['array'] = [1, 2, 3, 4, 5]
         | 
| 296 | 
            +
                @context['hash'] = { 'first' => 'Hello' }
         | 
| 309 297 |  | 
| 310 298 | 
             
                assert_equal 1, @context['array.first']
         | 
| 311 | 
            -
                 | 
| 299 | 
            +
                assert_nil @context['array["first"]']
         | 
| 312 300 | 
             
                assert_equal 'Hello', @context['hash["first"]']
         | 
| 313 301 | 
             
              end
         | 
| 314 302 |  | 
| 315 303 | 
             
              def test_first_can_appear_in_middle_of_callchain
         | 
| 316 | 
            -
             | 
| 317 | 
            -
                @context['product'] = {'variants' => [ {'title' => 'draft151cm'}, {'title' => 'element151cm'}  ]}
         | 
| 304 | 
            +
                @context['product'] = { 'variants' => [ { 'title' => 'draft151cm' }, { 'title' => 'element151cm' } ] }
         | 
| 318 305 |  | 
| 319 306 | 
             
                assert_equal 'draft151cm', @context['product.variants[0].title']
         | 
| 320 307 | 
             
                assert_equal 'element151cm', @context['product.variants[1].title']
         | 
| 321 308 | 
             
                assert_equal 'draft151cm', @context['product.variants.first.title']
         | 
| 322 309 | 
             
                assert_equal 'element151cm', @context['product.variants.last.title']
         | 
| 323 | 
            -
             | 
| 324 310 | 
             
              end
         | 
| 325 311 |  | 
| 326 312 | 
             
              def test_cents
         | 
| 327 | 
            -
                @context.merge( | 
| 313 | 
            +
                @context.merge("cents" => HundredCentes.new)
         | 
| 328 314 | 
             
                assert_equal 100, @context['cents']
         | 
| 329 315 | 
             
              end
         | 
| 330 316 |  | 
| 331 317 | 
             
              def test_nested_cents
         | 
| 332 | 
            -
                @context.merge( | 
| 318 | 
            +
                @context.merge("cents" => { 'amount' => HundredCentes.new })
         | 
| 333 319 | 
             
                assert_equal 100, @context['cents.amount']
         | 
| 334 320 |  | 
| 335 | 
            -
                @context.merge( | 
| 321 | 
            +
                @context.merge("cents" => { 'cents' => { 'amount' => HundredCentes.new } })
         | 
| 336 322 | 
             
                assert_equal 100, @context['cents.cents.amount']
         | 
| 337 323 | 
             
              end
         | 
| 338 324 |  | 
| 339 325 | 
             
              def test_cents_through_drop
         | 
| 340 | 
            -
                @context.merge( | 
| 326 | 
            +
                @context.merge("cents" => CentsDrop.new)
         | 
| 341 327 | 
             
                assert_equal 100, @context['cents.amount']
         | 
| 342 328 | 
             
              end
         | 
| 343 329 |  | 
| 344 330 | 
             
              def test_nested_cents_through_drop
         | 
| 345 | 
            -
                @context.merge( | 
| 331 | 
            +
                @context.merge("vars" => { "cents" => CentsDrop.new })
         | 
| 346 332 | 
             
                assert_equal 100, @context['vars.cents.amount']
         | 
| 347 333 | 
             
              end
         | 
| 348 334 |  | 
| 349 335 | 
             
              def test_drop_methods_with_question_marks
         | 
| 350 | 
            -
                @context.merge( | 
| 336 | 
            +
                @context.merge("cents" => CentsDrop.new)
         | 
| 351 337 | 
             
                assert @context['cents.non_zero?']
         | 
| 352 338 | 
             
              end
         | 
| 353 339 |  | 
| 354 340 | 
             
              def test_context_from_within_drop
         | 
| 355 | 
            -
                @context.merge( | 
| 341 | 
            +
                @context.merge("test" => '123', "vars" => ContextSensitiveDrop.new)
         | 
| 356 342 | 
             
                assert_equal '123', @context['vars.test']
         | 
| 357 343 | 
             
              end
         | 
| 358 344 |  | 
| 359 345 | 
             
              def test_nested_context_from_within_drop
         | 
| 360 | 
            -
                @context.merge( | 
| 346 | 
            +
                @context.merge("test" => '123', "vars" => { "local" => ContextSensitiveDrop.new })
         | 
| 361 347 | 
             
                assert_equal '123', @context['vars.local.test']
         | 
| 362 348 | 
             
              end
         | 
| 363 349 |  | 
| 364 350 | 
             
              def test_ranges
         | 
| 365 | 
            -
                @context.merge( | 
| 351 | 
            +
                @context.merge("test" => '5')
         | 
| 366 352 | 
             
                assert_equal (1..5), @context['(1..5)']
         | 
| 367 353 | 
             
                assert_equal (1..5), @context['(1..test)']
         | 
| 368 354 | 
             
                assert_equal (5..5), @context['(test..test)']
         | 
| 369 355 | 
             
              end
         | 
| 370 356 |  | 
| 371 357 | 
             
              def test_cents_through_drop_nestedly
         | 
| 372 | 
            -
                @context.merge( | 
| 358 | 
            +
                @context.merge("cents" => { "cents" => CentsDrop.new })
         | 
| 373 359 | 
             
                assert_equal 100, @context['cents.cents.amount']
         | 
| 374 360 |  | 
| 375 | 
            -
                @context.merge( | 
| 361 | 
            +
                @context.merge("cents" => { "cents" => { "cents" => CentsDrop.new } })
         | 
| 376 362 | 
             
                assert_equal 100, @context['cents.cents.cents.amount']
         | 
| 377 363 | 
             
              end
         | 
| 378 364 |  | 
| @@ -393,7 +379,7 @@ class ContextUnitTest < Minitest::Test | |
| 393 379 | 
             
              end
         | 
| 394 380 |  | 
| 395 381 | 
             
              def test_proc_as_variable
         | 
| 396 | 
            -
                @context['dynamic'] =  | 
| 382 | 
            +
                @context['dynamic'] = proc { 'Hello' }
         | 
| 397 383 |  | 
| 398 384 | 
             
                assert_equal 'Hello', @context['dynamic']
         | 
| 399 385 | 
             
              end
         | 
| @@ -411,7 +397,7 @@ class ContextUnitTest < Minitest::Test | |
| 411 397 | 
             
              end
         | 
| 412 398 |  | 
| 413 399 | 
             
              def test_array_containing_lambda_as_variable
         | 
| 414 | 
            -
                @context['dynamic'] = [1,2, proc { 'Hello' }  | 
| 400 | 
            +
                @context['dynamic'] = [1, 2, proc { 'Hello' }, 4, 5]
         | 
| 415 401 |  | 
| 416 402 | 
             
                assert_equal 'Hello', @context['dynamic[2]']
         | 
| 417 403 | 
             
              end
         | 
| @@ -437,7 +423,7 @@ class ContextUnitTest < Minitest::Test | |
| 437 423 | 
             
              end
         | 
| 438 424 |  | 
| 439 425 | 
             
              def test_lambda_in_array_is_called_once
         | 
| 440 | 
            -
                @context['callcount'] = [1,2, proc { @global ||= 0; @global += 1; @global.to_s }  | 
| 426 | 
            +
                @context['callcount'] = [1, 2, proc { @global ||= 0; @global += 1; @global.to_s }, 4, 5]
         | 
| 441 427 |  | 
| 442 428 | 
             
                assert_equal '1', @context['callcount[2]']
         | 
| 443 429 | 
             
                assert_equal '1', @context['callcount[2]']
         | 
| @@ -460,33 +446,44 @@ class ContextUnitTest < Minitest::Test | |
| 460 446 | 
             
                assert_equal @context, @context['category'].context
         | 
| 461 447 | 
             
              end
         | 
| 462 448 |  | 
| 463 | 
            -
              def  | 
| 464 | 
            -
                 | 
| 465 | 
            -
             | 
| 466 | 
            -
                 | 
| 449 | 
            +
              def test_interrupt_avoids_object_allocations
         | 
| 450 | 
            +
                assert_no_object_allocations do
         | 
| 451 | 
            +
                  @context.interrupt?
         | 
| 452 | 
            +
                end
         | 
| 453 | 
            +
              end
         | 
| 467 454 |  | 
| 468 | 
            -
             | 
| 455 | 
            +
              def test_context_initialization_with_a_proc_in_environment
         | 
| 456 | 
            +
                contx = Context.new([test: ->(c) { c['poutine'] }], { test: :foo })
         | 
| 469 457 |  | 
| 470 | 
            -
                 | 
| 471 | 
            -
                 | 
| 472 | 
            -
              end | 
| 458 | 
            +
                assert contx
         | 
| 459 | 
            +
                assert_nil contx['poutine']
         | 
| 460 | 
            +
              end
         | 
| 473 461 |  | 
| 474 | 
            -
              def  | 
| 475 | 
            -
                 | 
| 462 | 
            +
              def test_apply_global_filter
         | 
| 463 | 
            +
                global_filter_proc = ->(output) { "#{output} filtered" }
         | 
| 476 464 |  | 
| 477 | 
            -
                 | 
| 478 | 
            -
                 | 
| 479 | 
            -
                @context['string']
         | 
| 465 | 
            +
                context = Context.new
         | 
| 466 | 
            +
                context.global_filter = global_filter_proc
         | 
| 480 467 |  | 
| 481 | 
            -
                assert_equal  | 
| 468 | 
            +
                assert_equal 'hi filtered', context.apply_global_filter('hi')
         | 
| 482 469 | 
             
              end
         | 
| 483 470 |  | 
| 484 | 
            -
              def  | 
| 485 | 
            -
                 | 
| 486 | 
            -
             | 
| 487 | 
            -
                assert contx
         | 
| 488 | 
            -
                assert_nil contx['poutine']
         | 
| 471 | 
            +
              def test_apply_global_filter_when_no_global_filter_exist
         | 
| 472 | 
            +
                context = Context.new
         | 
| 473 | 
            +
                assert_equal 'hi', context.apply_global_filter('hi')
         | 
| 489 474 | 
             
              end
         | 
| 490 475 |  | 
| 476 | 
            +
              private
         | 
| 491 477 |  | 
| 478 | 
            +
              def assert_no_object_allocations
         | 
| 479 | 
            +
                unless RUBY_ENGINE == 'ruby'
         | 
| 480 | 
            +
                  skip "stackprof needed to count object allocations"
         | 
| 481 | 
            +
                end
         | 
| 482 | 
            +
                require 'stackprof'
         | 
| 483 | 
            +
             | 
| 484 | 
            +
                profile = StackProf.run(mode: :object) do
         | 
| 485 | 
            +
                  yield
         | 
| 486 | 
            +
                end
         | 
| 487 | 
            +
                assert_equal 0, profile[:samples]
         | 
| 488 | 
            +
              end
         | 
| 492 489 | 
             
            end # ContextTest
         | 
| @@ -5,13 +5,13 @@ class FileSystemUnitTest < Minitest::Test | |
| 5 5 |  | 
| 6 6 | 
             
              def test_default
         | 
| 7 7 | 
             
                assert_raises(FileSystemError) do
         | 
| 8 | 
            -
                  BlankFileSystem.new.read_template_file("dummy" | 
| 8 | 
            +
                  BlankFileSystem.new.read_template_file("dummy")
         | 
| 9 9 | 
             
                end
         | 
| 10 10 | 
             
              end
         | 
| 11 11 |  | 
| 12 12 | 
             
              def test_local
         | 
| 13 13 | 
             
                file_system = Liquid::LocalFileSystem.new("/some/path")
         | 
| 14 | 
            -
                assert_equal "/some/path/_mypartial.liquid" | 
| 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 17 | 
             
                assert_raises(FileSystemError) do
         | 
| @@ -29,7 +29,7 @@ class FileSystemUnitTest < Minitest::Test | |
| 29 29 |  | 
| 30 30 | 
             
              def test_custom_template_filename_patterns
         | 
| 31 31 | 
             
                file_system = Liquid::LocalFileSystem.new("/some/path", "%s.html")
         | 
| 32 | 
            -
                assert_equal "/some/path/mypartial.html" | 
| 32 | 
            +
                assert_equal "/some/path/mypartial.html", file_system.full_path("mypartial")
         | 
| 33 33 | 
             
                assert_equal "/some/path/dir/mypartial.html", file_system.full_path("dir/mypartial")
         | 
| 34 34 | 
             
              end
         | 
| 35 35 | 
             
            end # FileSystemTest
         | 
    
        data/test/unit/i18n_unit_test.rb
    CHANGED
    
    | @@ -16,7 +16,7 @@ class I18nUnitTest < Minitest::Test | |
| 16 16 | 
             
              end
         | 
| 17 17 |  | 
| 18 18 | 
             
              def test_single_string_interpolation
         | 
| 19 | 
            -
                assert_equal "something different", @i18n.translate("whatever", : | 
| 19 | 
            +
                assert_equal "something different", @i18n.translate("whatever", something: "different")
         | 
| 20 20 | 
             
              end
         | 
| 21 21 |  | 
| 22 22 | 
             
              # def test_raises_translation_error_on_undefined_interpolation_key
         | 
| @@ -24,7 +24,7 @@ class I18nUnitTest < Minitest::Test | |
| 24 24 | 
             
              #     @i18n.translate("whatever", :oopstypos => "yes")
         | 
| 25 25 | 
             
              #   end
         | 
| 26 26 | 
             
              # end
         | 
| 27 | 
            -
             | 
| 27 | 
            +
             | 
| 28 28 | 
             
              def test_raises_unknown_translation
         | 
| 29 29 | 
             
                assert_raises I18n::TranslationError do
         | 
| 30 30 | 
             
                  @i18n.translate("doesnt_exist")
         |