Back to Repositories

Testing Regular Expression Pattern Implementation in Liquid

This test suite validates regular expression patterns used in the Liquid templating engine, focusing on parsing quoted fragments and variable expressions. It ensures robust string handling and variable parsing functionality across different input scenarios.

Test Coverage Overview

The test suite provides comprehensive coverage of regular expression patterns, specifically QuotedFragment and VariableParser.

Key areas tested include:
  • Empty string handling
  • Single and double quoted text parsing
  • HTML tag processing
  • Variable expression parsing
  • Performance with large inputs

Implementation Analysis

The testing approach employs Minitest framework with systematic verification of regex pattern matching. Test cases progress from simple to complex scenarios, including edge cases like empty strings and nested expressions.

Technical patterns include:
  • Timeout-wrapped tests for performance validation
  • Array equality assertions for pattern matching results
  • Systematic input variation testing

Technical Details

Testing infrastructure includes:
  • Minitest as the testing framework
  • Ruby’s built-in Timeout module for performance checks
  • Custom regex patterns: QuotedFragment and VariableParser
  • Integration with Liquid module functionality

Best Practices Demonstrated

The test suite exemplifies several testing best practices:

  • Isolated test cases with clear purpose
  • Comprehensive edge case coverage
  • Performance consideration through timeout checks
  • Systematic test organization
  • Clear test naming conventions

shopify/liquid

test/unit/regexp_unit_test.rb

            
# frozen_string_literal: true

require 'test_helper'
require 'timeout'

class RegexpUnitTest < Minitest::Test
  include Liquid

  def test_empty
    assert_equal([], ''.scan(QuotedFragment))
  end

  def test_quote
    assert_equal(['"arg 1"'], '"arg 1"'.scan(QuotedFragment))
  end

  def test_words
    assert_equal(['arg1', 'arg2'], 'arg1 arg2'.scan(QuotedFragment))
  end

  def test_tags
    assert_equal(['<tr>', '</tr>'], '<tr> </tr>'.scan(QuotedFragment))
    assert_equal(['<tr></tr>'], '<tr></tr>'.scan(QuotedFragment))
    assert_equal(['<style', 'class="hello">', '</style>'], %(<style class="hello">' </style>).scan(QuotedFragment))
  end

  def test_double_quoted_words
    assert_equal(['arg1', 'arg2', '"arg 3"'], 'arg1 arg2 "arg 3"'.scan(QuotedFragment))
  end

  def test_single_quoted_words
    assert_equal(['arg1', 'arg2', "'arg 3'"], 'arg1 arg2 \'arg 3\''.scan(QuotedFragment))
  end

  def test_quoted_words_in_the_middle
    assert_equal(['arg1', 'arg2', '"arg 3"', 'arg4'], 'arg1 arg2 "arg 3" arg4   '.scan(QuotedFragment))
  end

  def test_variable_parser
    assert_equal(['var'],                               'var'.scan(VariableParser))
    assert_equal(['[var]'],                             '[var]'.scan(VariableParser))
    assert_equal(['var', 'method'],                     'var.method'.scan(VariableParser))
    assert_equal(['var', '[method]'],                   'var[method]'.scan(VariableParser))
    assert_equal(['var', '[method]', '[0]'],            'var[method][0]'.scan(VariableParser))
    assert_equal(['var', '["method"]', '[0]'],          'var["method"][0]'.scan(VariableParser))
    assert_equal(['var', '[method]', '[0]', 'method'],  'var[method][0].method'.scan(VariableParser))
  end

  def test_variable_parser_with_large_input
    Timeout.timeout(1) { assert_equal(['[var]'], '[var]'.scan(VariableParser)) }

    very_long_string = "foo" * 1000

    # valid dynamic lookup
    Timeout.timeout(1) { assert_equal(["[#{very_long_string}]"], "[#{very_long_string}]".scan(VariableParser)) }
    # invalid dynamic lookup with missing closing bracket
    Timeout.timeout(1) { assert_equal([very_long_string], "[#{very_long_string}".scan(VariableParser)) }
  end
end # RegexpTest