reflex-vty-1.0.0.0: test/Reflex/Vty/CanvasSpec.hs
{-# LANGUAGE OverloadedStrings #-}
module Reflex.Vty.CanvasSpec (spec) where
import Data.Map.Strict (Map)
import qualified Data.Map.Strict as Map
import qualified Graphics.Vty as V
import Test.Hspec
import Reflex.Vty.Canvas
spec :: Spec
spec = describe "Reflex.Vty.Canvas" $ do
let red = V.withForeColor V.defAttr (V.ISOColor 1)
blue = V.withForeColor V.defAttr (V.ISOColor 4)
fromList = Map.fromList :: [((Int, Int), (Char, V.Attr))] -> Map (Int, Int) (Char, V.Attr)
describe "blankCanvas" $ do
it "creates a transparent canvas" $ do
let c = blankCanvas 5 3
canvasWidth c `shouldBe` 5
canvasHeight c `shouldBe` 3
canvasCells c `shouldBe` mempty
it "cellAt returns Nothing for blank" $ do
let c = blankCanvas 3 3
canvasCellAt 1 1 c `shouldBe` Nothing
describe "placeCanvas" $ do
it "overlays opaque cells" $ do
let dst = blankCanvas 5 3
src = Canvas 2 1 (fromList [((0, 0), ('X', red))])
result = placeCanvas 1 0 src dst
canvasCellAt 1 0 result `shouldBe` Just ('X', red)
it "transparent source cells don't overwrite" $ do
let dst = Canvas 3 1 (fromList [((0, 0), ('A', blue))])
src = blankCanvas 3 1
result = placeCanvas 0 0 src dst
canvasCellAt 0 0 result `shouldBe` Just ('A', blue)
it "clips cells outside destination bounds" $ do
let dst = blankCanvas 3 3
src = Canvas 2 1 (fromList [((0, 0), ('X', red))])
result = placeCanvas 5 5 src dst
canvasCells result `shouldBe` mempty
describe "translate" $ do
it "shifts cells by offset" $ do
let c = Canvas 5 5 (fromList [((0, 0), ('X', red))])
result = translate 2 3 c
canvasCellAt 2 3 result `shouldBe` Just ('X', red)
canvasCellAt 0 0 result `shouldBe` Nothing
it "drops cells that move outside bounds" $ do
let c = Canvas 3 3 (fromList [((0, 0), ('X', red))])
result = translate 5 0 c
canvasCells result `shouldBe` mempty
describe "stack" $ do
it "later canvases overlay earlier ones" $ do
let bottom = Canvas 3 1 (fromList [((0, 0), ('A', red))])
top = Canvas 3 1 (fromList [((0, 0), ('B', blue))])
result = stack [bottom, top]
canvasCellAt 0 0 result `shouldBe` Just ('B', blue)
it "transparent cells in top layer show bottom" $ do
let bottom = Canvas 3 1 (fromList [((0, 0), ('A', red))])
top = Canvas 3 1 (fromList [((1, 0), ('B', blue))])
result = stack [bottom, top]
canvasCellAt 0 0 result `shouldBe` Just ('A', red)
canvasCellAt 1 0 result `shouldBe` Just ('B', blue)
it "empty list returns blank" $ do
let result = stack []
canvasWidth result `shouldBe` 0
describe "imageToCanvas" $ do
it "converts plain text" $ do
let img = V.text' red "AB"
c = imageToCanvas img
canvasWidth c `shouldBe` 2
canvasHeight c `shouldBe` 1
canvasCellAt 0 0 c `shouldBe` Just ('A', red)
canvasCellAt 1 0 c `shouldBe` Just ('B', red)
it "converts charFill" $ do
let img = V.charFill red 'X' 3 2
c = imageToCanvas img
canvasWidth c `shouldBe` 3
canvasHeight c `shouldBe` 2
canvasCellAt 0 0 c `shouldBe` Just ('X', red)
canvasCellAt 2 1 c `shouldBe` Just ('X', red)
describe "canvasToImage" $ do
it "round-trips through imageToCanvas for opaque content" $ do
let img = V.text' red "Hello"
c = imageToCanvas img
img' = canvasToImage c
V.imageWidth img' `shouldBe` 5
V.imageHeight img' `shouldBe` 1
it "preserves dimensions for transparent canvas" $ do
let c = blankCanvas 4 2
img = canvasToImage c
V.imageWidth img `shouldBe` 4
V.imageHeight img `shouldBe` 2