forked from avescodes/conformity
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Tests, default conformity attribute, and numerous doc changes
- Also removed "requires" dependencies for the time being.
- Loading branch information
Ryan Neufeld
committed
Oct 26, 2012
1 parent
42de9ce
commit fe1f765
Showing
4 changed files
with
88 additions
and
63 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,3 +8,4 @@ pom.xml | |
.lein-deps-sum | ||
.lein-failures | ||
.lein-plugins | ||
dev |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,61 +1,64 @@ | ||
(ns conformity | ||
(:use [datomic.api :only [q db] :as d])) | ||
|
||
(defn- has-attribute? | ||
"Does database have an attribute named attr-name?" | ||
(def default-conformity-attribute :confirmity/conformed-norms) | ||
|
||
(defn has-attribute? | ||
"Check if a database has an attribute named attr-name" | ||
[db attr-name] | ||
(-> (d/entity db attr-name) | ||
:db.install/_attribute | ||
boolean)) | ||
|
||
(defn- ensure-conformity-attribute | ||
"Ensure that conformity-attr, a keyword-valued attribute used | ||
as a value on transactions to track named norms, is | ||
installed in database." | ||
(defn ensure-conformity-attribute | ||
"Ensure that conformity-attr, a keyword-valued attribute, | ||
is installed in database." | ||
[conn conformity-attr] | ||
(when-not (has-attribute? (db conn) conformity-attr) | ||
(d/transact conn [{:db/id #db/id [:db.part/db] | ||
:db/ident conformity-attr | ||
:db/valueType :db.type/keyword | ||
:db/cardinality :db.cardinality/one | ||
:db/doc "Name of schema installed by this transaction" | ||
:db/index true | ||
:db.install/_attribute :db.part/db}]))) | ||
:db/ident conformity-attr | ||
:db/valueType :db.type/keyword | ||
:db/cardinality :db.cardinality/one | ||
:db/doc "Name of schema installed by this transaction" | ||
:db/index true | ||
:db.install/_attribute :db.part/db}]))) | ||
|
||
(defn conforms-to? | ||
"Does database have a schema named norm installed? | ||
Uses conformity-attr (an attribute added to transactions!) to track | ||
which schema names are installed." | ||
[db conformity-attr norm] | ||
(and (has-attribute? db conformity-attr) | ||
(-> (q '[:find ?e | ||
:in $ ?sa ?sn | ||
:where [?e ?sa ?sn ?e]] | ||
db conformity-attr norm) | ||
seq boolean))) | ||
"Does database have a norm installed? | ||
conformity-attr (optional) the keyword name of the attribute used to track | ||
conformity | ||
norm the keyword name of the norm you want to check" | ||
([db norm] (conforms-to? db default-conformity-attribute norm)) | ||
([db conformity-attr norm] | ||
(and (has-attribute? db conformity-attr) | ||
(-> (q '[:find ?e | ||
:in $ ?sa ?sn | ||
:where [?e ?sa ?sn ?e]] | ||
db conformity-attr norm) | ||
seq boolean)))) | ||
|
||
(defn ensure-conforms | ||
"Ensure that norms represented as datoms are conformed-to (installed), be they | ||
schema, data or otherwise. | ||
conformity-attr the keyword-valued attribute in which | ||
enacted norms will be recorded | ||
conformity-attr (optional) the keyword-valued attribute where conformity | ||
tracks enacted norms. | ||
norm-map a map from norm names to data maps. | ||
the data map contains two keys: | ||
the data map contains one keys: | ||
:txes - the data to install | ||
:requires - a list of other norms to conform to | ||
norms the names of norms to conform to" | ||
[conn conformity-attr norm-map & names] | ||
(ensure-conformity-attribute conn conformity-attr) | ||
(doseq [norm names] | ||
(when-not (conforms-to? (db conn) conformity-attr norm) | ||
(let [{:keys [requires txes]} (get norm-map norm)] | ||
(apply ensure-conforms conn conformity-attr norm-map requires) | ||
(if txes | ||
(doseq [tx txes] | ||
;; hrm, could mark the last tx specially | ||
(d/transact conn (cons {:db/id (d/tempid :db.part/tx) | ||
conformity-attr norm} | ||
tx))) | ||
(throw (ex-info (str "No data provided for norm" norm) | ||
{:schema/missing norm}))))))) | ||
norm-names A collection of names of norms to conform to" | ||
([conn norm-map norm-names] (ensure-conforms conn default-conformity-attribute norm-map norm-names)) | ||
([conn conformity-attr norm-map norm-names] | ||
(ensure-conformity-attribute conn conformity-attr) | ||
(doseq [norm norm-names] | ||
(when-not (conforms-to? (db conn) conformity-attr norm) | ||
(let [{txes :txes} (get norm-map norm)] | ||
(if txes | ||
(doseq [tx txes] | ||
;; hrm, could mark the last tx specially | ||
(d/transact conn (cons {:db/id (d/tempid :db.part/tx) | ||
conformity-attr norm} | ||
tx))) | ||
(throw (ex-info (str "No data provided for norm " norm) | ||
{:schema/missing norm})))))))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,38 +1,57 @@ | ||
(ns conformity-test | ||
(:use clojure.test | ||
conformity | ||
[datomic.api :only [db] :as d])) | ||
[datomic.api :only [q db] :as d])) | ||
|
||
(def uri "datomic:mem://test") | ||
(defn fresh-conn [] | ||
(d/delete-database uri) | ||
(d/create-database uri) | ||
(d/connect uri)) | ||
|
||
(def sample-norms-map {:test/norm-1 {:txes [[]]}}) | ||
(def sample-norms (keys sample-norms-map)) | ||
(def sample-norms-map {:test/norm-1 | ||
{:txes [[{:db/id #db/id [:db.part/db] | ||
:db/ident :test/attribute | ||
:db/valueType :db.type/string | ||
:db/cardinality :db.cardinality/one | ||
:db/fulltext false | ||
:db/index false | ||
:db.install/_attribute :db.part/db}]]}}) | ||
|
||
(deftest test-ensure-conforms | ||
(testing "installs all norm expected" | ||
(let [conn (fresh-conn)] | ||
(ensure-conforms conn sample-norms-map [:test/norm-1]) | ||
(is (= 1 (count (q '[:find ?e :where [?e :db/ident :test/attribute]] (db conn))))))) | ||
|
||
(testing "throws exception if norm-map lacks transactions for a norm" | ||
(let [conn (fresh-conn)] | ||
(is (thrown-with-msg? clojure.lang.ExceptionInfo #"No data provided for norm :test/norm-2" | ||
(ensure-conforms conn {:test/norm-2 {}} [:test/norm-2])))))) | ||
|
||
(deftest test-conforms-to? | ||
(testing "returns true if a norm is already installed" | ||
(let [conn (fresh-conn)] | ||
(ensure-conformity-attribute conn :test/conformity) | ||
(ensure-conforms conn :test/conformity {})) | ||
(is )) | ||
(ensure-conforms conn sample-norms-map [:test/norm-1]) | ||
(is (= true (conforms-to? (db conn) :test/norm-1))))) | ||
|
||
(testing "returns false if a norm has not been installed" | ||
(is false)) | ||
(let [conn (fresh-conn)] | ||
(ensure-conformity-attribute conn default-conformity-attribute) | ||
(is (= false (conforms-to? (db conn) :test/norm-1))))) | ||
|
||
(testing "returns false if conformity-attr does not exist" | ||
(is false))) | ||
|
||
(deftest test-ensure-conforms | ||
(testing "installs all norm expected" (is false)) | ||
(testing "throws exception if norm-map lacks transactions for a norm" (is false))) | ||
|
||
;; How do you test private functions? | ||
(def has-attribute? (ns-resolve 'conform 'has-attribute?)) | ||
(deftest test-has-attribute? | ||
(testing "is true when attribute exists in db" (is false)) | ||
(testing "is false when attribute isn't in db" (is false))) | ||
(let [conn (fresh-conn)] | ||
(is (= false (conforms-to? (db conn) :test/norm-1)))))) | ||
|
||
(def ensure-conformity-attribute (ns-resolve 'conform 'ensure-conform-attribute)) | ||
(deftest test-ensure-conform-attribute | ||
(testing "it adds the conformity attribute if it is absent") | ||
(testing "it does nothing if the conformity attribute exists")) | ||
(testing "it adds the conformity attribute if it is absent" | ||
(let [conn (fresh-conn)] | ||
(ensure-conformity-attribute conn :test/conformity) | ||
(is (= true (has-attribute? (db conn) :test/conformity))))) | ||
|
||
(testing "it does nothing if the conformity attribute exists" | ||
(defn count-txes [conn] (count (q '[:find ?tx :where [?tx :db/txInstant _]] (db conn)))) | ||
(let [conn (fresh-conn)] | ||
(ensure-conformity-attribute conn :test/conformity) | ||
(is (= (count-txes conn) (do (ensure-conformity-attribute conn :test/conformity) (count-txes conn))))))) |