import { describe, expect, it } from 'vitest'; import { columnHasInk, keptColumns, tighten, type Greyscale } from './tighten'; /** Builds an image from a picture: '#' is ink, '.' is paper. */ function image(row: string, height = 2): Greyscale { const width = row.length; const data = Buffer.alloc(width * height, 255); for (let y = 0; y < height; y += 1) { [...row].forEach((cell, x) => { data[y * width + x] = cell === '#' ? 0 : 255; }); } return { data, width, height }; } describe('columnHasInk', () => { it('finds ink anywhere down the column', () => { const grid: Greyscale = { data: Buffer.from([255, 255, 0, 255]), width: 2, height: 2 }; expect(columnHasInk(grid, 0)).toBe(true); expect(columnHasInk(grid, 1)).toBe(false); }); }); describe('keptColumns', () => { it('shortens a gap to the allowance', () => { expect(keptColumns(image('#.....#'), 2)).toEqual([0, 1, 2, 6]); }); it('leaves a gap already within the allowance alone', () => { expect(keptColumns(image('#.#'), 2)).toEqual([0, 1, 2]); }); it('drops the margins, which are not spacing', () => { expect(keptColumns(image('..#.#..'), 2)).toEqual([2, 3, 4]); }); it('handles several gaps independently', () => { expect(keptColumns(image('#....#....#'), 1)).toEqual([0, 1, 5, 6, 10]); }); it('returns nothing for a blank image', () => { expect(keptColumns(image('.....'), 2)).toEqual([]); }); it('keeps solid ink untouched', () => { expect(keptColumns(image('####'), 0)).toEqual([0, 1, 2, 3]); }); }); describe('tighten', () => { it('narrows the image by the width it removed', () => { const result = tighten(image('#.....#'), 2); expect(result.width).toBe(4); expect(result.height).toBe(2); }); it('preserves the letterforms, only the space between them', () => { const result = tighten(image('##....##'), 1); const row = Array.from({ length: result.width }, (_, x) => (result.data[x] === 0 ? '#' : '.')); expect(row.join('')).toBe('##.##'); }); it('copies every row, not just the first', () => { const source = image('#..#', 3); const result = tighten(source, 1); for (let y = 0; y < 3; y += 1) { expect(result.data[y * result.width]).toBe(0); } }); });