annotate velib_python/test/mock_gobject.py @ 18:9c2e08444598

Make sure timer is called more than once. Not sure how this worked earlier..
author Daniel O'Connor <darius@dons.net.au>
date Mon, 06 Dec 2021 12:07:30 +1030
parents 9c0435a617db
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
8
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
1 # This module contains mock functions for some of the functionality in gobject.
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
2 # You can use this to create unit tests on code using gobject timers without having to wait for those timer.
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
3 # Use the patch functions to replace the original gobject functions. The timer_manager object defined here
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
4 # allows you to set a virtual time stamp, which will invoke all timers that would normally run in the
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
5 # specified interval.
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
6
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
7 from datetime import datetime as dt
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
8 import time
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
9
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
10 class MockTimer(object):
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
11 def __init__(self, start, timeout, callback, *args, **kwargs):
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
12 self._timeout = timeout
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
13 self._next = start + timeout
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
14 self._callback = callback
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
15 self._args = args
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
16 self._kwargs = kwargs
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
17
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
18 def run(self):
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
19 self._next += self._timeout
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
20 return self._callback(*self._args, **self._kwargs)
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
21
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
22 @property
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
23 def next(self):
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
24 return self._next
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
25
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
26
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
27 class MockTimerManager(object):
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
28 def __init__(self, start_time=None):
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
29 self._resources = []
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
30 self._time = 0
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
31 self._id = 0
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
32 self._timestamp = start_time or time.time()
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
33
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
34 def add_timer(self, timeout, callback, *args, **kwargs):
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
35 return self._add_resource(MockTimer(self._time, timeout, callback, *args, **kwargs))
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
36
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
37 def add_idle(self, callback, *args, **kwargs):
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
38 return self.add_timer(self._time, callback, *args, **kwargs)
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
39
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
40 def remove_resouce(self, id):
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
41 for rid, rr in self._resources:
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
42 if rid == id:
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
43 self._resources.remove((rid, rr))
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
44 return
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
45 raise Exception('Resource not found: {}'.format(id))
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
46
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
47 def _add_resource(self, resource):
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
48 self._id += 1
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
49 self._resources.append((self._id, resource))
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
50 return self._id
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
51
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
52 def _terminate(self):
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
53 raise StopIteration()
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
54
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
55 @property
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
56 def time(self):
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
57 return self._time
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
58
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
59 @property
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
60 def datetime(self):
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
61 return dt.fromtimestamp(self._timestamp + self._time / 1000.0)
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
62
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
63 def run(self, interval=None):
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
64 '''
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
65 Simulate the given interval. Starting from the current (mock) time until time + interval, all timers
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
66 will be triggered. The timers will be triggered in chronological order. Timer removal (calling
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
67 source_remove or a False/None return value) and addition within the callback function is supported.
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
68 If interval is None or not supplied, the function will run until there are no timers left.
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
69 '''
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
70 if interval != None:
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
71 self.add_timer(interval, self._terminate)
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
72 try:
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
73 while True:
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
74 next_timer = None
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
75 next_id = None
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
76 for id,t in self._resources:
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
77 if next_timer == None or t.next < next_timer.next:
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
78 next_timer = t
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
79 next_id = id
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
80 if next_timer == None:
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
81 return
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
82 self._time = next_timer.next
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
83 if not next_timer.run():
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
84 self._resources.remove((next_id, next_timer))
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
85 except StopIteration:
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
86 self._resources.remove((next_id, next_timer))
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
87 pass
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
88
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
89 def reset(self):
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
90 self._resources = []
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
91 self._time = 0
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
92
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
93
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
94 timer_manager = MockTimerManager()
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
95
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
96
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
97 def idle_add(callback, *args, **kwargs):
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
98 return timer_manager.add_idle(callback, *args, **kwargs)
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
99
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
100
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
101 def timeout_add(timeout, callback, *args, **kwargs):
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
102 return timer_manager.add_timer(timeout, callback, *args, **kwargs)
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
103
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
104
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
105 def timeout_add_seconds(timeout, callback, *args, **kwargs):
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
106 return timeout_add(timeout * 1000, callback, *args, **kwargs)
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
107
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
108
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
109 class datetime(object):
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
110 @staticmethod
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
111 def now():
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
112 return timer_manager.datetime
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
113
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
114 @staticmethod
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
115 def strptime(*args, **kwargs):
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
116 return dt.strptime(*args, **kwargs)
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
117
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
118
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
119 def source_remove(id):
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
120 timer_manager.remove_resouce(id)
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
121
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
122
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
123 def test_function(m, name):
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
124 print(m.time, m.datetime, name)
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
125 return True
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
126
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
127
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
128 def patch_gobject(dest):
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
129 '''
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
130 Use this function to replace the original gobject/GLib functions with the
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
131 mocked versions in this file. Suppose your source files being tested uses
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
132 'from gi.repository import GLib' and the unit test uses 'import tested' you
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
133 should call path(tested.GLib).
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
134 '''
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
135 dest.timeout_add = timeout_add
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
136 dest.timeout_add_seconds = timeout_add_seconds
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
137 dest.idle_add = idle_add
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
138 dest.source_remove = source_remove
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
139
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
140
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
141 def patch_datetime(dest):
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
142 dest.datetime = datetime
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
143
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
144
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
145 if __name__ == '__main__':
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
146 m = MockTimerManager()
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
147 id1 = m.add_timer(100, test_function, m, 'F1')
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
148 id2 = m.add_timer(30, test_function, m, 'F2')
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
149 m.run(5000)
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
150 m.remove_resouce(id1)
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
151 m.run(2000)
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
152 m.remove_resouce(id2)
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
153 m.run(2000)