{-# 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 = (defaultPrimary "USD") & commHistory .~ IntMap.fromList [ (2, Map.fromList [(oneHourAgo, 0.75)]) , (3, Map.fromList [(oneDayAgo, 0.66)]) ] cad = (defaultPrimary "CAD") & commHistory .~ IntMap.fromList [ (1, Map.fromList [(oneHourAgo, 1.33)]) , (3, Map.fromList [(oneHourAgo, 0.83)]) ] eur = (defaultPrimary "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) ] where defaultPrimary sym = defaultCommodityInfo & commSymbol .~ sym & commPrecision .~ 2 & commNoMarket .~ True & commKnown .~ True & commPrimary .~ True testMap' :: UTCTime -> CommodityMap testMap' now = let usd = defaultPrimary "USD" cad = defaultPrimary "CAD" eur = defaultPrimary "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) where defaultPrimary sym = defaultCommodityInfo & commSymbol .~ sym & commPrecision .~ 2 & commNoMarket .~ True & commKnown .~ True & commPrimary .~ True