kopia lustrzana https://github.com/transitive-bullshit/chatgpt-api
244 wiersze
7.2 KiB
TypeScript
244 wiersze
7.2 KiB
TypeScript
import test from 'ava'
|
|
import { z } from 'zod'
|
|
|
|
import {
|
|
parseArrayOutput,
|
|
parseBooleanOutput,
|
|
parseNumberOutput,
|
|
parseObjectOutput,
|
|
parseOutput
|
|
} from '@/llms/parse-output'
|
|
|
|
test('parseArrayOutput - handles valid arrays correctly', (t) => {
|
|
const output1 = parseArrayOutput('[1,2,3]')
|
|
const output2 = parseArrayOutput('["a", "b", "c"]')
|
|
const output3 = parseArrayOutput('[{"a": 1}, {"b": 2}]')
|
|
|
|
t.snapshot(output1, 'should return [1, 2, 3] for "[1,2,3]"')
|
|
t.snapshot(output2, 'should return ["a", "b", "c"] for "["a", "b", "c"]')
|
|
t.snapshot(
|
|
output3,
|
|
'should return [{"a": 1}, {"b": 2}] for [{"a": 1}, {"b": 2}]'
|
|
)
|
|
})
|
|
|
|
test('parseArrayOutput - handles arrays surrounded by text correctly', (t) => {
|
|
const output1 = parseArrayOutput('The array is [1,2,3]')
|
|
const output2 = parseArrayOutput('Array: ["a", "b", "c"]. That\'s all!')
|
|
const output3 = parseArrayOutput(
|
|
'This is the array [{"a": 1}, {"b": 2}] in the text'
|
|
)
|
|
|
|
t.snapshot(output1, 'should return [1, 2, 3] for "The array is [1,2,3]"')
|
|
t.snapshot(
|
|
output2,
|
|
'should return ["a", "b", "c"] for "Array: ["a", "b", "c"]. That\'s all!"'
|
|
)
|
|
t.snapshot(
|
|
output3,
|
|
'should return [{"a": 1}, {"b": 2}] for "This is the array [{"a": 1}, {"b": 2}] in the text"'
|
|
)
|
|
})
|
|
|
|
test('parseArrayOutput - handles and repairs broken JSON arrays correctly', (t) => {
|
|
const output1 = parseArrayOutput('[1, "two, 3]')
|
|
const output2 = parseArrayOutput('Array: ["a, "b", "c"]. Error here!')
|
|
const output3 = parseArrayOutput('Array in text {"arr": ["value1, "value2"]}')
|
|
|
|
t.snapshot(output1, 'should repair and return [1, "two", 3] for [1, "two, 3]')
|
|
t.snapshot(
|
|
output2,
|
|
'should repair and return ["a", "b", "c"] for Array: ["a, "b", "c"]. Error here!'
|
|
)
|
|
t.snapshot(
|
|
output3,
|
|
'should repair and return {"arr": ["value1", "value2"]} for Array in text {"arr": ["value1, "value2"]}'
|
|
)
|
|
})
|
|
|
|
test('parseArrayOutput - throws error for invalid arrays', (t) => {
|
|
const error = t.throws(
|
|
() => {
|
|
parseArrayOutput('not a valid array')
|
|
},
|
|
{ instanceOf: Error }
|
|
)
|
|
|
|
t.snapshot(error?.message)
|
|
})
|
|
|
|
test('parseObjectOutput - handles valid objects correctly', (t) => {
|
|
const output1 = parseObjectOutput('{"a":1,"b":2,"c":3}')
|
|
const output2 = parseObjectOutput(
|
|
'{"name":"John","age":30,"city":"New York"}'
|
|
)
|
|
|
|
t.snapshot(
|
|
output1,
|
|
'should return {"a":1,"b":2,"c":3} for {"a":1,"b":2,"c":3}'
|
|
)
|
|
t.snapshot(
|
|
output2,
|
|
'should return {"name":"John","age":30,"city":"New York"} for {"name":"John","age":30,"city":"New York"}'
|
|
)
|
|
})
|
|
|
|
test('parseObjectOutput - handles objects surrounded by text correctly', (t) => {
|
|
const output1 = parseObjectOutput('The object is {"a":1,"b":2,"c":3}')
|
|
const output2 = parseObjectOutput(
|
|
'Object: {"name":"John","age":30,"city":"New York"}. That\'s all!'
|
|
)
|
|
|
|
t.snapshot(
|
|
output1,
|
|
'should return {"a":1,"b":2,"c":3} for "The object is {"a":1,"b":2,"c":3}"'
|
|
)
|
|
t.snapshot(
|
|
output2,
|
|
'should return {"name":"John","age":30,"city":"New York"} for "Object: {"name":"John","age":30,"city":"New York"}. That\'s all!"'
|
|
)
|
|
})
|
|
|
|
test('parseObjectOutput - handles and repairs broken JSON objects correctly', (t) => {
|
|
const output1 = parseObjectOutput('{"a":1, "b":2, "c":3')
|
|
const output2 = parseObjectOutput(
|
|
'Object: {"name":"John,"age":30,"city":"New York"}. Error here!'
|
|
)
|
|
|
|
t.snapshot(
|
|
output1,
|
|
'should repair and return {"a":1, "b":2, "c":3} for {"a":1, "b":2, "c":3'
|
|
)
|
|
t.snapshot(
|
|
output2,
|
|
'should repair and return {"name":"John","age":30,"city":"New York"} for Object: {"name":"John,"age":30,"city":"New York"}. Error here!'
|
|
)
|
|
})
|
|
|
|
test('parseObjectOutput - handles JSON array of objects', (t) => {
|
|
const output = parseObjectOutput('[{"a":1,"b":2},{"c":3,"d":4}]')
|
|
|
|
t.snapshot(
|
|
output,
|
|
'should return first object {"a":1,"b":2} for [{"a":1,"b":2},{"c":3,"d":4}]'
|
|
)
|
|
})
|
|
|
|
test('parseObjectOutput - throws error for invalid objects', (t) => {
|
|
const error = t.throws(
|
|
() => {
|
|
parseObjectOutput('not a valid object')
|
|
},
|
|
{ instanceOf: Error }
|
|
)
|
|
|
|
t.snapshot(error?.message)
|
|
})
|
|
|
|
test('parseBooleanOutput - handles `true` outputs correctly', (t) => {
|
|
const output1 = parseBooleanOutput('True')
|
|
const output2 = parseBooleanOutput('TRUE')
|
|
const output3 = parseBooleanOutput('true.')
|
|
|
|
t.snapshot(output1, 'should return true for "True"')
|
|
t.snapshot(output2, 'should return true for "TRUE"')
|
|
t.snapshot(output3, 'should return true for "true."')
|
|
})
|
|
|
|
test('parseBooleanOutput - handles `false` outputs correctly', (t) => {
|
|
const output1 = parseBooleanOutput('False')
|
|
const output2 = parseBooleanOutput('FALSE')
|
|
const output3 = parseBooleanOutput('false!')
|
|
|
|
t.snapshot(output1, 'should return false for "False"')
|
|
t.snapshot(output2, 'should return false for "FALSE"')
|
|
t.snapshot(output3, 'should return false for "false!"')
|
|
})
|
|
|
|
test('parseBooleanOutput - throws error for invalid outputs', (t) => {
|
|
const error = t.throws(
|
|
() => {
|
|
parseBooleanOutput('NotBooleanValue')
|
|
},
|
|
{ instanceOf: Error }
|
|
)
|
|
|
|
t.snapshot(error?.message)
|
|
})
|
|
|
|
test('parseNumberOutput - handles integer outputs correctly', (t) => {
|
|
const output1 = parseNumberOutput('42', z.number().int())
|
|
const output2 = parseNumberOutput(' -5 ', z.number().int())
|
|
|
|
t.snapshot(output1, 'should return 42 for "42"')
|
|
t.snapshot(output2, 'should return -5 for " -5 "')
|
|
})
|
|
|
|
test('parseNumberOutput - handles float outputs correctly', (t) => {
|
|
const output1 = parseNumberOutput('42.42', z.number())
|
|
const output2 = parseNumberOutput(' -5.5 ', z.number())
|
|
|
|
t.snapshot(output1, 'should return 42.42 for "42.42"')
|
|
t.snapshot(output2, 'should return -5.5 for " -5.5 "')
|
|
})
|
|
|
|
test('parseNumberOutput - throws error for invalid outputs', (t) => {
|
|
const error = t.throws(
|
|
() => {
|
|
parseNumberOutput('NotANumber', z.number())
|
|
},
|
|
{ instanceOf: Error }
|
|
)
|
|
|
|
t.snapshot(error?.message)
|
|
})
|
|
|
|
test('parseOutput - handles arrays correctly', (t) => {
|
|
const arraySchema = z.array(z.number())
|
|
const output = '[1, 2, 3]'
|
|
const result = parseOutput(output, arraySchema)
|
|
|
|
t.snapshot(result, 'should parse and return [1, 2, 3] for "[1, 2, 3]"')
|
|
})
|
|
|
|
test('parseOutput - handles objects correctly', (t) => {
|
|
const objectSchema = z.object({ a: z.number(), b: z.string() })
|
|
const output = '{"a": 1, "b": "two"}'
|
|
const result = parseOutput(output, objectSchema)
|
|
|
|
t.snapshot(
|
|
result,
|
|
'should parse and return {"a": 1, "b": "two"} for "{"a": 1, "b": "two"}"'
|
|
)
|
|
})
|
|
|
|
test('parseOutput - handles booleans correctly', (t) => {
|
|
const booleanSchema = z.boolean()
|
|
const output = 'True'
|
|
const result = parseOutput(output, booleanSchema)
|
|
|
|
t.snapshot(result, 'should parse and return true for "True"')
|
|
})
|
|
|
|
test('parseOutput - handles numbers correctly', (t) => {
|
|
const numberSchema = z.number()
|
|
const output = '123.45'
|
|
const result = parseOutput(output, numberSchema)
|
|
|
|
t.snapshot(result, 'should parse and return 123.45 for "123.45"')
|
|
})
|
|
|
|
test('parseOutput - throws error for invalid data', (t) => {
|
|
const numberSchema = z.number()
|
|
const output = 'not a number'
|
|
|
|
const error = t.throws(
|
|
() => {
|
|
parseOutput(output, numberSchema)
|
|
},
|
|
{ instanceOf: Error }
|
|
)
|
|
|
|
t.snapshot(error?.message)
|
|
})
|