emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[nongnu] elpa/with-simulated-input ddd7bd71b1 011/134: Add "wsi-simulate


From: ELPA Syncer
Subject: [nongnu] elpa/with-simulated-input ddd7bd71b1 011/134: Add "wsi-simulate-idle-time" and tests for it
Date: Mon, 10 Jan 2022 22:59:59 -0500 (EST)

branch: elpa/with-simulated-input
commit ddd7bd71b178435035e7339e785eb8f30ee11277
Author: Ryan C. Thompson <rct@thompsonclan.org>
Commit: Ryan C. Thompson <rct@thompsonclan.org>

    Add "wsi-simulate-idle-time" and tests for it
    
    Fixes #1.
---
 tests/test-with-simulated-input.el | 44 ++++++++++++++++++++++++++++++++
 with-simulated-input.el            | 52 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 96 insertions(+)

diff --git a/tests/test-with-simulated-input.el 
b/tests/test-with-simulated-input.el
index 6524e68a4a..273ccffc3d 100644
--- a/tests/test-with-simulated-input.el
+++ b/tests/test-with-simulated-input.el
@@ -90,4 +90,48 @@
          (read-string "Enter a string: "))
        :to-equal "hello world"))))
 
+(defun idle-canary ())
+(defvar timers-to-cancel nil)
+(defvar orig-timer--activate (symbol-function 'timer--activate))
+
+(describe "`wsi-simulate-idle-time'"
+  (spy-on 'idle-canary)
+  (spy-on 'timer--activate
+          :and-call-fake
+          (lambda (timer &rest args)
+            (push timer timers-to-cancel)
+            (apply orig-timer--activate timer args)))
+  (after-each
+    (mapcar #'cancel-timer timers-to-cancel)
+    (setq timers-to-cancel nil)
+    (spy-calls-reset 'idle-canary))
+  (it "should run idle timers"
+    (run-with-idle-timer 500 nil 'idle-canary)
+    (wsi-simulate-idle-time 501)
+    (expect 'idle-canary :to-have-been-called))
+  (it "should not run idle times with longer times"
+    (run-with-idle-timer 500 nil 'set 'idle-canary)
+    (wsi-simulate-idle-time 100)
+    (expect 'idle-canary :not :to-have-been-called))
+  (it "should run idle timers added by other idle timers"
+    (run-with-idle-timer
+     100 nil 'run-with-idle-timer
+     200 nil 'idle-canary)
+    (wsi-simulate-idle-time 500)
+    (expect 'idle-canary :to-have-been-called))
+  (it "should run idle timers added by other idle timers when the new timer is 
in the past"
+    (run-with-idle-timer
+     100 nil 'run-with-idle-timer
+     50 nil 'idle-canary)
+    (wsi-simulate-idle-time 500)
+    (expect 'idle-canary :to-have-been-called))
+
+  (describe "used within `with-simulated-input'"
+    (it "should allow idle timers to trigger during simulated input"
+      (run-with-idle-timer 500 nil 'insert "world")
+      (expect
+       (with-simulated-input '("hello SPC" (wsi-simulate-idle-time 501) "RET")
+         (read-string "Enter a string: "))
+       :to-equal "hello world"))))
+
 ;;; test-with-simulated-input.el ends here
diff --git a/with-simulated-input.el b/with-simulated-input.el
index 83c352ff3e..ae3c07558b 100644
--- a/with-simulated-input.el
+++ b/with-simulated-input.el
@@ -208,6 +208,58 @@ in `progn'."
          (error "Reached end of simulated input while evaluating body")
        result)))
 
+(defvar wsi-simulated-idle-time nil)
+
+(defadvice current-idle-time (around simulat-idle-time activate)
+  "Return the faked value while simulating idle time.
+
+While executing `wsi-simulate-idle-time', this advice causes the
+simulated idle time to be returned instead of the real value."
+  (if wsi-simulated-idle-time
+      (setq ad-return-value
+            (when (> (float-time wsi-simulated-idle-time) 0)
+              (seconds-to-time wsi-simulated-idle-time)))
+    ad-do-it))
+
+(cl-defun wsi-simulate-idle-time (secs &optional actually-wait)
+  "Run all idle timers with delay less than SECS.
+
+This simulates resetting the idle time to zero and then being
+idle for SECS seconds. If ACTUALLY-WAIT is non-nil, this function
+will also wait for the specified amount of time before running
+each timers.
+
+While each timer is running, `current-idle-time' will be
+overridden to return the current simulated idle time."
+  (interactive
+   "nSeconds of idle time: \nP")
+  (cl-loop
+   with already-run-timers = nil
+   with stop-time = (float-time secs)
+   with wsi-simulated-idle-time = 0.0
+   ;; We have to search `timer-idle-list' from the beginning each time
+   ;; through the loop because each timer that runs might add more
+   ;; timers to the list, and picking up at the same list position
+   ;; would ignore those new timers.
+   for next-timer = (car (cl-member-if-not
+                          (lambda (timer) (memq timer already-run-timers))
+                          timer-idle-list))
+   while next-timer
+   for previous-idle-time = wsi-simulated-idle-time
+   maximize (float-time (timer--time next-timer))
+   into wsi-simulated-idle-time
+   when actually-wait
+   do (sleep-for (float-time (time-subtract wsi-simulated-idle-time
+                                            previous-idle-time)))
+   while (time-less-p wsi-simulated-idle-time stop-time)
+   when (not (timer--triggered next-timer))
+   do (timer-event-handler next-timer)
+   do (push next-timer already-run-timers)
+   finally do
+   (when actually-wait
+     (sleep-for (float-time (time-subtract stop-time
+                                           wsi-simulated-idle-time))))))
+
 (provide 'with-simulated-input)
 
 ;;; with-simulated-input.el ends here



reply via email to

[Prev in Thread] Current Thread [Next in Thread]