MyKindlebox/mykindlebox/client/src/lib/ocrParse.test.js

134 lines
4.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { test } from 'node:test'
import assert from 'node:assert/strict'
import { parseCellFields, looksLikeAncestorCell } from './ocrParse.js'
// --- The three cases required by plan Step 3.5 ---
test('case 1: all five fields present and labelled', () => {
const cell = [
"Belowland's Thumper",
'Tattoo: AB12',
'DOB: 03/15/2024',
'Weight: 8 lbs 4 oz',
].join('\n')
assert.deepEqual(parseCellFields(cell), {
farmName: "Belowland's",
rabbitName: 'Thumper',
earNumber: 'AB12',
dob: '2024-03-15',
weight: 8.25,
})
})
test('case 2: only name and ear number (DOB and weight absent)', () => {
const cell = ['Clover', 'RZ7'].join('\n')
assert.deepEqual(parseCellFields(cell), {
farmName: null,
rabbitName: 'Clover',
earNumber: 'RZ7',
dob: null,
weight: null,
})
})
test('case 3: name has no possessive (rabbit name only, no farm)', () => {
const cell = ['Midnight', 'Ear #: XY99'].join('\n')
const result = parseCellFields(cell)
assert.equal(result.farmName, null)
assert.equal(result.rabbitName, 'Midnight')
assert.equal(result.earNumber, 'XY99')
})
// --- Per-field rule coverage ---
test('possessive split handles a plain "s without apostrophe-s', () => {
// "Lund Lops' Seabreeze" → farm "Lund Lops'", name "Seabreeze"
const result = parseCellFields("Lund Lops' Seabreeze")
assert.equal(result.farmName, "Lund Lops'")
assert.equal(result.rabbitName, 'Seabreeze')
})
test('weight: decimal lbs form', () => {
assert.equal(parseCellFields('Bunny\nWeight 8.5 lbs').weight, 8.5)
})
test('weight: bare number with no unit is not a weight', () => {
assert.equal(parseCellFields('Bunny\n8.5').weight, null)
})
test('dob: 2-digit year maps to 20xx and slashes/dashes both parse', () => {
assert.equal(parseCellFields('Bunny\nborn 5/9/24').dob, '2024-05-09')
assert.equal(parseCellFields('Bunny\n12-25-2023').dob, '2023-12-25')
})
test('dob: 2-digit year beyond the current-year pivot maps to 19xx', () => {
// Older slips carry 1990s ancestors; "98" must not become a future 2098 DOB.
assert.equal(parseCellFields('Bunny\nDOB: 3/15/98').dob, '1998-03-15')
})
test('dob: invalid month is rejected', () => {
assert.equal(parseCellFields('Bunny\n13/40/2024').dob, null)
})
test('dob: impossible day for the month is rejected', () => {
assert.equal(parseCellFields('Bunny\n2/31/2024').dob, null)
// 2024 is a leap year — 2/29 is real.
assert.equal(parseCellFields('Bunny\n2/29/2024').dob, '2024-02-29')
assert.equal(parseCellFields('Bunny\n2/29/2023').dob, null)
})
test('ear number: labelled value wins over a later bare token', () => {
const result = parseCellFields('Rocky\nTattoo: GH42\nREW')
assert.equal(result.earNumber, 'GH42')
})
// --- ALL-CAPS pedigrees (real-world: BASTET'S SHANGHEI etc.) ---
test('all-caps possessive splits farm from name on one line', () => {
const result = parseCellFields('BASTET’S SHANGHEI'.replace('’', "'"))
assert.equal(result.farmName, "BASTET'S")
assert.equal(result.rabbitName, 'SHANGHEI')
})
test('farm on its own line, rabbit name on the next line', () => {
const cell = ["BASTET'S", 'SHAMWOW', 'Ear #: BSHAMW', 'Weight: 3 # 15 oz'].join('\n')
const result = parseCellFields(cell)
assert.equal(result.farmName, "BASTET'S")
assert.equal(result.rabbitName, 'SHAMWOW')
assert.equal(result.earNumber, 'BSHAMW')
})
test('an all-caps name is not mistaken for a bare ear number', () => {
// "SHANGHEI" is all letters → a name, not an ear. The labelled ear wins.
const cell = ['MIDNIGHT', 'Ear #: XY99'].join('\n')
const result = parseCellFields(cell)
assert.equal(result.rabbitName, 'MIDNIGHT')
assert.equal(result.earNumber, 'XY99')
})
test('a bare all-letter token is not treated as an ear number', () => {
// No label, no digit → not an ear; it becomes the name instead.
const result = parseCellFields('SHAMWOW')
assert.equal(result.earNumber, null)
assert.equal(result.rabbitName, 'SHAMWOW')
})
test('looksLikeAncestorCell distinguishes a real cell from the form title', () => {
assert.equal(looksLikeAncestorCell("BASTET'S SHAMWOW\nEar #: BSHAMW\nWeight: 3 lbs"), true)
assert.equal(looksLikeAncestorCell("Bastet's Bunnies\nHolland Lop"), false)
assert.equal(looksLikeAncestorCell(''), false)
})
test('empty / whitespace cell yields all nulls', () => {
assert.deepEqual(parseCellFields(' \n \n'), {
farmName: null,
rabbitName: null,
earNumber: null,
dob: null,
weight: null,
})
})