Skip to content

Instantly share code, notes, and snippets.

@wilkes
Created July 16, 2010 19:51
Show Gist options
  • Save wilkes/478827 to your computer and use it in GitHub Desktop.
Save wilkes/478827 to your computer and use it in GitHub Desktop.
(ns karras.test-hooks
(:require [karras.core :as karras])
(:use karras.entity
karras.sugar
[karras.collection :only [drop-collection collection]]
clojure.test
midje.semi-sweet
robert.hooke))
(defn get-type [entity-or-type]
(if (= Class (class entity-or-type))
entity-or-type
(class entity-or-type)))
(defonce db (karras/mongo-db :karras-testing))
(defentity Person [:name])
(defentity Company
[:name
:ceo {:type Person}
:employees {:type :list :of Person}])
;; Example hook impl for logging the results of Company creation and deletion.
;; store calls for verification
(def companies-created (atom []))
(def companies-deleted (atom []))
;; define a multimethod to handle dispatching from with the hook
(defmulti handle-log-result (fn [f type result args] [f type]))
;; define a no-op default
(defmethod handle-log-result :default [& _])
;; define the hook itself. Invokes the hooked function and
;; passes the result and args to the multimethod
(defn log-result [f & args]
(let [result (apply f args)]
(handle-log-result f (get-type (first args)) result args)
result))
;; log creatation of companies
(defmethod handle-log-result [create Company]
[f type result args]
(swap! companies-created conj result))
;; log deletion of companies
(defmethod handle-log-result [delete Company]
[f type result args]
(swap! companies-deleted (fn [curr] (apply conj curr args))))
;; setup and clear the collections and hooks
(use-fixtures :each (fn [t]
(karras/with-mongo-request db
(add-hook #'create log-result)
(add-hook #'delete log-result)
(t)
(remove-hook #'delete log-result)
(remove-hook #'create log-result)
(drop-collection (collection-for Person))
(drop-collection (collection-for Company)))))
;; example usage
(deftest test-log-hooks
(expect @companies-created => [])
(expect @companies-deleted => [])
(let [acme (create Company {:name "ACME"})]
(expect @companies-created => [acme])
(expect @companies-deleted => [])
(delete acme)
(expect @companies-created => [acme])
(expect @companies-deleted => [acme]))
(testing ":default dispatch, blows up if :default not implemented"
(let [john (create Person {:name "John"})]
(delete john))))
@bhenry
Copy link

bhenry commented Jul 16, 2010

very nice!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment