被 region 坑了几个小时

我有两个函数使用正常,考虑到它们依赖的函数可能会改变,于是写了几个测试来保障这两个函数。然而测试用例在终端运行全部失败,在 Emacs 里却都通过。

一直怀疑原来的函数有错,不断修改调试,依然通不过,后来看 region-active-p 的实现,才发现问题所在。

$ emacs --batch --eval '(with-temp-buffer
  (insert "foobar")
  (goto-char 4)
  (set-mark 7)
  (print (region-active-p)))'

nil

这段代码通过 M-: 执行是返回 t 的, 关键在于 transient-mark-mode,它在 noninteractive 模式下被禁用了(导致 (region-active-p) 始终返回 nil),所以在测试用例中要开启才能通过:


$ cat /path/to/test-dummy.el
(require 'ert)

(defun dummy-set-region (beg end)
    (goto-char beg)
    (set-mark end))

(ert-deftest test-set-region ()
  (with-temp-buffer
    (insert "foobar")
    (transient-mark-mode) ;; <<--
    (dummy-set-region 4 7)
    (should (region-active-p))))

$ emacs --batch -l ert -l /path/to/test-dummy.el -f ert-run-tests-batch-and-exit
Running 1 tests (2018-09-04 13:22:32+0800, selector ‘t’)
   passed  1/1  test-set-region (0.000630 sec)

Ran 1 tests, 1 results as expected (2018-09-04 13:22:32+0800, 0.000932 sec)

5 个赞