packages feed

aeson-injector 1.0.0.1 → 1.0.1.0

raw patch · 3 files changed

+130/−63 lines, 3 filesdep +QuickCheckdep +bifunctorsdep +quickcheck-textPVP ok

version bump matches the API change (PVP)

Dependencies added: QuickCheck, bifunctors, quickcheck-text, tasty, tasty-hunit, tasty-quickcheck

API changes (from Hackage documentation)

+ Data.Aeson.WithField: instance Data.Bifunctor.Bifunctor (Data.Aeson.WithField.WithField s)
+ Data.Aeson.WithField: instance Data.Bifunctor.Bifunctor Data.Aeson.WithField.WithFields
+ Data.Aeson.WithField: instance GHC.Base.Functor (Data.Aeson.WithField.WithField s a)
+ Data.Aeson.WithField: instance GHC.Base.Functor (Data.Aeson.WithField.WithFields a)

Files

aeson-injector.cabal view
@@ -1,5 +1,5 @@ name:                aeson-injector-version:             1.0.0.1+version:             1.0.1.0 synopsis:            Injecting fields into aeson values description:         See README.md license:             MIT@@ -30,6 +30,7 @@   build-depends:        base                 >= 4.7   && < 4.10     , aeson                >= 0.11  && < 0.13+    , bifunctors           >= 5.2   && < 6     , deepseq              >= 1.4   && < 2     , lens                 >= 4.13  && < 5     , swagger2             >= 2.0   && < 3.0@@ -47,5 +48,10 @@     , aeson-injector     , HUnit >= 1.3     , lens+    , QuickCheck >= 2.8.2+    , quickcheck-text     , swagger2 +    , tasty >= 0.11+    , tasty-hunit >= 0.9+    , tasty-quickcheck >= 0.8     , text
src/Data/Aeson/WithField.hs view
@@ -161,6 +161,7 @@ import Control.Lens hiding ((.=)) import Control.Monad  import Data.Aeson +import Data.Bifunctor import Data.Monoid  import Data.Proxy  import Data.Swagger @@ -190,6 +191,12 @@  instance (NFData a, NFData b) => NFData (WithField s a b) +instance Functor (WithField s a) where +  fmap f (WithField a b) = WithField a (f b)++instance Bifunctor (WithField s) where +  bimap fa fb (WithField a b) = WithField (fa a) (fb b)+ -- | Workaround for a problem that is discribed as: -- sometimes I need a id with the data, sometimes not. --@@ -270,6 +277,13 @@   deriving (Generic, Eq, Show, Read)  instance (NFData a, NFData b) => NFData (WithFields a b)++instance Functor (WithFields a) where +  fmap f (WithFields a b) = WithFields a (f b)++instance Bifunctor WithFields where +  bimap fa fb (WithFields a b) = WithFields (fa a) (fb b)+  -- | Note: the instance injects field only in 'Object' case. -- In other cases it forms a wrapper around the 'Value' produced 
test/Main.hs view
@@ -6,22 +6,41 @@  import Control.Lens hiding ((.=)) import Control.Monad -import Data.Aeson+import Data.Aeson as A  import Data.Aeson.WithField+import Data.Proxy import Data.Swagger import Data.Swagger.Internal.Schema-import Data.Text -import Data.Proxy-import Test.HUnit +import Data.Text+import Data.Text.Arbitrary+import Test.Tasty+import Test.Tasty.HUnit+import Test.Tasty.QuickCheck as QC +instance (Arbitrary a, Arbitrary b) => Arbitrary (WithField s a b) where +  arbitrary = WithField <$> arbitrary <*> arbitrary++instance (Arbitrary a, Arbitrary b) => Arbitrary (WithFields a b) where +  arbitrary = WithFields <$> arbitrary <*> arbitrary+ main :: IO ()-main = runTestTT tests >> return ()-  where-  tests = TestList [-      (TestLabel "WithField tests" withFieldTests)-    , (TestLabel "WithFields tests" withFieldsTests)-    ]+main = defaultMain tests +tests :: TestTree+tests = testGroup "Tests" [qcProperties, unitTests]++qcProperties :: TestTree +qcProperties = testGroup "Properties" [+    withFieldProps+  , withFieldsProps+  ]++unitTests :: TestTree +unitTests = testGroup "Unit tests" [+    withFieldTests+  , withFieldsTests+  ]+ data TestObj = TestObj !Text    deriving (Eq, Show) @@ -37,99 +56,101 @@       & type_ .~ SwaggerObject       & properties .~ [("field", Inline t)]       & required .~ ["field"]+instance Arbitrary TestObj where +  arbitrary = TestObj <$> arbitrary -withFieldTests :: Test-withFieldTests = TestList [-    TestLabel "toJSON" testsToJSON-  , TestLabel "fromJSON" testsFromJSON-  , TestLabel "toSchema" testsToSchema+withFieldTests :: TestTree+withFieldTests = testGroup "WithField tests" [+    testsToJSON+  , testsFromJSON+  , testsToSchema   ]   where-  testsToJSON = TestList [-      TestLabel "Inline mode: atomic field" $ TestCase $ do +  testsToJSON = testGroup "toJSON" [+      testCase "Inline mode: atomic field" $ do          let expected = object ["a" .= (0 :: Int), "field" .= ("val" :: Text)]         let actual = toJSON (WithField 0 (TestObj "val") :: WithField "a" Int TestObj)         expected @=? actual-    , TestLabel "Inline mode: complex field" $ TestCase $ do +    , testCase "Inline mode: complex field" $ do          let expected = object [                 "a" .= object ["field" .= ("key" :: Text)]               , "field" .= ("val" :: Text)]         let actual = toJSON (WithField (TestObj "key") (TestObj "val")                :: WithField "a" TestObj TestObj)         expected @=? actual-    , TestLabel "Wrapper mode: atomic" $ TestCase $ do +    , testCase "Wrapper mode: atomic" $ do          let expected = object ["a" .= (0 :: Int), "value" .= ("val" :: Text)]         let actual = toJSON (WithField 0 "val" :: WithField "a" Int String)         expected @=? actual-    , TestLabel "Wrapper mode: array" $ TestCase $ do +    , testCase "Wrapper mode: array" $ do          let expected = object ["a" .= (0 :: Int), "value" .= (["val1", "val2"] :: [Text])]         let actual = toJSON (WithField 0 ["val1", "val2"] :: WithField "a" Int [String])         expected @=? actual-    , TestLabel "Wrapper mode: complex field" $ TestCase $ do +    , testCase "Wrapper mode: complex field" $ do          let expected = object [                 "a" .= object ["field" .= ("key" :: Text)]               , "value" .= ("val":: Text)]         let actual = toJSON (WithField (TestObj "key") "val" :: WithField "a" TestObj String)         expected @=? actual     ]-  testsFromJSON = TestList [-      TestLabel "Inline mode: atomic field" $ TestCase $ do -        let Success (expected :: WithField "a" Int TestObj) = fromJSON $ object [+  testsFromJSON = testGroup "fromJSON" [+      testCase "Inline mode: atomic field" $ do +        let A.Success (expected :: WithField "a" Int TestObj) = fromJSON $ object [                 "a" .= (0 :: Int)               , "field" .= ("val" :: Text)]         let actual = WithField 0 (TestObj "val") :: WithField "a" Int TestObj         expected @=? actual-    , TestLabel "Inline mode: complex field" $ TestCase $ do -        let Success (expected :: WithField "a" TestObj TestObj) = fromJSON $ object [+    , testCase "Inline mode: complex field" $ do +        let A.Success (expected :: WithField "a" TestObj TestObj) = fromJSON $ object [                 "a" .= object ["field" .= ("key" :: Text)]               , "field" .= ("val" :: Text)]         let actual = WithField (TestObj "key") (TestObj "val") :: WithField "a" TestObj TestObj         expected @=? actual-    , TestLabel "Wrapper mode: atomic" $ TestCase $ do -        let Success (expected :: WithField "a" Int String) = fromJSON $ object [+    , testCase "Wrapper mode: atomic" $ do +        let A.Success (expected :: WithField "a" Int String) = fromJSON $ object [                 "a" .= (0 :: Int)               , "value" .= ("val" :: Text)]         let actual = WithField 0 "val" :: WithField "a" Int String         expected @=? actual-    , TestLabel "Wrapper mode: array" $ TestCase $ do -        let Success (expected :: WithField "a" Int [String]) = fromJSON $ object [+    , testCase "Wrapper mode: array" $ do +        let A.Success (expected :: WithField "a" Int [String]) = fromJSON $ object [                 "a" .= (0 :: Int)               , "value" .= (["val1", "val2"] :: [Text]) ]         let actual = WithField 0 ["val1", "val2"] :: WithField "a" Int [String]         expected @=? actual-    , TestLabel "Wrapper mode: complex field" $ TestCase $ do -        let Success (expected :: WithField "a" TestObj String) = fromJSON $ object [+    , testCase "Wrapper mode: complex field" $ do +        let A.Success (expected :: WithField "a" TestObj String) = fromJSON $ object [                 "a" .= object ["field" .= ("key" :: Text)]               , "value" .= ("val":: Text)]         let actual = WithField (TestObj "key") "val" :: WithField "a" TestObj String         expected @=? actual     ]-  testsToSchema = TestList [-      TestLabel "Inline mode: atomic field" $ TestCase $ do +  testsToSchema = testGroup "toSchema" [+      testCase "Inline mode: atomic field" $ do          let expected = [                 ("a", Inline $ toSchema (Proxy :: Proxy Int))               , ("field", Inline $ toSchema (Proxy :: Proxy String))]         let actual = toSchema (Proxy :: Proxy (WithField "a" Int TestObj))         expected @=? (actual ^. properties)-    , TestLabel "Inline mode: complex field" $ TestCase $ do +    , testCase "Inline mode: complex field" $ do          let expected = [                 ("a", Inline $ toSchema (Proxy :: Proxy TestObj))               , ("field", Inline $ toSchema (Proxy :: Proxy String))]         let actual = toSchema (Proxy :: Proxy (WithField "a" TestObj TestObj))         expected @=? (actual ^. properties)-    , TestLabel "Wrapper mode: atomic" $ TestCase $ do +    , testCase "Wrapper mode: atomic" $ do          let expected = [                 ("a", Inline $ toSchema (Proxy :: Proxy Int))               , ("value", Inline $ toSchema (Proxy :: Proxy String))]         let actual = toSchema (Proxy :: Proxy (WithField "a" Int String))         expected @=? (actual ^. properties)-    , TestLabel "Wrapper mode: array" $ TestCase $ do +    , testCase "Wrapper mode: array" $ do          let expected = [                 ("a", Inline $ toSchema (Proxy :: Proxy Int))               , ("value", Inline $ toSchema (Proxy :: Proxy [String]))]         let actual = toSchema (Proxy :: Proxy (WithField "a" Int [String]))         expected @=? (actual ^. properties)-    , TestLabel "Wrapper mode: complex field" $ TestCase $ do +    , testCase "Wrapper mode: complex field" $ do          let expected = [                 ("a", Inline $ toSchema (Proxy :: Proxy TestObj))               , ("value", Inline $ toSchema (Proxy :: Proxy String))]@@ -152,6 +173,8 @@       & type_ .~ SwaggerObject       & properties .~ [("field1", Inline t)]       & required .~ ["field1"]+instance Arbitrary TestObj1 where +  arbitrary = TestObj1 <$> arbitrary  data TestObj2 = TestObj2 !Text    deriving (Eq, Show)@@ -168,89 +191,113 @@       & type_ .~ SwaggerObject       & properties .~ [("field2", Inline t)]       & required .~ ["field2"]+instance Arbitrary TestObj2 where +  arbitrary = TestObj2 <$> arbitrary -withFieldsTests :: Test-withFieldsTests = TestList [-    TestLabel "toJSON" testsToJSON-  , TestLabel "fromJSON" testsFromJSON-  , TestLabel "toSchema" testsToSchema+withFieldsTests :: TestTree+withFieldsTests = testGroup "WithFields tests" [+    testsToJSON+  , testsFromJSON+  , testsToSchema   ]   where-  testsToJSON = TestList [-      TestLabel "Inline mode" $ TestCase $ do +  testsToJSON = testGroup "toJSON" [+      testCase "Inline mode" $ do          let expected = object [                 "field1" .= ("val1" :: Text)               , "field2" .= ("val2" :: Text) ]         let actual = toJSON (WithFields (TestObj1 "val1") (TestObj2 "val2"))         expected @=? actual-    , TestLabel "Wrapper mode: first" $ TestCase $ do +    , testCase "Wrapper mode: first" $ do          let expected = object [                 "injected" .= ("val1" :: Text)               , "field2" .= ("val2" :: Text) ]         let actual = toJSON (WithFields ("val1" :: Text) (TestObj2 "val2"))         expected @=? actual-    , TestLabel "Wrapper mode: second" $ TestCase $ do +    , testCase "Wrapper mode: second" $ do          let expected = object [                 "field1" .= ("val1" :: Text)               , "value" .= ("val2" :: Text) ]         let actual = toJSON (WithFields (TestObj1 "val1") ("val2" :: Text))         expected @=? actual-    , TestLabel "Wrapper mode: both" $ TestCase $ do +    , testCase "Wrapper mode: both" $ do          let expected = object [                 "injected" .= ("val1" :: Text)               , "value" .= ("val2" :: Text) ]         let actual = toJSON (WithFields ("val1" :: Text) ("val2" :: Text))         expected @=? actual     ]-  testsFromJSON = TestList [-      TestLabel "Inline mode" $ TestCase $ do -        let Success (expected :: WithFields TestObj1 TestObj2) = fromJSON $ object [+  testsFromJSON = testGroup "fromJSON" [+      testCase "Inline mode" $ do +        let A.Success (expected :: WithFields TestObj1 TestObj2) = fromJSON $ object [                 "field1" .= ("val1" :: Text)               , "field2" .= ("val2" :: Text)]         let actual = WithFields (TestObj1 "val1") (TestObj2 "val2")         expected @=? actual-    , TestLabel "Wrapper mode: first" $ TestCase $ do -        let Success (expected :: WithFields Text TestObj2) = fromJSON $ object [+    , testCase "Wrapper mode: first" $ do +        let A.Success (expected :: WithFields Text TestObj2) = fromJSON $ object [                 "injected" .= ("val1" :: Text)               , "field2" .= ("val2" :: Text)]         let actual = WithFields ("val1" :: Text) (TestObj2 "val2")         expected @=? actual-    , TestLabel "Wrapper mode: second" $ TestCase $ do -        let Success (expected :: WithFields TestObj1 Text) = fromJSON $ object [+    , testCase "Wrapper mode: second" $ do +        let A.Success (expected :: WithFields TestObj1 Text) = fromJSON $ object [                 "field1" .= ("val1" :: Text)               , "value" .= ("val2" :: Text)]         let actual = WithFields (TestObj1 "val1") ("val2" :: Text)         expected @=? actual-    , TestLabel "Wrapper mode: both" $ TestCase $ do -        let Success (expected :: WithFields Text Text) = fromJSON $ object [+    , testCase "Wrapper mode: both" $ do +        let A.Success (expected :: WithFields Text Text) = fromJSON $ object [                 "injected" .= ("val1" :: Text)               , "value" .= ("val2" :: Text)]         let actual = WithFields ("val1" :: Text) ("val2" :: Text)         expected @=? actual     ]-  testsToSchema = TestList [-      TestLabel "Inline mode" $ TestCase $ do +  testsToSchema = testGroup "toSchema" [+      testCase "Inline mode" $ do          let expected = [                 ("field1", Inline $ toSchema (Proxy :: Proxy Text))               , ("field2", Inline $ toSchema (Proxy :: Proxy Text))]         let actual = toSchema (Proxy :: Proxy (WithFields TestObj1 TestObj2))         expected @=? (actual ^. properties)-    , TestLabel "Wrapper mode: first" $ TestCase $ do +    , testCase "Wrapper mode: first" $ do          let expected = [                 ("injected", Inline $ toSchema (Proxy :: Proxy Text))               , ("field2", Inline $ toSchema (Proxy :: Proxy Text))]         let actual = toSchema (Proxy :: Proxy (WithFields Text TestObj2))         expected @=? (actual ^. properties)-    , TestLabel "Wrapper mode: second" $ TestCase $ do +    , testCase "Wrapper mode: second" $ do          let expected = [                 ("field1", Inline $ toSchema (Proxy :: Proxy Text))               , ("value", Inline $ toSchema (Proxy :: Proxy Text))]         let actual = toSchema (Proxy :: Proxy (WithFields TestObj1 Text))         expected @=? (actual ^. properties)-    , TestLabel "Wrapper mode: both" $ TestCase $ do +    , testCase "Wrapper mode: both" $ do          let expected = [                 ("injected", Inline $ toSchema (Proxy :: Proxy Text))               , ("value", Inline $ toSchema (Proxy :: Proxy Text))]         let actual = toSchema (Proxy :: Proxy (WithFields Text Text))         expected @=? (actual ^. properties)     ]++withFieldProps :: TestTree+withFieldProps = testGroup "withField properties" [+    functorProps+  , bifunctorProps+  ]+  where +    functorProps = QC.testProperty "fmap id  ==  id" $  \(wf :: WithField "id" Int TestObj) -> +      fmap id wf == wf +    bifunctorProps = QC.testProperty "bimap id id == id" $  \(wf :: WithField "id" Int TestObj) -> +      bimap id id wf == wf ++withFieldsProps :: TestTree+withFieldsProps = testGroup "withFields properties" [+    functorProps+  , bifunctorProps+  ]+  where +    functorProps = QC.testProperty "fmap id  ==  id" $  \(wf :: WithFields TestObj1 TestObj2) -> +      fmap id wf == wf +    bifunctorProps = QC.testProperty "bimap id id == id" $  \(wf :: WithFields TestObj1 TestObj2) -> +      bimap id id wf == wf