<commit_before>(ns datomish.test.query
  (:require
     [datomish.query :as dq]
     #?(:clj  [clojure.test :as t :refer [is are deftest testing]])
     #?(:cljs [cljs.test :as t :refer-macros [is are deftest testing]])
     ))

(deftest test-query
  (is (= 1 1)))<commit_msg>Add tests for joins and not-clauses.<commit_after>(ns datomish.test.query
  (:require
     [datomish.query.context :as context]
     [datomish.query.source :as source]
     [datomish.query.transforms :as transforms]
     [datomish.query :as query]
     #?@(:clj
           [
          [honeysql.core :as sql :refer [param]]
          [clojure.test :as t :refer [is are deftest testing]]])
     #?@(:cljs
           [
          [honeysql.core :as sql :refer-macros [param]]
          [cljs.test :as t :refer-macros [is are deftest testing]]])
     ))

(defn- fgensym [s c]
  (symbol (str s c)))

(defn make-predictable-gensym []
  (let [counter (atom 0)]
    (fn
      ([]
       (fgensym "G__" (dec (swap! counter inc))))
      ([s]
       (fgensym s (dec (swap! counter inc)))))))

(defn mock-source [db]
  (source/map->Source
    {:table :datoms
     :columns [:e :a :v :tx :added]
     :attribute-transform transforms/attribute-transform-string
     :constant-transform transforms/constant-transform-default
     :table-alias (comp (make-predictable-gensym) name)
     :make-constraints nil}))

(defn- expand [find]
  (let [context (context/->Context (mock-source nil) nil nil)
        parsed (query/parse find)]
    (query/find->sql-clause context parsed)))

(deftest test-basic-join
  (is (= {:select '([:datoms1.v :timestampMicros] [:datoms0.e :page]),
          :modifiers [:distinct],
          :from '[[:datoms datoms0]
                  [:datoms datoms1]],
          :where (list
                   :and
                   [:= :datoms1.e :datoms0.tx]
                   [:= :datoms0.a "page/starred"]
                   [:= :datoms0.v 1]
                   [:= :datoms1.a "db/txInstant"]
                   [:not
                    (list :and (list :> :datoms1.e (sql/param :latest)))])}
         (expand
           '[:find ?timestampMicros ?page :in $ ?latest :where
             [?page :page/starred true ?t]
             [?t :db/txInstant ?timestampMicros]
             (not [(> ?t ?latest)])]))))

(deftest test-pattern-not-join
  (is (= '{:select ([:datoms1.v :timestampMicros] [:datoms0.e :page]),
           :modifiers [:distinct],
           :from [[:datoms datoms0]
                  [:datoms datoms1]],
           :where (:and
                     [:= :datoms1.e :datoms0.tx]
                     [:= :datoms0.a "page/starred"]
                     [:= :datoms0.v 1]
                     [:= :datoms1.a "db/txInstant"]
                     [:not
                      [:exists
                       {:select [1],
                        :from [[:datoms datoms2]],
                        :where (:and
                                  [:= :datoms2.a "foo/bar"]
                                  [:= :datoms0.e :datoms2.e])}]])}
         (expand
           '[:find ?timestampMicros ?page :in $ ?latest :where
             [?page :page/starred true ?t]
             [?t :db/txInstant ?timestampMicros]
             (not [?page :foo/bar _])]))))
{'fraction_non_alphanumeric': 0.15895061728395063, 'fraction_numerical': 0.008950617283950617, 'mean_word_length': 1.7327150084317031, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 8, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6789587', 'n_tokens_mistral': 1115, 'n_tokens_neox': 1069, 'n_words': 247}