(ns buddho.tests.dhamma
  (:require  [cljs.test :as t :include-macros true]
             [buddho.core.dhamma :as d]
             [buddho.core.state :as s]))

;;; XXX doesn't freeze yet
(t/use-fixtures :once
  (fn [tests]
    (let [orig-state (swap! s/state identity)]
      (s/reset-state!)
      (tests)
      (reset! s/state orig-state))))

(t/use-fixtures :each
  (fn [test]
    (s/reset-state!)
    (test)))

(t/deftest register-dhamma!
  (t/testing "Dhamma Creation"
    (let [dhamma (d/register-dhamma! :testname :test)]
      (t/is (s/get-element dhamma :source) test))))

(t/deftest register-aspect!
  (t/testing "Aspect Registration"
    (let [dhamma (d/register-dhamma! :testname :test)
          aspect (d/register-dhamma! :aspname :test)]
      (d/register-aspect! aspect [:testname])
      (t/is (contains? (d/get-aspects [:testname]) aspect))
      (t/is (contains? (set (d/aspects-of dhamma)) aspect)))))

(defmethod d/impl! :verify-value [dhamma & [_whole]]
  (let [key (d/get-data dhamma :key)
        value (d/get-data dhamma key)
        expected (d/get-data dhamma :expected)]
    (t/is (= value expected))))

(defmethod d/modify-whole :modify-value [dhamma whole]
  (let [key (d/get-data dhamma :key)
        value (d/get-data dhamma :value)]
    (d/assoc-data whole key value)))

(t/deftest aspects
  (t/testing "Aspect Execution"
    (let [dhamma (d/register-dhamma! :verify-value :test
                                     :data {:test nil :key :test :expected true})
          aspect (d/register-dhamma! :modify-value :test
                                     :data {:key :test :value true})]
      (d/register-aspect! aspect [:verify-value])
      (d/occur! dhamma))))
