"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const field_1 = require("../types/field");
const fieldSetExpander_1 = require("./fieldSetExpander");
const createMockTable = (name, dimensions, metrics, sets) => ({
    name,
    label: name,
    database: 'test_db',
    schema: 'test_schema',
    sqlTable: name,
    description: `${name} table`,
    dimensions: dimensions.reduce((acc, dim) => ({
        ...acc,
        [dim]: {
            fieldType: field_1.FieldType.DIMENSION,
            type: field_1.DimensionType.STRING,
            name: dim,
            label: dim,
            table: name,
            tableLabel: name,
            sql: `\${TABLE}.${dim}`,
            hidden: false,
            index: 0,
        },
    }), {}),
    metrics: metrics.reduce((acc, metric) => ({
        ...acc,
        [metric]: {
            fieldType: field_1.FieldType.METRIC,
            type: field_1.MetricType.COUNT,
            name: metric,
            label: metric,
            table: name,
            tableLabel: name,
            sql: `COUNT(\${${metric}})`,
            hidden: false,
            index: 0,
            isAutoGenerated: false,
        },
    }), {}),
    lineageGraph: {},
    sets,
});
describe('expandFieldsWithSets', () => {
    describe('Basic Expansion', () => {
        it('should expand a simple set reference', () => {
            const table = createMockTable('orders', ['order_id', 'customer_id', 'total'], ['count'], {
                basic_fields: {
                    fields: ['order_id', 'customer_id'],
                },
            });
            const result = (0, fieldSetExpander_1.expandFieldsWithSets)(['basic_fields*'], table);
            expect(result).toEqual(['order_id', 'customer_id']);
        });
        it('should pass through regular field references unchanged', () => {
            const table = createMockTable('orders', ['order_id', 'customer_id'], []);
            const result = (0, fieldSetExpander_1.expandFieldsWithSets)(['order_id', 'customer_id'], table);
            expect(result).toEqual(['order_id', 'customer_id']);
        });
        it('should mix set references and regular fields', () => {
            const table = createMockTable('orders', ['order_id', 'customer_id', 'created_at', 'total'], [], {
                id_fields: {
                    fields: ['order_id', 'customer_id'],
                },
            });
            const result = (0, fieldSetExpander_1.expandFieldsWithSets)(['id_fields*', 'created_at', 'total'], table);
            expect(result).toEqual([
                'order_id',
                'customer_id',
                'created_at',
                'total',
            ]);
        });
    });
    describe('Exclusions', () => {
        it('should exclude fields with - prefix', () => {
            const table = createMockTable('orders', ['order_id', 'customer_id', 'total', 'tax'], [], {
                all_fields: {
                    fields: ['order_id', 'customer_id', 'total', 'tax'],
                },
            });
            const result = (0, fieldSetExpander_1.expandFieldsWithSets)(['all_fields*', '-tax'], table);
            expect(result).toEqual(['order_id', 'customer_id', 'total']);
        });
        it('should handle multiple exclusions', () => {
            const table = createMockTable('orders', ['a', 'b', 'c', 'd', 'e'], [], {
                all_fields: {
                    fields: ['a', 'b', 'c', 'd', 'e'],
                },
            });
            const result = (0, fieldSetExpander_1.expandFieldsWithSets)(['all_fields*', '-b', '-d'], table);
            expect(result).toEqual(['a', 'c', 'e']);
        });
        it('handles nested exclusions', () => {
            const table = createMockTable('orders', ['a', 'b', 'c', 'd', 'e'], [], {
                base_fields: {
                    fields: ['a', 'b', 'c'],
                },
                all_fields: {
                    fields: ['base_fields*', '-c'],
                },
            });
            const result = (0, fieldSetExpander_1.expandFieldsWithSets)(['all_fields*'], table);
            expect(result).toEqual(['a', 'b']);
        });
        it('should preserve order when excluding', () => {
            const table = createMockTable('orders', ['created_at', 'order_id', 'customer_id', 'updated_at'], [], {
                middle_fields: {
                    fields: ['order_id', 'customer_id'],
                },
            });
            const result = (0, fieldSetExpander_1.expandFieldsWithSets)(['created_at', 'middle_fields*', 'updated_at', '-customer_id'], table);
            expect(result).toEqual(['created_at', 'order_id', 'updated_at']);
        });
    });
    describe('Nested Sets', () => {
        it('should expand nested set references (up to 3 levels)', () => {
            const table = createMockTable('orders', ['a', 'b', 'c', 'd'], [], {
                level1: { fields: ['a'] },
                level2: { fields: ['level1*', 'b'] },
                level3a: { fields: ['level2*', 'c'] },
                level3b: { fields: ['level2*', '-a'] },
            });
            const result = (0, fieldSetExpander_1.expandFieldsWithSets)(['level3a*'], table);
            expect(result).toEqual(['a', 'b', 'c']);
            const result2 = (0, fieldSetExpander_1.expandFieldsWithSets)(['level3b*'], table);
            expect(result2).toEqual(['b']);
        });
        it('should throw error for sets with more than 3 levels of nesting', () => {
            const table = createMockTable('orders', ['a', 'b', 'c', 'd'], [], {
                level1: { fields: ['a'] },
                level2: { fields: ['level1*', 'b'] },
                level3: { fields: ['level2*', 'c'] },
                level4: { fields: ['level3*', 'd'] },
            });
            expect(() => (0, fieldSetExpander_1.expandFieldsWithSets)(['level4*'], table)).toThrow(/Only up to 3 levels of nesting are allowed/);
        });
    });
    describe('Error Handling', () => {
        it('should throw error for non-existent set', () => {
            const table = createMockTable('orders', ['order_id'], []);
            expect(() => (0, fieldSetExpander_1.expandFieldsWithSets)(['nonexistent_set*'], table)).toThrow(/Set "nonexistent_set" not found/);
        });
        it('should detect direct circular references', () => {
            const table = createMockTable('orders', ['field1'], [], {
                set_a: { fields: ['set_b*'] },
                set_b: { fields: ['set_a*'] },
            });
            expect(() => (0, fieldSetExpander_1.expandFieldsWithSets)(['set_a*'], table)).toThrow(/Circular reference detected/);
        });
    });
    describe('Deduplication', () => {
        it('should deduplicate fields from multiple sets', () => {
            const table = createMockTable('orders', ['order_id', 'customer_id', 'total'], [], {
                set1: { fields: ['order_id', 'customer_id'] },
                set2: { fields: ['customer_id', 'total'] },
            });
            const result = (0, fieldSetExpander_1.expandFieldsWithSets)(['set1*', 'set2*'], table);
            expect(result).toEqual(['order_id', 'customer_id', 'total']);
        });
        it('should not duplicate explicitly listed fields', () => {
            const table = createMockTable('orders', ['order_id', 'customer_id'], [], {
                id_fields: { fields: ['order_id', 'customer_id'] },
            });
            const result = (0, fieldSetExpander_1.expandFieldsWithSets)(['order_id', 'id_fields*'], table);
            expect(result).toEqual(['order_id', 'customer_id']);
        });
    });
    describe('Empty Sets', () => {
        it('should handle empty field list', () => {
            const table = createMockTable('orders', ['order_id'], []);
            const result = (0, fieldSetExpander_1.expandFieldsWithSets)([], table);
            expect(result).toEqual([]);
        });
        it('should handle only exclusions', () => {
            const table = createMockTable('orders', ['order_id'], []);
            const result = (0, fieldSetExpander_1.expandFieldsWithSets)(['-order_id'], table);
            expect(result).toEqual([]);
        });
    });
});
//# sourceMappingURL=fieldSetExpander.test.js.map