Skip to content

Commit

Permalink
Add shift() method to time_machine pytest fixture (#312)
Browse files Browse the repository at this point in the history
Co-authored-by: Adam Johnson <[email protected]>
  • Loading branch information
soxofaan and adamchainz authored Sep 19, 2023
1 parent 21be5b7 commit d97adc6
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 2 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
Changelog
=========

* Add ``shift()`` method to the ``time_machine`` pytest fixture.

Thanks to Stefaan Lippens in `PR 312 <https://github.com/adamchainz/time-machine/pull/312>`__.

* Mock ``time.monotonic()`` and ``time.monotonic_ns()``.
They return the values of ``time.time()`` and ``time.time_ns()`` respectively, rather than real monotonic clocks.

Expand Down
6 changes: 5 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ pytest plugin
-------------

time-machine also works as a pytest plugin.
It provides a function-scoped fixture called ``time_machine`` that has one method, ``move_to()``, which has the same signature as ``Coordinates.move_to()``.
It provides a function-scoped fixture called ``time_machine`` with methods ``move_to()`` and ``shift()``, which have the same signature as their equivalents in ``Coordinates``.
This can be used to mock your test at different points in time and will automatically be un-mock when the test is torn down.

For example:
Expand All @@ -316,6 +316,10 @@ For example:
assert dt.date.today().isoformat() == "2015-10-21"
time_machine.shift(dt.timedelta(days=1))
assert dt.date.today().isoformat() == "2015-10-22"
If you are using pytest test classes, you can apply the fixture to all test methods in a class by adding an autouse fixture:

.. code-block:: python
Expand Down
8 changes: 8 additions & 0 deletions src/time_machine/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,14 @@ def move_to(
assert self.coordinates is not None
self.coordinates.move_to(destination, tick=tick)

def shift(self, delta: dt.timedelta | int | float) -> None:
if self.traveller is None:
raise RuntimeError(
"Initialize time_machine with move_to() before using shift()."
)
assert self.coordinates is not None
self.coordinates.shift(delta=delta)

def stop(self) -> None:
if self.traveller is not None:
self.traveller.stop()
Expand Down
18 changes: 17 additions & 1 deletion tests/test_time_machine.py
Original file line number Diff line number Diff line change
Expand Up @@ -717,14 +717,30 @@ def test_fixture_used_tick_true(time_machine):
assert original < time.time() < EPOCH + 10.0


def test_fixture_used_twice(time_machine):
def test_fixture_move_to_twice(time_machine):
time_machine.move_to(EPOCH)
assert time.time() == EPOCH

time_machine.move_to(EPOCH_PLUS_ONE_YEAR)
assert time.time() == EPOCH_PLUS_ONE_YEAR


def test_fixture_move_to_and_shift(time_machine):
time_machine.move_to(EPOCH, tick=False)
assert time.time() == EPOCH
time_machine.shift(100)
assert time.time() == EPOCH + 100


def test_fixture_shift_without_move_to(time_machine):
with pytest.raises(RuntimeError) as excinfo:
time_machine.shift(100)

assert excinfo.value.args == (
"Initialize time_machine with move_to() before using shift().",
)


# escape hatch tests


Expand Down

0 comments on commit d97adc6

Please sign in to comment.