on master help sign in
Clean up some of the high weirdness of the ZonedTime tests
commit838a626815d12d602895fd6d83516fbb51335d76 authorBryan O'Sullivan <bos@serpentine.com> dateMon 25 May 2015, 22:45 (11 years ago) parent297b5bd
3 files changed+57−54
tests/Properties.hs+9−8 tests/Properties/ZonedTime.hs+43−46 tests/Types.hs+5
tests/Properties.hs+9−8
@@ -10,7 +10,7 @@ import Test.Framework (Test, defaultMain, testGroup)
1010import Test.Framework.Providers.QuickCheck2 (testProperty)
1111import Test.Framework.Providers.HUnit (testCase)
1212import Test.HUnit (Assertion, assertFailure, assertEqual)
13−import Test.QuickCheck (Arbitrary(..), Property, (===), property)
13+import Test.QuickCheck (Arbitrary(..), Property, (===))
1414import qualified Data.Vector as V
1515import qualified Data.Attoparsec.Lazy as L
1616import qualified Data.ByteString.Lazy.Char8 as L
@@ -49,21 +49,23 @@ toParseJSON :: (Arbitrary a, Eq a, Show a) =>
4949 (Value -> Parser a) -> (a -> Value) -> a -> Property
5050toParseJSON parsejson tojson x =
5151 case parse parsejson . tojson $ x of
52− Error _ -> property False
52+ Error msg -> failure "parse" msg x
5353 Success x' -> x === x'
5454
55−roundTrip :: (FromJSON a, ToJSON a) => (a -> a -> Property) -> a -> a -> Property
55+roundTrip :: (FromJSON a, ToJSON a, Show a) =>
56+ (a -> a -> Property) -> a -> a -> Property
5657roundTrip eq _ i =
5758 case fmap fromJSON . L.parse value . encode . toJSON $ i of
5859 L.Done _ (Success v) -> v `eq` i
59− _ -> property False
60+ L.Done _ (Error err) -> failure "fromJSON" err i
61+ L.Fail _ _ err -> failure "parse" err i
6062
6163roundTripEq :: (Eq a, FromJSON a, ToJSON a, Show a) => a -> a -> Property
6264roundTripEq x y = roundTrip (===) x y
6365
6466toFromJSON :: (Arbitrary a, Eq a, FromJSON a, ToJSON a, Show a) => a -> Property
65−toFromJSON x = case fromJSON . toJSON $ x of
66− Error _ -> property False
67+toFromJSON x = case fromJSON (toJSON x) of
68+ Error err -> failure "fromJSON" err x
6769 Success x' -> x === x'
6870
6971modifyFailureProp :: String -> String -> Bool
@@ -144,7 +146,7 @@ tests = [
144146 , testProperty "Maybe Integer" (toFromJSON :: Maybe Integer -> Property)
145147 , testProperty "Either Integer Double" (toFromJSON :: Either Integer Double -> Property)
146148 , testProperty "Either Integer Integer" (toFromJSON :: Either Integer Integer -> Property)
147− , testProperty "ZonedTime" $ zonedTimeToJSON
149+ , zonedTimeToJSON
148150 ]
149151 , testGroup "failure messages" [
150152 testProperty "modify failure" modifyFailureProp
@@ -211,7 +213,6 @@ tests = [
211213 ]
212214 ]
213215
214−
215216------------------------------------------------------------------------------
216217-- Comparison between bytestring and text encoders
217218------------------------------------------------------------------------------
tests/Properties/ZonedTime.hs+43−46
@@ -3,79 +3,76 @@
33module Properties.ZonedTime (zonedTimeToJSON) where
44
55import Data.Aeson.Types
6−import Test.Framework (Test, defaultMain, testGroup)
7−import Test.Framework.Providers.QuickCheck2 (testProperty)
8−import Test.QuickCheck (Arbitrary(..), Property, (===), property)
96import Data.Time
107import Instances ()
11−import System.IO
12−import System.IO.Unsafe (unsafePerformIO)
8+import Test.Framework (Test, testGroup)
9+import Test.Framework.Providers.QuickCheck2 (testProperty)
10+import Test.QuickCheck ((===))
11+import Types
1312
1413#if !MIN_VERSION_time(1,5,0)
1514import System.Locale (defaultTimeLocale, dateTimeFmt)
1615#endif
1716
18−zonedTimeToJSON :: ZonedTime -> Bool
19−zonedTimeToJSON t = and $
20− toFromJSON' "%FT%T%QZ" t (clearTimeZone t) : -- (javascript new Date().toISOString())
21− toFromJSON' "%F %T%Q%z" t t : -- (postgres)
22− toFromJSON' "%F %T%Q %Z" t t : -- (time's Show format)
23− toFromJSON' "%FT%T%Q%z" t t :
24− toFromJSON' "%Y-%mT%T%Q" t (clearTimeZone . clearDay $ t) :
25− toFromJSON' "%Y-%mT%R" t (clearTimeZone . clearDay . clearSeconds $ t) :
26− toFromJSON' "%Y-%mT%T" t (clearTimeZone . clearDay $ t) :
27− toFromJSON' "%Y-%mT%T%QZ" t (clearTimeZone . clearDay $ t) :
28− toFromJSON' "%Y-%mT%T%Q%z" t (clearDay t) :
29− toFromJSON' "%YT%T%Q" t (clearTimeZone . clearMonth . clearDay $ t) :
30− toFromJSON' "%YT%R" t (clearTimeZone . clearMonth . clearDay . clearSeconds $ t) :
31− toFromJSON' "%YT%T" t (clearTimeZone . clearMonth . clearDay $ t) :
32− toFromJSON' "%YT%T%QZ" t (clearTimeZone . clearMonth . clearDay $ t) :
33− toFromJSON' "%YT%T%Q%z" t (clearMonth . clearDay $ t) :
34− toFromJSON' "%FT%T%Q" t (clearTimeZone t) :
35− toFromJSON' "%FT%R" t (clearTimeZone . clearSeconds $ t) :
36− toFromJSON' "%FT%T" t (clearTimeZone t) :
37− toFromJSON' (dateTimeFmt defaultTimeLocale) t t :
38− []
17+zonedTimeToJSON :: Test
18+zonedTimeToJSON = testGroup "ZonedTime" [
19+ test "%FT%T%QZ" clearTimeZone -- javascript new Date().toISOString()
20+ , test "%F %T%Q%z" id -- postgres
21+ , test "%F %T%Q %Z" id -- time's Show format
22+ , test "%FT%T%Q%z" id
23+ , test "%Y-%mT%T%Q" (clearTimeZone . clearDay)
24+ , test "%Y-%mT%R" (clearTimeZone . clearDay . clearSeconds)
25+ , test "%Y-%mT%T" (clearTimeZone . clearDay)
26+ , test "%Y-%mT%T%QZ" (clearTimeZone . clearDay)
27+ , test "%Y-%mT%T%Q%z" clearDay
28+ , test "%YT%T%Q" (clearTimeZone . clearMonth . clearDay)
29+ , test "%YT%R" (clearTimeZone . clearMonth . clearDay . clearSeconds)
30+ , test "%YT%T" (clearTimeZone . clearMonth . clearDay)
31+ , test "%YT%T%QZ" (clearTimeZone . clearMonth . clearDay)
32+ , test "%YT%T%Q%z" (clearMonth . clearDay)
33+ , test "%FT%T%Q" clearTimeZone
34+ , test "%FT%R" (clearTimeZone . clearSeconds)
35+ , test "%FT%T" clearTimeZone
36+ , test (dateTimeFmt defaultTimeLocale) id
37+ ]
3938 where
4039 toJSON' :: String -> ZonedTime -> Value
4140 toJSON' format = toJSON . formatTime defaultTimeLocale format
4241
43− toFromJSON' :: String -> ZonedTime -> ZonedTime -> Bool
44− toFromJSON' format t_ t_' = case fromJSON . toJSON' format $ t_ of
45− Error msg -> error' msg
46− Success t_'' -> if t_'' == t_' then True else error' (show t_'')
42+ test :: String -> (ZonedTime -> ZonedTime) -> Test
43+ test format f = testProperty format go
4744 where
48− error' :: String -> Bool
49− error' msg = unsafePerformIO (hPutStrLn stderr . ("zonedTimeToJSON: " ++) $ show
50− (format, t_, toJSON' format t_, t_', msg))
51− `seq` False
45+ go t = case fromJSON (toJSON' format t) of
46+ Error msg -> failure "fromJSON" msg t
47+ Success t' -> t' === f t
5248
5349clearTimeZone :: ZonedTime -> ZonedTime
5450clearTimeZone t = t { zonedTimeZone = TimeZone 0 False "" }
5551
5652clearMonth :: ZonedTime -> ZonedTime
57−clearMonth = f
53+clearMonth zt = zt { zonedTimeToLocalTime = g (zonedTimeToLocalTime zt) }
5854 where
59− f zt = zt { zonedTimeToLocalTime = g $ zonedTimeToLocalTime zt }
60− g lt = lt { localDay = h $ localDay lt }
55+ g lt = lt { localDay = h (localDay lt) }
6156
6257 h :: Day -> Day
63− h = maybe (error "clearMonth") id . parseTime defaultTimeLocale "%Y-%m-%d" . formatTime defaultTimeLocale "%Y-01-%d"
58+ h = maybe (error "clearMonth") id . parseTime defaultTimeLocale "%Y-%m-%d" .
59+ formatTime defaultTimeLocale "%Y-01-%d"
6460
6561clearDay :: ZonedTime -> ZonedTime
66−clearDay = f
62+clearDay zt = zt { zonedTimeToLocalTime = g (zonedTimeToLocalTime zt) }
6763 where
68− f zt = zt { zonedTimeToLocalTime = g $ zonedTimeToLocalTime zt }
69− g lt = lt { localDay = h $ localDay lt }
64+ g lt = lt { localDay = h (localDay lt) }
7065
7166 h :: Day -> Day
72− h = maybe (error "clearDay") id . parseTime defaultTimeLocale "%Y-%m-%d" . formatTime defaultTimeLocale "%Y-%m-01"
67+ h = maybe (error "clearDay") id . parseTime defaultTimeLocale "%Y-%m-%d" .
68+ formatTime defaultTimeLocale "%Y-%m-01"
7369
7470clearSeconds :: ZonedTime -> ZonedTime
75−clearSeconds = f
71+clearSeconds zt = zt { zonedTimeToLocalTime = g (zonedTimeToLocalTime zt) }
7672 where
77− f zt = zt { zonedTimeToLocalTime = g $ zonedTimeToLocalTime zt }
78− g lt = lt { localTimeOfDay = h $ localTimeOfDay lt }
73+ g lt = lt { localTimeOfDay = h (localTimeOfDay lt) }
7974
8075 h :: TimeOfDay -> TimeOfDay
81− h = maybe (error "clearSeconds") id . parseTime defaultTimeLocale "%H:%M:%S" . formatTime defaultTimeLocale "%H:%M:00"
76+ h = maybe (error "clearSeconds") id .
77+ parseTime defaultTimeLocale "%H:%M:%S" .
78+ formatTime defaultTimeLocale "%H:%M:00"
tests/Types.hs+5
@@ -7,6 +7,7 @@ import qualified Data.Map as Map
77import Data.Data
88import Data.Text
99import GHC.Generics
10+import Test.QuickCheck (Property, counterexample)
1011
1112data Foo = Foo {
1213 fooInt :: Int
@@ -62,3 +63,7 @@ deriving instance Generic (Sum4 a b c d)
6263deriving instance Generic (Approx a)
6364deriving instance Generic Nullary
6465deriving instance Generic (SomeType a)
66+
67+failure :: Show a => String -> String -> a -> Property
68+failure func msg v = counterexample
69+ (func ++ " failed: " ++ msg ++ ", " ++ show v) False