diff --git a/README.md b/README.md index 6802a71..055e032 100644 --- a/README.md +++ b/README.md @@ -80,22 +80,24 @@ It is also recommended that you use it in the template editors of existing apps By default, the renderer doesn't raise or in any other way notify you if some variables or filters are missing, i.e. not passed to the `render` method. You can improve this situation by passing `strict_variables: true` and/or `strict_filters: true` options to the `render` method. -When one of these options is set to true, all errors about undefined variables and undefined filters will be stored in `errors` array of a `Liquid::Template` instance. +When one of these options is set to true, all errors about undefined variables and undefined filters will be stored in an `errors` array on the `Liquid::Context` instance used for rendering. Here are some examples: ```ruby template = Liquid::Template.parse("{{x}} {{y}} {{z.a}} {{z.b}}") -template.render({ 'x' => 1, 'z' => { 'a' => 2 } }, { strict_variables: true }) +context = Liquid::Context.new({ 'x' => 1, 'z' => { 'a' => 2 } }) +template.render(context, { strict_variables: true }) #=> '1 2 ' # when a variable is undefined, it's rendered as nil -template.errors +context.errors #=> [#, #] ``` ```ruby template = Liquid::Template.parse("{{x | filter1 | upcase}}") -template.render({ 'x' => 'foo' }, { strict_filters: true }) +context = Liquid::Context.new({ 'x' => 'foo' }) +template.render(context, { strict_filters: true }) #=> '' # when at least one filter in the filter chain is undefined, a whole expression is rendered as nil -template.errors +context.errors #=> [#] ``` @@ -111,4 +113,4 @@ template.render!({ 'x' => 1}, { strict_variables: true }) To help track usages of a feature or code path in production, we have released opt-in usage tracking. To enable this, we provide an empty `Liquid:: Usage.increment` method which you can customize to your needs. The feature is well suited to https://github.com/Shopify/statsd-instrument. However, the choice of implementation is up to you. -Once you have enabled usage tracking, we recommend reporting any events through Github Issues that your system may be logging. It is highly likely this event has been added to consider deprecating or improving code specific to this event, so please raise any concerns. \ No newline at end of file +Once you have enabled usage tracking, we recommend reporting any events through Github Issues that your system may be logging. It is highly likely this event has been added to consider deprecating or improving code specific to this event, so please raise any concerns. diff --git a/lib/liquid/template.rb b/lib/liquid/template.rb index 189fcc0..b075930 100644 --- a/lib/liquid/template.rb +++ b/lib/liquid/template.rb @@ -16,7 +16,7 @@ module Liquid # class Template attr_accessor :root - attr_reader :resource_limits, :warnings + attr_reader :warnings class TagRegistry include Enumerable @@ -106,11 +106,6 @@ module Liquid end end - def initialize - @rethrow_errors = false - @resource_limits = ResourceLimits.new(Template.default_resource_limits) - end - # Parse source code. # Returns self for easy chaining def parse(source, options = {}) @@ -123,22 +118,6 @@ module Liquid self end - def registers - @registers ||= {} - end - - def assigns - @assigns ||= {} - end - - def instance_assigns - @instance_assigns ||= {} - end - - def errors - @errors ||= [] - end - # Render takes a hash with local variables. # # if you use the same filters over and over again consider registering them globally @@ -153,37 +132,18 @@ module Liquid # * registers : hash with register variables. Those can be accessed from # filters and tags and might be useful to integrate liquid more with its host application # - def render(*args) + def render(assigns_or_context = nil, options = nil) return '' if @root.nil? - context = case args.first - when Liquid::Context - c = args.shift - - if @rethrow_errors - c.exception_renderer = ->(_e) { raise } - end - - c - when Liquid::Drop - drop = args.shift - drop.context = Context.new([drop, assigns], instance_assigns, registers, @rethrow_errors, @resource_limits) - when Hash - Context.new([args.shift, assigns], instance_assigns, registers, @rethrow_errors, @resource_limits) - when nil - Context.new(assigns, instance_assigns, registers, @rethrow_errors, @resource_limits) - else - raise ArgumentError, "Expected Hash or Liquid::Context as parameter" - end + context = coerce_context(assigns_or_context) output = nil context_register = context.registers.is_a?(StaticRegisters) ? context.registers.static : context.registers - case args.last + case options when Hash - options = args.pop - output = options[:output] if options[:output] + output = options[:output] if options[:output] options[:registers]&.each do |key, register| context_register[key] = register @@ -191,7 +151,7 @@ module Liquid apply_options_to_context(context, options) when Module, Array - context.add_filters(args.pop) + context.add_filters(options) end Template.registers.each do |key, register| @@ -209,14 +169,15 @@ module Liquid end rescue Liquid::MemoryError => e context.handle_error(e) - ensure - @errors = context.errors end end - def render!(*args) - @rethrow_errors = true - render(*args) + def render!(assigns_or_context = nil, options = nil) + context = coerce_context(assigns_or_context) + # rethrow errors + context.exception_renderer = ->(_e) { raise } + + render(context, options) end def render_to_output_buffer(context, output) @@ -225,6 +186,22 @@ module Liquid private + def coerce_context(assigns_or_context) + case assigns_or_context + when Liquid::Context + assigns_or_context + when Liquid::Drop + drop = assigns_or_context + drop.context = Context.build(environments: [drop]) + when Hash + Context.build(environments: [assigns_or_context]) + when nil + Context.build + else + raise ArgumentError, "Expected Hash or Liquid::Context as parameter" + end + end + def tokenize(source) Tokenizer.new(source, @line_numbers) end diff --git a/test/integration/error_handling_test.rb b/test/integration/error_handling_test.rb index c6463cc..511ea5b 100644 --- a/test/integration/error_handling_test.rb +++ b/test/integration/error_handling_test.rb @@ -40,26 +40,29 @@ class ErrorHandlingTest < Minitest::Test def test_standard_error template = Liquid::Template.parse(' {{ errors.standard_error }} ') - assert_equal(' Liquid error: standard error ', template.render('errors' => ErrorDrop.new)) + context = Liquid::Context.new('errors' => ErrorDrop.new) + assert_equal(' Liquid error: standard error ', template.render(context)) - assert_equal(1, template.errors.size) - assert_equal(StandardError, template.errors.first.class) + assert_equal(1, context.errors.size) + assert_equal(StandardError, context.errors.first.class) end def test_syntax template = Liquid::Template.parse(' {{ errors.syntax_error }} ') - assert_equal(' Liquid syntax error: syntax error ', template.render('errors' => ErrorDrop.new)) + context = Liquid::Context.new('errors' => ErrorDrop.new) + assert_equal(' Liquid syntax error: syntax error ', template.render(context)) - assert_equal(1, template.errors.size) - assert_equal(SyntaxError, template.errors.first.class) + assert_equal(1, context.errors.size) + assert_equal(SyntaxError, context.errors.first.class) end def test_argument template = Liquid::Template.parse(' {{ errors.argument_error }} ') - assert_equal(' Liquid error: argument error ', template.render('errors' => ErrorDrop.new)) + context = Liquid::Context.new('errors' => ErrorDrop.new) + assert_equal(' Liquid error: argument error ', template.render(context)) - assert_equal(1, template.errors.size) - assert_equal(ArgumentError, template.errors.first.class) + assert_equal(1, context.errors.size) + assert_equal(ArgumentError, context.errors.first.class) end def test_missing_endtag_parse_time_error @@ -78,9 +81,10 @@ class ErrorHandlingTest < Minitest::Test def test_lax_unrecognized_operator template = Liquid::Template.parse(' {% if 1 =! 2 %}ok{% endif %} ', error_mode: :lax) - assert_equal(' Liquid error: Unknown operator =! ', template.render) - assert_equal(1, template.errors.size) - assert_equal(Liquid::ArgumentError, template.errors.first.class) + context = Liquid::Context.new('errors' => ErrorDrop.new) + assert_equal(' Liquid error: Unknown operator =! ', template.render(context)) + assert_equal(1, context.errors.size) + assert_equal(Liquid::ArgumentError, context.errors.first.class) end def test_with_line_numbers_adds_numbers_to_parser_errors @@ -202,10 +206,11 @@ class ErrorHandlingTest < Minitest::Test def test_default_exception_renderer_with_internal_error template = Liquid::Template.parse('This is a runtime error: {{ errors.runtime_error }}', line_numbers: true) - output = template.render('errors' => ErrorDrop.new) + context = Liquid::Context.new('errors' => ErrorDrop.new) + output = template.render(context) assert_equal('This is a runtime error: Liquid error (line 1): internal', output) - assert_equal([Liquid::InternalError], template.errors.map(&:class)) + assert_equal([Liquid::InternalError], context.errors.map(&:class)) end def test_setting_default_exception_renderer @@ -217,10 +222,11 @@ class ErrorHandlingTest < Minitest::Test } template = Liquid::Template.parse('This is a runtime error: {{ errors.argument_error }}') - output = template.render('errors' => ErrorDrop.new) + context = Liquid::Context.new('errors' => ErrorDrop.new) + output = template.render(context) assert_equal('This is a runtime error: ', output) - assert_equal([Liquid::ArgumentError], template.errors.map(&:class)) + assert_equal([Liquid::ArgumentError], context.errors.map(&:class)) ensure Liquid::Template.default_exception_renderer = old_exception_renderer if old_exception_renderer end @@ -233,11 +239,12 @@ class ErrorHandlingTest < Minitest::Test e.cause } - output = template.render({ 'errors' => ErrorDrop.new }, exception_renderer: handler) + context = Liquid::Context.new('errors' => ErrorDrop.new) + output = template.render(context, exception_renderer: handler) assert_equal('This is a runtime error: runtime error', output) assert_equal([Liquid::InternalError], exceptions.map(&:class)) - assert_equal(exceptions, template.errors) + assert_equal(exceptions, context.errors) assert_equal('#', exceptions.first.cause.inspect) end @@ -250,15 +257,16 @@ class ErrorHandlingTest < Minitest::Test def test_included_template_name_with_line_numbers old_file_system = Liquid::Template.file_system + context = Liquid::Context.new('errors' => ErrorDrop.new) begin Liquid::Template.file_system = TestFileSystem.new template = Liquid::Template.parse("Argument error:\n{% include 'product' %}", line_numbers: true) - page = template.render('errors' => ErrorDrop.new) + page = template.render(context) ensure Liquid::Template.file_system = old_file_system end assert_equal("Argument error:\nLiquid error (product line 1): argument error", page) - assert_equal("product", template.errors.first.template_name) + assert_equal("product", context.errors.first.template_name) end end diff --git a/test/integration/tags/include_tag_test.rb b/test/integration/tags/include_tag_test.rb index bfe0a5b..e2e94f5 100644 --- a/test/integration/tags/include_tag_test.rb +++ b/test/integration/tags/include_tag_test.rb @@ -217,8 +217,9 @@ class IncludeTagTest < Minitest::Test Liquid::Template.file_system = TestFileSystem.new a = Liquid::Template.parse(' {% include "nested_template" %}') - a.render! - assert_empty(a.errors) + context = Liquid::Context.new + a.render!(context) + assert_empty(context.errors) end def test_passing_options_to_included_templates @@ -257,9 +258,10 @@ class IncludeTagTest < Minitest::Test def test_including_with_strict_variables template = Liquid::Template.parse("{% include 'simple' %}", error_mode: :warn) - template.render(nil, strict_variables: true) + context = Liquid::Context.new + template.render(context, strict_variables: true) - assert_equal([], template.errors) + assert_equal([], context.errors) end def test_break_through_include diff --git a/test/integration/template_test.rb b/test/integration/template_test.rb index 57d6e4f..acac7f3 100644 --- a/test/integration/template_test.rb +++ b/test/integration/template_test.rb @@ -38,12 +38,6 @@ end class TemplateTest < Minitest::Test include Liquid - def test_instance_assigns_persist_on_same_template_object_between_parses - t = Template.new - assert_equal('from instance assigns', t.parse("{% assign foo = 'from instance assigns' %}{{ foo }}").render!) - assert_equal('from instance assigns', t.parse("{{ foo }}").render!) - end - def test_warnings_is_not_exponential_time str = "false" 100.times do @@ -54,12 +48,6 @@ class TemplateTest < Minitest::Test assert_equal([], Timeout.timeout(1) { t.warnings }) end - def test_instance_assigns_persist_on_same_template_parsing_between_renders - t = Template.new.parse("{{ foo }}{% assign foo = 'foo' %}{{ foo }}") - assert_equal('foo', t.render!) - assert_equal('foofoo', t.render!) - end - def test_custom_assigns_do_not_persist_on_same_template t = Template.new assert_equal('from custom assigns', t.parse("{{ foo }}").render!('foo' => 'from custom assigns')) @@ -72,25 +60,6 @@ class TemplateTest < Minitest::Test assert_equal('from custom assigns', t.parse("{{ foo }}").render!('foo' => 'from custom assigns')) end - def test_persistent_assigns_squash_instance_assigns - t = Template.new - assert_equal('from instance assigns', t.parse("{% assign foo = 'from instance assigns' %}{{ foo }}").render!) - t.assigns['foo'] = 'from persistent assigns' - assert_equal('from persistent assigns', t.parse("{{ foo }}").render!) - end - - def test_lambda_is_called_once_from_persistent_assigns_over_multiple_parses_and_renders - t = Template.new - t.assigns['number'] = -> { - @global ||= 0 - @global += 1 - } - assert_equal('1', t.parse("{{number}}").render!) - assert_equal('1', t.parse("{{number}}").render!) - assert_equal('1', t.render!) - @global = nil - end - def test_lambda_is_called_once_from_custom_assigns_over_multiple_parses_and_renders t = Template.new assigns = { 'number' => -> { @@ -105,112 +74,124 @@ class TemplateTest < Minitest::Test def test_resource_limits_works_with_custom_length_method t = Template.parse("{% assign foo = bar %}") - t.resource_limits.render_length_limit = 42 - assert_equal("", t.render!("bar" => SomethingWithLength.new)) + context = Liquid::Context.new("bar" => SomethingWithLength.new) + context.resource_limits.render_length_limit = 42 + assert_equal("", t.render!(context)) end def test_resource_limits_render_length t = Template.parse("0123456789") - t.resource_limits.render_length_limit = 5 - assert_equal("Liquid error: Memory limits exceeded", t.render) - assert(t.resource_limits.reached?) + context = Liquid::Context.new + context.resource_limits.render_length_limit = 5 + assert_equal("Liquid error: Memory limits exceeded", t.render(context)) + assert(context.resource_limits.reached?) - t.resource_limits.render_length_limit = 10 + context.resource_limits.render_length_limit = 10 assert_equal("0123456789", t.render!) - refute_nil(t.resource_limits.render_length) + refute_nil(context.resource_limits.render_length) end def test_resource_limits_render_score t = Template.parse("{% for a in (1..10) %} {% for a in (1..10) %} foo {% endfor %} {% endfor %}") - t.resource_limits.render_score_limit = 50 - assert_equal("Liquid error: Memory limits exceeded", t.render) - assert(t.resource_limits.reached?) + context = Liquid::Context.new + context.resource_limits.render_score_limit = 50 + assert_equal("Liquid error: Memory limits exceeded", t.render(context)) + assert(context.resource_limits.reached?) t = Template.parse("{% for a in (1..100) %} foo {% endfor %}") - t.resource_limits.render_score_limit = 50 - assert_equal("Liquid error: Memory limits exceeded", t.render) - assert(t.resource_limits.reached?) + context.resource_limits.render_score_limit = 50 + assert_equal("Liquid error: Memory limits exceeded", t.render(context)) + assert(context.resource_limits.reached?) - t.resource_limits.render_score_limit = 200 - assert_equal((" foo " * 100), t.render!) - refute_nil(t.resource_limits.render_score) + context.resource_limits.render_score_limit = 200 + assert_equal((" foo " * 100), t.render!(context)) + refute_nil(context.resource_limits.render_score) end def test_resource_limits_assign_score t = Template.parse("{% assign foo = 42 %}{% assign bar = 23 %}") - t.resource_limits.assign_score_limit = 1 - assert_equal("Liquid error: Memory limits exceeded", t.render) - assert(t.resource_limits.reached?) + context = Liquid::Context.new + context.resource_limits.assign_score_limit = 1 + assert_equal("Liquid error: Memory limits exceeded", t.render(context)) + assert(context.resource_limits.reached?) - t.resource_limits.assign_score_limit = 2 - assert_equal("", t.render!) - refute_nil(t.resource_limits.assign_score) + context.resource_limits.assign_score_limit = 2 + assert_equal("", t.render!(context)) + refute_nil(context.resource_limits.assign_score) end def test_resource_limits_assign_score_counts_bytes_not_characters t = Template.parse("{% assign foo = 'すごい' %}") - t.render - assert_equal(9, t.resource_limits.assign_score) + context = Liquid::Context.new + t.render(context) + assert_equal(9, context.resource_limits.assign_score) t = Template.parse("{% capture foo %}すごい{% endcapture %}") - t.render - assert_equal(9, t.resource_limits.assign_score) + t.render(context) + assert_equal(9, context.resource_limits.assign_score) end def test_resource_limits_assign_score_nested t = Template.parse("{% assign foo = 'aaaa' | reverse %}") - t.resource_limits.assign_score_limit = 3 - assert_equal("Liquid error: Memory limits exceeded", t.render) - assert(t.resource_limits.reached?) + context = Liquid::Context.new + context.resource_limits.assign_score_limit = 3 + assert_equal("Liquid error: Memory limits exceeded", t.render(context)) + assert(context.resource_limits.reached?) - t.resource_limits.assign_score_limit = 5 - assert_equal("", t.render!) + context.resource_limits.assign_score_limit = 5 + assert_equal("", t.render!(context)) end def test_resource_limits_aborts_rendering_after_first_error t = Template.parse("{% for a in (1..100) %} foo1 {% endfor %} bar {% for a in (1..100) %} foo2 {% endfor %}") - t.resource_limits.render_score_limit = 50 - assert_equal("Liquid error: Memory limits exceeded", t.render) - assert(t.resource_limits.reached?) + context = Liquid::Context.new + context.resource_limits.render_score_limit = 50 + assert_equal("Liquid error: Memory limits exceeded", t.render(context)) + assert(context.resource_limits.reached?) end def test_resource_limits_hash_in_template_gets_updated_even_if_no_limits_are_set t = Template.parse("{% for a in (1..100) %} {% assign foo = 1 %} {% endfor %}") - t.render! - assert(t.resource_limits.assign_score > 0) - assert(t.resource_limits.render_score > 0) - assert(t.resource_limits.render_length > 0) + context = Liquid::Context.new + t.render!(context) + assert(context.resource_limits.assign_score > 0) + assert(context.resource_limits.render_score > 0) + assert(context.resource_limits.render_length > 0) end def test_render_length_persists_between_blocks t = Template.parse("{% if true %}aaaa{% endif %}") - t.resource_limits.render_length_limit = 7 - assert_equal("Liquid error: Memory limits exceeded", t.render) - t.resource_limits.render_length_limit = 8 - assert_equal("aaaa", t.render) + context = Liquid::Context.new + context.resource_limits.render_length_limit = 7 + assert_equal("Liquid error: Memory limits exceeded", t.render(context)) + context.resource_limits.render_length_limit = 8 + assert_equal("aaaa", t.render(context)) t = Template.parse("{% if true %}aaaa{% endif %}{% if true %}bbb{% endif %}") - t.resource_limits.render_length_limit = 13 - assert_equal("Liquid error: Memory limits exceeded", t.render) - t.resource_limits.render_length_limit = 14 - assert_equal("aaaabbb", t.render) + context = Liquid::Context.new + context.resource_limits.render_length_limit = 13 + assert_equal("Liquid error: Memory limits exceeded", t.render(context)) + context.resource_limits.render_length_limit = 14 + assert_equal("aaaabbb", t.render(context)) t = Template.parse("{% if true %}a{% endif %}{% if true %}b{% endif %}{% if true %}a{% endif %}{% if true %}b{% endif %}{% if true %}a{% endif %}{% if true %}b{% endif %}") - t.resource_limits.render_length_limit = 5 - assert_equal("Liquid error: Memory limits exceeded", t.render) - t.resource_limits.render_length_limit = 11 - assert_equal("Liquid error: Memory limits exceeded", t.render) - t.resource_limits.render_length_limit = 12 - assert_equal("ababab", t.render) + context = Liquid::Context.new + context.resource_limits.render_length_limit = 5 + assert_equal("Liquid error: Memory limits exceeded", t.render(context)) + context.resource_limits.render_length_limit = 11 + assert_equal("Liquid error: Memory limits exceeded", t.render(context)) + context.resource_limits.render_length_limit = 12 + assert_equal("ababab", t.render(context)) end def test_render_length_uses_number_of_bytes_not_characters t = Template.parse("{% if true %}すごい{% endif %}") - t.resource_limits.render_length_limit = 10 - assert_equal("Liquid error: Memory limits exceeded", t.render) - t.resource_limits.render_length_limit = 18 - assert_equal("すごい", t.render) + context = Liquid::Context.new + context.resource_limits.render_length_limit = 10 + assert_equal("Liquid error: Memory limits exceeded", t.render(context)) + context.resource_limits.render_length_limit = 18 + assert_equal("すごい", t.render(context)) end def test_default_resource_limits_unaffected_by_render_with_context @@ -224,11 +205,12 @@ class TemplateTest < Minitest::Test def test_can_use_drop_as_context t = Template.new - t.registers['lulz'] = 'haha' drop = TemplateContextDrop.new - assert_equal('fizzbuzz', t.parse('{{foo}}').render!(drop)) - assert_equal('bar', t.parse('{{bar}}').render!(drop)) - assert_equal('haha', t.parse("{{baz}}").render!(drop)) + context = Liquid::Context.build(environments: drop, registers: { 'lulz' => 'haha' }) + drop.context = context + assert_equal('fizzbuzz', t.parse('{{foo}}').render!(context)) + assert_equal('bar', t.parse('{{bar}}').render!(context)) + assert_equal('haha', t.parse("{{baz}}").render!(context)) end def test_render_bang_force_rethrow_errors_on_passed_context @@ -280,25 +262,27 @@ class TemplateTest < Minitest::Test end def test_undefined_variables - t = Template.parse("{{x}} {{y}} {{z.a}} {{z.b}} {{z.c.d}}") - result = t.render({ 'x' => 33, 'z' => { 'a' => 32, 'c' => { 'e' => 31 } } }, strict_variables: true) + t = Template.parse("{{x}} {{y}} {{z.a}} {{z.b}} {{z.c.d}}") + context = Liquid::Context.new('x' => 33, 'z' => { 'a' => 32, 'c' => { 'e' => 31 } }) + result = t.render(context, strict_variables: true) assert_equal('33 32 ', result) - assert_equal(3, t.errors.count) - assert_instance_of(Liquid::UndefinedVariable, t.errors[0]) - assert_equal('Liquid error: undefined variable y', t.errors[0].message) - assert_instance_of(Liquid::UndefinedVariable, t.errors[1]) - assert_equal('Liquid error: undefined variable b', t.errors[1].message) - assert_instance_of(Liquid::UndefinedVariable, t.errors[2]) - assert_equal('Liquid error: undefined variable d', t.errors[2].message) + assert_equal(3, context.errors.count) + assert_instance_of(Liquid::UndefinedVariable, context.errors[0]) + assert_equal('Liquid error: undefined variable y', context.errors[0].message) + assert_instance_of(Liquid::UndefinedVariable, context.errors[1]) + assert_equal('Liquid error: undefined variable b', context.errors[1].message) + assert_instance_of(Liquid::UndefinedVariable, context.errors[2]) + assert_equal('Liquid error: undefined variable d', context.errors[2].message) end def test_nil_value_does_not_raise Liquid::Template.error_mode = :strict - t = Template.parse("some{{x}}thing") - result = t.render!({ 'x' => nil }, strict_variables: true) + t = Template.parse("some{{x}}thing") + context = Liquid::Context.new('x' => nil) + result = t.render!(context, strict_variables: true) - assert_equal(0, t.errors.count) + assert_equal(0, context.errors.count) assert_equal('something', result) end @@ -313,11 +297,13 @@ class TemplateTest < Minitest::Test def test_undefined_drop_methods d = DropWithUndefinedMethod.new t = Template.new.parse('{{ foo }} {{ woot }}') - result = t.render(d, strict_variables: true) + context = Liquid::Context.new(d) + d.context = context + result = t.render(context, strict_variables: true) assert_equal('foo ', result) - assert_equal(1, t.errors.count) - assert_instance_of(Liquid::UndefinedDropMethod, t.errors[0]) + assert_equal(1, context.errors.count) + assert_instance_of(Liquid::UndefinedDropMethod, context.errors[0]) end def test_undefined_drop_methods_raise @@ -336,12 +322,13 @@ class TemplateTest < Minitest::Test "-#{v}-" end end - result = t.render({ 'a' => 123, 'x' => 'foo' }, filters: [filters], strict_filters: true) + context = Liquid::Context.new('a' => 123, 'x' => 'foo') + result = t.render(context, filters: [filters], strict_filters: true) assert_equal('123 ', result) - assert_equal(1, t.errors.count) - assert_instance_of(Liquid::UndefinedFilter, t.errors[0]) - assert_equal('Liquid error: undefined filter somefilter1', t.errors[0].message) + assert_equal(1, context.errors.count) + assert_instance_of(Liquid::UndefinedFilter, context.errors[0]) + assert_equal('Liquid error: undefined filter somefilter1', context.errors[0].message) end def test_undefined_filters_raise diff --git a/test/integration/variable_test.rb b/test/integration/variable_test.rb index 45268bd..7ffb549 100644 --- a/test/integration/variable_test.rb +++ b/test/integration/variable_test.rb @@ -51,29 +51,10 @@ class VariableTest < Minitest::Test assert_equal('cat', Template.parse("{{ nil | append: 'cat' }}").render!) end - def test_preset_assigns - template = Template.parse(%({{ test }})) - template.assigns['test'] = 'worked' - assert_equal('worked', template.render!) - end - def test_reuse_parsed_template - template = Template.parse(%({{ greeting }} {{ name }})) - template.assigns['greeting'] = 'Goodbye' + template = Template.parse(%({{ greeting }} {{ name }})) assert_equal('Hello Tobi', template.render!('greeting' => 'Hello', 'name' => 'Tobi')) - assert_equal('Hello ', template.render!('greeting' => 'Hello', 'unknown' => 'Tobi')) - assert_equal('Hello Brian', template.render!('greeting' => 'Hello', 'name' => 'Brian')) - assert_equal('Goodbye Brian', template.render!('name' => 'Brian')) - assert_equal({ 'greeting' => 'Goodbye' }, template.assigns) - end - - def test_assigns_not_polluted_from_template - template = Template.parse(%({{ test }}{% assign test = 'bar' %}{{ test }})) - template.assigns['test'] = 'baz' - assert_equal('bazbar', template.render!) - assert_equal('bazbar', template.render!) - assert_equal('foobar', template.render!('test' => 'foo')) - assert_equal('bazbar', template.render!) + assert_equal('Goodbye Brian', template.render!('greeting' => 'Goodbye', 'name' => 'Brian')) end def test_hash_with_default_proc