Converts a raw filename into a human-readable title candidate by stripping the extension and replacing underscore/hyphen runs with spaces. Reuses the existing stripExtension() helper. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
120 lines
3.5 KiB
TypeScript
120 lines
3.5 KiB
TypeScript
import { describe, it, expect } from 'vitest';
|
|
import { parseFilename, stripExtension, bulkTitleFromFilename } from './filename';
|
|
|
|
describe('parseFilename', () => {
|
|
describe('date-first patterns', () => {
|
|
it('YYYY-MM-DD_Lastname_Firstname', () => {
|
|
expect(parseFilename('1965-03-12_Mueller_Hans.pdf')).toEqual({
|
|
dateIso: '1965-03-12',
|
|
personName: 'Hans Mueller',
|
|
suggestedTitle: 'Hans Mueller (12.03.1965)'
|
|
});
|
|
});
|
|
|
|
it('YYYYMMDD_Lastname_Firstname', () => {
|
|
expect(parseFilename('19650312_Mueller_Hans.pdf')).toEqual({
|
|
dateIso: '1965-03-12',
|
|
personName: 'Hans Mueller',
|
|
suggestedTitle: 'Hans Mueller (12.03.1965)'
|
|
});
|
|
});
|
|
|
|
it('YYYYMMDD_compound_lastname_Firstname', () => {
|
|
expect(parseFilename('18881025_de_Gruyter_Walter.pdf')).toEqual({
|
|
dateIso: '1888-10-25',
|
|
personName: 'Walter de Gruyter',
|
|
suggestedTitle: 'Walter de Gruyter (25.10.1888)'
|
|
});
|
|
});
|
|
|
|
it('handles umlauts in names', () => {
|
|
const result = parseFilename('2024-01-15_Müller_Jürgen.pdf');
|
|
expect(result.personName).toBe('Jürgen Müller');
|
|
});
|
|
});
|
|
|
|
describe('date-last patterns', () => {
|
|
it('Lastname_Firstname_YYYY-MM-DD', () => {
|
|
expect(parseFilename('Mueller_Hans_1965-03-12.pdf')).toEqual({
|
|
dateIso: '1965-03-12',
|
|
personName: 'Hans Mueller',
|
|
suggestedTitle: 'Hans Mueller (12.03.1965)'
|
|
});
|
|
});
|
|
|
|
it('Lastname_Firstname_YYYYMMDD', () => {
|
|
expect(parseFilename('Mueller_Hans_19650312.pdf')).toEqual({
|
|
dateIso: '1965-03-12',
|
|
personName: 'Hans Mueller',
|
|
suggestedTitle: 'Hans Mueller (12.03.1965)'
|
|
});
|
|
});
|
|
|
|
it('compound_lastname_Firstname_YYYYMMDD', () => {
|
|
expect(parseFilename('de_Gruyter_Walter_18881025.pdf')).toEqual({
|
|
dateIso: '1888-10-25',
|
|
personName: 'Walter de Gruyter',
|
|
suggestedTitle: 'Walter de Gruyter (25.10.1888)'
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('non-matching filenames', () => {
|
|
it('returns empty for date-only filename', () => {
|
|
expect(parseFilename('1965-03-12.pdf')).toEqual({});
|
|
});
|
|
|
|
it('returns empty for two segments with no date', () => {
|
|
expect(parseFilename('Mueller_Hans.pdf')).toEqual({});
|
|
});
|
|
|
|
it('returns empty for unstructured filename', () => {
|
|
expect(parseFilename('scan_001.pdf')).toEqual({});
|
|
});
|
|
|
|
it('returns empty for three name segments with no date', () => {
|
|
expect(parseFilename('Mueller_Hans_Juergen.pdf')).toEqual({});
|
|
});
|
|
|
|
it('returns empty for filename without extension', () => {
|
|
expect(parseFilename('1965-03-12_Mueller_Hans')).toEqual({});
|
|
});
|
|
|
|
it('rejects implausible date (month 13)', () => {
|
|
expect(parseFilename('19651345_Mueller_Hans.pdf')).toEqual({});
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('bulkTitleFromFilename', () => {
|
|
it('replaces underscores with spaces', () => {
|
|
expect(bulkTitleFromFilename('hello_world.pdf')).toBe('hello world');
|
|
});
|
|
|
|
it('replaces hyphens with spaces', () => {
|
|
expect(bulkTitleFromFilename('2024-01-01_Max.pdf')).toBe('2024 01 01 Max');
|
|
});
|
|
|
|
it('collapses multiple separators', () => {
|
|
expect(bulkTitleFromFilename('foo__bar--baz.pdf')).toBe('foo bar baz');
|
|
});
|
|
|
|
it('strips extension', () => {
|
|
expect(bulkTitleFromFilename('document.pdf')).toBe('document');
|
|
});
|
|
});
|
|
|
|
describe('stripExtension', () => {
|
|
it('removes the extension', () => {
|
|
expect(stripExtension('document.pdf')).toBe('document');
|
|
});
|
|
|
|
it('removes only the last extension', () => {
|
|
expect(stripExtension('archive.tar.gz')).toBe('archive.tar');
|
|
});
|
|
|
|
it('leaves names without extension unchanged', () => {
|
|
expect(stripExtension('nodotfile')).toBe('nodotfile');
|
|
});
|
|
});
|