-
Notifications
You must be signed in to change notification settings - Fork 85
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: added tests for field extraction functions
- Loading branch information
Showing
4 changed files
with
228 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import test from 'ava'; | ||
|
||
import { parseLLMFriendlyDate, parseLLMFriendlyDateTime } from './datetime.js'; | ||
import type { AxField } from './sig.js'; | ||
|
||
const field: AxField = { | ||
name: 'date', | ||
type: { name: 'date', isArray: false } | ||
}; | ||
|
||
test('datetime parsing with timezone abbr', (t) => { | ||
const dt = parseLLMFriendlyDateTime(field, '2022-01-01 12:00 EST'); | ||
t.is(dt.toUTCString(), 'Sat, 01 Jan 2022 17:00:00 GMT'); | ||
}); | ||
|
||
test('datetime parsing with seconds and timezone abbr', (t) => { | ||
const dt = parseLLMFriendlyDateTime(field, '2022-01-01 12:00:10 EST'); | ||
t.is(dt.toUTCString(), 'Sat, 01 Jan 2022 17:00:10 GMT'); | ||
}); | ||
|
||
test('datetime parsing with full timezone', (t) => { | ||
const dt = parseLLMFriendlyDateTime( | ||
field, | ||
'2022-01-01 12:00 America/New_York' | ||
); | ||
t.is(dt.toUTCString(), 'Sat, 01 Jan 2022 17:00:00 GMT'); | ||
}); | ||
|
||
test('datetime parsing: invalid datetime value', (t) => { | ||
t.throws(() => parseLLMFriendlyDateTime(field, '2022-01-01 12:00')); | ||
}); | ||
|
||
test('date parsing', (t) => { | ||
const dt = parseLLMFriendlyDate(field, '2022-01-01'); | ||
t.is(dt.toUTCString(), 'Sat, 01 Jan 2022 00:00:00 GMT'); | ||
}); | ||
|
||
test('date parsing: invalid date value', (t) => { | ||
t.throws(() => parseLLMFriendlyDate(field, '2022-01-32')); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,40 +1,200 @@ | ||
import test from 'ava'; | ||
|
||
import { parseLLMFriendlyDate, parseLLMFriendlyDateTime } from './datetime.js'; | ||
import type { AxField } from './sig.js'; | ||
import { | ||
type extractionState, | ||
extractValues, | ||
streamingExtractFinalValue, | ||
streamingExtractValues | ||
} from './extract.js'; | ||
import { AxSignature } from './sig.js'; | ||
|
||
const field: AxField = { | ||
name: 'date', | ||
type: { name: 'date', isArray: false } | ||
}; | ||
// Helper function to create a clean initial state | ||
const createInitialState = (): extractionState => ({ | ||
currField: undefined, | ||
s: -1 | ||
}); | ||
|
||
// Tests for extractValues | ||
test('extractValues: extracts single output field', (t) => { | ||
const sig = new AxSignature('inputField1 -> outputField1'); | ||
const values: Record<string, unknown> = {}; | ||
const content = 'Output Field 1:This is the output content!'; | ||
|
||
extractValues(sig, values, content); | ||
|
||
t.deepEqual(values, { outputField1: 'This is the output content!' }); | ||
}); | ||
|
||
test('datetime parsing with timezone abbr', (t) => { | ||
const dt = parseLLMFriendlyDateTime(field, '2022-01-01 12:00 EST'); | ||
t.is(dt.toUTCString(), 'Sat, 01 Jan 2022 17:00:00 GMT'); | ||
test('extractValues: extracts multiple output fields', (t) => { | ||
const sig = new AxSignature('input1, input2 -> output1, output2'); | ||
const values: Record<string, unknown> = {}; | ||
const content = `Output 1: First output content | ||
Output 2: Second\noutput\ncontent`; | ||
|
||
extractValues(sig, values, content); | ||
|
||
t.deepEqual(values, { | ||
output1: 'First output content', | ||
output2: 'Second\noutput\ncontent' | ||
}); | ||
}); | ||
|
||
test('datetime parsing with seconds and timezone abbr', (t) => { | ||
const dt = parseLLMFriendlyDateTime(field, '2022-01-01 12:00:10 EST'); | ||
t.is(dt.toUTCString(), 'Sat, 01 Jan 2022 17:00:10 GMT'); | ||
test('extractValues: preserves existing values', (t) => { | ||
const sig = new AxSignature('input1, input2 -> output1, output2'); | ||
const values: Record<string, unknown> = { | ||
output1: 'existing content' | ||
}; | ||
const content = 'Output 2: New content'; | ||
|
||
extractValues(sig, values, content); | ||
|
||
t.deepEqual(values, { | ||
output1: 'existing content', | ||
output2: 'New content' | ||
}); | ||
}); | ||
|
||
test('datetime parsing with full timezone', (t) => { | ||
const dt = parseLLMFriendlyDateTime( | ||
field, | ||
'2022-01-01 12:00 America/New_York' | ||
); | ||
t.is(dt.toUTCString(), 'Sat, 01 Jan 2022 17:00:00 GMT'); | ||
test('extractValues: handles multiline output content', (t) => { | ||
const sig = new AxSignature('input -> output1, output2'); | ||
const values: Record<string, unknown> = {}; | ||
const content = `Output 1: This is a multi-line | ||
output content for field 1 | ||
Output 2:And this is the | ||
multi-line content for field 2`; | ||
|
||
extractValues(sig, values, content); | ||
|
||
t.deepEqual(values, { | ||
output1: 'This is a multi-line\noutput content for field 1', | ||
output2: 'And this is the\nmulti-line content for field 2' | ||
}); | ||
}); | ||
|
||
// Tests for streamingExtractValues | ||
test('streamingExtractValues: handles streaming output fields', (t) => { | ||
const sig = new AxSignature('input -> output1, outputField2'); | ||
const values: Record<string, unknown> = {}; | ||
const state = createInitialState(); | ||
|
||
// First chunk | ||
let content = 'Output 1: First '; | ||
streamingExtractValues(sig, values, state, content); | ||
content += 'output content\n'; | ||
streamingExtractValues(sig, values, state, content); | ||
content += 'Output Field 2: Second '; | ||
streamingExtractValues(sig, values, state, content); | ||
content += 'output content'; | ||
streamingExtractFinalValue(values, state, content); | ||
|
||
t.deepEqual(values, { | ||
output1: 'First output content', | ||
outputField2: 'Second output content' | ||
}); | ||
}); | ||
|
||
test('streamingExtractValues: handles partial output label', (t) => { | ||
const sig = new AxSignature('input -> output1'); | ||
const values: Record<string, unknown> = {}; | ||
const state = createInitialState(); | ||
|
||
// Split in middle of "Output" label | ||
let content = 'Out'; | ||
streamingExtractValues(sig, values, state, content); | ||
content += 'put 1: Content here'; | ||
streamingExtractValues(sig, values, state, content); | ||
streamingExtractFinalValue(values, state, content); | ||
|
||
t.deepEqual(values, { | ||
output1: 'Content here' | ||
}); | ||
}); | ||
|
||
test('datetime parsing: invalid datetime value', (t) => { | ||
t.throws(() => parseLLMFriendlyDateTime(field, '2022-01-01 12:00')); | ||
test('handles multiple output occurrences', (t) => { | ||
const sig = new AxSignature('input -> output1, output2'); | ||
const values: Record<string, unknown> = {}; | ||
const content = `Output: First content | ||
Output: Updated content | ||
Output 1: Final content`; | ||
|
||
extractValues(sig, values, content); | ||
|
||
// Should use the last occurrence | ||
t.deepEqual(values, { | ||
output1: 'Final content' | ||
}); | ||
}); | ||
|
||
test('date parsing', (t) => { | ||
const dt = parseLLMFriendlyDate(field, '2022-01-01'); | ||
t.is(dt.toUTCString(), 'Sat, 01 Jan 2022 00:00:00 GMT'); | ||
test('extracts content with various output field formats', (t) => { | ||
const sig = new AxSignature('input -> custom1, custom2, custom3'); | ||
const values: Record<string, unknown> = {}; | ||
const content = `Custom 1: Generic output | ||
Custom 2: First custom output | ||
Custom 3: Another output`; | ||
|
||
extractValues(sig, values, content); | ||
|
||
t.deepEqual(values, { | ||
custom1: 'Generic output', | ||
custom2: 'First custom output', | ||
custom3: 'Another output' | ||
}); | ||
}); | ||
|
||
test('date parsing: invalid date value', (t) => { | ||
t.throws(() => parseLLMFriendlyDate(field, '2022-01-32')); | ||
test('streamingExtractValues: handles incremental content with multiple fields', (t) => { | ||
const sig = new AxSignature( | ||
'input -> outputField1, outputField2, outputField3' | ||
); | ||
const values: Record<string, unknown> = {}; | ||
const state = createInitialState(); | ||
|
||
// Send content in chunks | ||
const chunks = [ | ||
'Output Field 1: First', | ||
' content here\n', | ||
'Output Field 2: Sec', | ||
'ond content\n', | ||
'Output Field 3: Third content' | ||
]; | ||
|
||
let content = ''; | ||
|
||
for (const chunk of chunks) { | ||
content += chunk; | ||
streamingExtractValues(sig, values, state, content); | ||
} | ||
streamingExtractFinalValue(values, state, content); | ||
|
||
t.deepEqual(values, { | ||
outputField1: 'First content here', | ||
outputField2: 'Second content', | ||
outputField3: 'Third content' | ||
}); | ||
}); | ||
|
||
test('handles empty and whitespace content', (t) => { | ||
const sig = new AxSignature('input -> output1?, output2?'); | ||
const values: Record<string, unknown> = {}; | ||
const content = `Output 1: | ||
Output 2: | ||
Output: `; | ||
|
||
extractValues(sig, values, content); | ||
|
||
t.deepEqual(values, { | ||
output1: undefined, | ||
output2: 'Output:' | ||
}); | ||
}); | ||
|
||
test('error handling for malformed content', (t) => { | ||
const sig = new AxSignature('input -> output1, output2'); | ||
const values: Record<string, unknown> = {}; | ||
|
||
// Content without proper Output: prefix | ||
const malformedContent = 'Some random content without output prefix'; | ||
|
||
extractValues(sig, values, malformedContent); | ||
|
||
// Should not extract any values | ||
t.deepEqual(values, {}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters