tricorder-0.2.0.0: test/Unit/Tricorder/Daemon/BuildStateSpec.hs
module Unit.Tricorder.Daemon.BuildStateSpec (spec_BuildState) where
import Data.Aeson (eitherDecode, encode)
import Data.Time (UTCTime (..), fromGregorian)
import Test.Hspec
import Tricorder.Build
( BuildId (..)
, BuildResult (..)
, BuildState (..)
, Diagnostic (..)
, PostBuild (..)
, Severity (..)
)
import Tricorder.Daemon.DaemonInfo (DaemonInfo (..))
import Tricorder.Build qualified as Build
import Tricorder.Build.EvalComment qualified as Eval
spec_BuildState :: Spec
spec_BuildState = do
describe "JSON round-trip" do
it "survives Unicode smart quotes in message text" do
let msg =
Diagnostic
{ severity = SWarning
, file = "<interactive>"
, line = 2
, col = 8
, endLine = 2
, endCol = 8
, title = "Found \8216qualified\8217 in prepositive position"
, text = "Found \8216qualified\8217 in prepositive position\n Suggested fixes:\n \8226 Place \8216qualified\8217 after the module name."
}
bs = mkBuildState [msg]
eitherDecode (encode bs) `shouldBe` Right bs
it "survives control characters in message text" do
let msg =
Diagnostic
{ severity = SWarning
, file = "<interactive>"
, line = 1
, col = 1
, endLine = 1
, endCol = 1
, title = "text with \CAN control \EM chars and \ESC[1m ANSI \ESC[0m codes"
, text = "text with \CAN control \EM chars and \ESC[1m ANSI \ESC[0m codes"
}
bs = mkBuildState [msg]
eitherDecode (encode bs) `shouldBe` Right bs
it "survives curly double quotes in message text" do
let msg =
Diagnostic
{ severity = SWarning
, file = "<interactive>"
, line = 1
, col = 1
, endLine = 1
, endCol = 1
, title = "\8220Place qualified after the module name.\8221"
, text = "\8220Place qualified after the module name.\8221"
}
bs = mkBuildState [msg]
eitherDecode (encode bs) `shouldBe` Right bs
-- Guards the wire format for the BuildFailed phase: the captured
-- cabal/build error (multi-line, Unicode) must round-trip intact so
-- the CLI/UI clients can render it.
it "survives a BuildFailed phase with a multi-line message" do
let bs =
mkBuildState [] :: BuildState
failed =
bs
{ phase =
Build.Failed
"cabal: Could not resolve dependencies:\n[__0] trying: \8216base\8217\nrejecting: ..."
}
eitherDecode (encode failed) `shouldBe` Right failed
mkBuildState :: [Diagnostic] -> BuildState
mkBuildState msgs =
BuildState
{ buildId = BuildId 1
, phase =
Build.Finished
( BuildResult
{ completedAt = epoch
, duration = 0
, moduleCount = 0
, diagnostics = msgs
}
)
$ PostBuild mempty Eval.NoneFound
, daemonInfo =
DaemonInfo
{ targets = []
, watchDirs = []
, sockPath = ""
, logFile = ""
}
}
where
epoch = UTCTime (fromGregorian 1970 1 1) 0