Files
topola-viewer/src/util/gedcom_util.spec.ts
Przemek Więch 8202c9cd05 Improve code quality
Fix lint warnings
2026-05-11 18:06:31 +02:00

191 lines
4.5 KiB
TypeScript

import {describe, expect, it} from '@jest/globals';
import {JsonGedcomData} from 'topola';
import {
findRelationshipPath,
getAncestors,
getDescendants,
getName,
idToFamMap,
idToIndiMap,
normalizeGedcom,
} from './gedcom_util';
describe('normalizeGedcom()', () => {
it('sorts children', () => {
const data = {
indis: [
{
id: 'I3',
birth: {date: {year: 1901}},
famc: 'F1',
},
{
id: 'I2',
birth: {date: {year: 1902, month: 7}},
famc: 'F1',
},
{
id: 'I1',
birth: {date: {year: 1902, month: 8}},
famc: 'F1',
},
],
fams: [
{
id: 'F1',
children: ['I1', 'I2', 'I3'],
},
],
};
const normalized = normalizeGedcom(data);
expect(normalized.fams[0].children).toEqual(['I3', 'I2', 'I1']);
});
it('sorts spouses', () => {
const data = {
indis: [
{id: 'I1', fams: ['F1']},
{id: 'I2', fams: ['F2']},
{id: 'I3', fams: ['F3']},
{id: 'I4', fams: ['F1', 'F2', 'F3']},
],
fams: [
{
id: 'F3',
marriage: {date: {year: 1901}},
husband: 'I4',
wife: 'I3',
},
{
id: 'F2',
marriage: {date: {year: 1902, month: 7}},
husband: 'I4',
wife: 'I2',
},
{
id: 'F1',
marriage: {date: {year: 1902, month: 8}},
husband: 'I4',
wife: 'I1',
},
],
};
const normalized = normalizeGedcom(data);
expect(normalized.indis.find((i) => i.id === 'I4')?.fams).toEqual([
'F3',
'F2',
'F1',
]);
});
});
describe('getName()', () => {
it('returns undefined with no name available', () => {
const person = {
level: 1,
pointer: '',
tag: 'INDI',
data: '',
tree: [],
};
expect(getName(person)).toBe(undefined);
});
it('returns first name available', () => {
const person = {
level: 1,
pointer: '',
tag: 'INDI',
data: '',
tree: [
{level: 2, pointer: '', tag: 'NAME', data: 'First /Name/', tree: []},
{level: 2, pointer: '', tag: 'NAME', data: 'Second /Name/', tree: []},
],
};
expect(getName(person)).toBe('First Name');
});
it('prefers a name without TYPE=married', () => {
const person = {
level: 1,
pointer: '',
tag: 'INDI',
data: '',
tree: [
{
level: 2,
pointer: '',
tag: 'NAME',
data: 'First /Name/',
tree: [
{level: 3, pointer: '', tag: 'TYPE', data: 'married', tree: []},
],
},
{level: 2, pointer: '', tag: 'NAME', data: 'Second /Name/', tree: []},
],
};
expect(getName(person)).toBe('Second Name');
});
it('picks a TYPE=married name if no other is available', () => {
const person = {
level: 1,
pointer: '',
tag: 'INDI',
data: '',
tree: [
{
level: 2,
pointer: '',
tag: 'NAME',
data: 'Only /Name/',
tree: [
{level: 3, pointer: '', tag: 'TYPE', data: 'married', tree: []},
],
},
],
};
expect(getName(person)).toBe('Only Name');
});
});
describe('Relationship algorithms', () => {
const sampleData: JsonGedcomData = {
indis: [
{id: 'I1', fams: ['F1']},
{id: 'I2', fams: ['F1'], famc: 'F2'},
{id: 'I3', famc: 'F1'},
{id: 'I4', famc: 'F2'},
],
fams: [
{id: 'F1', husb: 'I1', wife: 'I2', children: ['I3']},
{id: 'F2', children: ['I2', 'I4']},
],
};
const indiMap = idToIndiMap(sampleData);
const famMap = idToFamMap(sampleData);
it('findRelationshipPath finds direct paths', () => {
const path = findRelationshipPath('I1', 'I3', indiMap, famMap);
expect(path).toEqual(['I1', 'I3']);
});
it('findRelationshipPath finds sibling paths', () => {
const path = findRelationshipPath('I2', 'I4', indiMap, famMap);
expect(path).toEqual(['I2', 'I4']);
});
it('getAncestors respects generations bounds', () => {
const ancestors = getAncestors('I3', 1, indiMap, famMap);
expect(ancestors).toContain('I1');
expect(ancestors).toContain('I2');
expect(ancestors).not.toContain('I4');
});
it('getDescendants respects generations bounds', () => {
const descendants = getDescendants('I2', 1, indiMap, famMap);
expect(descendants).toContain('I3');
});
});