refac: cleaning round for image cropping/resizing

This commit is contained in:
fsylvain committed 2026-09-28 07:56:13 +02:00
1 parent e15f444603
commit 0fc00ceeff
3 files changed
+211 -38

No files matched your search

+121
View File
@@ -1,11 +1,16 @@
import { describe, expect, it } from 'vitest'
import {
clampRect,
computeOutputSize,
estimateOutputBytes,
formatEstimatedSize,
moveRect,
ratioValueFor,
rectForRatio,
resizeRect,
rotateRectBySteps,
rotatedDimensions,
widthPresetPixels,
wholeRect,
} from '../imageCrop'
@@ -41,6 +46,122 @@ describe('estimateOutputBytes', () => {
})
})
describe('formatEstimatedSize', () => {
it('stays in KB just under the 1000 KB threshold', () => {
expect(formatEstimatedSize(999 * 1024)).toBe('999 KB')
})
it('switches to MB at and above the 1000 KB threshold', () => {
expect(formatEstimatedSize(1024 * 1024 * 2.5)).toBe('2.5 MB')
})
})
describe('clampRect', () => {
it('rounds fractional coordinates and dimensions to whole pixels', () => {
expect(clampRect({ x: 100.2, y: 50.7, width: 200.4, height: 150.6 }, 4032, 3024)).toEqual({
x: 100,
y: 51,
width: 200,
height: 151,
})
})
it('clamps width and height to the bounds', () => {
expect(clampRect({ x: 0, y: 0, width: 5000, height: 4000 }, 4032, 3024)).toEqual({
x: 0,
y: 0,
width: 4032,
height: 3024,
})
})
it('clamps x and y so the rect stays inside the bounds', () => {
expect(clampRect({ x: 4000, y: 3000, width: 3024, height: 3024 }, 4032, 3024)).toEqual({
x: 1008,
y: 0,
width: 3024,
height: 3024,
})
})
it('never lets width or height drop below 1px', () => {
expect(clampRect({ x: 0, y: 0, width: -10, height: 0 }, 4032, 3024)).toEqual({
x: 0,
y: 0,
width: 1,
height: 1,
})
})
})
describe('moveRect', () => {
it('offsets the rect and clamps it inside the bounds', () => {
const rect = { x: 100, y: 100, width: 200, height: 200 }
expect(moveRect(rect, 50, -50, 4032, 3024)).toEqual({
x: 150,
y: 50,
width: 200,
height: 200,
})
})
it('stops at the bound edge instead of moving past it', () => {
const rect = { x: 0, y: 0, width: 200, height: 200 }
expect(moveRect(rect, -50, -50, 4032, 3024)).toEqual({
x: 0,
y: 0,
width: 200,
height: 200,
})
})
})
describe('resizeRect', () => {
it('grows freely on both axes when no ratio is locked', () => {
const rect = { x: 0, y: 0, width: 200, height: 200 }
expect(resizeRect(rect, 20, 10, 4032, 3024, null)).toEqual({
x: 0,
y: 0,
width: 220,
height: 210,
})
})
it('derives height from width when a ratio is locked and width changes', () => {
const rect = { x: 0, y: 0, width: 200, height: 200 }
expect(resizeRect(rect, 100, 0, 4032, 3024, 16 / 9)).toEqual({
x: 0,
y: 0,
width: 300,
height: 169,
})
})
})
describe('ratioValueFor', () => {
it('returns null for Free so the frame is unconstrained', () => {
expect(ratioValueFor('Free', 4032, 3024)).toBeNull()
})
it('derives Original from the current bounds', () => {
expect(ratioValueFor('Original', 4032, 3024)).toBeCloseTo(4032 / 3024)
})
it('returns the fixed value for a named ratio', () => {
expect(ratioValueFor('1:1', 4032, 3024)).toBe(1)
})
})
describe('widthPresetPixels', () => {
it('returns null for Original so the crop keeps its own width', () => {
expect(widthPresetPixels('Original')).toBeNull()
})
it('returns the pixel target for a fixed preset', () => {
expect(widthPresetPixels('800 px')).toBe(800)
})
})
describe('rotateRectBySteps', () => {
it('rotates a whole-image rect 90deg clockwise into the new bounds', () => {
const rotated = rotateRectBySteps(wholeRect(4032, 3024), 4032, 3024, 1)