PageRenderTime 90ms CodeModel.GetById 47ms app.highlight 37ms RepoModel.GetById 1ms app.codeStats 0ms

/test/lobos/test.clj

http://github.com/budu/lobos
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))