import { render, screen } from '@testing-library/react'; import { describe, it, expect } from 'vitest'; import React from 'react'; import { MapScaleBar } from './map-scale-bar'; import { niceScaleDistance } from './scale-distance'; describe('niceScaleDistance', () => { it('picks a round distance a reader can divide by', () => { const scale = niceScaleDistance(10, 120, 'metric')!; // A bar labelled 1.37 km is useless for estimating anything. expect( [1, 2, 5].some(step => scale.distance / step === 10 ** Math.log10(scale.distance / step)) ).toBe(true); expect(scale.widthPx).toBeLessThanOrEqual(120); }); it('never overflows the allotted width', () => { [0.5, 5, 50, 500, 5000].forEach(mpp => { const scale = niceScaleDistance(mpp, 120, 'metric')!; expect(scale.widthPx).toBeLessThanOrEqual(120); expect(scale.widthPx).toBeGreaterThan(0); }); }); it('switches to kilometres past 1000 m', () => { expect(niceScaleDistance(100, 120, 'metric')!.label).toMatch(/km$/); expect(niceScaleDistance(0.5, 120, 'metric')!.label).toMatch(/m$/); }); it('supports imperial units', () => { expect(niceScaleDistance(100, 120, 'imperial')!.label).toMatch(/mi$/); expect(niceScaleDistance(0.1, 120, 'imperial')!.label).toMatch(/ft$/); }); it('returns null for a nonsensical resolution', () => { expect(niceScaleDistance(0, 120, 'metric')).toBeNull(); expect(niceScaleDistance(NaN, 120, 'metric')).toBeNull(); }); }); describe('MapScaleBar', () => { it('renders the distance label', () => { render(); expect(screen.getByText(/km|m$/)).toBeInTheDocument(); }); it('renders nothing when the resolution is unusable', () => { const { container } = render(); expect(container).toBeEmptyDOMElement(); }); });