@@ -14,8 +14,10 @@ import Control.Applicative (Const)
1414import qualified Data.ByteString as B
1515import qualified Data.ByteString.Lazy as BL
1616import qualified Data.ByteString.Lazy.Char8 as BL8
17+ import Data.Char (toLower )
1718import qualified Data.HashMap.Strict as HM
1819import Data.Int
20+ import qualified Data.List as L
1921import Data.Scientific (Scientific )
2022import qualified Data.Text as T
2123import qualified Data.Text.Lazy as LT
@@ -448,6 +450,71 @@ instance DefaultOrdered SampleType where
448450instance Arbitrary SampleType where
449451 arbitrary = SampleType <$> arbitrary <*> arbitrary <*> arbitrary
450452
453+ ------------------------------------------------------------------------
454+ -- Generic ToField/FromField tests
455+
456+ data Foo = Foo
457+ deriving (Eq , Generic , Show )
458+
459+ instance FromField Foo
460+ instance ToField Foo
461+
462+ -- -- Should not compile
463+ --
464+ -- -- Newtype
465+ -- newtype Foo1 = Foo1 Int deriving (Eq, Generic, Show)
466+ -- instance FromField Foo1
467+ -- instance ToField Foo1
468+ -- newtype FooRec1 = FooRec1 { unFooRec1 :: Int } deriving (Eq, Generic, Show)
469+ -- instance FromField FooRec1
470+ -- instance ToField FooRec1
471+ -- newtype FooRecF1 a = FooRecF1 { unFooRecF1 :: a } deriving (Eq, Generic, Show)
472+ -- instance (FromField a) => FromField (FooRecF1 a)
473+ -- instance (ToField a) => ToField (FooRecF1 a)
474+ -- -- Product
475+ -- data Foo2 = Foo2 Char Int deriving (Eq, Generic, Show)
476+ -- instance FromField Foo2
477+ -- instance ToField Foo2
478+
479+ data Bar = BarN1 | BarU Int | BarN2
480+ deriving (Eq , Generic , Show )
481+
482+ instance FromField Bar
483+ instance ToField Bar
484+ instance Arbitrary Bar where
485+ arbitrary = frequency [(1 , pure BarN1 ), (3 , BarU <$> arbitrary), (1 , pure BarN2 )]
486+
487+ data BazEnum = BazOne | BazTwo | BazThree
488+ deriving (Bounded , Enum , Eq , Generic , Show )
489+
490+ instance FromField BazEnum where
491+ parseField = genericParseField bazOptions
492+ instance ToField BazEnum where
493+ toField = genericToField bazOptions
494+ instance Arbitrary BazEnum where
495+ arbitrary = elements [minBound .. maxBound ]
496+
497+ bazOptions :: Options
498+ bazOptions = defaultOptions { fieldLabelModifier = go }
499+ where go = maybe (error " No prefix Baz" ) (map toLower) . L. stripPrefix " Baz"
500+
501+ genericFieldTests :: [TF. Test ]
502+ genericFieldTests =
503+ [ testGroup " nullary constructor"
504+ [ testCase " encoding" $ toField Foo @?= " Foo"
505+ , testCase " decoding" $ runParser (parseField " Foo" ) @?= Right Foo ]
506+ , testCase " decoding failure" $ runParser (parseField " foo" )
507+ @?= (Left " Expected \" Foo\" " :: Either String Foo )
508+ , testProperty " sum type roundtrip" (roundtripProp :: Bar -> Bool )
509+ , testGroup " constructor modifier"
510+ [ testCase " encoding" $ toField BazOne @?= " one"
511+ , testCase " decoding" $ runParser (parseField " two" ) @?= Right BazTwo
512+ , testProperty " roundtrip" (roundtripProp :: BazEnum -> Bool ) ]
513+ ]
514+ where
515+ roundtripProp :: (Eq a , FromField a , ToField a ) => a -> Bool
516+ roundtripProp x = runParser (parseField $ toField x) == Right x
517+
451518------------------------------------------------------------------------
452519-- Test harness
453520
@@ -458,6 +525,7 @@ allTests = [ testGroup "positional" positionalTests
458525 , testGroup " custom-options" customOptionsTests
459526 , testGroup " instances" instanceTests
460527 , testGroup " generic-conversions" genericConversionTests
528+ , testGroup " generic-field-conversions" genericFieldTests
461529 ]
462530
463531main :: IO ()
0 commit comments