Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementing Matcher protocol only matters if used as expected value #224

Open
NoahTheDuke opened this issue May 22, 2024 · 0 comments
Open

Comments

@NoahTheDuke
Copy link

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.

(if-not (sequential? actual)
{::result/type :mismatch
::result/value (model/->Mismatch expected actual)
::result/weight 1}

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]))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant