<commit_before>(ns untangled.client.impl.application-spec
  (:require
    [untangled.client.core :as uc]
    [om.next :as om :refer [defui]]
    [untangled-spec.core :refer-macros [specification behavior assertions provided component when-mocking]]
    untangled.client.impl.built-in-mutations
    [om.dom :as dom]
    [untangled.i18n.core :as i18n]
    [untangled.client.impl.application :as app]
    [cljs.core.async :as async]
    [untangled.client.impl.data-fetch :as f]
    [untangled.client.impl.om-plumbing :as plumbing]
    [untangled.client.impl.network :as net]))

(defui ^:once Thing
  static om/Ident
  (ident [this props] [:thing/by-id (:id props)])
  static om/IQuery
  (query [this] [:id :name])
  Object
  (render [this] (dom/div nil "")))

(defui ^:once Root
  static om/IQuery
  (query [this] [:ui/react-key :ui/locale {:things (om/get-query Thing)}])
  Object
  (render [this]
    (dom/div nil "")))

(specification "Untangled Application (integration tests)"
  (let [startup-called    (atom false)
        thing-1           {:id 1 :name "A"}
        state             {:things [thing-1 {:id 2 :name "B"}]}
        callback          (fn [app] (reset! startup-called (:initial-state app)))
        unmounted-app     (uc/new-untangled-client
                            :initial-state state
                            :started-callback callback
                            :network-error-callback (fn [state _] (get-in @state [:thing/by-id 1]))
                            :reconciler-options {:root-unmount identity})
        app               (uc/mount unmounted-app Root "application-mount-point")
        mounted-app-state (om/app-state (:reconciler app))
        reconciler        (:reconciler app)
        reconciler-config (:config reconciler)
        migrate           (:migrate reconciler-config)]

    (component "Initialization"
      (behavior "custom reconciler options"
        (assertions
          (:root-unmount reconciler-config) => identity))

      (behavior "returns untangled client app record with"
        (assertions<commit_msg>Specs for generate-reconciler with user options<commit_after>(ns untangled.client.impl.application-spec
  (:require
    [untangled.client.core :as uc]
    [om.next :as om :refer [defui]]
    [untangled-spec.core :refer-macros [specification behavior assertions provided component when-mocking]]
    untangled.client.impl.built-in-mutations
    [om.dom :as dom]
    [untangled.i18n.core :as i18n]
    [untangled.client.impl.application :as app]
    [cljs.core.async :as async]
    [untangled.client.impl.data-fetch :as f]
    [untangled.client.impl.om-plumbing :as plumbing]
    [untangled.client.impl.network :as net]))

(defui ^:once Thing
  static om/Ident
  (ident [this props] [:thing/by-id (:id props)])
  static om/IQuery
  (query [this] [:id :name])
  Object
  (render [this] (dom/div nil "")))

(defui ^:once Root
  static om/IQuery
  (query [this] [:ui/react-key :ui/locale {:things (om/get-query Thing)}])
  Object
  (render [this]
    (dom/div nil "")))

(defn reconciler-with-config [config]
  (-> (app/generate-reconciler {} {} (om/parser {:read identity}) config)
      :config))

(specification "generate-reconciler"
  (behavior "open reconciler options"
    (assertions
      ":shared"
      (-> (reconciler-with-config {:shared {:res :value}}) :shared)
      => {:res :value}

      ":pathopt"
      (-> (reconciler-with-config {:pathopt false}) :pathopt)
      => false

      ":migrate"
      (-> (reconciler-with-config {:migrate identity}) :migrate)
      => identity

      ":root-unmount"
      (-> (reconciler-with-config {:root-unmount identity}) :root-unmount)
      => identity))

  (behavior "locked reconciler options"
    (assertions
      ":state"
      (-> (reconciler-with-config {:state {}}) :state)
      =fn=> #(not= % {})

      ":send"
      (-> (reconciler-with-config {:send identity}) :send)
      =fn=> #(not= % identity)

      ":normalize"
      (-> (reconciler-with-config {:normalize false}) :normalize)
      => true

      ":remotes"
      (-> (reconciler-with-config {:remotes []}) :remotes)
      =fn=> #(not= % [])

      ":merge-ident"
      (-> (reconciler-with-config {:merge-ident identity}) :merge-ident)
      =fn=> #(not= % identity)

      ":merge-tree"
      (-> (reconciler-with-config {:merge-tree identity}) :merge-tree)
      =fn=> #(not= % identity)

      ":parser"
      (-> (reconciler-with-config {:parser identity}) :parser)
      =fn=> #(not= % identity))))

(specification "Untangled Application (integration tests)"
  (let [startup-called    (atom false)
        thing-1           {:id 1 :name "A"}
        state             {:things [thing-1 {:id 2 :name "B"}]}
        callback          (fn [app] (reset! startup-called (:initial-state app)))
        unmounted-app     (uc/new-untangled-client
                            :initial-state state
                            :started-callback callback
                            :network-error-callback (fn [state _] (get-in @state [:thing/by-id 1])))
        app               (uc/mount unmounted-app Root "application-mount-point")
        mounted-app-state (om/app-state (:reconciler app))
        reconciler        (:reconciler app)
        reconciler-config (:config reconciler)
        migrate           (:migrate reconciler-config)]

    (component "Initialization"
      (behavior "returns untangled client app record with"
        (assertions
{'fraction_non_alphanumeric': 0.14805290227773696, 'fraction_numerical': 0.0033063923585598823, 'mean_word_length': 2.4747925973197193, 'pattern_counts': {'":': 11, '<': 3, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '127893', 'n_tokens_mistral': 1817, 'n_tokens_neox': 1744, 'n_words': 410}