reflex-vty-1.3.0.0: test/Reflex/Vty/ColorProfileSpec.hs
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
module Reflex.Vty.ColorProfileSpec (spec) where
import Control.Monad (forM_)
import qualified Graphics.Vty as V
import qualified Graphics.Vty.Attributes.Color as V.Color
import Test.Hspec
import Reflex.Vty.ColorProfile
spec :: Spec
spec = describe "Reflex.Vty.ColorProfile" $ do
describe "colorProfileFromColorMode" $ do
it "maps NoColor to Ascii" $
colorProfileFromColorMode V.Color.NoColor `shouldBe` ColorProfile_Ascii
it "maps ColorMode8 to Ansi16" $
colorProfileFromColorMode V.Color.ColorMode8 `shouldBe` ColorProfile_Ansi16
it "maps ColorMode16 to Ansi16" $
colorProfileFromColorMode V.Color.ColorMode16 `shouldBe` ColorProfile_Ansi16
it "maps ColorMode240 to Ansi256" $
colorProfileFromColorMode (V.Color.ColorMode240 0) `shouldBe` ColorProfile_Ansi256
it "maps FullColor to TrueColor" $
colorProfileFromColorMode V.Color.FullColor `shouldBe` ColorProfile_TrueColor
describe "convertColor" $ do
it "is identity for TrueColor" $
convertColor ColorProfile_TrueColor (V.Color.RGBColor 10 20 30)
`shouldBe` V.Color.RGBColor 10 20 30
it "downsamples RGB to Color240 for Ansi256" $
convertColor ColorProfile_Ansi256 (V.Color.RGBColor 10 20 30)
`shouldSatisfy` \case
V.Color.Color240 {} -> True
_ -> False
it "is identity for ISOColor under Ansi16" $
convertColor ColorProfile_Ansi16 V.Color.red `shouldBe` V.Color.red
it "maps pure black RGB to the black ISO color under Ansi16" $
convertColor ColorProfile_Ansi16 (V.Color.RGBColor 0 0 0)
`shouldBe` V.Color.black
it "maps pure white RGB to the white ISO color under Ansi16" $
convertColor ColorProfile_Ansi16 (V.Color.RGBColor 255 255 255)
`shouldBe` V.Color.brightWhite
describe "applyProfile" $ do
let redAttr = V.withForeColor V.defAttr V.Color.red
it "preserves the foreground color under TrueColor" $ do
V.attrForeColor (applyProfile ColorProfile_TrueColor redAttr)
`shouldBe` V.SetTo V.Color.red
it "resets the foreground to Default under Ascii" $ do
V.attrForeColor (applyProfile ColorProfile_Ascii redAttr)
`shouldBe` V.Default
it "resets foreground, background, and style to Default under NoTTY" $ do
let attr = V.withStyle (V.withForeColor (V.withBackColor V.defAttr V.Color.blue) V.Color.red) V.bold
applied = applyProfile ColorProfile_NoTTY attr
V.attrForeColor applied `shouldBe` V.Default
V.attrBackColor applied `shouldBe` V.Default
V.attrStyle applied `shouldBe` V.Default
it "preserves the URL field under NoTTY" $ do
let attr = V.withURL V.defAttr "https://example.com"
V.attrURL (applyProfile ColorProfile_NoTTY attr)
`shouldBe` V.SetTo "https://example.com"
describe "applyProfile (fields)" $ do
it "downsamples both foreground and background under Ansi256" $ do
let attr = V.withBackColor (V.withForeColor V.defAttr (V.Color.RGBColor 10 20 30)) (V.Color.RGBColor 40 50 60)
applied = applyProfile ColorProfile_Ansi256 attr
V.attrForeColor applied `shouldSatisfy` \case
V.SetTo (V.Color.Color240 _) -> True
_ -> False
V.attrBackColor applied `shouldSatisfy` \case
V.SetTo (V.Color.Color240 _) -> True
_ -> False
it "resets only the color fields of a fully transparent attr under Ascii" $ do
let attr = V.Attr V.KeepCurrent V.KeepCurrent V.KeepCurrent V.KeepCurrent
applied = applyProfile ColorProfile_Ascii attr
-- Ascii supports no colors at all. Color requests collapse to
-- Default, even transparent ones. Style and URL survive.
V.attrForeColor applied `shouldBe` V.Default
V.attrBackColor applied `shouldBe` V.Default
V.attrStyle applied `shouldBe` V.KeepCurrent
V.attrURL applied `shouldBe` V.KeepCurrent
it "keeps ISO colors under Ansi256" $ do
let attr = V.withBackColor (V.withForeColor V.defAttr V.Color.blue) V.Color.red
applied = applyProfile ColorProfile_Ansi256 attr
V.attrForeColor applied `shouldBe` V.SetTo V.Color.blue
V.attrBackColor applied `shouldBe` V.SetTo V.Color.red
it "only ever produces valid output colors" $ do
let attr = V.withBackColor (V.withForeColor V.defAttr (V.Color.RGBColor 1 2 3)) (V.Color.RGBColor 250 251 252)
forM_ [ColorProfile_TrueColor, ColorProfile_Ansi256, ColorProfile_Ansi16] $ \profile ->
forM_ [V.attrForeColor, V.attrBackColor] $ \sel ->
sel (applyProfile profile attr) `shouldSatisfy` \case
V.SetTo V.Color.RGBColor {} -> profile == ColorProfile_TrueColor
V.SetTo (V.Color.Color240 _) -> profile == ColorProfile_Ansi256
V.SetTo V.Color.ISOColor {} -> profile == ColorProfile_Ansi16
_ -> False