simfin-1.0.0: test/Test.hs
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE OverloadedStrings #-}
module Main
( main
) where
import Control.Monad.IO.Class
import Data.Aeson
import Data.Text (Text)
import Test.Tasty
import Test.Tasty.HUnit
import SimFin.Free
main :: IO ()
main = do
ctx <- createDefaultContext
defaultMain (tests ctx)
testStatementQuery :: Text -> StatementQueryFree
testStatementQuery ref = StatementQueryFree
{ stockRef = Ticker ref
, period = FullYear
, year = 2020
, ttm = False
}
type UnitIndustry = Industry () () ()
general :: UnitIndustry
general = General ()
bank :: UnitIndustry
bank = Bank ()
insurance :: UnitIndustry
insurance = Insurance ()
industryMatches :: Industry a b c -> Industry d e f -> Bool
industryMatches a b = case (a, b) of
(General _, General _) -> True
(Bank _, Bank _) -> True
(Insurance _, Insurance _) -> True
_ -> False
testFetchMaybe :: IO (ApiResult (Maybe a)) -> IO ()
testFetchMaybe f = do
res <- f
flip withRight res $ withMaybe $ const $ pure ()
testFetchIndustry :: UnitIndustry -> IO (ApiResult (Maybe (Industry a b c))) -> IO ()
testFetchIndustry ind f = do
res <- f
flip withRight res $ withMaybe $ assertBool "Industry Matches" . industryMatches ind
failWithEmpty :: IO ()
failWithEmpty = assertFailure "Retrieved Nothing successfully"
testFetchList :: IO (ApiResult [a]) -> IO ()
testFetchList f = do
res <- f
withRight ensureNE res
withRight :: Show c => (a -> IO b) -> Either c a -> IO b
withRight _ (Left a) = assertFailure $ "Retrieved Left: " <> show a
withRight f (Right a) = f a
withMaybe :: (a -> IO ()) -> Maybe a -> IO ()
withMaybe _ Nothing = failWithEmpty
withMaybe f (Just a) = f a
ensureNE :: [a] -> IO ()
ensureNE [] = failWithEmpty
ensureNE _ = pure ()
tests :: SimFinContext -> TestTree
tests ctx = testGroup "SimFin"
[ testCase "List companies" $ testFetchList $ fetchCompanyList ctx
, testCase "Company Info" $ testFetchMaybe $ fetchCompanyInfo ctx "AAPL"
, testGroup "Balance Sheet"
[ testCase "General" $ testBalanceSheet "AAPL" general
, testCase "Bank" $ testBalanceSheet "C" bank
, testCase "Insurance" $ testBalanceSheet "CB" insurance
]
, testGroup "Profit & Loss"
[ testCase "General" $ testProfitAndLoss "AAPL" general
, testCase "Bank" $ testProfitAndLoss "C" bank
, testCase "Insurance" $ testProfitAndLoss "CB" insurance
]
, testGroup "Cash Flow"
[ testCase "General" $ testCashFlow "AAPL" general
, testCase "Bank" $ testCashFlow "C" bank
, testCase "Insurance" $ testCashFlow "CB" insurance
]
-- This endpoint isn't different by industry types
, testGroup "Derived"
[ testCase "General" $ testDerived "AAPL"
, testCase "Bank" $ testDerived "C"
, testCase "Insurance" $ testDerived "CB"
]
, testGroup "Price"
[ testCase "General" $ testFetchPrices "AAPL"
, testCase "Bank" $ testFetchPrices "C"
, testCase "Insurance" $ testFetchPrices "CB"
]
]
where
testStmt :: (SimFinContext -> StatementQueryFree -> IO a) -> Text -> IO a
testStmt f ticker = f ctx $ testStatementQuery ticker
testBalanceSheet :: Text -> UnitIndustry -> Assertion
testBalanceSheet ticker industry = testFetchIndustry industry $ testStmt fetchBalanceSheet ticker
testProfitAndLoss :: Text -> UnitIndustry -> Assertion
testProfitAndLoss ticker industry = testFetchIndustry industry $ testStmt fetchProfitAndLoss ticker
testCashFlow :: Text -> UnitIndustry -> Assertion
testCashFlow ticker industry = testFetchIndustry industry $ testStmt fetchCashFlow ticker
testDerived :: Text -> Assertion
testDerived ticker = testFetchMaybe $ testStmt fetchDerived ticker
testFetchPrices :: StockRef -> IO ()
testFetchPrices ticker = testFetchList $ fetchPrices ctx ticker