diff options
author | Raphaël Barrois <raphael.barrois@polytechnique.org> | 2013-04-21 22:29:46 +0200 |
---|---|---|
committer | Raphaël Barrois <raphael.barrois@polytechnique.org> | 2013-04-21 22:29:46 +0200 |
commit | 3b75e132fd1f302b604e76f4c1a0361c32ba50d4 (patch) | |
tree | a285557ceda0d30fe85aa264f6578b1826d0bbb4 /tests/alter_time.py | |
parent | b5f0579a9050b38392f45eb8e29b51e46928584a (diff) | |
download | factory-boy-3b75e132fd1f302b604e76f4c1a0361c32ba50d4.tar factory-boy-3b75e132fd1f302b604e76f4c1a0361c32ba50d4.tar.gz |
Add tests.alter_time and fix time altering on pypy.
Diffstat (limited to 'tests/alter_time.py')
-rw-r--r-- | tests/alter_time.py | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/tests/alter_time.py b/tests/alter_time.py new file mode 100644 index 0000000..f426e03 --- /dev/null +++ b/tests/alter_time.py @@ -0,0 +1,113 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# This code is in the public domain +# Author: Raphaël Barrois + + +from __future__ import print_function + +import datetime +import mock + + +real_datetime_class = datetime.datetime + +def mock_datetime_now(target, datetime_module): + """Override ``datetime.datetime.now()`` with a custom target value. + + This creates a new datetime.datetime class, and alters its now()/utcnow() + methods. + + Returns: + A mock.patch context, can be used as a decorator or in a with. + """ + + # See http://bugs.python.org/msg68532 + # And http://docs.python.org/reference/datamodel.html#customizing-instance-and-subclass-checks + class DatetimeSubclassMeta(type): + """We need to customize the __instancecheck__ method for isinstance(). + + This must be performed at a metaclass level. + """ + + @classmethod + def __instancecheck__(mcs, obj): + return isinstance(obj, real_datetime_class) + + class BaseMockedDatetime(real_datetime_class): + @classmethod + def now(cls, tz=None): + return target.replace(tzinfo=tz) + + @classmethod + def utcnow(cls): + return target + + # Python2 & Python3-compatible metaclass + MockedDatetime = DatetimeSubclassMeta('datetime', (BaseMockedDatetime,), {}) + + return mock.patch.object(datetime_module, 'datetime', MockedDatetime) + +real_date_class = datetime.date + +def mock_date_today(target, datetime_module): + """Override ``datetime.date.today()`` with a custom target value. + + This creates a new datetime.date class, and alters its today() method. + + Returns: + A mock.patch context, can be used as a decorator or in a with. + """ + + # See http://bugs.python.org/msg68532 + # And http://docs.python.org/reference/datamodel.html#customizing-instance-and-subclass-checks + class DateSubclassMeta(type): + """We need to customize the __instancecheck__ method for isinstance(). + + This must be performed at a metaclass level. + """ + + @classmethod + def __instancecheck__(mcs, obj): + return isinstance(obj, real_date_class) + + class BaseMockedDate(real_date_class): + @classmethod + def today(cls): + return target + + # Python2 & Python3-compatible metaclass + MockedDate = DateSubclassMeta('date', (BaseMockedDate,), {}) + + return mock.patch.object(datetime_module, 'date', MockedDate) + + +def main(): + """Run a couple of tests""" + target_dt = real_datetime_class(2009, 1, 1) + target_date = real_date_class(2009, 1, 1) + + print("Entering mock") + with mock_datetime_now(target_dt, datetime): + print("- now ->", datetime.datetime.now()) + print("- isinstance(now, dt) ->", isinstance(datetime.datetime.now(), datetime.datetime)) + print("- isinstance(target, dt) ->", isinstance(target_dt, datetime.datetime)) + + with mock_date_today(target_date, datetime): + print("- today ->", datetime.date.today()) + print("- isinstance(now, date) ->", isinstance(datetime.date.today(), datetime.date)) + print("- isinstance(target, date) ->", isinstance(target_date, datetime.date)) + + + print("Outside mock") + print("- now ->", datetime.datetime.now()) + print("- isinstance(now, dt) ->", isinstance(datetime.datetime.now(), datetime.datetime)) + print("- isinstance(target, dt) ->", isinstance(target_dt, datetime.datetime)) + + print("- today ->", datetime.date.today()) + print("- isinstance(now, date) ->", isinstance(datetime.date.today(), datetime.date)) + print("- isinstance(target, date) ->", isinstance(target_date, datetime.date)) + + +if __name__ == '__main__': + main() |