 (p/defpattern constant-pattern [(X x)])
 (def p (p/parse-pattern '[(X x)]))
 
-;; FIXME: Clean up
-(t/deftest map-matcher-without-binding-test
-  (let [k "my-value"]
-    ((p/map-matcher [(:k 23)] (t/is (= "my-value" k))) {:k 23})))
-
-(t/deftest closes-over-outer-variables-test
-  (t/testing "with compare-fn"
+(t/deftest map-matcher-scope-test
+
+  (t/testing "let-variable is not overwritten if there is no binding"
+    (let [k "my-value"]
+      ((p/map-matcher [(:k 23)] (t/is (= "my-value" k))) {:k 23})))
+  (t/testing "let-variable is overwritten if there is a binding"
+    (let [k "my-value"]
+      ((p/map-matcher [(:k 23 :as k)] (t/is (= 23 k))) {:k 23})))
+  (t/testing "let-variable used within compare-fn"
     (let [evt {"X" "x"}]
       (t/is (= "x"
                ((p/map-matcher [(X (:compare-fn #(= % (get evt "X"))))] x)
                 evt)))))
-  (t/testing "as local constant"
+  (t/testing "local: let-variable used as constant"
     (let [x   "x"
           evt {"X" x}]
       (t/is (= x
                ((p/map-matcher [(X x)] x)
                 evt)))))
-  (t/testing "as global constant"
+  (t/testing "global: def-variable used as constant"
     (let [evt {"X" x}]
       (t/is (= x
                ((p/map-matcher [(X x)] x)
                 evt)))))
-  ;; FIXME: Docu below the same, tests different
-  (t/testing "as constant with global defpattern"
+  (t/testing "global: defpattern used as constant"
     (let [x   "x"
           evt {"X" x}]
       (t/is (= x
                ((p/map-matcher constant-pattern x)
                 evt)))))
-  (t/testing "as constant with global parse-pattern"
+  (t/testing "global: def-parse-pattern as constant"
     (let [evt {"X" x}]
       (t/is (= x
                ((p/map-matcher p x)
                 evt)))))
-  (t/testing "as constant with global defpattern"
+  (t/testing "local: defpattern as constant"
     (let [x   "x"
           evt {"X" x}]
       (p/defpattern p [("X" x)])
       (t/is (= x
                ((p/map-matcher p x)
                 evt)))))
+  ;; FIXME: What's wrong with this test?
   #_(t/testing "as constant with local parse-pattern"
     (let [x   "x"
           evt {"X" x}

    (t/is (= {:x {:y {:z "b"}}}
             (p/clause->lhs {} (p/path-matches-without-binding-clause [:x :y :z] (p/match-const "b")))))))

(t/deftest path-matches-with-binding-clause->rhs-match-test
  (t/is (= `[~(symbol "z") (get-in {:x {:y {:z "b"}}} [:x :y :z] "b")]
           (p/path-matches-with-binding-clause->rhs-match {:x {:y {:z "b"}}}

   [(:x (:compare-fn odd?))] ::odd))

(t/deftest map-matcher-predicate-test
  (t/testing "Predicates"
    (t/is (= ::even (predicate-matcher {:x 42})))
    (t/is (= ::odd (predicate-matcher {:x 41})))
    (t/is (= ::string (predicate-matcher {:x "string"})))
    (t/is (= ::boolean (predicate-matcher {:x true}))))
  (t/testing "Polymorphism: works with a pattern record"
    (t/is (= ::even
             ((p/map-matcher predicate-pattern ::even)
              {:x 42}))))
  (t/testing "Polymorphism: works with pattern syntax"
    (t/is (= ::even
             ((p/map-matcher [(:x (:compare-fn even?))] ::even)
              {:x 42})))))
