aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorYuan Fu2023-04-13 15:03:05 -0700
committerYuan Fu2023-04-13 15:08:51 -0700
commit361c5fc2d8e52d70aa58956c57eaef9495881197 (patch)
tree31c1573058144e6a70515b0198f1c2e7cf34e8bb /test
parenta5eb9f6ad4e6f5a2819b540a477f1e889f6ef355 (diff)
downloademacs-361c5fc2d8e52d70aa58956c57eaef9495881197.tar.gz
emacs-361c5fc2d8e52d70aa58956c57eaef9495881197.zip
Support more predicates in tree-sitter search functions
Right now we support regexp strings and predicate functions for the PRED argument. This change adds support for (not ...) (or ...) and (regexp . pred) predicates. I still need to find a place to document the supported shapes of a predicate. * src/treesit.c (treesit_traverse_validate_predicate): New function. (treesit_traverse_match_predicate): Support more predicate shapes. (treesit_search_dfs): (treesit_search_forward) (treesit_build_sparse_tree): Fix docstring (unrelated to this change). (Ftreesit_search_subtree) (Ftreesit_search_forward) (Ftreesit_induce_sparse_tree): Use the new function to validate predicate shape. (syms_of_treesit): New error Qtreesit_invalid_predicate. * test/src/treesit-tests.el: (treesit--ert-search-setup): Add edebug declaration. (treesit-search-forward-predicate) (treesit-search-forward-predicate-invalid-predicate): New tests.
Diffstat (limited to 'test')
-rw-r--r--test/src/treesit-tests.el53
1 files changed, 53 insertions, 0 deletions
diff --git a/test/src/treesit-tests.el b/test/src/treesit-tests.el
index ac5e6f1e08c..26a21c34152 100644
--- a/test/src/treesit-tests.el
+++ b/test/src/treesit-tests.el
@@ -257,6 +257,7 @@
257(defmacro treesit--ert-search-setup (&rest body) 257(defmacro treesit--ert-search-setup (&rest body)
258 "Setup macro used by `treesit-search-forward' and friends. 258 "Setup macro used by `treesit-search-forward' and friends.
259BODY is the test body." 259BODY is the test body."
260 (declare (debug (&rest form)))
260 `(with-temp-buffer 261 `(with-temp-buffer
261 (let (parser root array) 262 (let (parser root array)
262 (progn 263 (progn
@@ -332,6 +333,58 @@ BODY is the test body."
332 do (should (equal (treesit-node-text cursor) 333 do (should (equal (treesit-node-text cursor)
333 text))))) 334 text)))))
334 335
336(ert-deftest treesit-search-forward-predicate ()
337 "Test various form of supported predicates in search functions."
338 (skip-unless (treesit-language-available-p 'json))
339 (treesit--ert-search-setup
340 ;; The following tests are adapted from `treesit-search-forward'.
341
342 ;; Test `or'
343 (cl-loop for cursor = (treesit-node-child array 0)
344 then (treesit-search-forward cursor `(or "number" ,(rx "["))
345 nil t)
346 for text in '("[" "[" "1" "2" "3"
347 "[" "4" "5" "6"
348 "[" "7" "8" "9")
349 while cursor
350 do (should (equal (treesit-node-text cursor) text)))
351 ;; Test `not' and `or'
352 (cl-loop for cursor = (treesit-node-child array 0)
353 then (treesit-search-forward cursor
354 `(not (or "number" ,(rx "[")))
355 nil t)
356 for text in '("[" "," "," "]"
357 "[1,2,3]" ","
358 "," "," "]"
359 "[4,5,6]" ","
360 "," "," "]"
361 "[7,8,9]" "]"
362 "[[1,2,3], [4,5,6], [7,8,9]]")
363 while cursor
364 do (should (equal (treesit-node-text cursor) text)))
365 ;; Test (regexp . function)
366 (cl-labels ((is-odd (string)
367 (and (eq 1 (length string))
368 (cl-oddp (string-to-number string)))))
369 (cl-loop for cursor = (treesit-node-child array 0)
370 then (treesit-search-forward cursor '("number" . is-odd)
371 nil t)
372 for text in '("[" "1" "3" "5" "7" "9")
373 while cursor
374 do (should (equal (treesit-node-text cursor) text))))))
375
376(ert-deftest treesit-search-forward-predicate-invalid-predicate ()
377 "Test tree-sitter's ability to detect invalid predicates."
378 (skip-unless (treesit-language-available-p 'json))
379 (treesit--ert-search-setup
380 (dolist (pred '( 1 (not 1) (not "2" "3") (or) (or 1)))
381 (should-error (treesit-search-forward (treesit-node-child array 0)
382 pred)
383 :type 'treesit-invalid-predicate))
384 (should-error (treesit-search-forward (treesit-node-child array 0)
385 'not-a-function)
386 :type 'void-function)))
387
335(ert-deftest treesit-cursor-helper-with-missing-node () 388(ert-deftest treesit-cursor-helper-with-missing-node ()
336 "Test treesit_cursor_helper with a missing node." 389 "Test treesit_cursor_helper with a missing node."
337 (skip-unless (treesit-language-available-p 'json)) 390 (skip-unless (treesit-language-available-p 'json))