"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const moment_timezone_1 = tslib_1.__importDefault(require("moment-timezone"));
const moment_1 = tslib_1.__importDefault(require("moment/moment"));
const dbt_1 = require("../types/dbt");
const field_1 = require("../types/field");
const filter_1 = require("../types/filter");
const timeFrames_1 = require("../utils/timeFrames");
const filtersCompiler_1 = require("./filtersCompiler");
const filtersCompiler_mock_1 = require("./filtersCompiler.mock");
const formatTimestamp = (date) => (0, moment_1.default)(date).format('YYYY-MM-DD HH:mm:ssZ');
describe('Filter SQL', () => {
    beforeAll(() => {
        jest.useFakeTimers();
        jest.setSystemTime(new Date('04 Apr 2020 06:12:30 GMT').getTime());
    });
    afterAll(() => {
        jest.useFakeTimers();
    });
    test.each(Object.values(filter_1.FilterOperator))('should return number filter sql for operator %s', (operator) => {
        if (!filtersCompiler_mock_1.ExpectedNumberFilterSQL[operator]) {
            expect(() => {
                (0, filtersCompiler_1.renderNumberFilterSql)(filtersCompiler_mock_1.NumberDimensionMock, {
                    ...filtersCompiler_mock_1.NumberFilterBase,
                    operator,
                });
            }).toThrow();
            return;
        }
        if (filtersCompiler_mock_1.NumberOperatorsWithMultipleValues.includes(operator)) {
            expect((0, filtersCompiler_1.renderNumberFilterSql)(filtersCompiler_mock_1.NumberDimensionMock, {
                ...filtersCompiler_mock_1.NumberFilterBaseWithMultiValues,
                operator,
            })).toStrictEqual(filtersCompiler_mock_1.ExpectedNumberFilterSQL[operator]);
            return;
        }
        expect((0, filtersCompiler_1.renderNumberFilterSql)(filtersCompiler_mock_1.NumberDimensionMock, {
            ...filtersCompiler_mock_1.NumberFilterBase,
            operator,
        })).toStrictEqual(filtersCompiler_mock_1.ExpectedNumberFilterSQL[operator]);
    });
    test.each(Object.values(filter_1.UnitOfTime))('should return in the current %s filter sql', (unitOfTime) => {
        jest.setSystemTime(new Date('04 Apr 2020 06:12:30 GMT').getTime());
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, {
            ...filtersCompiler_mock_1.InTheCurrentFilterBase,
            settings: { unitOfTime },
        }, filtersCompiler_mock_1.adapterType.default, 'UTC', formatTimestamp)).toStrictEqual(filtersCompiler_mock_1.ExpectedInTheCurrentFilterSQL[unitOfTime]);
    });
    test.each(Object.values(filter_1.UnitOfTime))('should return in the current %s filter sql for trino adapter', (unitOfTime) => {
        jest.setSystemTime(new Date('04 Apr 2020 06:12:30 GMT').getTime());
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, {
            ...filtersCompiler_mock_1.InTheCurrentFilterBase,
            settings: { unitOfTime },
        }, filtersCompiler_mock_1.adapterType.trino, 'UTC', formatTimestamp)).toStrictEqual(filtersCompiler_mock_1.TrinoExpectedInTheCurrentFilterSQL[unitOfTime]);
    });
    test.each(Object.values(filter_1.UnitOfTime))('should return in the next %s filter sql', (unitOfTime) => {
        jest.setSystemTime(new Date('04 Apr 2020 06:12:30 GMT').getTime());
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, {
            ...filtersCompiler_mock_1.InTheNextFilterBase,
            settings: { unitOfTime },
        }, filtersCompiler_mock_1.adapterType.default, 'UTC', formatTimestamp)).toStrictEqual(filtersCompiler_mock_1.ExpectedInTheNextFilterSQL[unitOfTime]);
    });
    test.each(Object.values(filter_1.UnitOfTime))('should return in the next %s filter sql for trino adapter', (unitOfTime) => {
        jest.setSystemTime(new Date('04 Apr 2020 06:12:30 GMT').getTime());
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, {
            ...filtersCompiler_mock_1.InTheNextFilterBase,
            settings: { unitOfTime },
        }, filtersCompiler_mock_1.adapterType.trino, 'UTC', formatTimestamp)).toStrictEqual(filtersCompiler_mock_1.TrinoExpectedInTheNextFilterSQL[unitOfTime]);
    });
    test.each(Object.values(filter_1.UnitOfTime))('should return in the next complete %s filter sql', (unitOfTime) => {
        jest.setSystemTime(new Date('04 Apr 2020 06:12:30 GMT').getTime());
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, {
            ...filtersCompiler_mock_1.InTheNextFilterBase,
            settings: { unitOfTime, completed: true },
        }, filtersCompiler_mock_1.adapterType.default, 'UTC', formatTimestamp)).toStrictEqual(filtersCompiler_mock_1.ExpectedInTheNextCompleteFilterSQL[unitOfTime]);
    });
    test.each(Object.values(filter_1.UnitOfTime))('should return in the next complete %s filter sql for trino adapter', (unitOfTime) => {
        jest.setSystemTime(new Date('04 Apr 2020 06:12:30 GMT').getTime());
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, {
            ...filtersCompiler_mock_1.InTheNextFilterBase,
            settings: { unitOfTime, completed: true },
        }, filtersCompiler_mock_1.adapterType.trino, 'UTC', formatTimestamp)).toStrictEqual(filtersCompiler_mock_1.TrinoExpectedInTheNextCompleteFilterSQL[unitOfTime]);
    });
    test.each([timeFrames_1.WeekDay.MONDAY, timeFrames_1.WeekDay.SUNDAY])('should return in the next complete week filter sql with %s as the start of the week', (weekDay) => {
        jest.setSystemTime(new Date('04 Apr 2020 06:12:30 GMT').getTime());
        const filter = {
            ...filtersCompiler_mock_1.InTheNextFilterBase,
            settings: { unitOfTime: filter_1.UnitOfTime.weeks, completed: true },
        };
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filter, filtersCompiler_mock_1.adapterType.default, 'UTC', formatTimestamp, weekDay)).toStrictEqual(filtersCompiler_mock_1.ExpectedInTheNextCompleteWeekFilterSQLWithCustomStartOfWeek[weekDay]);
    });
    test.each([timeFrames_1.WeekDay.MONDAY, timeFrames_1.WeekDay.SUNDAY])('should return in the next complete week filter sql with %s as the start of the week for trino adapter', (weekDay) => {
        jest.setSystemTime(new Date('04 Apr 2020 06:12:30 GMT').getTime());
        const filter = {
            ...filtersCompiler_mock_1.InTheNextFilterBase,
            settings: { unitOfTime: filter_1.UnitOfTime.weeks, completed: true },
        };
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filter, filtersCompiler_mock_1.adapterType.trino, 'UTC', formatTimestamp, weekDay)).toStrictEqual(filtersCompiler_mock_1.TrinoExpectedInTheNextCompleteWeekFilterSQLWithCustomStartOfWeek[weekDay]);
    });
    test.each([timeFrames_1.WeekDay.MONDAY, timeFrames_1.WeekDay.SUNDAY])('should return in the last complete week filter sql with %s as the start of the week', (weekDay) => {
        jest.setSystemTime(new Date('04 Apr 2020 06:12:30 GMT').getTime());
        const filter = {
            ...filtersCompiler_mock_1.InThePastFilterBase,
            settings: { unitOfTime: filter_1.UnitOfTime.weeks, completed: true },
        };
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filter, filtersCompiler_mock_1.adapterType.default, 'UTC', formatTimestamp, weekDay)).toStrictEqual(filtersCompiler_mock_1.ExpectedInThePastCompleteWeekFilterSQLWithCustomStartOfWeek[weekDay]);
    });
    test.each([timeFrames_1.WeekDay.MONDAY, timeFrames_1.WeekDay.SUNDAY])('should return in the last complete week filter sql with %s as the start of the week for trino adapter', (weekDay) => {
        jest.setSystemTime(new Date('04 Apr 2020 06:12:30 GMT').getTime());
        const filter = {
            ...filtersCompiler_mock_1.InThePastFilterBase,
            settings: { unitOfTime: filter_1.UnitOfTime.weeks, completed: true },
        };
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filter, filtersCompiler_mock_1.adapterType.trino, 'UTC', formatTimestamp, weekDay)).toStrictEqual(filtersCompiler_mock_1.TrinoExpectedInThePastCompleteWeekFilterSQLWithCustomStartOfWeek[weekDay]);
    });
    test.each([timeFrames_1.WeekDay.MONDAY, timeFrames_1.WeekDay.SUNDAY])('should return in the current complete week filter sql with %s as the start of the week', (weekDay) => {
        jest.setSystemTime(new Date('04 Apr 2020 06:12:30 GMT').getTime());
        const filter = {
            ...filtersCompiler_mock_1.InTheCurrentFilterBase,
            settings: { unitOfTime: filter_1.UnitOfTime.weeks, completed: true },
        };
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filter, filtersCompiler_mock_1.adapterType.default, 'UTC', formatTimestamp, weekDay)).toStrictEqual(filtersCompiler_mock_1.ExpectedInTheCurrentWeekFilterSQLWithCustomStartOfWeek[weekDay]);
    });
    test.each([timeFrames_1.WeekDay.MONDAY, timeFrames_1.WeekDay.SUNDAY])('should return in the current complete week filter sql with %s as the start of the week for trino adapter', (weekDay) => {
        jest.setSystemTime(new Date('04 Apr 2020 06:12:30 GMT').getTime());
        const filter = {
            ...filtersCompiler_mock_1.InTheCurrentFilterBase,
            settings: { unitOfTime: filter_1.UnitOfTime.weeks, completed: true },
        };
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filter, filtersCompiler_mock_1.adapterType.trino, 'UTC', formatTimestamp, weekDay)).toStrictEqual(filtersCompiler_mock_1.TrinoExpectedInTheCurrentWeekFilterSQLWithCustomStartOfWeek[weekDay]);
    });
    test('should return in the last date filter sql', () => {
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.InTheLast1DayFilter, filtersCompiler_mock_1.adapterType.default, 'UTC')).toStrictEqual(filtersCompiler_mock_1.InTheLast1DayFilterSQL);
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.InTheLast1WeekFilter, filtersCompiler_mock_1.adapterType.default, 'UTC')).toStrictEqual(filtersCompiler_mock_1.InTheLast1WeekFilterSQL);
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.InTheLast1MonthFilter, filtersCompiler_mock_1.adapterType.default, 'UTC')).toStrictEqual(filtersCompiler_mock_1.InTheLast1MonthFilterSQL);
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.InTheLast1YearFilter, filtersCompiler_mock_1.adapterType.default, 'UTC')).toStrictEqual(filtersCompiler_mock_1.InTheLast1YearFilterSQL);
    });
    test('should return in the last date filter sql for trino adapter', () => {
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.InTheLast1DayFilter, filtersCompiler_mock_1.adapterType.trino, 'UTC')).toStrictEqual(filtersCompiler_mock_1.TrinoInTheLast1DayFilterSQL);
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.InTheLast1WeekFilter, filtersCompiler_mock_1.adapterType.trino, 'UTC')).toStrictEqual(filtersCompiler_mock_1.TrinoInTheLast1WeekFilterSQL);
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.InTheLast1MonthFilter, filtersCompiler_mock_1.adapterType.trino, 'UTC')).toStrictEqual(filtersCompiler_mock_1.TrinoInTheLast1MonthFilterSQL);
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.InTheLast1YearFilter, filtersCompiler_mock_1.adapterType.trino, 'UTC')).toStrictEqual(filtersCompiler_mock_1.TrinoInTheLast1YearFilterSQL);
    });
    test('should return in the last completed date filter sql ', () => {
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.InTheLast1CompletedDayFilter, filtersCompiler_mock_1.adapterType.default, 'UTC')).toStrictEqual(filtersCompiler_mock_1.InTheLast1CompletedDayFilterSQL);
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.InTheLast1CompletedWeekFilter, filtersCompiler_mock_1.adapterType.default, 'UTC')).toStrictEqual(filtersCompiler_mock_1.InTheLast1CompletedWeekFilterSQL);
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.InTheLast1CompletedMonthFilter, filtersCompiler_mock_1.adapterType.default, 'UTC')).toStrictEqual(filtersCompiler_mock_1.InTheLast1CompletedMonthFilterSQL);
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.InTheLast1CompletedYearFilter, filtersCompiler_mock_1.adapterType.default, 'UTC')).toStrictEqual(filtersCompiler_mock_1.InTheLast1CompletedYearFilterSQL);
    });
    test('should return in the last completed date filter sql for trino adapter', () => {
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.InTheLast1CompletedDayFilter, filtersCompiler_mock_1.adapterType.trino, 'UTC')).toStrictEqual(filtersCompiler_mock_1.TrinoInTheLast1CompletedDayFilterSQL);
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.InTheLast1CompletedWeekFilter, filtersCompiler_mock_1.adapterType.trino, 'UTC')).toStrictEqual(filtersCompiler_mock_1.TrinoInTheLast1CompletedWeekFilterSQL);
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.InTheLast1CompletedMonthFilter, filtersCompiler_mock_1.adapterType.trino, 'UTC')).toStrictEqual(filtersCompiler_mock_1.TrinoInTheLast1CompletedMonthFilterSQL);
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.InTheLast1CompletedYearFilter, filtersCompiler_mock_1.adapterType.trino, 'UTC')).toStrictEqual(filtersCompiler_mock_1.TrinoInTheLast1CompletedYearFilterSQL);
    });
    test('should return in the last date filter sql for timestamps', () => {
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.InTheLast1HourFilter, filtersCompiler_mock_1.adapterType.default, 'UTC', formatTimestamp)).toStrictEqual(filtersCompiler_mock_1.InTheLast1HourFilterSQL);
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.InTheLast1CompletedHourFilter, filtersCompiler_mock_1.adapterType.default, 'UTC', formatTimestamp)).toStrictEqual(filtersCompiler_mock_1.InTheLast1CompletedHourFilterSQL);
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.InTheLast1MinuteFilter, filtersCompiler_mock_1.adapterType.default, 'UTC', formatTimestamp)).toStrictEqual(filtersCompiler_mock_1.InTheLast1MinuteFilterSQL);
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.InTheLast1CompletedMinuteFilter, filtersCompiler_mock_1.adapterType.default, 'UTC', formatTimestamp)).toStrictEqual(filtersCompiler_mock_1.InTheLast1CompletedMinuteFilterSQL);
    });
    test('should return in the last date filter sql for timestamps for trino adapter', () => {
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.InTheLast1HourFilter, filtersCompiler_mock_1.adapterType.trino, 'UTC', formatTimestamp)).toStrictEqual(filtersCompiler_mock_1.TrinoInTheLast1HourFilterSQL);
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.InTheLast1CompletedHourFilter, filtersCompiler_mock_1.adapterType.trino, 'UTC', formatTimestamp)).toStrictEqual(filtersCompiler_mock_1.TrinoInTheLast1CompletedHourFilterSQL);
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.InTheLast1MinuteFilter, filtersCompiler_mock_1.adapterType.trino, 'UTC', formatTimestamp)).toStrictEqual(filtersCompiler_mock_1.TrinoInTheLast1MinuteFilterSQL);
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.InTheLast1CompletedMinuteFilter, filtersCompiler_mock_1.adapterType.trino, 'UTC', formatTimestamp)).toStrictEqual(filtersCompiler_mock_1.TrinoInTheLast1CompletedMinuteFilterSQL);
    });
    test('should return in between date filter sql', () => {
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.InBetweenPastTwoYearsFilter, filtersCompiler_mock_1.adapterType.default, 'UTC')).toStrictEqual(filtersCompiler_mock_1.InBetweenPastTwoYearsFilterSQL);
    });
    test('should return in between date filter sql for trino adapter', () => {
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.InBetweenPastTwoYearsFilter, filtersCompiler_mock_1.adapterType.trino, 'UTC')).toStrictEqual(filtersCompiler_mock_1.TrinoInBetweenPastTwoYearsFilterSQL);
    });
    test('should return in between date filter sql for timestamps', () => {
        expect((0, filtersCompiler_1.renderTimestampFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.InBetweenPastTwoYearsFilter, filtersCompiler_mock_1.adapterType.default, 'UTC', formatTimestamp)).toStrictEqual(filtersCompiler_mock_1.InBetweenPastTwoYearsTimestampFilterSQL);
    });
    test('should return in between date filter sql for timestamps for trino adapter', () => {
        expect((0, filtersCompiler_1.renderTimestampFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.InBetweenPastTwoYearsFilter, filtersCompiler_mock_1.adapterType.trino, 'UTC', formatTimestamp)).toStrictEqual(filtersCompiler_mock_1.TrinoInBetweenPastTwoYearsTimestampFilterSQL);
    });
    // To-date filter tests (system time: 04 Apr 2020 06:12:30 GMT)
    // April 4 2020: dayOfYear=95, dayOfMonth=4, dayInQuarter=3 (Apr1->Apr4), Saturday (dayInWeek=5 with Monday start)
    test('should return year to date filter sql', () => {
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.YearToDateFilterBase, filtersCompiler_mock_1.adapterType.default, 'UTC', formatTimestamp)).toStrictEqual(`(EXTRACT(DOY FROM ${filtersCompiler_mock_1.DimensionSqlMock}) <= 95)`);
    });
    test('should return year to date filter sql for bigquery', () => {
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.YearToDateFilterBase, dbt_1.SupportedDbtAdapter.BIGQUERY, 'UTC', formatTimestamp)).toStrictEqual(`(EXTRACT(DAYOFYEAR FROM ${filtersCompiler_mock_1.DimensionSqlMock}) <= 95)`);
    });
    test('should return year to date filter sql for clickhouse', () => {
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.YearToDateFilterBase, dbt_1.SupportedDbtAdapter.CLICKHOUSE, 'UTC', formatTimestamp)).toStrictEqual(`(toDayOfYear(${filtersCompiler_mock_1.DimensionSqlMock}) <= 95)`);
    });
    test('should return year to date filter sql for trino', () => {
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.YearToDateFilterBase, dbt_1.SupportedDbtAdapter.TRINO, 'UTC', formatTimestamp)).toStrictEqual(`(EXTRACT(DOY FROM ${filtersCompiler_mock_1.DimensionSqlMock}) <= 95)`);
    });
    test('should return year to date filter sql for snowflake', () => {
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.YearToDateFilterBase, dbt_1.SupportedDbtAdapter.SNOWFLAKE, 'UTC', formatTimestamp)).toStrictEqual(`(EXTRACT(DOY FROM ${filtersCompiler_mock_1.DimensionSqlMock}) <= 95)`);
    });
    test('should return year to date filter sql for databricks', () => {
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.YearToDateFilterBase, dbt_1.SupportedDbtAdapter.DATABRICKS, 'UTC', formatTimestamp)).toStrictEqual(`(EXTRACT(DOY FROM ${filtersCompiler_mock_1.DimensionSqlMock}) <= 95)`);
    });
    test('should return year to date filter sql for redshift', () => {
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.YearToDateFilterBase, dbt_1.SupportedDbtAdapter.REDSHIFT, 'UTC', formatTimestamp)).toStrictEqual(`(EXTRACT(DOY FROM ${filtersCompiler_mock_1.DimensionSqlMock}) <= 95)`);
    });
    test('should return month to date filter sql', () => {
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.MonthToDateFilterBase, filtersCompiler_mock_1.adapterType.default, 'UTC', formatTimestamp)).toStrictEqual(`(EXTRACT(DAY FROM ${filtersCompiler_mock_1.DimensionSqlMock}) <= 4)`);
    });
    test('should return month to date filter sql for bigquery', () => {
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.MonthToDateFilterBase, dbt_1.SupportedDbtAdapter.BIGQUERY, 'UTC', formatTimestamp)).toStrictEqual(`(EXTRACT(DAY FROM ${filtersCompiler_mock_1.DimensionSqlMock}) <= 4)`);
    });
    test('should return month to date filter sql for clickhouse', () => {
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.MonthToDateFilterBase, dbt_1.SupportedDbtAdapter.CLICKHOUSE, 'UTC', formatTimestamp)).toStrictEqual(`(toDayOfMonth(${filtersCompiler_mock_1.DimensionSqlMock}) <= 4)`);
    });
    test('should return month to date filter sql for trino', () => {
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.MonthToDateFilterBase, dbt_1.SupportedDbtAdapter.TRINO, 'UTC', formatTimestamp)).toStrictEqual(`(EXTRACT(DAY FROM ${filtersCompiler_mock_1.DimensionSqlMock}) <= 4)`);
    });
    test('should return month to date filter sql for snowflake', () => {
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.MonthToDateFilterBase, dbt_1.SupportedDbtAdapter.SNOWFLAKE, 'UTC', formatTimestamp)).toStrictEqual(`(EXTRACT(DAY FROM ${filtersCompiler_mock_1.DimensionSqlMock}) <= 4)`);
    });
    test('should return quarter to date filter sql', () => {
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.QuarterToDateFilterBase, filtersCompiler_mock_1.adapterType.default, 'UTC', formatTimestamp)).toStrictEqual(`(EXTRACT(DAY FROM ${filtersCompiler_mock_1.DimensionSqlMock} - DATE_TRUNC('QUARTER', ${filtersCompiler_mock_1.DimensionSqlMock})) <= 3)`);
    });
    test('should return quarter to date filter sql for trino', () => {
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.QuarterToDateFilterBase, filtersCompiler_mock_1.adapterType.trino, 'UTC', formatTimestamp)).toStrictEqual(`(DATE_DIFF('day', DATE_TRUNC('quarter', ${filtersCompiler_mock_1.DimensionSqlMock}), ${filtersCompiler_mock_1.DimensionSqlMock}) <= 3)`);
    });
    test('should return quarter to date filter sql for bigquery', () => {
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.QuarterToDateFilterBase, dbt_1.SupportedDbtAdapter.BIGQUERY, 'UTC', formatTimestamp)).toStrictEqual(`(DATE_DIFF(${filtersCompiler_mock_1.DimensionSqlMock}, DATE_TRUNC(${filtersCompiler_mock_1.DimensionSqlMock}, QUARTER), DAY) <= 3)`);
    });
    test('should return quarter to date filter sql for clickhouse', () => {
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.QuarterToDateFilterBase, dbt_1.SupportedDbtAdapter.CLICKHOUSE, 'UTC', formatTimestamp)).toStrictEqual(`(dateDiff('day', toStartOfQuarter(${filtersCompiler_mock_1.DimensionSqlMock}), ${filtersCompiler_mock_1.DimensionSqlMock}) <= 3)`);
    });
    test('should return quarter to date filter sql for athena', () => {
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.QuarterToDateFilterBase, dbt_1.SupportedDbtAdapter.ATHENA, 'UTC', formatTimestamp)).toStrictEqual(`(DATE_DIFF('day', DATE_TRUNC('quarter', ${filtersCompiler_mock_1.DimensionSqlMock}), ${filtersCompiler_mock_1.DimensionSqlMock}) <= 3)`);
    });
    test('should return quarter to date filter sql for snowflake', () => {
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.QuarterToDateFilterBase, dbt_1.SupportedDbtAdapter.SNOWFLAKE, 'UTC', formatTimestamp)).toStrictEqual(`(EXTRACT(DAY FROM ${filtersCompiler_mock_1.DimensionSqlMock} - DATE_TRUNC('QUARTER', ${filtersCompiler_mock_1.DimensionSqlMock})) <= 3)`);
    });
    test('should return week to date filter sql (monday start)', () => {
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.WeekToDateFilterBase, filtersCompiler_mock_1.adapterType.default, 'UTC', formatTimestamp)).toStrictEqual(`(EXTRACT(DAY FROM ${filtersCompiler_mock_1.DimensionSqlMock} - DATE_TRUNC('WEEK', ${filtersCompiler_mock_1.DimensionSqlMock})) <= 5)`);
    });
    test('should return week to date filter sql for bigquery (sunday start default)', () => {
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.WeekToDateFilterBase, dbt_1.SupportedDbtAdapter.BIGQUERY, 'UTC', formatTimestamp)).toStrictEqual(`(DATE_DIFF(${filtersCompiler_mock_1.DimensionSqlMock}, DATE_TRUNC(${filtersCompiler_mock_1.DimensionSqlMock}, WEEK(SUNDAY)), DAY) <= 6)`);
    });
    test('should return week to date filter sql for clickhouse (sunday start default)', () => {
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.WeekToDateFilterBase, dbt_1.SupportedDbtAdapter.CLICKHOUSE, 'UTC', formatTimestamp)).toStrictEqual(`(dateDiff('day', toStartOfWeek(${filtersCompiler_mock_1.DimensionSqlMock}, 0), ${filtersCompiler_mock_1.DimensionSqlMock}) <= 6)`);
    });
    test('should return week to date filter sql for trino', () => {
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.WeekToDateFilterBase, dbt_1.SupportedDbtAdapter.TRINO, 'UTC', formatTimestamp)).toStrictEqual(`(DATE_DIFF('day', DATE_TRUNC('week', ${filtersCompiler_mock_1.DimensionSqlMock}), ${filtersCompiler_mock_1.DimensionSqlMock}) <= 5)`);
    });
    test('should return week to date filter sql for snowflake', () => {
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.WeekToDateFilterBase, dbt_1.SupportedDbtAdapter.SNOWFLAKE, 'UTC', formatTimestamp)).toStrictEqual(`(EXTRACT(DAY FROM ${filtersCompiler_mock_1.DimensionSqlMock} - DATE_TRUNC('WEEK', ${filtersCompiler_mock_1.DimensionSqlMock})) <= 5)`);
    });
    // Week to date with custom startOfWeek
    // April 4, 2020 is Saturday. Monday start: dayInWeek=5 (Mon=0..Sat=5). Sunday start: dayInWeek=6 (Sun=0..Sat=6).
    test('should return week to date filter sql for postgres with sunday start', () => {
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.WeekToDateFilterBase, filtersCompiler_mock_1.adapterType.default, 'UTC', formatTimestamp, timeFrames_1.WeekDay.SUNDAY)).toStrictEqual(`(EXTRACT(DAY FROM ${filtersCompiler_mock_1.DimensionSqlMock} - DATE_TRUNC('WEEK', ${filtersCompiler_mock_1.DimensionSqlMock})) <= 6)`);
    });
    test('should return week to date filter sql for bigquery with monday start', () => {
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.WeekToDateFilterBase, dbt_1.SupportedDbtAdapter.BIGQUERY, 'UTC', formatTimestamp, timeFrames_1.WeekDay.MONDAY)).toStrictEqual(`(DATE_DIFF(${filtersCompiler_mock_1.DimensionSqlMock}, DATE_TRUNC(${filtersCompiler_mock_1.DimensionSqlMock}, WEEK(MONDAY)), DAY) <= 5)`);
    });
    test('should return week to date filter sql for clickhouse with monday start', () => {
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.WeekToDateFilterBase, dbt_1.SupportedDbtAdapter.CLICKHOUSE, 'UTC', formatTimestamp, timeFrames_1.WeekDay.MONDAY)).toStrictEqual(`(dateDiff('day', toStartOfWeek(${filtersCompiler_mock_1.DimensionSqlMock}, 1), ${filtersCompiler_mock_1.DimensionSqlMock}) <= 5)`);
    });
    test.each(filtersCompiler_mock_1.filterInTheCurrentDayTimezoneMocks)('should return in the current day filter sql for timezone %s', (timezone, expected) => {
        jest.setSystemTime(new Date('04 Apr 2020 06:12:30 GMT').getTime());
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, filtersCompiler_mock_1.InTheCurrentFilterBase, filtersCompiler_mock_1.adapterType.default, timezone, formatTimestamp)).toStrictEqual(expected);
    });
    test.each(filtersCompiler_mock_1.filterInThePastCompletedDayTimezoneMocks)('should return in the past completed day filter sql for timezone %s', (timezone, expected) => {
        jest.setSystemTime(new Date('04 Apr 2020 06:12:30 GMT').getTime());
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, {
            ...filtersCompiler_mock_1.InThePastFilterBase,
            settings: {
                unitOfTime: filter_1.UnitOfTime.days,
                completed: true,
            },
        }, filtersCompiler_mock_1.adapterType.default, timezone, formatTimestamp)).toStrictEqual(expected);
    });
    test.each(filtersCompiler_mock_1.filterInTheNextCompletedDayTimezoneMocks)('should return in the next completed day filter sql for timezone %s', (timezone, expected) => {
        jest.setSystemTime(new Date('04 Apr 2020 06:12:30 GMT').getTime());
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, {
            ...filtersCompiler_mock_1.InTheNextFilterBase,
            settings: {
                unitOfTime: filter_1.UnitOfTime.days,
                completed: true,
            },
        }, filtersCompiler_mock_1.adapterType.default, timezone, formatTimestamp)).toStrictEqual(expected);
    });
    test.each(filtersCompiler_mock_1.filterInThePastCompletedDayDstMocks)('should handle DST spring forward for in the past completed day filter (timezone %s)', (timezone, expected) => {
        jest.setSystemTime(new Date('09 Mar 2020 05:00:00 GMT').getTime());
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, {
            ...filtersCompiler_mock_1.InThePastFilterBase,
            settings: {
                unitOfTime: filter_1.UnitOfTime.days,
                completed: true,
            },
        }, filtersCompiler_mock_1.adapterType.default, timezone, formatTimestamp)).toStrictEqual(expected);
    });
    test.each(filtersCompiler_mock_1.filterInTheNextCompletedDayDstMocks)('should handle DST spring forward for in the next completed day filter (timezone %s)', (timezone, expected) => {
        jest.setSystemTime(new Date('07 Mar 2020 05:00:00 GMT').getTime());
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, {
            ...filtersCompiler_mock_1.InTheNextFilterBase,
            settings: {
                unitOfTime: filter_1.UnitOfTime.days,
                completed: true,
            },
        }, filtersCompiler_mock_1.adapterType.default, timezone, formatTimestamp)).toStrictEqual(expected);
    });
    test.each(filtersCompiler_mock_1.filterInThePastNonCompletedDayTimezoneMocks)('should return in the past non-completed day filter sql for timezone %s', (timezone, expected) => {
        jest.setSystemTime(new Date('04 Apr 2020 06:12:30 GMT').getTime());
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, {
            ...filtersCompiler_mock_1.InThePastFilterBase,
            settings: {
                unitOfTime: filter_1.UnitOfTime.days,
                completed: false,
            },
        }, filtersCompiler_mock_1.adapterType.default, timezone, formatTimestamp)).toStrictEqual(expected);
    });
    test.each(filtersCompiler_mock_1.filterInTheNextNonCompletedDayTimezoneMocks)('should return in the next non-completed day filter sql for timezone %s', (timezone, expected) => {
        jest.setSystemTime(new Date('04 Apr 2020 06:12:30 GMT').getTime());
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, {
            ...filtersCompiler_mock_1.InTheNextFilterBase,
            settings: {
                unitOfTime: filter_1.UnitOfTime.days,
                completed: false,
            },
        }, filtersCompiler_mock_1.adapterType.default, timezone, formatTimestamp)).toStrictEqual(expected);
    });
    test.each(filtersCompiler_mock_1.filterInThePastNonCompletedDayDstMocks)('should handle DST spring forward for in the past non-completed day filter (timezone %s)', (timezone, expected) => {
        jest.setSystemTime(new Date('09 Mar 2020 05:00:00 GMT').getTime());
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, {
            ...filtersCompiler_mock_1.InThePastFilterBase,
            settings: {
                unitOfTime: filter_1.UnitOfTime.days,
                completed: false,
            },
        }, filtersCompiler_mock_1.adapterType.default, timezone, formatTimestamp)).toStrictEqual(expected);
    });
    test.each(filtersCompiler_mock_1.filterInTheNextNonCompletedDayDstMocks)('should handle DST spring forward for in the next non-completed day filter (timezone %s)', (timezone, expected) => {
        jest.setSystemTime(new Date('08 Mar 2020 06:00:00 GMT').getTime());
        expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, {
            ...filtersCompiler_mock_1.InTheNextFilterBase,
            settings: {
                unitOfTime: filter_1.UnitOfTime.days,
                completed: false,
            },
        }, filtersCompiler_mock_1.adapterType.default, timezone, formatTimestamp)).toStrictEqual(expected);
    });
    test('should return single value in includes filter sql', () => {
        expect((0, filtersCompiler_1.renderStringFilterSql)(filtersCompiler_mock_1.stringFilterDimension, filtersCompiler_mock_1.stringFilterRuleMocks.includeFilterWithSingleVal, "'")).toBe(filtersCompiler_mock_1.stringFilterRuleMocks.includeFilterWithSingleValSQL);
    });
    test('should return multiple values joined by OR in includes filter sql', () => {
        expect((0, filtersCompiler_1.renderStringFilterSql)(filtersCompiler_mock_1.stringFilterDimension, filtersCompiler_mock_1.stringFilterRuleMocks.includeFilterWithMultiVal, "'")).toBe(filtersCompiler_mock_1.stringFilterRuleMocks.includeFilterWithMultiValSQL);
    });
    test('should return true in includes filter sql for empty filter', () => {
        expect((0, filtersCompiler_1.renderStringFilterSql)(filtersCompiler_mock_1.stringFilterDimension, filtersCompiler_mock_1.stringFilterRuleMocks.includeFilterWithNoVal, "'")).toBe(filtersCompiler_mock_1.stringFilterRuleMocks.includeFilterWithNoValSQL);
    });
    test('should return single value in notIncludes filter sql', () => {
        expect((0, filtersCompiler_1.renderStringFilterSql)(filtersCompiler_mock_1.stringFilterDimension, filtersCompiler_mock_1.stringFilterRuleMocks.notIncludeFilterWithSingleVal, "'")).toBe(filtersCompiler_mock_1.stringFilterRuleMocks.notIncludeFilterWithSingleValSQL);
    });
    test('should return multiple values joined by AND in notIncludes filter sql', () => {
        expect((0, filtersCompiler_1.renderStringFilterSql)(filtersCompiler_mock_1.stringFilterDimension, filtersCompiler_mock_1.stringFilterRuleMocks.notIncludeFilterWithMultiVal, "'")).toBe(filtersCompiler_mock_1.stringFilterRuleMocks.notIncludeFilterWithMultiValSQL);
    });
    test('should return true in notIncludes filter sql for empty filter', () => {
        expect((0, filtersCompiler_1.renderStringFilterSql)(filtersCompiler_mock_1.stringFilterDimension, filtersCompiler_mock_1.stringFilterRuleMocks.notIncludeFilterWithNoVal, "'")).toBe(filtersCompiler_mock_1.stringFilterRuleMocks.notIncludeFilterWithNoValSQL);
    });
    test('should return true when includes filter has empty string value', () => {
        expect((0, filtersCompiler_1.renderStringFilterSql)(filtersCompiler_mock_1.stringFilterDimension, filtersCompiler_mock_1.stringFilterRuleMocks.includeFilterWithEmptyString, "'")).toBe(filtersCompiler_mock_1.stringFilterRuleMocks.includeFilterWithEmptyStringSQL);
    });
    test('should filter out empty strings and process valid values in mixed array', () => {
        expect((0, filtersCompiler_1.renderStringFilterSql)(filtersCompiler_mock_1.stringFilterDimension, filtersCompiler_mock_1.stringFilterRuleMocks.includeFilterWithMixedEmptyStrings, "'")).toBe(filtersCompiler_mock_1.stringFilterRuleMocks.includeFilterWithMixedEmptyStringsSQL);
    });
    test('should return empty string filter sql when equals filter has empty string value', () => {
        expect((0, filtersCompiler_1.renderStringFilterSql)(filtersCompiler_mock_1.stringFilterDimension, filtersCompiler_mock_1.stringFilterRuleMocks.equalsFilterWithEmptyString, "'")).toBe(filtersCompiler_mock_1.stringFilterRuleMocks.equalsFilterWithEmptyStringSQL);
    });
    test('should return true when starts with filter has empty string value', () => {
        expect((0, filtersCompiler_1.renderStringFilterSql)(filtersCompiler_mock_1.stringFilterDimension, filtersCompiler_mock_1.stringFilterRuleMocks.startsWithFilterWithEmptyString, "'")).toBe(filtersCompiler_mock_1.stringFilterRuleMocks.startsWithFilterWithEmptyStringSQL);
    });
    test('should return true when ends with filter has empty string value', () => {
        expect((0, filtersCompiler_1.renderStringFilterSql)(filtersCompiler_mock_1.stringFilterDimension, filtersCompiler_mock_1.stringFilterRuleMocks.endsWithFilterWithEmptyString, "'")).toBe(filtersCompiler_mock_1.stringFilterRuleMocks.endsWithFilterWithEmptyStringSQL);
    });
    test('should return true when not equals filter has empty string value', () => {
        expect((0, filtersCompiler_1.renderStringFilterSql)(filtersCompiler_mock_1.stringFilterDimension, filtersCompiler_mock_1.stringFilterRuleMocks.notEqualsFilterWithEmptyString, "'")).toBe(filtersCompiler_mock_1.stringFilterRuleMocks.notEqualsFilterWithEmptyStringSQL);
    });
    test('should return true when not include filter has empty string value', () => {
        expect((0, filtersCompiler_1.renderStringFilterSql)(filtersCompiler_mock_1.stringFilterDimension, filtersCompiler_mock_1.stringFilterRuleMocks.notIncludeFilterWithEmptyString, "'")).toBe(filtersCompiler_mock_1.stringFilterRuleMocks.notIncludeFilterWithEmptyStringSQL);
    });
    test('should return single value in startsWith filter sql', () => {
        expect((0, filtersCompiler_1.renderStringFilterSql)(filtersCompiler_mock_1.stringFilterDimension, filtersCompiler_mock_1.stringFilterRuleMocks.startsWithFilterWithSingleVal, "'")).toBe(filtersCompiler_mock_1.stringFilterRuleMocks.startsWithFilterWithSingleValSQL);
    });
    test('should return multiple values joined by OR in startsWith filter sql', () => {
        expect((0, filtersCompiler_1.renderStringFilterSql)(filtersCompiler_mock_1.stringFilterDimension, filtersCompiler_mock_1.stringFilterRuleMocks.startsWithFilterWithMultiVal, "'")).toBe(filtersCompiler_mock_1.stringFilterRuleMocks.startsWithFilterWithMultiValSQL);
    });
    test('should return true in startsWith filter sql for empty filter', () => {
        expect((0, filtersCompiler_1.renderStringFilterSql)(filtersCompiler_mock_1.stringFilterDimension, filtersCompiler_mock_1.stringFilterRuleMocks.startsWithFilterWithNoVal, "'")).toBe(filtersCompiler_mock_1.stringFilterRuleMocks.startsWithFilterWithNoValSQL);
    });
    test('should return single value in endsWith filter sql', () => {
        expect((0, filtersCompiler_1.renderStringFilterSql)(filtersCompiler_mock_1.stringFilterDimension, filtersCompiler_mock_1.stringFilterRuleMocks.endsWithFilterWithSingleVal, "'")).toBe(filtersCompiler_mock_1.stringFilterRuleMocks.endsWithFilterWithSingleValSQL);
    });
    test('should return multiple values joined by OR in endsWith filter sql', () => {
        expect((0, filtersCompiler_1.renderStringFilterSql)(filtersCompiler_mock_1.stringFilterDimension, filtersCompiler_mock_1.stringFilterRuleMocks.endsWithFilterWithMultiVal, "'")).toBe(filtersCompiler_mock_1.stringFilterRuleMocks.endsWithFilterWithMultiValSQL);
    });
    test('should return true in endsWith filter sql for empty filter', () => {
        expect((0, filtersCompiler_1.renderStringFilterSql)(filtersCompiler_mock_1.stringFilterDimension, filtersCompiler_mock_1.stringFilterRuleMocks.endsWithFilterWithNoVal, "'")).toBe(filtersCompiler_mock_1.stringFilterRuleMocks.endsWithFilterWithNoValSQL);
    });
    describe('case sensitivity hierarchy', () => {
        const caseFilter = {
            id: '1',
            target: { fieldId: 'testField' },
            operator: filter_1.FilterOperator.EQUALS,
            values: ['TestValue'],
        };
        const mockDimension = filtersCompiler_mock_1.disabledFilterMock.field;
        test('should be case sensitive by default', () => {
            const sql = (0, filtersCompiler_1.renderStringFilterSql)('field_name', caseFilter, "'", true);
            expect(sql).toBe(`(field_name) IN ('TestValue')`);
        });
        test('should be case insensitive when caseSensitive is false', () => {
            const sql = (0, filtersCompiler_1.renderStringFilterSql)('field_name', caseFilter, "'", false);
            expect(sql).toBe(`(UPPER(field_name)) IN ('TESTVALUE')`);
        });
        test('field-level caseSensitive overrides explore-level', () => {
            const fieldWithCaseSensitive = {
                ...mockDimension,
                caseSensitive: false, // field-level setting
            };
            const sql = (0, filtersCompiler_1.renderFilterRuleSqlFromField)(caseFilter, fieldWithCaseSensitive, '"', "'", (str) => str, timeFrames_1.WeekDay.MONDAY, dbt_1.SupportedDbtAdapter.POSTGRES, 'UTC', true);
            expect(sql).toContain('UPPER');
        });
        test('explore-level caseSensitive is used when field has no override', () => {
            const fieldWithoutCaseSensitive = {
                ...mockDimension,
                // No caseSensitive property
            };
            const sql = (0, filtersCompiler_1.renderFilterRuleSqlFromField)(caseFilter, fieldWithoutCaseSensitive, '"', "'", (str) => str, timeFrames_1.WeekDay.MONDAY, dbt_1.SupportedDbtAdapter.POSTGRES, 'UTC', false);
            expect(sql).toContain('UPPER');
        });
        test('filter-rule-level caseSensitive overrides case-sensitive field and explore', () => {
            const fieldCaseSensitive = {
                ...mockDimension,
                caseSensitive: true,
            };
            const filterRuleOverride = {
                ...caseFilter,
                caseSensitive: false,
            };
            const sql = (0, filtersCompiler_1.renderFilterRuleSqlFromField)(filterRuleOverride, fieldCaseSensitive, '"', "'", (str) => str, timeFrames_1.WeekDay.MONDAY, dbt_1.SupportedDbtAdapter.POSTGRES, 'UTC', true);
            expect(sql).toContain('UPPER');
        });
        test('filter-rule-level caseSensitive=true overrides case-insensitive field', () => {
            const fieldCaseInsensitive = {
                ...mockDimension,
                caseSensitive: false,
            };
            const filterRuleOverride = {
                ...caseFilter,
                caseSensitive: true,
            };
            const sql = (0, filtersCompiler_1.renderFilterRuleSqlFromField)(filterRuleOverride, fieldCaseInsensitive, '"', "'", (str) => str, timeFrames_1.WeekDay.MONDAY, dbt_1.SupportedDbtAdapter.POSTGRES, 'UTC', false);
            expect(sql).not.toContain('UPPER');
        });
    });
    test('should return 1=1 if filter is disabled', () => {
        expect((0, filtersCompiler_1.renderFilterRuleSqlFromField)(filtersCompiler_mock_1.disabledFilterMock.filterRule, filtersCompiler_mock_1.disabledFilterMock.field, filtersCompiler_mock_1.disabledFilterMock.fieldQuoteChar, filtersCompiler_mock_1.disabledFilterMock.stringQuoteChar, filtersCompiler_mock_1.disabledFilterMock.escapeString, filtersCompiler_mock_1.disabledFilterMock.startOfWeek, filtersCompiler_mock_1.disabledFilterMock.adapterType, filtersCompiler_mock_1.disabledFilterMock.timezone)).toBe('1=1');
    });
});
describe('case sensitivity', () => {
    test('should apply UPPER() when caseSensitive is false for EQUALS', () => {
        const filter = {
            ...filtersCompiler_mock_1.stringFilterRuleMocks.equalsFilterWithSingleUnescapedValue,
            values: ['Bob'],
        };
        expect((0, filtersCompiler_1.renderStringFilterSql)(filtersCompiler_mock_1.stringFilterDimension, filter, "'", false)).toBe(`(UPPER(${filtersCompiler_mock_1.stringFilterDimension})) IN ('BOB')`);
    });
    test('should not apply UPPER() when caseSensitive is true for EQUALS', () => {
        const filter = {
            ...filtersCompiler_mock_1.stringFilterRuleMocks.equalsFilterWithSingleUnescapedValue,
            values: ['Bob'],
        };
        expect((0, filtersCompiler_1.renderStringFilterSql)(filtersCompiler_mock_1.stringFilterDimension, filter, "'", true)).toBe(`(${filtersCompiler_mock_1.stringFilterDimension}) IN ('Bob')`);
    });
    test('should apply UPPER() when caseSensitive is false for NOT_EQUALS', () => {
        const filter = {
            id: 'test',
            target: { fieldId: 'test' },
            operator: filter_1.FilterOperator.NOT_EQUALS,
            values: ['Bob'],
        };
        expect((0, filtersCompiler_1.renderStringFilterSql)(filtersCompiler_mock_1.stringFilterDimension, filter, "'", false)).toBe(`((UPPER(${filtersCompiler_mock_1.stringFilterDimension})) NOT IN ('BOB') OR (${filtersCompiler_mock_1.stringFilterDimension}) IS NULL)`);
    });
    test('should apply UPPER() when caseSensitive is false for STARTS_WITH', () => {
        const filter = {
            ...filtersCompiler_mock_1.stringFilterRuleMocks.startsWithFilterWithSingleVal,
            values: ['Bob'],
        };
        expect((0, filtersCompiler_1.renderStringFilterSql)(filtersCompiler_mock_1.stringFilterDimension, filter, "'", false)).toBe(`UPPER(${filtersCompiler_mock_1.stringFilterDimension}) LIKE 'BOB%'`);
    });
    test('should apply UPPER() when caseSensitive is false for ENDS_WITH', () => {
        const filter = {
            ...filtersCompiler_mock_1.stringFilterRuleMocks.endsWithFilterWithSingleVal,
            values: ['Bob'],
        };
        expect((0, filtersCompiler_1.renderStringFilterSql)(filtersCompiler_mock_1.stringFilterDimension, filter, "'", false)).toBe(`UPPER(${filtersCompiler_mock_1.stringFilterDimension}) LIKE '%BOB'`);
    });
    test('should apply UPPER() when caseSensitive is false for INCLUDE', () => {
        const filter = {
            ...filtersCompiler_mock_1.stringFilterRuleMocks.includeFilterWithSingleVal,
            values: ['Bob'],
        };
        expect((0, filtersCompiler_1.renderStringFilterSql)(filtersCompiler_mock_1.stringFilterDimension, filter, "'", false)).toBe(`UPPER(${filtersCompiler_mock_1.stringFilterDimension}) LIKE UPPER('%Bob%')`);
    });
    test('should not apply UPPER() when caseSensitive is true for INCLUDE', () => {
        const filter = {
            ...filtersCompiler_mock_1.stringFilterRuleMocks.includeFilterWithSingleVal,
            values: ['Bob'],
        };
        expect((0, filtersCompiler_1.renderStringFilterSql)(filtersCompiler_mock_1.stringFilterDimension, filter, "'", true)).toBe(`(${filtersCompiler_mock_1.stringFilterDimension}) LIKE '%Bob%'`);
    });
    test('should apply UPPER() when caseSensitive is false for INCLUDE with multiple values', () => {
        const filter = {
            ...filtersCompiler_mock_1.stringFilterRuleMocks.includeFilterWithMultiVal,
            values: ['Tom', 'Jerry'],
        };
        expect((0, filtersCompiler_1.renderStringFilterSql)(filtersCompiler_mock_1.stringFilterDimension, filter, "'", false)).toBe(`(UPPER(${filtersCompiler_mock_1.stringFilterDimension}) LIKE UPPER('%Tom%')
  OR
  UPPER(${filtersCompiler_mock_1.stringFilterDimension}) LIKE UPPER('%Jerry%'))`);
    });
    test('should apply UPPER() when caseSensitive is false for NOT_INCLUDE', () => {
        const filter = {
            ...filtersCompiler_mock_1.stringFilterRuleMocks.notIncludeFilterWithSingleVal,
            values: ['Bob'],
        };
        expect((0, filtersCompiler_1.renderStringFilterSql)(filtersCompiler_mock_1.stringFilterDimension, filter, "'", false)).toBe(`(UPPER(${filtersCompiler_mock_1.stringFilterDimension}) NOT LIKE UPPER('%Bob%') OR (${filtersCompiler_mock_1.stringFilterDimension}) IS NULL)`);
    });
    test('should not apply UPPER() when caseSensitive is true for NOT_INCLUDE', () => {
        const filter = {
            ...filtersCompiler_mock_1.stringFilterRuleMocks.notIncludeFilterWithSingleVal,
            values: ['Bob'],
        };
        expect((0, filtersCompiler_1.renderStringFilterSql)(filtersCompiler_mock_1.stringFilterDimension, filter, "'", true)).toBe(`((${filtersCompiler_mock_1.stringFilterDimension}) NOT LIKE '%Bob%' OR (${filtersCompiler_mock_1.stringFilterDimension}) IS NULL)`);
    });
    test('should apply UPPER() when caseSensitive is false for NOT_INCLUDE with multiple values', () => {
        const filter = {
            ...filtersCompiler_mock_1.stringFilterRuleMocks.notIncludeFilterWithMultiVal,
            values: ['Tom', 'Jerry'],
        };
        expect((0, filtersCompiler_1.renderStringFilterSql)(filtersCompiler_mock_1.stringFilterDimension, filter, "'", false)).toBe(`(UPPER(${filtersCompiler_mock_1.stringFilterDimension}) NOT LIKE UPPER('%Tom%')
  AND
  UPPER(${filtersCompiler_mock_1.stringFilterDimension}) NOT LIKE UPPER('%Jerry%') OR (${filtersCompiler_mock_1.stringFilterDimension}) IS NULL)`);
    });
    test.each([
        [filter_1.FilterOperator.EQUALS, `(UPPER(${filtersCompiler_mock_1.stringFilterDimension})) IN ('1')`],
        [
            filter_1.FilterOperator.NOT_EQUALS,
            `((UPPER(${filtersCompiler_mock_1.stringFilterDimension})) NOT IN ('1') OR (${filtersCompiler_mock_1.stringFilterDimension}) IS NULL)`,
        ],
        [
            filter_1.FilterOperator.STARTS_WITH,
            `UPPER(${filtersCompiler_mock_1.stringFilterDimension}) LIKE '1%'`,
        ],
        [filter_1.FilterOperator.ENDS_WITH, `UPPER(${filtersCompiler_mock_1.stringFilterDimension}) LIKE '%1'`],
    ])('should coerce numeric values to strings when caseSensitive is false for %s', (operator, expectedSql) => {
        const filter = {
            id: 'test',
            target: { fieldId: 'test' },
            operator,
            values: [1],
        };
        expect((0, filtersCompiler_1.renderStringFilterSql)(filtersCompiler_mock_1.stringFilterDimension, filter, "'", false)).toBe(expectedSql);
    });
    test('should respect field-level caseSensitive over explore-level', () => {
        const field = {
            ...filtersCompiler_mock_1.disabledFilterMock.field,
            caseSensitive: false, // field level setting
        };
        const filter = {
            id: 'test',
            target: { fieldId: 'test' },
            operator: filter_1.FilterOperator.EQUALS,
            values: ['Bob'],
        };
        expect((0, filtersCompiler_1.renderFilterRuleSqlFromField)(filter, field, filtersCompiler_mock_1.disabledFilterMock.fieldQuoteChar, filtersCompiler_mock_1.disabledFilterMock.stringQuoteChar, (v) => v, filtersCompiler_mock_1.disabledFilterMock.startOfWeek, filtersCompiler_mock_1.disabledFilterMock.adapterType, filtersCompiler_mock_1.disabledFilterMock.timezone, true)).toBe(`(UPPER("payments".payment_method)) IN ('BOB')`);
    });
    test('should use explore-level caseSensitive when field-level is undefined', () => {
        const field = {
            ...filtersCompiler_mock_1.disabledFilterMock.field,
            // no caseSensitive defined at field level
        };
        const filter = {
            id: 'test',
            target: { fieldId: 'test' },
            operator: filter_1.FilterOperator.EQUALS,
            values: ['Bob'],
        };
        expect((0, filtersCompiler_1.renderFilterRuleSqlFromField)(filter, field, filtersCompiler_mock_1.disabledFilterMock.fieldQuoteChar, filtersCompiler_mock_1.disabledFilterMock.stringQuoteChar, (v) => v, filtersCompiler_mock_1.disabledFilterMock.startOfWeek, filtersCompiler_mock_1.disabledFilterMock.adapterType, filtersCompiler_mock_1.disabledFilterMock.timezone, false)).toBe(`(UPPER("payments".payment_method)) IN ('BOB')`);
    });
});
describe('escape string values', () => {
    test('should not escape on the string filter method', () => {
        // Escape happens now on the parent method, not on the string filter
        expect((0, filtersCompiler_1.renderStringFilterSql)(filtersCompiler_mock_1.stringFilterDimension, filtersCompiler_mock_1.stringFilterRuleMocks.equalsFilterWithSingleUnescapedValue, "'")).toBe(`("customers".first_name) IN ('Bob's')`);
    });
    test('should return escaped query for unescaped single filter value', () => {
        expect((0, filtersCompiler_1.renderFilterRuleSqlFromField)(filtersCompiler_mock_1.stringFilterRuleMocks.equalsFilterWithSingleUnescapedValue, filtersCompiler_mock_1.disabledFilterMock.field, filtersCompiler_mock_1.disabledFilterMock.fieldQuoteChar, filtersCompiler_mock_1.disabledFilterMock.stringQuoteChar, (v) => v.replaceAll("'", "''"), filtersCompiler_mock_1.disabledFilterMock.startOfWeek, filtersCompiler_mock_1.disabledFilterMock.adapterType, filtersCompiler_mock_1.disabledFilterMock.timezone)).toBe(`("payments".payment_method) IN ('Bob''s')`);
    });
    test('should return escaped query for unescaped multi filter values', () => {
        expect((0, filtersCompiler_1.renderFilterRuleSqlFromField)(filtersCompiler_mock_1.stringFilterRuleMocks.equalsFilterWithMultiUnescapedValue, filtersCompiler_mock_1.disabledFilterMock.field, filtersCompiler_mock_1.disabledFilterMock.fieldQuoteChar, filtersCompiler_mock_1.disabledFilterMock.stringQuoteChar, (v) => v.replaceAll("'", "''"), filtersCompiler_mock_1.disabledFilterMock.startOfWeek, filtersCompiler_mock_1.disabledFilterMock.adapterType, filtersCompiler_mock_1.disabledFilterMock.timezone)).toBe(`("payments".payment_method) IN ('Bob''s','Tom''s')`);
    });
});
describe('Boolean Filter SQL', () => {
    const dimensionSql = '("table"."is_active")';
    const baseFilter = {
        id: 'test-id',
        target: { fieldId: 'is_active' },
    };
    describe('equals operator', () => {
        it('should handle boolean true correctly', () => {
            const filter = {
                ...baseFilter,
                operator: filter_1.FilterOperator.EQUALS,
                values: [true],
            };
            expect((0, filtersCompiler_1.renderBooleanFilterSql)(dimensionSql, filter)).toBe('(("table"."is_active")) = true');
        });
        it('should handle boolean false correctly', () => {
            const filter = {
                ...baseFilter,
                operator: filter_1.FilterOperator.EQUALS,
                values: [false],
            };
            expect((0, filtersCompiler_1.renderBooleanFilterSql)(dimensionSql, filter)).toBe('(("table"."is_active")) = false');
        });
        it('should handle string "true" correctly', () => {
            const filter = {
                ...baseFilter,
                operator: filter_1.FilterOperator.EQUALS,
                values: ['true'],
            };
            expect((0, filtersCompiler_1.renderBooleanFilterSql)(dimensionSql, filter)).toBe('(("table"."is_active")) = true');
        });
        it('should handle string "false" correctly (THIS WILL FAIL BEFORE FIX)', () => {
            const filter = {
                ...baseFilter,
                operator: filter_1.FilterOperator.EQUALS,
                values: ['false'],
            };
            // This test will fail initially because current implementation returns "true"
            expect((0, filtersCompiler_1.renderBooleanFilterSql)(dimensionSql, filter)).toBe('(("table"."is_active")) = false');
        });
        it('should handle case insensitive string booleans', () => {
            const filterFalse = {
                ...baseFilter,
                operator: filter_1.FilterOperator.EQUALS,
                values: ['FALSE'],
            };
            const filterTrue = {
                ...baseFilter,
                operator: filter_1.FilterOperator.EQUALS,
                values: ['TRUE'],
            };
            expect((0, filtersCompiler_1.renderBooleanFilterSql)(dimensionSql, filterFalse)).toBe('(("table"."is_active")) = false');
            expect((0, filtersCompiler_1.renderBooleanFilterSql)(dimensionSql, filterTrue)).toBe('(("table"."is_active")) = true');
        });
        it('should handle whitespace around boolean strings', () => {
            const filterFalse = {
                ...baseFilter,
                operator: filter_1.FilterOperator.EQUALS,
                values: [' false '],
            };
            const filterTrue = {
                ...baseFilter,
                operator: filter_1.FilterOperator.EQUALS,
                values: [' true '],
            };
            expect((0, filtersCompiler_1.renderBooleanFilterSql)(dimensionSql, filterFalse)).toBe('(("table"."is_active")) = false');
            expect((0, filtersCompiler_1.renderBooleanFilterSql)(dimensionSql, filterTrue)).toBe('(("table"."is_active")) = true');
        });
    });
    describe('notEquals operator', () => {
        it('should handle boolean false correctly', () => {
            const filter = {
                ...baseFilter,
                operator: filter_1.FilterOperator.NOT_EQUALS,
                values: [false],
            };
            expect((0, filtersCompiler_1.renderBooleanFilterSql)(dimensionSql, filter)).toBe('((("table"."is_active")) != false OR (("table"."is_active")) IS NULL)');
        });
        it('should handle string "false" correctly (THIS WILL FAIL BEFORE FIX)', () => {
            const filter = {
                ...baseFilter,
                operator: filter_1.FilterOperator.NOT_EQUALS,
                values: ['false'],
            };
            // This test will fail initially because current implementation uses "true"
            expect((0, filtersCompiler_1.renderBooleanFilterSql)(dimensionSql, filter)).toBe('((("table"."is_active")) != false OR (("table"."is_active")) IS NULL)');
        });
    });
    describe('isNull and notNull operators', () => {
        it('should handle isNull operator', () => {
            const filter = {
                ...baseFilter,
                operator: filter_1.FilterOperator.NULL,
                values: [true],
            };
            expect((0, filtersCompiler_1.renderBooleanFilterSql)(dimensionSql, filter)).toBe('(("table"."is_active")) IS NULL');
        });
        it('should handle notNull operator', () => {
            const filter = {
                ...baseFilter,
                operator: filter_1.FilterOperator.NOT_NULL,
                values: [true],
            };
            expect((0, filtersCompiler_1.renderBooleanFilterSql)(dimensionSql, filter)).toBe('(("table"."is_active")) IS NOT NULL');
        });
    });
});
describe('Number Filter SQL Injection Prevention', () => {
    const dimensionSql = '("table"."customer_id")';
    const baseFilter = {
        id: 'test-id',
        target: { fieldId: 'customer_id' },
    };
    describe('SQL injection attempts should throw errors', () => {
        it('should reject SQL injection in EQUALS filter', () => {
            const filter = {
                ...baseFilter,
                operator: filter_1.FilterOperator.EQUALS,
                values: ['1) OR 1=1; --'],
            };
            expect(() => (0, filtersCompiler_1.renderNumberFilterSql)(dimensionSql, filter)).toThrow('Invalid number value in filter: "1) OR 1=1; --". Expected a valid number.');
        });
        it('should reject SQL injection with UNION SELECT', () => {
            const filter = {
                ...baseFilter,
                operator: filter_1.FilterOperator.EQUALS,
                values: ['1) UNION SELECT * FROM users; --'],
            };
            expect(() => (0, filtersCompiler_1.renderNumberFilterSql)(dimensionSql, filter)).toThrow('Invalid number value in filter: "1) UNION SELECT * FROM users; --". Expected a valid number.');
        });
        it('should reject SQL injection in NOT_EQUALS filter', () => {
            const filter = {
                ...baseFilter,
                operator: filter_1.FilterOperator.NOT_EQUALS,
                values: ['1); DELETE FROM customers; --'],
            };
            expect(() => (0, filtersCompiler_1.renderNumberFilterSql)(dimensionSql, filter)).toThrow('Invalid number value in filter: "1); DELETE FROM customers; --". Expected a valid number.');
        });
        it('should reject subquery injection attempts', () => {
            const filter = {
                ...baseFilter,
                operator: filter_1.FilterOperator.EQUALS,
                values: ['SELECT customer_id FROM customers'],
            };
            expect(() => (0, filtersCompiler_1.renderNumberFilterSql)(dimensionSql, filter)).toThrow('Invalid number value in filter: "SELECT customer_id FROM customers". Expected a valid number.');
        });
        it('should reject multiple SQL injection values', () => {
            const filter = {
                ...baseFilter,
                operator: filter_1.FilterOperator.EQUALS,
                values: ['1', '2) OR 1=1; --', '3'],
            };
            expect(() => (0, filtersCompiler_1.renderNumberFilterSql)(dimensionSql, filter)).toThrow('Invalid number value in filter: "2) OR 1=1; --". Expected a valid number.');
        });
        it('should reject SQL injection in comparison operators', () => {
            const filter = {
                ...baseFilter,
                operator: filter_1.FilterOperator.GREATER_THAN,
                values: ['1 OR 1=1'],
            };
            expect(() => (0, filtersCompiler_1.renderNumberFilterSql)(dimensionSql, filter)).toThrow('Invalid number value in filter: "1 OR 1=1". Expected a valid number.');
        });
        it('should reject SQL injection in BETWEEN operator', () => {
            const filter = {
                ...baseFilter,
                operator: filter_1.FilterOperator.IN_BETWEEN,
                values: ['1', '100); DROP TABLE customers; --'],
            };
            expect(() => (0, filtersCompiler_1.renderNumberFilterSql)(dimensionSql, filter)).toThrow('Invalid number value in filter: "100); DROP TABLE customers; --". Expected a valid number.');
        });
    });
    describe('Valid number inputs should be accepted', () => {
        it('should accept valid integer values', () => {
            const filter = {
                ...baseFilter,
                operator: filter_1.FilterOperator.EQUALS,
                values: [1, 2, 3],
            };
            expect((0, filtersCompiler_1.renderNumberFilterSql)(dimensionSql, filter)).toBe('(("table"."customer_id")) IN (1,2,3)');
        });
        it('should accept valid decimal values', () => {
            const filter = {
                ...baseFilter,
                operator: filter_1.FilterOperator.EQUALS,
                values: [1.5, 2.7, 3.14159],
            };
            expect((0, filtersCompiler_1.renderNumberFilterSql)(dimensionSql, filter)).toBe('(("table"."customer_id")) IN (1.5,2.7,3.14159)');
        });
        it('should accept negative numbers', () => {
            const filter = {
                ...baseFilter,
                operator: filter_1.FilterOperator.EQUALS,
                values: [-1, -2.5, -100],
            };
            expect((0, filtersCompiler_1.renderNumberFilterSql)(dimensionSql, filter)).toBe('(("table"."customer_id")) IN (-1,-2.5,-100)');
        });
        it('should accept numeric strings that can be converted', () => {
            const filter = {
                ...baseFilter,
                operator: filter_1.FilterOperator.EQUALS,
                values: ['123', '456.78', '-90'],
            };
            expect((0, filtersCompiler_1.renderNumberFilterSql)(dimensionSql, filter)).toBe('(("table"."customer_id")) IN (123,456.78,-90)');
        });
        it('should handle comparison operators with valid numbers', () => {
            const filter = {
                ...baseFilter,
                operator: filter_1.FilterOperator.GREATER_THAN,
                values: ['100'],
            };
            expect((0, filtersCompiler_1.renderNumberFilterSql)(dimensionSql, filter)).toBe('(("table"."customer_id")) > (100)');
        });
        it('should handle BETWEEN operator with valid numbers', () => {
            const filter = {
                ...baseFilter,
                operator: filter_1.FilterOperator.IN_BETWEEN,
                values: ['10', '100'],
            };
            expect((0, filtersCompiler_1.renderNumberFilterSql)(dimensionSql, filter)).toBe('(("table"."customer_id")) >= (10) AND (("table"."customer_id")) <= (100)');
        });
    });
    describe('Edge cases and special values', () => {
        it('should reject NaN values', () => {
            const filter = {
                ...baseFilter,
                operator: filter_1.FilterOperator.EQUALS,
                values: [NaN],
            };
            expect(() => (0, filtersCompiler_1.renderNumberFilterSql)(dimensionSql, filter)).toThrow('Invalid number value in filter: "NaN". Expected a valid number.');
        });
        it('should reject Infinity values', () => {
            const filter = {
                ...baseFilter,
                operator: filter_1.FilterOperator.EQUALS,
                values: [Infinity],
            };
            expect(() => (0, filtersCompiler_1.renderNumberFilterSql)(dimensionSql, filter)).toThrow('Invalid number value in filter: "Infinity". Expected a valid number.');
        });
        it('should reject string values that are not numbers', () => {
            const filter = {
                ...baseFilter,
                operator: filter_1.FilterOperator.EQUALS,
                values: ['abc', 'hello world', ''],
            };
            expect(() => (0, filtersCompiler_1.renderNumberFilterSql)(dimensionSql, filter)).toThrow('Invalid number value in filter: "abc". Expected a valid number.');
        });
        it('should reject objects and arrays', () => {
            const filterWithObject = {
                ...baseFilter,
                operator: filter_1.FilterOperator.EQUALS,
                values: [{}],
            };
            expect(() => (0, filtersCompiler_1.renderNumberFilterSql)(dimensionSql, filterWithObject)).toThrow('Invalid number value in filter: "[object Object]". Expected a valid number.');
            const filterWithArray = {
                ...baseFilter,
                operator: filter_1.FilterOperator.EQUALS,
                values: [[1, 2, 3]],
            };
            expect(() => (0, filtersCompiler_1.renderNumberFilterSql)(dimensionSql, filterWithArray)).toThrow('Invalid number value in filter: "1,2,3". Expected a valid number.');
        });
        it('should handle exponential notation', () => {
            const filter = {
                ...baseFilter,
                operator: filter_1.FilterOperator.EQUALS,
                values: ['1e3', '2.5e-4'],
            };
            expect((0, filtersCompiler_1.renderNumberFilterSql)(dimensionSql, filter)).toBe('(("table"."customer_id")) IN (1000,0.00025)');
        });
        it('should return true for comparison operators with empty values', () => {
            const comparisonOperators = [
                filter_1.FilterOperator.GREATER_THAN,
                filter_1.FilterOperator.GREATER_THAN_OR_EQUAL,
                filter_1.FilterOperator.LESS_THAN,
                filter_1.FilterOperator.LESS_THAN_OR_EQUAL,
            ];
            comparisonOperators.forEach((operator) => {
                const filter = {
                    ...baseFilter,
                    operator,
                    values: [],
                };
                expect((0, filtersCompiler_1.renderNumberFilterSql)(dimensionSql, filter)).toBe('true');
            });
        });
        it('should return true for IN_BETWEEN operator with empty values', () => {
            const filter = {
                ...baseFilter,
                operator: filter_1.FilterOperator.IN_BETWEEN,
                values: [],
            };
            expect((0, filtersCompiler_1.renderNumberFilterSql)(dimensionSql, filter)).toBe('true');
        });
        it('should return true for IN_BETWEEN operator with only one value', () => {
            const filter = {
                ...baseFilter,
                operator: filter_1.FilterOperator.IN_BETWEEN,
                values: [5],
            };
            expect((0, filtersCompiler_1.renderNumberFilterSql)(dimensionSql, filter)).toBe('true');
        });
        it('should return true for NOT_IN_BETWEEN operator with empty values', () => {
            const filter = {
                ...baseFilter,
                operator: filter_1.FilterOperator.NOT_IN_BETWEEN,
                values: [],
            };
            expect((0, filtersCompiler_1.renderNumberFilterSql)(dimensionSql, filter)).toBe('true');
        });
        it('should return true for NOT_IN_BETWEEN operator with only one value', () => {
            const filter = {
                ...baseFilter,
                operator: filter_1.FilterOperator.NOT_IN_BETWEEN,
                values: [5],
            };
            expect((0, filtersCompiler_1.renderNumberFilterSql)(dimensionSql, filter)).toBe('true');
        });
    });
    describe('timezone-aware date formatter boundaries with positive-offset timezones', () => {
        test.each(filtersCompiler_mock_1.filterInThePastCompletedDayDateFormatterMocks)('inThePast completed day (tz-aware formatter) for timezone %s', (timezone, expected) => {
            jest.setSystemTime(new Date('04 Apr 2020 06:12:30 GMT').getTime());
            expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, {
                ...filtersCompiler_mock_1.InThePastFilterBase,
                settings: {
                    unitOfTime: filter_1.UnitOfTime.days,
                    completed: true,
                },
            }, filtersCompiler_mock_1.adapterType.default, timezone, (0, filtersCompiler_1.createBoundaryDateFormatter)(timezone))).toStrictEqual(expected);
        });
        test.each(filtersCompiler_mock_1.filterInTheCurrentDayDateFormatterMocks)('inTheCurrent day (tz-aware formatter) for timezone %s', (timezone, expected) => {
            jest.setSystemTime(new Date('04 Apr 2020 06:12:30 GMT').getTime());
            expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, {
                ...filtersCompiler_mock_1.InTheCurrentFilterBase,
                settings: { unitOfTime: filter_1.UnitOfTime.days },
            }, filtersCompiler_mock_1.adapterType.default, timezone, (0, filtersCompiler_1.createBoundaryDateFormatter)(timezone))).toStrictEqual(expected);
        });
        test.each(filtersCompiler_mock_1.filterInThePastNonCompletedDayDateFormatterMocks)('inThePast non-completed day (tz-aware formatter) for timezone %s', (timezone, expected) => {
            jest.setSystemTime(new Date('04 Apr 2020 06:12:30 GMT').getTime());
            expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, {
                ...filtersCompiler_mock_1.InThePastFilterBase,
                settings: {
                    unitOfTime: filter_1.UnitOfTime.days,
                    completed: false,
                },
            }, filtersCompiler_mock_1.adapterType.default, timezone, (0, filtersCompiler_1.createBoundaryDateFormatter)(timezone))).toStrictEqual(expected);
        });
        test.each(filtersCompiler_mock_1.filterInTheNextCompletedDayDateFormatterMocks)('inTheNext completed day (tz-aware formatter) for timezone %s', (timezone, expected) => {
            jest.setSystemTime(new Date('04 Apr 2020 06:12:30 GMT').getTime());
            expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, {
                ...filtersCompiler_mock_1.InTheNextFilterBase,
                settings: {
                    unitOfTime: filter_1.UnitOfTime.days,
                    completed: true,
                },
            }, filtersCompiler_mock_1.adapterType.default, timezone, (0, filtersCompiler_1.createBoundaryDateFormatter)(timezone))).toStrictEqual(expected);
        });
        test.each(filtersCompiler_mock_1.filterInTheNextNonCompletedDayDateFormatterMocks)('inTheNext non-completed day (tz-aware formatter) for timezone %s', (timezone, expected) => {
            jest.setSystemTime(new Date('04 Apr 2020 06:12:30 GMT').getTime());
            expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, {
                ...filtersCompiler_mock_1.InTheNextFilterBase,
                settings: {
                    unitOfTime: filter_1.UnitOfTime.days,
                    completed: false,
                },
            }, filtersCompiler_mock_1.adapterType.default, timezone, (0, filtersCompiler_1.createBoundaryDateFormatter)(timezone))).toStrictEqual(expected);
        });
    });
    describe('negative-offset edge case near midnight UTC', () => {
        test.each(filtersCompiler_mock_1.filterNegativeOffsetEdgeCaseCurrentDayMocks)('inTheCurrent day near midnight UTC for timezone %s', (timezone, expected) => {
            jest.setSystemTime(new Date('04 Apr 2020 02:00:00 GMT').getTime());
            expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, {
                ...filtersCompiler_mock_1.InTheCurrentFilterBase,
                settings: { unitOfTime: filter_1.UnitOfTime.days },
            }, filtersCompiler_mock_1.adapterType.default, timezone, (0, filtersCompiler_1.createBoundaryDateFormatter)(timezone))).toStrictEqual(expected);
        });
        test.each(filtersCompiler_mock_1.filterNegativeOffsetEdgeCasePastCompletedDayMocks)('inThePast completed day near midnight UTC for timezone %s', (timezone, expected) => {
            jest.setSystemTime(new Date('04 Apr 2020 02:00:00 GMT').getTime());
            expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, {
                ...filtersCompiler_mock_1.InThePastFilterBase,
                settings: {
                    unitOfTime: filter_1.UnitOfTime.days,
                    completed: true,
                },
            }, filtersCompiler_mock_1.adapterType.default, timezone, (0, filtersCompiler_1.createBoundaryDateFormatter)(timezone))).toStrictEqual(expected);
        });
    });
    describe('positive-offset edge case near end of UTC day', () => {
        test.each(filtersCompiler_mock_1.filterPositiveOffsetEdgeCaseCurrentDayMocks)('inTheCurrent day late UTC for timezone %s', (timezone, expected) => {
            jest.setSystemTime(new Date('04 Apr 2020 22:00:00 GMT').getTime());
            expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, {
                ...filtersCompiler_mock_1.InTheCurrentFilterBase,
                settings: { unitOfTime: filter_1.UnitOfTime.days },
            }, filtersCompiler_mock_1.adapterType.default, timezone, (0, filtersCompiler_1.createBoundaryDateFormatter)(timezone))).toStrictEqual(expected);
        });
        test.each(filtersCompiler_mock_1.filterPositiveOffsetEdgeCasePastCompletedDayMocks)('inThePast completed day late UTC for timezone %s', (timezone, expected) => {
            jest.setSystemTime(new Date('04 Apr 2020 22:00:00 GMT').getTime());
            expect((0, filtersCompiler_1.renderDateFilterSql)(filtersCompiler_mock_1.DimensionSqlMock, {
                ...filtersCompiler_mock_1.InThePastFilterBase,
                settings: {
                    unitOfTime: filter_1.UnitOfTime.days,
                    completed: true,
                },
            }, filtersCompiler_mock_1.adapterType.default, timezone, (0, filtersCompiler_1.createBoundaryDateFormatter)(timezone))).toStrictEqual(expected);
        });
    });
});
describe('DATE dimension filters are server-timezone-independent', () => {
    // Regression: the default boundaryFormatter (formatDate) used moment(date)
    // which formats in the server's local timezone. On a server with a positive
    // UTC offset, endOf('day') in UTC (23:59 UTC) gets shifted to the next
    // calendar day, producing a 2-day filter range instead of 1.
    const systemTime = new Date('10 Apr 2026 14:00:00 GMT');
    beforeEach(() => {
        jest.setSystemTime(systemTime.getTime());
    });
    afterEach(() => {
        // Reset moment default timezone so other tests are unaffected
        moment_timezone_1.default.tz.setDefault();
    });
    test.each([
        ['UTC', 'UTC'],
        ['Europe/Moscow', 'UTC'],
        ['Asia/Tokyo', 'UTC'],
        ['America/New_York', 'UTC'],
        ['Pacific/Auckland', 'UTC'],
    ])('inTheCurrent day for DATE dimension produces single-day range regardless of server TZ=%s', (serverTz, projectTz) => {
        // Simulate a server running in a non-UTC timezone
        moment_timezone_1.default.tz.setDefault(serverTz);
        const sql = (0, filtersCompiler_1.renderFilterRuleSql)({
            id: 'id',
            target: { fieldId: 'fieldId' },
            operator: filter_1.FilterOperator.IN_THE_CURRENT,
            values: [1],
            settings: { unitOfTime: filter_1.UnitOfTime.days },
        }, field_1.DimensionType.DATE, filtersCompiler_mock_1.DimensionSqlMock, "'", (s) => s, null, dbt_1.SupportedDbtAdapter.POSTGRES, projectTz);
        // Both boundaries must be the same UTC date — no 2-day range
        expect(sql).toBe(`((${filtersCompiler_mock_1.DimensionSqlMock}) >= ('2026-04-10') AND (${filtersCompiler_mock_1.DimensionSqlMock}) <= ('2026-04-10'))`);
    });
    test.each([
        ['Europe/Moscow', 'UTC'],
        ['Asia/Tokyo', 'UTC'],
        ['America/New_York', 'UTC'],
    ])('inThePast 1 completed day for DATE dimension is server-TZ-independent (server TZ=%s)', (serverTz, projectTz) => {
        moment_timezone_1.default.tz.setDefault(serverTz);
        const sql = (0, filtersCompiler_1.renderFilterRuleSql)({
            id: 'id',
            target: { fieldId: 'fieldId' },
            operator: filter_1.FilterOperator.IN_THE_PAST,
            values: [1],
            settings: {
                unitOfTime: filter_1.UnitOfTime.days,
                completed: true,
            },
        }, field_1.DimensionType.DATE, filtersCompiler_mock_1.DimensionSqlMock, "'", (s) => s, null, dbt_1.SupportedDbtAdapter.POSTGRES, projectTz);
        // Yesterday in UTC: April 9
        expect(sql).toBe(`((${filtersCompiler_mock_1.DimensionSqlMock}) >= ('2026-04-09') AND (${filtersCompiler_mock_1.DimensionSqlMock}) < ('2026-04-10'))`);
    });
});
describe('useTimezoneAwareDateTrunc parameter — filter literal wrapping', () => {
    const equalsFilter = {
        id: 'id',
        target: { fieldId: 'fieldId' },
        operator: filter_1.FilterOperator.EQUALS,
        values: ['2024-01-15'],
    };
    test('DATE-over-TIMESTAMP filter wraps literal in project TZ when parameter is true', () => {
        const sql = (0, filtersCompiler_1.renderFilterRuleSql)(equalsFilter, field_1.DimensionType.DATE, filtersCompiler_mock_1.DimensionSqlMock, "'", (s) => s, null, dbt_1.SupportedDbtAdapter.POSTGRES, 'Asia/Tokyo', true, undefined, true, field_1.DimensionType.TIMESTAMP);
        expect(sql).toContain("AT TIME ZONE 'Asia/Tokyo'");
        expect(sql).toContain("'2024-01-15'::timestamp");
    });
    test('DATE filter leaves literal bare when parameter is omitted', () => {
        const sql = (0, filtersCompiler_1.renderFilterRuleSql)(equalsFilter, field_1.DimensionType.DATE, filtersCompiler_mock_1.DimensionSqlMock, "'", (s) => s, null, dbt_1.SupportedDbtAdapter.POSTGRES, 'Asia/Tokyo');
        expect(sql).not.toContain('AT TIME ZONE');
    });
    test('DATE filter over a DATE base emits a bare literal even when parameter is true', () => {
        const sql = (0, filtersCompiler_1.renderFilterRuleSql)(equalsFilter, field_1.DimensionType.DATE, filtersCompiler_mock_1.DimensionSqlMock, "'", (s) => s, null, dbt_1.SupportedDbtAdapter.POSTGRES, 'Asia/Tokyo', true, undefined, true, field_1.DimensionType.DATE);
        expect(sql).not.toContain('AT TIME ZONE');
        expect(sql).not.toContain('::timestamp');
    });
    test('BigQuery DATE-over-TIMESTAMP filter emits TIMESTAMP(literal, tz)', () => {
        const sql = (0, filtersCompiler_1.renderFilterRuleSql)(equalsFilter, field_1.DimensionType.DATE, filtersCompiler_mock_1.DimensionSqlMock, "'", (s) => s, null, dbt_1.SupportedDbtAdapter.BIGQUERY, 'Asia/Tokyo', true, undefined, true, field_1.DimensionType.TIMESTAMP);
        expect(sql).toContain("TIMESTAMP('2024-01-15', 'Asia/Tokyo')");
        expect(sql).not.toContain('::timestamp');
    });
    test('BigQuery DATE filter over a DATE base emits a bare literal (no TIMESTAMP wrap)', () => {
        const sql = (0, filtersCompiler_1.renderFilterRuleSql)(equalsFilter, field_1.DimensionType.DATE, filtersCompiler_mock_1.DimensionSqlMock, "'", (s) => s, null, dbt_1.SupportedDbtAdapter.BIGQUERY, 'Asia/Tokyo', true, undefined, true, field_1.DimensionType.DATE);
        expect(sql).not.toContain('TIMESTAMP(');
        expect(sql).toContain("'2024-01-15'");
    });
    test('ClickHouse DATE-over-TIMESTAMP filter anchors literal with toDateTime(literal, tz)', () => {
        const sql = (0, filtersCompiler_1.renderFilterRuleSql)(equalsFilter, field_1.DimensionType.DATE, filtersCompiler_mock_1.DimensionSqlMock, "'", (s) => s, null, dbt_1.SupportedDbtAdapter.CLICKHOUSE, 'Asia/Tokyo', true, undefined, true, field_1.DimensionType.TIMESTAMP);
        expect(sql).toContain("toDateTime('2024-01-15', 'Asia/Tokyo')");
        expect(sql).not.toContain('::timestamp');
    });
    test('ClickHouse DATE filter over a DATE base emits a bare literal (no toDateTime wrap)', () => {
        const sql = (0, filtersCompiler_1.renderFilterRuleSql)(equalsFilter, field_1.DimensionType.DATE, filtersCompiler_mock_1.DimensionSqlMock, "'", (s) => s, null, dbt_1.SupportedDbtAdapter.CLICKHOUSE, 'Asia/Tokyo', true, undefined, true, field_1.DimensionType.DATE);
        expect(sql).not.toContain('toDateTime(');
    });
    test('TIMESTAMP filter does not wrap literal even when parameter is true', () => {
        const sql = (0, filtersCompiler_1.renderFilterRuleSql)(equalsFilter, field_1.DimensionType.TIMESTAMP, filtersCompiler_mock_1.DimensionSqlMock, "'", (s) => s, null, dbt_1.SupportedDbtAdapter.POSTGRES, 'Asia/Tokyo', true, undefined, true, field_1.DimensionType.TIMESTAMP);
        expect(sql).not.toContain("AT TIME ZONE 'Asia/Tokyo'");
    });
    describe('relative filters', () => {
        beforeEach(() => {
            jest.setSystemTime(new Date('2026-04-22 00:00:00 GMT').getTime());
        });
        const renderWithParam = (filter, useTimezoneAwareDateTrunc, baseTimeIntervalDimensionType = field_1.DimensionType.TIMESTAMP) => (0, filtersCompiler_1.renderFilterRuleSql)(filter, field_1.DimensionType.DATE, filtersCompiler_mock_1.DimensionSqlMock, "'", (s) => s, null, dbt_1.SupportedDbtAdapter.POSTGRES, 'Asia/Tokyo', true, undefined, useTimezoneAwareDateTrunc, baseTimeIntervalDimensionType);
        test('inThePast completed day wraps boundaries in project TZ', () => {
            const filter = {
                id: 'id',
                target: { fieldId: 'fieldId' },
                operator: filter_1.FilterOperator.IN_THE_PAST,
                values: [1],
                settings: { unitOfTime: filter_1.UnitOfTime.days, completed: true },
            };
            const sql = renderWithParam(filter, true);
            expect(sql).toContain("AT TIME ZONE 'Asia/Tokyo'");
            expect(sql).toContain("'2026-04-21'::timestamp");
        });
        test('inTheCurrent day wraps boundaries in project TZ', () => {
            const filter = {
                id: 'id',
                target: { fieldId: 'fieldId' },
                operator: filter_1.FilterOperator.IN_THE_CURRENT,
                values: [1],
                settings: { unitOfTime: filter_1.UnitOfTime.days },
            };
            const sql = renderWithParam(filter, true);
            expect(sql).toContain("AT TIME ZONE 'Asia/Tokyo'");
            expect(sql).toContain("'2026-04-22'::timestamp");
        });
        test('inTheNext day wraps boundaries in project TZ', () => {
            const filter = {
                id: 'id',
                target: { fieldId: 'fieldId' },
                operator: filter_1.FilterOperator.IN_THE_NEXT,
                values: [1],
                settings: { unitOfTime: filter_1.UnitOfTime.days, completed: false },
            };
            const sql = renderWithParam(filter, true);
            expect(sql).toContain("AT TIME ZONE 'Asia/Tokyo'");
        });
        test('inThePast completed day leaves boundaries bare when parameter is omitted', () => {
            const filter = {
                id: 'id',
                target: { fieldId: 'fieldId' },
                operator: filter_1.FilterOperator.IN_THE_PAST,
                values: [1],
                settings: { unitOfTime: filter_1.UnitOfTime.days, completed: true },
            };
            const sql = renderWithParam(filter, false);
            expect(sql).not.toContain('AT TIME ZONE');
        });
        test('inThePast completed weeks on a DATE-backed dimension does not wrap BigQuery literals in TIMESTAMP', () => {
            const filter = {
                id: 'id',
                target: { fieldId: 'fieldId' },
                operator: filter_1.FilterOperator.IN_THE_PAST,
                values: [14],
                settings: { unitOfTime: filter_1.UnitOfTime.weeks, completed: true },
            };
            const sql = (0, filtersCompiler_1.renderFilterRuleSql)(filter, field_1.DimensionType.DATE, filtersCompiler_mock_1.DimensionSqlMock, "'", (s) => s, null, dbt_1.SupportedDbtAdapter.BIGQUERY, 'Asia/Tokyo', true, undefined, true, field_1.DimensionType.DATE);
            expect(sql).not.toContain('TIMESTAMP(');
        });
    });
    describe('target tz === source tz short-circuit (mirrors dim-side resolveTimezoneWrap)', () => {
        test('BigQuery: UTC project tz + UTC source drops the TIMESTAMP wrap on the literal', () => {
            const sql = (0, filtersCompiler_1.renderFilterRuleSql)(equalsFilter, field_1.DimensionType.DATE, filtersCompiler_mock_1.DimensionSqlMock, "'", (s) => s, null, dbt_1.SupportedDbtAdapter.BIGQUERY, 'UTC', true, undefined, true, field_1.DimensionType.TIMESTAMP, 'UTC');
            expect(sql).not.toContain('TIMESTAMP(');
            expect(sql).toContain("'2024-01-15'");
        });
        test('BigQuery: UTC project tz + undefined source (defaults to UTC) drops the wrap', () => {
            const sql = (0, filtersCompiler_1.renderFilterRuleSql)(equalsFilter, field_1.DimensionType.DATE, filtersCompiler_mock_1.DimensionSqlMock, "'", (s) => s, null, dbt_1.SupportedDbtAdapter.BIGQUERY, 'UTC', true, undefined, true, field_1.DimensionType.TIMESTAMP);
            expect(sql).not.toContain('TIMESTAMP(');
        });
        test('BigQuery: matching non-UTC source/target drops the wrap', () => {
            const sql = (0, filtersCompiler_1.renderFilterRuleSql)(equalsFilter, field_1.DimensionType.DATE, filtersCompiler_mock_1.DimensionSqlMock, "'", (s) => s, null, dbt_1.SupportedDbtAdapter.BIGQUERY, 'America/New_York', true, undefined, true, field_1.DimensionType.TIMESTAMP, 'America/New_York');
            expect(sql).not.toContain('TIMESTAMP(');
        });
        test('BigQuery: non-matching source/target preserves the wrap', () => {
            const sql = (0, filtersCompiler_1.renderFilterRuleSql)(equalsFilter, field_1.DimensionType.DATE, filtersCompiler_mock_1.DimensionSqlMock, "'", (s) => s, null, dbt_1.SupportedDbtAdapter.BIGQUERY, 'America/New_York', true, undefined, true, field_1.DimensionType.TIMESTAMP, 'UTC');
            expect(sql).toContain("TIMESTAMP('2024-01-15', 'America/New_York')");
        });
        test('Postgres: matching source/target drops the AT TIME ZONE wrap on the literal', () => {
            const sql = (0, filtersCompiler_1.renderFilterRuleSql)(equalsFilter, field_1.DimensionType.DATE, filtersCompiler_mock_1.DimensionSqlMock, "'", (s) => s, null, dbt_1.SupportedDbtAdapter.POSTGRES, 'UTC', true, undefined, true, field_1.DimensionType.TIMESTAMP, 'UTC');
            expect(sql).not.toContain('AT TIME ZONE');
            expect(sql).not.toContain('::timestamp');
        });
        test('ClickHouse: matching source/target drops the toDateTime wrap on the literal', () => {
            const sql = (0, filtersCompiler_1.renderFilterRuleSql)(equalsFilter, field_1.DimensionType.DATE, filtersCompiler_mock_1.DimensionSqlMock, "'", (s) => s, null, dbt_1.SupportedDbtAdapter.CLICKHOUSE, 'UTC', true, undefined, true, field_1.DimensionType.TIMESTAMP, 'UTC');
            expect(sql).not.toContain('toDateTime(');
        });
        test('Postgres: non-matching source/target preserves the AT TIME ZONE wrap', () => {
            const sql = (0, filtersCompiler_1.renderFilterRuleSql)(equalsFilter, field_1.DimensionType.DATE, filtersCompiler_mock_1.DimensionSqlMock, "'", (s) => s, null, dbt_1.SupportedDbtAdapter.POSTGRES, 'America/New_York', true, undefined, true, field_1.DimensionType.TIMESTAMP, 'UTC');
            expect(sql).toContain("AT TIME ZONE 'America/New_York'");
            expect(sql).toContain("'2024-01-15'::timestamp");
        });
        test('ClickHouse: non-matching source/target preserves the toDateTime wrap', () => {
            const sql = (0, filtersCompiler_1.renderFilterRuleSql)(equalsFilter, field_1.DimensionType.DATE, filtersCompiler_mock_1.DimensionSqlMock, "'", (s) => s, null, dbt_1.SupportedDbtAdapter.CLICKHOUSE, 'America/New_York', true, undefined, true, field_1.DimensionType.TIMESTAMP, 'UTC');
            expect(sql).toContain("toDateTime('2024-01-15', 'America/New_York')");
        });
    });
});
//# sourceMappingURL=filtersCompiler.test.js.map