0

In an integration test of a Yesod REST service, the called API returns

{
  "userId": "xxx"
}

where xxx is a MongoDB ObjectID (12 byte hex-encoded string).

I would like to verify that the returned JSON is, in fact, in this form, using aeson.

Is there a way to transform the JSON into a canonical form, say

{
   "userId": "-1"
}

if the value of userId field matches a given regular expression?

I can then use assertEquals to match the response JSON (actual) to an expected value.

In the Scala Lift JSON library I can do something like the following:

val actual = json.transform {
case JField("userId", value)
  if """[0-9a-f]{24}""".r.findFirstIn(value).isDefined =>
  JField("userId", "-1")
}

Is there something similar in aeson?

Ralph
  • 31,584
  • 38
  • 145
  • 282

1 Answers1

2

For generic transformations of algebraic data types, have a look at the uniplate package.

For example, given this expression type:

data Expr = Val Int
          | Add Expr Expr
          | Sub Expr Expr
          | Div Expr Expr
          | Mul Expr Expr
          | Neg Expr
          deriving (Show, Eq)

one can transform the subtree Neg (Val x) to Val (negate x) everywhere with this function:

import Data.Generics.Uniplate

optimise :: Expr -> Expr
optimise = transform $ \x -> case x of
    Neg (Val i) -> Val (negate i)
    x -> x
ErikR
  • 51,541
  • 9
  • 73
  • 124