dataframe-1.1.1.0: tests/IO/CSV.hs
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeApplications #-}
module IO.CSV where
import qualified Data.ByteString.Lazy as BL
import qualified Data.Text as T
import qualified Data.Text.Encoding as TE
import qualified DataFrame as D
import DataFrame.IO.CSV (fromCsv, fromCsvBytes)
import qualified DataFrame.Internal.Column as DI
import DataFrame.Internal.DataFrame (DataFrame (..), toCsv)
import qualified DataFrame.Operations.Core as D
import Test.HUnit (
Test (TestCase, TestLabel),
assertEqual,
assertFailure,
)
-- | Happy path: parse a simple CSV string with Int and Text columns.
fromCsvHappyPath :: Test
fromCsvHappyPath = TestLabel "fromCsv_happy_path" $ TestCase $ do
result <- fromCsv "name,age\nAlice,30\nBob,25\nCharlie,35\n"
case result of
Left err -> assertFailure $ "Unexpected Left: " ++ err
Right df -> do
assertEqual "rows" 3 (D.nRows df)
assertEqual "columns" 2 (D.nColumns df)
-- | Empty input should return a Left.
fromCsvEmpty :: Test
fromCsvEmpty = TestLabel "fromCsv_empty" $ TestCase $ do
result <- fromCsv ""
case result of
Left _ -> return ()
Right _ -> assertFailure "Expected Left for empty input"
-- | fromCsvBytes happy path.
fromCsvBytesHappyPath :: Test
fromCsvBytesHappyPath = TestLabel "fromCsvBytes_happy_path" $ TestCase $ do
let bs = BL.fromStrict (TE.encodeUtf8 "x,y\n1,2\n3,4\n")
df <- fromCsvBytes bs
assertEqual "rows" 2 (D.nRows df)
assertEqual "columns" 2 (D.nColumns df)
-- | Round trip: toCsv then fromCsv preserves data.
fromCsvRoundTrip :: Test
fromCsvRoundTrip = TestLabel "fromCsv_roundTrip" $ TestCase $ do
let df =
D.fromNamedColumns
[ ("a", DI.fromList @Int [1, 2, 3])
, ("b", DI.fromList @T.Text ["hello", "world", "test"])
]
let csvString = T.unpack (toCsv df)
result <- fromCsv csvString
case result of
Left err -> assertFailure $ "Unexpected Left: " ++ err
Right df' -> do
assertEqual
"round trip dimensions"
(dataframeDimensions df)
(dataframeDimensions df')
assertEqual "round trip data" df df'
-- | Round trip via fromCsvBytes.
fromCsvBytesRoundTrip :: Test
fromCsvBytesRoundTrip = TestLabel "fromCsvBytes_roundTrip" $ TestCase $ do
let df =
D.fromNamedColumns
[ ("x", DI.fromList @Int [10, 20])
, ("y", DI.fromList @Double [1.5, 2.5])
]
let bs = BL.fromStrict (TE.encodeUtf8 (toCsv df))
df' <- fromCsvBytes bs
assertEqual
"round trip dimensions"
(dataframeDimensions df)
(dataframeDimensions df')
-- | Single column CSV.
fromCsvSingleColumn :: Test
fromCsvSingleColumn = TestLabel "fromCsv_single_column" $ TestCase $ do
result <- fromCsv "id\n10\n20\n30\n"
case result of
Left err -> assertFailure $ "Unexpected Left: " ++ err
Right df -> do
assertEqual "rows" 3 (D.nRows df)
assertEqual "columns" 1 (D.nColumns df)
tests :: [Test]
tests =
[ fromCsvHappyPath
, fromCsvEmpty
, fromCsvBytesHappyPath
, fromCsvRoundTrip
, fromCsvBytesRoundTrip
, fromCsvSingleColumn
]