[{:test/label ":db.cardinality/one, insert" :test/assertions [[:db/add 100 :db/ident :name/Ivan] [:db/add 101 :db/ident :name/Petr]] :test/expected-transaction #{[100 :db/ident :name/Ivan ?tx1 true] [101 :db/ident :name/Petr ?tx1 true] [?tx1 :db/txInstant ?ms1 ?tx1 true]} :test/expected-datoms #{[100 :db/ident :name/Ivan] [101 :db/ident :name/Petr]}} {:test/label "upsert two tempids to same entid" :test/assertions [[:db/add "t1" :db/ident :name/Ivan] [:db/add "t1" :db.schema/attribute 100] [:db/add "t2" :db/ident :name/Petr] [:db/add "t2" :db.schema/attribute 101]] :test/expected-transaction #{[100 :db.schema/attribute 100 ?tx2 true] [101 :db.schema/attribute 101 ?tx2 true] [?tx2 :db/txInstant ?ms2 ?tx2 true]} :test/expected-datoms #{[100 :db/ident :name/Ivan] [101 :db/ident :name/Petr] [100 :db.schema/attribute 100] [101 :db.schema/attribute 101]} :test/expected-tempids {"t1" 100 "t2" 101}} {:test/label "upsert with tempid" :test/assertions [[:db/add "t1" :db/ident :name/Ivan] ;; Ref doesn't have to exist (at this time). Can't reuse due to :db/unique :db.unique/value. [:db/add "t1" :db.schema/attribute 102]] :test/expected-transaction #{[100 :db.schema/attribute 102 ?tx3 true] [?tx3 :db/txInstant ?ms3 ?tx3 true]} :test/expected-datoms #{[100 :db/ident :name/Ivan] [101 :db/ident :name/Petr] [100 :db.schema/attribute 100] [100 :db.schema/attribute 102] [101 :db.schema/attribute 101]} :test/expected-tempids {"t1" 100}} ;; TODO: don't hard-code allocated entids. {:test/label "single complex upsert allocates new entid" :test/assertions [[:db/add "t1" :db.schema/attribute "t2"]] :test/expected-transaction #{[65536 :db.schema/attribute 65537 ?tx4 true] [?tx4 :db/txInstant ?ms4 ?tx4 true]} :test/expected-tempids {"t1" 65536 "t2" 65537}} {:test/label "conflicting upserts fail" :test/assertions [[:db/add "t1" :db/ident :name/Ivan] [:db/add "t1" :db/ident :name/Petr]] :test/expected-transaction nil :test/expected-error-message "Conflicting upsert" ;; nil } {:test/label "tempids in :db/retract that do upsert are fine" :test/assertions [[:db/add "t1" :db/ident :name/Ivan] ;; This ref doesn't exist, so the assertion will be ignored. [:db/retract "t1" :db.schema/attribute 103]] :test/expected-transaction #{[?tx6 :db/txInstant ?ms6 ?tx6 true]} :test/expected-error-message "" :test/expected-tempids {}} {:test/label "tempids in :db/retract that don't upsert fail" :test/assertions [[:db/retract "t1" :db/ident :name/Anonymous]] :test/expected-transaction nil :test/expected-error-message ""} ;; The upsert algorithm will first try to resolve "t1", fail, and then allocate both "t1" and "t2". {:test/label "multistep, both allocated" :test/assertions [[:db/add "t1" :db/ident :name/Josef] [:db/add "t2" :db.schema/attribute "t1"]] :test/expected-transaction #{[65538 :db/ident :name/Josef ?tx8 true] [65539 :db.schema/attribute 65538 ?tx8 true] [?tx8 :db/txInstant ?ms8 ?tx8 true]} :test/expected-error-message "" :test/expected-tempids {"t1" 65538 "t2" 65539}} ;; Can't quite test this without more schema elements. ;; ;; This time, we can resolve both, but we have to try "t1", succeed, and then resolve "t2". ;; {:test/label "multistep, upserted allocated" ;; :test/assertions ;; [[:db/add "t1" :db/ident :name/Josef] ;; [:db/add "t2" :db/ident "t1"]] ;; :test/expected-transaction ;; #{[65538 :db/ident :name/Josef] ;; [65538 :db/ident :name/Karl] ;; [?tx8 :db/txInstant ?ms8 ?tx8 true]} ;; :test/expected-error-message ;; "" ;; :test/expected-tempids ;; {"t1" 65538 ;; "t2" 65539}} ]