@@ -33,15 +33,15 @@ import Data.Aeson.Parser
33 ( json, jsonLast, jsonAccum, jsonNoDup
33 ( json, jsonLast, jsonAccum, jsonNoDup
34 , json', jsonLast', jsonAccum', jsonNoDup')
34 , json', jsonLast', jsonAccum', jsonNoDup')
35import Data.Aeson.Types
35import Data.Aeson.Types
36− ( Options(..), Result(Success, Error), ToJSON(..)
36+ ( Options(..), Result(Success), ToJSON(..), Value(Array, Bool, Null, Object)
37− , Value(Array, Bool, Null, Number, Object, String), camelTo, camelTo2
38− , defaultOptions, formatPath, formatRelativePath, omitNothingFields, parse)
37+ , camelTo, camelTo2, defaultOptions, formatPath, formatRelativePath
38+ , omitNothingFields, parse)
39import Data.Attoparsec.ByteString (Parser, parseOnly)
39import Data.Attoparsec.ByteString (Parser, parseOnly)
40import Data.Char (toUpper)
40import Data.Char (toUpper)
41import Data.Either.Compat (isLeft, isRight)
41import Data.Either.Compat (isLeft, isRight)
42import Data.Hashable (hash)
42import Data.Hashable (hash)
43import Data.HashMap.Strict (HashMap)
43import Data.HashMap.Strict (HashMap)
44−import Data.List (sort, isSuffixOf)
44+import Data.List (sort)
45import Data.Maybe (fromMaybe)
45import Data.Maybe (fromMaybe)
46import Data.Scientific (Scientific, scientific)
46import Data.Scientific (Scientific, scientific)
47import Data.Tagged (Tagged(..))
47import Data.Tagged (Tagged(..))
@@ -112,12 +112,8 @@ tests = testGroup "unit" [
112 , testGroup "SingleMaybeField" singleMaybeField
112 , testGroup "SingleMaybeField" singleMaybeField
113 , testCase "withEmbeddedJSON" withEmbeddedJSONTest
113 , testCase "withEmbeddedJSON" withEmbeddedJSONTest
114 , testCase "SingleFieldCon" singleFieldCon
114 , testCase "SingleFieldCon" singleFieldCon
115− , testGroup "UnknownFields" unknownFields
116 , testGroup "Ordering of object keys" keyOrdering
115 , testGroup "Ordering of object keys" keyOrdering
117 , testCase "Ratio with denominator 0" ratioDenominator0
116 , testCase "Ratio with denominator 0" ratioDenominator0
118− , testCase "Rational parses number" rationalNumber
119− , testCase "Big rational" bigRationalDecoding
120− , testCase "Small rational" smallRationalDecoding
121 , testCase "Big scientific exponent" bigScientificExponent
117 , testCase "Big scientific exponent" bigScientificExponent
122 , testCase "Big integer decoding" bigIntegerDecoding
118 , testCase "Big integer decoding" bigIntegerDecoding
123 , testCase "Big natural decading" bigNaturalDecoding
119 , testCase "Big natural decading" bigNaturalDecoding
@@ -540,7 +536,6 @@ showOptions =
540 ++ ", sumEncoding = TaggedObject {tagFieldName = \"tag\", contentsFieldName = \"contents\"}"
536 ++ ", sumEncoding = TaggedObject {tagFieldName = \"tag\", contentsFieldName = \"contents\"}"
541 ++ ", unwrapUnaryRecords = False"
537 ++ ", unwrapUnaryRecords = False"
542 ++ ", tagSingleConstructors = False"
538 ++ ", tagSingleConstructors = False"
543− ++ ", rejectUnknownFields = False"
545 (show defaultOptions)
540 (show defaultOptions)
@@ -585,79 +580,6 @@ singleFieldCon :: Assertion
585singleFieldCon =
580singleFieldCon =
586 assertEqual "fromJSON" (Right (SingleFieldCon 0)) (eitherDecode "0")
581 assertEqual "fromJSON" (Right (SingleFieldCon 0)) (eitherDecode "0")
588−newtype UnknownFields = UnknownFields { knownField :: Int }
589− deriving (Eq, Show, Generic)
590−newtype UnknownFieldsTag = UnknownFieldsTag { tag :: Int }
591− deriving (Eq, Show, Generic)
592−newtype UnknownFieldsUnaryTagged = UnknownFieldsUnaryTagged { knownFieldUnaryTagged :: Int }
593− deriving (Eq, Show, Generic)
594−data UnknownFieldsSum
595− = UnknownFields1 { knownField1 :: Int }
596− | UnknownFields2 { knownField2 :: Int }
597− deriving (Eq, Show, Generic)
599−unknownFields :: [TestTree]
600−unknownFields = concat
603− (object [("knownField", Number 1), ("unknownField", Number 1)])
604− (Error "nknown fields: [\"unknownField\"]" :: Result UnknownFields)
607− (object [("knownField", Number 1), ("tag", String "UnknownFields")])
608− (Error "nknown fields: [\"tag\"]" :: Result UnknownFields)
610− "unary-explicit-tag"
611− (object [("tag", Number 1)])
612− (Success $ UnknownFieldsTag 1)
615− (object [("knownField1", Number 1), ("tag", String "UnknownFields1")])
616− (Success $ UnknownFields1 1)
618− "sum-unknown-in-branch"
619− (object [("knownField1", Number 1), ("knownField2", Number 1), ("tag", String "UnknownFields1")])
620− (Error "nknown fields: [\"knownField2\"]" :: Result UnknownFieldsSum)
623− (object [("knownField1", Number 1), ("unknownField", Number 1), ("tag", String "UnknownFields1")])
624− (Error "nknown fields: [\"unknownField\"]" :: Result UnknownFieldsSum)
627− (object [("knownFieldUnaryTagged", Number 1), ("tag", String "UnknownFieldsUnaryTagged")])
628− (Success $ UnknownFieldsUnaryTagged 1)
629− , -- Just a case to verify that the tag isn't optional, this is likely already tested by other unit tests
631− "unary-tagged-notag"
632− (object [("knownFieldUnaryTagged", Number 1)])
633− (Error "key \"tag\" not found" :: Result UnknownFieldsUnaryTagged)
635− "unary-tagged-unknown"
636− (object [ ("knownFieldUnaryTagged", Number 1), ("unknownField", Number 1)
637− , ("tag", String "UnknownFieldsUnaryTagged")])
638− (Error "nknown fields: [\"unknownField\"]" :: Result UnknownFieldsUnaryTagged)
641− opts = defaultOptions{rejectUnknownFields=True}
642− taggedOpts = opts{tagSingleConstructors=True}
643− assertApprox :: (Show a, Eq a) => Result a -> Result a -> IO ()
644− assertApprox (Error expected) (Error actual) | expected `isSuffixOf` actual = return ()
645− assertApprox expected actual = assertEqual "fromJSON" expected actual
646− testsBase :: (Show a, Eq a) => (Value -> Result a) -> (Value -> Result a)
647− -> String -> Value -> Result a -> [TestTree]
648− testsBase th g name value expected =
649− [ testCase (name ++ "-th") $ assertApprox expected (th value)
650− , testCase (name ++ "-generic") $ assertApprox expected (g value)
652− testsUnary :: String -> Value -> Result UnknownFields -> [TestTree]
653− testsUnary = testsBase fromJSON (parse (genericParseJSON opts))
654− testsUnaryTag :: String -> Value -> Result UnknownFieldsTag -> [TestTree]
655− testsUnaryTag = testsBase fromJSON (parse (genericParseJSON opts))
656− testsSum :: String -> Value -> Result UnknownFieldsSum -> [TestTree]
657− testsSum = testsBase fromJSON (parse (genericParseJSON opts))
658− testsTagged :: String -> Value -> Result UnknownFieldsUnaryTagged -> [TestTree]
659− testsTagged = testsBase fromJSON (parse (genericParseJSON taggedOpts))
661testParser :: (Eq a, Show a)
583testParser :: (Eq a, Show a)
662 => String -> Parser a -> S.ByteString -> Either String a -> TestTree
584 => String -> Parser a -> S.ByteString -> Either String a -> TestTree
663testParser name json_ s expected =
585testParser name json_ s expected =
@@ -698,25 +620,6 @@ ratioDenominator0 =
698 (Left "Error in $: Ratio denominator was 0")
620 (Left "Error in $: Ratio denominator was 0")
699 (eitherDecode "{ \"numerator\": 1, \"denominator\": 0 }" :: Either String Rational)
621 (eitherDecode "{ \"numerator\": 1, \"denominator\": 0 }" :: Either String Rational)
701−rationalNumber :: Assertion
703− assertEqual "Ratio with denominator 0"
705− (eitherDecode "1.37" :: Either String Rational)
707−bigRationalDecoding :: Assertion
708−bigRationalDecoding =
709− assertEqual "Decoding an Integer with a large exponent should fail"
710− (Left "Error in $: parsing Ratio failed, found a number with exponent 2000, but it must not be greater than 1024 or less than -1024")
711− ((eitherDecode :: L.ByteString -> Either String Rational) "1e2000")
713−smallRationalDecoding :: Assertion
714−smallRationalDecoding =
715− assertEqual "Decoding an Integer with a large exponent should fail"
716− (Left "Error in $: parsing Ratio failed, found a number with exponent -2000, but it must not be greater than 1024 or less than -1024")
717− ((eitherDecode :: L.ByteString -> Either String Rational) "1e-2000")
720bigScientificExponent :: Assertion
623bigScientificExponent :: Assertion
721bigScientificExponent =
624bigScientificExponent =
722 assertEqual "Encoding an integral scientific with a large exponent should normalize it"
625 assertEqual "Encoding an integral scientific with a large exponent should normalize it"
@@ -753,8 +656,3 @@ deriveToJSON defaultOptions ''Foo
753deriveToJSON1 defaultOptions ''Foo
656deriveToJSON1 defaultOptions ''Foo
755deriveJSON defaultOptions{omitNothingFields=True,unwrapUnaryRecords=True} ''SingleMaybeField
658deriveJSON defaultOptions{omitNothingFields=True,unwrapUnaryRecords=True} ''SingleMaybeField
757−deriveJSON defaultOptions{rejectUnknownFields=True} ''UnknownFields
758−deriveJSON defaultOptions{rejectUnknownFields=True} ''UnknownFieldsTag
759−deriveJSON defaultOptions{tagSingleConstructors=True,rejectUnknownFields=True} ''UnknownFieldsUnaryTagged
760−deriveJSON defaultOptions{rejectUnknownFields=True} ''UnknownFieldsSum