;;; test.el --- test -*- lexical-binding: t -*- ;;; Code: (defun test-debug (proc &rest args) "Print `current-thread' and ARGS in timestamped `message'." (message "[%s] %s" (format-time-string "%T:%3N") (mapconcat #'prin1-to-string `(,(current-thread) ,(process-thread proc) ,@args) " "))) (defun test-sentinel (proc msg) "Kill buffer of PROC when it exits." (test-debug proc 'sentinel (process-status proc) (substring msg 0 -1)) (and (not (eq (process-status proc) 'run)) (buffer-live-p (process-buffer proc)) (kill-buffer (process-buffer proc)))) (defun test-slave () "Create an asynchronous process and wait for it to exit." (let ((proc (make-process :name "test" :buffer (generate-new-buffer " *test*") :command '("wget" "-qO-" "https://en.wikipedia.org/wiki/Emacs") :connection-type 'pipe :sentinel #'test-sentinel))) (while (eq (process-status proc) 'run) (test-debug proc 'accept-output (accept-process-output proc 5))) (test-debug proc 'exit (process-status proc) (process-exit-status proc)))) (defun test-master (async) "Successively run `test-slave'. With non-nil ASYNC, use a new thread for each invocation." (if async (progn (dotimes (i 5) (make-thread #'test-slave (format "test-%d" i))) (while (cdr (all-threads) (thread-join (cadr (all-threads)))))) (dotimes (i 5) (test-slave)))) (defun test-job (async) "Successively run `test-slave'. Like `test-master', but avoid blocking interactive sessions by running `test-master' in its own thread." (if noninteractive (test-master async) (make-thread (apply-partially #'test-master async) "test-master"))) (defun test-threads () "Run `test-master' with threads." (test-job t)) (defun test-no-threads () "Run `test-master' without threads." (test-job nil)) ;;; test.el ends here