Fix SelfDrop equality (#2091)

This commit is contained in:
Guilherme Carreiro
2026-06-05 10:47:37 +02:00
committed by GitHub
parent 742ac3dbf5
commit 7b368dffb8
3 changed files with 37 additions and 1 deletions
+1 -1
View File
@@ -208,7 +208,7 @@ module Liquid
# `self` resolves to a SelfDrop (enabling `self['var']` lookups), # `self` resolves to a SelfDrop (enabling `self['var']` lookups),
# but only when it hasn't been explicitly assigned as a local variable. # but only when it hasn't been explicitly assigned as a local variable.
return SelfDrop.new(self) if key == Expression::SELF && !index return @self_drop ||= SelfDrop.new(self) if key == Expression::SELF && !index
variable = if index variable = if index
lookup_and_evaluate(@scopes[index], key, raise_on_not_found: raise_on_not_found) lookup_and_evaluate(@scopes[index], key, raise_on_not_found: raise_on_not_found)
+14
View File
@@ -35,6 +35,20 @@ module Liquid
self self
end end
def ==(other)
other.is_a?(SelfDrop) && other.self_context.equal?(@self_context)
end
alias_method :eql?, :==
def hash
@self_context.object_id.hash
end
protected
attr_reader :self_context
undef context= undef context=
end end
end end
@@ -77,6 +77,28 @@ class SelfDropContextTest < Minitest::Test
assert_template_result('42', '{{ self.x }}', { 'x' => 42 }) assert_template_result('42', '{{ self.x }}', { 'x' => 42 })
end end
def test_self_drop_repeated_lookups_compare_equal_for_same_context
context = Context.new
drop = context.find_variable("self")
cached_drop = context.find_variable("self")
assert_same(drop, cached_drop)
assert_equal(drop.object_id, cached_drop.object_id)
assert_equal(drop, cached_drop)
end
def test_assigned_self_drop_compares_equal_to_itself
assert_template_result('T', '{% assign s = self %}{% if s == s %}T{% else %}F{% endif %}')
end
def test_distinct_self_assignments_compare_equal_for_same_context
assert_template_result('T', '{% assign a = self %}{% assign b = self %}{% if a == b %}T{% else %}F{% endif %}')
end
def test_bare_self_compares_equal_to_bare_self
assert_template_result('T', '{% if self == self %}T{% else %}F{% endif %}')
end
def test_self_drop_with_strict_variables_does_not_raise_for_defined_var def test_self_drop_with_strict_variables_does_not_raise_for_defined_var
t = Template.parse('{{ self.x }}') t = Template.parse('{{ self.x }}')
result = t.render({ 'x' => 42 }, strict_variables: true) result = t.render({ 'x' => 42 }, strict_variables: true)