Units correctness: exact imperial entry, garden grid at dimension scale (#47) (#60)
Build image / build-and-push (push) Successful in 6s

Co-authored-by: Steve Dudenhoeffer <[email protected]>
This commit was merged in pull request #60.
This commit is contained in:
2026-07-21 04:50:49 +00:00
committed by steve
parent 1716362981
commit 8a12069118
7 changed files with 204 additions and 57 deletions
+31 -7
View File
@@ -1,5 +1,6 @@
import { describe, expect, it } from 'vitest'
import {
cmFromDisplay,
cmFromFtIn,
cmFromMeters,
cmFromSpacing,
@@ -11,15 +12,37 @@ import {
} from './units'
describe('cm conversions', () => {
it('feet+inches → whole cm', () => {
expect(cmFromFtIn(4)).toBe(122) // 4ft = 121.92 → 122
expect(cmFromFtIn(8)).toBe(244)
expect(cmFromFtIn(4, 6)).toBe(137) // 4'6" = 137.16 → 137
// Every cm column is REAL, so entry is exact — no whole-cm quantization. A 1 ft
// grid is 30.48 cm, not 30, or the error accumulates across the garden (#47).
it('feet+inches → exact cm', () => {
expect(cmFromFtIn(1)).toBe(30.48)
expect(cmFromFtIn(4)).toBe(121.92)
expect(cmFromFtIn(8)).toBe(243.84)
expect(cmFromFtIn(4, 6)).toBe(137.16)
})
it('meters → whole cm', () => {
it('meters → exact cm', () => {
expect(cmFromMeters(10)).toBe(1000)
expect(cmFromMeters(1.22)).toBe(122)
expect(cmFromMeters(0.305)).toBe(30.5)
})
it('rounds away float dust, not precision', () => {
// 12 × 2.54 is 30.479999999999997 in IEEE-754; 1 ft must read as 30.48.
expect(cmFromFtIn(0, 12)).toBe(30.48)
expect(cmFromSpacing(12, 'imperial')).toBe(30.48)
expect(cmFromSpacing(1, 'imperial')).toBe(2.54)
})
it('round-trips display → cm → display at display precision', () => {
const imperial = [0.5, 1, 2.5, 4, 8, 12.5, 24]
for (const ft of imperial) {
expect(displayFromCm(cmFromDisplay(ft, 'imperial'), 'imperial')).toBe(ft)
}
const metric = [0.15, 1, 1.22, 3.05, 10, 24.5]
for (const m of metric) {
expect(displayFromCm(cmFromDisplay(m, 'metric'), 'metric')).toBe(m)
}
})
})
@@ -59,13 +82,14 @@ describe('plant spacing (small scale)', () => {
expect(formatSpacing(30, 'imperial')).toBe('12″')
})
it('parses an entered value back to whole cm', () => {
it('parses an entered value back to exact cm', () => {
expect(cmFromSpacing(15, 'metric')).toBe(15)
expect(cmFromSpacing(6, 'imperial')).toBe(15) // 6in = 15.24 → 15
expect(cmFromSpacing(6, 'imperial')).toBe(15.24)
})
it('prefills an input from cm', () => {
expect(spacingFromCm(15, 'metric')).toBe(15)
expect(spacingFromCm(30, 'imperial')).toBe(11.8) // 30/2.54 = 11.81 → 11.8
expect(spacingFromCm(30.48, 'imperial')).toBe(12) // an exactly-12in grid reads back as 12
})
})