Skip to content

Commit

Permalink
extend example to show failing case
Browse files Browse the repository at this point in the history
```
Error decoding Foo: An error occurred while decoding a JSON value:
  Under 'When decoding a Foo':
  Under '"tag" property is missing':
  No value was found.
```
  • Loading branch information
peterbecich committed Oct 1, 2023
1 parent 88f1e31 commit c17265e
Show file tree
Hide file tree
Showing 12 changed files with 142 additions and 37 deletions.
4 changes: 2 additions & 2 deletions example/packages.dhall
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ let additions =
, "test-unit"
]
, repo =
"https://github.com/coot/purescript-argonaut-aeson-generic.git"
, version = "v0.4.1"
"https://github.com/peterbecich/purescript-argonaut-aeson-generic.git"
, version = "e22b1b9046aef15d6441ea90870dfbfa455a70fb"
}
, foreign-generic =
{ dependencies =
Expand Down
11 changes: 5 additions & 6 deletions example/src/Main.purs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import Types (Foo, fooMessage, fooNumber, fooList)
import Data.Argonaut.Decode.Error (JsonDecodeError)
import Data.Argonaut.Decode.Generic (genericDecodeJson)
import Data.Argonaut.Encode.Generic (genericEncodeJson)
import Types (Foo, fooMessage, fooNumber, fooList, fooMap)
import Types (Foo, fooMessage, fooNumber, fooList, fooMap, fooTestSum)
import Data.Map as Map

import Foreign.Object as Object
Expand All @@ -44,11 +44,10 @@ main = log "Hello, Purescript!" *> launchAff_ do
for_ efoo \foo -> do
liftEffect do
log $ "Foo message: " <> (view fooMessage foo)
<> "\t Foo number: " <> (show $ view fooNumber foo)
<> "\t Foo list length: "
<> (show (length $ view fooList foo :: Int))
<> "\t Foo map size: "
<> (show (Object.size $ view fooMap foo :: Int))
log $ "Foo number: " <> (show $ view fooNumber foo)
log $ "Foo list length: " <> (show (length $ view fooList foo :: Int))
log $ "Foo map size: " <> (show (Object.size $ view fooMap foo :: Int))
log $ "Foo test sum: " <> show (view fooTestSum foo)
let
-- modify the Foo received and send it back
foo' = set fooMessage "Hola"
Expand Down
5 changes: 4 additions & 1 deletion example/src/MyLib.hs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ import Servant
import System.Environment (lookupEnv)

import Types (Baz (Baz), Foo (Foo), fooList, fooMap, fooMessage,
fooNumber)
fooNumber, TestData(..), TestSum(..))
import qualified Types

type FooServer
= "foo" :> (Get '[JSON] Foo
Expand All @@ -34,6 +35,8 @@ foo = Foo
[10..20]
(Map.fromList [(pack "foo", 2), (pack "bar", 3), (pack "baz", 3)])
(Baz $ pack "hello")
-- (Types.Maybe (Just (Int 5)))
(Types.Number 1.23)

fooServer :: Server FooServer
fooServer = getFoo :<|> postFoo
Expand Down
24 changes: 16 additions & 8 deletions example/src/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -27,32 +27,38 @@ data Baz = Baz

makeLenses ''Baz

bazProxy :: Proxy Baz
bazProxy = Proxy
data TestSum
= Nullary
| Bool Bool
| Int Int
| Number Double
deriving (Eq, Generic, Ord, Show, FromJSON, ToJSON)

data TestData
= Maybe (Maybe TestSum)
| Either (Either (Maybe Int) (Maybe Bool))
deriving (Eq, Generic, Ord, Show, FromJSON, ToJSON)


data Foo = Foo
{ _fooMessage :: Text
, _fooNumber :: Int
, _fooList :: [Int]
, _fooMap :: Map.Map Text Int
, _fooBaz :: Baz
-- , _fooTestData :: TestData
, _fooTestSum :: TestSum
}
deriving (FromJSON, Generic, ToJSON)

makeLenses ''Foo

fooProxy :: Proxy Foo
fooProxy = Proxy

-- TODO newtype
data Bar a = Bar a
deriving (FromJSON, Generic, Show, ToJSON, Typeable)

makeLenses ''Bar

barProxy :: Proxy Bar
barProxy = Proxy

myBridge :: BridgePart
myBridge = defaultBridge

Expand All @@ -63,4 +69,6 @@ myTypes =
[ additionalInstances $ mkSumType @Baz
, additionalInstances $ mkSumType @Foo
, additionalInstances $ mkSumType @(Bar A)
, additionalInstances $ mkSumType @TestSum
, additionalInstances $ mkSumType @TestData
]
82 changes: 81 additions & 1 deletion example/src/Types.purs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@ import Data.Argonaut.Decode (class DecodeJson)
import Data.Argonaut.Decode.Class (class DecodeJson, class DecodeJsonField, decodeJson)
import Data.Argonaut.Encode (class EncodeJson)
import Data.Argonaut.Encode.Class (class EncodeJson, encodeJson)
import Data.Either (Either)
import Data.Generic.Rep (class Generic)
import Data.Lens (Iso', Lens', Prism', iso, lens, prism')
import Data.Lens.Iso.Newtype (_Newtype)
import Data.Lens.Record (prop)
import Data.Maybe (Maybe(..))
import Data.Newtype (class Newtype)
import Data.Show.Generic (genericShow)
import Foreign.Object (Object)
Expand Down Expand Up @@ -53,6 +55,7 @@ newtype Foo = Foo
, _fooList :: Array Int
, _fooMap :: Object Int
, _fooBaz :: Baz
, _fooTestSum :: TestSum
}


Expand All @@ -72,7 +75,7 @@ derive instance Newtype Foo _

--------------------------------------------------------------------------------

_Foo :: Iso' Foo {_fooMessage :: String, _fooNumber :: Int, _fooList :: Array Int, _fooMap :: Object Int, _fooBaz :: Baz}
_Foo :: Iso' Foo {_fooMessage :: String, _fooNumber :: Int, _fooList :: Array Int, _fooMap :: Object Int, _fooBaz :: Baz, _fooTestSum :: TestSum}
_Foo = _Newtype

fooMessage :: Lens' Foo String
Expand All @@ -90,6 +93,9 @@ fooMap = _Newtype <<< prop (Proxy :: _"_fooMap")
fooBaz :: Lens' Foo Baz
fooBaz = _Newtype <<< prop (Proxy :: _"_fooBaz")

fooTestSum :: Lens' Foo TestSum
fooTestSum = _Newtype <<< prop (Proxy :: _"_fooTestSum")

--------------------------------------------------------------------------------

newtype Bar a = Bar a
Expand All @@ -113,3 +119,77 @@ derive instance Newtype (Bar a) _

_Bar :: forall a. Iso' (Bar a) a
_Bar = _Newtype

--------------------------------------------------------------------------------

data TestSum
= Nullary
| Bool Boolean
| Int Int
| Number Number



instance Show TestSum where
show a = genericShow a

instance EncodeJson TestSum where
encodeJson = defer \_ -> genericEncodeAeson Argonaut.defaultOptions

instance DecodeJson TestSum where
decodeJson = defer \_ -> genericDecodeAeson Argonaut.defaultOptions

derive instance Generic TestSum _

--------------------------------------------------------------------------------

_Nullary :: Prism' TestSum Unit
_Nullary = prism' (const Nullary) case _ of
Nullary -> Just unit
_ -> Nothing

_Bool :: Prism' TestSum Boolean
_Bool = prism' Bool case _ of
(Bool a) -> Just a
_ -> Nothing

_Int :: Prism' TestSum Int
_Int = prism' Int case _ of
(Int a) -> Just a
_ -> Nothing

_Number :: Prism' TestSum Number
_Number = prism' Number case _ of
(Number a) -> Just a
_ -> Nothing

--------------------------------------------------------------------------------

data TestData
= Maybe (Maybe TestSum)
| Either (Either (Maybe Int) (Maybe Boolean))



instance Show TestData where
show a = genericShow a

instance EncodeJson TestData where
encodeJson = defer \_ -> genericEncodeAeson Argonaut.defaultOptions

instance DecodeJson TestData where
decodeJson = defer \_ -> genericDecodeAeson Argonaut.defaultOptions

derive instance Generic TestData _

--------------------------------------------------------------------------------

_Maybe :: Prism' TestData (Maybe TestSum)
_Maybe = prism' Maybe case _ of
(Maybe a) -> Just a
_ -> Nothing

_Either :: Prism' TestData (Either (Maybe Int) (Maybe Boolean))
_Either = prism' Either case _ of
(Either a) -> Just a
_ -> Nothing
2 changes: 1 addition & 1 deletion purescript-bridge.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ Test-Suite tests
, base
, containers
, directory
, hspec
, hspec >= 2.11
, hspec-expectations-pretty-diff
, process
, purescript-bridge
Expand Down
3 changes: 2 additions & 1 deletion src/Language/PureScript/Bridge/Printer.hs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import Language.PureScript.Bridge.SumType (CustomInstance (..),
_recLabel, getUsedTypes,
importsFromList,
instanceToImportLines,
baselineImports,
nootype, recLabel,
recValue, sigConstructor)
import Language.PureScript.Bridge.TypeInfo (Language (PureScript),
Expand Down Expand Up @@ -107,7 +108,7 @@ sumTypeToModule packageName st@(SumType t _ is) =
dropSelf $
unionImportLines
(typesToImportLines (getUsedTypes st))
(instancesToImportLines is)
(instancesToImportLines is <> baselineImports)
, psQualifiedImports = instancesToQualifiedImports is
, psTypes = [st]
}
Expand Down
8 changes: 8 additions & 0 deletions src/Language/PureScript/Bridge/SumType.hs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ module Language.PureScript.Bridge.SumType
, PSInstance
, importsFromList
, instanceToImportLines
, baselineImports
, nootype
, lenses
, prisms
Expand Down Expand Up @@ -359,6 +360,13 @@ implementationToTypes :: InstanceImplementation lang -> [TypeInfo lang]
implementationToTypes (Explicit members) = concatMap _memberDependencies members
implementationToTypes _ = []

baselineImports :: ImportLines
baselineImports = importsFromList
[ ImportLine "Data.Maybe" Nothing $ Set.singleton "Maybe(..)"
, ImportLine "Data.Newtype" Nothing $ Set.singleton "class Newtype"
]


instanceToImportLines :: PSInstance -> ImportLines
instanceToImportLines GenericShow =
importsFromList [ImportLine "Data.Show.Generic" Nothing $ Set.singleton "genericShow"]
Expand Down
26 changes: 16 additions & 10 deletions test/RoundTrip/Spec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import Test.Hspec (Spec, around, aroundAll_, around_, describe, it)
import Test.Hspec.Expectations.Pretty (shouldBe)
import Test.Hspec.QuickCheck (prop)
import Test.HUnit (assertBool, assertEqual)
import Test.QuickCheck (noShrinking, once, verbose, withMaxSuccess)
import Test.QuickCheck (verbose)
import Test.QuickCheck.Property (Testable (property))

myBridge :: BridgePart
Expand Down Expand Up @@ -75,15 +75,21 @@ roundtripSpec = do
assertBool stderr $ not $ "[warn]" `isInfixOf` stderr
around withApp $
it "should produce aeson-compatible argonaut instances" $
\(hin, hout, herr, hproc) ->
property $
\testData -> do
let input = toString $ encode @TestData testData
hPutStrLn hin input
err <- hGetLine herr
output <- hGetLine hout
assertEqual input "" err
assertEqual output (Right testData) $ eitherDecode @TestData $ fromString output
\(hin, hout, herr, hproc) -> verbose . property $ \testData -> do
let input = toString $ encode @TestData testData
hPutStrLn hin input
err <- hGetLine herr
output <- hGetLine hout

-- empty string signifies no error from Purescript process
assertEqual ("Error from Purescript, parsing: " <> input) "" err

-- compare the value parsed by Purescipt to the
-- source value in Haskell
assertEqual ("Mismatch between value sent to Purescript and value returned: " <> output) (Right testData)
. eitherDecode @TestData
$ fromString output

where
withApp = bracket runApp killApp
runApp = do
Expand Down
4 changes: 2 additions & 2 deletions test/RoundTrip/app/packages.dhall
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ let additions =
, "test-unit"
]
, repo =
"https://github.com/coot/purescript-argonaut-aeson-generic.git"
, version = "v0.4.1"
"https://github.com/peterbecich/purescript-argonaut-aeson-generic.git"
, version = "e22b1b9046aef15d6441ea90870dfbfa455a70fb"
}
, foreign-generic =
{ dependencies =
Expand Down
5 changes: 3 additions & 2 deletions test/RoundTrip/app/spago.dhall
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
{ name = "my-project"
, dependencies =
[ "foreign-object"
, "argonaut-aeson-generic"
[ "argonaut-aeson-generic"
, "argonaut-codecs"
, "argonaut-core"
, "console"
, "control"
, "effect"
, "either"
, "enums"
, "foreign-object"
, "maybe"
, "newtype"
, "node-readline"
, "ordered-collections"
, "prelude"
, "profunctor-lenses"
, "strings"
, "tuples"
]
, packages = ./packages.dhall
Expand Down
5 changes: 2 additions & 3 deletions test/RoundTrip/app/src/Main.purs
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,8 @@ main = do
parsed = decodeJson =<< parseJson input
case parsed of
Left err -> do
error $ "got " <> input
error $ printJsonDecodeError err
log ""
error $ input <> " " <> show err
log $ printJsonDecodeError err
Right testData -> do
error ""
log $ stringify $ encodeJson testData
Expand Down

0 comments on commit c17265e

Please sign in to comment.