GTest

RTags is a package that indexes C/C++ code. Normally LSP is good enough for source code navigation for me, but I use it to jump to failed google tests. Based on a test name from a test run like Foo.bar, we know that the resulting symbol is Foo_bar_Test::TestBody.

So we use RTags from within the compilation output buffer to locate that within the source.

First, install RTags as per their instructions. Then hook it into your system, I've used a user-systemd-unit in ~/.config/systemd/user/rdm.service as follows:

[Unit]
PartOf=graphical-session.target
After=graphical-session.target

[Install]
WantedBy=default.target

[Service]
ExecStart=nice -n 19 /usr/local/bin/rdm

Don't forget to systemd --user enable rdm.

Add your project with rc -J <director-with-compile_commands.json>.

Then we need to hook into the compile mode error regexpes and trigger a lookup:

(use-package rtags)
(require 'rtags)
(require 'compile)

(defun deets/gtest-file-name ()
  (setq deets/gtest-file-name-var nil)
  (setq deets/gtest-line-number-var nil)
  (let ((data (match-data)))
    (unwind-protect
        (let* ((test-class (match-string 1))
               (test-name (match-string 2))
               (symbol-name (format "%s_%s_Test::TestBody" test-class test-name)))
          (message (format "rtags: %s" symbol-name))
          (with-temp-buffer
            (when (rtags-call-rc :noerror t "--elisp" "-K" "--find-symbols" symbol-name)
              (let ((rc-output (string-split (substring (buffer-string) 1 -1) ":")))
                (message (format "deets/gtest-file-name: %s" (car rc-output)))
                (setq deets/gtest-file-name-var (car rc-output))
                (setq deets/gtest-line-number-var (cadr rc-output))))))
      (set-match-data data)))
  deets/gtest-file-name-var)

(defun deets/gtest-line-number () (message (format "deets/gtest-line-number: %s" deets/gtest-line-number-var)) (string-to-number deets/gtest-line-number-var))

(add-to-list 'compilation-error-regexp-alist 'gtest)
(add-to-list 'compilation-error-regexp-alist-alist '(gtest "^\\[  FAILED  \\] \\(\\w+\\)\\.\\(\\(\\w\\|_\\)+\\).*$" deets/gtest-file-name deets/gtest-line-number))

Now you can just navigate to the failed test using the usual means in a compilation buffer.

Created: 2024-10-05 Sa 14:04

Validate