Skip to content

Commit 4ce594d

Browse files
committed
Add tests for addColumn scenarios.
1 parent fbafe19 commit 4ce594d

File tree

3 files changed

+60
-4
lines changed

3 files changed

+60
-4
lines changed

src/Data/DataFrame/Operations.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ addColumn' name xs d
116116
Nothing -> xs
117117
Just (BoxedColumn col) -> Just $ BoxedColumn $ V.map Just col <> V.replicate diff Nothing
118118
Just (UnboxedColumn col) -> Just $ BoxedColumn $ V.map Just (V.convert col) <> V.replicate diff Nothing
119+
| diff < 0 = error "Column is too large to add"
119120
in d
120121
{ columns = columns' V.// [(n, xs')],
121122
columnIndices = M.insert name n (DI.columnIndices d),

test_coverage.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
- Adding columns > initial vector size gracefully adds a column that we can retrieve.
1515
- Adding columns > initial vector size gracefully adds a column updates dimentions.
1616
- Adding a column with the same name as an existing column overwrites the contents.
17-
- Adding a column with more values than the current DF dimensions throws an exception.
18-
- Adding a column with less values than the current DF dimensions adds column with optionals.
17+
- Adding a column with more values than the current DF dimensions throws an exception. DONE
18+
- Adding a column with less values than the current DF dimensions adds column with optionals. DONE
1919

2020
* addColumnWithDefault
2121
- Adding a column with less values than the current DF dimensions adds column with optionals.

tests/DataFrameTests.hs

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
{-# LANGUAGE TypeApplications #-}
22
{-# LANGUAGE OverloadedStrings #-}
3+
{-# LANGUAGE ScopedTypeVariables #-}
34
module Main where
45

56
import qualified Data.DataFrame as D
67
import qualified Data.DataFrame.Internal as DI
8+
import qualified Data.List as L
79
import qualified Data.Text as T
810
import qualified Data.Vector as V
911
import qualified Data.Vector.Unboxed as VU
1012
import qualified System.Exit as Exit
1113

14+
import Control.Exception
1215
import Test.HUnit
16+
import GHC.IO (unsafePerformIO)
1317

1418
testData :: D.DataFrame
1519
testData = D.addColumn "test1" (V.fromList ([1..26] :: [Int]))
@@ -61,6 +65,53 @@ addUnboxedColumn = TestCase (assertEqual "Value should be boxed"
6165
(Just $ DI.UnboxedColumn (VU.fromList [1 :: Int, 2, 3]))
6266
(DI.getColumn "new" $ D.addColumn "new" (V.fromList [1 :: Int, 2, 3]) D.empty))
6367

68+
-- Adding a column with less values than the current DF dimensions adds column with optionals.
69+
addSmallerColumnBoxed :: Test
70+
addSmallerColumnBoxed = TestCase (
71+
assertEqual "Missing values should be replaced with Nothing"
72+
(Just $ DI.BoxedColumn (V.fromList [Just "a" :: Maybe T.Text, Just "b", Just "c", Nothing, Nothing]))
73+
(DI.getColumn "newer" $ D.addColumn "newer" (V.fromList ["a" :: T.Text, "b", "c"]) $ D.addColumn "new" (V.fromList ["a" :: T.Text, "b", "c", "d", "e"]) D.empty)
74+
)
75+
76+
addSmallerColumnUnboxed :: Test
77+
addSmallerColumnUnboxed = TestCase (
78+
assertEqual "Missing values should be replaced with Nothing"
79+
(Just $ DI.BoxedColumn (V.fromList [Just 1 :: Maybe Int, Just 2, Just 3, Nothing, Nothing]))
80+
(DI.getColumn "newer" $ D.addColumn "newer" (V.fromList [1 :: Int, 2, 3]) $ D.addColumn "new" (V.fromList [1 :: Int, 2, 3, 4, 5]) D.empty)
81+
)
82+
83+
-- Adapted from: https://github.com/BartMassey/chunk/blob/1ee4bd6545e0db6b8b5f4935d97e7606708eacc9/hunit.hs#L29
84+
assertExpectException :: String -> String ->
85+
IO a -> Assertion
86+
assertExpectException preface expected action = do
87+
r <- catch
88+
(action >> (return . Just) "no exception thrown")
89+
(\(e::SomeException) ->
90+
return (checkForExpectedException e))
91+
case r of
92+
Nothing -> return ()
93+
Just msg -> assertFailure $ preface ++ ": " ++ msg
94+
where
95+
checkForExpectedException :: SomeException -> Maybe String
96+
checkForExpectedException e
97+
| expected `L.isInfixOf` show e = Nothing
98+
| otherwise =
99+
Just $ "wrong exception detail, expected " ++
100+
expected ++ ", got: " ++ show e
101+
102+
addLargerColumnBoxed :: Test
103+
addLargerColumnBoxed =
104+
TestCase (assertExpectException "[Error Case]"
105+
"Column is too large to add"
106+
(print $ D.addColumn "new" (V.fromList ["a" :: T.Text, "b", "c", "d", "e"])
107+
$ D.addColumn "newer" (V.fromList ["a" :: T.Text, "b", "c"]) D.empty))
108+
addLargerColumnUnboxed :: Test
109+
addLargerColumnUnboxed =
110+
TestCase (assertExpectException "[Error Case]"
111+
"Column is too large to add"
112+
(print $ D.addColumn "new" (V.fromList [1 :: Int, 2, 3, 4, 5])
113+
$ D.addColumn "newer" (V.fromList [1 :: Int, 2, 3]) D.empty))
114+
64115
dimensionsChangeAfterAdd :: Test
65116
dimensionsChangeAfterAdd = TestCase (assertEqual "should be (26, 3)"
66117
(26, 3)
@@ -74,11 +125,15 @@ dimensionsNotChangedAfterDuplicate = TestCase (assertEqual "should be (26, 3)"
74125

75126

76127
addColumnTest :: [Test]
77-
addColumnTest = [
128+
addColumnTest = [
78129
TestLabel "dimensionsChangeAfterAdd" dimensionsChangeAfterAdd
79130
, TestLabel "dimensionsNotChangedAfterDuplicate" dimensionsNotChangedAfterDuplicate
80131
, TestLabel "addBoxedColunmToEmpty" addBoxedColumn
81132
, TestLabel "addBoxedColumnAutoUnboxes" addBoxedColumn
133+
, TestLabel "addSmallerColumnBoxed" addSmallerColumnBoxed
134+
, TestLabel "addSmallerColumnUnboxed" addSmallerColumnUnboxed
135+
, TestLabel "addLargerColumnBoxed" addLargerColumnBoxed
136+
, TestLabel "addLargerColumnUnboxed" addLargerColumnUnboxed
82137
]
83138

84139
tests :: Test
@@ -89,4 +144,4 @@ tests = TestList $ dimensionsTest
89144
main :: IO ()
90145
main = do
91146
result <- runTestTT tests
92-
if failures result > 0 then Exit.exitFailure else Exit.exitSuccess
147+
if failures result > 0 || errors result > 0 then Exit.exitFailure else Exit.exitSuccess

0 commit comments

Comments
 (0)