* [PATCH] When testing, fake the current time more robustly
@ 2019-02-12 22:44 Paul Eggert
2019-02-12 23:50 ` Kyle Meyer
0 siblings, 1 reply; 3+ messages in thread
From: Paul Eggert @ 2019-02-12 22:44 UTC (permalink / raw)
To: Emacs-orgmode; +Cc: Paul Eggert
The old approach required Lisp code to use (current-time)
explicitly when calling other primitives, e.g., (float-time
(current-time)). The new approach fakes all the primitives,
so that Lisp code can now use expressions like plain (float-time).
* testing/org-test.el (org-test-at-time): New macro.
* testing/lisp/test-org-colview.el (test-org-colview/columns-summary):
* testing/lisp/test-org-timer.el (test-org-timer/with-current-time):
* testing/lisp/test-org.el (test-org/org-read-date)
(test-org/deadline-close-p, test-org/deadline)
(test-org/schedule, test-org/time-stamp):
Use it.
---
testing/lisp/test-org-colview.el | 15 ++-------
testing/lisp/test-org-timer.el | 3 +-
testing/lisp/test-org.el | 57 ++++++++------------------------
testing/org-test.el | 52 +++++++++++++++++++++++++++++
4 files changed, 69 insertions(+), 58 deletions(-)
diff --git a/testing/lisp/test-org-colview.el b/testing/lisp/test-org-colview.el
index 532515b53..ed75090df 100644
--- a/testing/lisp/test-org-colview.el
+++ b/testing/lisp/test-org-colview.el
@@ -510,10 +510,7 @@
(should
(equal
"0min"
- (cl-letf (((symbol-function 'current-time)
- (lambda ()
- (apply #'encode-time
- (org-parse-time-string "<2014-03-04 Tue>")))))
+ (org-test-at-time "<2014-03-04 Tue>"
(org-test-with-temp-text
"* H
** S1
@@ -529,10 +526,7 @@
(should
(equal
"2d"
- (cl-letf (((symbol-function 'current-time)
- (lambda ()
- (apply #'encode-time
- (org-parse-time-string "<2014-03-04 Tue>")))))
+ (org-test-at-time "<2014-03-04 Tue>"
(org-test-with-temp-text
"* H
** S1
@@ -548,10 +542,7 @@
(should
(equal
"1d 12h"
- (cl-letf (((symbol-function 'current-time)
- (lambda ()
- (apply #'encode-time
- (org-parse-time-string "<2014-03-04 Tue>")))))
+ (org-test-at-time "<2014-03-04 Tue>"
(org-test-with-temp-text
"* H
** S1
diff --git a/testing/lisp/test-org-timer.el b/testing/lisp/test-org-timer.el
index f6bd5ab1a..27156dfa9 100644
--- a/testing/lisp/test-org-timer.el
+++ b/testing/lisp/test-org-timer.el
@@ -40,8 +40,7 @@ Also, mute output from `message'."
(defmacro test-org-timer/with-current-time (time &rest body)
"Run BODY, setting `current-time' output to TIME."
(declare (indent 1))
- `(cl-letf (((symbol-function 'current-time) (lambda () ,time)))
- ,@body))
+ `(org-test-at-time ,time ,@body))
\f
;;; Time conversion and formatting
diff --git a/testing/lisp/test-org.el b/testing/lisp/test-org.el
index feaacf673..c3bd07923 100644
--- a/testing/lisp/test-org.el
+++ b/testing/lisp/test-org.el
@@ -198,18 +198,14 @@
(should
(equal
"2015-03-04"
- (cl-letf (((symbol-function 'current-time)
- (lambda ()
- (apply #'encode-time (org-parse-time-string "2014-03-04")))))
+ (org-test-at-time "2014-03-04"
(org-read-date
t nil "+1y" nil
(apply #'encode-time (org-parse-time-string "2012-03-29"))))))
(should
(equal
"2013-03-29"
- (cl-letf (((symbol-function 'current-time)
- (lambda ()
- (apply #'encode-time (org-parse-time-string "2014-03-04")))))
+ (org-test-at-time "2014-03-04"
(org-read-date
t nil "++1y" nil
(apply #'encode-time (org-parse-time-string "2012-03-29"))))))
@@ -219,25 +215,19 @@
(should
(equal
"2014-04-01"
- (cl-letf (((symbol-function 'current-time)
- (lambda ()
- (apply #'encode-time (org-parse-time-string "2014-03-04")))))
+ (org-test-at-time "2014-03-04"
(let ((org-read-date-prefer-future t))
(org-read-date t nil "1")))))
(should
(equal
"2013-03-04"
- (cl-letf (((symbol-function 'current-time)
- (lambda ()
- (apply #'encode-time (org-parse-time-string "2012-03-29")))))
+ (org-test-at-time "2012-03-29"
(let ((org-read-date-prefer-future t))
(org-read-date t nil "3-4")))))
(should
(equal
"2012-03-04"
- (cl-letf (((symbol-function 'current-time)
- (lambda ()
- (apply #'encode-time (org-parse-time-string "2012-03-29")))))
+ (org-test-at-time "2012-03-29"
(let ((org-read-date-prefer-future nil))
(org-read-date t nil "3-4")))))
;; When set to `org-read-date-prefer-future' is set to `time', read
@@ -247,17 +237,13 @@
(should
(equal
"2012-03-30"
- (cl-letf (((symbol-function 'current-time)
- (lambda ()
- (apply #'encode-time (org-parse-time-string "2012-03-29 16:40")))))
+ (org-test-at-time "2012-03-29 16:40"
(let ((org-read-date-prefer-future 'time))
(org-read-date t nil "00:40" nil)))))
(should-not
(equal
"2012-03-30"
- (cl-letf (((symbol-function 'current-time)
- (lambda ()
- (apply #'encode-time (org-parse-time-string "2012-03-29 16:40")))))
+ (org-test-at-time "2012-03-29 16:40"
(let ((org-read-date-prefer-future 'time))
(org-read-date t nil "29 00:40" nil)))))
;; Caveat: `org-read-date-prefer-future' always refers to current
@@ -265,9 +251,7 @@
(should
(equal
"2014-04-01"
- (cl-letf (((symbol-function 'current-time)
- (lambda ()
- (apply #'encode-time (org-parse-time-string "2014-03-04")))))
+ (org-test-at-time "2014-03-04"
(let ((org-read-date-prefer-future t))
(org-read-date
t nil "1" nil
@@ -275,9 +259,7 @@
(should
(equal
"2014-03-25"
- (cl-letf (((symbol-function 'current-time)
- (lambda ()
- (apply #'encode-time (org-parse-time-string "2014-03-04")))))
+ (org-test-at-time "2014-03-04"
(let ((org-read-date-prefer-future t))
(org-read-date
t nil "25" nil
@@ -376,11 +358,7 @@
(ert-deftest test-org/deadline-close-p ()
"Test `org-deadline-close-p' specifications."
- ;; Pretend that the current time is 2016-06-03 Fri 01:43
- (cl-letf (((symbol-function 'current-time)
- (lambda ()
- (apply #'encode-time
- (org-parse-time-string "2016-06-03 Fri 01:43")))))
+ (org-test-at-time "2016-06-03 Fri 01:43"
;; Timestamps are close if they are within `ndays' of lead time.
(org-test-with-temp-text "* Heading"
(should (org-deadline-close-p "2016-06-03 Fri" 0))
@@ -4859,10 +4837,7 @@ Paragraph<point>"
;; Accept delta time, e.g., "+2d".
(should
(equal "* H\nDEADLINE: <2015-03-04>\n"
- (cl-letf (((symbol-function 'current-time)
- (lambda (&rest args)
- (apply #'encode-time
- (org-parse-time-string "2014-03-04")))))
+ (org-test-at-time "2014-03-04"
(org-test-with-temp-text "* H"
(let ((org-adapt-indentation nil)
(org-last-inserted-timestamp nil))
@@ -4976,10 +4951,7 @@ Paragraph<point>"
;; Accept delta time, e.g., "+2d".
(should
(equal "* H\nSCHEDULED: <2015-03-04>\n"
- (cl-letf (((symbol-function 'current-time)
- (lambda (&rest args)
- (apply #'encode-time
- (org-parse-time-string "2014-03-04")))))
+ (org-test-at-time "2014-03-04"
(org-test-with-temp-text "* H"
(let ((org-adapt-indentation nil)
(org-last-inserted-timestamp nil))
@@ -6871,10 +6843,7 @@ CLOCK: [2012-03-29 Thu 10:00]--[2012-03-29 Thu 16:40] => 6:40"
(string-match
"Te<2014-03-04 .*? 00:41>xt"
(org-test-with-temp-text "Te<point>xt"
- (cl-letf (((symbol-function 'current-time)
- (lambda ()
- (apply #'encode-time
- (org-parse-time-string "2014-03-04 00:41")))))
+ (org-test-at-time "2014-03-04 00:41"
(org-time-stamp '(16))
(buffer-string)))))
;; When optional argument is non-nil, insert an inactive timestamp.
diff --git a/testing/org-test.el b/testing/org-test.el
index 8bf75b421..39c346410 100644
--- a/testing/org-test.el
+++ b/testing/org-test.el
@@ -418,6 +418,58 @@ Load all test files first."
(ert "\\(org\\|ob\\)")
(org-test-kill-all-examples))
+(defmacro org-test-at-time (time &rest body)
+ "Run body while pretending that the current time is TIME.
+TIME can be a non-nil Lisp time value, or a string specifying a date and time."
+ (declare (indent 1))
+ (let ((tm (cl-gensym))
+ (at (cl-gensym)))
+ `(let* ((,tm ,time)
+ (,at (if (stringp ,tm)
+ (apply #'encode-time (org-parse-time-string ,tm))
+ ,tm)))
+ (cl-letf
+ ;; Wrap builtins whose behavior can depend on the current time.
+ (((symbol-function 'current-time)
+ (lambda () ,at))
+ ((symbol-function 'current-time-string)
+ (lambda (&optional time &rest args)
+ (apply ,(symbol-function 'current-time-string)
+ (or time ,at) args)))
+ ((symbol-function 'current-time-zone)
+ (lambda (&optional time &rest args)
+ (apply ,(symbol-function 'current-time-zone)
+ (or time ,at) args)))
+ ((symbol-function 'decode-time)
+ (lambda (&optional time) (funcall ,(symbol-function 'decode-time)
+ (or time ,at))))
+ ((symbol-function 'encode-time)
+ (lambda (time &rest args)
+ (apply ,(symbol-function 'encode-time) (or time ,at) args)))
+ ((symbol-function 'float-time)
+ (lambda (&optional time)
+ (funcall ,(symbol-function 'float-time) (or time ,at))))
+ ((symbol-function 'format-time-string)
+ (lambda (format &optional time &rest args)
+ (apply ,(symbol-function 'format-time-string)
+ format (or time ,at) args)))
+ ((symbol-function 'set-file-times)
+ (lambda (file &optional time)
+ (funcall ,(symbol-function 'set-file-times) file (or time ,at))))
+ ((symbol-function 'time-add)
+ (lambda (a b) (funcall ,(symbol-function 'time-add)
+ (or a ,at) (or b ,at))))
+ ((symbol-function 'time-equal-p)
+ (lambda (a b) (funcall ,(symbol-function 'time-equal-p)
+ (or a ,at) (or b ,at))))
+ ((symbol-function 'time-less-p)
+ (lambda (a b) (funcall ,(symbol-function 'time-less-p)
+ (or a ,at) (or b ,at))))
+ ((symbol-function 'time-subtract)
+ (lambda (a b) (funcall ,(symbol-function 'time-subtract)
+ (or a ,at) (or b ,at)))))
+ ,@body))))
+
(provide 'org-test)
;;; org-test.el ends here
--
2.20.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] When testing, fake the current time more robustly
2019-02-12 22:44 [PATCH] When testing, fake the current time more robustly Paul Eggert
@ 2019-02-12 23:50 ` Kyle Meyer
2019-02-13 1:03 ` Kyle Meyer
0 siblings, 1 reply; 3+ messages in thread
From: Kyle Meyer @ 2019-02-12 23:50 UTC (permalink / raw)
To: Paul Eggert, Emacs-orgmode
Paul Eggert <eggert@cs.ucla.edu> writes:
> The old approach required Lisp code to use (current-time)
> explicitly when calling other primitives, e.g., (float-time
> (current-time)). The new approach fakes all the primitives,
> so that Lisp code can now use expressions like plain (float-time).
Great, thanks! I'll go through all the spots where I've
s/nil/(current-time)/ for the sake of testing and restore nil.
--
Kyle
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] When testing, fake the current time more robustly
2019-02-12 23:50 ` Kyle Meyer
@ 2019-02-13 1:03 ` Kyle Meyer
0 siblings, 0 replies; 3+ messages in thread
From: Kyle Meyer @ 2019-02-13 1:03 UTC (permalink / raw)
To: Paul Eggert, Emacs-orgmode
Kyle Meyer <kyle@kyleam.com> writes:
> Paul Eggert <eggert@cs.ucla.edu> writes:
>
>> The old approach required Lisp code to use (current-time)
>> explicitly when calling other primitives, e.g., (float-time
>> (current-time)). The new approach fakes all the primitives,
>> so that Lisp code can now use expressions like plain (float-time).
>
> Great, thanks! I'll go through all the spots where I've
> s/nil/(current-time)/ for the sake of testing and restore nil.
Pushed (2cd1f9b028b) along with a follow-up commit removing current-time
calls that were kept for testing purposes.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2019-02-13 1:04 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-02-12 22:44 [PATCH] When testing, fake the current time more robustly Paul Eggert
2019-02-12 23:50 ` Kyle Meyer
2019-02-13 1:03 ` Kyle Meyer
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).