Implement multi-backend tests
Reorganize plist backend methods Address some failing tests for plist backend methods
This commit is contained in:
parent
909be83e3a
commit
5d5b423c59
|
@ -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"
|
||||
|
|
|
@ -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 -
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Reference in New Issue