Commit Graph
185 Commits
Author SHA1 Message Date
Charles-P. Clermont 3b13ee0ff3 Remove default_context test from Condition 2026-01-27 10:07:36 -05:00
Charles-P. Clermont ef4770975b Fix MethodLiteral for updated blank & empty 2026-01-27 10:07:36 -05:00
Charles-P. Clermont 10c0de74b5 Add support for parenthesized expressions 2026-01-27 10:07:35 -05:00
Charles-P. Clermont 7f414e5fa6 Remove Condition#{child_relation,and,or}
- Remove Condition#child_relation
- Remove Condition#and
- Remove Condition#or
- Simplify Condition#evaluate

This logic was moved to the Parser & BinaryExpression
2026-01-27 10:07:35 -05:00
Charles-P. Clermont 429711fd82 Add support for logical expressions 2026-01-26 16:53:38 -05:00
Charles-P. Clermont e911eea3df Remove Condition.op, Condition.right
- Remove comparison expression logic
2026-01-26 16:52:46 -05:00
Charles-P. Clermont abbd342b22 Remove Condition.operators feature that let you define operators
It was incompatible with the lexer anyway. Not used internally either.
2026-01-26 16:52:31 -05:00
Charles-P. Clermont daae2186d2 Make Condition unit tests go through BinaryExpression
Instead of having Condition parse the left op right, make
BinaryExpression do it. Make sure all the tests pass as they
used to in the process.
2026-01-26 16:52:31 -05:00
Charles-P. Clermont f60d3f0a41 Use BinaryExpression instead of Condition for comparisons 2026-01-26 16:52:31 -05:00
Charles-P. Clermont 0b890904f0 Make Parser.expression parse equality expressions 2026-01-26 16:52:31 -05:00
Charles-P. Clermont b161dae495 Make Parser.expression parse comparisons 2026-01-26 16:52:31 -05:00
Charles-P. ClermontandClaude Opus 4.5 6f03452245 style: fix rubocop offenses
Co-Authored-By: Claude Opus 4.5 <[email protected]>
2026-01-26 16:52:21 -05:00
Charles-P. Clermont dff829ec72 Extract Parser#range_lookup out of Expression.parse 2026-01-26 16:52:17 -05:00
Charles-P. Clermont 8b04c52ab2 Extract Parser#variable_lookup out of Expression.parse 2026-01-26 16:52:17 -05:00
Charles-P. Clermont 8efcf7dd3a Move VariableLookup parsing logic to .parse instead of initializer
Goal is to get rid of it entirely, but baby steps.
2026-01-26 16:52:17 -05:00
Charles-P. Clermont e1e0129983 Extract Parser#number parse out of Expression.parse 2026-01-26 16:52:17 -05:00
Charles-P. Clermont 2a86852eb3 Extract Parser#string out of Expression.parse 2026-01-26 16:52:17 -05:00
Charles-P. Clermont c9ae128354 Rename Parser#expression_node -> Parser#expression 2026-01-26 16:52:17 -05:00
Charles-P. Clermont 6cfcd6cac0 Rename Parser#argument -> argument_string 2026-01-26 16:52:17 -05:00
Charles-P. Clermont 6b78291449 Rename Parser#expression -> Parser#expression_string 2026-01-26 16:52:17 -05:00
Charles-P. Clermont 7d0bdd166d Move parse_expression to Parser.unsafe_parse_expression
- Add Parser#string
- Add Parser#unsafe_parse_expression
- Add private Parser#parse_expression
- Remove ParseContext.parse_expression
- Remove Tag.parse_expression
- Condition.parse_expression now takes a parser as argument
2026-01-26 16:52:17 -05:00
Charles-P. Clermont cf3d845315 Move safe_parse_expression into Parser.expression_node
- Make `Parser` accept the expression cache
- Remove `safe_parse_expression` from `ParseContext`
- Replace all usage of `safe_parse_expression` with `parser.expression_node`
2026-01-26 16:52:17 -05:00
Charles-P. Clermont 851584327a Remove warnings system 2026-01-26 16:52:17 -05:00
Charles-P. Clermont 62400f71d0 Remove :error_mode 2026-01-14 09:55:20 -05:00
Charles-P. Clermont d936ce4ac9 Remove :lax, :strict and :warn error modes 2026-01-14 09:54:19 -05:00
Tobi Lutke ef13b2dfd5 Fix empty? semantics and string first/last for empty strings
- 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
2026-01-01 22:06:22 -05:00
Tobi Lutke af58800c16 Update rubocop-shopify to 2.18.0 and fix new offenses 2026-01-01 20:22:19 -05:00
Tobi Lutke 361d1d52b1 Fix rubocop offenses from 1.82 upgrade 2026-01-01 20:20:50 -05:00
Tobi Lutke 33bac87a5c Address liquid-spec issues without ActiveSupport loaded
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
2026-01-01 20:14:21 -05:00
Julia Boutin fa27bfe6e0 Preserve literal semantics in strict2 case/when
Previously, strict2 case/when used `safe_parse_expression`
to parse when expressions causing `blank`/`empty` to be
treated as string literals (Expression::LITERALS maps 'empty' => ''),
rather than method literals

This caused unexpected behavior:

```
{%- case empty_obj -%}
{%- when empty -%}
  previously: doesn't render (empty_obj == '' is false)
  now: renders (empty_obj.empty? is true)
{%- endcase -%}
```

This commit instead calls `Condition.parse_expression`
with `safe: true`, which will correctly handle `blank`
and `empty`
2025-11-28 15:51:48 -07:00
Guilherme CarreiroandGitHub 32b50ecafe Bump Liquid to 5.11.0 (#2012)
This commit reverts the Inline Snippets tag (#2001) and bumps
Liquid to 5.11. For now, the inclusion of Inline Snippets
in the latest Liquid release is being treated as a bug.

While #2001 does implement the scope contained in RFC#1916,
we need to take a step back to make sure we’re setting our
sights high enough with this feature, and that we’re truly
supporting theme developers in the ways they need.

If you have any feedback, please leave a comment on RFC#1916.

- Liquid Developer Tools
2025-11-19 18:03:23 +01:00
Guilherme CarreiroandGuilherme Carreiro 1f58216f48 Add unit test mixing positional and kwargs arguments 2025-10-27 16:33:31 +01:00
Guilherme CarreiroandGuilherme Carreiro 6aa4041c0f Rename with_error_mode(...) to with_error_modes(...) 2025-10-27 16:33:31 +01:00
Guilherme CarreiroandAlok Swamy 1733586242 Update test/unit/tags/case_tag_unit_test.rb
Co-authored-by: Alok Swamy <[email protected]>
2025-10-27 16:33:31 +01:00
Guilherme CarreiroandGuilherme Carreiro 018442b7d1 Covered changes with more tests, remove redundant cases, and the new with_error_mode(*modes)
Most of changes update this:
```
[:lax, :strict].each do |mode|
  with_error_mode(mode) do
    assert_template_result(...
```

to be this:
```
with_error_mode(:lax, :strict) do
  assert_template_result(...
```
2025-10-27 16:33:31 +01:00
Guilherme CarreiroandGuilherme Carreiro a23c71e40b Fix variable to keep it backward-compatible in strict mode
* lax_parse    - no changes
  * strict_parse - uses the `lax_parse_filter_expressions` (as it was doing before)
  * rigid_parse  - uses the `rigid_parse_filter_expressions`
2025-10-27 16:33:31 +01:00
Guilherme CarreiroandGuilherme Carreiro 738540a601 Update infrastructure that handles parsing switching:
* Remove development helpers from parse context
* Simplify strict_parse_with_error_mode_fallback and update
  documentation
* Add unit tests for `Liquid::Expression` and `Liquid::ParseContext`
* Update test helpers to work better with the `:rigid` mode
2025-10-27 16:33:31 +01:00
Guilherme CarreiroandGuilherme Carreiro 5ec3008b37 Add rigid parser to tablerow tag 2025-10-27 16:33:31 +01:00
Guilherme CarreiroandGuilherme Carreiro 5248025439 Remove redundant tests where rigid and strict modes have the same
behavior
2025-10-27 16:33:31 +01:00
Guilherme CarreiroandGuilherme Carreiro 0bc69b86b7 No longer test ParseContext directly on RigidModeUnitTest as
now the `safe: true` calls are considered safe

Test the entire template instead
2025-10-27 16:33:31 +01:00
Charles-P. ClermontandGuilherme Carreiro b8958f626d Stricter 1:1 refactor of strict_parse for Variable 2025-10-27 16:33:31 +01:00
Guilherme CarreiroandGuilherme Carreiro d77662cd0e Remove unnecessary skips 2025-10-27 16:33:31 +01:00
Guilherme CarreiroandGuilherme Carreiro 65a1c167b3 Add rigid_parse to case/when 2025-10-27 16:33:31 +01:00
Guilherme CarreiroandGuilherme Carreiro e413104e78 Remove ExpressionParser in favor of ParseContext#safe_parse 2025-10-27 16:33:31 +01:00
Guilherme CarreiroandGuilherme Carreiro 1bff382ebc Add ExpressionParser and ExpressionConsumer 2025-10-27 16:33:31 +01:00
Guilherme CarreiroandGuilherme Carreiro edf06c2882 Introduce :rigid parsing mode 2025-10-27 16:33:31 +01:00
James Meng 7f2f8a226b Add tests for new public methods 2025-06-09 12:24:59 -07:00
James Meng 7b2b25fda1 Fix Doc tag blank? method to check body content
Previously the blank? method always returned true. Now it properly checks
if the body is empty, making the tag behavior consistent with other tags.

Also updated test to use whitespace control for cleaner assertions.
2025-06-09 11:36:18 -07:00
James Meng 8548b96a97 Remove body attr_reader and initiliaze @body instance variable in parse method 2025-06-06 13:08:06 -07:00
James Meng 79a771d724 Add test for doc tag capturing token before enddoc 2025-06-04 19:30:47 -07:00