From d70cd2a1ead39eff174d96af1315140a310451ec Mon Sep 17 00:00:00 2001 From: Joonas Date: Wed, 16 Dec 2020 11:08:43 +0200 Subject: [PATCH] feat: add preserveTimezones option --- src/builtin/filters/date.ts | 11 ++++++++-- src/liquid-options.ts | 4 ++++ test/integration/builtin/filters/date.ts | 27 ++++++++++++++---------- test/stub/render.ts | 9 ++++---- 4 files changed, 34 insertions(+), 17 deletions(-) diff --git a/src/builtin/filters/date.ts b/src/builtin/filters/date.ts index a75f604e70..cad21e9ef1 100644 --- a/src/builtin/filters/date.ts +++ b/src/builtin/filters/date.ts @@ -1,14 +1,21 @@ import strftime, { TimezoneDate } from '../../util/strftime' import { isString, isNumber } from '../../util/underscore' +import { FilterImpl } from '../../template/filter/filter-impl' -export function date (v: string | Date, arg: string) { +export function date (this: FilterImpl, v: string | Date, arg: string) { let date = v if (v === 'now' || v === 'today') { date = new Date() } else if (isNumber(v)) { date = new Date(v * 1000) } else if (isString(v)) { - date = /^\d+$/.test(v) ? new Date(+v * 1000) : new TimezoneDate(v) + if (/^\d+$/.test(v)) { + date = new Date(+v * 1000) + } else if (this.context.opts.preserveTimezones) { + date = new TimezoneDate(v) + } else { + date = new Date(v) + } } return isValidDate(date) ? strftime(date, arg) : v } diff --git a/src/liquid-options.ts b/src/liquid-options.ts index b8213479ab..32d362cbb5 100644 --- a/src/liquid-options.ts +++ b/src/liquid-options.ts @@ -37,6 +37,8 @@ export interface LiquidOptions { outputDelimiterLeft?: string; /** The right delimiter for liquid outputs. **/ outputDelimiterRight?: string; + /** Whether input strings to date filter preserve the given timezone **/ + preserveTimezones?: boolean; /** Whether `trim*Left`/`trim*Right` is greedy. When set to `true`, all consecutive blank characters including `\n` will be trimed regardless of line breaks. Defaults to `true`. */ greedy?: boolean; /** `fs` is used to override the default file-system module with a custom implementation. */ @@ -69,6 +71,7 @@ export interface NormalizedFullOptions extends NormalizedOptions { tagDelimiterRight: string; outputDelimiterLeft: string; outputDelimiterRight: string; + preserveTimezones: boolean; greedy: boolean; globals: object; keepOutputType: boolean; @@ -89,6 +92,7 @@ export const defaultOptions: NormalizedFullOptions = { tagDelimiterRight: '%}', outputDelimiterLeft: '{{', outputDelimiterRight: '}}', + preserveTimezones: false, strictFilters: false, strictVariables: false, lenientIf: false, diff --git a/test/integration/builtin/filters/date.ts b/test/integration/builtin/filters/date.ts index f55d550d3e..6d4fa655af 100644 --- a/test/integration/builtin/filters/date.ts +++ b/test/integration/builtin/filters/date.ts @@ -1,3 +1,4 @@ +import { LiquidOptions } from '../../../../src/liquid-options' import { test } from '../../../stub/render' describe('filters/date', function () { @@ -14,17 +15,21 @@ describe('filters/date', function () { it('should parse as Date when given a timezoneless string', function () { return test('{{ "1991-02-22T00:00:00" | date: "%Y-%m-%dT%H:%M:%S"}}', '1991-02-22T00:00:00') }) - it('should not change the timezone between input and output', function () { - return test('{{ "1990-12-31T23:00:00Z" | date: "%Y-%m-%dT%H:%M:%S"}}', '1990-12-31T23:00:00') - }) - it('should apply numeric timezone offset (0)', function () { - return test('{{ "1990-12-31T23:00:00+00:00" | date: "%Y-%m-%dT%H:%M:%S"}}', '1990-12-31T23:00:00') - }) - it('should apply numeric timezone offset (-1)', function () { - return test('{{ "1990-12-31T23:00:00-01:00" | date: "%Y-%m-%dT%H:%M:%S"}}', '1990-12-31T23:00:00') - }) - it('should apply numeric timezone offset (+2.30)', function () { - return test('{{ "1990-12-31T23:00:00+02:30" | date: "%Y-%m-%dT%H:%M:%S"}}', '1990-12-31T23:00:00') + describe('when preserveTimezones is enabled', function () { + const opts: LiquidOptions = { preserveTimezones: true }; + + it('should not change the timezone between input and output', function () { + return test('{{ "1990-12-31T23:00:00Z" | date: "%Y-%m-%dT%H:%M:%S"}}', '1990-12-31T23:00:00', undefined, opts) + }) + it('should apply numeric timezone offset (0)', function () { + return test('{{ "1990-12-31T23:00:00+00:00" | date: "%Y-%m-%dT%H:%M:%S"}}', '1990-12-31T23:00:00', undefined, opts) + }) + it('should apply numeric timezone offset (-1)', function () { + return test('{{ "1990-12-31T23:00:00-01:00" | date: "%Y-%m-%dT%H:%M:%S"}}', '1990-12-31T23:00:00', undefined, opts) + }) + it('should apply numeric timezone offset (+2.30)', function () { + return test('{{ "1990-12-31T23:00:00+02:30" | date: "%Y-%m-%dT%H:%M:%S"}}', '1990-12-31T23:00:00', undefined, opts) + }) }) it('should render string as string if not valid', function () { return test('{{ "foo" | date: "%Y"}}', 'foo') diff --git a/test/stub/render.ts b/test/stub/render.ts index 997be0a611..a8bdb46baa 100644 --- a/test/stub/render.ts +++ b/test/stub/render.ts @@ -1,16 +1,17 @@ import { Liquid } from '../../src/liquid' +import { LiquidOptions } from '../../src/liquid-options' import { expect } from 'chai' export const liquid = new Liquid() -export function render (src: string, ctx?: object) { - return liquid.parseAndRender(src, ctx) +export function render (src: string, ctx?: object, opts?: LiquidOptions) { + return liquid.parseAndRender(src, ctx, opts) } -export async function test (src: string, ctx: object | string, dst?: string) { +export async function test (src: string, ctx: object | string, dst?: string, opts?: LiquidOptions) { if (dst === undefined) { dst = ctx as string ctx = {} } - return expect(await render(src, ctx as object)).to.equal(dst) + return expect(await render(src, ctx as object, opts)).to.equal(dst) }