datahike-browser-tests 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.circleci/config.yml +405 -0
- package/.circleci/scripts/gen_ci.clj +194 -0
- package/.cirrus.yml +60 -0
- package/.clj-kondo/babashka/sci/config.edn +1 -0
- package/.clj-kondo/babashka/sci/sci/core.clj +9 -0
- package/.clj-kondo/config.edn +95 -0
- package/.dir-locals.el +2 -0
- package/.github/FUNDING.yml +3 -0
- package/.github/ISSUE_TEMPLATE/1-bug-report.yml +68 -0
- package/.github/ISSUE_TEMPLATE/2-feature-request.yml +28 -0
- package/.github/ISSUE_TEMPLATE/config.yml +6 -0
- package/.github/pull_request_template.md +24 -0
- package/.github/workflows/native-image.yml +84 -0
- package/LICENSE +203 -0
- package/README.md +273 -0
- package/bb/deps.edn +9 -0
- package/bb/resources/github-fingerprints +3 -0
- package/bb/resources/native-image-tests/run-bb-pod-tests.clj +162 -0
- package/bb/resources/native-image-tests/run-libdatahike-tests +12 -0
- package/bb/resources/native-image-tests/run-native-image-tests +74 -0
- package/bb/resources/native-image-tests/run-python-tests +22 -0
- package/bb/resources/native-image-tests/testconfig.attr-refs.edn +6 -0
- package/bb/resources/native-image-tests/testconfig.edn +5 -0
- package/bb/resources/template/.settings/org.eclipse.jdt.apt.core.prefs +2 -0
- package/bb/resources/template/.settings/org.eclipse.jdt.core.prefs +9 -0
- package/bb/resources/template/.settings/org.eclipse.m2e.core.prefs +4 -0
- package/bb/resources/template/pom.xml +22 -0
- package/bb/src/tools/build.clj +132 -0
- package/bb/src/tools/clj_kondo.clj +32 -0
- package/bb/src/tools/deploy.clj +26 -0
- package/bb/src/tools/examples.clj +19 -0
- package/bb/src/tools/npm.clj +100 -0
- package/bb/src/tools/python.clj +14 -0
- package/bb/src/tools/release.clj +94 -0
- package/bb/src/tools/test.clj +148 -0
- package/bb/src/tools/version.clj +47 -0
- package/bb.edn +269 -0
- package/benchmark/src/benchmark/cli.clj +195 -0
- package/benchmark/src/benchmark/compare.clj +157 -0
- package/benchmark/src/benchmark/config.clj +316 -0
- package/benchmark/src/benchmark/measure.clj +187 -0
- package/benchmark/src/benchmark/store.clj +190 -0
- package/benchmark/test/benchmark/measure_test.clj +156 -0
- package/build.clj +30 -0
- package/config.edn +49 -0
- package/deps.edn +138 -0
- package/dev/sandbox.clj +82 -0
- package/dev/sandbox.cljs +127 -0
- package/dev/sandbox_benchmarks.clj +27 -0
- package/dev/sandbox_client.clj +87 -0
- package/dev/sandbox_transact_bench.clj +109 -0
- package/dev/user.clj +79 -0
- package/doc/README.md +96 -0
- package/doc/adl/README.md +6 -0
- package/doc/adl/adr-000-adr.org +28 -0
- package/doc/adl/adr-001-attribute-references.org +15 -0
- package/doc/adl/adr-002-build-tooling.org +54 -0
- package/doc/adl/adr-003-db-meta-data.md +52 -0
- package/doc/adl/adr-004-github-flow.md +40 -0
- package/doc/adl/adr-XYZ-template.md +30 -0
- package/doc/adl/index.org +3 -0
- package/doc/assets/datahike-logo.svg +3 -0
- package/doc/assets/datahiking-invoice.org +85 -0
- package/doc/assets/hhtree2.png +0 -0
- package/doc/assets/network_topology.svg +624 -0
- package/doc/assets/perf.png +0 -0
- package/doc/assets/schema_mindmap.mm +132 -0
- package/doc/assets/schema_mindmap.svg +970 -0
- package/doc/assets/temporal_index.mm +74 -0
- package/doc/backend-development.md +78 -0
- package/doc/bb-pod.md +89 -0
- package/doc/benchmarking.md +360 -0
- package/doc/bindings/edn-conversion.md +383 -0
- package/doc/cli.md +162 -0
- package/doc/cljdoc.edn +27 -0
- package/doc/cljs-support.md +133 -0
- package/doc/config.md +406 -0
- package/doc/contributing.md +114 -0
- package/doc/datalog-vs-sql.md +210 -0
- package/doc/datomic_differences.md +109 -0
- package/doc/development/pull-api-ns.md +186 -0
- package/doc/development/pull-frame-state-diagram.jpg +0 -0
- package/doc/distributed.md +566 -0
- package/doc/entity_spec.md +92 -0
- package/doc/gc.md +273 -0
- package/doc/java-api.md +808 -0
- package/doc/javascript-api.md +421 -0
- package/doc/libdatahike.md +86 -0
- package/doc/logging_and_error_handling.md +43 -0
- package/doc/norms.md +66 -0
- package/doc/schema-migration.md +85 -0
- package/doc/schema.md +287 -0
- package/doc/storage-backends.md +363 -0
- package/doc/store-id-refactoring.md +596 -0
- package/doc/time_variance.md +325 -0
- package/doc/unstructured.md +167 -0
- package/doc/versioning.md +261 -0
- package/examples/basic/README.md +19 -0
- package/examples/basic/deps.edn +6 -0
- package/examples/basic/docker-compose.yml +13 -0
- package/examples/basic/src/examples/core.clj +60 -0
- package/examples/basic/src/examples/schema.clj +155 -0
- package/examples/basic/src/examples/store.clj +60 -0
- package/examples/basic/src/examples/time_travel.clj +185 -0
- package/examples/java/.settings/org.eclipse.core.resources.prefs +3 -0
- package/examples/java/.settings/org.eclipse.jdt.apt.core.prefs +2 -0
- package/examples/java/.settings/org.eclipse.jdt.core.prefs +9 -0
- package/examples/java/.settings/org.eclipse.m2e.core.prefs +4 -0
- package/examples/java/README.md +162 -0
- package/examples/java/pom.xml +62 -0
- package/examples/java/src/main/java/examples/QuickStart.java +115 -0
- package/examples/java/src/main/java/examples/SchemaExample.java +148 -0
- package/examples/java/src/main/java/examples/TimeTravelExample.java +121 -0
- package/flake.lock +27 -0
- package/flake.nix +27 -0
- package/http-server/datahike/http/middleware.clj +75 -0
- package/http-server/datahike/http/server.clj +269 -0
- package/java/src/datahike/java/Database.java +274 -0
- package/java/src/datahike/java/Datahike.java +281 -0
- package/java/src/datahike/java/DatahikeGeneratedTest.java +349 -0
- package/java/src/datahike/java/DatahikeTest.java +370 -0
- package/java/src/datahike/java/EDN.java +170 -0
- package/java/src/datahike/java/IEntity.java +11 -0
- package/java/src/datahike/java/Keywords.java +161 -0
- package/java/src/datahike/java/SchemaFlexibility.java +52 -0
- package/java/src/datahike/java/Util.java +219 -0
- package/karma.conf.js +19 -0
- package/libdatahike/compile-cpp +7 -0
- package/libdatahike/src/datahike/impl/LibDatahikeBase.java +203 -0
- package/libdatahike/src/datahike/impl/libdatahike.clj +59 -0
- package/libdatahike/src/test_cpp.cpp +61 -0
- package/npm-package/PUBLISHING.md +140 -0
- package/npm-package/README.md +226 -0
- package/npm-package/package.template.json +34 -0
- package/npm-package/test-isomorphic.ts +281 -0
- package/npm-package/test.js +557 -0
- package/npm-package/typescript-test.ts +70 -0
- package/package.json +16 -0
- package/pydatahike/README.md +569 -0
- package/pydatahike/pyproject.toml +91 -0
- package/pydatahike/setup.py +42 -0
- package/pydatahike/src/datahike/__init__.py +134 -0
- package/pydatahike/src/datahike/_native.py +250 -0
- package/pydatahike/src/datahike/_version.py +2 -0
- package/pydatahike/src/datahike/database.py +722 -0
- package/pydatahike/src/datahike/edn.py +311 -0
- package/pydatahike/src/datahike/py.typed +0 -0
- package/pydatahike/tests/conftest.py +17 -0
- package/pydatahike/tests/test_basic.py +170 -0
- package/pydatahike/tests/test_database.py +51 -0
- package/pydatahike/tests/test_edn_conversion.py +299 -0
- package/pydatahike/tests/test_query.py +99 -0
- package/pydatahike/tests/test_schema.py +55 -0
- package/resources/clj-kondo.exports/io.replikativ/datahike/config.edn +5 -0
- package/resources/example_server.edn +4 -0
- package/shadow-cljs.edn +56 -0
- package/src/data_readers.clj +7 -0
- package/src/datahike/api/impl.cljc +176 -0
- package/src/datahike/api/specification.cljc +633 -0
- package/src/datahike/api/types.cljc +261 -0
- package/src/datahike/api.cljc +41 -0
- package/src/datahike/array.cljc +99 -0
- package/src/datahike/cli.clj +166 -0
- package/src/datahike/cljs.cljs +6 -0
- package/src/datahike/codegen/cli.clj +406 -0
- package/src/datahike/codegen/clj_kondo.clj +291 -0
- package/src/datahike/codegen/java.clj +403 -0
- package/src/datahike/codegen/naming.cljc +33 -0
- package/src/datahike/codegen/native.clj +559 -0
- package/src/datahike/codegen/pod.clj +488 -0
- package/src/datahike/codegen/python.clj +838 -0
- package/src/datahike/codegen/report.clj +55 -0
- package/src/datahike/codegen/typescript.clj +262 -0
- package/src/datahike/codegen/validation.clj +145 -0
- package/src/datahike/config.cljc +294 -0
- package/src/datahike/connections.cljc +16 -0
- package/src/datahike/connector.cljc +265 -0
- package/src/datahike/constants.cljc +142 -0
- package/src/datahike/core.cljc +297 -0
- package/src/datahike/datom.cljc +459 -0
- package/src/datahike/db/interface.cljc +119 -0
- package/src/datahike/db/search.cljc +305 -0
- package/src/datahike/db/transaction.cljc +937 -0
- package/src/datahike/db/utils.cljc +338 -0
- package/src/datahike/db.cljc +956 -0
- package/src/datahike/experimental/unstructured.cljc +126 -0
- package/src/datahike/experimental/versioning.cljc +172 -0
- package/src/datahike/externs.js +31 -0
- package/src/datahike/gc.cljc +69 -0
- package/src/datahike/http/client.clj +188 -0
- package/src/datahike/http/writer.clj +79 -0
- package/src/datahike/impl/entity.cljc +218 -0
- package/src/datahike/index/interface.cljc +93 -0
- package/src/datahike/index/persistent_set.cljc +469 -0
- package/src/datahike/index/utils.cljc +44 -0
- package/src/datahike/index.cljc +32 -0
- package/src/datahike/js/api.cljs +172 -0
- package/src/datahike/js/api_macros.clj +22 -0
- package/src/datahike/js.cljs +163 -0
- package/src/datahike/json.cljc +209 -0
- package/src/datahike/lru.cljc +146 -0
- package/src/datahike/migrate.clj +39 -0
- package/src/datahike/norm/norm.clj +245 -0
- package/src/datahike/online_gc.cljc +252 -0
- package/src/datahike/pod.clj +155 -0
- package/src/datahike/pull_api.cljc +325 -0
- package/src/datahike/query.cljc +1945 -0
- package/src/datahike/query_stats.cljc +88 -0
- package/src/datahike/readers.cljc +62 -0
- package/src/datahike/remote.cljc +218 -0
- package/src/datahike/schema.cljc +228 -0
- package/src/datahike/schema_cache.cljc +42 -0
- package/src/datahike/spec.cljc +101 -0
- package/src/datahike/store.cljc +80 -0
- package/src/datahike/tools.cljc +308 -0
- package/src/datahike/transit.cljc +80 -0
- package/src/datahike/writer.cljc +239 -0
- package/src/datahike/writing.cljc +362 -0
- package/src/deps.cljs +1 -0
- package/src-hitchhiker-tree/datahike/index/hitchhiker_tree/insert.cljc +76 -0
- package/src-hitchhiker-tree/datahike/index/hitchhiker_tree/upsert.cljc +128 -0
- package/src-hitchhiker-tree/datahike/index/hitchhiker_tree.cljc +213 -0
- package/test/datahike/backward_compatibility_test/src/backward_test.clj +37 -0
- package/test/datahike/integration_test/config_record_file_test.clj +14 -0
- package/test/datahike/integration_test/config_record_test.clj +14 -0
- package/test/datahike/integration_test/depr_config_uri_test.clj +15 -0
- package/test/datahike/integration_test/return_map_test.clj +62 -0
- package/test/datahike/integration_test.cljc +67 -0
- package/test/datahike/norm/norm_test.clj +124 -0
- package/test/datahike/norm/resources/naming-and-sorting-test/001-a1-example.edn +5 -0
- package/test/datahike/norm/resources/naming-and-sorting-test/002-a2-example.edn +5 -0
- package/test/datahike/norm/resources/naming-and-sorting-test/003-tx-fn-test.edn +1 -0
- package/test/datahike/norm/resources/naming-and-sorting-test/004-tx-data-and-tx-fn-test.edn +5 -0
- package/test/datahike/norm/resources/naming-and-sorting-test/01-transact-basic-characters.edn +2 -0
- package/test/datahike/norm/resources/naming-and-sorting-test/02 add occupation.edn +5 -0
- package/test/datahike/norm/resources/naming-and-sorting-test/checksums.edn +12 -0
- package/test/datahike/norm/resources/simple-test/001-a1-example.edn +5 -0
- package/test/datahike/norm/resources/simple-test/002-a2-example.edn +5 -0
- package/test/datahike/norm/resources/simple-test/checksums.edn +4 -0
- package/test/datahike/norm/resources/tx-data-and-tx-fn-test/first/001-a1-example.edn +5 -0
- package/test/datahike/norm/resources/tx-data-and-tx-fn-test/first/002-a2-example.edn +5 -0
- package/test/datahike/norm/resources/tx-data-and-tx-fn-test/first/003-tx-fn-test.edn +1 -0
- package/test/datahike/norm/resources/tx-data-and-tx-fn-test/first/checksums.edn +6 -0
- package/test/datahike/norm/resources/tx-data-and-tx-fn-test/second/004-tx-data-and-tx-fn-test.edn +5 -0
- package/test/datahike/norm/resources/tx-data-and-tx-fn-test/second/checksums.edn +2 -0
- package/test/datahike/norm/resources/tx-fn-test/first/001-a1-example.edn +5 -0
- package/test/datahike/norm/resources/tx-fn-test/first/002-a2-example.edn +5 -0
- package/test/datahike/norm/resources/tx-fn-test/first/checksums.edn +4 -0
- package/test/datahike/norm/resources/tx-fn-test/second/003-tx-fn-test.edn +1 -0
- package/test/datahike/norm/resources/tx-fn-test/second/checksums.edn +2 -0
- package/test/datahike/test/api_test.cljc +895 -0
- package/test/datahike/test/array_test.cljc +40 -0
- package/test/datahike/test/attribute_refs/datoms_test.cljc +140 -0
- package/test/datahike/test/attribute_refs/db_test.cljc +42 -0
- package/test/datahike/test/attribute_refs/differences_test.cljc +515 -0
- package/test/datahike/test/attribute_refs/entity_test.cljc +89 -0
- package/test/datahike/test/attribute_refs/pull_api_test.cljc +320 -0
- package/test/datahike/test/attribute_refs/query_find_specs_test.cljc +59 -0
- package/test/datahike/test/attribute_refs/query_fns_test.cljc +130 -0
- package/test/datahike/test/attribute_refs/query_interop_test.cljc +47 -0
- package/test/datahike/test/attribute_refs/query_not_test.cljc +193 -0
- package/test/datahike/test/attribute_refs/query_or_test.cljc +137 -0
- package/test/datahike/test/attribute_refs/query_pull_test.cljc +156 -0
- package/test/datahike/test/attribute_refs/query_rules_test.cljc +176 -0
- package/test/datahike/test/attribute_refs/query_test.cljc +241 -0
- package/test/datahike/test/attribute_refs/temporal_search.cljc +22 -0
- package/test/datahike/test/attribute_refs/transact_test.cljc +220 -0
- package/test/datahike/test/attribute_refs/utils.cljc +128 -0
- package/test/datahike/test/cache_test.cljc +38 -0
- package/test/datahike/test/components_test.cljc +92 -0
- package/test/datahike/test/config_test.cljc +158 -0
- package/test/datahike/test/core_test.cljc +105 -0
- package/test/datahike/test/datom_test.cljc +44 -0
- package/test/datahike/test/db_test.cljc +54 -0
- package/test/datahike/test/entity_spec_test.cljc +159 -0
- package/test/datahike/test/entity_test.cljc +103 -0
- package/test/datahike/test/explode_test.cljc +143 -0
- package/test/datahike/test/filter_test.cljc +75 -0
- package/test/datahike/test/gc_test.cljc +159 -0
- package/test/datahike/test/http/server_test.clj +192 -0
- package/test/datahike/test/http/writer_test.clj +86 -0
- package/test/datahike/test/ident_test.cljc +32 -0
- package/test/datahike/test/index_test.cljc +345 -0
- package/test/datahike/test/insert.cljc +125 -0
- package/test/datahike/test/java_bindings_test.clj +6 -0
- package/test/datahike/test/listen_test.cljc +41 -0
- package/test/datahike/test/lookup_refs_test.cljc +266 -0
- package/test/datahike/test/lru_test.cljc +27 -0
- package/test/datahike/test/migrate_test.clj +297 -0
- package/test/datahike/test/model/core.cljc +376 -0
- package/test/datahike/test/model/invariant.cljc +142 -0
- package/test/datahike/test/model/rng.cljc +82 -0
- package/test/datahike/test/model_test.clj +217 -0
- package/test/datahike/test/nodejs_test.cljs +262 -0
- package/test/datahike/test/online_gc_test.cljc +475 -0
- package/test/datahike/test/pod_test.clj +369 -0
- package/test/datahike/test/pull_api_test.cljc +474 -0
- package/test/datahike/test/purge_test.cljc +144 -0
- package/test/datahike/test/query_aggregates_test.cljc +101 -0
- package/test/datahike/test/query_find_specs_test.cljc +52 -0
- package/test/datahike/test/query_fns_test.cljc +523 -0
- package/test/datahike/test/query_interop_test.cljc +47 -0
- package/test/datahike/test/query_not_test.cljc +189 -0
- package/test/datahike/test/query_or_test.cljc +158 -0
- package/test/datahike/test/query_pull_test.cljc +147 -0
- package/test/datahike/test/query_rules_test.cljc +248 -0
- package/test/datahike/test/query_stats_test.cljc +218 -0
- package/test/datahike/test/query_test.cljc +984 -0
- package/test/datahike/test/schema_test.cljc +424 -0
- package/test/datahike/test/specification_test.cljc +30 -0
- package/test/datahike/test/store_test.cljc +78 -0
- package/test/datahike/test/stress_test.cljc +57 -0
- package/test/datahike/test/time_variance_test.cljc +518 -0
- package/test/datahike/test/tools_test.clj +134 -0
- package/test/datahike/test/transact_test.cljc +518 -0
- package/test/datahike/test/tuples_test.cljc +564 -0
- package/test/datahike/test/unstructured_test.cljc +291 -0
- package/test/datahike/test/upsert_impl_test.cljc +205 -0
- package/test/datahike/test/upsert_test.cljc +363 -0
- package/test/datahike/test/utils.cljc +110 -0
- package/test/datahike/test/validation_test.cljc +48 -0
- package/test/datahike/test/versioning_test.cljc +56 -0
- package/test/datahike/test.cljc +66 -0
- package/tests.edn +24 -0
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
(ns datahike.test.upsert-test
|
|
2
|
+
(:require
|
|
3
|
+
#?(:cljs [cljs.test :as t :refer-macros [is are deftest testing]]
|
|
4
|
+
:clj [clojure.test :as t :refer [is are deftest testing]])
|
|
5
|
+
[datahike.api :as d]
|
|
6
|
+
[datahike.db :as db]
|
|
7
|
+
[datahike.impl.entity :as de]
|
|
8
|
+
[datahike.constants :as const]
|
|
9
|
+
[datahike.test.core-test :as tdc])
|
|
10
|
+
(:import [java.util UUID]))
|
|
11
|
+
|
|
12
|
+
#?(:cljs
|
|
13
|
+
(def Throwable js/Error))
|
|
14
|
+
|
|
15
|
+
(deftest test-upsert
|
|
16
|
+
(let [db (d/db-with (db/empty-db {:name {:db/unique :db.unique/identity}
|
|
17
|
+
:email {:db/unique :db.unique/identity}})
|
|
18
|
+
[{:db/id 1 :name "Ivan" :email "@1"}
|
|
19
|
+
{:db/id 2 :name "Petr" :email "@2"}])
|
|
20
|
+
touched (fn [tx e] (into {} (de/touch (d/entity (:db-after tx) e))))
|
|
21
|
+
tempids (fn [tx] (dissoc (:tempids tx) :db/current-tx))]
|
|
22
|
+
(testing "upsert, no tempid"
|
|
23
|
+
(let [tx (d/with db [{:name "Ivan" :age 35}])]
|
|
24
|
+
(is (= (touched tx 1)
|
|
25
|
+
{:name "Ivan" :email "@1" :age 35}))
|
|
26
|
+
(is (= (tempids tx)
|
|
27
|
+
{}))))
|
|
28
|
+
|
|
29
|
+
(testing "upsert by 2 attrs, no tempid"
|
|
30
|
+
(let [tx (d/with db [{:name "Ivan" :email "@1" :age 35}])]
|
|
31
|
+
(is (= (touched tx 1)
|
|
32
|
+
{:name "Ivan" :email "@1" :age 35}))
|
|
33
|
+
(is (= (tempids tx)
|
|
34
|
+
{}))))
|
|
35
|
+
|
|
36
|
+
(testing "upsert with tempid"
|
|
37
|
+
(let [tx (d/with db [{:db/id -1 :name "Ivan" :age 35}])]
|
|
38
|
+
(is (= (touched tx 1)
|
|
39
|
+
{:name "Ivan" :email "@1" :age 35}))
|
|
40
|
+
(is (= (tempids tx)
|
|
41
|
+
{-1 1}))))
|
|
42
|
+
|
|
43
|
+
(testing "upsert with string tempid"
|
|
44
|
+
(let [tx (d/with db [{:db/id "1" :name "Ivan" :age 35}
|
|
45
|
+
[:db/add "2" :name "Oleg"]
|
|
46
|
+
[:db/add "2" :email "@2"]])]
|
|
47
|
+
(is (= (touched tx 1)
|
|
48
|
+
{:name "Ivan" :email "@1" :age 35}))
|
|
49
|
+
(is (= (touched tx 2)
|
|
50
|
+
{:name "Oleg" :email "@2"}))
|
|
51
|
+
(is (= (tempids tx)
|
|
52
|
+
{"1" 1
|
|
53
|
+
"2" 2}))))
|
|
54
|
+
|
|
55
|
+
(testing "upsert by 2 attrs with tempid"
|
|
56
|
+
(let [tx (d/with db [{:db/id -1 :name "Ivan" :email "@1" :age 35}])]
|
|
57
|
+
(is (= (touched tx 1)
|
|
58
|
+
{:name "Ivan" :email "@1" :age 35}))
|
|
59
|
+
(is (= (tempids tx)
|
|
60
|
+
{-1 1}))))
|
|
61
|
+
|
|
62
|
+
(testing "upsert to two entities, resolve to same tempid"
|
|
63
|
+
(let [tx (d/with db [{:db/id -1 :name "Ivan" :age 35}
|
|
64
|
+
{:db/id -1 :name "Ivan" :age 36}])]
|
|
65
|
+
(is (= (touched tx 1)
|
|
66
|
+
{:name "Ivan" :email "@1" :age 36}))
|
|
67
|
+
(is (= (tempids tx)
|
|
68
|
+
{-1 1}))))
|
|
69
|
+
|
|
70
|
+
(testing "upsert to two entities, two tempids"
|
|
71
|
+
(let [tx (d/with db [{:db/id -1 :name "Ivan" :age 35}
|
|
72
|
+
{:db/id -2 :name "Ivan" :age 36}])]
|
|
73
|
+
(is (= (touched tx 1)
|
|
74
|
+
{:name "Ivan" :email "@1" :age 36}))
|
|
75
|
+
(is (= (tempids tx)
|
|
76
|
+
{-1 1, -2 1}))))
|
|
77
|
+
|
|
78
|
+
(testing "upsert with existing id"
|
|
79
|
+
(let [tx (d/with db [{:db/id 1 :name "Ivan" :age 35}])]
|
|
80
|
+
(is (= (touched tx 1)
|
|
81
|
+
{:name "Ivan" :email "@1" :age 35}))
|
|
82
|
+
(is (= (tempids tx)
|
|
83
|
+
{}))))
|
|
84
|
+
|
|
85
|
+
(testing "upsert by 2 attrs with existing id"
|
|
86
|
+
(let [tx (d/with db [{:db/id 1 :name "Ivan" :email "@1" :age 35}])]
|
|
87
|
+
(is (= (touched tx 1)
|
|
88
|
+
{:name "Ivan" :email "@1" :age 35}))
|
|
89
|
+
(is (= (tempids tx)
|
|
90
|
+
{}))))
|
|
91
|
+
|
|
92
|
+
(testing "upsert conficts with existing id"
|
|
93
|
+
(is (thrown-with-msg? Throwable #"Conflicting upsert: \[:name \"Ivan\"\] resolves to 1, but entity already has :db/id 2"
|
|
94
|
+
(d/with db [{:db/id 2 :name "Ivan" :age 36}]))))
|
|
95
|
+
|
|
96
|
+
(testing "upsert conficts with non-existing id"
|
|
97
|
+
(is (thrown-with-msg? Throwable #"Conflicting upsert: \[:name \"Ivan\"\] resolves to 1, but entity already has :db/id 3"
|
|
98
|
+
(d/with db [{:db/id 3 :name "Ivan" :age 36}]))))
|
|
99
|
+
|
|
100
|
+
(testing "upsert by non-existing value resolves as update"
|
|
101
|
+
(let [tx (d/with db [{:name "Ivan" :email "@3" :age 35}])]
|
|
102
|
+
(is (= (touched tx 1)
|
|
103
|
+
{:name "Ivan" :email "@3" :age 35}))
|
|
104
|
+
(is (= (tempids tx)
|
|
105
|
+
{}))))
|
|
106
|
+
|
|
107
|
+
(testing "upsert by 2 conflicting fields"
|
|
108
|
+
(is (thrown-with-msg? Throwable #"Conflicting upserts: \[:name \"Ivan\"\] resolves to 1, but \[:email \"@2\"\] resolves to 2"
|
|
109
|
+
(d/with db [{:name "Ivan" :email "@2" :age 35}]))))
|
|
110
|
+
|
|
111
|
+
(testing "upsert over intermediate db"
|
|
112
|
+
(let [tx (d/with db [{:name "Igor" :age 35}
|
|
113
|
+
{:name "Igor" :age 36}])]
|
|
114
|
+
(is (= (touched tx 3)
|
|
115
|
+
{:name "Igor" :age 36}))
|
|
116
|
+
(is (= (tempids tx)
|
|
117
|
+
{}))))
|
|
118
|
+
|
|
119
|
+
(testing "upsert over intermediate db, tempids"
|
|
120
|
+
(let [tx (d/with db [{:db/id -1 :name "Igor" :age 35}
|
|
121
|
+
{:db/id -1 :name "Igor" :age 36}])]
|
|
122
|
+
(is (= (touched tx 3)
|
|
123
|
+
{:name "Igor" :age 36}))
|
|
124
|
+
(is (= (tempids tx)
|
|
125
|
+
{-1 3}))))
|
|
126
|
+
|
|
127
|
+
(testing "upsert over intermediate db, different tempids"
|
|
128
|
+
(let [tx (d/with db [{:db/id -1 :name "Igor" :age 35}
|
|
129
|
+
{:db/id -2 :name "Igor" :age 36}])]
|
|
130
|
+
(is (= (touched tx 3)
|
|
131
|
+
{:name "Igor" :age 36}))
|
|
132
|
+
(is (= (tempids tx)
|
|
133
|
+
{-1 3, -2 3}))))
|
|
134
|
+
|
|
135
|
+
(testing "upsert and :current-tx conflict"
|
|
136
|
+
(is (thrown-with-msg? Throwable #"Conflicting upsert: \[:name \"Ivan\"\] resolves to 1, but entity already has :db/id \d+"
|
|
137
|
+
(d/with db [{:db/id :db/current-tx :name "Ivan" :age 35}]))))))
|
|
138
|
+
|
|
139
|
+
(deftest test-redefining-ids
|
|
140
|
+
(let [db (-> (db/empty-db {:name {:db/unique :db.unique/identity}})
|
|
141
|
+
(d/db-with [{:db/id -1 :name "Ivan"}]))
|
|
142
|
+
tx (d/with db [{:db/id -1 :age 35}
|
|
143
|
+
{:db/id -1 :name "Ivan" :age 36}])]
|
|
144
|
+
(is (= #{[1 :age 36] [1 :name "Ivan"]}
|
|
145
|
+
(tdc/all-datoms (:db-after tx))))
|
|
146
|
+
(is (= {-1 1, :db/current-tx (+ const/tx0 2)}
|
|
147
|
+
(:tempids tx))))
|
|
148
|
+
|
|
149
|
+
(let [db (-> (db/empty-db {:name {:db/unique :db.unique/identity}})
|
|
150
|
+
(d/db-with [{:db/id -1 :name "Ivan"}
|
|
151
|
+
{:db/id -2 :name "Oleg"}]))]
|
|
152
|
+
(is (thrown-with-msg? Throwable #"Conflicting upsert: -1 resolves both to 1 and 2"
|
|
153
|
+
(d/with db [{:db/id -1 :name "Ivan" :age 35}
|
|
154
|
+
{:db/id -1 :name "Oleg" :age 36}])))))
|
|
155
|
+
|
|
156
|
+
;; https://github.com/tonsky/datahike/issues/285
|
|
157
|
+
(deftest test-retries-order
|
|
158
|
+
(let [db (-> (db/empty-db {:name {:db/unique :db.unique/identity}})
|
|
159
|
+
(d/db-with [[:db/add -1 :age 42]
|
|
160
|
+
[:db/add -2 :likes "Pizza"]
|
|
161
|
+
[:db/add -1 :name "Bob"]
|
|
162
|
+
[:db/add -2 :name "Bob"]]))]
|
|
163
|
+
(is (= {:db/id 1, :name "Bob", :likes "Pizza", :age 42}
|
|
164
|
+
(tdc/entity-map db 1))))
|
|
165
|
+
|
|
166
|
+
(let [db (-> (db/empty-db {:name {:db/unique :db.unique/identity}})
|
|
167
|
+
(d/db-with [[:db/add -1 :age 42]
|
|
168
|
+
[:db/add -2 :likes "Pizza"]
|
|
169
|
+
[:db/add -2 :name "Bob"]
|
|
170
|
+
[:db/add -1 :name "Bob"]]))]
|
|
171
|
+
(is (= {:db/id 2, :name "Bob", :likes "Pizza", :age 42}
|
|
172
|
+
(tdc/entity-map db 2)))))
|
|
173
|
+
|
|
174
|
+
(deftest test-vector-upsert
|
|
175
|
+
(let [db (-> (db/empty-db {:name {:db/unique :db.unique/identity}})
|
|
176
|
+
(d/db-with [{:db/id -1, :name "Ivan"}]))]
|
|
177
|
+
(are [tx res] (= res (tdc/all-datoms (d/db-with db tx)))
|
|
178
|
+
[[:db/add -1 :name "Ivan"]
|
|
179
|
+
[:db/add -1 :age 12]]
|
|
180
|
+
#{[1 :age 12] [1 :name "Ivan"]}
|
|
181
|
+
|
|
182
|
+
[[:db/add -1 :age 12]
|
|
183
|
+
[:db/add -1 :name "Ivan"]]
|
|
184
|
+
#{[1 :age 12] [1 :name "Ivan"]}))
|
|
185
|
+
|
|
186
|
+
(let [db (-> (db/empty-db {:name {:db/unique :db.unique/identity}})
|
|
187
|
+
(d/db-with [[:db/add -1 :name "Ivan"]
|
|
188
|
+
[:db/add -2 :name "Oleg"]]))]
|
|
189
|
+
(is (thrown-with-msg? Throwable #"Conflicting upsert: -1 resolves both to 1 and 2"
|
|
190
|
+
(d/with db [[:db/add -1 :name "Ivan"]
|
|
191
|
+
[:db/add -1 :age 35]
|
|
192
|
+
[:db/add -1 :name "Oleg"]
|
|
193
|
+
[:db/add -1 :age 36]])))))
|
|
194
|
+
|
|
195
|
+
(defn temporal-history-test [cfg]
|
|
196
|
+
(let [schema [{:db/ident :name
|
|
197
|
+
:db/cardinality :db.cardinality/one
|
|
198
|
+
:db/index true
|
|
199
|
+
:db/unique :db.unique/identity
|
|
200
|
+
:db/valueType :db.type/string}
|
|
201
|
+
{:db/ident :age
|
|
202
|
+
:db/cardinality :db.cardinality/one
|
|
203
|
+
:db/valueType :db.type/long}]
|
|
204
|
+
_ (d/delete-database cfg)
|
|
205
|
+
_ (d/create-database cfg)
|
|
206
|
+
conn (d/connect cfg)]
|
|
207
|
+
(testing "inserting a new datom creates an entry in history"
|
|
208
|
+
(d/transact conn {:tx-data schema})
|
|
209
|
+
(d/transact conn {:tx-data [{:name "Alice"
|
|
210
|
+
:age 25}]})
|
|
211
|
+
(is (= 1 (count (d/datoms (d/history @conn) :eavt [:name "Alice"] :age)))))
|
|
212
|
+
(testing "inserting the exact same datom"
|
|
213
|
+
(d/transact conn {:tx-data [{:db/id [:name "Alice"]
|
|
214
|
+
:age 25}]})
|
|
215
|
+
(testing " does not change history"
|
|
216
|
+
(is (= 1 (count (d/datoms (d/history @conn) :eavt [:name "Alice"] :age))))))
|
|
217
|
+
(testing "changing the datom value increases the history with 2 datoms: the retraction datom and the new value."
|
|
218
|
+
(d/transact conn {:tx-data [{:db/id [:name "Alice"]
|
|
219
|
+
:age 26}]})
|
|
220
|
+
(is (= 3 (count (d/datoms (d/history @conn) :eavt [:name "Alice"] :age)))))
|
|
221
|
+
(d/release conn)))
|
|
222
|
+
|
|
223
|
+
(deftest temporal-history-mem
|
|
224
|
+
(let [config {:store {:backend :memory :id #uuid "80000000-0000-0000-0000-000000000008"}
|
|
225
|
+
:schema-flexibility :write
|
|
226
|
+
:keep-history? true}]
|
|
227
|
+
(temporal-history-test config)))
|
|
228
|
+
|
|
229
|
+
(deftest temporal-history-file
|
|
230
|
+
(let [config {:store {:backend :file :path "/tmp/temp-hist-hht" :id #uuid "ab5e0000-0000-0000-0000-000000000001"}
|
|
231
|
+
:schema-flexibility :write
|
|
232
|
+
:keep-history? true}]
|
|
233
|
+
(temporal-history-test config)))
|
|
234
|
+
|
|
235
|
+
(deftest temporal-history-file-with-attr-refs
|
|
236
|
+
(let [config {:store {:backend :file :path "/tmp/temp-hist-attr-refs" :id #uuid "ab5e0000-0000-0000-0000-000000000002"}
|
|
237
|
+
:schema-flexibility :write
|
|
238
|
+
:keep-history? true
|
|
239
|
+
:attribute-refs? true}]
|
|
240
|
+
(temporal-history-test config)))
|
|
241
|
+
|
|
242
|
+
(deftest test-upsert-after-large-coll
|
|
243
|
+
(let [ascii-ish (map char (concat (range 48 58) (range 65 91) (range 97 123)))
|
|
244
|
+
file-cfg {:store {:backend :file
|
|
245
|
+
:path "/tmp/upsert-large-test"
|
|
246
|
+
:id #uuid "ab5e0000-0000-0000-0000-000000000003"}}
|
|
247
|
+
file-pss-cfg {:store {:backend :file
|
|
248
|
+
:index :datahike.index/persistent-set
|
|
249
|
+
:path "/tmp/upsert-large-pss-test"
|
|
250
|
+
:id #uuid "ab5e0000-0000-0000-0000-000000000004"}}
|
|
251
|
+
mem-cfg {:store {:backend :memory
|
|
252
|
+
:id #uuid "90000000-0000-0000-0000-000000000009"}}
|
|
253
|
+
_ (if (d/database-exists? file-cfg)
|
|
254
|
+
(do
|
|
255
|
+
(d/delete-database file-cfg)
|
|
256
|
+
(d/create-database file-cfg))
|
|
257
|
+
(d/create-database file-cfg))
|
|
258
|
+
_ (if (d/database-exists? file-pss-cfg)
|
|
259
|
+
(do
|
|
260
|
+
(d/delete-database file-pss-cfg)
|
|
261
|
+
(d/create-database file-pss-cfg))
|
|
262
|
+
(d/create-database file-pss-cfg))
|
|
263
|
+
_ (if (d/database-exists? mem-cfg)
|
|
264
|
+
(do
|
|
265
|
+
(d/delete-database mem-cfg)
|
|
266
|
+
(d/create-database mem-cfg))
|
|
267
|
+
(d/create-database mem-cfg))
|
|
268
|
+
file-conn (d/connect file-cfg)
|
|
269
|
+
file-pss-conn (d/connect file-pss-cfg)
|
|
270
|
+
mem-conn (d/connect mem-cfg)
|
|
271
|
+
initial-active-count 8
|
|
272
|
+
inactive-count 5
|
|
273
|
+
space-taker-count 1000]
|
|
274
|
+
(letfn [(ident-eid [db ident]
|
|
275
|
+
(d/q '[:find ?e .
|
|
276
|
+
:in $ ?ident
|
|
277
|
+
:where [?e :db/ident ?ident]]
|
|
278
|
+
db ident))
|
|
279
|
+
(random-uuid []
|
|
280
|
+
(UUID/randomUUID))
|
|
281
|
+
(random-char []
|
|
282
|
+
(rand-nth ascii-ish))
|
|
283
|
+
(random-string [length]
|
|
284
|
+
(apply str (repeatedly length random-char)))
|
|
285
|
+
(ent-ids [db]
|
|
286
|
+
(d/q '[:find [?e ...]
|
|
287
|
+
:where
|
|
288
|
+
[?e :ent/id]]
|
|
289
|
+
db))
|
|
290
|
+
(active-count [db]
|
|
291
|
+
(d/q '[:find (count ?e) .
|
|
292
|
+
:where
|
|
293
|
+
[?e :ent/active? true]]
|
|
294
|
+
db))
|
|
295
|
+
(init-data [conn]
|
|
296
|
+
(d/transact conn {:tx-data [{:db/ident :ent/id
|
|
297
|
+
:db/valueType :db.type/uuid
|
|
298
|
+
:db/cardinality :db.cardinality/one
|
|
299
|
+
:db/unique :db.unique/identity
|
|
300
|
+
:db/doc "The entity ID."}
|
|
301
|
+
{:db/ident :ent/active?
|
|
302
|
+
:db/valueType :db.type/boolean
|
|
303
|
+
:db/cardinality :db.cardinality/one
|
|
304
|
+
:db/doc "Whether the entity is active."}
|
|
305
|
+
{:db/ident :meta/space-taker
|
|
306
|
+
:db/valueType :db.type/string
|
|
307
|
+
:db/cardinality :db.cardinality/one
|
|
308
|
+
:db/doc "Takes up some space in the db"}]})
|
|
309
|
+
|
|
310
|
+
(d/transact conn {:tx-data (map (fn [_]
|
|
311
|
+
{:ent/id (random-uuid)})
|
|
312
|
+
(range initial-active-count))})
|
|
313
|
+
|
|
314
|
+
(d/transact conn {:tx-data (map (fn [_]
|
|
315
|
+
{:meta/space-taker (random-string 250)})
|
|
316
|
+
(range space-taker-count))})
|
|
317
|
+
|
|
318
|
+
(d/transact conn {:tx-data (map (fn [eid]
|
|
319
|
+
{:db/id eid
|
|
320
|
+
:ent/active? true})
|
|
321
|
+
(ent-ids @conn))})
|
|
322
|
+
|
|
323
|
+
(d/transact conn {:tx-data (->> (ent-ids @conn)
|
|
324
|
+
sort
|
|
325
|
+
(take inactive-count)
|
|
326
|
+
(map (fn [eid]
|
|
327
|
+
[:db/add eid :ent/active? false])))}))]
|
|
328
|
+
(testing "File upsert"
|
|
329
|
+
(init-data file-conn)
|
|
330
|
+
(let [cached-db @file-conn
|
|
331
|
+
fresh-conn (d/connect file-cfg)
|
|
332
|
+
fresh-db @fresh-conn
|
|
333
|
+
actual-count (- initial-active-count inactive-count)
|
|
334
|
+
cached-count (active-count cached-db)
|
|
335
|
+
fresh-count (active-count fresh-db)]
|
|
336
|
+
(is (= actual-count cached-count))
|
|
337
|
+
(is (= cached-count fresh-count))
|
|
338
|
+
(d/release fresh-conn)))
|
|
339
|
+
(testing "File pss upsert"
|
|
340
|
+
(init-data file-pss-conn)
|
|
341
|
+
(let [cached-db @file-pss-conn
|
|
342
|
+
fresh-conn (d/connect file-pss-cfg)
|
|
343
|
+
fresh-db @fresh-conn
|
|
344
|
+
actual-count (- initial-active-count inactive-count)
|
|
345
|
+
cached-count (active-count cached-db)
|
|
346
|
+
fresh-count (active-count fresh-db)]
|
|
347
|
+
(is (= actual-count cached-count))
|
|
348
|
+
(is (= cached-count fresh-count))
|
|
349
|
+
(d/release fresh-conn)))
|
|
350
|
+
(testing "Mem upsert"
|
|
351
|
+
(init-data mem-conn)
|
|
352
|
+
(let [cached-db @mem-conn
|
|
353
|
+
fresh-conn (d/connect mem-cfg)
|
|
354
|
+
fresh-db @fresh-conn
|
|
355
|
+
actual-count (- initial-active-count inactive-count)
|
|
356
|
+
cached-count (active-count cached-db)
|
|
357
|
+
fresh-count (active-count fresh-db)]
|
|
358
|
+
(is (= actual-count cached-count))
|
|
359
|
+
(is (= cached-count fresh-count))
|
|
360
|
+
(d/release fresh-conn))))
|
|
361
|
+
(d/release file-conn)
|
|
362
|
+
(d/release file-pss-conn)
|
|
363
|
+
(d/release mem-conn)))
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
(ns datahike.test.utils
|
|
2
|
+
(:require ;; Load hitchhiker-tree FIRST before datahike.api which loads datahike.index
|
|
3
|
+
#?(:clj [datahike.index.hitchhiker-tree])
|
|
4
|
+
[datahike.api :as d]
|
|
5
|
+
[datahike.tools :as tools])
|
|
6
|
+
#?(:clj (:import [java.util UUID Date])))
|
|
7
|
+
|
|
8
|
+
(defn get-all-datoms
|
|
9
|
+
"Based on Wanderung function `wanderung.datahike/extract-datahike-data`."
|
|
10
|
+
([db] (get-all-datoms db identity))
|
|
11
|
+
([db final-xform]
|
|
12
|
+
(let [txs (->> db
|
|
13
|
+
(d/q '[:find ?tx ?inst
|
|
14
|
+
:in $
|
|
15
|
+
:where
|
|
16
|
+
[?tx :db/txInstant ?inst]
|
|
17
|
+
[(< #inst "1970-01-02" ?inst)]])
|
|
18
|
+
(sort-by first))
|
|
19
|
+
query {:query '[:find ?e ?a ?v ?t ?added
|
|
20
|
+
:in $ ?t
|
|
21
|
+
:where
|
|
22
|
+
[?e ?a ?v ?t ?added]
|
|
23
|
+
(not [?e :db/txInstant ?v ?t ?added])]
|
|
24
|
+
:args [(d/history db)]}]
|
|
25
|
+
(into []
|
|
26
|
+
(comp (mapcat
|
|
27
|
+
(fn [[tid tinst]]
|
|
28
|
+
(->> (d/q (update-in query [:args] conj tid))
|
|
29
|
+
(sort-by first)
|
|
30
|
+
(into [[tid :db/txInstant tinst tid true]]))))
|
|
31
|
+
final-xform)
|
|
32
|
+
txs))))
|
|
33
|
+
|
|
34
|
+
(defn unmap-tx-timestamp [[e a _ tx added :as datom]]
|
|
35
|
+
(if (= a :db/txInstant)
|
|
36
|
+
[e a :timestamp tx added]
|
|
37
|
+
datom))
|
|
38
|
+
|
|
39
|
+
(defn cfg-template
|
|
40
|
+
"Returning a config template with a random store-id"
|
|
41
|
+
[]
|
|
42
|
+
{:store {:backend :memory
|
|
43
|
+
:id #?(:clj (java.util.UUID/randomUUID) :cljs (random-uuid))}
|
|
44
|
+
:keep-history? true
|
|
45
|
+
:schema-flexibility :read})
|
|
46
|
+
|
|
47
|
+
(defn recreate-database [cfg]
|
|
48
|
+
(d/delete-database cfg)
|
|
49
|
+
(d/create-database cfg)
|
|
50
|
+
cfg)
|
|
51
|
+
|
|
52
|
+
(defn with-connect-fn [cfg body-fn]
|
|
53
|
+
(let [conn (d/connect cfg)]
|
|
54
|
+
(try
|
|
55
|
+
(body-fn conn)
|
|
56
|
+
(finally
|
|
57
|
+
(d/release conn)))))
|
|
58
|
+
|
|
59
|
+
(defmacro with-connect [[conn cfg] & body]
|
|
60
|
+
`(with-connect-fn ~cfg (fn [~conn] ~@body)))
|
|
61
|
+
|
|
62
|
+
(defn provide-unique-id [cfg]
|
|
63
|
+
(assoc-in cfg [:store :id] #?(:clj (UUID/randomUUID)
|
|
64
|
+
:cljs (random-uuid))))
|
|
65
|
+
|
|
66
|
+
(defn setup-db
|
|
67
|
+
"Setting up a test-db in memory by default. Deep-merges the passed config into the defaults."
|
|
68
|
+
([]
|
|
69
|
+
(setup-db {}))
|
|
70
|
+
([cfg]
|
|
71
|
+
(setup-db cfg (not (get-in cfg [:store :id]))))
|
|
72
|
+
([cfg gen-uuid?]
|
|
73
|
+
(let [cfg (cond-> (tools/deep-merge (cfg-template) cfg)
|
|
74
|
+
gen-uuid? (provide-unique-id))]
|
|
75
|
+
(recreate-database cfg)
|
|
76
|
+
(d/connect cfg))))
|
|
77
|
+
|
|
78
|
+
(defn all-true? [c] (every? true? c))
|
|
79
|
+
|
|
80
|
+
(defn all-eq? [c1 c2] (all-true? (map = c1 c2)))
|
|
81
|
+
|
|
82
|
+
(defn setup-default-db [config test-data]
|
|
83
|
+
(recreate-database config)
|
|
84
|
+
(let [conn (d/connect config)]
|
|
85
|
+
(d/transact conn test-data)
|
|
86
|
+
conn))
|
|
87
|
+
|
|
88
|
+
(defn teardown-db [conn]
|
|
89
|
+
(d/release conn)
|
|
90
|
+
(d/delete-database (:config @conn)))
|
|
91
|
+
|
|
92
|
+
(defn with-db
|
|
93
|
+
"Test database fixture"
|
|
94
|
+
([config f]
|
|
95
|
+
(with-db config [] f))
|
|
96
|
+
([config test-data f]
|
|
97
|
+
(let [conn (setup-default-db config test-data)]
|
|
98
|
+
(f)
|
|
99
|
+
(teardown-db conn))))
|
|
100
|
+
|
|
101
|
+
(defn sleep [ms]
|
|
102
|
+
#?(:clj (Thread/sleep ms)
|
|
103
|
+
:cljs (js/setTimeout (fn []) ms)))
|
|
104
|
+
|
|
105
|
+
(defn get-time []
|
|
106
|
+
#?(:clj (.getTime (Date.))
|
|
107
|
+
:cljs (.getTime (js/Date.))))
|
|
108
|
+
|
|
109
|
+
(defn conn-id []
|
|
110
|
+
(str (get-time)))
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
(ns datahike.test.validation-test
|
|
2
|
+
(:require
|
|
3
|
+
#?(:cljs [cljs.test :as t :refer-macros [is are deftest]]
|
|
4
|
+
:clj [clojure.test :as t :refer [is are deftest]])
|
|
5
|
+
[datahike.api :as d]
|
|
6
|
+
[datahike.db :as db]
|
|
7
|
+
[datahike.test.core-test]))
|
|
8
|
+
|
|
9
|
+
#?(:cljs
|
|
10
|
+
(def Throwable js/Error))
|
|
11
|
+
|
|
12
|
+
(deftest test-with-validation
|
|
13
|
+
(let [db (db/empty-db {:profile {:db/valueType :db.type/ref}})]
|
|
14
|
+
(are [tx] (thrown-with-msg? Throwable #"Expected number, string, keyword or lookup ref for :db/id" (d/db-with db tx))
|
|
15
|
+
[{:db/id #"" :name "Ivan"}])
|
|
16
|
+
|
|
17
|
+
(are [tx] (thrown-with-msg? Throwable #"Bad entity attribute" (d/db-with db tx))
|
|
18
|
+
[[:db/add -1 nil "Ivan"]]
|
|
19
|
+
[[:db/add -1 17 "Ivan"]]
|
|
20
|
+
[{:db/id -1 17 "Ivan"}])
|
|
21
|
+
|
|
22
|
+
(are [tx] (thrown-with-msg? Throwable #"Cannot store nil as a value" (d/db-with db tx))
|
|
23
|
+
[[:db/add -1 :name nil]]
|
|
24
|
+
[{:db/id -1 :name nil}])
|
|
25
|
+
|
|
26
|
+
(are [tx] (thrown-with-msg? Throwable #"Expected number or lookup ref for entity id" (d/db-with db tx))
|
|
27
|
+
[[:db/add nil :name "Ivan"]]
|
|
28
|
+
[[:db/add {} :name "Ivan"]]
|
|
29
|
+
[[:db/add -1 :profile #"regexp"]]
|
|
30
|
+
[{:db/id -1 :profile #"regexp"}])
|
|
31
|
+
|
|
32
|
+
(is (thrown-with-msg? Throwable #"Unknown operation" (d/db-with db [["aaa" :name "Ivan"]])))
|
|
33
|
+
(is (thrown-with-msg? Throwable #"Tempids are allowed in :db/add only" (d/db-with db [[:db/retract -1 :name "Ivan"]])))
|
|
34
|
+
(is (thrown-with-msg? Throwable #"Bad transaction data" (d/db-with db {:profile "aaa"})))))
|
|
35
|
+
|
|
36
|
+
(deftest ^:no-spec test-with-validation-caught-by-spec
|
|
37
|
+
(let [db (db/empty-db {:profile {:db/valueType :db.type/ref}})]
|
|
38
|
+
(is (thrown-with-msg? Throwable #"Bad entity type at" (d/db-with db [:db/add "aaa" :name "Ivan"])))))
|
|
39
|
+
|
|
40
|
+
(deftest test-unique
|
|
41
|
+
(let [db (d/db-with (db/empty-db {:name {:db/unique :db.unique/value}})
|
|
42
|
+
[[:db/add 1 :name "Ivan"]
|
|
43
|
+
[:db/add 2 :name "Petr"]])]
|
|
44
|
+
(are [tx] (thrown-with-msg? Throwable #"unique constraint" (d/db-with db tx))
|
|
45
|
+
[[:db/add 3 :name "Ivan"]]
|
|
46
|
+
[{:db/add 3 :name "Petr"}])
|
|
47
|
+
(d/db-with db [[:db/add 3 :name "Igor"]])
|
|
48
|
+
(d/db-with db [[:db/add 3 :nick "Ivan"]])))
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
(ns datahike.test.versioning-test
|
|
2
|
+
(:require #?(:cljs [cljs.test :as t :refer-macros [is deftest testing]]
|
|
3
|
+
:clj [clojure.test :as t :refer [is deftest testing]])
|
|
4
|
+
[datahike.experimental.versioning :refer
|
|
5
|
+
[branch-history branch! delete-branch! merge! force-branch! branch-as-db parent-commit-ids
|
|
6
|
+
commit-id commit-as-db]]
|
|
7
|
+
[datahike.db.utils :refer [db?]]
|
|
8
|
+
[datahike.api :as d]
|
|
9
|
+
[konserve.core :as k]
|
|
10
|
+
[superv.async :refer [<?? S]]))
|
|
11
|
+
|
|
12
|
+
(deftest datahike-versioning-test
|
|
13
|
+
(testing "Testing versioning functionality."
|
|
14
|
+
(let [cfg {:store {:backend :file
|
|
15
|
+
:path "/tmp/dh-versioning-test"
|
|
16
|
+
:id #uuid "1e510000-0000-0000-0000-00000000001e"}
|
|
17
|
+
:keep-history? true
|
|
18
|
+
:schema-flexibility :write
|
|
19
|
+
:index :datahike.index/persistent-set}
|
|
20
|
+
conn (do
|
|
21
|
+
(d/delete-database cfg)
|
|
22
|
+
(d/create-database cfg)
|
|
23
|
+
(d/connect cfg))
|
|
24
|
+
schema [{:db/ident :age
|
|
25
|
+
:db/cardinality :db.cardinality/one
|
|
26
|
+
:db/valueType :db.type/long}]
|
|
27
|
+
_ (d/transact conn schema)
|
|
28
|
+
store (:store @conn)]
|
|
29
|
+
(testing "Test branching."
|
|
30
|
+
(branch! conn :db :foo)
|
|
31
|
+
(is (= (k/get store :branches nil {:sync? true})
|
|
32
|
+
#{:db :foo})))
|
|
33
|
+
(testing "Test merging."
|
|
34
|
+
(let [foo-conn (d/connect (assoc cfg :branch :foo))]
|
|
35
|
+
(d/transact foo-conn [{:age 42}])
|
|
36
|
+
;; extracted data from foo and decide to merge it into :db
|
|
37
|
+
(merge! conn #{:foo} [{:age 42}])
|
|
38
|
+
(d/release foo-conn))
|
|
39
|
+
(is (= 4 (count (<?? S (branch-history conn)))))
|
|
40
|
+
(is (= 2 (count (parent-commit-ids @conn)))))
|
|
41
|
+
(testing "Force branch."
|
|
42
|
+
(force-branch! @conn :foo2 #{:foo})
|
|
43
|
+
(is (db? (branch-as-db store :foo2))))
|
|
44
|
+
(testing "Load different references on current db."
|
|
45
|
+
(is (= (commit-as-db store (commit-id @conn))
|
|
46
|
+
(branch-as-db store :db)
|
|
47
|
+
@conn)))
|
|
48
|
+
(testing "Check branch history."
|
|
49
|
+
(let [conn-foo2 (d/connect (assoc cfg :branch :foo2))]
|
|
50
|
+
(is (= 4 (count (<?? S (branch-history conn-foo2)))))
|
|
51
|
+
(d/release conn-foo2)))
|
|
52
|
+
(testing "Delete branch."
|
|
53
|
+
(delete-branch! conn :foo)
|
|
54
|
+
(is (= (k/get store :branches nil {:sync? true})
|
|
55
|
+
#{:db :foo2})))
|
|
56
|
+
(d/release conn))))
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
(ns datahike.test
|
|
2
|
+
(:require
|
|
3
|
+
#?(:cljs [cljs.test :as t :refer-macros [is are deftest testing]]
|
|
4
|
+
:clj [clojure.test :as t :refer [is are deftest testing]])
|
|
5
|
+
#?(:clj [clojure.java.shell :as sh])
|
|
6
|
+
datahike.test.core-test
|
|
7
|
+
datahike.test.cache-test
|
|
8
|
+
datahike.test.components-test
|
|
9
|
+
datahike.test.config-test
|
|
10
|
+
datahike.test.db-test
|
|
11
|
+
datahike.test.entity-test
|
|
12
|
+
datahike.test.explode-test
|
|
13
|
+
datahike.test.filter-test
|
|
14
|
+
datahike.test.ident-test
|
|
15
|
+
datahike.test.index-test
|
|
16
|
+
datahike.test.listen-test
|
|
17
|
+
datahike.test.lookup-refs-test
|
|
18
|
+
datahike.test.lru-test
|
|
19
|
+
datahike.test.migrate-test
|
|
20
|
+
datahike.test.pull-api-test
|
|
21
|
+
datahike.test.purge-test
|
|
22
|
+
datahike.test.query-test
|
|
23
|
+
datahike.test.query-aggregates-test
|
|
24
|
+
datahike.test.query-find-specs-test
|
|
25
|
+
datahike.test.query-fns-test
|
|
26
|
+
datahike.test.query-interop-test
|
|
27
|
+
datahike.test.query-not-test
|
|
28
|
+
datahike.test.query-or-test
|
|
29
|
+
datahike.test.query-pull-test
|
|
30
|
+
datahike.test.query-rules-test
|
|
31
|
+
datahike.test.schema-test
|
|
32
|
+
datahike.test.store-test
|
|
33
|
+
datahike.test.time-variance-test
|
|
34
|
+
datahike.test.transact-test
|
|
35
|
+
datahike.test.tuples-test
|
|
36
|
+
datahike.test.upsert-test
|
|
37
|
+
datahike.test.upsert-impl-test
|
|
38
|
+
datahike.test.validation-test
|
|
39
|
+
datahike.test.attribute-refs.differences-test
|
|
40
|
+
datahike.test.attribute-refs.entity-test
|
|
41
|
+
datahike.test.attribute-refs.pull-api-test
|
|
42
|
+
datahike.test.attribute-refs.query-test
|
|
43
|
+
datahike.test.attribute-refs.transact-test
|
|
44
|
+
datahike.test.attribute-refs.utils
|
|
45
|
+
datahike.test.middleware.query-test
|
|
46
|
+
datahike.test.middleware.utils-test))
|
|
47
|
+
|
|
48
|
+
(defn ^:export test-clj []
|
|
49
|
+
(datahike.test.core/wrap-res #(t/run-all-tests #"datahike\..*")))
|
|
50
|
+
|
|
51
|
+
(defn ^:export test-cljs []
|
|
52
|
+
(datahike.test.core/wrap-res #(t/run-all-tests #"datahike\..*")))
|
|
53
|
+
|
|
54
|
+
#?(:clj
|
|
55
|
+
(defn test-node [& args]
|
|
56
|
+
(let [res (apply sh/sh "node" "test_node.js" args)]
|
|
57
|
+
(println (:out res))
|
|
58
|
+
(binding [*out* *err*]
|
|
59
|
+
(println (:err res)))
|
|
60
|
+
(System/exit (:exit res)))))
|
|
61
|
+
|
|
62
|
+
(comment
|
|
63
|
+
|
|
64
|
+
(test-clj))
|
|
65
|
+
|
|
66
|
+
|
package/tests.edn
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#kaocha/v1
|
|
2
|
+
#meta-merge [{:tests [{:id :clj-pss
|
|
3
|
+
:ns-patterns ["datahike.test."]
|
|
4
|
+
:bindings {datahike.config/*default-index* :datahike.index/persistent-set}}
|
|
5
|
+
{:id :clj-hht
|
|
6
|
+
:ns-patterns ["datahike.test."]
|
|
7
|
+
:bindings {datahike.config/*default-index* :datahike.index/hitchhiker-tree}
|
|
8
|
+
:kaocha.plugin.hooks/pre-load [datahike.index.hitchhiker-tree]}
|
|
9
|
+
{:id :specs
|
|
10
|
+
:skip-meta [:no-spec]
|
|
11
|
+
:ns-patterns ["datahike.test."]}
|
|
12
|
+
#_{:id :cljs
|
|
13
|
+
:type :kaocha.type/cljs
|
|
14
|
+
:ns-patterns ["datahike.test."]}
|
|
15
|
+
{:id :norm
|
|
16
|
+
:test-paths ["test/datahike/norm"]}
|
|
17
|
+
{:id :integration
|
|
18
|
+
:test-paths ["test/datahike/integration_test"]}
|
|
19
|
+
{:id :kabel
|
|
20
|
+
:test-paths ["test/datahike/kabel"]
|
|
21
|
+
:skip-meta [:browser]}]
|
|
22
|
+
;; More verbose than the default reporter, and with prettier errors
|
|
23
|
+
:reporter kaocha.report/documentation}
|
|
24
|
+
#include "tests.user.edn"]
|