test/render-size.test.ts (2398 bytes)
1 import fc from 'fast-check'; 2 import { describe, expect, it } from 'vitest'; 3 import { 4 MAX_RENDER_AREA, 5 MAX_RENDER_WIDTH, 6 MIN_RENDER_WIDTH, 7 renderWidth, 8 } from '../src/render-size'; 9 10 /** A4: the height is 1.414 times the width. */ 11 const A4 = 842 / 595; 12 13 describe('renderWidth', () => { 14 it('renders the phone page sharp at a pinch zoom of 2.5', () => { 15 // The phone finding: after a pinch zoom the canvas stayed at the width 16 // of no zoom, and the text was soft. 17 const phone = { cssWidth: 352, dpr: 2.625, aspect: A4 }; 18 expect(renderWidth({ ...phone, zoom: 1 })).toBe(924); 19 expect(renderWidth({ ...phone, zoom: 2.5 })).toBe(2310); 20 }); 21 22 it('renders a landscape page wider than 2048 px', () => { 23 // The phone finding: the landscape canvas stopped at 2048 px for 2237 device px. 24 expect(renderWidth({ cssWidth: 852.2, dpr: 2.625, zoom: 1, aspect: A4 })).toBe(2237); 25 }); 26 27 it('stops at the largest width and area', () => { 28 expect(renderWidth({ cssWidth: 852, dpr: 2.625, zoom: 3, aspect: A4 })).toBe( 29 Math.round(Math.sqrt(MAX_RENDER_AREA / A4)), 30 ); 31 expect(renderWidth({ cssWidth: 3000, dpr: 2, zoom: 1, aspect: 0.5 })).toBe(MAX_RENDER_WIDTH); 32 expect(renderWidth({ cssWidth: 50, dpr: 1, zoom: 1, aspect: A4 })).toBe(MIN_RENDER_WIDTH); 33 }); 34 35 it('never goes over the limits, and grows with the zoom', () => { 36 const input = fc.record({ 37 cssWidth: fc.double({ min: 1, max: 5000, noNaN: true }), 38 dpr: fc.double({ min: 0.5, max: 4, noNaN: true }), 39 zoom: fc.double({ min: 0.5, max: 10, noNaN: true }), 40 aspect: fc.double({ min: 0.2, max: 5, noNaN: true }), 41 }); 42 fc.assert( 43 fc.property(input, fc.double({ min: 1, max: 3, noNaN: true }), (s, more) => { 44 const w = renderWidth(s); 45 expect(w).toBeGreaterThanOrEqual(MIN_RENDER_WIDTH); 46 expect(w).toBeLessThanOrEqual(MAX_RENDER_WIDTH); 47 // Rounding adds at most half a pixel to the width. The factor allows for floating point. 48 if (w > MIN_RENDER_WIDTH) { 49 expect((w - 0.5) ** 2 * s.aspect).toBeLessThanOrEqual(MAX_RENDER_AREA * (1 + 1e-9)); 50 } 51 const sharp = s.cssWidth * s.dpr * Math.max(1, s.zoom); 52 if (sharp <= w) expect(w).toBe(Math.max(MIN_RENDER_WIDTH, Math.round(sharp))); 53 expect(renderWidth({ ...s, zoom: s.zoom * more })).toBeGreaterThanOrEqual(w); 54 }), 55 ); 56 }); 57 });