emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[nongnu] elpa/cider 0da71dd6c9 3/4: Add support to view printed exceptio


From: ELPA Syncer
Subject: [nongnu] elpa/cider 0da71dd6c9 3/4: Add support to view printed exceptions in the stacktrace inspector
Date: Mon, 5 Dec 2022 08:58:29 -0500 (EST)

branch: elpa/cider
commit 0da71dd6c992a4686d5f1c93b3ced65ab87e137c
Author: Roman Scherer <roman@burningswell.com>
Commit: Bozhidar Batsov <bozhidar@batsov.dev>

    Add support to view printed exceptions in the stacktrace inspector
    
    This PR adds the `cider-stacktrace-analyze-at-point` and
    `cider-stacktrace-analyze-in-region` commands to view printed
    exceptions in the stacktrace inspector.
---
 CHANGELOG.md                                       |   1 +
 cider-stacktrace.el                                |  98 ++++++++---
 .../ROOT/pages/usage/dealing_with_errors.adoc      |  92 ++++++++++
 test/cider-stacktrace-tests.el                     | 189 ++++++++++++++++++++-
 4 files changed, 353 insertions(+), 27 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index a0cad9b5d8..f54cc1b61e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,7 @@
 ### New features
 
 - [#3249](https://github.com/clojure-emacs/cider/pull/3249): Add support for 
Clojure Spec 2.
+- [#3247](https://github.com/clojure-emacs/cider/pull/3247) Add the 
`cider-stacktrace-analyze-at-point` and `cider-stacktrace-analyze-in-region` 
commands to view printed exceptions in the stacktrace inspector.
 
 ### Changes
 
diff --git a/cider-stacktrace.el b/cider-stacktrace.el
index 24b4e57fa9..b1e45facc8 100644
--- a/cider-stacktrace.el
+++ b/cider-stacktrace.el
@@ -670,29 +670,30 @@ This associates text properties to enable filtering and 
source navigation."
                               'follow-link t
                               'action (lambda (x) (browse-url (button-get x 
'url)))))
       (nrepl-dbind-response frame (file line flags class method name var ns fn)
-        (let ((flags (mapcar #'intern flags))) ; strings -> symbols
-          (insert-text-button (format "%26s:%5d  %s/%s"
-                                      (if (member 'repl flags) "REPL" file) 
line
-                                      (if (member 'clj flags) ns class)
-                                      (if (member 'clj flags) fn method))
-                              'var var 'class class 'method method
-                              'name name 'file file 'line line
-                              'flags flags 'follow-link t
-                              'action #'cider-stacktrace-navigate
-                              'help-echo (cider-stacktrace-tooltip
-                                          "View source at this location")
-                              'font-lock-face 'cider-stacktrace-face
-                              'type 'cider-plain-button)
-          (save-excursion
-            (let ((p4 (point))
-                  (p1 (search-backward " "))
-                  (p2 (search-forward "/"))
-                  (p3 (search-forward-regexp "[^/$]+")))
-              (put-text-property p1 p4 'font-lock-face 
'cider-stacktrace-ns-face)
-              (put-text-property p2 p3 'font-lock-face 
'cider-stacktrace-fn-face)
-              (put-text-property (line-beginning-position) (line-end-position)
-                                 'cider-stacktrace-frame t)))
-          (insert "\n"))))))
+        (when (or class file fn method ns name)
+          (let ((flags (mapcar #'intern flags))) ; strings -> symbols
+            (insert-text-button (format "%26s:%5d  %s/%s"
+                                        (if (member 'repl flags) "REPL" file) 
(or line -1)
+                                        (if (member 'clj flags) ns class)
+                                        (if (member 'clj flags) fn method))
+                                'var var 'class class 'method method
+                                'name name 'file file 'line line
+                                'flags flags 'follow-link t
+                                'action #'cider-stacktrace-navigate
+                                'help-echo (cider-stacktrace-tooltip
+                                            "View source at this location")
+                                'font-lock-face 'cider-stacktrace-face
+                                'type 'cider-plain-button)
+            (save-excursion
+              (let ((p4 (point))
+                    (p1 (search-backward " "))
+                    (p2 (search-forward "/"))
+                    (p3 (search-forward-regexp "[^/$]+")))
+                (put-text-property p1 p4 'font-lock-face 
'cider-stacktrace-ns-face)
+                (put-text-property p2 p3 'font-lock-face 
'cider-stacktrace-fn-face)
+                (put-text-property (line-beginning-position) 
(line-end-position)
+                                   'cider-stacktrace-frame t)))
+            (insert "\n")))))))
 
 (defun cider-stacktrace-render-compile-error (buffer cause)
   "Emit into BUFFER the compile error CAUSE, and enable jumping to it."
@@ -844,7 +845,8 @@ the NAME.  The whole group is prefixed by string INDENT."
               (goto-char (next-single-property-change (point) 'compile-error))
             (progn
               (while (cider-stacktrace-next-cause))
-              (goto-char (next-single-property-change (point) 'flags)))))))))
+              (when-let (position (next-single-property-change (point) 'flags))
+                (goto-char position)))))))))
 
 (defun cider-stacktrace-render (buffer causes &optional error-types)
   "Emit into BUFFER useful stacktrace information for the CAUSES.
@@ -876,6 +878,54 @@ through the `cider-stacktrace-suppressed-errors' variable."
     (cider-stacktrace-initialize causes)
     (font-lock-refresh-defaults)))
 
+(defun cider-stacktrace--analyze-stacktrace-op (stacktrace)
+  "Return the Cider NREPL op to analyze STACKTRACE."
+  (list "op" "analyze-stacktrace" "stacktrace" stacktrace))
+
+(defun cider-stacktrace--stacktrace-request (stacktrace)
+  "Return the Cider NREPL request to analyze STACKTRACE."
+  (thread-last
+    (map-merge 'list
+               (list (cider-stacktrace--analyze-stacktrace-op stacktrace))
+               (cider--nrepl-print-request-map fill-column))
+    (seq-mapcat #'identity)))
+
+(defun cider-stacktrace--analyze-render (causes)
+  "Render the CAUSES of the stacktrace analysis result."
+  (let ((buffer (get-buffer-create cider-error-buffer)))
+    (with-current-buffer buffer
+      (cider-stacktrace-mode)
+      (cider-stacktrace-render buffer (reverse causes))
+      (display-buffer buffer cider-jump-to-pop-to-buffer-actions))))
+
+(defun cider-stacktrace-analyze-string (stacktrace)
+  "Analyze the STACKTRACE string and show the result."
+  (when (stringp stacktrace)
+    (set-text-properties 0 (length stacktrace) nil stacktrace))
+  (let (causes)
+    (cider-nrepl-send-request
+     (cider-stacktrace--stacktrace-request stacktrace)
+     (lambda (response)
+       (setq causes (nrepl-dbind-response response (class status)
+                      (cond (class (cons response causes))
+                            ((and (member "done" status) causes)
+                             (cider-stacktrace--analyze-render causes)))))))))
+
+(defun cider-stacktrace-analyze-at-point ()
+  "Analyze the stacktrace at point."
+  (interactive)
+  (cond ((thing-at-point 'sentence)
+         (cider-stacktrace-analyze-string (thing-at-point 'sentence)))
+        ((thing-at-point 'paragraph)
+         (cider-stacktrace-analyze-string (thing-at-point 'paragraph)))
+        (t (cider-stacktrace-analyze-in-region (region-beginning) 
(region-end)))))
+
+(defun cider-stacktrace-analyze-in-region (beg end)
+  "Analyze the stacktrace in the region between BEG and END."
+  (interactive (list (region-beginning) (region-end)))
+  (let ((stacktrace (buffer-substring beg end)))
+    (cider-stacktrace-analyze-string stacktrace)))
+
 (provide 'cider-stacktrace)
 
 ;;; cider-stacktrace.el ends here
diff --git a/doc/modules/ROOT/pages/usage/dealing_with_errors.adoc 
b/doc/modules/ROOT/pages/usage/dealing_with_errors.adoc
index d016be6808..8234b0bbd2 100644
--- a/doc/modules/ROOT/pages/usage/dealing_with_errors.adoc
+++ b/doc/modules/ROOT/pages/usage/dealing_with_errors.adoc
@@ -182,3 +182,95 @@ for instance:
 ----
 (setq cider-stacktrace-fill-column 80)
 ----
+
+=== Inspecting printed stacktraces
+
+Some of the errors you encounter as a Clojurists aren't necessarily
+evaluation errors that happened in your REPL. Many times, you see
+errors printed in a textual representation in other buffers as well,
+like log files or the REPL for example. Cider can parse and analyze
+some of those printed errors as well and show them in
+`cider-stacktrace-mode` with the following commands:
+
+* The `cider-stacktrace-analyze-at-point` command uses the `thingatpt`
+  library to extract the current stacktrace at point. It sends the
+  extracted stacktrace to the middleware in order to parse and analyze
+  it, and then shows the result in Cider's `cider-stacktrace-mode`.
+
+* The `cider-stacktrace-analyze-in-region` command does the same as
+  `cider-stacktrace-analyze-at-point`, but uses the current region to
+  extract the stacktrace.
+
+===== Examples
+
+Here is an example of a stacktrace printed with the Java
+`printStackTrace` method:
+
+[source,text]
+----
+clojure.lang.ExceptionInfo: BOOM-1 {:boom "1"}
+  at java.base/java.lang.Thread.run(Thread.java:829)
+----
+
+To open this stacktrace in the Cider stacktrace inspector, move point
+somewhere over the exception and run `M-x
+cider-stacktrace-analyze-at-point`.
+
+This also works to some extend for exceptions that are buried inside a
+string like the following exception:
+
+[source,text]
+----
+"clojure.lang.ExceptionInfo: BOOM-1 {:boom \"1\"}\n at 
java.base/java.lang.Thread.run(Thread.java:829)"
+----
+
+Those exceptions are often hard to read. The Cider stacktrace
+inspector can help you navigating exceptions even in those cases.
+
+===== Supported formats
+
+Cider recognizes stacktraces printed in the following formats:
+
+- `Aviso` - Exceptions printed with the
+  
https://ioavisopretty.readthedocs.io/en/latest/exceptions.html[write-exception]
+  function of the https://github.com/AvisoNovate/pretty[Aviso]
+  library.
+
+- `clojure.repl` - Exceptions printed with the
+  
https://clojure.github.io/clojure/branch-master/clojure.repl-api.html#clojure.repl/pst[clojure.repl/pst]
+  function.
+
+- `clojure.stacktrace` - Exceptions printed with the
+  
https://clojure.github.io/clojure/branch-master/clojure.stacktrace-api.html#clojure.stacktrace/print-cause-trace[clojure.stacktrace/print-cause-trace]
+  function.
+
+- `Java` - Exceptions printed with the
+  
https://docs.oracle.com/javase/8/docs/api/java/lang/Throwable.html#printStackTrace--[Throwable/printStackTrace]
+  method.
+
+- `Tagged Literal` - Exceptions printed with the
+  
https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/pr[clojure.core/pr]
+  function.
+
+===== Limitations
+
+- Cider only recognizes stacktraces that have been printed in one of
+  the supported formats.
+
+- The buffers in which `cider-stacktrace-analyze-at-point` or
+  `cider-stacktrace-analyze-in-region` are called in, must have a
+  Cider session associated with them. Tip: Use
+  `sesman-link-with-project` and friends in case the buffer containing
+  the exception is not linked to a Cider session.
+
+- Stacktraces are analyzed with the classpath of the Cider session the
+  buffer is associated with. If the stacktrace contains references to
+  classes not on this classpath, some information might be missing
+  from the analysis.
+
+- The `cider-stacktrace-analyze-at-point` function might not detect
+  the stacktrace at point in every situation. The thing at point might
+  be different depending on which major mode is active in a
+  buffer. When `cider-stacktrace-analyze-at-point` fails to detect the
+  stacktrace, `cider-stacktrace-analyze-in-region` can be used to
+  select the stacktrace manually.
diff --git a/test/cider-stacktrace-tests.el b/test/cider-stacktrace-tests.el
index 613d3ddc06..d903f60313 100644
--- a/test/cider-stacktrace-tests.el
+++ b/test/cider-stacktrace-tests.el
@@ -30,6 +30,135 @@
 (require 'buttercup)
 (require 'cider-stacktrace)
 
+;; cider-stacktrace test data
+
+(defvar cider-stacktrace-tests-boom-aviso
+  (string-join
+   '("   nrepl.middleware.interruptible-eval/evaluate/fn  
interruptible_eval.clj:   87"
+     "                                               ..."
+     "                       clojure.core/with-bindings*                
core.clj: 1977 (repeats 2 times)"
+     "                                clojure.core/apply                
core.clj:  667"
+     "                                               ..."
+     "nrepl.middleware.interruptible-eval/evaluate/fn/fn  
interruptible_eval.clj:   87"
+     "                                 clojure.core/eval                
core.clj: 3202"
+     "                                               ..."
+     "          orchard.stacktrace.parser-test/eval15048               REPL 
Input"
+     "                                               ..."
+     "clojure.lang.ExceptionInfo: BOOM-3"
+     "    boom: \"3\""
+     "clojure.lang.ExceptionInfo: BOOM-2"
+     "    boom: \"2\""
+     "clojure.lang.ExceptionInfo: BOOM-1"
+     "    boom: \"1\"")
+   "\n"))
+
+(defvar cider-stacktrace-tests-boom-clojure
+  (string-join
+   '("#error {"
+     " :cause \"BOOM-3\""
+     " :data {:boom \"3\"}"
+     " :via"
+     " [{:type clojure.lang.ExceptionInfo"
+     "   :message \"BOOM-1\""
+     "   :data {:boom \"1\"}"
+     "   :at [clojure.lang.AFn applyToHelper \"AFn.java\" 160]}"
+     "  {:type clojure.lang.ExceptionInfo"
+     "   :message \"BOOM-2\""
+     "   :data {:boom \"2\"}"
+     "   :at [clojure.lang.AFn applyToHelper \"AFn.java\" 160]}"
+     "  {:type clojure.lang.ExceptionInfo"
+     "   :message \"BOOM-3\""
+     "   :data {:boom \"3\"}"
+     "   :at [clojure.lang.AFn applyToHelper \"AFn.java\" 156]}]"
+     " :trace"
+     " [[clojure.lang.AFn applyToHelper \"AFn.java\" 156]"
+     "  [clojure.lang.AFn applyTo \"AFn.java\" 144]"
+     "  [clojure.lang.Compiler$InvokeExpr eval \"Compiler.java\" 3706]"
+     "  [clojure.lang.Compiler$InvokeExpr eval \"Compiler.java\" 3705]"
+     "  [clojure.lang.Compiler$InvokeExpr eval \"Compiler.java\" 3705]"
+     "  [clojure.lang.Compiler$DefExpr eval \"Compiler.java\" 457]"
+     "  [clojure.lang.Compiler eval \"Compiler.java\" 7186]"
+     "  [clojure.lang.Compiler load \"Compiler.java\" 7640]"
+     "  [orchard.stacktrace.parser_test$eval10939 invokeStatic 
\"form-init13443654147290506544.clj\" 1]"
+     "  [orchard.stacktrace.parser_test$eval10939 invoke 
\"form-init13443654147290506544.clj\" 1]"
+     "  [clojure.lang.Compiler eval \"Compiler.java\" 7181]"
+     "  [clojure.lang.Compiler eval \"Compiler.java\" 7136]"
+     "  [clojure.core$eval invokeStatic \"core.clj\" 3202]"
+     "  [clojure.core$eval invoke \"core.clj\" 3198]"
+     "  [nrepl.middleware.interruptible_eval$evaluate$fn__1933$fn__1934 invoke 
\"interruptible_eval.clj\" 87]"
+     "  [clojure.lang.AFn applyToHelper \"AFn.java\" 152]"
+     "  [clojure.lang.AFn applyTo \"AFn.java\" 144]"
+     "  [clojure.core$apply invokeStatic \"core.clj\" 667]"
+     "  [clojure.core$with_bindings_STAR_ invokeStatic \"core.clj\" 1977]"
+     "  [clojure.core$with_bindings_STAR_ doInvoke \"core.clj\" 1977]"
+     "  [clojure.lang.RestFn invoke \"RestFn.java\" 425]"
+     "  [nrepl.middleware.interruptible_eval$evaluate$fn__1933 invoke 
\"interruptible_eval.clj\" 87]"
+     "  [clojure.main$repl$read_eval_print__9110$fn__9113 invoke \"main.clj\" 
437]"
+     "  [clojure.main$repl$read_eval_print__9110 invoke \"main.clj\" 437]"
+     "  [clojure.main$repl$fn__9119 invoke \"main.clj\" 458]"
+     "  [clojure.main$repl invokeStatic \"main.clj\" 458]"
+     "  [clojure.main$repl doInvoke \"main.clj\" 368]"
+     "  [clojure.lang.RestFn invoke \"RestFn.java\" 1523]"
+     "  [nrepl.middleware.interruptible_eval$evaluate invokeStatic 
\"interruptible_eval.clj\" 84]"
+     "  [nrepl.middleware.interruptible_eval$evaluate invoke 
\"interruptible_eval.clj\" 56]"
+     "  
[nrepl.middleware.interruptible_eval$interruptible_eval$fn__1966$fn__1970 
invoke \"interruptible_eval.clj\" 152]"
+     "  [clojure.lang.AFn run \"AFn.java\" 22]"
+     "  [nrepl.middleware.session$session_exec$main_loop__2036$fn__2040 invoke 
\"session.clj\" 218]"
+     "  [nrepl.middleware.session$session_exec$main_loop__2036 invoke 
\"session.clj\" 217]"
+     "  [clojure.lang.AFn run \"AFn.java\" 22]"
+     "  [java.lang.Thread run \"Thread.java\" 829]]}")
+   "\n"))
+
+(defvar cider-stacktrace-tests-boom-java
+  (string-join '("clojure.lang.ExceptionInfo: BOOM-1 {:boom \"1\"}"
+                 "     at clojure.lang.AFn.applyToHelper(AFn.java:160)"
+                 "     at clojure.lang.AFn.applyTo(AFn.java:144)"
+                 "     at 
clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3706)"
+                 "     at 
clojure.lang.Compiler$DefExpr.eval(Compiler.java:457)"
+                 "     at clojure.lang.Compiler.eval(Compiler.java:7186)"
+                 "     at clojure.lang.Compiler.load(Compiler.java:7640)"
+                 "     at 
user$eval10785.invokeStatic(form-init16591543638769050486.clj:1)"
+                 "     at 
user$eval10785.invoke(form-init16591543638769050486.clj:1)"
+                 "     at clojure.lang.Compiler.eval(Compiler.java:7181)"
+                 "     at clojure.lang.Compiler.eval(Compiler.java:7136)"
+                 "     at clojure.core$eval.invokeStatic(core.clj:3202)"
+                 "     at clojure.core$eval.invoke(core.clj:3198)"
+                 "     at 
nrepl.middleware.interruptible_eval$evaluate$fn__1933$fn__1934.invoke(interruptible_eval.clj:87)"
+                 "     at clojure.lang.AFn.applyToHelper(AFn.java:152)"
+                 "     at clojure.lang.AFn.applyTo(AFn.java:144)"
+                 "     at clojure.core$apply.invokeStatic(core.clj:667)"
+                 "     at 
clojure.core$with_bindings_STAR_.invokeStatic(core.clj:1977)"
+                 "     at 
clojure.core$with_bindings_STAR_.doInvoke(core.clj:1977)"
+                 "     at clojure.lang.RestFn.invoke(RestFn.java:425)"
+                 "     at 
nrepl.middleware.interruptible_eval$evaluate$fn__1933.invoke(interruptible_eval.clj:87)"
+                 "     at 
clojure.main$repl$read_eval_print__9110$fn__9113.invoke(main.clj:437)"
+                 "     at 
clojure.main$repl$read_eval_print__9110.invoke(main.clj:437)"
+                 "     at clojure.main$repl$fn__9119.invoke(main.clj:458)"
+                 "     at clojure.main$repl.invokeStatic(main.clj:458)"
+                 "     at clojure.main$repl.doInvoke(main.clj:368)"
+                 "     at clojure.lang.RestFn.invoke(RestFn.java:1523)"
+                 "     at 
nrepl.middleware.interruptible_eval$evaluate.invokeStatic(interruptible_eval.clj:84)"
+                 "     at 
nrepl.middleware.interruptible_eval$evaluate.invoke(interruptible_eval.clj:56)"
+                 "     at 
nrepl.middleware.interruptible_eval$interruptible_eval$fn__1966$fn__1970.invoke(interruptible_eval.clj:152)"
+                 "     at clojure.lang.AFn.run(AFn.java:22)"
+                 "     at 
nrepl.middleware.session$session_exec$main_loop__2036$fn__2040.invoke(session.clj:218)"
+                 "     at 
nrepl.middleware.session$session_exec$main_loop__2036.invoke(session.clj:217)"
+                 "     at clojure.lang.AFn.run(AFn.java:22)"
+                 "     at java.base/java.lang.Thread.run(Thread.java:829)"
+                 "Caused by: clojure.lang.ExceptionInfo: BOOM-2 {:boom \"2\"}"
+                 "     at clojure.lang.AFn.applyToHelper(AFn.java:160)"
+                 "     at clojure.lang.AFn.applyTo(AFn.java:144)"
+                 "     at 
clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3706)"
+                 "     at 
clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3705)"
+                 "     ... 31 more"
+                 "Caused by: clojure.lang.ExceptionInfo: BOOM-3 {:boom \"3\"}"
+                 "     at clojure.lang.AFn.applyToHelper(AFn.java:156)"
+                 "     at clojure.lang.AFn.applyTo(AFn.java:144)"
+                 "     at 
clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3706)"
+                 "     at 
clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3705)"
+                 "     ... 32 more")
+               "\n"))
+
 ;;; cider-stacktrace tests
 
 ;;; Internal/Middleware error suppression
@@ -88,9 +217,9 @@
     (apply #'nrepl-dict
            (append (apply #'append
                           (mapcar (lambda (name) (list (symbol-name name)
-                                                (if (funcall numeric? name)
-                                                    4
-                                                  (symbol-name name))))
+                                                       (if (funcall numeric? 
name)
+                                                           4
+                                                         (symbol-name name))))
                                   names))
                    stipulated))))
 
@@ -126,3 +255,57 @@
               :to-be-truthy)
       (expect (or both shown1 shown2)
               :to-be nil))))
+
+(defun cider-stacktrace-tests--analyze-at-point (stacktrace pos)
+  "Test `cider-stacktrace-analyze-at-point' with STACKTRACE at POS."
+  (with-temp-buffer
+    (erase-buffer)
+    (insert stacktrace)
+    (goto-char pos)
+    (cider-stacktrace-analyze-at-point)))
+
+(describe "cider-stacktrace-analyze-at-point"
+  :var (cider-stacktrace-analyze-string)
+  (before-each (spy-on 'cider-stacktrace-analyze-string))
+
+  (it "should analyze the Aviso stacktrace with point at beginning"
+    (cider-stacktrace-tests--analyze-at-point 
cider-stacktrace-tests-boom-aviso 0)
+    (expect 'cider-stacktrace-analyze-string :to-have-been-called-with 
cider-stacktrace-tests-boom-aviso))
+
+  (it "should analyze the Clojure stacktrace with point at beginning"
+    (cider-stacktrace-tests--analyze-at-point 
cider-stacktrace-tests-boom-clojure 0)
+    (expect 'cider-stacktrace-analyze-string :to-have-been-called-with 
cider-stacktrace-tests-boom-clojure))
+
+  (it "should analyze the Java stacktrace with point at beginning"
+    (cider-stacktrace-tests--analyze-at-point cider-stacktrace-tests-boom-java 
0)
+    (expect 'cider-stacktrace-analyze-string :to-have-been-called-with 
cider-stacktrace-tests-boom-java))
+
+  (it "should analyze the Clojure stacktrace with point inside"
+    (cider-stacktrace-tests--analyze-at-point 
cider-stacktrace-tests-boom-clojure 10)
+    (expect 'cider-stacktrace-analyze-string :to-have-been-called-with 
cider-stacktrace-tests-boom-clojure))
+
+  (it "should analyze the Java stacktrace with point inside"
+    (cider-stacktrace-tests--analyze-at-point cider-stacktrace-tests-boom-java 
10)
+    (expect 'cider-stacktrace-analyze-string :to-have-been-called-with 
cider-stacktrace-tests-boom-java)))
+
+(defun cider-stacktrace-tests--analyze-in-region (stacktrace)
+  "Test `cider-stacktrace-analyze-in-region' with STACKTRACE."
+  (with-temp-buffer
+    (insert stacktrace)
+    (cider-stacktrace-analyze-in-region (point-min) (point-max))))
+
+(describe "cider-stacktrace-analyze-in-region"
+  :var (cider-stacktrace-analyze-string)
+  (before-each (spy-on 'cider-stacktrace-analyze-string))
+
+  (it "should analyze the Aviso stacktrace in region"
+    (cider-stacktrace-tests--analyze-in-region 
cider-stacktrace-tests-boom-aviso)
+    (expect 'cider-stacktrace-analyze-string :to-have-been-called-with 
cider-stacktrace-tests-boom-aviso))
+
+  (it "should analyze the Clojure stacktrace in region"
+    (cider-stacktrace-tests--analyze-in-region 
cider-stacktrace-tests-boom-clojure)
+    (expect 'cider-stacktrace-analyze-string :to-have-been-called-with 
cider-stacktrace-tests-boom-clojure))
+
+  (it "should analyze the Java stacktrace in region"
+    (cider-stacktrace-tests--analyze-in-region 
cider-stacktrace-tests-boom-java)
+    (expect 'cider-stacktrace-analyze-string :to-have-been-called-with 
cider-stacktrace-tests-boom-java)))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]