/test/lobos/test.clj
Clojure | 152 lines | 116 code | 26 blank | 10 comment | 1 complexity | 9fb65bd63795ed270ad421e84aa130f6 MD5 | raw file
1;; Copyright (c) Nicolas Buduroi. All rights reserved. 2;; The use and distribution terms for this software are covered by the 3;; Eclipse Public License 1.0 which can be found in the file 4;; epl-v10.html at the root of this distribution. By using this software 5;; in any fashion, you are agreeing to be bound by the terms of this 6;; license. 7;; You must not remove this notice, or any other, from this software. 8 9(ns lobos.test 10 (:refer-clojure :exclude [alter defonce drop]) 11 (:use clojure.test 12 (clojure.java [io :only [delete-file file]]) 13 (lobos analyzer connectivity core utils) 14 (lobos [schema :only [schema]])) 15 (:import (java.lang UnsupportedOperationException))) 16 17;;;; DB connection specifications 18 19(def h2-spec 20 {:classname "org.h2.Driver" 21 :subprotocol "h2" 22 :subname "./lobos.h2" 23 :unsafe true}) 24 25(def mysql-spec 26 {:classname "com.mysql.jdbc.Driver" 27 :subprotocol "mysql" 28 :user "lobos" 29 :password "lobos" 30 :subname "//localhost:3306/" 31 :unsafe true}) 32 33(def postgresql-spec 34 {:classname "org.postgresql.Driver" 35 :subprotocol "postgresql" 36 :user "lobos" 37 :password "lobos" 38 :subname "//localhost:5432/lobos" 39 :unsafe true}) 40 41(def sqlite-spec 42 {:classname "org.sqlite.JDBC" 43 :subprotocol "sqlite" 44 :subname "./lobos.sqlite3" 45 :create true 46 :unsafe true}) 47 48(def sqlserver-spec 49 {:classname "com.microsoft.sqlserver.jdbc.SQLServerDriver" 50 :subprotocol "sqlserver" 51 :user "lobos" 52 :password "lobos" 53 :subname "//localhost:1433" 54 :databaseName "lobos" 55 :unsafe true}) 56 57(def db-specs [h2-spec 58 mysql-spec 59 postgresql-spec 60 sqlite-spec 61 sqlserver-spec]) 62 63(defn driver-available? 64 [{:keys [classname]}] 65 (try 66 (clojure.lang.RT/classForName classname) 67 true 68 (catch Exception e false))) 69 70(def available-specs (filter driver-available? db-specs)) 71 72(defn available-global-cnx [] 73 (keys @global-connections)) 74 75(defn test-db-name [db-spec] 76 (keyword (:subprotocol db-spec))) 77 78(def ^{:dynamic true} *db* nil) 79 80;;;; Helpers 81 82(defn first-non-runtime-cause [e] 83 (if (isa? (type e) RuntimeException) 84 (if-let [c (.getCause e)] 85 (first-non-runtime-cause c) 86 e) 87 e)) 88 89(defmacro when-supported [action & body] 90 `(try ~action 91 ~@body 92 (catch Exception e# 93 (when-not (isa? (type (first-non-runtime-cause e#)) 94 UnsupportedOperationException) 95 (throw e#))))) 96 97(defmacro def-db-test [name & body] 98 `(do ~@(for [db-spec available-specs] 99 (let [db (test-db-name db-spec)] 100 `(deftest ~(symbol (str name "-" (:subprotocol db-spec))) 101 (when ((set (available-global-cnx)) ~db) 102 (binding [*db* ~db] 103 ~@body))))))) 104 105(defmacro with-schema [[var-name sname] & body] 106 `(let [db-spec# (get-db-spec *db*)] 107 (try 108 (let [~var-name (schema ~sname {:db-spec db-spec#})] 109 (create db-spec# ~var-name) 110 ~@body) 111 (finally (try (drop db-spec# (schema ~sname) :cascade) 112 (catch Exception _#)))))) 113 114(defmacro inspect-schema [& keys] 115 `(-> (analyze-schema *db* :lobos) ~@keys)) 116 117(defn open-global-connections [] 118 (doseq [db-spec available-specs] 119 (try 120 (open-global (test-db-name db-spec) db-spec) 121 (catch Exception _ 122 (println "WARNING: Failed to connect to" (:subprotocol db-spec)))))) 123 124(defn close-global-connections [] 125 (doseq [db (available-global-cnx)] 126 (close-global db))) 127 128;;;; Fixtures 129 130(def tmp-files-ext '(db sqlite3)) 131 132(defn remove-tmp-files [] 133 (let [current-dir (file-seq (file ".")) 134 p (str ".*\\." (apply join "|" tmp-files-ext)) 135 tmp? #(re-find (re-pattern p) (str %))] 136 (doseq [tmp-file (filter tmp? current-dir)] 137 (delete-file tmp-file true)))) 138 139(defn remove-tmp-files-fixture [f] 140 (remove-tmp-files) 141 (f) 142 (remove-tmp-files)) 143 144(defn open-global-connections-fixture [f] 145 (doseq [db-spec db-specs] 146 (when-not (driver-available? db-spec) 147 (println (format "WARNING: Driver for %s isn't available: %s missing" 148 (:subprotocol db-spec) 149 (:classname db-spec))))) 150 (open-global-connections) 151 (f) 152 (close-global-connections))