refactor: remove createScope helper

Drop the exported helper and finish migrating call sites. Revert incidental context/for/include/layout churn so behavior matches mainline aside from the removal. Trim duplicate e2e and heavy Object.prototype loops in registry tests.

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
Yang Jun
2026-05-14 14:39:57 +08:00
co-authored by Cursor
parent ac683a917b
commit 80da505608
13 changed files with 28 additions and 77 deletions
-16
View File
@@ -77,22 +77,6 @@ describe('Issues', function () {
)
expect(html).toBe('BAR')
})
it('filter/tag maps are null-prototype (node + UMD)', async () => {
const nodeEngine = new Liquid()
const umdEngine = new LiquidUMD()
expect(Object.getPrototypeOf(nodeEngine.filters)).toBeNull()
expect(Object.getPrototypeOf(nodeEngine.tags)).toBeNull()
expect(Object.getPrototypeOf(umdEngine.filters)).toBeNull()
expect(Object.getPrototypeOf(umdEngine.tags)).toBeNull()
})
it('filter/tag lookups ignore Object.prototype keys unless registered (node + UMD)', async () => {
for (const LiquidClass of [Liquid, LiquidUMD]) {
const engine = new LiquidClass()
await expect(engine.parseAndRender('{{ x | constructor }}', { x: 'OK' })).resolves.toBe('OK')
await expect(new LiquidClass({ strictFilters: true }).parseAndRender('{{ x | constructor }}', { x: 'OK' })).rejects.toThrow(/undefined filter/)
expect(() => engine.parse('{% constructor %}')).toThrow('tag "constructor" not found')
}
})
it('lenientIf not working as expected in umd #313', async () => {
const engine = new LiquidUMD({
strictVariables: true,
@@ -61,19 +61,9 @@ describe('liquid#registerFilter()', function () {
})
})
describe('filter registry storage', () => {
it('should use a null-prototype map for filters', () => {
expect(Object.getPrototypeOf(liquid.filters)).toBeNull()
})
it('should treat Object.prototype keys as unregistered unless explicitly registered', async () => {
const registered = new Set(Object.keys(liquid.filters))
const strict = new Liquid({ strictFilters: true })
for (const name of Object.getOwnPropertyNames(Object.prototype)) {
if (registered.has(name)) continue
const out = await liquid.parseAndRender(`{{ x | ${name} }}`, { x: 42 })
expect(out).toBe('42')
await expect(strict.parseAndRender(`{{ 1 | ${name} }}`)).rejects.toThrow('undefined filter')
}
})
it('should not treat Object.prototype names as registered filters', async () => {
expect(Object.getPrototypeOf(liquid.filters)).toBeNull()
await expect(liquid.parseAndRender('{{ x | constructor }}', { x: 42 })).resolves.toBe('42')
await expect(new Liquid({ strictFilters: true }).parseAndRender('{{ 1 | constructor }}')).rejects.toThrow('undefined filter')
})
})
+4 -12
View File
@@ -39,17 +39,9 @@ describe('liquid#registerTag()', function () {
return expect(html).toBe('ABC')
})
describe('tag registry storage', () => {
it('should use a null-prototype map for tags', () => {
expect(Object.getPrototypeOf(new Liquid().tags)).toBeNull()
})
it('should not resolve names that exist only on Object.prototype', () => {
const l = new Liquid()
const registered = new Set(Object.keys(l.tags))
for (const name of Object.getOwnPropertyNames(Object.prototype)) {
if (registered.has(name)) continue
expect(() => l.parse(`{% ${name} %}`)).toThrow(`tag "${name}" not found`)
}
})
it('should not treat Object.prototype names as registered tags', () => {
const l = new Liquid()
expect(Object.getPrototypeOf(l.tags)).toBeNull()
expect(() => l.parse('{% constructor %}')).toThrow('tag "constructor" not found')
})
})