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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: clock-pattern
3
- Version: 0.2.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.5.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,7 @@
1
+ from .fixed_clock import FixedClock
2
+ from .mock_clock import MockClock
3
+
4
+ __all__ = (
5
+ 'FixedClock',
6
+ 'MockClock',
7
+ )
@@ -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()
@@ -37,7 +37,7 @@ keywords = [
37
37
  'domain-driven-design',
38
38
  ]
39
39
  requires-python = '>=3.11'
40
- dependencies = ['value-object-pattern>=0.5.0']
40
+ dependencies = ['value-object-pattern>=0.6.0']
41
41
  dynamic = ['version']
42
42
 
43
43
  [project.urls]
@@ -1 +0,0 @@
1
- __version__ = '0.2.0'
File without changes
File without changes
File without changes