|
| 1 | +;;; tsc-dyn-get-tests.el --- Tests for tsc-dyn-get.el -*- lexical-binding: t; coding: utf-8 -*- |
| 2 | + |
| 3 | +;; Copyright (C) 2021 Tuấn-Anh Nguyễn |
| 4 | +;; |
| 5 | +;; Author: Tuấn-Anh Nguyễn <ubolonton@gmail.com> |
| 6 | +;; SPDX-License-Identifier: MIT |
| 7 | + |
| 8 | +;;; Commentary: |
| 9 | + |
| 10 | +;; Tests for the code that downloads/builds and loads `tsc-dyn'. Since Emacs |
| 11 | +;; cannot unload dynamic modules, each test needs to run in a fresh Emacs |
| 12 | +;; process. These are considered expensive "integration tests" that should be |
| 13 | +;; run once in a while, not during normal development. |
| 14 | + |
| 15 | +(require 'async) |
| 16 | + |
| 17 | +(eval-when-compile |
| 18 | + (require 'subr-x)) |
| 19 | + |
| 20 | +(defun -remove-tsc-from-load-path () |
| 21 | + "Remove directories containing `tsc' so that we can properly test. |
| 22 | +This is mainly needed because we use `tree-sitter''s env, which depends on |
| 23 | +`tsc'." |
| 24 | + (dolist (lib '("tsc" "tsc-dyn")) |
| 25 | + (while |
| 26 | + (when-let* ((loc (locate-library lib)) |
| 27 | + (extra-dir (file-name-directory loc))) |
| 28 | + (setq load-path (delete (file-name-as-directory extra-dir) load-path)) |
| 29 | + (setq load-path (delete (directory-file-name extra-dir) load-path)))))) |
| 30 | + |
| 31 | +(defvar *root-dir* |
| 32 | + (file-name-directory |
| 33 | + (directory-file-name |
| 34 | + (file-name-directory |
| 35 | + (locate-library "tsc-dyn-get-tests.el"))))) |
| 36 | + |
| 37 | +(defmacro -with-sub-eval (&rest body) |
| 38 | + (declare (indent 0)) |
| 39 | + `(async-sandbox |
| 40 | + (lambda () |
| 41 | + (add-to-list 'load-path (concat ,*root-dir* "tests")) |
| 42 | + (load "tsc-dyn-get-tests.el") |
| 43 | + (-remove-tsc-from-load-path) |
| 44 | + ,@body))) |
| 45 | + |
| 46 | +(defmacro -sub-funcall (sym &rest args) |
| 47 | + (declare (indent 1)) |
| 48 | + `(-with-sub-eval |
| 49 | + (funcall ',sym ,@args))) |
| 50 | + |
| 51 | +(defmacro -with-fresh-tsc (&rest body) |
| 52 | + `(let ((default-directory (file-name-as-directory |
| 53 | + (make-temp-file "tsc-dyn-get-tests." :dir)))) |
| 54 | + (message "Fresh copy of `tsc' in %s" default-directory) |
| 55 | + (dolist (file '("tsc.el" "tsc-dyn-get.el" "tsc-obsolete.el" |
| 56 | + "src" "Cargo.toml" "Cargo.lock" ".cargo")) |
| 57 | + (let ((path (concat (file-name-as-directory |
| 58 | + (concat *root-dir* "core")) |
| 59 | + file))) |
| 60 | + (if (file-directory-p path) |
| 61 | + (copy-directory path file) |
| 62 | + (copy-file path file)))) |
| 63 | + (prog1 |
| 64 | + (eval (append |
| 65 | + `(-with-sub-eval |
| 66 | + (add-to-list 'load-path ,default-directory)) |
| 67 | + ',body)) |
| 68 | + (delete-directory default-directory :recursive)))) |
| 69 | + |
| 70 | +(defmacro -with-call-count (sym &rest body) |
| 71 | + (declare (indent 1)) |
| 72 | + `(let* ((cnt 0) |
| 73 | + (incr (lambda (&rest _args) (setq cnt (1+ cnt))))) |
| 74 | + (advice-add ,sym :before incr) |
| 75 | + (cons |
| 76 | + (unwind-protect |
| 77 | + ,@body |
| 78 | + (advice-remove ,sym incr)) |
| 79 | + cnt))) |
| 80 | + |
| 81 | +(ert-deftest tsc-dyn-get:no-sources () |
| 82 | + (should-error (-with-fresh-tsc |
| 83 | + (setq tsc-dyn-get-from nil) |
| 84 | + (require 'tsc)) |
| 85 | + :type 'file-missing)) |
| 86 | + |
| 87 | +(ert-deftest tsc-dyn-get:only-github () |
| 88 | + (should (equal (-with-fresh-tsc |
| 89 | + (setq tsc-dyn-get-from '(:github)) |
| 90 | + (-with-call-count 'tsc-dyn-get--github |
| 91 | + (require 'tsc))) |
| 92 | + '(tsc . 1)))) |
| 93 | + |
| 94 | +(ert-deftest tsc-dyn-get:only-compilation () |
| 95 | + (ert-skip "?") |
| 96 | + (should (equal (-with-fresh-tsc |
| 97 | + (setq tsc-dyn-get-from '(:compilation)) |
| 98 | + (-with-call-count 'tsc-dyn-get--build |
| 99 | + (require 'tsc))) |
| 100 | + '(tsc . 1)))) |
| 101 | + |
| 102 | +;;; Code: |
| 103 | +;; Local Variables: |
| 104 | +;; no-byte-compile: t |
| 105 | +;; End: |
0 commit comments