Responses for exercises in Exercism.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

80 lines
2.6 KiB

{-# OPTIONS_GHC -fno-warn-type-defaults #-}
{-# LANGUAGE RecordWildCards #-}
import Data.Foldable (for_)
import Data.Function (on)
import Test.Hspec (Spec, describe, it, shouldBe)
import Test.Hspec.Runner (configFastFail, defaultConfig, hspecWith)
import SpaceAge (Planet(..), ageOn)
main :: IO ()
main = hspecWith defaultConfig {configFastFail = True} specs
specs :: Spec
specs = describe "ageOn" $ for_ cases test
where
-- Here we used `fromIntegral`, `fromRational` and `toRational` to
-- generalize the test suite, allowing any function that takes a
-- `Planet` and a number, returning an instance of `Real`.
test Case{..} = it description $ expression `shouldBeAround` expected
where
expression = fromRational
. toRational
. ageOn planet
. fromIntegral
$ seconds
shouldBeAround = shouldBe `on` roundTo 2
roundTo n = (/ 10 ^ n) . fromIntegral . round . (* 10 ^ n)
data Case = Case { description :: String
, planet :: Planet
, seconds :: Integer
, expected :: Double
}
cases :: [Case]
cases = [ Case { description = "Earth"
, planet = Earth
, seconds = 1000000000
, expected = 31.69
}
, Case { description = "Mercury"
, planet = Mercury
, seconds = 2134835688
, expected = 280.88
}
, Case { description = "Venus"
, planet = Venus
, seconds = 189839836
, expected = 9.78
}
, Case { description = "Mars"
, planet = Mars
, seconds = 2129871239
, expected = 35.88
}
, Case { description = "Jupiter"
, planet = Jupiter
, seconds = 901876382
, expected = 2.41
}
, Case { description = "Saturn"
, planet = Saturn
, seconds = 2000000000
, expected = 2.15
}
, Case { description = "Uranus"
, planet = Uranus
, seconds = 1210123456
, expected = 0.46
}
, Case { description = "Neptune"
, planet = Neptune
, seconds = 1821023456
, expected = 0.35
}
]
-- 33c40fce28c835600282d0bfdc589d7c6d785f6e