Skip to content

Commit 40fbdb8

Browse files
committed
tests: core: add tests for idling
refactor run_next_break into another method that allows continuing after idling
1 parent a642103 commit 40fbdb8

File tree

1 file changed

+327
-10
lines changed

1 file changed

+327
-10
lines changed

safeeyes/tests/test_core.py

Lines changed: 327 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -148,18 +148,8 @@ def run_next_break(
148148
was already called.
149149
"""
150150
on_update_next_break = mock.Mock()
151-
on_pre_break = mock.Mock(return_value=True)
152-
on_start_break = mock.Mock(return_value=True)
153-
start_break = mock.Mock()
154-
on_count_down = mock.Mock()
155-
on_stop_break = mock.Mock()
156151

157152
safe_eyes_core.on_update_next_break += on_update_next_break
158-
safe_eyes_core.on_pre_break += on_pre_break
159-
safe_eyes_core.on_start_break += on_start_break
160-
safe_eyes_core.start_break += start_break
161-
safe_eyes_core.on_count_down += on_count_down
162-
safe_eyes_core.on_stop_break += on_stop_break
163153

164154
if initial:
165155
safe_eyes_core.start()
@@ -175,6 +165,36 @@ def run_next_break(
175165
assert on_update_next_break.call_args[0][0].name == break_name_translated
176166
on_update_next_break.reset_mock()
177167

168+
self.run_next_break_from_waiting_state(
169+
sequential_threading_handle,
170+
safe_eyes_core,
171+
context,
172+
break_duration,
173+
break_name_translated,
174+
)
175+
176+
def run_next_break_from_waiting_state(
177+
self,
178+
sequential_threading_handle: SafeEyesCoreHandle,
179+
safe_eyes_core: core.SafeEyesCore,
180+
context,
181+
break_duration: int,
182+
break_name_translated: str,
183+
) -> None:
184+
on_pre_break = mock.Mock(return_value=True)
185+
on_start_break = mock.Mock(return_value=True)
186+
start_break = mock.Mock()
187+
on_count_down = mock.Mock()
188+
on_stop_break = mock.Mock()
189+
190+
safe_eyes_core.on_pre_break += on_pre_break
191+
safe_eyes_core.on_start_break += on_start_break
192+
safe_eyes_core.start_break += start_break
193+
safe_eyes_core.on_count_down += on_count_down
194+
safe_eyes_core.on_stop_break += on_stop_break
195+
196+
assert context["state"] == model.State.WAITING
197+
178198
# continue after condvar
179199
sequential_threading_handle.next()
180200
# end of __scheduler_job
@@ -547,3 +567,300 @@ def test_long_duration_is_bigger_than_short_interval(
547567
safe_eyes_core.stop()
548568

549569
assert context["state"] == model.State.STOPPED
570+
571+
def test_idle(
572+
self,
573+
sequential_threading: SequentialThreadingFixture,
574+
time_machine: TimeMachineFixture,
575+
):
576+
"""Test idling for short amount of time."""
577+
context: dict[str, typing.Any] = {
578+
"session": {},
579+
}
580+
short_break_duration = 15 # seconds
581+
short_break_interval = 15 # minutes
582+
pre_break_warning_time = 10 # seconds
583+
long_break_duration = 60 # seconds
584+
long_break_interval = 75 # minutes
585+
config = model.Config(
586+
user_config={
587+
"short_breaks": [
588+
{"name": "break 1"},
589+
{"name": "break 2"},
590+
{"name": "break 3"},
591+
{"name": "break 4"},
592+
],
593+
"long_breaks": [
594+
{"name": "long break 1"},
595+
{"name": "long break 2"},
596+
{"name": "long break 3"},
597+
],
598+
"short_break_interval": short_break_interval,
599+
"long_break_interval": long_break_interval,
600+
"long_break_duration": long_break_duration,
601+
"short_break_duration": short_break_duration,
602+
"pre_break_warning_time": pre_break_warning_time,
603+
"random_order": False,
604+
"postpone_duration": 5,
605+
},
606+
system_config={},
607+
)
608+
609+
self.assert_datetime("2024-08-25T13:00:00")
610+
611+
safe_eyes_core = core.SafeEyesCore(context)
612+
613+
sequential_threading_handle = sequential_threading(safe_eyes_core)
614+
615+
safe_eyes_core.initialize(config)
616+
617+
self.run_next_break(
618+
sequential_threading_handle,
619+
time_machine,
620+
safe_eyes_core,
621+
context,
622+
short_break_duration,
623+
"translated!: break 1",
624+
initial=True,
625+
)
626+
627+
# Time passed: 15min 25s
628+
# 15min short_break_interval, 10 seconds pre_break_warning_time,
629+
# 15 seconds short_break_duration
630+
self.assert_datetime("2024-08-25T13:15:25")
631+
632+
# idle, simulate behaviour of smartpause plugin
633+
idle_seconds = 30
634+
idle_period = datetime.timedelta(seconds=idle_seconds)
635+
636+
safe_eyes_core.stop(is_resting=True)
637+
638+
assert context["state"] == model.State.RESTING
639+
640+
time_machine.shift(delta=idle_period)
641+
642+
assert safe_eyes_core.scheduled_next_break_time is not None
643+
next_break = safe_eyes_core.scheduled_next_break_time + idle_period
644+
645+
safe_eyes_core.start(next_break_time=next_break.timestamp())
646+
647+
self.assert_datetime("2024-08-25T13:15:55")
648+
649+
self.run_next_break_from_waiting_state(
650+
sequential_threading_handle,
651+
safe_eyes_core,
652+
context,
653+
short_break_duration,
654+
"translated!: break 2",
655+
)
656+
657+
self.assert_datetime("2024-08-25T13:31:20")
658+
659+
self.run_next_break(
660+
sequential_threading_handle,
661+
time_machine,
662+
safe_eyes_core,
663+
context,
664+
short_break_duration,
665+
"translated!: break 3",
666+
)
667+
668+
self.assert_datetime("2024-08-25T13:46:45")
669+
670+
self.run_next_break(
671+
sequential_threading_handle,
672+
time_machine,
673+
safe_eyes_core,
674+
context,
675+
short_break_duration,
676+
"translated!: break 4",
677+
)
678+
679+
self.assert_datetime("2024-08-25T14:02:10")
680+
681+
self.run_next_break(
682+
sequential_threading_handle,
683+
time_machine,
684+
safe_eyes_core,
685+
context,
686+
long_break_duration,
687+
"translated!: long break 1",
688+
)
689+
690+
# Time passed: 16min 10s
691+
# 15min short_break_interval (from previous, as long_break_interval must be
692+
# multiple)
693+
# 10 seconds pre_break_warning_time, 1 minute long_break_duration
694+
self.assert_datetime("2024-08-25T14:18:20")
695+
696+
self.run_next_break(
697+
sequential_threading_handle,
698+
time_machine,
699+
safe_eyes_core,
700+
context,
701+
short_break_duration,
702+
"translated!: break 1",
703+
)
704+
705+
# Time passed: 15min 25s
706+
# 15min short_break_interval, 10 seconds pre_break_warning_time,
707+
# 15 seconds short_break_duration
708+
self.assert_datetime("2024-08-25T14:33:45")
709+
710+
safe_eyes_core.stop()
711+
712+
assert context["state"] == model.State.STOPPED
713+
714+
def test_idle_skip_long(
715+
self,
716+
sequential_threading: SequentialThreadingFixture,
717+
time_machine: TimeMachineFixture,
718+
):
719+
"""Test idling for longer than long break time."""
720+
context: dict[str, typing.Any] = {
721+
"session": {},
722+
}
723+
short_break_duration = 15 # seconds
724+
short_break_interval = 15 # minutes
725+
pre_break_warning_time = 10 # seconds
726+
long_break_duration = 60 # seconds
727+
long_break_interval = 75 # minutes
728+
config = model.Config(
729+
user_config={
730+
"short_breaks": [
731+
{"name": "break 1"},
732+
{"name": "break 2"},
733+
{"name": "break 3"},
734+
{"name": "break 4"},
735+
],
736+
"long_breaks": [
737+
{"name": "long break 1"},
738+
{"name": "long break 2"},
739+
{"name": "long break 3"},
740+
],
741+
"short_break_interval": short_break_interval,
742+
"long_break_interval": long_break_interval,
743+
"long_break_duration": long_break_duration,
744+
"short_break_duration": short_break_duration,
745+
"pre_break_warning_time": pre_break_warning_time,
746+
"random_order": False,
747+
"postpone_duration": 5,
748+
},
749+
system_config={},
750+
)
751+
752+
self.assert_datetime("2024-08-25T13:00:00")
753+
754+
safe_eyes_core = core.SafeEyesCore(context)
755+
756+
sequential_threading_handle = sequential_threading(safe_eyes_core)
757+
758+
safe_eyes_core.initialize(config)
759+
760+
self.run_next_break(
761+
sequential_threading_handle,
762+
time_machine,
763+
safe_eyes_core,
764+
context,
765+
short_break_duration,
766+
"translated!: break 1",
767+
initial=True,
768+
)
769+
770+
# Time passed: 15min 25s
771+
# 15min short_break_interval, 10 seconds pre_break_warning_time,
772+
# 15 seconds short_break_duration
773+
self.assert_datetime("2024-08-25T13:15:25")
774+
775+
# idle, simulate behaviour of smartpause plugin
776+
idle_seconds = 65
777+
idle_period = datetime.timedelta(seconds=idle_seconds)
778+
779+
safe_eyes_core.stop(is_resting=True)
780+
781+
assert context["state"] == model.State.RESTING
782+
783+
time_machine.shift(delta=idle_period)
784+
785+
assert safe_eyes_core.scheduled_next_break_time is not None
786+
next_break = safe_eyes_core.scheduled_next_break_time + idle_period
787+
788+
safe_eyes_core.start(next_break_time=next_break.timestamp())
789+
790+
self.assert_datetime("2024-08-25T13:16:30")
791+
792+
self.run_next_break_from_waiting_state(
793+
sequential_threading_handle,
794+
safe_eyes_core,
795+
context,
796+
short_break_duration,
797+
"translated!: break 2",
798+
)
799+
800+
self.assert_datetime("2024-08-25T13:31:55")
801+
802+
self.run_next_break(
803+
sequential_threading_handle,
804+
time_machine,
805+
safe_eyes_core,
806+
context,
807+
short_break_duration,
808+
"translated!: break 3",
809+
)
810+
811+
self.assert_datetime("2024-08-25T13:47:20")
812+
813+
self.run_next_break(
814+
sequential_threading_handle,
815+
time_machine,
816+
safe_eyes_core,
817+
context,
818+
short_break_duration,
819+
"translated!: break 4",
820+
)
821+
822+
self.assert_datetime("2024-08-25T14:02:45")
823+
824+
self.run_next_break(
825+
sequential_threading_handle,
826+
time_machine,
827+
safe_eyes_core,
828+
context,
829+
short_break_duration,
830+
"translated!: break 1",
831+
)
832+
833+
self.assert_datetime("2024-08-25T14:18:10")
834+
835+
self.run_next_break(
836+
sequential_threading_handle,
837+
time_machine,
838+
safe_eyes_core,
839+
context,
840+
long_break_duration,
841+
"translated!: long break 1",
842+
)
843+
844+
# Time passed: 16min 10s
845+
# 15min short_break_interval (from previous, as long_break_interval must be
846+
# multiple)
847+
# 10 seconds pre_break_warning_time, 1 minute long_break_duration
848+
self.assert_datetime("2024-08-25T14:34:20")
849+
850+
self.run_next_break(
851+
sequential_threading_handle,
852+
time_machine,
853+
safe_eyes_core,
854+
context,
855+
short_break_duration,
856+
"translated!: break 2",
857+
)
858+
859+
# Time passed: 15min 25s
860+
# 15min short_break_interval, 10 seconds pre_break_warning_time,
861+
# 15 seconds short_break_duration
862+
self.assert_datetime("2024-08-25T14:49:45")
863+
864+
safe_eyes_core.stop()
865+
866+
assert context["state"] == model.State.STOPPED

0 commit comments

Comments
 (0)