addy-0.1.0.0: test/RenderTest.hs
-- |
--
-- Copyright:
-- This file is part of the package addy. It is subject to the license
-- terms in the LICENSE file found in the top-level directory of this
-- distribution and at:
--
-- https://code.devalot.com/open/addy
--
-- No part of this package, including this file, may be copied,
-- modified, propagated, or distributed except according to the terms
-- contained in the LICENSE file.
--
-- License: BSD-2-Clause
module RenderTest
( test,
)
where
import qualified Addy.Internal.Parser as Parser
import Addy.Internal.Render
import Addy.Internal.Types
import Data.Char
import qualified Data.Text as Text
import qualified Data.Text.Lazy.Builder as TB
import Test.Tasty (TestTree, testGroup)
import Test.Tasty.HUnit
import TestData
test :: TestTree
test =
testGroup
"Render"
[ testCase "isemail tests" testFromisEmailTests,
testCase "RFC 5322 examples" testRfcExamples,
testCase "Obsolete examples" testObsExamples,
testCase "Oddities" testOddities,
testCase "Wikipedia" testWikipediaExamples,
testCase "Misc" testMiscExamples
]
testRfcExamples :: Assertion
testRfcExamples =
mapM_ go rfc5322Examples
where
go :: (Text, Text) -> Assertion
go (source, expectS) = do
(_, actualS, actualF) <- roundTrip Parser.Strict source
let expectF =
-- We don't render the brackets unless they are needed.
if Text.isPrefixOf "<" source
&& Text.isSuffixOf ">" source
then Text.drop 1 (Text.dropEnd 1 source)
else source
actualS @?= expectS
actualF @?= expectF
idempotentTest actualS actualF
testObsExamples :: Assertion
testObsExamples =
mapM_ go rfc5322ObsExamples
where
go :: (Text, Text, Text) -> Assertion
go (source, simple, full) = do
(_, actualS, actualF) <- roundTrip Parser.Lenient source
actualS @?= simple
actualF @?= full
idempotentTest actualS actualF
-- | Weird stuff that we'll parse but won't render.
testOddities :: Assertion
testOddities =
mapM_
go
[ ( "(some (ne(st)ed) comment) example@example.com",
"(some nested comment) example@example.com",
"example@example.com"
)
]
where
go :: (Text, Text, Text) -> Assertion
go (source, full, simple) = do
(_, actualS, actualF) <- roundTrip Parser.Strict source
actualS @?= simple
actualF @?= full
testMiscExamples :: Assertion
testMiscExamples =
forM_ miscExamples $ \source -> do
(_, actualS, actualF) <- roundTrip Parser.Strict source
actualS @?= source
actualF @?= source
testFromisEmailTests :: Assertion
testFromisEmailTests = do
tests <- isEmailTests
mapM_
go
( filter
( \(iet, cat) ->
cat == CatOkay
&& ietId iet /= 42 -- Unnecessary quoting.
&& ietId iet /= 45 -- Unnecessary quoting.
&& ietId iet /= 55 -- Unnecessary quoting.
&& ietId iet /= 60 -- Unnecessary quoting.
&& ietId iet /= 79 -- We format better.
&& ietId iet /= 81 -- We format better.
&& ietId iet /= 85 -- We format better.
&& ietId iet /= 88 -- We strip \r\n.
&& ietId iet /= 92 -- We flattten comments.
&& ietId iet /= 144 -- We strip \r\n.
&& ietId iet /= 148 -- We strip \r\n.
&& ietId iet /= 153 -- We strip \r\n.
)
tests
)
where
go :: (IsEmailTest, IsEmailCat) -> Assertion
go (iet, _) = do
(_, _, actualF) <- roundTrip Parser.Strict (ietAddr iet)
fixup actualF @?= fixup (ietAddr iet)
-- Ignore white space changes and revert IPv6 address formatting
fixup :: Text -> Text
fixup = Text.filter (not . isSpace) . Text.replace ":0:" "::"
testWikipediaExamples :: Assertion
testWikipediaExamples =
mapM_ go wikipediaIntExamples
where
go :: Text -> Assertion
go source = do
(_, simple, full) <- roundTrip Parser.Strict source
simple @?= source
full @?= source
roundTrip :: MonadFail m => Parser.Mode -> Text -> m (EmailAddr, Text, Text)
roundTrip pmode t =
case Parser.parseWithMode pmode t of
Left e -> fail (show t <> " " <> show e)
Right addr ->
pure
( addr,
toStrict $ TB.toLazyText (render Short addr),
toStrict $ TB.toLazyText (render Full addr)
)
-- | Test that parsing the rendered output and then rendering it again
-- produces the same results.
idempotentTest :: Text -> Text -> Assertion
idempotentTest simple full = do
(_, x, y) <- roundTrip Parser.Strict simple
x @?= simple -- Parsing and rending a simple address should
y @?= simple -- produce a simple rendering both times.
(_, z, w) <- roundTrip Parser.Strict full
z @?= simple
w @?= full