Back to Repositories

Testing Liquid Template Capture Tag Implementation in Shopify/liquid

This test suite validates the Liquid template engine’s capture tag functionality through comprehensive integration testing. It verifies variable capture behavior, scope handling, and proper UTF-8 character processing.

Test Coverage Overview

The test suite provides thorough coverage of Liquid’s capture tag functionality across multiple use cases.

Key areas tested include:
  • Basic content capture into variables
  • Variable naming with special characters (hyphens)
  • Scope handling and variable reassignment
  • UTF-8 character handling and byte allocation
  • Nested capture behavior within control structures

Implementation Analysis

The testing approach utilizes Minitest framework with custom assertions specific to Liquid template rendering. Tests employ a combination of inline templates and heredoc syntax for complex scenarios, demonstrating both simple and nested capture tag implementations.

Technical patterns include template parsing, variable scope verification, and resource limit tracking for memory management.

Technical Details

Testing tools and configuration:
  • Minitest as the testing framework
  • Custom assert_template_result helper method
  • Template parsing and rendering infrastructure
  • Resource limits tracking for performance monitoring
  • UTF-8 encoding support verification

Best Practices Demonstrated

The test suite exemplifies strong testing practices through isolated test cases, clear naming conventions, and comprehensive edge case coverage.

Notable practices include:
  • Systematic validation of variable scope behavior
  • Explicit testing of special character handling
  • Performance monitoring through resource tracking
  • Consistent test structure and organization

shopify/liquid

test/integration/capture_test.rb

            
# frozen_string_literal: true

require 'test_helper'

class CaptureTest < Minitest::Test
  include Liquid

  def test_captures_block_content_in_variable
    assert_template_result("test string", "{% capture 'var' %}test string{% endcapture %}{{var}}", {})
  end

  def test_capture_with_hyphen_in_variable_name
    template_source = <<~END_TEMPLATE
      {% capture this-thing %}Print this-thing{% endcapture -%}
      {{ this-thing -}}
    END_TEMPLATE
    assert_template_result("Print this-thing", template_source)
  end

  def test_capture_to_variable_from_outer_scope_if_existing
    template_source = <<~END_TEMPLATE
      {% assign var = '' -%}
      {% if true -%}
        {% capture var %}first-block-string{% endcapture -%}
      {% endif -%}
      {% if true -%}
        {% capture var %}test-string{% endcapture -%}
      {% endif -%}
      {{var-}}
    END_TEMPLATE
    assert_template_result("test-string", template_source)
  end

  def test_assigning_from_capture
    template_source = <<~END_TEMPLATE
      {% assign first = '' -%}
      {% assign second = '' -%}
      {% for number in (1..3) -%}
        {% capture first %}{{number}}{% endcapture -%}
        {% assign second = first -%}
      {% endfor -%}
      {{ first }}-{{ second -}}
    END_TEMPLATE
    assert_template_result("3-3", template_source)
  end

  def test_increment_assign_score_by_bytes_not_characters
    t = Template.parse("{% capture foo %}すごい{% endcapture %}")
    t.render!
    assert_equal(9, t.resource_limits.assign_score)
  end
end