summaryrefslogtreecommitdiff
path: root/tests/alter_time.py
diff options
context:
space:
mode:
authorRaphaël Barrois <raphael.barrois@polytechnique.org>2013-04-21 22:29:46 +0200
committerRaphaël Barrois <raphael.barrois@polytechnique.org>2013-04-21 22:29:46 +0200
commit3b75e132fd1f302b604e76f4c1a0361c32ba50d4 (patch)
treea285557ceda0d30fe85aa264f6578b1826d0bbb4 /tests/alter_time.py
parentb5f0579a9050b38392f45eb8e29b51e46928584a (diff)
downloadfactory-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.py113
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()