Skip to content

Commit

Permalink
eclimd-start not error outside project, dont hang on eclimd-stop
Browse files Browse the repository at this point in the history
  • Loading branch information
nverno committed Sep 26, 2018
1 parent 99fda18 commit 64448e8
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 70 deletions.
2 changes: 1 addition & 1 deletion eclim-common.el
Expand Up @@ -765,7 +765,7 @@ containing non-ASCII characters)."
The refresh is only triggered if auto-updated is enabled.
The delay is specified by `eclim-problems-refresh-delay'."
(when (and (not eclim--is-completing)
(eclim--project-dir)
(ignore-errors (eclim--project-dir)) ;dont error when not in project
eclim-autoupdate-problems)
(setq eclim--problems-project (eclim-project-name))
(setq eclim--problems-file buffer-file-name)
Expand Down
4 changes: 3 additions & 1 deletion eclimd.el
Expand Up @@ -222,6 +222,7 @@ corresponding return value as argument."
(unwind-protect
(progn
(add-hook 'eclimd--process-event-functions closure)
;; don't hang during `eclimd-stop'
(while (not finished-p)
(accept-process-output eclimd-process))
(unless terminated-p output))
Expand Down Expand Up @@ -324,7 +325,8 @@ Also kill the *eclimd*-buffer and remove any hooks added by
(when eclimd-process
(when (eclim--connected-p)
(eclim/execute-command "shutdown")
(eclimd--match-process-output "Process eclimd finished"))
(eclimd--match-process-output
"Process eclimd finished" (called-interactively-p 'any)))
(delete-process eclimd-process)
(setq eclimd-process nil))
(when eclimd-process-buffer
Expand Down
165 changes: 97 additions & 68 deletions test/specs/test-eclimd.el
Expand Up @@ -22,7 +22,7 @@
;; Buttercup tests for eclimd.el.

;;; Code:

(require 'buttercup)
(require 'undercover-init.el)
(require 'eclimd)

Expand Down Expand Up @@ -52,72 +52,101 @@ the following forms:
(lambda (&rest _) current-status))))

(describe "eclimd"
(describe "eclimd--match-process-output"
(it "executes callback before returning when the supplied regexp matches the output"
(test-eclimd--fake-process-events
'("a string\n"
"a different string to be matched plus bonus\n"
"some more text"))
(let ((marker nil))
(eclimd--match-process-output "string to be matched"
nil
(lambda (&rest _) (setq marker t)))
(expect marker :to-be-truthy)))
(it "returns when the regexp matches inside the concatinated output"
(test-eclimd--fake-process-events
'("a string\n"
"a different string "
"to be "
"matched\n"
"some more text"))
(eclimd--match-process-output "string to be matched" nil nil))
(it "returns the concatinated output until the match and passes it to the callback"
;; This one is a little tricky since it is not specified
;; how much of the output is included in the return
;; value. It may or may not end immediatly after the
;; string to be matched.
(let* ((events '("a string\n"
"a different string "
"to be "
"matched"))
(expected-output (apply 'concat events))
(marker nil))
(test-eclimd--fake-process-events events)
(expect (eclimd--match-process-output
"string to be matched" nil
(lambda (output)
(expect output :to-equal expected-output)
(setq marker t)))
:to-equal expected-output)
;; Ensure the callback was actually executed.
(expect marker :to-be-truthy))))
(describe "eclimd--await-connection"
(it "executes callback before returning when async is nil"
(test-eclimd--fake-process-events
'("/usr/bin/java -version\njava version \"1.8.0_112\"\n"
"2017-02-27 [org.eclim.eclipse.EclimDaemon] Eclim Server "
"Started on: 127.0.0.1:9091\n"))
(let ((marker nil))
(eclimd--await-connection nil (lambda () (setq marker t)))
(expect marker :to-be-truthy)))
(it "does not execute callback when eclimd fails to start"
(test-eclimd--fake-process-events
'("/usr/bin/java -version\n"
(:set-status . exit)
(:state-change . "exited abnormally with code 1\n")))
(let ((marker nil))
(eclimd--await-connection nil (lambda () (setq marker t)))
(expect marker :not :to-be-truthy)))
(it "executes callback after a match when ASYNC is t"
(test-eclimd--fake-process-events
'("First string "
"Eclim Server Started on: 127.0.0.1:9091"))
(let ((marker nil))
(eclimd--await-connection t (lambda () (setq marker t)))
(expect marker :not :to-be-truthy)
(accept-process-output) ; Pops the first string off the list.
(expect marker :not :to-be-truthy)
(accept-process-output) ; Pops the second, matching string.
(expect marker :to-be-truthy)))))
(describe "eclimd--match-process-output"
(it "executes callback before returning when the supplied regexp matches \
the output"
(test-eclimd--fake-process-events
'("a string\n"
"a different string to be matched plus bonus\n"
"some more text"))
(let ((marker nil))
(eclimd--match-process-output "string to be matched"
nil
(lambda (&rest _) (setq marker t)))
(expect marker :to-be-truthy)))
(it "returns when the regexp matches inside the concatinated output"
(test-eclimd--fake-process-events
'("a string\n"
"a different string "
"to be "
"matched\n"
"some more text"))
(eclimd--match-process-output "string to be matched" nil nil))
(it "returns the concatinated output until the match and passes it to the \
callback"
;; This one is a little tricky since it is not specified
;; how much of the output is included in the return
;; value. It may or may not end immediatly after the
;; string to be matched.
(let* ((events '("a string\n"
"a different string "
"to be "
"matched"))
(expected-output (apply 'concat events))
(marker nil))
(test-eclimd--fake-process-events events)
(expect (eclimd--match-process-output
"string to be matched" nil
(lambda (output)
(expect output :to-equal expected-output)
(setq marker t)))
:to-equal expected-output)
;; Ensure the callback was actually executed.
(expect marker :to-be-truthy))))

(describe "eclimd--await-connection"
(it "executes callback before returning when async is nil"
(test-eclimd--fake-process-events
'("/usr/bin/java -version\njava version \"1.8.0_112\"\n"
"2017-02-27 [org.eclim.eclipse.EclimDaemon] Eclim Server "
"Started on: 127.0.0.1:9091\n"))
(let ((marker nil))
(eclimd--await-connection nil (lambda () (setq marker t)))
(expect marker :to-be-truthy)))
(it "does not execute callback when eclimd fails to start"
(test-eclimd--fake-process-events
'("/usr/bin/java -version\n"
(:set-status . exit)
(:state-change . "exited abnormally with code 1\n")))
(let ((marker nil))
(eclimd--await-connection nil (lambda () (setq marker t)))
(expect marker :not :to-be-truthy)))
(it "executes callback after a match when ASYNC is t"
(test-eclimd--fake-process-events
'("First string "
"Eclim Server Started on: 127.0.0.1:9091"))
(let ((marker nil))
(eclimd--await-connection t (lambda () (setq marker t)))
(expect marker :not :to-be-truthy)
(accept-process-output) ; Pops the first string off the list.
(expect marker :not :to-be-truthy)
(accept-process-output) ; Pops the second, matching string.
(expect marker :to-be-truthy)))))

(describe "eclimd start/stop"
(assume (executable-find "/bin/true") nil) ;dummy program
(before-each
(setq eclimd-executable "/bin/true"
eclim-executable "/bin/true"
eclimd-wait-for-process t
inhibit-message t))
(after-each
(ignore-errors (kill-process eclimd-process))
(remove-hook 'kill-emacs-hook 'eclimd-stop))

(describe "eclimd-start"
(it "doesn't error when not started in eclim project"
(expect (eclimd-start "~/workspace") :not :to-throw)))

(describe "eclimd-stop"
(it "doesn't hang when called interactively and cleans up after itself"
(let ((noninteractive nil) marker)
(eclimd-start "~workspace/")
(with-timeout (1 (setq marker t))
(call-interactively 'eclimd-stop))
(expect marker :not :to-be-truthy)
(when (not marker)
(expect (buffer-live-p eclimd-process-buffer) :not :to-be-truthy)
(expect 'eclimd-stop :not :to-be-in kill-emacs-hook))))))

;;; test-eclimd.el ends here

0 comments on commit 64448e8

Please sign in to comment.