fb-util-0.1.0.1: tests/UnitTests.hs
{-
Copyright (c) Meta Platforms, Inc. and affiliates.
All rights reserved.
This source code is licensed under the BSD-style license found in the
LICENSE file in the root directory of this source tree.
-}
{-# LANGUAGE CPP #-}
module UnitTests (main) where
import Test.HUnit
import TestRunner
import Util.ByteString
import Util.Aeson
import qualified Util.Text as UT
import Data.Aeson.Types
import Data.Aeson (decode)
import Data.ByteString (packCString, packCStringLen, ByteString)
import Foreign.Storable
import Foreign.C.String
import Foreign.C.Types
import Foreign.Marshal.Array (advancePtr)
import Foreign.Ptr (nullPtr, Ptr)
import TextShow
intToByteStringTest :: Test
intToByteStringTest = TestCase $ do
assertEqual "min int" (intToByteString minBound) "-9223372036854775808"
assertEqual "max int" (intToByteString maxBound) "9223372036854775807"
assertEqual "zero" (intToByteString 0) "0"
parseValueStrictTest :: Test
parseValueStrictTest = TestCase $ do
assertEqual "false" (Right $ Bool False) $ parseValueStrict' "false"
assertEqual "0.1" (Right $ Number 0.1) $ parseValueStrict' "0.1"
assertEqual "consume all input" (Left "endOfInput") $
parseValueStrict' "falsee"
#ifdef FACEBOOK
-- | We've patched the official aeson library to handle NaN. See #5183005
-- This test ensures that we notice if we forget to patch on upgrade.
parseNaN :: Test
parseNaN = TestCase $
case decode "[NaN]" of
Just [a :: Double] ->
assertBool "NaN" $ isNaN a
_ -> assertFailure "couldn't parse NaN"
#endif
withCStringLenTest :: Test
withCStringLenTest = TestCase $
UT.withCStringLen "Hello World" $ \(ptr, _) -> do
val <- peek ptr
assertEqual "first character" val (castCharToCChar 'H')
useByteStringsAsCStringsTest :: Test
useByteStringsAsCStringsTest = TestCase $
useByteStringsAsCStrings ["hello", "world"] $ \ptr -> do
hello <- packCString =<< peek ptr
world <- packCString =<< peek (advancePtr ptr 1)
term <- peek $ advancePtr ptr 2
assertEqual "first word" hello "hello"
assertEqual "second word" world "world"
assertEqual "terminator" term nullPtr
-- This should probably be a QuickCheck Property
bsListAsCStrLenArrTest :: [ByteString] -> Test
bsListAsCStrLenArrTest bs = TestCase $
bsListAsCStrLenArr bs $ \strPtr lenPtr len -> do
let packBS :: CSize -> IO ByteString
packBS i = packCStringLen =<< (,)
<$> peek (getPtr strPtr)
<*> (fromIntegral <$> peek (getPtr lenPtr))
where getPtr :: Storable a => Ptr a -> Ptr a
getPtr = (`advancePtr` fromIntegral i)
got <- mapM packBS [0..len - 1]
assertEqual "same list" got bs
data MyEnum = MyA | MyB
deriving (Bounded, Enum, Eq, Show)
instance UT.TextRead MyEnum
instance TextShow MyEnum where
showb MyA = "MyA"
showb MyB = "MyB"
readTextTest :: Test
readTextTest = TestCase $ do
assertEqual "myA" (Just MyA) (UT.readText "MyA")
assertEqual "Nothing" (Nothing :: Maybe MyEnum) (UT.readText "MyC")
insertCommasAndAndTest :: Test
insertCommasAndAndTest = TestCase $ do
assertEqual "null" "" $ UT.insertCommasAndAnd []
assertEqual "singleton" "foo" $ UT.insertCommasAndAnd ["foo"]
assertEqual "pair" "foo and bar" $ UT.insertCommasAndAnd ["foo", "bar"]
assertEqual "triple" "foo, bar, and baz" $
UT.insertCommasAndAnd ["foo", "bar", "baz"]
assertEqual "quad" "foo, bar, baz, and quux" $
UT.insertCommasAndAnd ["foo", "bar", "baz", "quux"]
assertEqual "10" "1, 2, 3, 4, 5, 6, 7, 8, 9, and 10" $
UT.insertCommasAndAnd [ showt (i::Int) | i <- [1..10] ]
main :: IO ()
main = testRunner $ TestList
[ TestLabel "intToByteString" intToByteStringTest
, TestLabel "parseValueStrictTest" parseValueStrictTest
#ifdef FACEBOOK
, TestLabel "parseNaN" parseNaN
#endif
, TestLabel "withCStringLen" withCStringLenTest
, TestLabel "useByteStringsAsCStrings" useByteStringsAsCStringsTest
, TestLabel "bsListAsCStrLenArr" (bsListAsCStrLenArrTest ["hello", "world"])
, TestLabel "readText" readTextTest
, TestLabel "insertCommasAndAnd" insertCommasAndAndTest
]