diff options
-rw-r--r-- | cider-browse-ns.el | 9 | ||||
-rw-r--r-- | cider-classpath.el | 11 | ||||
-rw-r--r-- | cider-client.el | 137 | ||||
-rw-r--r-- | cider-interaction.el | 54 | ||||
-rw-r--r-- | cider-macroexpansion.el | 15 | ||||
-rw-r--r-- | cider-repl.el | 2 | ||||
-rw-r--r-- | nrepl-client.el | 96 | ||||
-rw-r--r-- | test/cider-tests--no-auto.el | 11 | ||||
-rw-r--r-- | test/cider-tests.el | 31 | ||||
-rw-r--r-- | test/nrepl-bencode-tests.el | 25 |
10 files changed, 199 insertions, 192 deletions
diff --git a/cider-browse-ns.el b/cider-browse-ns.el index e28d7a31..972d9fb9 100644 --- a/cider-browse-ns.el +++ b/cider-browse-ns.el @@ -93,9 +93,9 @@ ;;;###autoload (defun cider-browse-ns (namespace) "List all NAMESPACE's vars in BUFFER." - (interactive (list (completing-read "Browse namespace: " (cider--all-ns)))) + (interactive (list (completing-read "Browse namespace: " (cider-sync-request:ns-list)))) (with-current-buffer (cider-popup-buffer cider-browse-ns-buffer t) - (let ((vars (cider--ns-vars namespace))) + (let ((vars (cider-sync-request:ns-vars namespace))) (cider-browse-ns-list (current-buffer) namespace (mapcar (lambda (var) @@ -109,7 +109,7 @@ "List all loaded namespaces in BUFFER." (interactive) (with-current-buffer (cider-popup-buffer cider-browse-ns-buffer t) - (let ((names (cider--all-ns))) + (let ((names (cider-sync-request:ns-list))) (cider-browse-ns-list (current-buffer) "All loaded namespaces" (mapcar (lambda (name) @@ -134,9 +134,6 @@ (interactive "e") (cider-browse-ns-operate-on-point)) - -(define-obsolete-variable-alias 'cider-eval-and-get-value 'cider-sync-eval-and-parse "0.8.0") - (provide 'cider-browse-ns) ;;; cider-browse-ns.el ends here diff --git a/cider-classpath.el b/cider-classpath.el index 183ddba5..076378fd 100644 --- a/cider-classpath.el +++ b/cider-classpath.el @@ -79,13 +79,6 @@ (interactive "e") (cider-classpath-operate-on-point)) -(defun cider--classpath-entries () - "Return a list of classpath entries." - (plist-get - (nrepl-send-sync-request (list "op" "classpath" - "session" (nrepl-current-session))) - :value)) - ;;;###autoload (defun cider-classpath () "List all classpath entries." @@ -94,13 +87,13 @@ (cider-classpath-list (current-buffer) (mapcar (lambda (name) (cider-classpath-properties name)) - (cider--classpath-entries))))) + (cider-sync-request:classpath))))) ;;;###autoload (defun cider-open-classpath-entry () "Open a classpath entry." (interactive) - (-when-let (entry (completing-read "Classpath entries: " (cider--classpath-entries))) + (-when-let (entry (completing-read "Classpath entries: " (cider-sync-request:classpath))) (find-file-other-window entry))) (defvar cider-classpath-mouse-map (make-sparse-keymap)) diff --git a/cider-client.el b/cider-client.el index da2e9d43..9508a202 100644 --- a/cider-client.el +++ b/cider-client.el @@ -111,44 +111,6 @@ NS specifies the namespace in which to evaluate the request." ;; namespace forms are always evaluated in the "user" namespace (cider-eval input callback ns (nrepl-current-tooling-session))) -(defun cider-eval-sync (input &optional ns session) - "Send the INPUT to the nREPL server synchronously. -NS & SESSION specify the evaluation context." - (nrepl-sync-request:eval input ns session)) - -(defun cider-sync-eval-and-parse (input &optional ns session) - "Send the INPUT to the nREPL server synchronously and return the value. -NS & SESSION specify the evaluation context. The output must be a readable -Emacs list or a vector of other lists and vectors as `read' is used to -convert the output into an Emacs object." - (read (plist-get (cider-eval-sync input ns session) :value))) - -(defun cider-tooling-eval-sync (input &optional ns) - "Send the INPUT to the nREPL server using a tooling session synchronously. -NS specifies the namespace in which to evaluate the request." - (cider-eval-sync input ns (nrepl-current-tooling-session))) - -(defun cider-send-op (op attributes handler) - "Send the specified OP with ATTRIBUTES and response HANDLER." - (nrepl-send-request (append - (list "op" op - "session" (nrepl-current-session) - "ns" nrepl-buffer-ns) - attributes) - handler)) - -(defun cider-send-load-file (file-contents file-path file-name) - "Perform the nREPL \"load-file\" op. -FILE-CONTENTS, FILE-PATH and FILE-NAME are details of the file to be -loaded." - (let ((buffer (current-buffer))) - (nrepl-send-request (list "op" "load-file" - "session" (nrepl-current-session) - "file" file-contents - "file-path" file-path - "file-name" file-name) - (cider-load-file-handler buffer)))) - (defun cider-interrupt () "Interrupt any pending evaluations." (interactive) @@ -177,27 +139,100 @@ contain a `candidates' key, it is returned as is." (defun cider-var-info (var &optional all) "Return VAR's info as an alist with list cdrs. - When multiple matching vars are returned you'll be prompted to select one, unless ALL is truthy." (when (and var (not (string= var ""))) - (let ((val (plist-get (nrepl-send-sync-request - (list "op" "info" - "session" (nrepl-current-session) - "ns" (cider-current-ns) - "symbol" var)) - :value))) + (let ((val (cider-sync-request:info var))) (if all val (cider--var-choice val))))) (defun cider-member-info (class member) "Return the CLASS MEMBER's info as an alist with list cdrs." (when (and class member) - (plist-get (nrepl-send-sync-request - (list "op" "info" - "session" (nrepl-current-session) - "class" class - "member" member)) - :value))) + (cider-sync-request:info nil class member))) + + +;;; Requests + +(defun cider-request:load-file (file-contents file-path file-name) + "Perform the nREPL \"load-file\" op. +FILE-CONTENTS, FILE-PATH and FILE-NAME are details of the file to be +loaded." + (nrepl-send-request (list "op" "load-file" + "session" (nrepl-current-session) + "file" file-contents + "file-path" file-path + "file-name" file-name) + (cider-load-file-handler (current-buffer)))) + + +;;; Sync Requests +(defun cider--sync-request-value (request) + "Send sync REQUEST and return the \"value\" slot." + (cider-ensure-op-supported (lax-plist-get request "op")) + (nrepl-dict-get (nrepl-send-sync-request request) "value")) + +(defun cider-sync-request:apropos (query &optional search-ns docs-p privates-p case-sensitive-p) + "Send \"apropos\" op with args SEARCH-NS, DOCS-P, PRIVATES-P, CASE-SENSITIVE-P." + (cider--sync-request-value `("op" "apropos" + "ns" ,(cider-current-ns) + "query" ,query + ,@(when search-ns `("search-ns" ,search-ns)) + ,@(when docs-p '("docs?" "t")) + ,@(when privates-p '("privates?" "t")) + ,@(when case-sensitive-p '("case-sensitive?" "t"))))) + +(defun cider-sync-request:classpath () + "Return a list of classpath entries." + (cider--sync-request-value (list "op" "classpath" + "session" (nrepl-current-session)))) + +(defun cider-sync-request:complete (str context) + "Return a list of completions for STR using nREPL's \"complete\" op." + (cider--sync-request-value (list "op" "complete" + "session" (nrepl-current-session) + "ns" (cider-current-ns) + "symbol" str + "context" context))) + +(defun cider-sync-request:info (symbol &optional class member) + "Send \"info\" op with parameters SYMBOL or CLASS and MEMBER." + (cider--sync-request-value `("op" "info" + "session" ,(nrepl-current-session) + "ns" ,(cider-current-ns) + ,@(when symbol (list "symbol" symbol)) + ,@(when class (list "class" class)) + ,@(when member (list "member" member))))) + +(defun cider-sync-request:macroexpand (expander expr &optional display-namespaces) + "Macroexpand, using EXPANDER, the given EXPR. +The default for DISPLAY-NAMESPACES is taken from +`cider-macroexpansion-display-namespaces'." + (cider-ensure-op-supported "macroexpand") + (-> (list "op" "macroexpand" + "expander" expander + "code" expr + "ns" (cider-current-ns) + "display-namespaces" + (or display-namespaces + (symbol-name cider-macroexpansion-display-namespaces))) + (nrepl-send-sync-request) + (nrepl-dict-get "expansion"))) + +(defun cider-sync-request:ns-list () + "Get a list of the available namespaces." + (cider--sync-request-value (list "op" "ns-list" + "session" (nrepl-current-session)))) + +(defun cider-sync-request:ns-vars (ns) + "Get a list of the vars in NS." + (cider--sync-request-value (list "op" "ns-vars" + "session" (nrepl-current-session) + "ns" ns))) + +(defun cider-sync-request:resource (name) + "Perform nREPL \"resource\" op with resource name NAME." + (cider--sync-request-value (list "op" "resource" + "name" name))) (provide 'cider-client) diff --git a/cider-interaction.el b/cider-interaction.el index a53b1104..fdd67885 100644 --- a/cider-interaction.el +++ b/cider-interaction.el @@ -150,8 +150,7 @@ which will use the default REPL connection." '("classpath" "complete" "info" "inspect-start" "inspect-refresh" "inspect-pop" "inspect-push" "inspect-reset" - "macroexpand" "macroexpand-1" "macroexpand-all" - "ns-list" "ns-vars" + "macroexpand" "ns-list" "ns-vars" "resource" "stacktrace" "toggle-trace" "undef") "A list of nREPL ops required by CIDER to function properly. @@ -697,9 +696,7 @@ otherwise `switch-to-buffer'." When called interactively, this operates on point." (interactive (list (thing-at-point 'filename))) (cider-ensure-op-supported "resource") - (-if-let* ((resource (-> (list "op" "resource" "name" path) - (nrepl-send-sync-request) - (plist-get :value))) + (-if-let* ((resource cider-sync-request:resource path) (buffer (cider-find-file resource))) (cider-jump-to buffer line) (message "Cannot find resource %s" path))) @@ -774,16 +771,8 @@ form, with symbol at point replaced by __prefix__." context))) (defun cider-complete (str) - "Return a list of completions for STR using nREPL's \"complete\" op." - (cider-ensure-op-supported "complete") - (plist-get - (nrepl-send-sync-request - (list "op" "complete" - "session" (nrepl-current-session) - "ns" (cider-current-ns) - "symbol" str - "context" (cider-completion-get-context))) - :value)) + "Complete STR with context at point." + (cider-sync-request:complete str (cider-completion-get-context))) (defun cider-annotate-symbol (symbol) "Append extra information to SYMBOL's name. @@ -1330,7 +1319,7 @@ If invoked with a PREFIX argument, print the result in the current buffer." (interactive) (let ((last-sexp (cider-last-sexp))) ;; we have to be sure the evaluation won't result in an error - (cider-eval-sync last-sexp) + (nrepl-sync-request:eval last-sexp) ;; seems like the sexp is valid, so we can safely kill it (backward-kill-sexp) (cider-interactive-eval-print last-sexp))) @@ -1401,7 +1390,7 @@ If invoked with a prefix ARG eval the expression after inserting it." (defun cider-ping () "Check that communication with the server works." (interactive) - (message "%s" (cider-sync-eval-and-parse "\"PONG\""))) + (message (read (nrepl-sync-request:eval "\"PONG\"" nil nil t)))) (defun clojure-enable-cider () "Turn on CIDER mode (see command `cider-mode'). @@ -1449,21 +1438,6 @@ See command `cider-mode'." (unless (cider-connected-p) (cider-disable-on-existing-clojure-buffers))) -(defun cider--all-ns () - "Get a list of the available namespaces." - (-> (list "op" "ns-list" - "session" (nrepl-current-session)) - (nrepl-send-sync-request) - (plist-get :value))) - -(defun cider--ns-vars (ns) - "Get a list of the vars in NS." - (-> (list "op" "ns-vars" - "session" (nrepl-current-session) - "ns" ns) - (nrepl-send-sync-request) - (plist-get :value))) - (defun cider-fetch-vars-form (ns) "Construct a Clojure form to read vars inside for NS." `(concat (if (find-ns (symbol ,ns)) @@ -1736,15 +1710,7 @@ strings, include private vars, and be case sensitive." (cider-ensure-op-supported "apropos") (-if-let* ((summary (cider-apropos-summary query ns docs-p privates-p case-sensitive-p)) - (results (-> `("op" "apropos" - "ns" ,(cider-current-ns) - "query" ,query - ,@(when ns `("search-ns" ,ns)) - ,@(when docs-p '("docs?" "t")) - ,@(when privates-p '("privates?" "t")) - ,@(when case-sensitive-p '("case-sensitive?" "t"))) - (nrepl-send-sync-request) - (plist-get :value)))) + (results (cider-sync-request:apropos query ns docs-p privates-p case-sensitive-p))) (cider-show-apropos summary results query docs-p) (message "No apropos matches for %S" query))) @@ -1804,9 +1770,9 @@ strings, include private vars, and be case sensitive." (file-name-nondirectory (buffer-file-name)))))) (cider--clear-compilation-highlights) - (cider-send-load-file (cider-file-string filename) - (funcall cider-to-nrepl-filename-function (cider--server-filename filename)) - (file-name-nondirectory filename)) + (cider-request:load-file (cider-file-string filename) + (funcall cider-to-nrepl-filename-function (cider--server-filename filename)) + (file-name-nondirectory filename)) (message "Loading %s..." filename)) (defun cider-load-current-buffer () diff --git a/cider-macroexpansion.el b/cider-macroexpansion.el index 11306b47..40f2493f 100644 --- a/cider-macroexpansion.el +++ b/cider-macroexpansion.el @@ -68,27 +68,16 @@ ARG is passed along to `undo-only'." "Specify the last macroexpansion preformed. This variable specifies both what was expanded and the expander.") -(defun cider-macroexpansion (expander expr) - "Macroexpand, using EXPANDER, the given EXPR." - (cider-ensure-op-supported expander) - (plist-get - (nrepl-send-sync-request - (list "op" expander - "code" expr - "ns" (cider-current-ns) - "display-namespaces" (symbol-name cider-macroexpansion-display-namespaces))) - :value)) - (defun cider-macroexpand-expr (expander expr) "Macroexpand, use EXPANDER, the given EXPR." - (let* ((expansion (cider-macroexpansion expander expr))) + (let* ((expansion (cider-sync-request:macroexpand expander expr))) (setq cider-last-macroexpand-expression expr) (cider-initialize-macroexpansion-buffer expansion (cider-current-ns)))) (defun cider-macroexpand-expr-inplace (expander) "Substitute the form preceding point with its macroexpansion using EXPANDER." (interactive) - (let* ((expansion (cider-macroexpansion expander (cider-last-sexp))) + (let* ((expansion (cider-sync-request:macroexpand expander (cider-last-sexp))) (bounds (cons (save-excursion (backward-sexp) (point)) (point)))) (cider-redraw-macroexpansion-buffer expansion (current-buffer) (car bounds) (cdr bounds)))) diff --git a/cider-repl.el b/cider-repl.el index 1cd9ebb9..0d72b8fe 100644 --- a/cider-repl.el +++ b/cider-repl.el @@ -661,7 +661,7 @@ If invoked in a REPL buffer the command will prompt you for the name of the namespace to switch to." (interactive (list (if (derived-mode-p 'cider-repl-mode) (completing-read "Switch to namespace: " - (cider--all-ns)) + (cider-sync-request:ns-list)) (cider-current-ns)))) (if ns (with-current-buffer (cider-current-repl-buffer) diff --git a/nrepl-client.el b/nrepl-client.el index 8b33dea6..e14fac91 100644 --- a/nrepl-client.el +++ b/nrepl-client.el @@ -302,6 +302,29 @@ FN must accept two arguments key and value." (cons obj (car stack))) (cdr stack)))) +(defun nrepl--merge (dict1 dict2 &optional no-join) + "Join nREPL dicts DICT1 and DICT2 in a meaningful way. +String values for non \"id\" and \"session\" keys are concatenated. Lists +are appended. nREPL dicts merged recursively. All other objects are +accumulated accumulated into a list. DICT1 is modified destructively and +then returned." + (if no-join + (or dict1 dict2) + (cond ((null dict1) dict2) + ((null dict2) dict1) + ((stringp dict1) (concat dict1 dict2)) + ((nrepl-dict-p dict1) + (nrepl-dict-map + (lambda (k2 v2) + (nrepl-dict-put dict1 k2 + (nrepl--merge (nrepl-dict-get dict1 k2) v2 + (member k2 '("id" "session"))))) + dict2) + dict1) + ((and (listp dict2) (listp dict1)) (append dict1 dict2)) + ((listp dict1) (append dict1 (list dict2))) + (t (list dict1 dict2))))) + ;;; Bencode @@ -668,7 +691,7 @@ server responses." (funcall done-handler buffer)))))))) -;;; Client: Request Handling +;;; Client: Request Core API ;; Requests are messages from an nREPL client (like CIDER) to an nREPL server. ;; Requests can be asynchronous (sent with `nrepl-send-request') or @@ -693,20 +716,34 @@ server responses." (with-current-buffer (nrepl-current-connection-buffer) (number-to-string (cl-incf nrepl-request-counter)))) -;; asynchronous requests (defun nrepl-send-request (request callback) "Send REQUEST and register response handler CALLBACK. REQUEST is a pair list of the form (\"op\" \"operation\" \"par1-name\" \"par1\" ... ). See the code of `nrepl-request:clone', `nrepl-request:stdin', etc." - (let* ((request-id (nrepl-next-request-id)) - (request (append (list 'dict "id" request-id) request)) + (let* ((id (nrepl-next-request-id)) + (request (cons 'dict (lax-plist-put request "id" id))) (message (nrepl-bencode request))) (nrepl-log-message (cons '---> (cdr request))) (with-current-buffer (nrepl-current-connection-buffer) - (puthash request-id callback nrepl-pending-requests) + (puthash id callback nrepl-pending-requests) (process-send-string nil message)))) +(defun nrepl-send-sync-request (request) + "Send REQUEST to the nREPL server synchronously (discouraged). +Hold till final \"done\" message has arrived and join all response messages +of the same \"op\" that came along." + (let* ((time0 (current-time)) + (response (cons 'dict nil))) + (nrepl-send-request request (lambda (resp) (nrepl--merge response resp))) + (while (not (member "done" (nrepl-dict-get response "status"))) + (accept-process-output nil 0.01) + ;; break out in case we don't receive a response for a while + (when (> (cadr (time-subtract (current-time) time0)) + nrepl-sync-request-timeout) + (error "Sync nREPL request timed out %s" request))) + response)) + (defun nrepl-request:clone (callback) "Sent a :clone request to create a new client session. Response will be handled by CALLBACK." @@ -732,7 +769,7 @@ Register CALLBACK as the response handler." "interrupt-id" pending-request-id) callback)) -(defun nrepl--make-eval-request (input &optional ns session) +(defun nrepl--eval-request (input &optional ns session) "Prepare :eval request message for INPUT in the context of NS ans SESSION." (append (and ns (list "ns" ns)) (list "op" "eval" @@ -742,50 +779,13 @@ Register CALLBACK as the response handler." (defun nrepl-request:eval (input callback &optional ns session) "Send the request INPUT and register the CALLBACK as the response handler. If NS is non-nil, include it in the request. SESSION defaults to current session." - (nrepl-send-request (nrepl--make-eval-request input ns session) callback)) - -;; synchronous requests -(defun nrepl-sync-request-handler (buffer) - "Make a synchronous request handler for BUFFER." - (nrepl-make-response-handler buffer - (lambda (_buffer value) - (setq nrepl-last-sync-response - (plist-put nrepl-last-sync-response :value value))) - (lambda (_buffer out) - (let ((so-far (plist-get nrepl-last-sync-response :stdout))) - (setq nrepl-last-sync-response - (plist-put nrepl-last-sync-response - :stdout (concat so-far out))))) - (lambda (_buffer err) - (let ((so-far (plist-get nrepl-last-sync-response :stderr))) - (setq nrepl-last-sync-response - (plist-put nrepl-last-sync-response - :stderr (concat so-far err))))) - (lambda (_buffer) - (setq nrepl-last-sync-response - (plist-put nrepl-last-sync-response :done t))))) - -(defun nrepl-send-sync-request (request) - "Send REQUEST to the nREPL server synchronously (discouraged). -The result is a plist with keys :value, :stderr and :stdout." - (with-current-buffer (nrepl-current-connection-buffer) - (setq nrepl-last-sync-response nil) - (setq nrepl-last-sync-request-timestamp (current-time)) - (nrepl-send-request request (nrepl-sync-request-handler (current-buffer))) - (while (or (null nrepl-last-sync-response) - (null (plist-get nrepl-last-sync-response :done))) - (accept-process-output nil 0.01) - ;; break out in case we don't receive a response for a while - (when nrepl-sync-request-timeout - (let ((seconds-ellapsed (cadr (time-subtract (current-time) nrepl-last-sync-request-timestamp)))) - (when (> seconds-ellapsed nrepl-sync-request-timeout) - (error "nREPL sync request timed out %s" request))))) - nrepl-last-sync-response)) + (nrepl-send-request (nrepl--eval-request input ns session) callback)) (defun nrepl-sync-request:eval (input &optional ns session) "Send the INPUT to the nREPL server synchronously. -If NS is non-nil, include it in the request. SESSION defaults to current session." - (nrepl-send-sync-request (nrepl--make-eval-request input ns session))) +If NS is non-nil, include it in the request. SESSION defaults to current +session." + (nrepl-send-sync-request (nrepl--eval-request input ns session))) ;;; Server @@ -962,7 +962,7 @@ number of buffer shrinking operations.") (head (format "(%s" (car object))) (foreground (and id (nth id nrepl--message-colors)))) (cl-flet ((color (str) - (propertize str 'font-lock-face `(:weight ultra-bold :foreground ,foreground)))) + (propertize str 'face `(:weight ultra-bold :foreground ,foreground)))) (insert (color head)) (let ((indent (+ 2 (- (current-column) (length head))))) (if (null (cdr object)) diff --git a/test/cider-tests--no-auto.el b/test/cider-tests--no-auto.el index fe90547d..cd543630 100644 --- a/test/cider-tests--no-auto.el +++ b/test/cider-tests--no-auto.el @@ -45,7 +45,8 @@ leading line of all dashes and trailing nil (when no doc is present) are removed from the latter. Remaining content is compared for string equality." (let ((repl-doc (with-temp-buffer (let ((form (format "(clojure.repl/doc %s)" sym))) - (insert (plist-get (nrepl-send-sync-request form) :stdout)) + (insert (nrepl-dict-get (nrepl-send-sync-request form) + "out")) (goto-char (point-min)) (while (re-search-forward "^ nil\n" nil t) (replace-match "")) @@ -69,14 +70,16 @@ from the latter. Remaining content is compared for string equality." (defun cider-test-all-docs () "Verify docs for all special forms and every public var in `clojure/core'." - (let ((syms (cider-sync-eval-and-parse - "(->> (merge @#'clojure.repl/special-doc-map + (let ((syms (read + (nrepl-sync-request:eval + "(->> (merge @#'clojure.repl/special-doc-map (->> (ns-map 'clojure.core) (filter (every-pred (comp var? val) (complement (comp :private meta val)))))) (keys) - (remove '#{.}))"))) ; emacs lisp chokes on the dot symbol + (remove '#{.}))" ; emacs lisp chokes on the dot symbol + nil nil t)))) (let (untested diffs) (dolist (sym syms) (let ((name (cond ((symbolp sym) (symbol-name sym)) diff --git a/test/cider-tests.el b/test/cider-tests.el index abae19f3..78559a39 100644 --- a/test/cider-tests.el +++ b/test/cider-tests.el @@ -68,23 +68,24 @@ (ert-deftest test-cider-var-info () (noflet ((nrepl-send-sync-request (list) - `(:value - (dict - "arglists" "([] [x] [x & ys])" - "ns" "clojure.core" - "name" "str" - "column" 1 - "added" "1.0" - "static" "true" - "doc" "stub" - "line" 504 - "file" "jar:file:/clojure-1.5.1.jar!/clojure/core.clj" - "tag" "class java.lang.String") - :done t)) + '(dict + "value" (dict + "arglists" "([] [x] [x & ys])" + "ns" "clojure.core" + "name" "str" + "column" 1 + "added" "1.0" + "static" "true" + "doc" "stub" + "line" 504 + "file" "jar:file:/clojure-1.5.1.jar!/clojure/core.clj" + "tag" "class java.lang.String") + "status" ("done"))) + (cider-ensure-op-supported (op) t) (nrepl-current-session () nil) (cider-current-ns () "user")) - (should (equal (nrepl-dict-get (cider-var-info "str") "doc") "stub" )) - (should (not (cider-var-info ""))))) + (should (equal "stub" (nrepl-dict-get (cider-var-info "str") "doc"))) + (should (null (cider-var-info ""))))) (ert-deftest test-nrepl-dict-get () (let ((var-info '(dict "doc" "var doc" "arglists" "var arglists"))) diff --git a/test/nrepl-bencode-tests.el b/test/nrepl-bencode-tests.el index e528bfcc..9755c735 100644 --- a/test/nrepl-bencode-tests.el +++ b/test/nrepl-bencode-tests.el @@ -307,7 +307,30 @@ If object is incomplete, return a decoded path." (nrepl-dict-keys '(dict (2 . 3) (3 . 4) (4 . 5))))) (should (equal '(1 5 9) (nrepl-dict-map (lambda (k v) (+ k v)) - '(dict 0 1 2 3 4 5))))) + '(dict 0 1 2 3 4 5)))) + (should (equal '(dict "id" "1" + "session" "blabla" + "a" (1 11) + "a2" (1 2 11) + "b" (1 2 11 22) + "c" "aaaaaAAAAA" + "d" (dict "a" "aaaaaAAAAA" + "b" "BBBBB")) + (nrepl--merge '(dict "id" "1" + "session" "blabla" + "a" 1 + "a2" (1 2) + "b" (1 2) + "c" "aaaaa" + "d" (dict "a" "aaaaa")) + '(dict "id" "2" + "session" "bombom" + "a" 11 + "a2" 11 + "b" (11 22) + "c" "AAAAA" + "d" (dict "a" "AAAAA" + "b" "BBBBB")))))) ;; benchmarks |