Public Vars

Back

with-redefs (clj)

(source)

macro

(with-redefs bindings & body)
binding => var-symbol temp-value-expr Temporarily redefines Vars while executing the body. The temp-value-exprs will be evaluated and each resulting value will replace in parallel the root value of its Var. After the body is executed, the root values of all the Vars will be set back to their old values. These temporary changes will be visible in all threads. Useful for mocking out functions during testing.

Examples

Netflix/PigPen
      (test-diff
        (->> s
          (#'pigpen.oven/braise {})
          (#'pigpen.pig.oven/dec-rank {})
          (#'pigpen.oven/optimize-binds {})
          (map #(select-keys % [:projections :ancestors :fields :id :type])))
        '[{:type :return, :id return1, :fields [return1/value]}
          {:type :rank, :id rank2_0, :fields [rank2/index rank2/value], :ancestors [return1]}
          {:type :project
           :id project4
           :fields [project4/value]
           :ancestors [rank2_0]
           :projections [{:type :projection
                          :expr {:type :code
                                 :init (clojure.core/require (quote [pigpen.runtime]))
                                 :func (clojure.core/comp (pigpen.runtime/process->bind (pigpen.runtime/pre-process nil :frozen))
                                                          (pigpen.runtime/process->bind (fn [[i v]] [(dec i) v]))
                                                          (pigpen.runtime/map->bind (pigpen.runtime/with-ns pigpen.pig.oven-test vector))
                                                          (pigpen.runtime/process->bind (pigpen.runtime/post-process nil :frozen)))
                                 :udf :seq
                                 :args [rank2_0/$0 rank2_0/value]}
                          :flatten true
                          :alias [project4/value]
                          :types nil}]}]))))

(deftest test-split-project
  (with-redefs [pigpen.raw/pigsym (pigsym-inc)]
Netflix/PigPen
(deftest test-code$
  (test-diff
    (code$ :seq
           '(require '[pigpen.runtime])
           '(var clojure.core/prn)
           ["a" 'r0/b 'c/d])
    '{:type :code
      :udf :seq
      :init (require (quote [pigpen.runtime]))
      :func (var clojure.core/prn)
      :args ["a" r0/b c/d]}))

(deftest test-load$
  (with-redefs [pigpen.raw/pigsym pigsym-zero]
    (test-diff
      (load$ "foo" :string ['value] {})
      '{:type :load
        :id load0
        :description "foo"
        :location "foo"
        :fields [load0/value]
        :field-type :native
        :storage :string
        :opts {:type :load-opts}})))

(deftest test-store$
  (with-redefs [pigpen.raw/pigsym pigsym-zero]
    (test-diff
      (store$ "foo" :string {} r0)
      '{:type :store
        :id store0
        :description "foo"
        :ancestors [{:id r0
                     :fields [r0/value]
                     :field-type :frozen}]
        :location "foo"
        :args [r0/value]
        :storage :string
        :opts {:type :store-opts}})))

(deftest test-return$
  (with-redefs [pigpen.raw/pigsym pigsym-zero]
    (test-diff
      (return$ ['value] [{'value "foo"}])
      '{:type :return
        :id return0
        :field-type :frozen
        :fields [return0/value]
        :data [{return0/value "foo"}]})))

(deftest test-project$*
  (with-redefs [pigpen.raw/pigsym pigsym-zero]
    (test-diff
      (project$* [(projection-field$ 'r0/value)] {} 'r0)
      '{:type :project
        :id project0
        :description nil
        :ancestors [r0]
        :fields [project0/value]
        :field-type :frozen
        :projections [{:type :projection
                       :expr {:type :field
                              :field r0/value}
                       :flatten false
                       :alias [project0/value]}]
        :opts {:type :project-opts}})))

(deftest test-project$
  (with-redefs [pigpen.raw/pigsym pigsym-zero]
    (test-diff
      (project$ [(projection-field$ 'r0/value)] {} r0)
      '{:type :project
        :id project0
        :description nil
        :ancestors [{:id r0
                     :fields [r0/value]
                     :field-type :frozen}]
        :fields [project0/value]
        :field-type :frozen
        :projections [{:type :projection
                       :expr {:type :field
                              :field r0/value}
                       :flatten false
                       :alias [project0/value]}]
        :opts {:type :project-opts}})))

(deftest test-bind$
  (with-redefs [pigpen.raw/pigsym pigsym-zero]
    (test-diff
      (bind$ '[pigpen.raw-test] `identity {} r0)
      '{:type :bind
        :id bind0
        :description nil
        :ancestors [{:id r0
                     :fields [r0/value]
                     :field-type :frozen}]
        :requires [pigpen.raw-test]
        :func clojure.core/identity
        :args [r0/value]
        :fields [bind0/value]
        :field-type-in :frozen
        :field-type :frozen
        :types nil
        :opts {:type :bind-opts}})

(deftest test-sort$
  (with-redefs [pigpen.raw/pigsym pigsym-zero]
    (test-diff
      (sort$ 'key :asc {} r1)
      '{:type :sort
        :id sort0
        :description nil
        :ancestors [{:id r1
                     :fields [r1/key r1/value]
                     :field-type :frozen}]
        :fields [sort0/value]
        :field-type :frozen
        :key r1/key
        :comp :asc
        :opts {:type :sort-opts}})))

(deftest test-rank$
  (with-redefs [pigpen.raw/pigsym pigsym-zero]
    (test-diff
      (rank$ {} r1)
      '{:type :rank
        :id rank0
        :description nil
        :ancestors [{:id r1
                     :fields [r1/key r1/value]
                     :field-type :frozen}]
        :fields [rank0/index rank0/key rank0/value]
        :field-type :frozen
        :opts {:type :rank-opts}})))

(deftest test-filter$
  (with-redefs [pigpen.raw/pigsym pigsym-zero]
    (test-diff
      (filter$ '(and (= foo "a") (> bar 2))
               {}
               r0)
      '{:type :filter
        :id filter0
        :description nil
        :ancestors [{:id r0
                     :fields [r0/value]
                     :field-type :frozen}]
        :fields [filter0/value]
        :field-type :native
        :expr (and (= foo "a") (> bar 2))
        :opts {:type :filter-opts}})))

(deftest test-take$
  (with-redefs [pigpen.raw/pigsym pigsym-zero]
    (test-diff
      (take$ 1000 {} r0)
      '{:type :take
        :id take0
        :description nil
        :ancestors [{:id r0
                     :fields [r0/value]
                     :field-type :frozen}]
        :n 1000
        :fields [take0/value]
        :field-type :frozen
        :opts {:type :take-opts}})))

(deftest test-sample$
  (with-redefs [pigpen.raw/pigsym pigsym-zero]
    (test-diff
      (sample$ 0.001 {} r0)
      '{:type :sample
        :id sample0
        :description nil
        :ancestors [{:id r0
                     :fields [r0/value]
                     :field-type :frozen}]
        :p 0.0010
        :fields [sample0/value]
        :field-type :frozen
        :opts {:type :sample-opts}})))

(deftest test-distinct$
  (with-redefs [pigpen.raw/pigsym pigsym-zero]
    (test-diff
      (distinct$ {:parallel 20} r0)
      '{:type :distinct
        :id distinct0
        :description nil
        :ancestors [{:id r0
                     :fields [r0/value]
                     :field-type :frozen}]
        :fields [distinct0/value]
        :field-type :frozen
        :opts {:type :distinct-opts
               :parallel 20}})))

(deftest test-concat$
  (with-redefs [pigpen.raw/pigsym pigsym-zero]
    (test-diff
      (concat$ {}
               '[{:id r0, :fields [r0/value], :field-type :frozen}
                 {:id r1, :fields [r1/value], :field-type :frozen}])
      '{:type :concat
        :id concat0
        :description nil
        :fields [concat0/value]
        :field-type :frozen
        :ancestors [{:id r0, :fields [r0/value], :field-type :frozen}
                    {:id r1, :fields [r1/value], :field-type :frozen}]
        :opts {:type :concat-opts}})))

(deftest test-reduce$
  (with-redefs [pigpen.raw/pigsym pigsym-zero]
    (test-diff
      (reduce$ {} r0)
      '{:type :reduce
        :id reduce0
        :description nil
        :arg r0/value
        :fields [r0/value]
        :field-type :frozen
        :ancestors [{:id r0
                     :fields [r0/value]
                     :field-type :frozen}]
        :opts {:type :reduce-opts}})))

(deftest test-group$
  (with-redefs [pigpen.raw/pigsym pigsym-zero]
    (test-diff
      (group$ :group
              [:optional :optional]
              {}
              [{:id 'g1, :fields '[g1/key g1/value], :field-type :frozen}
               {:id 'g2, :fields '[g2/key g2/value], :field-type :frozen}])
      '{:type :group
        :id group0
        :description nil
        :keys [g1/key g2/key]
        :join-types [:optional :optional]
        :field-dispatch :group
        :fields [group0/group g1/key g1/value g2/key g2/value]
        :field-type :frozen
        :ancestors [{:id g1, :fields [g1/key g1/value], :field-type :frozen}
                    {:id g2, :fields [g2/key g2/value], :field-type :frozen}]
        :opts {:type :group-opts}})))

(deftest test-join$
  (with-redefs [pigpen.raw/pigsym pigsym-zero]
    (test-diff
      (join$ :join
             [:required :required]
             {}
             [{:id 'g1, :fields '[g1/key g1/value], :field-type :frozen}
              {:id 'g2, :fields '[g2/key g2/value], :field-type :frozen}])
      '{:type :join
        :id join0
        :description nil
        :keys [g1/key g2/key]
        :join-types [:required :required]
        :field-dispatch :join
        :fields [g1/key g1/value g2/key g2/value]
        :field-type :frozen
        :ancestors [{:id g1, :fields [g1/key g1/value], :field-type :frozen}
                    {:id g2, :fields [g2/key g2/value], :field-type :frozen}]
        :opts {:type :join-opts}})))

(deftest test-noop$
  (with-redefs [pigpen.raw/pigsym (pigsym-inc)]
    (test-diff
      (noop$ {} r0)
      '{:type :noop
        :id noop1
        :description nil
        :args [r0/value]
        :fields [noop1/value]
        :field-type :frozen
        :ancestors [{:id r0
                     :fields [r0/value]
                     :field-type :frozen}]
        :opts {:type :noop-opts}})))

(deftest test-store-many$
  (with-redefs [pigpen.raw/pigsym (pigsym-inc)]
    (test-diff
      (store-many$ [(store$ "foo" :string {} r0)
                    (store$ "foo" :string {} r0)])
      '{:type :store-many
        :id store-many3
        :ancestors [{:storage :string
                     :location "foo"
                     :args [r0/value]
                     :ancestors [{:id r0
                                  :fields [r0/value]
                                  :field-type :frozen}]
                     :type :store
                     :id store1
                     :description "foo"
                     :opts {:type :store-opts}}
                    {:storage :string
                     :location "foo"
                     :args [r0/value]
                     :ancestors [{:id r0
                                  :fields [r0/value]
                                  :field-type :frozen}]
                     :type :store
                     :id store2
                     :description "foo"
                     :opts {:type :store-opts}}]})))
unclebob/more-speech
(ns more-speech.nostr.zaps-spec
  (:require
    [clj-http.client :as client]
    [clojure.core.async :as async]
    [clojure.data.json :as json]
    [clojure.string :as string]
    [more-speech.bech32 :as bech32]
    [more-speech.config :as config]
    [more-speech.db.gateway :as gateway]
    [more-speech.mem :refer :all]
    [more-speech.nostr.elliptic-signature :as es]
    [more-speech.nostr.event-composers :as composers]
    [more-speech.nostr.util :as util]
    [more-speech.nostr.zaps :as zaps]
    [more-speech.relay :as relay]
    [more-speech.spec-util :refer :all]
    [more-speech.util.fortune-messages :as fortune]
    [more-speech.websocket-relay :as ws-relay]
    [speclj.core :refer :all])
  (:import (ecdhJava SECP256K1)))

      (it "makes a zap request if all is valid"
        (with-redefs [util/get-now (stub :get-now {:return 11111})]
          (let [b32-lnurl (bech32/encode-str "lnurl" "lnurl")
                my-privkey 0xb0b
                my-pubkey (util/bytes->num (es/get-pub-key (util/num->bytes 32 my-privkey)))
                _ (set-mem :pubkey my-pubkey)
                _ (set-mem [:keys :private-key] (util/hexify my-privkey))
                _ (set-mem [:keys :public-key] (util/hexify my-pubkey))
                _ (set-mem :relays {"relay-r1" {:read :read-all}
                                    "relay-nr" {:read :read-none}
                                    "relay-r2" {:read :read-all}})
                body (zaps/make-zap-request-event
                       @wallet-response "lnurl" @zap-descriptor)
                {:keys [kind content tags pubkey created_at]} body
                tags (set tags)]

      (it "gets the zap invoice"
        (let [ln-response {:body (json/write-str @wallet-response)}
              invoice-response {:status 200
                                :body (json/write-str {:status "OK"
                                                       :pr "invoice"})}
              zap-descriptor {:zap-amount 1000
                              :zap-comment "comment"
                              :id 1
                              :pubkey 2
                              :auto-zap? true}
              messages {"lnurl" ln-response
                        "invoice-url" invoice-response}
              client-get (fn [url] (get messages (first (string/split url #"\?"))))]
          (with-redefs [zaps/get-lnurl (stub :get-lnurl {:return "lnurl"})
                        client/get (stub :client-get {:invoke client-get})
                        es/do-sign (stub :do-sign {:return (util/num->bytes 64 99)})]
            (should= "invoice" (zaps/get-zap-invoice zap-descriptor))
            (should= {"invoice" {:id 1, :amount 1000, :comment "comment"}}
                     (get-mem :pending-zaps)))))
      )
    )

  (context "auto-thanks"
    (it "sends thanks for a zap when auto-thanks is :on"
      (with-redefs [composers/compose-and-send-text-event (stub :send)
                    config/auto-thanks :on
                    config/auto-thanks-fortune :off]
        (let [zapper-id (rand-int 1000000)]
          (gateway/add-profile @db zapper-id {:name "zapper"})
          (zaps/auto-thanks zapper-id)
          (should-have-invoked :send {:with [nil "Auto Thanks" "@zapper Thank you!\n"]}))))

    (it "dms thanks for a zap when auto-thanks is :dm"
      (with-redefs [composers/compose-and-send-text-event (stub :send)
                    config/auto-thanks :dm
                    config/auto-thanks-fortune :off]
        (let [zapper-id (rand-int 1000000)]
          (gateway/add-profile @db zapper-id {:name "zapper"})
          (zaps/auto-thanks zapper-id)
          (should-have-invoked :send {:with [nil "Auto Thanks" "D @zapper Thank you!\n"]}))))

    (it "sends thanks for a zap with a fortune"
      (with-redefs [composers/compose-and-send-text-event (stub :send)
                    fortune/get-message (stub :get-message {:return "hi"})
                    config/auto-thanks :on
                    config/auto-thanks-fortune :normal]
        (let [zapper-id (rand-int 1000000)]
          (gateway/add-profile @db zapper-id {:name "zapper"})
          (zaps/auto-thanks zapper-id)
          (should-have-invoked :send {:with [nil "Auto Thanks" "@zapper Thank you!\nhi"]}))))
    )

  (context "wallet-connect"
    (it "executes wallet-connect payment"
      (let [event-index (atom -1)
            events [{:content "pay_invoice"} {:kind 23195
                                              :tags [[:p "e6c47ae6962c5ea1559f48b437c193a1bcb1d72d08d75d743ba3cbfb8e7afbeb"]]
                                              :content "{\"result_type\": \"pay_invoice\"}"}]]
        (set-mem [:keys :wallet-connect] "nostrwalletconnect://beef?relay=wc-relay-url&secret=dead")
        (with-redefs [ws-relay/make (stub :relay-make {:return "some-relay"})
                      relay/open (stub :relay-open {:return "open-relay"})
                      relay/send (stub :relay-send)
                      relay/close (stub :relay-close)
                      zaps/decrypt-content (stub :calc-key {:invoke (fn [_ _ c] c)})
                      zaps/get-wc-request-event (stub :request-event {:return "request-event"})
                      async/<!! (stub :read-chan {:invoke (fn [_x] (get events (swap! event-index inc)))})]
          (zaps/zap-by-wallet-connect "event-to-zap")
          (should-have-invoked :relay-make {:with ["wc-relay-url" :*]})
          (should-have-invoked :relay-open {:with ["some-relay"]})
          (should-have-invoked :relay-send {:with ["open-relay" ["REQ" "ms-info" {"kinds" [13194], "authors" ["beef"]}]]})
          (should-have-invoked :request-event {:with ["event-to-zap" :*]})
          (should-have-invoked :relay-send {:with ["open-relay" "request-event"]})
          (should-have-invoked :relay-close {:with ["open-relay"]}))))

    (it "composes a wc request event"
      (with-redefs [config/proof-of-work-default 0]
        (let [sender-private-key-bytes (util/make-private-key)
              sender-private-key (util/bytes->num sender-private-key-bytes)
              sender-private-key-hex (util/hexify sender-private-key)
              sender-public-key-bytes (es/get-pub-key sender-private-key-bytes)
              sender-public-key (util/bytes->num sender-public-key-bytes)
              recipient-private-key-bytes (util/make-private-key)
              recipient-private-key (util/bytes->num recipient-private-key-bytes)
              recipient-public-key-bytes (es/get-pub-key recipient-private-key-bytes)
              recipient-public-key (util/bytes->num recipient-public-key-bytes)
              recipient-public-key-hex (util/hexify recipient-public-key)
              inbound-shared-secret (SECP256K1/calculateKeyAgreement
                                      recipient-private-key
                                      sender-public-key)
              request "request"
              _ (set-mem :pubkey 1)
              [_ event] (zaps/compose-wc-request-event recipient-public-key-hex sender-private-key-hex request)]
          (should= 23194 (:kind event))
          (should= [[:p recipient-public-key-hex]] (filter #(= :p (first %)) (:tags event)))
          (should= request (SECP256K1/decrypt inbound-shared-secret (:content event)))))))
  )
frenchy64/fully-satisfies
(ns io.github.frenchy64.fully-satisfies.non-leaky-macros.clojure.core
  "Implementations of clojure.core macros that don't leak implementation details."
  (:refer-clojure :exclude [locking binding with-bindings sync with-local-vars
                            with-in-str dosync with-precision with-loading-context
                            with-redefs delay vswap! lazy-seq lazy-cat future
                            pvalues])
  (:require [clojure.core :as cc]))

(defmacro non-leaky-with-redefs
  "Like clojure.core/with-redefs, except body not leak pre/post syntax and does not
  have a recur target available."
  [bindings & body]
  `(cc/with-redefs ~bindings
     (let [res# (do ~@body)]
       res#)))

(defmacro with-redefs
  [& args]
  `(non-leaky-with-redefs ~@args))

(defmacro non-leaky-vswap!
  "Like clojure.core/with-redefs, except vol is only expanded once and .reset never reflects."
  [vol f & args]
  `(let [v# ~vol]
     (cc/vswap! v# ~f ~@args)))
finnishtransportagency/harja
(ns harja.palvelin.integraatiot.api.yllapitokohteet-test
  (:require [clojure.test :refer [deftest testing is use-fixtures]]
            [harja.testi :refer :all]
            [taoensso.timbre :as log]
            [harja.palvelin.integraatiot.api.tyokalut :as api-tyokalut]
            [com.stuartsierra.component :as component]
            [cheshire.core :as cheshire]
            [harja.integraatio :as integraatio]
            [harja.palvelin.integraatiot.api.yllapitokohteet :as api-yllapitokohteet]
            [harja.palvelin.integraatiot.api.tyokalut.sijainnit :as sijainnit]
            [harja.palvelin.komponentit.fim-test :refer [+testi-fim+]]
            [harja.palvelin.integraatiot.vkm.vkm-test :refer [+testi-vkm+]]
            [harja.jms-test :refer [feikki-jms]]
            [clojure.core.async :refer [<!! timeout]]
            [clojure.string :as str]
            [harja.palvelin.komponentit.fim :as fim]
            [harja.palvelin.integraatiot.vayla-rest.sahkoposti :as sahkoposti-api]
            [harja.palvelin.integraatiot.jms :as jms]
            [clojure.java.io :as io]
            [harja.palvelin.integraatiot.vkm.vkm-komponentti :as vkm])
  (:import (org.postgresql.util PSQLException PSQLState)
           (java.util UUID))
  (:use org.httpkit.fake))

(deftest useamman-tarkastuksen-kirjaamisessa-transaktio-toimii
  (let [urakka-id (hae-urakan-id-nimella "Utajärven päällystysurakka")
        kohde-id (hae-utajarven-yllapitokohde-jolla-ei-ole-paallystysilmoitusta)
        hae-tarkastukset #(q-map "SELECT * FROM tarkastus WHERE yllapitokohde =" kohde-id)
        tarkastukset-ennen-kirjausta (hae-tarkastukset)
        polku ["/api/urakat/" urakka-id "/yllapitokohteet/" kohde-id "/tarkastus"]
        kutsudata (slurp "test/resurssit/api/usean-yllapitokohteen-tarkastuksen-kirjaus-request.json")
        _ (anna-kirjoitusoikeus kayttaja-paallystys)
        vastaus (with-redefs [sijainnit/hae-tierekisteriosoite (fn [db alkusijainti loppusijainti]
                                                                 (when (= (:x alkusijainti) 443673.469)
                                                                   (throw (PSQLException. "Foo" (PSQLState/DATA_ERROR)))))]
                  (api-tyokalut/post-kutsu polku kayttaja-paallystys portti kutsudata))
        tarkastukset-kirjauksen-jalkeen (hae-tarkastukset)]
    (is (= 500 (:status vastaus)))
    (is (= (count tarkastukset-ennen-kirjausta) (count tarkastukset-kirjauksen-jalkeen)))))