"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const migrate_1 = require("../../src/migrate");
const evalResult_1 = __importDefault(require("../../src/models/evalResult"));
const utils_1 = require("../../src/prompts/utils");
const types_1 = require("../../src/types");
const json_1 = require("../../src/util/json");
describe('EvalResult', () => {
    beforeAll(async () => {
        await (0, migrate_1.runDbMigrations)();
    });
    const mockProvider = {
        id: 'test-provider',
        label: 'Test Provider',
    };
    const mockTestCase = {
        vars: {},
        provider: mockProvider,
    };
    const mockPrompt = {
        raw: 'Test prompt',
        display: 'Test prompt',
        label: 'Test label',
    };
    const mockEvaluateResult = {
        promptIdx: 0,
        testIdx: 0,
        prompt: mockPrompt,
        success: true,
        score: 1,
        provider: mockProvider,
        testCase: mockTestCase,
        vars: {},
        latencyMs: 100,
        cost: 0.01,
        metadata: {},
        failureReason: types_1.ResultFailureReason.NONE,
        id: 'test-id',
        promptId: (0, utils_1.hashPrompt)(mockPrompt),
        namedScores: {},
        response: undefined,
    };
    describe('createFromEvaluateResult', () => {
        it('should create and persist an EvalResult', async () => {
            const evalId = 'test-eval-id';
            const result = await evalResult_1.default.createFromEvaluateResult(evalId, mockEvaluateResult, mockTestCase);
            expect(result).toBeInstanceOf(evalResult_1.default);
            expect(result.evalId).toBe(evalId);
            expect(result.promptId).toBe((0, utils_1.hashPrompt)(mockPrompt));
            expect(result.persisted).toBe(true);
            // Verify it was persisted to database
            const retrieved = await evalResult_1.default.findById(result.id);
            expect(retrieved).not.toBeNull();
            expect(retrieved?.score).toBe(mockEvaluateResult.score);
        });
        it('should create without persisting when persist option is false', async () => {
            const evalId = 'test-eval-id';
            const result = await evalResult_1.default.createFromEvaluateResult(evalId, mockEvaluateResult, mockTestCase, { persist: false });
            expect(result).toBeInstanceOf(evalResult_1.default);
            expect(result.persisted).toBe(false);
            // Verify it was not persisted to database
            const retrieved = await evalResult_1.default.findById(result.id);
            expect(retrieved).toBeNull();
        });
        it('should properly handle circular references in provider', async () => {
            const evalId = 'test-eval-id';
            // Create a provider with a circular reference
            const circularProvider = {
                id: 'test-provider',
                label: 'Test Provider',
                config: {
                    circular: undefined,
                },
            };
            circularProvider.config.circular = circularProvider;
            const testCaseWithCircular = {
                ...mockTestCase,
                provider: circularProvider,
            };
            // Pre-serialize the provider to handle circular references
            const serializedProvider = JSON.parse((0, json_1.safeJsonStringify)(circularProvider));
            const resultWithCircular = await evalResult_1.default.createFromEvaluateResult(evalId, {
                ...mockEvaluateResult,
                provider: serializedProvider, // Use pre-serialized provider
            }, {
                ...testCaseWithCircular,
                provider: serializedProvider, // Use pre-serialized provider
            }, { persist: true });
            // Verify the provider was properly serialized
            expect(resultWithCircular.testCase.provider).toEqual({
                id: 'test-provider',
                label: 'Test Provider',
                config: {},
            });
            // Verify it can be persisted without errors
            const retrieved = await evalResult_1.default.findById(resultWithCircular.id);
            expect(retrieved).not.toBeNull();
            expect(retrieved?.testCase.provider).toEqual({
                id: 'test-provider',
                label: 'Test Provider',
                config: {},
            });
        });
        it('should preserve non-circular provider properties', async () => {
            const evalId = 'test-eval-id';
            const providerWithNestedData = {
                id: 'test-provider',
                label: 'Test Provider',
                config: {
                    apiKey: 'secret-key',
                    options: {
                        temperature: 0.7,
                        maxTokens: 100,
                    },
                },
            };
            const testCaseWithNestedData = {
                ...mockTestCase,
                provider: providerWithNestedData,
            };
            const result = await evalResult_1.default.createFromEvaluateResult(evalId, {
                ...mockEvaluateResult,
                provider: providerWithNestedData,
            }, testCaseWithNestedData, { persist: true });
            // Verify nested properties are preserved
            expect(result.testCase.provider).toEqual(providerWithNestedData);
            // Verify it can be persisted and retrieved with all properties intact
            const retrieved = await evalResult_1.default.findById(result.id);
            expect(retrieved).not.toBeNull();
            expect(retrieved?.testCase.provider).toEqual(providerWithNestedData);
        });
    });
    describe('findManyByEvalId', () => {
        it('should retrieve multiple results for an eval ID', async () => {
            const evalId = 'test-eval-id-multiple';
            // Create multiple results
            await evalResult_1.default.createFromEvaluateResult(evalId, {
                ...mockEvaluateResult,
                testIdx: 0,
            }, mockTestCase);
            await evalResult_1.default.createFromEvaluateResult(evalId, {
                ...mockEvaluateResult,
                testIdx: 1,
            }, mockTestCase);
            const results = await evalResult_1.default.findManyByEvalId(evalId);
            expect(results).toHaveLength(2);
            expect(results[0]).toBeInstanceOf(evalResult_1.default);
            expect(results[1]).toBeInstanceOf(evalResult_1.default);
        });
        it('should filter by testIdx when provided', async () => {
            const evalId = 'test-eval-id-filter';
            await evalResult_1.default.createFromEvaluateResult(evalId, {
                ...mockEvaluateResult,
                testIdx: 0,
            }, mockTestCase);
            await evalResult_1.default.createFromEvaluateResult(evalId, {
                ...mockEvaluateResult,
                testIdx: 1,
            }, mockTestCase);
            const results = await evalResult_1.default.findManyByEvalId(evalId, { testIdx: 0 });
            expect(results).toHaveLength(1);
            expect(results[0].testIdx).toBe(0);
        });
    });
    describe('save', () => {
        it('should save new results', async () => {
            const result = new evalResult_1.default({
                id: 'test-save-id',
                evalId: 'test-eval-id',
                promptIdx: 0,
                testIdx: 0,
                testCase: mockTestCase,
                prompt: mockPrompt,
                success: true,
                score: 1,
                response: null,
                gradingResult: null,
                provider: mockProvider,
                failureReason: types_1.ResultFailureReason.NONE,
                namedScores: {},
            });
            await result.save();
            expect(result.persisted).toBe(true);
            const retrieved = await evalResult_1.default.findById(result.id);
            expect(retrieved).not.toBeNull();
        });
        it('should update existing results', async () => {
            const result = await evalResult_1.default.createFromEvaluateResult('test-eval-id', mockEvaluateResult, mockTestCase);
            result.score = 0.5;
            await result.save();
            const retrieved = await evalResult_1.default.findById(result.id);
            expect(retrieved?.score).toBe(0.5);
        });
    });
    describe('toEvaluateResult', () => {
        it('should convert EvalResult to EvaluateResult format', async () => {
            const result = await evalResult_1.default.createFromEvaluateResult('test-eval-id', mockEvaluateResult, mockTestCase);
            const evaluateResult = result.toEvaluateResult();
            // Only test the specific fields we care about
            expect(evaluateResult).toEqual(expect.objectContaining({
                promptIdx: mockEvaluateResult.promptIdx,
                testIdx: mockEvaluateResult.testIdx,
                prompt: mockEvaluateResult.prompt,
                success: mockEvaluateResult.success,
                score: mockEvaluateResult.score,
                provider: {
                    id: mockProvider.id,
                    label: mockProvider.label,
                },
            }));
        });
    });
});
//# sourceMappingURL=evalResult.test.js.map