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,92 @@
|
|
|
1
|
+
(ns datahike.test.components-test
|
|
2
|
+
(:require
|
|
3
|
+
[#?(:cljs cljs.reader :clj clojure.edn) :as edn]
|
|
4
|
+
#?(:cljs [cljs.test :as t :refer-macros [is deftest testing]]
|
|
5
|
+
:clj [clojure.test :as t :refer [is deftest testing]])
|
|
6
|
+
[datahike.api :as d]
|
|
7
|
+
[datahike.db :as db]
|
|
8
|
+
[datahike.test.core-test :as tdc]
|
|
9
|
+
[datahike.impl.entity :as de]))
|
|
10
|
+
|
|
11
|
+
(t/use-fixtures :once tdc/no-namespace-maps)
|
|
12
|
+
|
|
13
|
+
#?(:cljs
|
|
14
|
+
(def Throwable js/Error))
|
|
15
|
+
|
|
16
|
+
(deftest test-components
|
|
17
|
+
(is (thrown-with-msg? Throwable
|
|
18
|
+
#"Bad attribute specification for :profile: \{:db/isComponent true\} should also have \{:db/valueType :db.type/ref\}"
|
|
19
|
+
(db/empty-db {:profile {:db/isComponent true}})))
|
|
20
|
+
(is (thrown-with-msg? Throwable
|
|
21
|
+
#"Bad attribute specification for \{:profile \{:db/isComponent \"aaa\"\}\}, expected one of #\{true false\}"
|
|
22
|
+
(db/empty-db {:profile {:db/isComponent "aaa" :db/valueType :db.type/ref}})))
|
|
23
|
+
|
|
24
|
+
(let [db (d/db-with
|
|
25
|
+
(db/empty-db {:profile {:db/valueType :db.type/ref
|
|
26
|
+
:db/isComponent true}})
|
|
27
|
+
[{:db/id 1 :name "Ivan" :profile 3}
|
|
28
|
+
{:db/id 3 :email "@3"}
|
|
29
|
+
{:db/id 4 :email "@4"}])
|
|
30
|
+
visible #(edn/read-string (pr-str %))
|
|
31
|
+
touched #(visible (de/touch %))]
|
|
32
|
+
|
|
33
|
+
(testing "touch"
|
|
34
|
+
(is (= (touched (d/entity db 1))
|
|
35
|
+
{:db/id 1
|
|
36
|
+
:name "Ivan"
|
|
37
|
+
:profile {:db/id 3
|
|
38
|
+
:email "@3"}}))
|
|
39
|
+
(is (= (touched (d/entity (d/db-with db [[:db/add 3 :profile 4]]) 1))
|
|
40
|
+
{:db/id 1
|
|
41
|
+
:name "Ivan"
|
|
42
|
+
:profile {:db/id 3
|
|
43
|
+
:email "@3"
|
|
44
|
+
:profile {:db/id 4
|
|
45
|
+
:email "@4"}}})))
|
|
46
|
+
(testing "retractEntity"
|
|
47
|
+
(let [db (d/db-with db [[:db.fn/retractEntity 1]])]
|
|
48
|
+
(is (= (d/q '[:find ?a ?v :where [1 ?a ?v]] db)
|
|
49
|
+
#{}))
|
|
50
|
+
(is (= (d/q '[:find ?a ?v :where [3 ?a ?v]] db)
|
|
51
|
+
#{}))))
|
|
52
|
+
|
|
53
|
+
(testing "retractAttribute"
|
|
54
|
+
(let [db (d/db-with db [[:db.fn/retractAttribute 1 :profile]])]
|
|
55
|
+
(is (= (d/q '[:find ?a ?v :where [3 ?a ?v]] db)
|
|
56
|
+
#{}))))
|
|
57
|
+
|
|
58
|
+
(testing "reverse navigation"
|
|
59
|
+
(is (= (visible (:_profile (d/entity db 3)))
|
|
60
|
+
{:db/id 1})))))
|
|
61
|
+
|
|
62
|
+
(deftest test-components-multival
|
|
63
|
+
(let [db (d/db-with
|
|
64
|
+
(db/empty-db {:profile {:db/valueType :db.type/ref
|
|
65
|
+
:db/cardinality :db.cardinality/many
|
|
66
|
+
:db/isComponent true}})
|
|
67
|
+
[{:db/id 1 :name "Ivan" :profile [3 4]}
|
|
68
|
+
{:db/id 3 :email "@3"}
|
|
69
|
+
{:db/id 4 :email "@4"}])
|
|
70
|
+
visible #(edn/read-string (pr-str %))
|
|
71
|
+
touched #(visible (de/touch %))]
|
|
72
|
+
|
|
73
|
+
(testing "touch"
|
|
74
|
+
(is (= (touched (d/entity db 1))
|
|
75
|
+
{:db/id 1
|
|
76
|
+
:name "Ivan"
|
|
77
|
+
:profile #{{:db/id 3 :email "@3"}
|
|
78
|
+
{:db/id 4 :email "@4"}}})))
|
|
79
|
+
|
|
80
|
+
(testing "retractEntity"
|
|
81
|
+
(let [db (d/db-with db [[:db.fn/retractEntity 1]])]
|
|
82
|
+
(is (= (d/q '[:find ?a ?v :in $ [?e ...] :where [?e ?a ?v]] db [1 3 4])
|
|
83
|
+
#{}))))
|
|
84
|
+
|
|
85
|
+
(testing "retractAttribute"
|
|
86
|
+
(let [db (d/db-with db [[:db.fn/retractAttribute 1 :profile]])]
|
|
87
|
+
(is (= (d/q '[:find ?a ?v :in $ [?e ...] :where [?e ?a ?v]] db [3 4])
|
|
88
|
+
#{}))))
|
|
89
|
+
|
|
90
|
+
(testing "reverse navigation"
|
|
91
|
+
(is (= (visible (:_profile (d/entity db 3)))
|
|
92
|
+
{:db/id 1})))))
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
(ns datahike.test.config-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.config :as c]
|
|
6
|
+
[datahike.db :as db]
|
|
7
|
+
[datahike.api :as d]
|
|
8
|
+
[datahike.index :as di]
|
|
9
|
+
[datahike.index.hitchhiker-tree :as dih]
|
|
10
|
+
[datahike.connector :as conn]))
|
|
11
|
+
|
|
12
|
+
#?(:cljs (def Throwable js/Error))
|
|
13
|
+
|
|
14
|
+
(deftest int-from-env-test
|
|
15
|
+
(is (= 1000
|
|
16
|
+
(c/int-from-env :foo 1000))))
|
|
17
|
+
|
|
18
|
+
(deftest bool-from-env-test
|
|
19
|
+
(is (c/bool-from-env :foo true)))
|
|
20
|
+
|
|
21
|
+
(deftest uri-test
|
|
22
|
+
(let [mem-uri "datahike:mem://config-test"
|
|
23
|
+
file-uri "datahike:file:///tmp/config-test"]
|
|
24
|
+
|
|
25
|
+
(are [x y] (= x (c/uri->config y))
|
|
26
|
+
{:backend :memory :host "config-test" :uri mem-uri}
|
|
27
|
+
mem-uri
|
|
28
|
+
|
|
29
|
+
{:backend :file :path "/tmp/config-test" :uri file-uri}
|
|
30
|
+
file-uri)))
|
|
31
|
+
|
|
32
|
+
(deftest deprecated-test
|
|
33
|
+
(let [mem-cfg {:backend :memory
|
|
34
|
+
:host "deprecated-test"}
|
|
35
|
+
file-cfg {:backend :file
|
|
36
|
+
:path "/deprecated/test"}
|
|
37
|
+
default-new-cfg {:attribute-refs? false
|
|
38
|
+
:keep-history? true
|
|
39
|
+
:initial-tx nil
|
|
40
|
+
:index :datahike.index/persistent-set
|
|
41
|
+
:index-config {}
|
|
42
|
+
:schema-flexibility :write
|
|
43
|
+
:crypto-hash? false
|
|
44
|
+
:branch :db
|
|
45
|
+
:writer c/self-writer
|
|
46
|
+
:search-cache-size c/*default-search-cache-size*
|
|
47
|
+
:store-cache-size c/*default-store-cache-size*}]
|
|
48
|
+
(is (= (merge default-new-cfg
|
|
49
|
+
{:store {:backend :memory :id #uuid "ec3537bd-3f0d-3719-acd5-40751bbb1012"}})
|
|
50
|
+
(c/from-deprecated mem-cfg)))
|
|
51
|
+
(is (= (merge default-new-cfg
|
|
52
|
+
{:store {:backend :file
|
|
53
|
+
:path "/deprecated/test"
|
|
54
|
+
:id #uuid "908d33ed-b562-3301-9a9f-94b961e56f05"}})
|
|
55
|
+
(c/from-deprecated file-cfg)))))
|
|
56
|
+
|
|
57
|
+
(deftest load-config-test
|
|
58
|
+
(testing "configuration defaults"
|
|
59
|
+
(let [config (c/load-config)]
|
|
60
|
+
(is (= (merge {:store {:backend :memory}
|
|
61
|
+
:attribute-refs? c/*default-attribute-refs?*
|
|
62
|
+
:keep-history? c/*default-keep-history?*
|
|
63
|
+
:schema-flexibility c/*default-schema-flexibility*
|
|
64
|
+
:index c/*default-index*
|
|
65
|
+
:crypto-hash? c/*default-crypto-hash?*
|
|
66
|
+
:branch c/*default-db-branch*
|
|
67
|
+
:writer c/self-writer
|
|
68
|
+
:search-cache-size c/*default-search-cache-size*
|
|
69
|
+
:store-cache-size c/*default-store-cache-size*}
|
|
70
|
+
(when (seq (di/default-index-config c/*default-index*))
|
|
71
|
+
{:index-config (di/default-index-config c/*default-index*)}))
|
|
72
|
+
(update config :store dissoc :id :scope))))))
|
|
73
|
+
|
|
74
|
+
(deftest core-config-test
|
|
75
|
+
(testing "Schema on write in core empty database"
|
|
76
|
+
(is (thrown-with-msg? Throwable
|
|
77
|
+
#"Bad entity attribute :name at \{:db/id 1, :name \"Ivan\"\}, not defined in current schema"
|
|
78
|
+
(d/db-with (db/empty-db nil {:schema-flexibility :write})
|
|
79
|
+
[{:db/id 1 :name "Ivan" :aka ["IV" "Terrible"]}
|
|
80
|
+
{:db/id 2 :name "Petr" :age 37 :huh? false}])))
|
|
81
|
+
(is (thrown-with-msg? Throwable
|
|
82
|
+
#"Incomplete schema attributes, expected at least :db/valueType, :db/cardinality"
|
|
83
|
+
(db/empty-db {:name {:db/cardinality :db.cardinality/one}} {:schema-flexibility :write})))
|
|
84
|
+
(is (= #{["Alice"]}
|
|
85
|
+
(let [db (-> (db/empty-db {:name {:db/cardinality :db.cardinality/one :db/valueType :db.type/string}} {:schema-flexibility :write})
|
|
86
|
+
(d/db-with [{:name "Alice"}]))]
|
|
87
|
+
(d/q '[:find ?n :where [_ :name ?n]] db))))
|
|
88
|
+
(is (= #{["Alice"]}
|
|
89
|
+
(let [db (-> (db/empty-db [{:db/ident :name :db/cardinality :db.cardinality/one :db/valueType :db.type/string}]
|
|
90
|
+
{:schema-flexibility :write})
|
|
91
|
+
(d/db-with [{:name "Alice"}]))]
|
|
92
|
+
(d/q '[:find ?n :where [_ :name ?n]] db))))))
|
|
93
|
+
|
|
94
|
+
(deftest store-identity-config-test
|
|
95
|
+
(testing "different configs with equal identities"
|
|
96
|
+
(let [mem-start {:store {:backend :memory
|
|
97
|
+
:id #uuid "51de0715-1000-0000-0000-000000000001"}}
|
|
98
|
+
mem-other {:store {:backend :memory
|
|
99
|
+
:id #uuid "a107be12-1de0-7157-0000-000000000001"}}
|
|
100
|
+
file-start {:store {:backend :file
|
|
101
|
+
:path "/tmp/store-identity-test"
|
|
102
|
+
:id #uuid "1de07157-0000-0000-0000-000000000001"}}
|
|
103
|
+
file-index {:index :datahike.index/hitchhiker-tree
|
|
104
|
+
:store {:backend :file
|
|
105
|
+
:path "/tmp/store-identity-test"
|
|
106
|
+
:id #uuid "1de07157-0000-0000-0000-000000000001"}}
|
|
107
|
+
mem-named {:name "has-name"
|
|
108
|
+
:store {:backend :memory
|
|
109
|
+
:id #uuid "51de0715-1000-0000-0000-000000000001"}}
|
|
110
|
+
mem-same {:store {:backend :memory
|
|
111
|
+
:id #uuid "51de0715-1000-0000-0000-000000000001"
|
|
112
|
+
:irrelevant-property true}}]
|
|
113
|
+
(is (thrown-with-msg? Throwable
|
|
114
|
+
#"Store identity mismatch"
|
|
115
|
+
(conn/ensure-stored-config-consistency mem-start mem-other)))
|
|
116
|
+
(is (not= mem-start mem-other))
|
|
117
|
+
(is (thrown-with-msg? Throwable
|
|
118
|
+
#"Configuration does not match stored configuration."
|
|
119
|
+
(conn/ensure-stored-config-consistency file-start file-index)))
|
|
120
|
+
(is (not= file-start file-index))
|
|
121
|
+
(is (thrown-with-msg? Throwable
|
|
122
|
+
#"Store identity mismatch"
|
|
123
|
+
(conn/ensure-stored-config-consistency mem-start file-start)))
|
|
124
|
+
(is (not= mem-start file-start))
|
|
125
|
+
(is (nil? (conn/ensure-stored-config-consistency mem-start mem-named)))
|
|
126
|
+
(is (not= mem-start mem-named))
|
|
127
|
+
(is (nil? (conn/ensure-stored-config-consistency mem-start mem-same)))
|
|
128
|
+
(is (not= mem-start mem-same))
|
|
129
|
+
(is (nil? (conn/ensure-stored-config-consistency mem-named mem-same)))
|
|
130
|
+
(is (not= mem-named mem-same)))))
|
|
131
|
+
|
|
132
|
+
(deftest store-identity-connection-test
|
|
133
|
+
(testing "different connections with equal identities"
|
|
134
|
+
(let [mem-start {:store {:backend :memory
|
|
135
|
+
:id #uuid "51dec000-ec71-0000-0000-000000000001"}}
|
|
136
|
+
mem-other {:store {:backend :memory
|
|
137
|
+
:id #uuid "a107be12-c000-ec71-0000-000000000001"}}
|
|
138
|
+
file-start {:store {:backend :file
|
|
139
|
+
:path "/tmp/store-connection-test"
|
|
140
|
+
:id #uuid "c000ec71-0000-0000-0000-000000000001"}}
|
|
141
|
+
file-index {:index :datahike.index/hitchhiker-tree
|
|
142
|
+
:store {:backend :file
|
|
143
|
+
:path "/tmp/store-connection-test"
|
|
144
|
+
:id #uuid "c000ec71-0000-0000-0000-000000000001"}}
|
|
145
|
+
mem-named {:name "has-name"
|
|
146
|
+
:store {:backend :memory
|
|
147
|
+
:id #uuid "51dec000-ec71-0000-0000-000000000001"}}
|
|
148
|
+
mem-same {:store {:backend :memory
|
|
149
|
+
:id #uuid "51dec000-ec71-0000-0000-000000000001"
|
|
150
|
+
:irrelevant-property true}}
|
|
151
|
+
_ (doall (map d/delete-database [mem-start mem-other file-start file-index mem-named mem-same]))]
|
|
152
|
+
(d/create-database mem-start)
|
|
153
|
+
(is (= (d/connect mem-start) (d/connect mem-named) (d/connect mem-same)))
|
|
154
|
+
(d/create-database file-start)
|
|
155
|
+
(d/connect file-start)
|
|
156
|
+
(is (thrown-with-msg? Throwable
|
|
157
|
+
#"Configuration does not match existing connections."
|
|
158
|
+
(d/connect file-index))))))
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
(ns datahike.test.core-test
|
|
2
|
+
(:require
|
|
3
|
+
#?(:cljs [cljs.test :as t :refer-macros [is deftest]]
|
|
4
|
+
:clj [clojure.test :as t :refer [is deftest]])
|
|
5
|
+
[clojure.walk]
|
|
6
|
+
[clojure.data]
|
|
7
|
+
#?(:clj [kaocha.stacktrace])
|
|
8
|
+
[datahike.core :as dc]
|
|
9
|
+
[datahike.constants :as const]
|
|
10
|
+
[datahike.impl.entity :as de]
|
|
11
|
+
#?(:cljs [datahike.test.cljs])))
|
|
12
|
+
|
|
13
|
+
#?(:cljs
|
|
14
|
+
(enable-console-print!))
|
|
15
|
+
|
|
16
|
+
;; Added special case for printing ex-data of ExceptionInfo
|
|
17
|
+
#?(:cljs
|
|
18
|
+
(defmethod t/report [::t/default :error] [m]
|
|
19
|
+
(t/inc-report-counter! :error)
|
|
20
|
+
(println "\nERROR in" (t/testing-vars-str m))
|
|
21
|
+
(when (seq (:testing-contexts (t/get-current-env)))
|
|
22
|
+
(println (t/testing-contexts-str)))
|
|
23
|
+
(when-let [message (:message m)] (println message))
|
|
24
|
+
(println "expected:" (pr-str (:expected m)))
|
|
25
|
+
(print " actual: ")
|
|
26
|
+
(let [actual (:actual m)]
|
|
27
|
+
(cond
|
|
28
|
+
(instance? ExceptionInfo actual)
|
|
29
|
+
(println (.-stack actual) "\n" (pr-str (ex-data actual)))
|
|
30
|
+
(instance? js/Error actual)
|
|
31
|
+
(println (.-stack actual))
|
|
32
|
+
:else
|
|
33
|
+
(prn actual)))))
|
|
34
|
+
|
|
35
|
+
#?(:cljs (def test-summary (atom nil)))
|
|
36
|
+
#?(:cljs (defmethod t/report [::t/default :end-run-tests] [m]
|
|
37
|
+
(reset! test-summary (dissoc m :type))))
|
|
38
|
+
|
|
39
|
+
(defn wrap-res [f]
|
|
40
|
+
#?(:cljs (do (f) (clj->js @test-summary))
|
|
41
|
+
:clj (let [res (f)]
|
|
42
|
+
(when (pos? (+ (:fail res) (:error res)))
|
|
43
|
+
(System/exit 1)))))
|
|
44
|
+
|
|
45
|
+
(defn entity-map [db e]
|
|
46
|
+
(when-let [entity (dc/entity db e)]
|
|
47
|
+
(->> (assoc (into {} entity) :db/id (:db/id entity))
|
|
48
|
+
(clojure.walk/prewalk #(if (de/entity? %)
|
|
49
|
+
{:db/id (:db/id %)}
|
|
50
|
+
%)))))
|
|
51
|
+
|
|
52
|
+
(defn all-datoms [db]
|
|
53
|
+
(into #{} (map (juxt :e :a :v)) (dc/datoms db :eavt)))
|
|
54
|
+
|
|
55
|
+
(defn no-namespace-maps [t]
|
|
56
|
+
(binding [*print-namespace-maps* false]
|
|
57
|
+
(t)))
|
|
58
|
+
|
|
59
|
+
;; Filter Kaocha frames from exceptions
|
|
60
|
+
|
|
61
|
+
#?(:clj
|
|
62
|
+
(alter-var-root #'kaocha.stacktrace/*stacktrace-filters* (constantly ["java." "clojure." "kaocha." "orchestra."])))
|
|
63
|
+
|
|
64
|
+
;; Core tests
|
|
65
|
+
|
|
66
|
+
(deftest test-protocols
|
|
67
|
+
(let [schema {:aka {:db/cardinality :db.cardinality/many}}
|
|
68
|
+
db (dc/db-with (dc/empty-db schema)
|
|
69
|
+
[{:db/id 1 :name "Ivan" :aka ["IV" "Terrible"]}
|
|
70
|
+
{:db/id 2 :name "Petr" :age 37 :huh? false}])]
|
|
71
|
+
(is (= (dc/empty-db schema)
|
|
72
|
+
(empty db)))
|
|
73
|
+
(is (= 6 (count db)))
|
|
74
|
+
(is (= (set (seq db))
|
|
75
|
+
#{(dc/datom 1 :aka "IV")
|
|
76
|
+
(dc/datom 1 :aka "Terrible")
|
|
77
|
+
(dc/datom 1 :name "Ivan")
|
|
78
|
+
(dc/datom 2 :age 37)
|
|
79
|
+
(dc/datom 2 :name "Petr")
|
|
80
|
+
(dc/datom 2 :huh? false)}))))
|
|
81
|
+
|
|
82
|
+
(defn- now []
|
|
83
|
+
#?(:clj (System/currentTimeMillis)
|
|
84
|
+
:cljs (.getTime (js/Date.))))
|
|
85
|
+
|
|
86
|
+
(deftest test-uuid
|
|
87
|
+
(let [now-ms (loop []
|
|
88
|
+
(let [ts (now)]
|
|
89
|
+
(if (> (mod ts 1000) 900) ;; sleeping over end of a second
|
|
90
|
+
(recur)
|
|
91
|
+
ts)))
|
|
92
|
+
now (int (/ now-ms 1000))]
|
|
93
|
+
(is (= (* 1000 now) (dc/squuid-time-millis (dc/squuid))))
|
|
94
|
+
(is (not= (dc/squuid) (dc/squuid)))
|
|
95
|
+
(is (= (subs (str (dc/squuid)) 0 8)
|
|
96
|
+
(subs (str (dc/squuid)) 0 8)))))
|
|
97
|
+
|
|
98
|
+
(deftest test-diff
|
|
99
|
+
(is (= [[(dc/datom 1 :b 2) (dc/datom 1 :c 4) (dc/datom 2 :a 1)]
|
|
100
|
+
[(dc/datom 1 :b 3) (dc/datom 1 :d 5)]
|
|
101
|
+
[(dc/datom 1 :a 1)]]
|
|
102
|
+
(clojure.data/diff
|
|
103
|
+
(dc/db-with (dc/empty-db) [{:a 1 :b 2 :c 4} {:a 1}])
|
|
104
|
+
(dc/db-with (dc/empty-db) [{:a 1 :b 3 :d 5}])))))
|
|
105
|
+
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
(ns datahike.test.datom-test
|
|
2
|
+
(:require
|
|
3
|
+
#?(:cljs [cljs.test :as t :refer-macros [is deftest testing]]
|
|
4
|
+
:clj [clojure.test :as t :refer [is deftest testing]])
|
|
5
|
+
[datahike.datom :as d :refer [datom]]))
|
|
6
|
+
|
|
7
|
+
(deftest datom-impl
|
|
8
|
+
(let [d (datom 123 :foo/bar "foobar")]
|
|
9
|
+
(is (= [:e 123]
|
|
10
|
+
(find d :e)))
|
|
11
|
+
(is (= {:e 123
|
|
12
|
+
:a :foo/bar
|
|
13
|
+
:v "foobar"}
|
|
14
|
+
(select-keys d [:e :a :v])))
|
|
15
|
+
(is (= 123 (d :e)))))
|
|
16
|
+
|
|
17
|
+
(deftest prefix-comparators
|
|
18
|
+
(testing "Prefix comparators match on e,a,v ignoring tx"
|
|
19
|
+
(let [d1 (datom 1 :name "Alice" 100)
|
|
20
|
+
d2 (datom 1 :name "Alice" 200) ; same e,a,v but different tx
|
|
21
|
+
d3 (datom 1 :name "Bob" 100)] ; different v
|
|
22
|
+
|
|
23
|
+
(testing "eavt prefix"
|
|
24
|
+
(is (= 0 (d/cmp-datoms-eavt-prefix d1 d2))
|
|
25
|
+
"Should match datoms with same e,a,v but different tx")
|
|
26
|
+
(is (not= 0 (d/cmp-datoms-eavt-prefix d1 d3))
|
|
27
|
+
"Should not match datoms with different v"))
|
|
28
|
+
|
|
29
|
+
(testing "aevt prefix"
|
|
30
|
+
(is (= 0 (d/cmp-datoms-aevt-prefix d1 d2))
|
|
31
|
+
"Should match datoms with same a,e,v but different tx")
|
|
32
|
+
(is (not= 0 (d/cmp-datoms-aevt-prefix d1 d3))
|
|
33
|
+
"Should not match datoms with different v"))
|
|
34
|
+
|
|
35
|
+
(testing "avet prefix"
|
|
36
|
+
(is (= 0 (d/cmp-datoms-avet-prefix d1 d2))
|
|
37
|
+
"Should match datoms with same a,v,e but different tx")
|
|
38
|
+
(is (not= 0 (d/cmp-datoms-avet-prefix d1 d3))
|
|
39
|
+
"Should not match datoms with different v"))))
|
|
40
|
+
|
|
41
|
+
(testing "index-type->cmp-prefix returns correct comparator"
|
|
42
|
+
(is (= d/cmp-datoms-eavt-prefix (d/index-type->cmp-prefix :eavt)))
|
|
43
|
+
(is (= d/cmp-datoms-aevt-prefix (d/index-type->cmp-prefix :aevt)))
|
|
44
|
+
(is (= d/cmp-datoms-avet-prefix (d/index-type->cmp-prefix :avet)))))
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
(ns datahike.test.db-test
|
|
2
|
+
(:require
|
|
3
|
+
[clojure.data]
|
|
4
|
+
#?(:cljs [cljs.test :as t :refer-macros [is deftest testing]]
|
|
5
|
+
:clj [clojure.test :as t :refer [is deftest testing]])
|
|
6
|
+
[datahike.api :as d]
|
|
7
|
+
[datahike.constants :as const]
|
|
8
|
+
[datahike.test.core-test]
|
|
9
|
+
[datahike.db :as db #?@(:cljs [:refer-macros [defrecord-updatable]]
|
|
10
|
+
:clj [:refer [defrecord-updatable]])]))
|
|
11
|
+
|
|
12
|
+
#?(:cljs (def Throwable js/Error))
|
|
13
|
+
|
|
14
|
+
;; verify that defrecord-updatable works with compiler/core macro configuration
|
|
15
|
+
;; define dummy class which redefines hash, could produce either
|
|
16
|
+
;; compiler or runtime error
|
|
17
|
+
;;
|
|
18
|
+
(defrecord-updatable HashBeef [x]
|
|
19
|
+
#?@(:cljs [IHash (-hash [hb] 0xBEEF)]
|
|
20
|
+
:clj [clojure.lang.IHashEq (hasheq [hb] 0xBEEF)]))
|
|
21
|
+
|
|
22
|
+
(deftest test-defrecord-updatable
|
|
23
|
+
(is (= 0xBEEF (-> (map->HashBeef {:x :ignored}) hash))))
|
|
24
|
+
|
|
25
|
+
(deftest test-fn-hash-changes
|
|
26
|
+
(let [db (d/db-with (db/empty-db)
|
|
27
|
+
[{:db/id 1 :name "Konrad"}])
|
|
28
|
+
r1 (d/db-with db [[:db.fn/retractEntity 1]])
|
|
29
|
+
r2 (d/db-with db [[:db.fn/retractEntity 1]])]
|
|
30
|
+
(is (= (hash r1) (hash r2)))))
|
|
31
|
+
|
|
32
|
+
(deftest test-equiv-db-hash
|
|
33
|
+
(let [db (d/db-with (db/empty-db)
|
|
34
|
+
[{:db/id 1 :name "Konrad"}])
|
|
35
|
+
r1 (d/db-with db [[:db.fn/retractEntity 1]])]
|
|
36
|
+
(is (= (hash (db/empty-db)) (hash r1)))))
|
|
37
|
+
|
|
38
|
+
(deftest empty-db-with-schema
|
|
39
|
+
(testing "Test old write schema"
|
|
40
|
+
(is (thrown-with-msg? Throwable
|
|
41
|
+
#"Incomplete schema attributes, expected at least :db/valueType, :db/cardinality"
|
|
42
|
+
(db/empty-db {:name {:db/cardinality :db.cardinality/many}} {:schema-flexibility :write})))
|
|
43
|
+
(is (= (merge const/non-ref-implicit-schema
|
|
44
|
+
{:name {:db/cardinality :db.cardinality/one :db/valueType :db.type/string}})
|
|
45
|
+
(:schema (db/empty-db {:name {:db/cardinality :db.cardinality/one
|
|
46
|
+
:db/valueType :db.type/string}}
|
|
47
|
+
{:schema-flexibility :write}))))
|
|
48
|
+
|
|
49
|
+
(is (= (merge const/non-ref-implicit-schema
|
|
50
|
+
{:name {:db/ident :name :db/cardinality :db.cardinality/one :db/valueType :db.type/string}})
|
|
51
|
+
(:schema (db/empty-db [{:db/ident :name
|
|
52
|
+
:db/cardinality :db.cardinality/one
|
|
53
|
+
:db/valueType :db.type/string}]
|
|
54
|
+
{:schema-flexibility :write}))))))
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
(ns datahike.test.entity-spec-test
|
|
2
|
+
(:require
|
|
3
|
+
#?(:cljs [cljs.test :as t :refer-macros [is deftest testing]]
|
|
4
|
+
:clj [clojure.test :as t :refer [is deftest testing]])
|
|
5
|
+
[datahike.test.core-test]
|
|
6
|
+
[datahike.api :as d]))
|
|
7
|
+
|
|
8
|
+
#?(:cljs (def Throwable js/Error))
|
|
9
|
+
|
|
10
|
+
(def cfg-template {:store {:backend :memory
|
|
11
|
+
:id #uuid "001c0000-0000-0000-0000-00000000001c"}
|
|
12
|
+
:keep-history? false
|
|
13
|
+
:schema-flexibility :write})
|
|
14
|
+
|
|
15
|
+
(def schema-template
|
|
16
|
+
[{:db/ident :account/email
|
|
17
|
+
:db/valueType :db.type/string
|
|
18
|
+
:db/unique :db.unique/identity
|
|
19
|
+
:db/cardinality :db.cardinality/one}
|
|
20
|
+
{:db/ident :account/balance
|
|
21
|
+
:db/valueType :db.type/long
|
|
22
|
+
:db/cardinality :db.cardinality/one}])
|
|
23
|
+
|
|
24
|
+
(defn setup-db [cfg]
|
|
25
|
+
(d/delete-database cfg)
|
|
26
|
+
(d/create-database cfg)
|
|
27
|
+
(d/connect cfg))
|
|
28
|
+
|
|
29
|
+
(deftest test-attribute-assertion
|
|
30
|
+
(let [schema (conj schema-template
|
|
31
|
+
{:db/ident :account/guard
|
|
32
|
+
:db.entity/attrs [:account/email :account/balance]})
|
|
33
|
+
valid-account {:account/email "antonia@a.corp"
|
|
34
|
+
:account/balance 1000}
|
|
35
|
+
invalid-account {:account/email "arthur@b.corp"}
|
|
36
|
+
empty-account {}]
|
|
37
|
+
(letfn [(tx-with-ensure [conn account]
|
|
38
|
+
(d/transact conn [(assoc account :db/ensure :account/guard)]))]
|
|
39
|
+
(testing "with write schema flexibility"
|
|
40
|
+
(let [cfg (-> cfg-template
|
|
41
|
+
(assoc-in [:store :id] #uuid "a77e0000-0000-0000-0000-000000000001")
|
|
42
|
+
(assoc :initial-tx schema))
|
|
43
|
+
conn (setup-db cfg)]
|
|
44
|
+
(testing "assert valid account"
|
|
45
|
+
(let [{:keys [db-after]} (tx-with-ensure conn valid-account)]
|
|
46
|
+
(is (= valid-account (d/pull db-after '[:account/email :account/balance] [:account/email (:account/email valid-account)])))))
|
|
47
|
+
(testing "assert invalid account"
|
|
48
|
+
(is (thrown-with-msg? Throwable
|
|
49
|
+
#"Entity 5 missing attributes #\{:account/balance\} of spec :account/guard"
|
|
50
|
+
(tx-with-ensure conn invalid-account))))
|
|
51
|
+
(testing "assert empty entity"
|
|
52
|
+
(is (thrown-with-msg? Throwable
|
|
53
|
+
#"Entity 5 missing attributes #\{:account/balance :account/email\} of spec :account/guard"
|
|
54
|
+
(tx-with-ensure conn empty-account))))
|
|
55
|
+
(d/release conn)))
|
|
56
|
+
(testing "with read schema flexibility"
|
|
57
|
+
(let [cfg (-> cfg-template
|
|
58
|
+
(assoc :schema-flexibility :read)
|
|
59
|
+
(assoc-in [:store :id] #uuid "a77e0000-0000-0000-0000-000000000002")
|
|
60
|
+
(assoc :initial-tx schema))
|
|
61
|
+
conn (setup-db cfg)]
|
|
62
|
+
(testing "assert valid account"
|
|
63
|
+
(let [{:keys [db-after]} (tx-with-ensure conn valid-account)]
|
|
64
|
+
(is (= valid-account (d/pull db-after '[:account/email :account/balance] [:account/email (:account/email valid-account)])))))
|
|
65
|
+
(testing "assert invalid account"
|
|
66
|
+
(is (thrown-with-msg? Throwable
|
|
67
|
+
#"Entity 5 missing attributes #\{:account/balance\} of spec :account/guard"
|
|
68
|
+
(tx-with-ensure conn invalid-account))))
|
|
69
|
+
(testing "assert empty entity"
|
|
70
|
+
(is (thrown-with-msg? Throwable
|
|
71
|
+
#"Entity 5 missing attributes #\{:account/balance :account/email\} of spec :account/guard"
|
|
72
|
+
(tx-with-ensure conn empty-account))))
|
|
73
|
+
(d/release conn))))))
|
|
74
|
+
|
|
75
|
+
(defn is-email? [db eid]
|
|
76
|
+
;; email could not exist
|
|
77
|
+
(if-let [email (:account/email (d/entity db eid))]
|
|
78
|
+
(seq (re-find #"(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)" email))
|
|
79
|
+
false))
|
|
80
|
+
|
|
81
|
+
(defn positive-balance? [db eid]
|
|
82
|
+
;; balance could not exist
|
|
83
|
+
(if-let [balance (-> (d/entity db eid) :account/balance)]
|
|
84
|
+
(< 0 balance)
|
|
85
|
+
false))
|
|
86
|
+
|
|
87
|
+
(deftest test-predicate-assertion
|
|
88
|
+
(let [schema (conj schema-template
|
|
89
|
+
{:db/ident :account/guard
|
|
90
|
+
:db.entity/preds ['datahike.test.entity-spec-test/is-email? 'datahike.test.entity-spec-test/positive-balance?]})
|
|
91
|
+
valid-account {:account/email "greta@a.corp"
|
|
92
|
+
:account/balance 1000}
|
|
93
|
+
invalid-account {:account/email "georg"
|
|
94
|
+
:account/balance 500}
|
|
95
|
+
invalid-account-multiple {:account/email "gustav"
|
|
96
|
+
:account/balance -500}
|
|
97
|
+
empty-account {}
|
|
98
|
+
cfg (-> cfg-template
|
|
99
|
+
(assoc-in [:store :id] #uuid "a77e0000-0000-0000-0000-000000000003")
|
|
100
|
+
(assoc :initial-tx schema))
|
|
101
|
+
conn (setup-db cfg)]
|
|
102
|
+
(letfn [(tx-with-ensure [account]
|
|
103
|
+
(d/transact conn {:tx-data [(assoc account :db/ensure :account/guard)]}))]
|
|
104
|
+
(testing "assert valid account"
|
|
105
|
+
(let [{:keys [db-after]} (tx-with-ensure valid-account)]
|
|
106
|
+
(is (= valid-account (d/pull db-after '[:account/email :account/balance] [:account/email (:account/email valid-account)])))))
|
|
107
|
+
(testing "assert invalid account with one invalid predicate"
|
|
108
|
+
(is (thrown-with-msg? Throwable
|
|
109
|
+
#"Entity 5 failed predicates #\{datahike.test.entity-spec-test/is-email\?\} of spec :account/guard"
|
|
110
|
+
(tx-with-ensure invalid-account))))
|
|
111
|
+
(testing "assert invalid account with mulitple invalid predicates"
|
|
112
|
+
(is (thrown-with-msg? Throwable
|
|
113
|
+
#"Entity 5 failed predicates #\{datahike.test.entity-spec-test/positive-balance\? datahike.test.entity-spec-test/is-email\?\} of spec :account/guard"
|
|
114
|
+
(tx-with-ensure invalid-account-multiple))))
|
|
115
|
+
(testing "assert empty account"
|
|
116
|
+
(is (thrown-with-msg? Throwable
|
|
117
|
+
#"Entity 5 failed predicates #\{datahike.test.entity-spec-test/positive-balance\? datahike.test.entity-spec-test/is-email\?\} of spec :account/guard"
|
|
118
|
+
(tx-with-ensure empty-account)))))
|
|
119
|
+
(d/release conn)))
|
|
120
|
+
|
|
121
|
+
(deftest test-attribute-and-predicate-assertion
|
|
122
|
+
(let [schema (conj schema-template
|
|
123
|
+
{:db/ident :account/guard
|
|
124
|
+
:db.entity/attrs [:account/email :account/balance]
|
|
125
|
+
:db.entity/preds ['datahike.test.entity-spec-test/is-email? 'datahike.test.entity-spec-test/positive-balance?]})
|
|
126
|
+
valid-account {:account/email "karla@a.corp"
|
|
127
|
+
:account/balance 1000}
|
|
128
|
+
invalid-account-attr {:account/email "konstantin@b.corp"}
|
|
129
|
+
invalid-account-pred {:account/email "kaspar"
|
|
130
|
+
:account/balance 500}
|
|
131
|
+
invalid-account-pred-multiple {:account/email "katharina"
|
|
132
|
+
:account/balance -500}
|
|
133
|
+
empty-account {}
|
|
134
|
+
cfg (-> cfg-template
|
|
135
|
+
(assoc-in [:store :id] #uuid "a77e0000-0000-0000-0000-000000000004")
|
|
136
|
+
(assoc :initial-tx schema))
|
|
137
|
+
conn (setup-db cfg)]
|
|
138
|
+
(letfn [(tx-with-ensure [account]
|
|
139
|
+
(d/transact conn {:tx-data [(assoc account :db/ensure :account/guard)]}))]
|
|
140
|
+
(testing "assert valid account"
|
|
141
|
+
(let [{:keys [db-after]} (tx-with-ensure valid-account)]
|
|
142
|
+
(is (= valid-account (d/pull db-after '[:account/email :account/balance] [:account/email (:account/email valid-account)])))))
|
|
143
|
+
(testing "assert invalid account with missing attributes"
|
|
144
|
+
(is (thrown-with-msg? Throwable
|
|
145
|
+
#"Entity 5 missing attributes #\{:account/balance\} of spec :account/guard"
|
|
146
|
+
(tx-with-ensure invalid-account-attr))))
|
|
147
|
+
(testing "assert invalid account with one invalid predicate"
|
|
148
|
+
(is (thrown-with-msg? Throwable
|
|
149
|
+
#"Entity 5 failed predicates #\{datahike.test.entity-spec-test/is-email\?\} of spec :account/guard"
|
|
150
|
+
(tx-with-ensure invalid-account-pred))))
|
|
151
|
+
(testing "assert invalid account with mulitple invalid predicates"
|
|
152
|
+
(is (thrown-with-msg? Throwable
|
|
153
|
+
#"Entity 5 failed predicates #\{datahike.test.entity-spec-test/positive-balance\? datahike.test.entity-spec-test/is-email\?\} of spec :account/guard"
|
|
154
|
+
(tx-with-ensure invalid-account-pred-multiple))))
|
|
155
|
+
(testing "assert empty account with required attributes precidenting over predicates"
|
|
156
|
+
(is (thrown-with-msg? Throwable
|
|
157
|
+
#"Entity 5 missing attributes #\{:account/balance :account/email\} of spec :account/guard"
|
|
158
|
+
(tx-with-ensure empty-account)))))
|
|
159
|
+
(d/release conn)))
|