hw-dsv-0.3.8: test/HaskellWorks/Data/Dsv/Lazy/CursorSpec.hs
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
module HaskellWorks.Data.Dsv.Lazy.CursorSpec (spec) where
import Data.Semigroup ((<>))
import HaskellWorks.Data.Bits.BitShown
import HaskellWorks.Data.Dsv.Internal.Char (comma)
import HaskellWorks.Hspec.Hedgehog
import Hedgehog
import Test.Hspec
import qualified Data.ByteString.Lazy as LBS
import qualified Data.Vector as DV
import qualified HaskellWorks.Data.Dsv.Lazy.Cursor as SVL
import qualified HaskellWorks.Data.Dsv.Lazy.Cursor.Lazy as SVLL
{-# ANN module ("HLint: ignore Redundant do" :: String) #-}
{-# ANN module ("HLint: ignore Reduce duplication" :: String) #-}
{-# ANN module ("HLint: ignore Redundant bracket" :: String) #-}
subjectEmpty, subjectSS, subjectSM, subjectMS, subjectMM :: LBS.ByteString
expectedEmpty, expectedSS, expectedSM, expectedMS, expectedMM :: [DV.Vector LBS.ByteString]
subjectEmpty = ""
expectedEmpty = mkExpected []
subjectSS = "hello"
expectedSS = mkExpected [["hello"]]
subjectSM = "hello\nyes"
expectedSM = mkExpected [["hello"],["yes"]]
subjectMS = "hello,goodbye"
expectedMS = mkExpected [["hello","goodbye"]]
subjectMM = "hello,goodbye\nyes,no"
expectedMM = mkExpected [["hello","goodbye"],["yes","no"]]
testToListVector :: LBS.ByteString -> [DV.Vector LBS.ByteString]
testToListVector = SVLL.toListVector . SVL.makeCursor comma
testToListList :: LBS.ByteString -> [[LBS.ByteString]]
testToListList = fmap DV.toList . testToListVector
-- Adds a terminal newline to the file
testToListVector' :: LBS.ByteString -> [DV.Vector LBS.ByteString]
testToListVector' = testToListVector . (<> "\n")
mkExpected :: [[LBS.ByteString]] -> [DV.Vector LBS.ByteString]
mkExpected = fmap DV.fromList
spec :: Spec
spec = describe "HaskellWorks.Data.Dsv.Lazy.CursorSpec" $ do
-- no terminal newline
it "Case 1" $ requireTest $ do
testToListVector subjectEmpty === expectedEmpty
it "Case 2" $ requireTest $ do
testToListVector subjectSS === expectedSS
it "Case 3" $ requireTest $ do
testToListVector subjectSM === expectedSM
it "Case 4" $ requireTest $ do
testToListVector subjectMS === expectedMS
it "Case 5" $ requireTest $ do
testToListVector subjectMM === expectedMM
-- terminal newline
-- the following test does not pass
--it "Case 6" $ requireTest $ do
--testToListVector' subjectEmpty === expectedEmpty
it "Case 7" $ requireTest $ do
testToListVector' subjectSS === expectedSS
it "Case 8" $ requireTest $ do
testToListVector' subjectSM === expectedSM
it "Case 9" $ requireTest $ do
testToListVector' subjectMS === expectedMS
it "Case 10" $ requireTest $ do
testToListVector' subjectMM === expectedMM
describe "boundaries" $ do
it "513 bytes" $ requireTest $ do
let actual = testToListList $ LBS.intercalate "\n"
[ "id,group_id,arm,first_name,last_name,email,contact_number,start_date,status,dose_smart_id,fitbit_id,glyco_id,sms_reminder,email_reminder,inactive_reminder,starting_weight,starting_bmi,starting_hba1c"
, "10,aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,1,aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,aaaaaaa,aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,2018-01-01 00:00:00 UTC,Active,,,,Never,Weekly,Never,100.01,10.01,1.0e-2"
]
actual ===
[ [ "id"
, "group_id"
, "arm"
, "first_name"
, "last_name"
, "email"
, "contact_number"
, "start_date"
, "status"
, "dose_smart_id"
, "fitbit_id"
, "glyco_id"
, "sms_reminder"
, "email_reminder"
, "inactive_reminder"
, "starting_weight"
, "starting_bmi"
, "starting_hba1c"
]
, [ "10"
, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
, "1"
, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
, "aaaaaaa"
, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
, "2018-01-01 00:00:00 UTC"
, "Active"
, ""
, ""
, ""
, "Never"
, "Weekly"
, "Never"
, "100.01"
, "10.01"
, "1.0e-2"
]
]
it "512 bytes" $ requireTest $ do
let actual = testToListList $ LBS.intercalate "\n"
[ "id,group_id,arm,first_name,last_name,email,contact_number,start_date,status,dose_smart_id,fitbit_id,glyco_id,sms_reminder,email_reminder,inactive_reminder,starting_weight,starting_bmi,starting_hba1c"
, "10,aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,1,aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,aaaaaaa,aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,2018-01-01 00:00:00 UTC,Active,,,,Never,Weekly,Never,100.01,10.01,1.0e-2"
]
actual ===
[ [ "id"
, "group_id"
, "arm"
, "first_name"
, "last_name"
, "email"
, "contact_number"
, "start_date"
, "status"
, "dose_smart_id"
, "fitbit_id"
, "glyco_id"
, "sms_reminder"
, "email_reminder"
, "inactive_reminder"
, "starting_weight"
, "starting_bmi"
, "starting_hba1c"
]
, [ "10"
, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
, "1"
, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
, "aaaaaaa"
, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
, "2018-01-01 00:00:00 UTC"
, "Active"
, ""
, ""
, ""
, "Never"
, "Weekly"
, "Never"
, "100.01"
, "10.01"
, "1.0e-2"
]
]
it "511 bytes" $ requireTest $ do
let actual = testToListList $ LBS.intercalate "\n"
[ "id,group_id,arm,first_name,last_name,email,contact_number,start_date,status,dose_smart_id,fitbit_id,glyco_id,sms_reminder,email_reminder,inactive_reminder,starting_weight,starting_bmi,starting_hba1c"
, "10,aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,1,aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,aaaaaaa,aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,2018-01-01 00:00:00 UTC,Active,,,,Never,Weekly,Never,100.01,10.01,1.0e-2"
]
actual ===
[ [ "id"
, "group_id"
, "arm"
, "first_name"
, "last_name"
, "email"
, "contact_number"
, "start_date"
, "status"
, "dose_smart_id"
, "fitbit_id"
, "glyco_id"
, "sms_reminder"
, "email_reminder"
, "inactive_reminder"
, "starting_weight"
, "starting_bmi"
, "starting_hba1c"
]
, [ "10"
, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
, "1"
, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
, "aaaaaaa"
, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
, "2018-01-01 00:00:00 UTC"
, "Active"
, ""
, ""
, ""
, "Never"
, "Weekly"
, "Never"
, "100.01"
, "10.01"
, "1.0e-2"
]
]
describe "single quoted field with newline at 127-129" $ do
it "newline at 127 bytes" $ requireTest $ do
let newlinePos = 127
let text = "\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n\""
let expected = [["\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n\""]]
let cursor = SVL.makeCursor 44 text
_ <- forAll $ pure $ BitShown (head (SVL.dsvCursorMarkers cursor))
_ <- forAll $ pure $ BitShown (head (SVL.dsvCursorNewlines cursor))
let actual = fmap DV.toList (DV.toList (SVLL.toVectorVector cursor))
LBS.length text === newlinePos + 2
LBS.index text newlinePos === 10
actual === expected
it "newline at 128 bytes" $ requireTest $ do
let newlinePos = 128
let text = "\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n\""
let expected = [["\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n\""]]
let cursor = SVL.makeCursor 44 text
_ <- forAll $ pure $ BitShown (head (SVL.dsvCursorMarkers cursor))
_ <- forAll $ pure $ BitShown (head (SVL.dsvCursorNewlines cursor))
let actual = fmap DV.toList (DV.toList (SVLL.toVectorVector cursor))
LBS.length text === newlinePos + 2
LBS.index text newlinePos === 10
actual === expected
it "newline at 129 bytes" $ requireTest $ do
let newlinePos = 129
let text = "\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n\""
let expected = [["\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n\""]]
let cursor = SVL.makeCursor 44 text
_ <- forAll $ pure $ BitShown (head (SVL.dsvCursorMarkers cursor))
_ <- forAll $ pure $ BitShown (head (SVL.dsvCursorNewlines cursor))
let actual = fmap DV.toList (DV.toList (SVLL.toVectorVector cursor))
LBS.length text === newlinePos + 2
LBS.index text newlinePos === 10
actual === expected