packages feed

commodities-0.2.0.1: test/Main.hs

{-# LANGUAGE OverloadedStrings #-}

module Main where

import           Control.Exception
import           Control.Lens
import           Control.Monad.Trans.State
import qualified Data.IntMap as IntMap
import qualified Data.Map as Map
import           Data.Ratio
import           Data.Thyme
import           Data.Thyme.Time
import           Ledger.Commodity
import           Ledger.Commodity.History
import           Test.Hspec
import           Test.QuickCheck

main :: IO ()
main = hspec $ do
    describe "Sample tests" $ do
        it "returns the first element of a list" $
            head [23 ..] `shouldBe` (23 :: Int)

        it "returns the first element of an *arbitrary* list" $
            property $ \x xs -> head (x:xs) == (x :: Int)

        it "throws an exception if used with an empty list" $
            evaluate (head []) `shouldThrow` anyException

    describe "Ledger.Commodity.History" $ do
        it "works with testMap" $ do
            let cm = testMap moment
            findConversion 1 3 moment cm
                `shouldBe` Just (oneHourAgo, 400 % 249)
            findConversion 1 3 (addUTCTime (-7000) moment) cm
                `shouldBe` Just (oneDayAgo, 50 % 33)

        it "works with testMap'" $ do
            let cm' = testMap' moment
            findConversion 1 3 moment cm'
                `shouldBe` Just (oneHourAgo, 8 % 5)
            findConversion 1 3 (addUTCTime (-7000) moment) cm'
                `shouldBe` Just (oneDayAgo, 3 % 2)
  where
    moment = UTCTime (ModifiedJulianDay 50000) (secondsToDiffTime 0)
        ^. from utcTime
    oneHourAgo = addUTCTime (-3600) moment
    oneDayAgo  = addUTCTime (-(24 * 3600)) moment

testMap :: UTCTime -> CommodityMap
testMap now =
    let oneHourAgo = addUTCTime (-3600) now
        oneDayAgo  = addUTCTime (-(24 * 3600)) now

        usd = (defaultPrimaryCommodityInfo "USD")
            & commHistory .~
                   IntMap.fromList [ (2, Map.fromList [(oneHourAgo, 0.75)])
                                   , (3, Map.fromList [(oneDayAgo, 0.66)])
                                   ]
        cad = (defaultPrimaryCommodityInfo "CAD")
            & commHistory .~
                IntMap.fromList [ (1, Map.fromList [(oneHourAgo, 1.33)])
                                , (3, Map.fromList [(oneHourAgo, 0.83)])
                                ]
        eur = (defaultPrimaryCommodityInfo "EUR")
            & commHistory .~
                IntMap.fromList [ (1, Map.fromList [(oneDayAgo, 1.5)])
                                , (2, Map.fromList [(oneHourAgo, 1.2)])
                                ]
    in CommodityMap $ IntMap.fromList
        [ (1, usd)
        , (2, cad)
        , (3, eur)
        ]

testMap' :: UTCTime -> CommodityMap
testMap' now =
    let usd = defaultPrimaryCommodityInfo "USD"
        cad = defaultPrimaryCommodityInfo "CAD"
        eur = defaultPrimaryCommodityInfo "EUR"

        cm = CommodityMap $ IntMap.fromList
            [ (1, usd)
            , (2, cad)
            , (3, eur)
            ]
    in flip execState cm $ do
        let oneHourAgo = addUTCTime (-3600) now
            oneDayAgo  = addUTCTime (-(24 * 3600)) now
        addConversion 1 2 oneHourAgo (3 % 4)
        addConversion 1 3 oneDayAgo  (2 % 3)
        addConversion 2 3 oneHourAgo (5 % 6)