timeseries-0.3.0: test-src/Data/TimeSeries/SeriesSpec.hs
module Data.TimeSeries.SeriesSpec (spec) where
import Test.Hspec
import Data.Time (UTCTime)
import Data.Time.Clock.POSIX (posixSecondsToUTCTime, utcTimeToPOSIXSeconds)
import qualified Statistics.Sample as S
import qualified Data.Vector as V
import qualified Data.TimeSeries as TS
import Data.TimeSeries.Time (seconds)
sampleSeries :: TS.Series Double
sampleSeries = TS.tsSeries [1..] [10.0, 1.2, 32.4, 0.6, 11.0]
spec :: Spec
spec = do
describe "Converting Series" $ do
it "toList" $ do
let xs = TS.toList sampleSeries
map (\(x, y) -> (utcTimeToPOSIXSeconds x, y)) xs `shouldBe` [(1, 10.0), (2, 1.2), (3, 32.4), (4, 0.6), (5, 11.0)]
describe "Selecting sub Series" $ do
it "return data point value at given index" $ do
let pos = posixSecondsToUTCTime $ fromIntegral 2
TS.valueAt pos sampleSeries `shouldBe` Just 1.2
it "return Nothing value if wrong index" $ do
let idx = [10, 20, 30]
let values = [10.0, 12.0, 32.4]
let pos = posixSecondsToUTCTime $ fromIntegral 1234
TS.valueAt pos (TS.tsSeries idx values) `shouldBe` Nothing
it "return subset" $ do
let xs = TS.tsSeries [1..5] [10.0, 1.2, 32.4, 0.65, 11.0]
let start = utcFromSeconds 2
let end = utcFromSeconds 3
TS.size (TS.slice start end xs) `shouldBe` 2
it "return empty subset" $ do
let xs = TS.tsSeries [1..5] [10.0, 1.2, 32.4, 0.65, 11.0]
let start = utcFromSeconds 12
let end = utcFromSeconds 34
TS.slice start end xs `shouldBe` TS.emptySeries
describe "Basic operations" $ do
it "return series size" $ do
let xs = TS.tsSeries [1..] [10.0, 1.2, 32.4, 0.65, 11.0]
TS.size xs `shouldBe` 5
it "map over series" $ do
let xs = TS.tsSeries [1..] [10.0, 1.2, 32.4, 0.65, 11.0]
let ys = fmap (+ 2) xs
TS.values ys `shouldBe` [12.0, 3.2, 34.4, 2.65, 13.0]
it "fold over series" $ do
foldr (\v acc -> v + acc) 0.0 sampleSeries `shouldBe` 55.2
it "maximum value" $ do
let xs = TS.tsSeries [1..] [10.0, 1.2, 32.4, 0.65, 11.0]
maximum xs `shouldBe` 32.4
it "minimum value" $ do
let xs = TS.tsSeries [1..5] [10.0, 1.2, 32.4, 0.65, 11.0]
minimum xs `shouldBe` 0.65
describe "Group operations" $ do
it "rolling window" $ do
let xs = TS.tsSeries [1..] [1.0, 2.0, 3.0, 4.0, 5.0]
TS.rolling 2 sum xs `shouldBe` TS.tsSeries [2..] [3.0, 5.0, 7.0, 9.0]
it "smoothing" $ do
let xs = TS.tsSeries [1..] [1.0, 2.0, 3.0, 4.0, 5.0]
TS.rolling 3 (S.mean . V.fromList) xs `shouldBe` TS.tsSeries [3..] [2.0, 3.0, 4.0]
it "resampling" $ do
let xs = TS.tsSeries [1..] [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
let startTime = posixSecondsToUTCTime $ fromIntegral 1
TS.resample startTime (seconds 2) sum xs `shouldBe` TS.tsSeries [1, 3, 5] [3.0, 7.0, 11.0]
utcFromSeconds :: Integer -> UTCTime
utcFromSeconds = posixSecondsToUTCTime . fromIntegral