tslib-0.1.4: tests/basicUTimeTest.hs
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Main where
import Control.Lens
import Data.Time
import Data.UTime
import Data.TimeSeries.UTime
import Data.TimeSeries.Class
import qualified Data.TimeSeries.Boxed as TSB
import qualified Data.TimeSeries.Storable as TSS
import Test.Hspec
import Test.HUnit
ut :: Integer -> Int -> Int -> DiffTime -> UTime
ut y m d dt = toUTime $ UTCTime (fromGregorian y m d) dt
t1, t12, t2, t23, t3, tOld, tFar :: UTime
tOld = ut 1900 01 01 0
t1 = ut 2014 05 05 0
t12 = ut 2014 05 20 3600
t2 = ut 2014 06 15 0
t23 = ut 2014 06 20 28800
t3 = ut 2014 07 01 0
tFar = ut 2024 07 07 43200
exAbstract :: TSeries ts Int => ts Int
exAbstract = fromUnsortedPairList [(t1, 10), (t3, 30), (t2, 20)]
ex2Abstract :: TSeries ts Int => ts Int
ex2Abstract = fromUnsortedPairList [(t12, 12), (t2, 2), (t23, 23)]
exDoubleAbstract :: (TSeries ts Int, TSeries ts Double) => ts Double
exDoubleAbstract = exAbstract & tsTraversed %~ fromIntegral
emptyAbstract :: TSeries ts Double => ts Double
emptyAbstract = fromSortedPairList []
type TSeriesTestable ts a = (TSeries ts a, Show (ts a), Eq (ts a))
mainAbstract :: forall ts. ( TSeriesTestable ts Double
, TSeriesTestable ts Int
, TSeriesTestable ts Bool) => ts Double -> Spec
mainAbstract _witness = do
let ex = exAbstract :: ts Int
ex2 = ex2Abstract :: ts Int
exDouble = exDoubleAbstract :: ts Double
empty = emptyAbstract :: ts Double
describe "fromUnsortedPairList" $ do
it "sorts" $ do
[(t1, 10), (t2, 20), (t3, 30)] @=? toPairList ex
describe "tsLength" $ do
it "0 on empty" $ do
0 @=? tsLength empty
it "3 on example" $ do
3 @=? tsLength ex
describe "tsRange" $ do
it "Nothing on empty" $ do
Nothing @=? tsRange empty
it "(t1,t3) on example" $ do
Just (t1,t3) @=? tsRange ex
describe "firstAfter" $ do
it "Nothing on far" $ do
Nothing @=? firstAfter ex tFar
it "exact" $ do
Just (t2,20) @=? firstAfter ex t2
it "t2 on t12" $ do
Just (t2,20) @=? firstAfter ex t12
it "first on old" $ do
Just (t1, 10) @=? firstAfter ex tOld
describe "lastBefore" $ do
it "Nothing on old" $ do
Nothing @=? lastBefore ex tOld
it "exact" $ do
Just (t2,20) @=? lastBefore ex t2
it "t1 on t12" $ do
Just (t1,10) @=? lastBefore ex t12
it "last on far" $ do
Just (t3, 30) @=? lastBefore ex tFar
let roundToTwoDigits :: Maybe (UTime, Double) -> Maybe (UTime, Int)
roundToTwoDigits = fmap (mapSnd (round . (* 100)))
where
mapSnd f (a, b) = (a, f b)
let interp1 t = interpolateAt interpolateLinear exDouble t
describe "interpolateAt with interpolateLinear" $ do
it "exact" $ do
Just (t1,10.0) @=? interp1 t1
it "Nothing on old" $ do
Nothing @=? interp1 tOld
it "Nothing on far" $ do
Nothing @=? interp1 tFar
it "interpolates" $ do
roundToTwoDigits (Just (t23, 20 + 10/3)) @=? (roundToTwoDigits $ interp1 t23)
let interp2 t = interpolateAt extendInterpolateLinear exDouble t
describe "interpolateAt with extendInterpolateLinear" $ do
it "exact" $ do
Just (t1,10.0) @=? interp2 t1
it "extends on old" $ do
Just (tOld, 10) @=? interp2 tOld
it "extends on far" $ do
Just (tFar, 30) @=? interp2 tFar
it "interpolates" $ do
roundToTwoDigits (Just (t23, 20 + 10/3)) @=? (roundToTwoDigits $ interp2 t23)
describe "tsMergeWith" $ do
it "empty with empty on the right" $ do
empty @=? tsMergeWith undefined ex empty
it "empty with empty on the left" $ do
empty @=? tsMergeWith undefined empty ex
it "equates with itself" $ do
fromSortedPairList [(t1,True), (t2, True), (t3, True)]
@=? tsMergeWith (const (==)) ex ex
describe "tsMerge" $ do
it "does it right" $ do
fromSortedPairList [(t1, 20), (t12, -12), (t2, 18), (t23, -23), (t3, 60)]
@=? tsMerge
(TSMerge (const $ Just . (2*)) (const $ Just . negate) (\_ a b -> Just (a - b)))
ex ex2
main :: IO ()
main = hspec $ do
describe "Boxed" $ mainAbstract (undefined :: TSB.TSeries Double)
describe "Storable" $ mainAbstract (undefined :: TSS.TSeries Double)