branch: elpa/logview
commit 9140067afdc2f0d1eb493dc4dfdb53645289dd2b
Author: Paul Pogonyshev <pogonys...@gmail.com>
Commit: Paul Pogonyshev <pogonys...@gmail.com>

    Fix a couple of problems with displaying timestamp differences; add tests.
---
 logview.el      | 46 ++++++++++++++++++++++-------------
 test/logview.el | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 104 insertions(+), 17 deletions(-)

diff --git a/logview.el b/logview.el
index 0df4a24cce..8e199d5617 100644
--- a/logview.el
+++ b/logview.el
@@ -701,9 +701,11 @@ settings) with this face.")
 (defvar-local logview--hide-all-details   nil)
 
 (defvar-local logview--timestamp-difference-base nil
-  "Either nil or (POSITION . TIMESTAMP-AS-FLOAT).")
+  "Either nil or (ENTRY . START).
+ENTRY will have its timestamp parsed.")
 (defvar-local logview--timestamp-difference-per-thread-bases nil
-  "Either nil or a hash-table of strings to cons cells.")
+  "Either nil or a hash-table of strings to cons cells.
+See `logview--timestamp-difference-base' for details.")
 
 (defvar-local logview--buffer-target-gap-length nil)
 (defvar-local logview--last-found-large-gap     nil)
@@ -2395,10 +2397,13 @@ difference bases (appointed with 
`\\<logview-mode-map>\\[logview-thread-differen
   (logview--assert 'timestamp)
   (logview--std-temporarily-widening
     (logview--locate-current-entry entry start
-      (unless (and (equal (cdr logview--timestamp-difference-base) start) 
(null logview--timestamp-difference-per-thread-bases))
-        (setq logview--timestamp-difference-base             (cons entry start)
-              logview--timestamp-difference-per-thread-bases nil)
-        (logview--refontify-buffer)))))
+      ;; Make sure that it is parsed.
+      (logview--entry-timestamp entry start)
+      (let ((base (cons entry start)))
+        (unless (and (equal logview--timestamp-difference-base base) (null 
logview--timestamp-difference-per-thread-bases))
+          (setq logview--timestamp-difference-base             base
+                logview--timestamp-difference-per-thread-bases nil)
+          (logview--refontify-buffer))))))
 
 (defun logview-thread-difference-to-current-entry ()
   "Display difference to current entry's timestamp in its thread.
@@ -2408,11 +2413,14 @@ it stays in effect for other threads."
   (logview--assert 'timestamp 'thread)
   (logview--std-temporarily-widening
     (logview--locate-current-entry entry start
-      (let ((thread (logview--entry-group entry start logview--thread-group)))
-        (unless (and logview--timestamp-difference-per-thread-bases (equal 
(cdr (gethash thread logview--timestamp-difference-per-thread-bases)) start))
+      ;; Make sure that it is parsed.
+      (logview--entry-timestamp entry start)
+      (let ((base   (cons entry start))
+            (thread (logview--entry-group entry start logview--thread-group)))
+        (unless (and logview--timestamp-difference-per-thread-bases (equal 
(gethash thread logview--timestamp-difference-per-thread-bases) base))
           (unless logview--timestamp-difference-per-thread-bases
             (setq logview--timestamp-difference-per-thread-bases 
(make-hash-table :test #'equal)))
-          (puthash thread (cons entry start) 
logview--timestamp-difference-per-thread-bases)
+          (puthash thread base logview--timestamp-difference-per-thread-bases)
           (logview--refontify-buffer))))))
 
 (defun logview-go-to-difference-base-entry ()
@@ -2427,10 +2435,10 @@ it stays in effect for other threads."
                                   logview--timestamp-difference-base)))
         (unless difference-base
           (user-error "There is no timestamp difference base for the current 
entry"))
-        (when (invisible-p difference-base)
-          (user-error "Timestamp difference base for the current entry is 
currently hidden"))
-        (let* ((entry (car difference-base))
-               (start (cdr difference-base)))
+        (when (invisible-p (cdr difference-base))
+          (user-error "Timestamp difference base is either hidden or not in 
the current file contents anymore (e.g. due to log rolling)"))
+        (let ((entry (car difference-base))
+              (start (cdr difference-base)))
           (unless (and (< start (logview--point-max)) (> (logview--entry-end 
entry start) (logview--point-min)))
             (user-error "Difference base entry is outside the narrowing 
region"))
           (goto-char (logview--entry-message-start entry start))
@@ -3870,9 +3878,9 @@ This list is preserved across Emacs session in
                        (have-name                   (memq 'name      
logview--submode-features))
                        (have-thread                 (memq 'thread    
logview--submode-features))
                        (validator                   (cdr 
logview--effective-filter))
-                       (difference-base             
logview--timestamp-difference-base)
+                       (common-difference-base      
logview--timestamp-difference-base)
                        (difference-bases-per-thread 
logview--timestamp-difference-per-thread-bases)
-                       (displaying-differences      (or difference-base 
difference-bases-per-thread))
+                       (displaying-differences      (or common-difference-base 
difference-bases-per-thread))
                        (difference-format-string    
logview--timestamp-difference-format-string)
                        (header-filter               (cdr 
logview--section-header-filter))
                        (highlighter                 (cdr 
logview--highlighted-filter))
@@ -3898,8 +3906,12 @@ This list is preserved across Emacs session in
                                  (when displaying-differences
                                    (let ((difference-base (or (when 
difference-bases-per-thread
                                                                 (gethash 
(logview--entry-group entry start logview--thread-group) 
difference-bases-per-thread))
-                                                              
difference-base)))
-                                     (when (and difference-base (not (= (cdr 
difference-base) start)))
+                                                              
common-difference-base)))
+                                     ;; Hide timestamp with time difference if 
there is a difference
+                                     ;; base entry and we are not positioned 
over it right now.
+                                     (when (and difference-base (not (and (= 
(cdr difference-base) start)
+                                                                          
(progn (logview--entry-timestamp entry start)  ; Make sure that it is parsed.
+                                                                               
  (equal (car difference-base) entry)))))
                                        ;; FIXME: It is possible that 
fractionals are not the last
                                        ;;        thing in the timestamp, in 
which case it would be
                                        ;;        nicer to add some spaces on 
the right. However,
diff --git a/test/logview.el b/test/logview.el
index 90910e263c..14d0ebecd4 100644
--- a/test/logview.el
+++ b/test/logview.el
@@ -31,6 +31,11 @@
   (error "Warning elevated to an error: %S" arguments))
 
 (defmacro logview--test-with-file (filename &rest body)
+  "Activate Logview in a temporary buffer with contents of the file.
+Instead of visiting the file, this macro creates a new buffer for
+it.  This avoids annoying clashes if the file is already open
+(when in interactive mode) and also allows to further modify
+buffer if the test needs that."
   (declare (debug (form body))
            (indent 1))
   ;; We do the following to avoid customizations influence testing
@@ -61,6 +66,23 @@
          (advice-remove 'display-warning 
#'logview--test-display-warning-advice)))))
 
 
+(defun logview--test-user-visible-buffer-string ()
+  (font-lock-ensure)
+  (let ((from (point-min))
+        chunks)
+    (while from
+      (let ((to (next-property-change from)))
+        (unless (invisible-p from)
+          (let ((display-as (get-text-property from 'display)))
+            (unless (and display-as to (eq display-as (get-text-property to 
'display)))
+              (push (cond ((stringp display-as) display-as)
+                          (display-as           (prin1-to-string display-as))
+                          (t                    
(buffer-substring-no-properties from (or to (point-max)))))
+                    chunks))))
+        (setf from to)))
+    (mapconcat #'identity (nreverse chunks) nil)))
+
+
 (defun logview--test-current-message ()
   (logview--std-temporarily-widening
     (logview--locate-current-entry entry start
@@ -158,6 +180,59 @@
     (logview-difference-to-current-entry)
     (logview-go-to-difference-base-entry)))
 
+(ert-deftest logview-hidden-difference-base ()
+  (logview--test-with-file "log4j/sections-1.log"
+    ;; Testing only one line, but it should hopefully be the same for other 
lines.
+    (should (string-match-p (rx bol "2010-03-10 20:03:44.100 [thread 1] DEBUG 
my.Class - before any sections" eol)
+                            (logview--test-user-visible-buffer-string)))
+    (logview-next-entry)
+    (logview-difference-to-current-entry)
+    (should (string-match-p (rx bol "                 -0.100 [thread 1] DEBUG 
my.Startup - starting up" eol)
+                            (logview--test-user-visible-buffer-string)))
+    (should (string-match-p (rx bol "2010-03-10 20:03:44.100 [thread 1] DEBUG 
my.Class - before any sections" eol)
+                            (logview--test-user-visible-buffer-string)))
+    (goto-char 1)
+    (logview-go-to-difference-base-entry)
+    (should (looking-at (rx "before any sections" eol)))
+    (logview-show-errors-warnings-and-information)
+    ;; Must be filtered out and invisible now.
+    (should-not (string-match-p (rx bol "2010-03-10 20:03:44.100 [thread 1] 
DEBUG my.Class - before any sections" eol)
+                                (logview--test-user-visible-buffer-string)))
+    (should-error (logview-go-to-difference-base-entry) :type 'user-error)))
+
+(ert-deftest logview-time-differences-after-full-buffer-reload ()
+  ;; Using a test file with different timestamps for different entries.
+  (logview--test-with-file "log4j/sections-1.log"
+    ;; Testing only one line, but it should hopefully be the same for other 
lines.
+    (should (string-match-p (rx bol "2010-03-10 20:03:44.100 [thread 1] DEBUG 
my.Class - before any sections" eol)
+                            (logview--test-user-visible-buffer-string)))
+    (logview-difference-to-current-entry)
+    ;; This first entry should stay the same (not because it's the first, but 
because it's
+    ;; the difference base).
+    (should (string-match-p (rx bol "2010-03-10 20:03:44.000 [thread 1] DEBUG 
my.Startup - starting up" eol)
+                            (logview--test-user-visible-buffer-string)))
+    (should (string-match-p (rx bol "                 +0.100 [thread 1] DEBUG 
my.Class - before any sections" eol)
+                            (logview--test-user-visible-buffer-string)))
+    (goto-char (point-max))
+    (logview-go-to-difference-base-entry)
+    (should (looking-at (rx "starting up" eol)))
+    ;; Emulate the log being fully changed, e.g. due to file rotation.
+    (logview--std-altering
+      (save-excursion
+        (goto-char (point-min))
+        (while (re-search-forward (rx "20:03:") nil t)
+          (replace-match "20:05:")
+          (end-of-line)
+          (insert " (changed)"))))
+    (logview--invalidate-region-entries (point-min) (point-max))
+    ;; Same buffer position, but the entry is now different, so must display 
time
+    ;; difference.
+    (should (string-match-p (rx bol "               +120.000 [thread 1] DEBUG 
my.Startup - starting up (changed)" eol)
+                            (logview--test-user-visible-buffer-string)))
+    (should (string-match-p (rx bol "               +120.100 [thread 1] DEBUG 
my.Class - before any sections (changed)" eol)
+                            (logview--test-user-visible-buffer-string)))))
+
+
 ;; See https://github.com/doublep/logview/issues/48 for rationale to have this 
at all.
 (ert-deftest logview-custom-submode-with-special-regexp ()
   (logview--test-with-file "custom/2.log"

Reply via email to