branch: elpa/clojure-ts-mode
commit b239b1cc6e78d5a8dfc2de092b1a7f2cb516a1ac
Author: Bozhidar Batsov <[email protected]>
Commit: Bozhidar Batsov <[email protected]>

    Add a :to-have-face matcher for font-lock tests
    
    The face helpers asserted with a bare (expect ACTUAL :to-equal EXPECTED),
    so a failure read "Expected face-a to equal face-b" with no hint of which
    token was wrong. Add a :to-have-face matcher that resolves a substring
    (searched from point), a position, or a (START END) range and reports
    e.g. "Expected \"def\" to have face font-lock-string-face, but it had
    font-lock-keyword-face". Route expect-face-at and clojure-ts--check-faces
    (hence when-fontifying-it) through it, so the whole font-lock suite gains
    the better messages.
---
 test/clojure-ts-mode-font-lock-test.el | 48 +++++++++++++++++++++++++++-------
 1 file changed, 39 insertions(+), 9 deletions(-)

diff --git a/test/clojure-ts-mode-font-lock-test.el 
b/test/clojure-ts-mode-font-lock-test.el
index 463d30c2b7..be008f8ccd 100644
--- a/test/clojure-ts-mode-font-lock-test.el
+++ b/test/clojure-ts-mode-font-lock-test.el
@@ -48,6 +48,41 @@ Assumes the current buffer is already fontified."
         start-face
       'various-faces)))
 
+(defun clojure-ts--face-target (target)
+  "Resolve TARGET to a (START END DESCRIPTION) list in the current buffer.
+TARGET is a substring (searched for from point), a position, or a
+\(START END) range.  Return nil when a substring cannot be found."
+  (cond
+   ((stringp target)
+    (when (search-forward target nil t)
+      (list (- (point) (length target)) (1- (point)) (format "%S" target))))
+   ((integerp target)
+    (list target target (format "position %d" target)))
+   ((and (consp target) (integerp (car target)))
+    (list (nth 0 target) (nth 1 target)
+          (format "range %d-%d" (nth 0 target) (nth 1 target))))))
+
+(buttercup-define-matcher :to-have-face (target expected)
+  "Check that TARGET is fontified with face EXPECTED in the current buffer.
+TARGET is a substring (searched for from point), a position, or a
+\(START END) range.  Only meaningful after the buffer has been fontified.
+On failure the message names the text and the face that was found."
+  (let* ((target (funcall target))
+         (expected (funcall expected))
+         (resolved (clojure-ts--face-target target)))
+    (if (not resolved)
+        (cons nil (format "Expected to find %S in the buffer to check its \
+face, but it was not present" target))
+      (let* ((start (nth 0 resolved))
+             (end (nth 1 resolved))
+             (desc (nth 2 resolved))
+             (actual (clojure-ts--uniform-face start end)))
+        (cons (equal actual expected)
+              (if (equal actual expected)
+                  (format "Expected %s not to have face %S" desc expected)
+                (format "Expected %s to have face %S, but it had %S"
+                        desc expected actual)))))))
+
 (defun clojure-ts-get-face-at (start end content)
   "Get the face between START and END in CONTENT."
   (with-fontified-clojure-ts-buffer content
@@ -64,19 +99,14 @@ that repeated substrings resolve naturally in document 
order."
     (dolist (spec face-specs)
       (pcase spec
         (`(,(and (pred stringp) substr) ,face)
-         (let ((found (search-forward substr nil t)))
-           (expect found :not :to-be nil)
-           (when found
-             (let* ((end (1- (point)))
-                    (start (- (point) (length substr))))
-               (expect (clojure-ts--uniform-face start end)
-                       :to-equal face)))))
+         (expect substr :to-have-face face))
         (`(,(and (pred numberp) start) ,end ,face)
-         (expect (clojure-ts--uniform-face start end) :to-equal face))))))
+         (expect (list start end) :to-have-face face))))))
 
 (defun expect-face-at (content start end face)
   "Expect face in CONTENT between START and END to be equal to FACE."
-  (expect (clojure-ts-get-face-at start end content) :to-equal face))
+  (with-fontified-clojure-ts-buffer content
+    (expect (list start end) :to-have-face face)))
 
 (defun expect-faces-at (content &rest faces)
   "Expect FACES in CONTENT.

Reply via email to