Skip to main content
Glama
Arize-ai

@arizeai/phoenix-mcp

Official
by Arize-ai
asEvaluatorFn.test.ts11.7 kB
import { asEvaluatorFn } from "../../src/helpers/asEvaluatorFn"; import { EvaluationResult } from "../../src/types"; import { describe, expect, it } from "vitest"; type TestRecord = { input: string; output: string; [key: string]: unknown; }; describe("asEvaluatorFn", () => { describe("synchronous functions", () => { it("should convert a sync function returning a number to an evaluator function", async () => { const fn = ({ output, expected, }: { output: string; expected: string; }) => { return output === expected ? 1 : 0; }; const evaluatorFn = asEvaluatorFn<TestRecord>(fn); const result = await evaluatorFn({ input: "test", output: "correct", expected: "correct", }); expect(result).toEqual({ score: 1 }); }); it("should convert a sync function returning 0 to an evaluator function", async () => { const fn = ({ output, expected, }: { output: string; expected: string; }) => { return output === expected ? 1 : 0; }; const evaluatorFn = asEvaluatorFn<TestRecord>(fn); const result = await evaluatorFn({ input: "test", output: "wrong", expected: "correct", }); expect(result).toEqual({ score: 0 }); }); it("should convert a sync function returning an EvaluationResult object", async () => { const fn = (_record: TestRecord): EvaluationResult => { return { score: 0.95, label: "high", explanation: "The output is of high quality", }; }; const evaluatorFn = asEvaluatorFn<TestRecord>(fn); const result = await evaluatorFn({ input: "test", output: "some output", }); expect(result).toEqual({ score: 0.95, label: "high", explanation: "The output is of high quality", }); }); it("should convert a sync function returning a string (label)", async () => { const fn = ({ output }: { output: string }) => { return output.length > 10 ? "long" : "short"; }; const evaluatorFn = asEvaluatorFn<TestRecord>(fn); const result = await evaluatorFn({ input: "test", output: "very long output text", }); expect(result).toEqual({ label: "long" }); }); it("should convert a sync function returning an object with score only", async () => { const fn = (_record: TestRecord) => { return { score: 0.8 }; }; const evaluatorFn = asEvaluatorFn<TestRecord>(fn); const result = await evaluatorFn({ input: "test", output: "some output", }); expect(result).toEqual({ score: 0.8 }); }); it("should convert a sync function returning an object with label only", async () => { const fn = (_record: TestRecord) => { return { label: "pass" }; }; const evaluatorFn = asEvaluatorFn<TestRecord>(fn); const result = await evaluatorFn({ input: "test", output: "some output", }); expect(result).toEqual({ label: "pass" }); }); it("should convert a sync function returning an object with explanation only", async () => { const fn = (_record: TestRecord) => { return { explanation: "This is a test explanation" }; }; const evaluatorFn = asEvaluatorFn<TestRecord>(fn); const result = await evaluatorFn({ input: "test", output: "some output", }); expect(result).toEqual({ explanation: "This is a test explanation" }); }); it("should handle a sync function returning null", async () => { const fn = () => null; const evaluatorFn = asEvaluatorFn<TestRecord>(fn); const result = await evaluatorFn({ input: "test", output: "some output", }); expect(result).toEqual({}); }); it("should handle a sync function returning undefined", async () => { const fn = () => undefined; const evaluatorFn = asEvaluatorFn<TestRecord>(fn); const result = await evaluatorFn({ input: "test", output: "some output", }); expect(result).toEqual({}); }); it("should handle a sync function returning an empty object", async () => { const fn = () => ({}); const evaluatorFn = asEvaluatorFn<TestRecord>(fn); const result = await evaluatorFn({ input: "test", output: "some output", }); expect(result).toEqual({}); }); }); describe("asynchronous functions", () => { it("should convert an async function returning a number to an evaluator function", async () => { const fn = async ({ output, expected, }: { output: string; expected: string; }) => { await new Promise((resolve) => setTimeout(resolve, 10)); return output === expected ? 1 : 0; }; const evaluatorFn = asEvaluatorFn<TestRecord>(fn); const result = await evaluatorFn({ input: "test", output: "correct", expected: "correct", }); expect(result).toEqual({ score: 1 }); }); it("should convert an async function returning an EvaluationResult object", async () => { const fn = async (_record: TestRecord): Promise<EvaluationResult> => { await new Promise((resolve) => setTimeout(resolve, 10)); return { score: 0.85, label: "medium", explanation: "The output quality is medium", }; }; const evaluatorFn = asEvaluatorFn<TestRecord>(fn); const result = await evaluatorFn({ input: "test", output: "some output", }); expect(result).toEqual({ score: 0.85, label: "medium", explanation: "The output quality is medium", }); }); it("should convert an async function returning a string (label)", async () => { const fn = async ({ output }: { output: string }) => { await new Promise((resolve) => setTimeout(resolve, 10)); return output.length > 5 ? "long" : "short"; }; const evaluatorFn = asEvaluatorFn<TestRecord>(fn); const result = await evaluatorFn({ input: "test", output: "very long output", }); expect(result).toEqual({ label: "long" }); }); it("should handle an async function that throws an error", async () => { const fn = async () => { throw new Error("Test error"); }; const evaluatorFn = asEvaluatorFn<TestRecord>(fn); await expect( evaluatorFn({ input: "test", output: "some output", }) ).rejects.toThrow("Test error"); }); }); describe("function arguments", () => { it("should pass the record argument to the original function", async () => { const fn = (record: TestRecord) => { return record.output === "expected" ? 1 : 0; }; const evaluatorFn = asEvaluatorFn<TestRecord>(fn); const result1 = await evaluatorFn({ input: "test", output: "expected", }); expect(result1).toEqual({ score: 1 }); const result2 = await evaluatorFn({ input: "test", output: "unexpected", }); expect(result2).toEqual({ score: 0 }); }); it("should handle functions with no parameters", async () => { const fn = () => 42; const evaluatorFn = asEvaluatorFn<TestRecord>(fn); const result = await evaluatorFn({ input: "test", output: "some output", }); expect(result).toEqual({ score: 42 }); }); }); describe("edge cases", () => { it("should handle a function returning a negative number", async () => { const fn = () => -1; const evaluatorFn = asEvaluatorFn<TestRecord>(fn); const result = await evaluatorFn({ input: "test", output: "some output", }); expect(result).toEqual({ score: -1 }); }); it("should handle a function returning a floating point number", async () => { const fn = () => 0.123456789; const evaluatorFn = asEvaluatorFn<TestRecord>(fn); const result = await evaluatorFn({ input: "test", output: "some output", }); expect(result).toEqual({ score: 0.123456789 }); }); it("should handle a function returning Infinity", async () => { const fn = () => Infinity; const evaluatorFn = asEvaluatorFn<TestRecord>(fn); const result = await evaluatorFn({ input: "test", output: "some output", }); expect(result).toEqual({ score: Infinity }); }); it("should handle a function returning NaN", async () => { const fn = () => NaN; const evaluatorFn = asEvaluatorFn<TestRecord>(fn); const result = await evaluatorFn({ input: "test", output: "some output", }); expect(result).toEqual({ score: NaN }); }); it("should handle a function returning an object with all EvaluationResult fields", async () => { const fn = () => ({ score: 0.9, label: "excellent", explanation: "Perfect output", }); const evaluatorFn = asEvaluatorFn<TestRecord>(fn); const result = await evaluatorFn({ input: "test", output: "some output", }); expect(result).toEqual({ score: 0.9, label: "excellent", explanation: "Perfect output", }); }); it("should handle a function returning an object with extra fields", async () => { const fn = () => ({ score: 0.8, label: "good", extraField: "this should be ignored", anotherField: 123, }); const evaluatorFn = asEvaluatorFn<TestRecord>(fn); const result = await evaluatorFn({ input: "test", output: "some output", }); // Only EvaluationResult fields should be included expect(result).toEqual({ score: 0.8, label: "good", }); expect(result).not.toHaveProperty("extraField"); expect(result).not.toHaveProperty("anotherField"); }); it("should handle a function returning a boolean (converted to empty result)", async () => { const fn = () => true; const evaluatorFn = asEvaluatorFn<TestRecord>(fn); const result = await evaluatorFn({ input: "test", output: "some output", }); expect(result).toEqual({}); }); it("should handle a function returning an array (converted to empty result)", async () => { const fn = () => [1, 2, 3]; const evaluatorFn = asEvaluatorFn<TestRecord>(fn); const result = await evaluatorFn({ input: "test", output: "some output", }); expect(result).toEqual({}); }); }); describe("return type", () => { it("should always return a Promise", () => { const fn = () => 1; const evaluatorFn = asEvaluatorFn<TestRecord>(fn); const result = evaluatorFn({ input: "test", output: "some output", }); expect(result).toBeInstanceOf(Promise); }); it("should return a Promise that resolves to EvaluationResult", async () => { const fn = () => ({ score: 0.5 }); const evaluatorFn = asEvaluatorFn<TestRecord>(fn); const result = await evaluatorFn({ input: "test", output: "some output", }); expect(result).toHaveProperty("score"); expect(typeof result.score).toBe("number"); }); }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Arize-ai/phoenix'

If you have feedback or need assistance with the MCP directory API, please join our Discord server