This repository has been archived on 2022-05-13. You can view files and clone it, but cannot push or open issues or pull requests.
chronometrist/tests/chronometrist-tests.el

419 lines
17 KiB
EmacsLisp

(require 'chronometrist)
(ert-deftest chronometrist-format-duration ()
(should
(equal (chronometrist-format-duration 0) " -"))
(should
(equal (chronometrist-format-duration 1) " 1"))
(should
(equal (chronometrist-format-duration 10) " 10"))
(should
(equal (chronometrist-format-duration 70) " 1:10"))
(should
(equal (chronometrist-format-duration (+ (* 10 60) 10))
" 10:10"))
(should
(equal (chronometrist-format-duration (+ (* 1 60 60) (* 10 60) 10))
" 1:10:10"))
(should
(equal (chronometrist-format-duration (+ (* 10 60 60) (* 10 60) 10))
"10:10:10")))
(ert-deftest chronometrist-previous-week-start ()
(let ((chronometrist-report-week-start-day "Sunday")
(ts (chronometrist-iso-date-to-ts "2018-09-02")))
(should (ts= (chronometrist-previous-week-start
(chronometrist-iso-date-to-ts "2018-09-01"))
(chronometrist-iso-date-to-ts "2018-08-26")))
(should (ts= ts (chronometrist-previous-week-start
(chronometrist-iso-date-to-ts "2018-09-02"))))
(should (ts= ts (chronometrist-previous-week-start
(chronometrist-iso-date-to-ts "2018-09-03"))))
(should (ts= ts (chronometrist-previous-week-start
(chronometrist-iso-date-to-ts "2018-09-04"))))
(should (ts= ts (chronometrist-previous-week-start
(chronometrist-iso-date-to-ts "2018-09-05"))))
(should (ts= ts (chronometrist-previous-week-start
(chronometrist-iso-date-to-ts "2018-09-06"))))
(should (ts= ts (chronometrist-previous-week-start
(chronometrist-iso-date-to-ts "2018-09-07"))))
(should (ts= ts (chronometrist-previous-week-start
(chronometrist-iso-date-to-ts "2018-09-08"))))))
(ert-deftest chronometrist-plist-remove ()
(should
(equal (chronometrist-plist-remove '(:a 1 :b 2 :c 3 :d 4) :a)
'(:b 2 :c 3 :d 4)))
(should
(equal (chronometrist-plist-remove '(:a 1 :b 2 :c 3 :d 4) :b)
'(:a 1 :c 3 :d 4)))
(should
(equal (chronometrist-plist-remove '(:a 1 :b 2 :c 3 :d 4) :c)
'(:a 1 :b 2 :d 4)))
(should
(equal (chronometrist-plist-remove '(:a 1 :b 2 :c 3 :d 4) :d)
'(:a 1 :b 2 :c 3)))
(should
(equal (chronometrist-plist-remove '(:a 1 :b 2 :c 3 :d 4) :a :b)
'(:c 3 :d 4)))
(should
(equal (chronometrist-plist-remove '(:a 1 :b 2 :c 3 :d 4) :a :d)
'(:b 2 :c 3)))
(should
(equal (chronometrist-plist-remove '(:a 1 :b 2 :c 3 :d 4) :c :d)
'(:a 1 :b 2)))
(should (equal
(chronometrist-plist-remove '(:a 1 :b 2 :c 3 :d 4) :a :b :c :d)
nil))
(should
(equal (chronometrist-plist-remove '(:a 1 :b 2 :c 3 :d 4) :d :a)
'(:b 2 :c 3))))
(ert-deftest plist-p ()
(should (eq t (chronometrist-plist-p '(:a 1 :b 2))))
(should (eq nil (chronometrist-plist-p '(0 :a 1 :b 2))))
(should (eq nil (chronometrist-plist-p '(:a 1 :b 2 3)))))
(ert-deftest plist-pp-buffer ()
(should
(equal
(chronometrist-plist-pp-to-string
'(:name "Task"
:tags (foo bar)
:comment ((70 . "baz")
"zot"
(16 . "frob")
(20 20 "quux"))
:start "2020-06-25T19:27:57+0530"
:stop "2020-06-25T19:43:30+0530"))
(concat
"(:name \"Task\"\n"
" :tags (foo bar)\n"
" :comment ((70 . \"baz\")\n"
" \"zot\"\n"
" (16 . \"frob\")\n"
" (20 20 \"quux\"))\n"
" :start \"2020-06-25T19:27:57+0530\"\n"
" :stop \"2020-06-25T19:43:30+0530\")")))
(should
(equal
(chronometrist-plist-pp-to-string
'(:name "Singing"
:tags (classical solo)
:piece ((:composer "Gioachino Rossini"
:name "Il barbiere di Siviglia"
:aria ("All'idea di quel metallo" "Dunque io son"))
(:composer "Ralph Vaughan Williams"
:name "Songs of Travel"
:movement ((4 . "Youth and Love")
(5 . "In Dreams")
(7 . "Wither Must I Wander?")))
(:composer "Ralph Vaughan Williams"
:name "Merciless Beauty"
:movement 1)
(:composer "Franz Schubert"
:name "Winterreise"
:movement ((1 . "Gute Nacht")
(2 . "Die Wetterfahne")
(4 . "Erstarrung"))))
:start "2020-11-01T12:01:20+0530"
:stop "2020-11-01T13:08:32+0530"))
(concat
"(:name \"Singing\"\n"
" :tags (classical solo)\n"
" :piece ((:composer \"Gioachino Rossini\"\n"
" :name \"Il barbiere di Siviglia\"\n"
" :aria (\"All'idea di quel metallo\" \"Dunque io son\"))\n"
" (:composer \"Ralph Vaughan Williams\"\n"
" :name \"Songs of Travel\"\n"
" :movement ((4 . \"Youth and Love\")\n"
" (5 . \"In Dreams\")\n"
" (7 . \"Wither Must I Wander?\")))\n"
" (:composer \"Ralph Vaughan Williams\"\n"
" :name \"Merciless Beauty\"\n"
" :movement 1)\n"
" (:composer \"Franz Schubert\"\n"
" :name \"Winterreise\"\n"
" :movement ((1 . \"Gute Nacht\")\n"
" (2 . \"Die Wetterfahne\")\n"
" (4 . \"Erstarrung\"))))\n"
" :start \"2020-11-01T12:01:20+0530\"\n"
" :stop \"2020-11-01T13:08:32+0530\")")))
(should (equal
(chronometrist-plist-pp-to-string
'(:name "Cooking"
:tags (lunch)
:recipe (:name "moong-masoor ki dal"
:url "https://www.mirchitales.com/moong-masoor-dal-red-and-yellow-lentil-curry/")
:start "2020-09-23T15:22:39+0530"
:stop "2020-09-23T16:29:49+0530"))
(concat
"(:name \"Cooking\"\n"
" :tags (lunch)\n"
" :recipe (:name \"moong-masoor ki dal\"\n"
" :url \"https://www.mirchitales.com/moong-masoor-dal-red-and-yellow-lentil-curry/\")\n"
" :start \"2020-09-23T15:22:39+0530\"\n"
" :stop \"2020-09-23T16:29:49+0530\")")))
(should (equal
(chronometrist-plist-pp-to-string
'(:name "Exercise"
:tags (warm-up)
:start "2018-11-21T15:35:04+0530"
:stop "2018-11-21T15:38:41+0530"
:comment ("stretching" (25 10 "push-ups"))))
(concat
"(:name \"Exercise\"\n"
" :tags (warm-up)\n"
" :start \"2018-11-21T15:35:04+0530\"\n"
" :stop \"2018-11-21T15:38:41+0530\"\n"
" :comment (\"stretching\" (25 10 \"push-ups\")))"))))
(defvar chronometrist-test-file
(make-temp-file
"chronometrist-test-" nil ".sexp"
(with-output-to-string
(mapc
(lambda (plist)
;; to use this, we'd have to move `chronometrist-plist-pp' before this
;; definition, and I'm perfectly content with where it is
;; right now
(chronometrist-plist-pp plist) (princ "\n\n")
;; (print plist) (princ "\n")
)
'((:name "Programming"
:start "2018-01-01T00:00:00+0530"
:stop "2018-01-01T01:00:00+0530")
(:name "Swimming"
:start "2018-01-01T02:00:00+0530"
:stop "2018-01-01T03:00:00+0530")
(:name "Cooking"
:start "2018-01-01T04:00:00+0530"
:stop "2018-01-01T05:00:00+0530")
(:name "Guitar"
:start "2018-01-01T06:00:00+0530"
:stop "2018-01-01T07:00:00+0530")
(:name "Cycling"
:start "2018-01-01T08:00:00+0530"
:stop "2018-01-01T09:00:00+0530")
(:name "Programming"
:start "2018-01-02T23:00:00+0530"
:stop "2018-01-03T01:00:00+0530")
(:name "Cooking"
:start "2018-01-03T23:00:00+0530"
:stop "2018-01-04T01:00:00+0530")
(:name "Programming"
:tags (bug-hunting)
:project "Chronometrist"
:component "goals"
:start "2020-05-09T20:03:25+0530"
:stop "2020-05-09T20:05:55+0530")
(:name "Arrangement/new edition"
:tags (new edition)
:song "Songs of Travel"
:composer "Vaughan Williams, Ralph"
:start "2020-05-10T00:04:14+0530"
:stop "2020-05-10T00:25:48+0530")
(:name "Guitar"
:tags (classical warm-up)
:start "2020-05-10T15:41:14+0530"
:stop "2020-05-10T15:55:42+0530")
(:name "Guitar"
:tags (classical solo)
:start "2020-05-10T16:00:00+0530"
:stop "2020-05-10T16:30:00+0530")
(:name "Programming"
:tags (reading)
:book "Smalltalk-80: The Language and Its Implementation"
:start "2020-05-10T16:33:17+0530"
:stop "2020-05-10T17:10:48+0530"))))))
(defmacro chronometrist-tests--change-type-and-update (state)
`(prog1 (chronometrist-file-change-type ,state)
(setq ,state
(list :last (chronometrist-file-hash :before-last nil)
:rest (chronometrist-file-hash nil :before-last t)))))
(ert-deftest task-list ()
(let ((task-list (chronometrist-task-list)))
(should (listp task-list))
(should (seq-every-p #'stringp task-list))))
(ert-deftest file-hash ()
(-let* ((chronometrist-file chronometrist-test-file)
((last-start last-end)
(chronometrist-file-hash :before-last nil))
((rest-start rest-end rest-hash)
(chronometrist-file-hash nil :before-last t)))
(message "chronometrist - file-hash test - file path is %s"
chronometrist-test-file)
(should (= 1 rest-start))
(should (= 1254 rest-end))
(should (= 1256 last-start))
(should (= 1426 last-end))))
(ert-deftest chronometrist-file-change-type ()
(let* ((chronometrist-file chronometrist-test-file)
(test-contents (with-current-buffer (find-file-noselect chronometrist-file)
(buffer-substring (point-min) (point-max))))
(chronometrist--file-state-old chronometrist--file-state)
(chronometrist--file-state (list :last (chronometrist-file-hash :before-last nil)
:rest (chronometrist-file-hash nil :before-last t)))
(chronometrist-events-old chronometrist-events))
(chronometrist-events-populate)
(unwind-protect
(progn
(should
(eq nil (chronometrist-file-change-type chronometrist--file-state)))
(should
(eq :append
(progn
(chronometrist-sexp-new
'(:name "Append Test"
:start "2021-02-01T13:06:46+0530"
:stop "2021-02-01T13:06:49+0530"))
(chronometrist-tests--change-type-and-update chronometrist--file-state))))
(should
(eq :modify
(progn
(chronometrist-sexp-replace-last
'(:name "Modify Test"
:tags (some tags)
:start "2021-02-01T13:06:46+0530"
:stop "2021-02-01T13:06:49+0530"))
(chronometrist-tests--change-type-and-update chronometrist--file-state))))
(should
(eq :remove
(progn
(chronometrist-sexp-in-file chronometrist-file
(goto-char (point-max))
(backward-list 1)
(chronometrist-sexp-delete-list 1)
(save-buffer))
(chronometrist-tests--change-type-and-update chronometrist--file-state))))
(should
(eq t
(progn
(chronometrist-sexp-in-file chronometrist-file
(goto-char (point-min))
(chronometrist-plist-pp '(:name "Other Change Test"
:start "2021-02-02T17:39:40+0530"
:stop "2021-02-02T17:39:44+0530")
(current-buffer))
(save-buffer))
(chronometrist-tests--change-type-and-update chronometrist--file-state)))))
;; restore test file contents
(with-current-buffer (find-file-noselect chronometrist-file)
(delete-region (point-min) (point-max))
(insert test-contents)
(save-buffer))
(setq chronometrist--file-state chronometrist--file-state-old
chronometrist-events chronometrist-events-old))))
(ert-deftest chronometrist-apply-time ()
(should
(equal (ts-format "%FT%T%z" (chronometrist-apply-time "01:02:03" "2021-02-17T01:20:18+0530"))
"2021-02-17T01:02:03+0530")))
(ert-deftest chronometrist-events-maybe-split ()
(should
(null (chronometrist-events-maybe-split
'(:name "Task"
:start "2021-02-17T01:33:12+0530"
:stop "2021-02-17T01:56:08+0530"))))
(should
(equal (chronometrist-events-maybe-split
'(:name "Guitar"
:tags (classical warm-up)
:start "2021-02-12T23:45:21+0530"
:stop "2021-02-13T00:03:46+0530"))
'((:name "Guitar"
:tags (classical warm-up)
:start "2021-02-12T23:45:21+0530"
:stop "2021-02-13T00:00:00+0530")
(:name "Guitar"
:tags (classical warm-up)
:start "2021-02-13T00:00:00+0530"
:stop "2021-02-13T00:03:46+0530")))))
(ert-deftest chronometrist-task-time-one-day ()
(let ((chronometrist-file-old chronometrist-file)
(chronometrist-file chronometrist-test-file)
(chronometrist--file-state-old chronometrist--file-state)
(chronometrist-events-old chronometrist-events)
(ts-1 (chronometrist-iso-date-to-ts "2018-01-01"))
(ts-2 (chronometrist-iso-date-to-ts "2018-01-02"))
(ts-3 (chronometrist-iso-date-to-ts "2018-01-03"))
(1-hour 3600))
(chronometrist-events-populate)
(unwind-protect
(progn
(should
(equal (chronometrist-task-time-one-day "Programming" ts-1)
1-hour))
(should
(equal (chronometrist-task-time-one-day "Swimming" ts-1)
1-hour))
(should
(equal (chronometrist-task-time-one-day "Cooking" ts-1)
1-hour))
(should
(equal (chronometrist-task-time-one-day "Guitar" ts-1)
1-hour))
(should
(equal (chronometrist-task-time-one-day "Cycling" ts-1)
1-hour))
(should
(equal (chronometrist-task-time-one-day "Programming" ts-2)
1-hour))
(should
(equal (chronometrist-task-time-one-day "Programming" ts-3)
1-hour)))
(setq chronometrist-file chronometrist-file-old
chronometrist--file-state chronometrist--file-state-old)
;; Not sure why simply assigning `chronometrist-events-old' did not restore
;; the value - it seems to work in `chronometrist-file-change-type'
(chronometrist-events-populate))))
(ert-deftest chronometrist-midnight-spanning-p ()
(should
(null
(chronometrist-midnight-spanning-p "2021-02-17T01:33:12+0530"
"2021-02-17T01:56:08+0530"
"00:00:00")))
(should
(equal
(chronometrist-midnight-spanning-p "2021-02-19T23:45:36+0530"
"2021-02-20T00:18:40+0530"
"00:00:00")
'((:start "2021-02-19T23:45:36+0530"
:stop "2021-02-20T00:00:00+0530")
(:start "2021-02-20T00:00:00+0530"
:stop "2021-02-20T00:18:40+0530"))))
(should
(equal
(chronometrist-midnight-spanning-p "2021-02-19T23:45:36+0530"
"2021-02-20T03:18:40+0530"
"01:20:30")
'((:start "2021-02-19T23:45:36+0530"
:stop "2021-02-20T01:20:30+0530")
(:start "2021-02-20T01:20:30+0530"
:stop "2021-02-20T03:18:40+0530")))))
(ert-deftest chronometrist-details-row-helper ()
(let ((tags '(a b c))
(plist '(:a 1 :b 2 :c 3)))
(let ((chronometrist-details-display-tags nil)
(chronometrist-details-display-key-values nil))
(should (equal (chronometrist-details-rows-helper tags) ""))
(should (equal (chronometrist-details-rows-helper plist) "")))
(let ((chronometrist-details-display-tags "%s")
(chronometrist-details-display-key-values "%s"))
(should (equal (chronometrist-details-rows-helper nil) ""))
(should (equal (chronometrist-details-rows-helper nil) ""))
(should (equal (chronometrist-details-rows-helper tags)
"a b c"))
(should (equal (chronometrist-details-rows-helper plist)
"1 2 3")))))