nano-ui-0.1.0.0: test/integration/Cases/NumericInput.hs
module Cases.NumericInput
( runNumericInputHexTest
, runNumericInputTest
) where
import Data.IORef (IORef, newIORef)
import Data.Text qualified as T
import NanoUI
import NanoUI.Testing
import NanoUI.Testing.Assert (assert, assertEq, withInput)
import NanoUI.Testing.Harness (held, pressAt, releaseAt, warmup2)
-- A numeric field steps with the arrow keys (Shift steps ten times as far),
-- drops typing that is not a number, clamps to its range while typing, and
-- Enter rewrites the text as the clamped value. The stepper's lower half steps
-- down.
runNumericInputTest :: Context -> IORef Int -> IO ()
runNumericInputTest ctx failed = do
valueRef <- newIORef 12
let inp = withInput 320 120
cfg = defaultNumericInputConfig {nicMin = 0, nicMax = 100}
ui = column (held valueRef (numericInputConfigured' cfg))
step event = (\((_, v), _, _, _) -> v) <$> runFrame ctx event ui
key k = inp {inputKeys = inputKeysFromList [k]}
(resp, _) <- warmup2 ctx inp ui
_ <- step (key KeyTab)
stepped <- step (key KeyUp)
assertEq failed stepped 13
steppedTen <- step ((key KeyUp) {inputModifiers = Modifiers True False False})
assertEq failed steppedTen 23
rejected <- step (inp {inputChars = "4x"})
assertEq failed rejected 23
clamped <- step (inp {inputChars = "4"})
assertEq failed clamped 100
assert failed =<< spanShown ctx "234"
_ <- step (key KeyEnter)
assert failed =<< spanShown ctx "100"
let Rect x y w h = respRect resp
press = pressAt inp (V2 (x + w - 4) (y + h * 0.75))
pressed <- step press
assertEq failed pressed 99
released <- step (releaseAt press)
assertEq failed released 99
-- Hexadecimal mode shows upper-case digits, takes hexadecimal typing but no
-- decimal point, and steps like decimal mode.
runNumericInputHexTest :: Context -> IORef Int -> IO ()
runNumericInputHexTest ctx failed = do
valueRef <- newIORef 255
let inp = withInput 320 120
cfg = defaultNumericInputConfig {nicMin = 0, nicHex = True, nicDecimals = 2}
ui = column (held valueRef (numericInputConfigured' cfg))
step event = (\((_, v), _, _, _) -> v) <$> runFrame ctx event ui
key k = inp {inputKeys = inputKeysFromList [k]}
_ <- warmup2 ctx inp ui
assert failed =<< spanShown ctx "FF"
_ <- step (key KeyTab)
typed <- step (inp {inputChars = "a"})
assertEq failed typed 0xFFA
point <- step (inp {inputChars = "."})
assertEq failed point 0xFFA
stepped <- step (key KeyUp)
assertEq failed stepped 0xFFB
assert failed =<< spanShown ctx "FFB"
spanShown :: Context -> T.Text -> IO Bool
spanShown ctx txt = any (\(_, t, _, _, _) -> t == txt) <$> collectTextSpans ctx