Implement multi-backend tests

Reorganize plist backend methods
Address some failing tests for plist backend methods
This commit is contained in:
contrapunctus 2022-01-03 02:11:49 +05:30
parent 909be83e3a
commit 5d5b423c59
3 changed files with 142 additions and 119 deletions

View File

@ -1152,32 +1152,16 @@ STREAM (which is the value of `current-buffer')."
:group 'chronometrist)
;; pretty-print-function:1 ends here
;; [[file:chronometrist.org::*count-records][count-records:1]]
(cl-defmethod chronometrist-count-records ((backend chronometrist-plist-backend))
(chronometrist-sexp-in-file (chronometrist-backend-file backend)
(goto-char (point-min))
(cl-loop with count = 0
while (ignore-errors (read (current-buffer)))
do (cl-incf count)
finally return count)))
;; count-records:1 ends here
;; [[file:chronometrist.org::*latest-date-records][latest-date-records:1]]
(cl-defmethod chronometrist-latest-date-records ((backend chronometrist-plist-backend))
(chronometrist-backend-run-assertions backend)
(with-slots (hash-table) backend
(let ((latest-date (chronometrist-events-last-date hash-table)))
(cons latest-date
(gethash latest-date hash-table)))))
(when-let*
((latest-date (chronometrist-events-last-date hash-table))
(records (gethash latest-date hash-table)))
(cons latest-date records))))
;; latest-date-records:1 ends here
;; [[file:chronometrist.org::*latest-record][latest-record:1]]
(cl-defmethod chronometrist-latest-record ((backend chronometrist-plist-backend))
(chronometrist-sexp-in-file (chronometrist-backend-file backend)
(goto-char (point-max))
(backward-list)
(ignore-errors (read (current-buffer)))))
;; latest-record:1 ends here
;; [[file:chronometrist.org::*to-hash-table][to-hash-table:1]]
(cl-defmethod chronometrist-to-hash-table ((backend chronometrist-plist-backend))
(chronometrist-sexp-in-file (chronometrist-backend-file backend)
@ -1209,6 +1193,7 @@ STREAM (which is the value of `current-buffer')."
;; [[file:chronometrist.org::*insert][insert:1]]
(cl-defmethod chronometrist-insert ((backend chronometrist-plist-backend) plist)
(chronometrist-backend-run-assertions backend)
(chronometrist-sexp-in-file (chronometrist-backend-file backend)
(goto-char (point-max))
;; If we're adding the first s-exp in the file, don't add a
@ -1221,6 +1206,7 @@ STREAM (which is the value of `current-buffer')."
;; [[file:chronometrist.org::*remove-last][remove-last:1]]
(cl-defmethod chronometrist-remove-last ((backend chronometrist-plist-backend))
(chronometrist-backend-run-assertions backend)
(chronometrist-sexp-in-file (chronometrist-backend-file backend)
(goto-char (point-max))
;; this condition should never really occur, since we insert a
@ -1230,14 +1216,6 @@ STREAM (which is the value of `current-buffer')."
(chronometrist-sexp-delete-list)))
;; remove-last:1 ends here
;; [[file:chronometrist.org::*replace-last][replace-last:1]]
(cl-defmethod chronometrist-replace-last ((backend chronometrist-plist-backend) plist)
(chronometrist-sexp-in-file (chronometrist-backend-file backend)
(goto-char (chronometrist-remove-last backend))
(funcall chronometrist-sexp-pretty-print-function plist (current-buffer))
(save-buffer)))
;; replace-last:1 ends here
;; [[file:chronometrist.org::*reindent-buffer][reindent-buffer:1]]
(defun chronometrist-sexp-reindent-buffer ()
"Reindent the current buffer.
@ -1358,15 +1336,6 @@ Return
:modify))))
;; file-change-type:1 ends here
;; [[file:chronometrist.org::*task-records-for-date][task-records-for-date:1]]
(cl-defmethod chronometrist-task-records-for-date ((backend chronometrist-plist-backend) task date-ts)
(let* ((date (chronometrist-date-iso date-ts))
(records (gethash date (chronometrist-backend-hash-table backend))))
(cl-loop for record in records
when (equal task (plist-get record :name))
collect record)))
;; task-records-for-date:1 ends here
;; [[file:chronometrist.org::*to-file][to-file:1]]
(cl-defmethod chronometrist-to-file (hash-table (backend chronometrist-plist-backend) file)
(delete-file file)
@ -1435,9 +1404,47 @@ Return
;; [[file:chronometrist.org::*to-list][to-list:1]]
(cl-defmethod chronometrist-to-list ((backend chronometrist-plist-backend))
(chronometrist-backend-run-assertions backend)
(chronometrist-loop-sexp-file for expr in (chronometrist-backend-file backend) collect expr))
;; to-list:1 ends here
;; [[file:chronometrist.org::#program-backend-plist-latest-record][latest-record:1]]
(cl-defmethod chronometrist-latest-record ((backend chronometrist-plist-backend))
(chronometrist-backend-run-assertions backend)
(chronometrist-sexp-in-file (chronometrist-backend-file backend)
(goto-char (point-max))
(backward-list)
(ignore-errors (read (current-buffer)))))
;; latest-record:1 ends here
;; [[file:chronometrist.org::*task-records-for-date][task-records-for-date:1]]
(cl-defmethod chronometrist-task-records-for-date ((backend chronometrist-plist-backend) task date-ts)
(chronometrist-backend-run-assertions backend)
(let* ((date (chronometrist-date-iso date-ts))
(records (gethash date (chronometrist-backend-hash-table backend))))
(cl-loop for record in records
when (equal task (plist-get record :name))
collect record)))
;; task-records-for-date:1 ends here
;; [[file:chronometrist.org::*replace-last][replace-last:1]]
(cl-defmethod chronometrist-replace-last ((backend chronometrist-plist-backend) plist)
(chronometrist-sexp-in-file (chronometrist-backend-file backend)
(goto-char (chronometrist-remove-last backend))
(funcall chronometrist-sexp-pretty-print-function plist (current-buffer))
(save-buffer)))
;; replace-last:1 ends here
;; [[file:chronometrist.org::*count-records][count-records:1]]
(cl-defmethod chronometrist-count-records ((backend chronometrist-plist-backend))
(chronometrist-sexp-in-file (chronometrist-backend-file backend)
(goto-char (point-min))
(cl-loop with count = 0
while (ignore-errors (read (current-buffer)))
do (cl-incf count)
finally return count)))
;; count-records:1 ends here
;; [[file:chronometrist.org::*backend][backend:1]]
(defclass chronometrist-plist-group-backend (chronometrist-elisp-sexp-backend chronometrist-file-backend-mixin)
((extension :initform "plg"

View File

@ -1866,36 +1866,20 @@ STREAM (which is the value of `current-buffer')."
:group 'chronometrist)
#+END_SRC
**** count-records :reader:method:
#+BEGIN_SRC emacs-lisp
(cl-defmethod chronometrist-count-records ((backend chronometrist-plist-backend))
(chronometrist-sexp-in-file (chronometrist-backend-file backend)
(goto-char (point-min))
(cl-loop with count = 0
while (ignore-errors (read (current-buffer)))
do (cl-incf count)
finally return count)))
#+END_SRC
**** latest-date-records :reader:method:
In this backend, it's easier to implement this in terms of [[#program-backend-plist-latest-record][=chronometrist-latest-record=]] than the other way round.
#+BEGIN_SRC emacs-lisp
(cl-defmethod chronometrist-latest-date-records ((backend chronometrist-plist-backend))
(chronometrist-backend-run-assertions backend)
(with-slots (hash-table) backend
(let ((latest-date (chronometrist-events-last-date hash-table)))
(cons latest-date
(gethash latest-date hash-table)))))
(when-let*
((latest-date (chronometrist-events-last-date hash-table))
(records (gethash latest-date hash-table)))
(cons latest-date records))))
#+END_SRC
**** latest-record :reader:method:
#+BEGIN_SRC emacs-lisp
(cl-defmethod chronometrist-latest-record ((backend chronometrist-plist-backend))
(chronometrist-sexp-in-file (chronometrist-backend-file backend)
(goto-char (point-max))
(backward-list)
(ignore-errors (read (current-buffer)))))
#+END_SRC
**** to-hash-table :writer:
**** to-hash-table :writer:method:
#+BEGIN_SRC emacs-lisp
(cl-defmethod chronometrist-to-hash-table ((backend chronometrist-plist-backend))
(chronometrist-sexp-in-file (chronometrist-backend-file backend)
@ -1928,6 +1912,7 @@ STREAM (which is the value of `current-buffer')."
**** insert :writer:method:
#+BEGIN_SRC emacs-lisp
(cl-defmethod chronometrist-insert ((backend chronometrist-plist-backend) plist)
(chronometrist-backend-run-assertions backend)
(chronometrist-sexp-in-file (chronometrist-backend-file backend)
(goto-char (point-max))
;; If we're adding the first s-exp in the file, don't add a
@ -1941,6 +1926,7 @@ STREAM (which is the value of `current-buffer')."
**** remove-last :writer:method:
#+BEGIN_SRC emacs-lisp
(cl-defmethod chronometrist-remove-last ((backend chronometrist-plist-backend))
(chronometrist-backend-run-assertions backend)
(chronometrist-sexp-in-file (chronometrist-backend-file backend)
(goto-char (point-max))
;; this condition should never really occur, since we insert a
@ -1950,15 +1936,6 @@ STREAM (which is the value of `current-buffer')."
(chronometrist-sexp-delete-list)))
#+END_SRC
**** replace-last :writer:method:
#+BEGIN_SRC emacs-lisp
(cl-defmethod chronometrist-replace-last ((backend chronometrist-plist-backend) plist)
(chronometrist-sexp-in-file (chronometrist-backend-file backend)
(goto-char (chronometrist-remove-last backend))
(funcall chronometrist-sexp-pretty-print-function plist (current-buffer))
(save-buffer)))
#+END_SRC
**** reindent-buffer :command:
#+BEGIN_SRC emacs-lisp
(defun chronometrist-sexp-reindent-buffer ()
@ -2174,15 +2151,6 @@ Return
(setq chronometrist--file-state chronometrist--file-state-old
chronometrist-events chronometrist-events-old))))
#+END_SRC
**** task-records-for-date :reader:
#+BEGIN_SRC emacs-lisp
(cl-defmethod chronometrist-task-records-for-date ((backend chronometrist-plist-backend) task date-ts)
(let* ((date (chronometrist-date-iso date-ts))
(records (gethash date (chronometrist-backend-hash-table backend))))
(cl-loop for record in records
when (equal task (plist-get record :name))
collect record)))
#+END_SRC
**** to-file :writer:method:
#+BEGIN_SRC emacs-lisp
(cl-defmethod chronometrist-to-file (hash-table (backend chronometrist-plist-backend) file)
@ -2254,9 +2222,55 @@ Return
**** to-list :reader:method:
#+BEGIN_SRC emacs-lisp
(cl-defmethod chronometrist-to-list ((backend chronometrist-plist-backend))
(chronometrist-backend-run-assertions backend)
(chronometrist-loop-sexp-file for expr in (chronometrist-backend-file backend) collect expr))
#+END_SRC
**** extended protocol
***** latest-record :reader:method:
:PROPERTIES:
:CUSTOM_ID: program-backend-plist-latest-record
:END:
#+BEGIN_SRC emacs-lisp
(cl-defmethod chronometrist-latest-record ((backend chronometrist-plist-backend))
(chronometrist-backend-run-assertions backend)
(chronometrist-sexp-in-file (chronometrist-backend-file backend)
(goto-char (point-max))
(backward-list)
(ignore-errors (read (current-buffer)))))
#+END_SRC
***** task-records-for-date :reader:method:
#+BEGIN_SRC emacs-lisp
(cl-defmethod chronometrist-task-records-for-date ((backend chronometrist-plist-backend) task date-ts)
(chronometrist-backend-run-assertions backend)
(let* ((date (chronometrist-date-iso date-ts))
(records (gethash date (chronometrist-backend-hash-table backend))))
(cl-loop for record in records
when (equal task (plist-get record :name))
collect record)))
#+END_SRC
***** replace-last :writer:method:
#+BEGIN_SRC emacs-lisp
(cl-defmethod chronometrist-replace-last ((backend chronometrist-plist-backend) plist)
(chronometrist-sexp-in-file (chronometrist-backend-file backend)
(goto-char (chronometrist-remove-last backend))
(funcall chronometrist-sexp-pretty-print-function plist (current-buffer))
(save-buffer)))
#+END_SRC
***** count-records :reader:method:
#+BEGIN_SRC emacs-lisp
(cl-defmethod chronometrist-count-records ((backend chronometrist-plist-backend))
(chronometrist-sexp-in-file (chronometrist-backend-file backend)
(goto-char (point-min))
(cl-loop with count = 0
while (ignore-errors (read (current-buffer)))
do (cl-incf count)
finally return count)))
#+END_SRC
*** plist group backend
This is largely like the plist backend, but plists are grouped by date by wrapping them in a tagged list -

View File

@ -364,53 +364,55 @@ Tests to be added -
1. to-hash-table
2. to-file
The order of these tests is important - the last test for each case is one which moves into the next case.
#+BEGIN_SRC emacs-lisp
(ert-deftest chronometrist-backend-tests ()
(let ((b chronometrist-test-backend)
(plist-1 (car chronometrist-test-records))
(let ((plist-1 (car chronometrist-test-records))
(plist-2 (cl-second chronometrist-test-records))
(today-ts (chronometrist-date-ts)))
(unwind-protect
(progn
;; * file does not exist *
(should-error (chronometrist-latest-date-records b))
(should-error (chronometrist-insert b plist-1))
(should-error (chronometrist-remove-last b))
(should-error (chronometrist-to-list b))
;; extended protocol
(should-error (chronometrist-latest-record b))
(should-error (chronometrist-task-records-for-date b "Test" today-ts))
(should-error (chronometrist-replace-last b plist-2))
(cl-loop for b in chronometrist-test-backends do
(unwind-protect
(progn
;; * file does not exist *
(should-error (chronometrist-latest-date-records b))
(should-error (chronometrist-insert b plist-1))
(should-error (chronometrist-remove-last b))
(should-error (chronometrist-to-list b))
;; extended protocol
(should-error (chronometrist-latest-record b))
(should-error (chronometrist-task-records-for-date b "Test" today-ts))
(should-error (chronometrist-replace-last b plist-2))
(should (chronometrist-create-file b))
(should (chronometrist-create-file b))
;; * file exists but has no records *
(should (not (chronometrist-create-file b)))
(should (not (chronometrist-latest-date-records b)))
(should-error (chronometrist-remove-last b))
(should (not (chronometrist-to-list b)))
;; extended protocol
(should (not (chronometrist-latest-record b)))
(should (not (chronometrist-task-records-for-date b "Test" today-ts)))
(should-error (chronometrist-replace-last b plist-2))
;; * file exists but has no records *
(should (not (chronometrist-create-file b)))
(should (not (chronometrist-latest-date-records b)))
(should-error (chronometrist-remove-last b))
(should (not (chronometrist-to-list b)))
;; extended protocol
(should (not (chronometrist-latest-record b)))
(should (not (chronometrist-task-records-for-date b "Test" today-ts)))
(should-error (chronometrist-replace-last b plist-2))
(should (chronometrist-insert b plist-1))
(should (chronometrist-insert b plist-1))
;; * backend has a single active record *
;; * backend has a single active record *
;; * backend has a single inactive record *
;; * backend has a single active day-crossing record *
;; * backend has a single inactive day-crossing record *
;; * backend has a single inactive record *
;; * backend has a single active day-crossing record *
;; * backend has a single inactive day-crossing record *
;; * backend has two records and one is active *
;; * backend has two records and both are inactive *
;; * backend has two day-crossing records and one is active *
;; * backend has two day-crossing records and both are inactive *
)
;; cleanup - remove test backend file
(let ((file (chronometrist-backend-file b)))
(chronometrist-reset-internal b)
(when file
(delete-file file)
(kill-buffer (get-file-buffer file)))))))
;; * backend has two records and one is active *
;; * backend has two records and both are inactive *
;; * backend has two day-crossing records and one is active *
;; * backend has two day-crossing records and both are inactive *
)
;; cleanup - remove test backend file
(let ((file (chronometrist-backend-file b)))
(chronometrist-reset-internal b)
(when (and file (file-exists-p file))
(delete-file file)
(kill-buffer (get-file-buffer file))))))))
#+END_SRC
*** count-records