ghc-bench-0.3.0: test/ResultSpec.hs
{-# OPTIONS_GHC -Wno-orphans #-}
module ResultSpec (spec) where
import Helper
import Data.Ord (comparing)
import Data.Aeson (ToJSONKey)
import Data.Yaml (ToJSON(..), object, (.=))
import Data.Yaml.Pretty qualified as Yaml
import System.Directory (listDirectory)
import Data.Text.IO.Utf8 qualified as Utf8
import Data.Map.Strict qualified as Map
import Fixtures.System qualified as System
import README (ensureFile)
import README qualified (update)
import SystemInfo
import Result
spec :: Spec
spec = do
describe "issueTitle" do
context "with a desktop system" do
it "creates a descriptive issue title" do
issueTitle 0 System.i10900K_desktop `shouldBe`
"[result] 0s - desktop computer - Intel Core i9-10900K"
context "with a laptop system" do
it "creates a descriptive issue title" do
issueTitle 0 System.dell_xps `shouldBe`
"[result] 0s - Dell Inc. XPS 13 9310 - Intel Core i7-1165G7"
context "with a LENOVO ThinkPad" do
it "creates a descriptive issue title" do
issueTitle 0 System.x200 `shouldBe`
"[result] 0s - LENOVO ThinkPad X200 - Intel Core 2 Duo P8700"
describe "parseFromIssueBody" do
let
fixtures = [
("raw/2026-04-12T16:01:13Z", Result {
times = [("ghc-9.12.4-build", 526)]
, concurrency = 20
, system = System.i10900K_desktop
}
)
, ("raw/2026-04-12T13:37:10Z", Result {
times = [("ghc-9.12.4-build", 715)]
, concurrency = 8
, system = System.dell_xps
}
)
, ("raw/2026-04-12T17:38:23Z", Result {
times = [("ghc-9.12.4-build", 3013)]
, concurrency = 2
, system = System.x200
}
)
]
for_ fixtures \ (name, expected) -> do
it name do
entry <- parseFromIssueBody <$> Utf8.readFile name
entry `shouldBe` expected
describe "resultPath" do
context "with a desktop system" do
it "creates a descriptive path" do
resultPath "2026-04-13" System.i10900K_desktop `shouldBe`
"results/intel/10th/i9-10900K/ASRock-Z490M-ITX-ac_2026-04-13.yaml"
context "with a laptop system" do
it "creates a descriptive path" do
resultPath "2026-04-13" System.dell_xps `shouldBe`
"results/intel/11th/i7-1165G7/XPS-13-9310_2026-04-13.yaml"
context "with a LENOVO ThinkPad" do
it "creates a descriptive path" do
resultPath "2026-04-13" System.x200 `shouldBe`
"results/intel/core_2/P8700/X200-7455D7G_2026-04-13.yaml"
it "process results" do
results <- processResults "raw"
README.update results
processResults :: FilePath -> IO [Result]
processResults dir = do
listDirectory dir >>= traverse \ timestamp -> do
body <- Utf8.readFile (dir </> timestamp)
let
result :: Result
result = parseFromIssueBody body
path :: FilePath
path = resultPath (fromString timestamp) result.system
encodeFile path result
return result
encodeFile :: FilePath -> Result -> IO ()
encodeFile file result = do
ensureFile file $ Yaml.encodePretty conf result
where
conf :: Yaml.Config
conf = Yaml.setConfCompare (comparing byFieldOrder) Yaml.defConfig
byFieldOrder :: Text -> Int
byFieldOrder name = fromMaybe maxBound (lookup name fieldOrder)
fieldOrder :: [(Text, Int)]
fieldOrder = flip zip [1..] [
"times"
, "concurrency"
, "os"
, "arch"
, "category"
, "chassis_type"
, "name"
, "cores"
, "threads"
, "vendor"
, "family"
, "model"
, "stepping"
, "version"
, "product"
, "board"
, "cpu"
, "ram"
]
instance ToJSON Result where
toJSON Result{..} = object [
"times" .= Map.fromList times
, "concurrency" .= concurrency
, "system" .= system
]
deriving newtype instance ToJSONKey Label
deriving newtype instance ToJSON Seconds
deriving newtype instance ToJSON Concurrency
instance ToJSON SystemInfo
instance ToJSON Product
instance ToJSON Board
instance ToJSON Cpu