clock-pattern 0.2.0__tar.gz → 0.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {clock_pattern-0.2.0 → clock_pattern-0.4.0}/PKG-INFO +2 -2
- clock_pattern-0.4.0/clock_pattern/__init__.py +1 -0
- clock_pattern-0.4.0/clock_pattern/clocks/testing/__init__.py +7 -0
- clock_pattern-0.4.0/clock_pattern/clocks/testing/fixed_clock.py +111 -0
- clock_pattern-0.4.0/clock_pattern/clocks/testing/mock_clock.py +289 -0
- {clock_pattern-0.2.0 → clock_pattern-0.4.0}/pyproject.toml +1 -1
- clock_pattern-0.2.0/clock_pattern/__init__.py +0 -1
- {clock_pattern-0.2.0 → clock_pattern-0.4.0}/.gitignore +0 -0
- {clock_pattern-0.2.0 → clock_pattern-0.4.0}/LICENSE.md +0 -0
- {clock_pattern-0.2.0 → clock_pattern-0.4.0}/README.md +0 -0
- {clock_pattern-0.2.0 → clock_pattern-0.4.0}/clock_pattern/clocks/__init__.py +0 -0
- {clock_pattern-0.2.0 → clock_pattern-0.4.0}/clock_pattern/clocks/system_clock.py +0 -0
- {clock_pattern-0.2.0 → clock_pattern-0.4.0}/clock_pattern/clocks/utc_clock.py +0 -0
- {clock_pattern-0.2.0 → clock_pattern-0.4.0}/clock_pattern/models/__init__.py +0 -0
- {clock_pattern-0.2.0 → clock_pattern-0.4.0}/clock_pattern/models/clock.py +0 -0
- {clock_pattern-0.2.0 → clock_pattern-0.4.0}/clock_pattern/py.typed +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: clock-pattern
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: The Clock Pattern is a Python package that turns time into an injectable dependency.
|
|
5
5
|
Project-URL: Homepage, https://github.com/adriamontoto/clock-pattern
|
|
6
6
|
Project-URL: Repository, https://github.com/adriamontoto/clock-pattern
|
|
@@ -19,7 +19,7 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
19
19
|
Classifier: Programming Language :: Python :: 3.13
|
|
20
20
|
Classifier: Typing :: Typed
|
|
21
21
|
Requires-Python: >=3.11
|
|
22
|
-
Requires-Dist: value-object-pattern>=0.
|
|
22
|
+
Requires-Dist: value-object-pattern>=0.6.0
|
|
23
23
|
Description-Content-Type: text/markdown
|
|
24
24
|
|
|
25
25
|
<a name="readme-top"></a>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = '0.4.0'
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"""
|
|
2
|
+
FixedClock module.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from sys import version_info
|
|
6
|
+
|
|
7
|
+
if version_info >= (3, 12):
|
|
8
|
+
from typing import override # pragma: no cover
|
|
9
|
+
else:
|
|
10
|
+
from typing_extensions import override # pragma: no cover
|
|
11
|
+
|
|
12
|
+
from datetime import UTC, date, datetime
|
|
13
|
+
|
|
14
|
+
from value_object_pattern.usables.dates import DatetimeValueObject
|
|
15
|
+
|
|
16
|
+
from clock_pattern.models.clock import Clock
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class FixedClock(Clock):
|
|
20
|
+
"""
|
|
21
|
+
MockModel is responsible for retrieving the date/datetime provided when `FixedClock` initialization. Use `MockClock`
|
|
22
|
+
for better testing features.
|
|
23
|
+
|
|
24
|
+
Example:
|
|
25
|
+
```python
|
|
26
|
+
from datetime import datetime
|
|
27
|
+
|
|
28
|
+
from clock_pattern.clocks.testing import FixedClock
|
|
29
|
+
|
|
30
|
+
fixed_datetime = datetime(year=1999, month=1, day=1)
|
|
31
|
+
clock = FixedClock(instant=fixed_datetime)
|
|
32
|
+
print(clock.now())
|
|
33
|
+
# >>> 1999-01-01 00:00:00+00:00
|
|
34
|
+
```
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
_instant: datetime
|
|
38
|
+
|
|
39
|
+
def __init__(self, *, instant: datetime) -> None:
|
|
40
|
+
"""
|
|
41
|
+
FixedClock constructor is used to provided which date/datetime `instance` will be retrieved. If the provided
|
|
42
|
+
datetime `instant` has not timezone UTC will be set.
|
|
43
|
+
|
|
44
|
+
Args:
|
|
45
|
+
instant (datetime): The datetime that will be retrieved.
|
|
46
|
+
|
|
47
|
+
Raises:
|
|
48
|
+
ValueError: If `instant` is not of type datetime.
|
|
49
|
+
|
|
50
|
+
Example:
|
|
51
|
+
```python
|
|
52
|
+
from datetime import datetime
|
|
53
|
+
|
|
54
|
+
from clock_pattern.clocks.testing import FixedClock
|
|
55
|
+
|
|
56
|
+
fixed_datetime = datetime(year=1999, month=1, day=1)
|
|
57
|
+
clock = FixedClock(instant=fixed_datetime)
|
|
58
|
+
print(clock.now())
|
|
59
|
+
# >>> 1999-01-01 00:00:00+00:00
|
|
60
|
+
```
|
|
61
|
+
"""
|
|
62
|
+
DatetimeValueObject(value=instant, title='FixedClock', parameter='instant')
|
|
63
|
+
|
|
64
|
+
if instant.tzinfo is None:
|
|
65
|
+
instant = instant.replace(tzinfo=UTC)
|
|
66
|
+
|
|
67
|
+
self._instant = instant
|
|
68
|
+
|
|
69
|
+
@override
|
|
70
|
+
def now(self) -> datetime:
|
|
71
|
+
"""
|
|
72
|
+
Retrieve the current datetime (now).
|
|
73
|
+
|
|
74
|
+
Returns:
|
|
75
|
+
datetime: The current datetime.
|
|
76
|
+
|
|
77
|
+
Example:
|
|
78
|
+
```python
|
|
79
|
+
from datetime import datetime
|
|
80
|
+
|
|
81
|
+
from clock_pattern.clocks.testing import FixedClock
|
|
82
|
+
|
|
83
|
+
fixed_datetime = datetime(year=1999, month=1, day=1)
|
|
84
|
+
clock = FixedClock(instant=fixed_datetime)
|
|
85
|
+
print(clock.now())
|
|
86
|
+
# >>> 1999-01-01 00:00:00+00:00
|
|
87
|
+
```
|
|
88
|
+
"""
|
|
89
|
+
return self._instant
|
|
90
|
+
|
|
91
|
+
@override
|
|
92
|
+
def today(self) -> date:
|
|
93
|
+
"""
|
|
94
|
+
Retrieve the current date (today).
|
|
95
|
+
|
|
96
|
+
Returns:
|
|
97
|
+
date: The current date.
|
|
98
|
+
|
|
99
|
+
Example:
|
|
100
|
+
```python
|
|
101
|
+
from datetime import datetime
|
|
102
|
+
|
|
103
|
+
from clock_pattern.clocks.testing import FixedClock
|
|
104
|
+
|
|
105
|
+
fixed_datetime = datetime(year=1999, month=1, day=1)
|
|
106
|
+
clock = FixedClock(instant=fixed_datetime)
|
|
107
|
+
print(clock.today())
|
|
108
|
+
# >>> 1999-01-01
|
|
109
|
+
```
|
|
110
|
+
"""
|
|
111
|
+
return self._instant.date()
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
"""
|
|
2
|
+
MockClock module.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from sys import version_info
|
|
6
|
+
|
|
7
|
+
if version_info >= (3, 12):
|
|
8
|
+
from typing import override # pragma: no cover
|
|
9
|
+
else:
|
|
10
|
+
from typing_extensions import override # pragma: no cover
|
|
11
|
+
|
|
12
|
+
from datetime import UTC, date, datetime
|
|
13
|
+
from unittest.mock import Mock
|
|
14
|
+
|
|
15
|
+
from value_object_pattern.usables import NotNoneValueObject
|
|
16
|
+
from value_object_pattern.usables.dates import DateValueObject, DatetimeValueObject
|
|
17
|
+
|
|
18
|
+
from clock_pattern.models.clock import Clock
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class MockClock(Clock):
|
|
22
|
+
"""
|
|
23
|
+
MockModel is responsible of mocking Clock class implementation for testing purposes.
|
|
24
|
+
|
|
25
|
+
Example:
|
|
26
|
+
```python
|
|
27
|
+
from datetime import datetime
|
|
28
|
+
|
|
29
|
+
from clock_pattern.clocks.testing import MockClock
|
|
30
|
+
|
|
31
|
+
return_datetime = datetime(year=1999, month=1, day=1)
|
|
32
|
+
clock = MockClock()
|
|
33
|
+
|
|
34
|
+
clock.prepare_now_method_return_value(now=return_datetime)
|
|
35
|
+
print(clock.now())
|
|
36
|
+
# >>> 1999-01-01 00:00:00+00:00
|
|
37
|
+
|
|
38
|
+
clock.assert_now_method_was_called_once()
|
|
39
|
+
```
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
_now_mock: Mock
|
|
43
|
+
_today_mock: Mock
|
|
44
|
+
_now_datetime: datetime | None
|
|
45
|
+
_today_date: date | None
|
|
46
|
+
|
|
47
|
+
def __init__(self) -> None:
|
|
48
|
+
"""
|
|
49
|
+
MockClock constructor.
|
|
50
|
+
|
|
51
|
+
Example:
|
|
52
|
+
```python
|
|
53
|
+
from datetime import datetime
|
|
54
|
+
|
|
55
|
+
from clock_pattern.clocks.testing import MockClock
|
|
56
|
+
|
|
57
|
+
return_datetime = datetime(year=1999, month=1, day=1)
|
|
58
|
+
clock = MockClock()
|
|
59
|
+
|
|
60
|
+
clock.prepare_now_method_return_value(now=return_datetime)
|
|
61
|
+
print(clock.now())
|
|
62
|
+
# >>> 1999-01-01 00:00:00+00:00
|
|
63
|
+
|
|
64
|
+
clock.assert_now_method_was_called_once()
|
|
65
|
+
```
|
|
66
|
+
"""
|
|
67
|
+
self._now_mock = Mock()
|
|
68
|
+
self._today_mock = Mock()
|
|
69
|
+
self._now_datetime = None
|
|
70
|
+
self._today_date = None
|
|
71
|
+
|
|
72
|
+
@override
|
|
73
|
+
def now(self) -> datetime:
|
|
74
|
+
"""
|
|
75
|
+
Retrieve the current datetime (now). Use `MockClock.prepare_now_method_return_value` to prepare the return value
|
|
76
|
+
for this method.
|
|
77
|
+
|
|
78
|
+
Raises:
|
|
79
|
+
TypeError: If `now` method return value is not configured.
|
|
80
|
+
|
|
81
|
+
Returns:
|
|
82
|
+
datetime: The current datetime.
|
|
83
|
+
|
|
84
|
+
Example:
|
|
85
|
+
```python
|
|
86
|
+
from datetime import datetime
|
|
87
|
+
|
|
88
|
+
from clock_pattern.clocks.testing import MockClock
|
|
89
|
+
|
|
90
|
+
return_datetime = datetime(year=1999, month=1, day=1)
|
|
91
|
+
clock = MockClock()
|
|
92
|
+
|
|
93
|
+
clock.prepare_now_method_return_value(now=return_datetime)
|
|
94
|
+
print(clock.now())
|
|
95
|
+
# >>> 1999-01-01 00:00:00+00:00
|
|
96
|
+
|
|
97
|
+
clock.assert_now_method_was_called_once()
|
|
98
|
+
```
|
|
99
|
+
"""
|
|
100
|
+
NotNoneValueObject(value=self._now_datetime, title='MockClock', parameter='now')
|
|
101
|
+
|
|
102
|
+
self._now_mock()
|
|
103
|
+
|
|
104
|
+
return self._now_datetime # type: ignore[return-value]
|
|
105
|
+
|
|
106
|
+
def prepare_now_method_return_value(self, *, now: datetime) -> None:
|
|
107
|
+
"""
|
|
108
|
+
Prepare now method to return the provided datetime `now`. If the provided datetime `now` has not timezone UTC
|
|
109
|
+
will be set.
|
|
110
|
+
|
|
111
|
+
Args:
|
|
112
|
+
now (datetime): Datetime to return.
|
|
113
|
+
|
|
114
|
+
Raises:
|
|
115
|
+
TypeError: If `now` is not of type datetime.
|
|
116
|
+
|
|
117
|
+
Example:
|
|
118
|
+
```python
|
|
119
|
+
from datetime import datetime
|
|
120
|
+
|
|
121
|
+
from clock_pattern.clocks.testing import MockClock
|
|
122
|
+
|
|
123
|
+
return_datetime = datetime(year=1999, month=1, day=1)
|
|
124
|
+
clock = MockClock()
|
|
125
|
+
|
|
126
|
+
clock.prepare_now_method_return_value(now=return_datetime)
|
|
127
|
+
print(clock.now())
|
|
128
|
+
# >>> 1999-01-01 00:00:00+00:00
|
|
129
|
+
|
|
130
|
+
clock.assert_now_method_was_called_once()
|
|
131
|
+
```
|
|
132
|
+
"""
|
|
133
|
+
DatetimeValueObject(value=now, title='MockClock', parameter='now')
|
|
134
|
+
|
|
135
|
+
if now.tzinfo is None:
|
|
136
|
+
now = now.replace(tzinfo=UTC)
|
|
137
|
+
|
|
138
|
+
self._now_datetime = now
|
|
139
|
+
|
|
140
|
+
def assert_now_method_was_called_once(self) -> None:
|
|
141
|
+
"""
|
|
142
|
+
Assert that the now method was called once.
|
|
143
|
+
|
|
144
|
+
Example:
|
|
145
|
+
```python
|
|
146
|
+
from datetime import datetime
|
|
147
|
+
|
|
148
|
+
from clock_pattern.clocks.testing import MockClock
|
|
149
|
+
|
|
150
|
+
return_datetime = datetime(year=1999, month=1, day=1)
|
|
151
|
+
clock = MockClock()
|
|
152
|
+
|
|
153
|
+
clock.prepare_now_method_return_value(now=return_datetime)
|
|
154
|
+
print(clock.now())
|
|
155
|
+
# >>> 1999-01-01 00:00:00+00:00
|
|
156
|
+
|
|
157
|
+
clock.assert_now_method_was_called_once()
|
|
158
|
+
```
|
|
159
|
+
"""
|
|
160
|
+
self._now_mock.assert_called_once_with()
|
|
161
|
+
|
|
162
|
+
def assert_now_method_was_not_called(self) -> None:
|
|
163
|
+
"""
|
|
164
|
+
Assert that the now method was not called.
|
|
165
|
+
|
|
166
|
+
Example:
|
|
167
|
+
```python
|
|
168
|
+
from datetime import date
|
|
169
|
+
|
|
170
|
+
from clock_pattern.clocks.testing import MockClock
|
|
171
|
+
|
|
172
|
+
return_date = date(year=1999, month=1, day=1)
|
|
173
|
+
clock = MockClock()
|
|
174
|
+
|
|
175
|
+
clock.prepare_today_method_return_value(today=return_date)
|
|
176
|
+
print(clock.today())
|
|
177
|
+
# >>> 2025-06-16
|
|
178
|
+
|
|
179
|
+
clock.assert_now_method_was_not_called()
|
|
180
|
+
```
|
|
181
|
+
"""
|
|
182
|
+
self._now_mock.assert_not_called()
|
|
183
|
+
|
|
184
|
+
@override
|
|
185
|
+
def today(self) -> date:
|
|
186
|
+
"""
|
|
187
|
+
Retrieve the current date (today). Use `MockClock.prepare_today_method_return_value` to prepare the return value
|
|
188
|
+
for this method.
|
|
189
|
+
|
|
190
|
+
Raises:
|
|
191
|
+
ValueError: If `today` method return value is not configured.
|
|
192
|
+
|
|
193
|
+
Returns:
|
|
194
|
+
date: The current date.
|
|
195
|
+
|
|
196
|
+
Example:
|
|
197
|
+
```python
|
|
198
|
+
from datetime import date
|
|
199
|
+
|
|
200
|
+
from clock_pattern.clocks.testing import MockClock
|
|
201
|
+
|
|
202
|
+
return_date = date(year=1999, month=1, day=1)
|
|
203
|
+
clock = MockClock()
|
|
204
|
+
|
|
205
|
+
clock.prepare_today_method_return_value(today=return_date)
|
|
206
|
+
print(clock.today())
|
|
207
|
+
# >>> 2025-06-16
|
|
208
|
+
|
|
209
|
+
clock.assert_today_method_was_called_once()
|
|
210
|
+
```
|
|
211
|
+
"""
|
|
212
|
+
NotNoneValueObject(value=self._today_date, title='MockClock', parameter='today')
|
|
213
|
+
|
|
214
|
+
self._today_mock()
|
|
215
|
+
|
|
216
|
+
return self._today_date # type: ignore[return-value]
|
|
217
|
+
|
|
218
|
+
def prepare_today_method_return_value(self, *, today: date) -> None:
|
|
219
|
+
"""
|
|
220
|
+
Prepare today method to return the provided date `today`.
|
|
221
|
+
|
|
222
|
+
Args:
|
|
223
|
+
today (date): Date to return.
|
|
224
|
+
|
|
225
|
+
Raises:
|
|
226
|
+
TypeError: If `today` is not of type date.
|
|
227
|
+
|
|
228
|
+
Example:
|
|
229
|
+
```python
|
|
230
|
+
from datetime import date
|
|
231
|
+
|
|
232
|
+
from clock_pattern.clocks.testing import MockClock
|
|
233
|
+
|
|
234
|
+
return_date = date(year=1999, month=1, day=1)
|
|
235
|
+
clock = MockClock()
|
|
236
|
+
|
|
237
|
+
clock.prepare_today_method_return_value(today=return_date)
|
|
238
|
+
print(clock.today())
|
|
239
|
+
# >>> 2025-06-16
|
|
240
|
+
|
|
241
|
+
clock.assert_today_method_was_called_once()
|
|
242
|
+
```
|
|
243
|
+
"""
|
|
244
|
+
DateValueObject(value=today, title='MockClock', parameter='today')
|
|
245
|
+
self._today_date = today
|
|
246
|
+
|
|
247
|
+
def assert_today_method_was_called_once(self) -> None:
|
|
248
|
+
"""
|
|
249
|
+
Assert that the today method was called once.
|
|
250
|
+
|
|
251
|
+
Example:
|
|
252
|
+
```python
|
|
253
|
+
from datetime import date
|
|
254
|
+
|
|
255
|
+
from clock_pattern.clocks.testing import MockClock
|
|
256
|
+
|
|
257
|
+
return_date = date(year=1999, month=1, day=1)
|
|
258
|
+
clock = MockClock()
|
|
259
|
+
|
|
260
|
+
clock.prepare_today_method_return_value(today=return_date)
|
|
261
|
+
print(clock.today())
|
|
262
|
+
# >>> 2025-06-16
|
|
263
|
+
|
|
264
|
+
clock.assert_today_method_was_called_once()
|
|
265
|
+
```
|
|
266
|
+
"""
|
|
267
|
+
self._today_mock.assert_called_once_with()
|
|
268
|
+
|
|
269
|
+
def assert_today_method_was_not_called(self) -> None:
|
|
270
|
+
"""
|
|
271
|
+
Assert that the today method was not called.
|
|
272
|
+
|
|
273
|
+
Example:
|
|
274
|
+
```python
|
|
275
|
+
from datetime import datetime
|
|
276
|
+
|
|
277
|
+
from clock_pattern.clocks.testing import MockClock
|
|
278
|
+
|
|
279
|
+
return_datetime = datetime(year=1999, month=1, day=1)
|
|
280
|
+
clock = MockClock()
|
|
281
|
+
|
|
282
|
+
clock.prepare_now_method_return_value(now=return_datetime)
|
|
283
|
+
print(clock.now())
|
|
284
|
+
# >>> 1999-01-01 00:00:00+00:00
|
|
285
|
+
|
|
286
|
+
clock.assert_today_method_was_not_called()
|
|
287
|
+
```
|
|
288
|
+
"""
|
|
289
|
+
self._today_mock.assert_not_called()
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = '0.2.0'
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|