Description
Problem statement
I use jsonb columns in Postgres to store arbitrary data. I don't automatically convert these columns when I query, preferring to wait until it's necessary. I can convert those columns before passing the results to match?
, but it would be nice to perform that automatically within the matcher.
However, implementing Matcher
for the PGObject or PGArray doesn't work if I use a normal sequence or object in the expected
position, as the built-in matcher implementations check the type of actual
to short-circuit an otherwise lengthy check. For example, here's sequence-match
as used by EqualSeq.
matcher-combinators/src/cljc/matcher_combinators/core.cljc
Lines 262 to 265 in afdb640
Proposed solution
I'm not sure the right way to go about this, as there's a step of transformation that must happen before the actual
can be checked, which I'm seeking to automate. Maybe that's outside the purview of matcher-combinators?
Thanks so much.
Repro:
(ns postgres-mc-example
(:require
[cheshire.core :as json]
[clojure.test :refer [deftest is]]
[matcher-combinators.core :as mc]
[matcher-combinators.result :as-alias mcr]
[matcher-combinators.test :refer [match?]])
(:import
[org.postgresql.util PGobject]))
(defn from-pg-json
[^PGobject obj & cheshire-options]
(when obj (apply json/parse-string (.getValue obj) cheshire-options)))
(defn to-pg-json
[data]
(doto (PGobject.)
(.setType "jsonb")
(.setValue (json/generate-string data))))
(extend-protocol mc/Matcher
PGobject
(-matcher-for [this] this)
(-matcher-for [this _t->m] this)
(-name [this] 'PGobjectEquals)
(-match [this actual] (mc/match (from-pg-json this) actual)))
(deftest matcher-smoke-test
(is (match? [1 2 3] (to-pg-json [1 2 3]))))