A JavaScript development environment for Emacs https://indium.readthedocs.io
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

139 lines
4.6 KiB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. ;;; test-helper.el --- Helpers for running Indium tests -*- lexical-binding: t; -*-
  2. ;; Copyright (C) 2016-2017 Nicolas Petton
  3. ;; Author: Nicolas Petton <nicolas@petton.fr>
  4. ;; Keywords: convenience
  5. ;; This program is free software; you can redistribute it and/or modify
  6. ;; it under the terms of the GNU General Public License as published by
  7. ;; the Free Software Foundation, either version 3 of the License, or
  8. ;; (at your option) any later version.
  9. ;; This program is distributed in the hope that it will be useful,
  10. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. ;; GNU General Public License for more details.
  13. ;; You should have received a copy of the GNU General Public License
  14. ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. ;;; Commentary:
  16. ;; This package provides helpers for running Indium tests.
  17. ;;; Code:
  18. (require 'seq)
  19. (require 'map)
  20. (when (require 'undercover nil t)
  21. (setq undercover-force-coverage t)
  22. (undercover "*.el" (:exclude "run-lint.el" "test/*.el")))
  23. (advice-add 'undercover-report :after #'print-coverage-report-safe)
  24. (defun print-coverage-report-safe (&rest _)
  25. (ignore-errors
  26. (print-coverage-report)))
  27. (defun print-coverage-report ()
  28. (let* ((coverage (apply #'seq-concatenate 'list
  29. (seq-map (lambda (src)
  30. (let ((coverage (map-elt src 'coverage)))
  31. (seq-filter #'identity coverage)))
  32. (map-elt (json-read-file "/tmp/undercover_coveralls_report") 'source_files))))
  33. (covered-lines (seq-filter (lambda (line)
  34. (not (zerop line)))
  35. coverage))
  36. (percentage (round (* (/ (seq-length covered-lines) (seq-length coverage) 1.0) 100))))
  37. (message "%d%% covered" percentage)))
  38. (defmacro with-js2-buffer (contents &rest body)
  39. "Evaluate BODY.
  40. BODY is evaluated with the current buffer set to a JavaScript
  41. buffer in `js2-mode' with CONTENTS."
  42. (declare (indent 1))
  43. `(with-temp-buffer
  44. (insert ,contents)
  45. (goto-char (point-max))
  46. (js2-mode)
  47. (js2-parse)
  48. ,@body))
  49. (defmacro with-temp-workspace-file (&rest body)
  50. "Evaluate BODY.
  51. During the evaluation of BODY, `indium-workspace-file' is set to
  52. a temporary file, which is removed afterwards."
  53. (declare (indent 0))
  54. `(let ((indium-workspace-file (make-temp-file "indium-workspace.el")))
  55. (prog1
  56. (progn ,@body)
  57. (ignore-errors (delete-file indium-workspace-file nil)))))
  58. (defmacro with-indium-connection (connection &rest body)
  59. "Evaluate BODY with CONNECTION as the indium-current-connection."
  60. (declare (indent 1))
  61. `(let ((indium-current-connection ,connection))
  62. ,@body))
  63. (defmacro with-fake-indium-connection (&rest body)
  64. "Evaluate BODY with an indium connection with a fake backend."
  65. (declare (indent 0))
  66. `(with-indium-connection (make-indium-connection :backend 'fake)
  67. ,@body))
  68. (defmacro with-nodejs-connection (&rest body)
  69. "Run BODY within a NodeJS connection on a process on fixtures/test.js."
  70. (declare (indent 0))
  71. `(progn
  72. (ignore-errors (exec-path-from-shell-initialize))
  73. (indium-run-node "node fixtures/test.js")
  74. (wait-for-repl-buffer)
  75. ,@body
  76. (kill-nodejs-process)))
  77. (defun wait-for-repl-buffer (&optional retry)
  78. (unless retry (setq retry 10))
  79. (sleep-for 0.2)
  80. (unless (or (get-buffer (indium-repl-buffer-name))
  81. (= retry 0))
  82. (wait-for-repl-buffer (1- retry)))
  83. (sleep-for 0.2))
  84. (defun kill-nodejs-process ()
  85. "Kill the nodejs process if any."
  86. (when-let ((buf (get-buffer "*node process*")))
  87. (when-let ((process (get-buffer-process buf)))
  88. (set-process-query-on-exit-flag process nil))
  89. (kill-buffer buf))
  90. (ignore-errors
  91. (indium-quit)))
  92. (defmacro with-repl-buffer (&rest body)
  93. "Execute BODY within a REPL buffer with a NodeJS connection."
  94. (declare (indent 0))
  95. `(with-nodejs-connection
  96. (with-current-buffer (indium-repl-buffer-name)
  97. ,@body)))
  98. (defun repl-eval (expression)
  99. "Send EXPRESSION to be evaluated.
  100. Onece EXPRESSION has been sent for evaluation, sleep for 500ms to
  101. give time for the runtime to send a response."
  102. (insert expression)
  103. (press-and-sleep-for "RET" 1))
  104. (defun press (keybinding)
  105. "Call interactively the command bound to KEYBINDING."
  106. (call-interactively (key-binding (kbd keybinding))))
  107. (defun press-and-sleep-for (keybinding seconds)
  108. "Call `(press KEYBINDING)` and sleep for SECONDS."
  109. (press keybinding)
  110. (sleep-for seconds))
  111. (provide 'test-helper)
  112. ;;; test-helper.el ends here