Multi-DB testing

Instead of just testing against H2 in-memory, we now test against Derby, 
H2 in-memory, H2 on-disk, hsqldb, and SQLite
This commit is contained in:
Sean Corfield 2019-04-21 17:10:29 -07:00
parent 2badd9f835
commit 2702a01773
4 changed files with 69 additions and 31 deletions

View file

@ -19,9 +19,9 @@
(deftest test-datafy-nav (deftest test-datafy-nav
(testing "default schema" (testing "default schema"
(let [connectable (ds) (let [connectable (ds)
test-row (rs/datafiable-row {:table/fruit_id 1} connectable {}) test-row (rs/datafiable-row {:TABLE/FRUIT_ID 1} connectable {})
data (d/datafy test-row) data (d/datafy test-row)
v (get data :table/fruit_id)] v (get data :TABLE/FRUIT_ID)]
;; check datafication is sane ;; check datafication is sane
(is (= 1 v)) (is (= 1 v))
(let [object (d/nav data :table/fruit_id v)] (let [object (d/nav data :table/fruit_id v)]

View file

@ -7,7 +7,8 @@
(:require [clojure.test :refer [deftest is testing use-fixtures]] (:require [clojure.test :refer [deftest is testing use-fixtures]]
[next.jdbc.quoted :refer [mysql sql-server]] [next.jdbc.quoted :refer [mysql sql-server]]
[next.jdbc.sql :as sql] [next.jdbc.sql :as sql]
[next.jdbc.test-fixtures :refer [with-test-db ds]])) [next.jdbc.test-fixtures
:refer [with-test-db ds derby? sqlite?]]))
(use-fixtures :once with-test-db) (use-fixtures :once with-test-db)
@ -117,7 +118,12 @@
(deftest test-insert-delete (deftest test-insert-delete
(testing "single insert/delete" (testing "single insert/delete"
(is (= {:FRUIT/ID 5} (is (= (cond (derby?)
{:1 5M}
(sqlite?)
{(keyword "last_insert_rowid()") 5}
:else
{:FRUIT/ID 5})
(sql/insert! (ds) :fruit (sql/insert! (ds) :fruit
{:name "Kiwi" :appearance "green & fuzzy" {:name "Kiwi" :appearance "green & fuzzy"
:cost 100 :grade 99.9}))) :cost 100 :grade 99.9})))
@ -126,7 +132,12 @@
(sql/delete! (ds) :fruit {:id 5}))) (sql/delete! (ds) :fruit {:id 5})))
(is (= 4 (count (sql/query (ds) ["select * from fruit"]))))) (is (= 4 (count (sql/query (ds) ["select * from fruit"])))))
(testing "multiple insert/delete" (testing "multiple insert/delete"
(is (= [{:FRUIT/ID 6} {:FRUIT/ID 7} {:FRUIT/ID 8}] (is (= (cond (derby?)
[{:1 nil}] ; WTF Apache Derby?
(sqlite?)
[{(keyword "last_insert_rowid()") 8}]
:else
[{:FRUIT/ID 6} {:FRUIT/ID 7} {:FRUIT/ID 8}])
(sql/insert-multi! (ds) :fruit (sql/insert-multi! (ds) :fruit
[:name :appearance :cost :grade] [:name :appearance :cost :grade]
[["Kiwi" "green & fuzzy" 100 99.9] [["Kiwi" "green & fuzzy" 100 99.9]

View file

@ -4,7 +4,23 @@
(:require [next.jdbc :as jdbc] (:require [next.jdbc :as jdbc]
[next.jdbc.sql :as sql])) [next.jdbc.sql :as sql]))
(def ^:private test-db-spec {:dbtype "h2:mem" :dbname "clojure_test_fixture"}) (def ^:private test-derby {:dbtype "derby" :dbname "clojure_test_derby" :create true})
(def ^:private test-h2-mem {:dbtype "h2:mem" :dbname "clojure_test_h2_mem"})
(def ^:private test-h2 {:dbtype "h2" :dbname "clojure_test_h2"})
(def ^:private test-hsql {:dbtype "hsqldb" :dbname "clojure_test_hsqldb"})
(def ^:private test-sqlite {:dbtype "sqlite" :dbname "clojure_test_sqlite"})
(def ^:private test-db-specs [test-derby test-h2-mem test-h2 test-hsql test-sqlite])
(def ^:private test-db-spec (atom nil))
(defn derby? [] (= "derby" (:dbtype @test-db-spec)))
(defn sqlite? [] (= "sqlite" (:dbtype @test-db-spec)))
(def ^:private test-datasource (atom nil)) (def ^:private test-datasource (atom nil))
@ -20,24 +36,35 @@
Tests can reach into here and call ds (above) to get a DataSource for use Tests can reach into here and call ds (above) to get a DataSource for use
in test functions (that operate inside this fixture)." in test functions (that operate inside this fixture)."
[t] [t]
(reset! test-datasource (jdbc/get-datasource test-db-spec)) (doseq [db test-db-specs]
(with-open [con (jdbc/get-connection (ds))] (reset! test-db-spec db)
(try (reset! test-datasource (jdbc/get-datasource db))
(jdbc/execute-one! con ["DROP TABLE fruit"]) (let [auto-inc-pk
(catch Exception _)) (cond (or (derby?) (= "hsqldb" (:dbtype db)))
(jdbc/execute-one! con [" (str "GENERATED ALWAYS AS IDENTITY"
CREATE TABLE fruit ( " (START WITH 1, INCREMENT BY 1)"
id int auto_increment primary key, " PRIMARY KEY")
name varchar(32), (sqlite?)
appearance varchar(32), "PRIMARY KEY AUTOINCREMENT"
cost int, :else
grade real "AUTO_INCREMENT PRIMARY KEY")]
)"]) (with-open [con (jdbc/get-connection (ds))]
(sql/insert-multi! con :fruit (try
[:id :name :appearance :cost :grade] (jdbc/execute-one! con ["DROP TABLE FRUIT"])
[[1 "Apple" "red" 59 87] (catch Exception _))
[2,"Banana","yellow",29,92.2] (jdbc/execute-one! con [(str "
[3,"Peach","fuzzy",139,90.0] CREATE TABLE FRUIT (
[4,"Orange","juicy",89,88.6]] ID INTEGER " auto-inc-pk ",
{:return-keys false}) NAME VARCHAR(32),
(t))) APPEARANCE VARCHAR(32),
COST INT,
GRADE REAL
)")])
(sql/insert-multi! con :fruit
[:name :appearance :cost :grade]
[["Apple" "red" 59 87]
["Banana","yellow",29,92.2]
["Peach","fuzzy",139,90.0]
["Orange","juicy",89,88.6]]
{:return-keys false})
(t)))))

View file

@ -98,8 +98,8 @@
(is (= [{:next.jdbc/update-count 1}] (is (= [{:next.jdbc/update-count 1}]
(jdbc/transact (ds) (jdbc/transact (ds)
(fn [t] (jdbc/execute! t [" (fn [t] (jdbc/execute! t ["
INSERT INTO fruit (id, name, appearance, cost, grade) INSERT INTO fruit (name, appearance, cost, grade)
VALUES (5, 'Pear', 'green', 49, 47) VALUES ('Pear', 'green', 49, 47)
"])) "]))
{:rollback-only true}))) {:rollback-only true})))
(is (= 4 (count (jdbc/execute! (ds) ["select * from fruit"]))))) (is (= 4 (count (jdbc/execute! (ds) ["select * from fruit"])))))
@ -107,7 +107,7 @@ VALUES (5, 'Pear', 'green', 49, 47)
(is (= [{:next.jdbc/update-count 1}] (is (= [{:next.jdbc/update-count 1}]
(jdbc/with-transaction [t (ds) {:rollback-only true}] (jdbc/with-transaction [t (ds) {:rollback-only true}]
(jdbc/execute! t [" (jdbc/execute! t ["
INSERT INTO fruit (id, name, appearance, cost, grade) INSERT INTO fruit (name, appearance, cost, grade)
VALUES (5, 'Pear', 'green', 49, 47) VALUES ('Pear', 'green', 49, 47)
"])))) "]))))
(is (= 4 (count (jdbc/execute! (ds) ["select * from fruit"])))))) (is (= 4 (count (jdbc/execute! (ds) ["select * from fruit"]))))))