Skip to content

Conversation

@tobi
Copy link
Member

@tobi tobi commented Jan 2, 2026

Summary

Adds liquid-spec conformance testing to CI and fixes Liquid to work correctly without ActiveSupport.

Changes

CI Integration

  • Add liquid-spec gem dependency for conformance testing
  • Add spec job to GitHub Actions that runs all adapters in spec/*.rb
  • Two adapters: ruby_liquid.rb (without ActiveSupport) and ruby_liquid_with_active_support.rb

ActiveSupport Independence

Liquid historically evolved with ActiveSupport always loaded. This PR makes Liquid work correctly without it by implementing equivalent behaviors internally:

  1. String first/last - {{ name.first }} and {{ name | first }} now work on strings, returning the first/last character (empty string for empty input, matching ActiveSupport)

  2. blank? comparisons - {% if x == blank %} now works for:

    • Whitespace-only strings (" ")
    • Empty arrays/hashes ([], {})
    • nil and false
  3. empty? comparisons - {% if x == empty %} correctly returns false for nil (nil is blank but not empty)

Other Fixes

  • Update rubocop to 1.82.0 and rubocop-shopify to 2.18.0 for Ruby 4.0 support
  • Fix various rubocop offenses
  • Update CI matrix: Ruby 3.3 minimum, add Ruby 4.0 with yjit/zjit

Test Results

Both adapters pass with 0 failures:

  • Without ActiveSupport: 4194 passed (skips 24 ActiveSupport-specific specs)
  • With ActiveSupport: 4203 passed

Related PRs

tobi added 23 commits January 1, 2026 20:14
Implement ActiveSupport-compatible behaviors internally so Liquid works
correctly without ActiveSupport being loaded:

1. String first/last via property access (name.first, name.last)
   - VariableLookup now handles string[0] and string[-1] for first/last

2. String first/last via filters (name | first, name | last)
   - StandardFilters#first and #last now handle strings

3. blank?/empty? comparisons for types without these methods
   - Condition now implements liquid_blank? and liquid_empty? internally
   - blank? matches ActiveSupport: nil, false, empty/whitespace strings,
     empty arrays/hashes are all blank
   - empty? checks length == 0 only (whitespace is NOT empty)

This fixes spec failures for templates like:
- {{ name.first }} / {{ name | first }} on strings
- {% if x == blank %} for whitespace strings, empty hashes/arrays
- {% case ' ' %}{% when blank %} matching whitespace
- Add liquid-spec gem from GitHub to :spec group
- Create spec/ruby-liquid.rb adapter for the reference implementation
- Add spec job to CI workflow to run liquid-spec tests
- nil is NOT empty (but IS blank) - matches Shopify production
- String first/last returns '' for empty strings, not nil - matches ActiveSupport
- Add test for nil not being empty
Both adapters now pass with 0 failures:
- ruby_liquid.rb: 4194 passed (skips activesupport and shopify_error_handling specs)
- ruby_liquid_with_active_support.rb: 4203 passed (skips shopify_error_handling specs)
@tobi tobi changed the title Address liquid-spec issues without ActiveSupport loaded Require liquid-spec to be run on commit automatically and related fixes Jan 2, 2026
@tobi tobi merged commit a4a29f3 into main Jan 2, 2026
25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant