graphql-engine/server/src-test/Hasura/Backends/Postgres/SQL/ValueSpec.hs
Samir Talwar 40617719ef server: Remove the Show instance from QErr and anything that touches it.
We only use these `Show` instances in error messages (where we call
`show` explicitly anyway) and test cases (in which Hspec requires `Show
a` for any `a` in an assertion).

This removes the instance in favor of a custom `showQErr` function
(which serializes the error to JSON). It is then used in certain error
message production which previously called `show` on a `QErr`.

There are two places where we serialize a QErr and then construct a new
QErr from the resulting string. Instead, we modify the existing QErr to
add extra information.

An orphan `Show QErr` instance is retained for tests so that we can have
nice test failure messages.

This is preparation for future changes in which the error message within
`QErr` will not be exposed directly, and therefore will not have a
`Show` instance. That said, it feels like a sensible kind of cleanup
anyway.

PR-URL: https://github.com/hasura/graphql-engine-mono/pull/4897
GitOrigin-RevId: 8f79f7a356f0aea571156f39aefac242bf751f3a
2022-07-01 11:48:26 +00:00

67 lines
2.5 KiB
Haskell

module Hasura.Backends.Postgres.SQL.ValueSpec (spec) where
import Hasura.Backends.Postgres.SQL.DML
import Hasura.Backends.Postgres.SQL.Types
import Hasura.Backends.Postgres.SQL.Value
import Hasura.Base.Error (Code (ParseFailed), QErr (..), runAesonParser)
import Hasura.Base.Error.TestInstances ()
import Hasura.Prelude
import Network.HTTP.Types qualified as HTTP
import Test.Hspec
spec :: Spec
spec = do
txtEncoderSpec
jsonValueSpec
singleElement, multiElement, nestedArray, nestedArray', malformedArray :: PGScalarValue
singleElement = PGValArray [PGValInteger 1]
multiElement = PGValArray [PGValVarchar "a", PGValVarchar "b"]
nestedArray = PGValArray [multiElement, multiElement]
nestedArray' = PGValArray [nestedArray]
malformedArray = PGValArray [PGValInteger 1]
txtEncoderSpec :: Spec
txtEncoderSpec =
describe "txtEncoder should encode a valid Postgres array of:" $ do
it "a single element" $ do
txtEncoder singleElement `shouldBe` SELit "{1}"
it "multiple elements" $ do
txtEncoder multiElement `shouldBe` SELit "{a,b}"
it "simple nested arrays" $ do
txtEncoder nestedArray `shouldBe` SELit "{{a,b},{a,b}}"
it "more deeply nested arrays" $ do
txtEncoder nestedArray' `shouldBe` SELit "{{{a,b},{a,b}}}"
pgArrayRoundtrip :: PGScalarValue -> PGScalarType -> Expectation
pgArrayRoundtrip v t = do
let parsedValue = runExcept $ runAesonParser (parsePGValue t) (pgScalarValueToJson v)
parsedValue `shouldBe` Right v
jsonValueSpec :: Spec
jsonValueSpec = describe "JSON Roundtrip: PGArray" do
describe "parsePGValue" $ do
it "singleElement PGArray" $ do
pgArrayRoundtrip singleElement (PGArray PGInteger)
it "multiElement PGArray" $ do
pgArrayRoundtrip multiElement (PGArray PGVarchar)
it "nestedArray PGArray" $ do
pgArrayRoundtrip nestedArray (PGArray (PGArray PGVarchar))
it "nestedArray' PGArray" $ do
pgArrayRoundtrip nestedArray' (PGArray (PGArray (PGArray PGVarchar)))
it "malformedArray PGArray" $ do
let parsedValue = runExcept $ runAesonParser (parsePGValue PGVarchar) (pgScalarValueToJson malformedArray)
parsedValue
`shouldBe` Left
QErr
{ qePath = [],
qeStatus =
HTTP.Status
{ statusCode = 400,
statusMessage = "Bad Request"
},
qeError = "parsing Text failed, expected String, but encountered Array",
qeCode = ParseFailed,
qeInternal = Nothing
}