
chrism at plope
Mar 3, 2006, 8:39 PM
Post #1 of 5
(1226 views)
Permalink
|
|
SVN: zope.timestamp/ Import zope.timestamp egg module
|
|
Log message for revision 65784: Import zope.timestamp egg module Changed: A zope.timestamp/ A zope.timestamp/README.txt A zope.timestamp/setup.py A zope.timestamp/src/ A zope.timestamp/src/zope/ A zope.timestamp/src/zope/TimeStamp.c A zope.timestamp/src/zope/__init__.py A zope.timestamp/src/zope/tests.py -=- Added: zope.timestamp/README.txt =================================================================== --- zope.timestamp/README.txt 2006-03-03 23:05:49 UTC (rev 65783) +++ zope.timestamp/README.txt 2006-03-04 04:39:35 UTC (rev 65784) @@ -0,0 +1,69 @@ +Installing This Package +======================= + +Prerequisites +------------- + +The installation steps below assume that you have the cool new 'setuptools' +package installed in your Python. Here is where to get it: + + $ wget http://peak.telecommunity.com/dist/ez_setup.py + $ /path/to/your/python ez_setup.py # req. write access to 'site-packages' + + - Docs for EasyInstall: + http://peak.telecommunity.com/DevCenter/EasyInstall + + - Docs for setuptools: + http://peak.telecommunity.com/DevCenter/setuptools + + - Docs for eggs: + http://peak.telecommunity.com/DevCenter/PythonEggs + + +Installing a Development Checkout +--------------------------------- + +Check out the package from subversion: + + $ svn co svn+ssh://svn.zope.org/repos/main/zope.timestamp/trunk \ + src/zope.timestamp + $ cd src/zope.timestamp + +Install it as a "devlopment egg": + + $ /path/to/your/python setup.py devel + +Running the Tests +----------------- + +Eventually, you should be able to type: + + $ /path/to/your/python setup.py test + +and have it run the tests. Today, the workaround is run the tests +from the checkout's 'zope' directory: + + $ /path/to/your/python tests.py + Running: + ............. + Ran 5 tests with 0 failures and 0 errors in 0.094 seconds. + +Installing a Source Distribution +-------------------------------- + +You can also install it from a source distribution: + + $ /path/to/easy_install --find-links="...." -eb src zope-timestamp + $ cd src/zope.weakset + $ /path/to/your/python setup.py devel + + +Installing a Binary Egg +----------------------- + +Install the package as a "binary egg" (which also installs its "hard" +dependencies): + + $ /path/to/easy_install --find-links="...." zope-timestamp + + Added: zope.timestamp/setup.py =================================================================== --- zope.timestamp/setup.py 2006-03-03 23:05:49 UTC (rev 65783) +++ zope.timestamp/setup.py 2006-03-04 04:39:35 UTC (rev 65784) @@ -0,0 +1,71 @@ +############################################################################## +# +# Copyright (c) 2006 Zope Corporation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +"""Zope Object Database: object database and persistence + +The Zope Object Database provides an object-oriented database for +Python that provides a high-degree of transparency. Applications can +take advantage of object database features with few, if any, changes +to application logic. ZODB includes features such as a plugable storage +interface, rich transaction support, and undo. + +This distribution includes the TimeStamp module from ZODB. +""" + +# The (non-obvious!) choices for the Trove Development Status line: +# Development Status :: 5 - Production/Stable +# Development Status :: 4 - Beta +# Development Status :: 3 - Alpha + +import os +from setuptools import setup, Extension + +classifiers = """\ +Development Status :: 5 - Production +Intended Audience :: Developers +License :: OSI Approved :: Zope Public License +Programming Language :: Python +Topic :: Database +Topic :: Software Development :: Libraries :: Python Modules +Operating System :: Microsoft :: Windows +Operating System :: Unix +""" + +timestamp = Extension(name = 'zope.timestamp', + include_dirs = ['src/zope'], + sources= ['src/zope/TimeStamp.c'] + ) + +setup(name='zope.timestamp', + version='3.6.0', + url='http://svn.zope.org/ZODB', + download_url = "http://www.zope.org/Products/ZODB3.6", + license='ZPL 2.1', + description='ZODB TimeStamp implementation', + author='Zope Corporation and Contributors', + maintainer='Zope Corporation and Contributors', + author_email='zodb-dev [at] zope', + maintainer_email='zodb-dev [at] zope', + platforms = ['any'], + classifiers = filter(None, classifiers.split("\n")), + long_description = __doc__, + packages=['zope'], + package_dir = {'': 'src'}, + ext_modules=[timestamp], + tests_require = [], + install_requires=[], + include_package_data = True, + zip_safe = True, + ) + + Property changes on: zope.timestamp/setup.py ___________________________________________________________________ Name: svn:eol-style + native Added: zope.timestamp/src/zope/TimeStamp.c =================================================================== --- zope.timestamp/src/zope/TimeStamp.c 2006-03-03 23:05:49 UTC (rev 65783) +++ zope.timestamp/src/zope/TimeStamp.c 2006-03-04 04:39:35 UTC (rev 65784) @@ -0,0 +1,437 @@ +/***************************************************************************** + + Copyright (c) 2001, 2004 Zope Corporation and Contributors. + All Rights Reserved. + + This software is subject to the provisions of the Zope Public License, + Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. + THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED + WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS + FOR A PARTICULAR PURPOSE + + ****************************************************************************/ + +#include "Python.h" +#include <time.h> + +PyObject *TimeStamp_FromDate(int, int, int, int, int, double); +PyObject *TimeStamp_FromString(const char *); + +static char TimeStampModule_doc[] = +"A 64-bit TimeStamp used as a ZODB serial number.\n" +"\n" +"$Id: TimeStamp.c 29450 2005-03-11 23:53:09Z tim_one $\n"; + + +typedef struct { + PyObject_HEAD + unsigned char data[8]; +} TimeStamp; + +/* The first dimension of the arrays below is non-leapyear / leapyear */ + +static char month_len[2][12]={ + {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, + {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} +}; + +static short joff[2][12] = { + {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}, + {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335} +}; + +static double gmoff=0; + +/* TODO: May be better (faster) to store in a file static. */ +#define SCONV ((double)60) / ((double)(1<<16)) / ((double)(1<<16)) + +static int +leap(int year) +{ + return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0); +} + +static int +days_in_month(int year, int month) +{ + return month_len[leap(year)][month]; +} + +static double +TimeStamp_yad(int y) +{ + double d, s; + + y -= 1900; + + d = (y - 1) * 365; + if (y > 0) { + s = 1.0; + y -= 1; + } else { + s = -1.0; + y = -y; + } + return d + s * (y / 4 - y / 100 + (y + 300) / 400); +} + +static double +TimeStamp_abst(int y, int mo, int d, int m, int s) +{ + return (TimeStamp_yad(y) + joff[leap(y)][mo] + d) * 86400 + m * 60 + s; +} + +static int +TimeStamp_init_gmoff(void) +{ + struct tm *t; + time_t z=0; + + t = gmtime(&z); + if (t == NULL) { + PyErr_SetString(PyExc_SystemError, "gmtime failed"); + return -1; + } + + gmoff = TimeStamp_abst(t->tm_year+1900, t->tm_mon, t->tm_mday - 1, + t->tm_hour * 60 + t->tm_min, t->tm_sec); + + return 0; +} + +static void +TimeStamp_dealloc(TimeStamp *ts) +{ + PyObject_Del(ts); +} + +static int +TimeStamp_compare(TimeStamp *v, TimeStamp *w) +{ + int cmp = memcmp(v->data, w->data, 8); + if (cmp < 0) return -1; + if (cmp > 0) return 1; + return 0; +} + +static long +TimeStamp_hash(TimeStamp *self) +{ + register unsigned char *p = (unsigned char *)self->data; + register int len = 8; + register long x = *p << 7; + while (--len >= 0) + x = (1000003*x) ^ *p++; + x ^= 8; + if (x == -1) + x = -2; + return x; +} + +typedef struct { + /* TODO: reverse-engineer what's in these things and comment them */ + int y; + int m; + int d; + int mi; +} TimeStampParts; + +static void +TimeStamp_unpack(TimeStamp *self, TimeStampParts *p) +{ + unsigned long v; + + v = (self->data[0] * 16777216 + self->data[1] * 65536 + + self->data[2] * 256 + self->data[3]); + p->y = v / 535680 + 1900; + p->m = (v % 535680) / 44640 + 1; + p->d = (v % 44640) / 1440 + 1; + p->mi = v % 1440; +} + +static double +TimeStamp_sec(TimeStamp *self) +{ + unsigned int v; + + v = (self->data[4] * 16777216 + self->data[5] * 65536 + + self->data[6] * 256 + self->data[7]); + return SCONV * v; +} + +static PyObject * +TimeStamp_year(TimeStamp *self) +{ + TimeStampParts p; + TimeStamp_unpack(self, &p); + return PyInt_FromLong(p.y); +} + +static PyObject * +TimeStamp_month(TimeStamp *self) +{ + TimeStampParts p; + TimeStamp_unpack(self, &p); + return PyInt_FromLong(p.m); +} + +static PyObject * +TimeStamp_day(TimeStamp *self) +{ + TimeStampParts p; + TimeStamp_unpack(self, &p); + return PyInt_FromLong(p.d); +} + +static PyObject * +TimeStamp_hour(TimeStamp *self) +{ + TimeStampParts p; + TimeStamp_unpack(self, &p); + return PyInt_FromLong(p.mi / 60); +} + +static PyObject * +TimeStamp_minute(TimeStamp *self) +{ + TimeStampParts p; + TimeStamp_unpack(self, &p); + return PyInt_FromLong(p.mi % 60); +} + +static PyObject * +TimeStamp_second(TimeStamp *self) +{ + return PyFloat_FromDouble(TimeStamp_sec(self)); +} + +static PyObject * +TimeStamp_timeTime(TimeStamp *self) +{ + TimeStampParts p; + TimeStamp_unpack(self, &p); + return PyFloat_FromDouble(TimeStamp_abst(p.y, p.m - 1, p.d - 1, p.mi, 0) + + TimeStamp_sec(self) - gmoff); +} + +static PyObject * +TimeStamp_raw(TimeStamp *self) +{ + return PyString_FromStringAndSize(self->data, 8); +} + +static PyObject * +TimeStamp_str(TimeStamp *self) +{ + char buf[128]; + TimeStampParts p; + int len; + + TimeStamp_unpack(self, &p); + len =sprintf(buf, "%4.4d-%2.2d-%2.2d %2.2d:%2.2d:%09.6f", + p.y, p.m, p.d, p.mi / 60, p.mi % 60, + TimeStamp_sec(self)); + + return PyString_FromStringAndSize(buf, len); +} + + +static PyObject * +TimeStamp_laterThan(TimeStamp *self, PyObject *obj) +{ + TimeStamp *o = NULL; + TimeStampParts p; + unsigned char new[8]; + int i; + + if (obj->ob_type != self->ob_type) { + PyErr_SetString(PyExc_TypeError, "expected TimeStamp object"); + return NULL; + } + o = (TimeStamp *)obj; + if (memcmp(self->data, o->data, 8) > 0) { + Py_INCREF(self); + return (PyObject *)self; + } + + memcpy(new, o->data, 8); + for (i = 7; i > 3; i--) { + if (new[i] == 255) + new[i] = 0; + else { + new[i]++; + return TimeStamp_FromString(new); + } + } + + /* All but the first two bytes are the same. Need to increment + the year, month, and day explicitly. */ + TimeStamp_unpack(o, &p); + if (p.mi >= 1439) { + p.mi = 0; + if (p.d == month_len[leap(p.y)][p.m - 1]) { + p.d = 1; + if (p.m == 12) { + p.m = 1; + p.y++; + } else + p.m++; + } else + p.d++; + } else + p.mi++; + + return TimeStamp_FromDate(p.y, p.m, p.d, p.mi / 60, p.mi % 60, 0); +} + +static struct PyMethodDef TimeStamp_methods[] = { + {"year", (PyCFunction)TimeStamp_year, METH_NOARGS}, + {"minute", (PyCFunction)TimeStamp_minute, METH_NOARGS}, + {"month", (PyCFunction)TimeStamp_month, METH_NOARGS}, + {"day", (PyCFunction)TimeStamp_day, METH_NOARGS}, + {"hour", (PyCFunction)TimeStamp_hour, METH_NOARGS}, + {"second", (PyCFunction)TimeStamp_second, METH_NOARGS}, + {"timeTime",(PyCFunction)TimeStamp_timeTime, METH_NOARGS}, + {"laterThan", (PyCFunction)TimeStamp_laterThan, METH_O}, + {"raw", (PyCFunction)TimeStamp_raw, METH_NOARGS}, + {NULL, NULL}, +}; + +static PyTypeObject TimeStamp_type = { + PyObject_HEAD_INIT(NULL) + 0, + "timestamp", + sizeof(TimeStamp), + 0, + (destructor)TimeStamp_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + (cmpfunc)TimeStamp_compare, /* tp_compare */ + (reprfunc)TimeStamp_raw, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + (hashfunc)TimeStamp_hash, /* tp_hash */ + 0, /* tp_call */ + (reprfunc)TimeStamp_str, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + TimeStamp_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ +}; + +PyObject * +TimeStamp_FromString(const char *buf) +{ + /* buf must be exactly 8 characters */ + TimeStamp *ts = (TimeStamp *)PyObject_New(TimeStamp, &TimeStamp_type); + memcpy(ts->data, buf, 8); + return (PyObject *)ts; +} + +#define CHECK_RANGE(VAR, LO, HI) if ((VAR) < (LO) || (VAR) > (HI)) { \ + return PyErr_Format(PyExc_ValueError, \ + # VAR " must be between %d and %d: %d", \ + (LO), (HI), (VAR)); \ + } + +PyObject * +TimeStamp_FromDate(int year, int month, int day, int hour, int min, + double sec) +{ + TimeStamp *ts = NULL; + int d; + unsigned int v; + + if (year < 1900) + return PyErr_Format(PyExc_ValueError, + "year must be greater than 1900: %d", year); + CHECK_RANGE(month, 1, 12); + d = days_in_month(year, month - 1); + if (day < 1 || day > d) + return PyErr_Format(PyExc_ValueError, + "day must be between 1 and %d: %d", d, day); + CHECK_RANGE(hour, 0, 23); + CHECK_RANGE(min, 0, 59); + /* Seconds are allowed to be anything, so chill + If we did want to be pickly, 60 would be a better choice. + if (sec < 0 || sec > 59) + return PyErr_Format(PyExc_ValueError, + "second must be between 0 and 59: %f", sec); + */ + ts = (TimeStamp *)PyObject_New(TimeStamp, &TimeStamp_type); + v = (((year - 1900) * 12 + month - 1) * 31 + day - 1); + v = (v * 24 + hour) * 60 + min; + ts->data[0] = v / 16777216; + ts->data[1] = (v % 16777216) / 65536; + ts->data[2] = (v % 65536) / 256; + ts->data[3] = v % 256; + sec /= SCONV; + v = (unsigned int)sec; + ts->data[4] = v / 16777216; + ts->data[5] = (v % 16777216) / 65536; + ts->data[6] = (v % 65536) / 256; + ts->data[7] = v % 256; + + return (PyObject *)ts; +} + +PyObject * +TimeStamp_TimeStamp(PyObject *obj, PyObject *args) +{ + char *buf = NULL; + int len = 0, y, mo, d, h = 0, m = 0; + double sec = 0; + + if (PyArg_ParseTuple(args, "s#:TimeStamp", &buf, &len)) { + if (len != 8) { + PyErr_SetString(PyExc_ValueError, "8-character string expected"); + return NULL; + } + return TimeStamp_FromString(buf); + } + PyErr_Clear(); + + if (!PyArg_ParseTuple(args, "iii|iid", &y, &mo, &d, &h, &m, &sec)) + return NULL; + return TimeStamp_FromDate(y, mo, d, h, m, sec); +} + +static PyMethodDef TimeStampModule_functions[] = { + {"TimeStamp", TimeStamp_TimeStamp, METH_VARARGS}, + {NULL, NULL}, +}; + + +void +inittimestamp(void) +{ + PyObject *m; + + if (TimeStamp_init_gmoff() < 0) + return; + + m = Py_InitModule4("timestamp", TimeStampModule_functions, + TimeStampModule_doc, NULL, PYTHON_API_VERSION); + if (m == NULL) + return; + + TimeStamp_type.ob_type = &PyType_Type; + TimeStamp_type.tp_getattro = PyObject_GenericGetAttr; +} Added: zope.timestamp/src/zope/__init__.py =================================================================== --- zope.timestamp/src/zope/__init__.py 2006-03-03 23:05:49 UTC (rev 65783) +++ zope.timestamp/src/zope/__init__.py 2006-03-04 04:39:35 UTC (rev 65784) @@ -0,0 +1,3 @@ +# Package +import pkg_resources +pkg_resources.declare_namespace('zope') Property changes on: zope.timestamp/src/zope/__init__.py ___________________________________________________________________ Name: svn:eol-style + native Added: zope.timestamp/src/zope/tests.py =================================================================== --- zope.timestamp/src/zope/tests.py 2006-03-03 23:05:49 UTC (rev 65783) +++ zope.timestamp/src/zope/tests.py 2006-03-04 04:39:35 UTC (rev 65784) @@ -0,0 +1,182 @@ +############################################################################# +# +# Copyright (c) 2006 Zope Corporation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## + +import unittest +import time +from timestamp import TimeStamp + +EPSILON = 0.000001 + +class TimeStampTests(unittest.TestCase): + def testStringInput(self): + ts = TimeStamp('00000000') + self.assertEqual(repr(ts), '00000000') + ts = TimeStamp('11111111') + self.assertEqual(repr(ts), '11111111') + + def testTupleInput(self): + t = int(time.time()) + args = time.gmtime(t)[:6] + ts = TimeStamp(*args) + self.assertEqual(ts.year(), args[0]) + self.assertEqual(ts.month(), args[1]) + self.assertEqual(ts.day(), args[2]) + self.assertEqual(ts.hour(), args[3]) + self.assertEqual(ts.minute(), args[4]) + self.assertEqual(int(round(ts.second())), args[5]) + + def testRaw(self): + ts = TimeStamp('00000000') + self.assertEqual(repr(ts), ts.raw()) + ts = TimeStamp('11111111') + self.assertEqual(repr(ts), ts.raw()) + + def testStr(self): + t1 = 1141445984 + args1 = time.gmtime(t1)[:6] + ts1 = TimeStamp(*args1) + self.assertEqual(str(ts1), '2006-03-04 04:19:44.000000') + + def testTimeTime(self): + t = int(time.time()) + args = time.gmtime(t)[:6] + ts = TimeStamp(*args) + tt = ts.timeTime() + self.assertEqual(tt, t) + + def testYMDTimeStamp(self): + self._check_ymd(2001, 6, 3) + + def _check_ymd(self, yr, mo, dy): + ts = TimeStamp(yr, mo, dy) + self.assertEqual(ts.year(), yr) + self.assertEqual(ts.month(), mo) + self.assertEqual(ts.day(), dy) + + self.assertEquals(ts.hour(), 0) + self.assertEquals(ts.minute(), 0) + self.assertEquals(ts.second(), 0) + + t = time.gmtime(ts.timeTime()) + self.assertEquals(yr, t[0]) + self.assertEquals(mo, t[1]) + self.assertEquals(dy, t[2]) + + def testFullTimeStamp(self): + native_ts = int(time.time()) # fractional seconds get in the way + t = time.gmtime(native_ts) # the corresponding GMT struct tm + ts = TimeStamp(*t[:6]) + + # Seconds are stored internally via (conceptually) multiplying by + # 2**32 then dividing by 60, ending up with a 32-bit integer. + # While this gives a lot of room for cramming many distinct + # TimeStamps into a second, it's not good at roundtrip accuracy. + # For example, 1 second is stored as int(2**32/60) == 71582788. + # Converting back gives 71582788*60.0/2**32 == 0.9999999962747097. + # In general, we can lose up to 0.999... to truncation during + # storing, creating an absolute error up to about 1*60.0/2**32 == + # 0.000000014 on the seconds value we get back. This is so even + # when we have an exact integral second value going in (as we + # do in this test), so we can't expect equality in any comparison + # involving seconds. Minutes (etc) are stored exactly, so we + # can expect equality for those. + + self.assert_(abs(ts.timeTime() - native_ts) < EPSILON) + self.assertEqual(ts.year(), t[0]) + self.assertEqual(ts.month(), t[1]) + self.assertEqual(ts.day(), t[2]) + self.assertEquals(ts.hour(), t[3]) + self.assertEquals(ts.minute(), t[4]) + self.assert_(abs(ts.second() - t[5]) < EPSILON) + + def testRawTimestamp(self): + t = time.gmtime() + ts1 = TimeStamp(*t[:6]) + ts2 = TimeStamp(`ts1`) + + self.assertEquals(ts1, ts2) + self.assertEquals(ts1.timeTime(), ts2.timeTime()) + self.assertEqual(ts1.year(), ts2.year()) + self.assertEqual(ts1.month(), ts2.month()) + self.assertEqual(ts1.day(), ts2.day()) + self.assertEquals(ts1.hour(), ts2.hour()) + self.assertEquals(ts1.minute(), ts2.minute()) + self.assert_(abs(ts1.second() - ts2.second()) < EPSILON) + + def testDictKey(self): + t = time.gmtime() + ts1 = TimeStamp(*t[:6]) + ts2 = TimeStamp(2000, *t[1:6]) + + d = {} + d[ts1] = 1 + d[ts2] = 2 + + self.assertEquals(len(d), 2) + + def testCompare(self): + ts1 = TimeStamp(1972, 6, 27) + ts2 = TimeStamp(1971, 12, 12) + self.assert_(ts1 > ts2) + self.assert_(ts2 <= ts1) + + def testLaterThan(self): + t = time.gmtime() + ts = TimeStamp(*t[:6]) + ts2 = ts.laterThan(ts) + self.assert_(ts2 > ts) + + # TODO: should test for bogus inputs to TimeStamp constructor + + def testTimeStamp(self): + # Alternate test suite + t = TimeStamp(2002, 1, 23, 10, 48, 5) # GMT + self.assertEquals(str(t), '2002-01-23 10:48:05.000000') + self.assertEquals(repr(t), '\x03B9H\x15UUU') + self.assertEquals(TimeStamp('\x03B9H\x15UUU'), t) + self.assertEquals(t.year(), 2002) + self.assertEquals(t.month(), 1) + self.assertEquals(t.day(), 23) + self.assertEquals(t.hour(), 10) + self.assertEquals(t.minute(), 48) + self.assertEquals(round(t.second()), 5) + self.assertEquals(t.timeTime(), 1011782885) + t1 = TimeStamp(2002, 1, 23, 10, 48, 10) + self.assertEquals(str(t1), '2002-01-23 10:48:10.000000') + self.assert_(t == t) + self.assert_(t != t1) + self.assert_(t < t1) + self.assert_(t <= t1) + self.assert_(t1 >= t) + self.assert_(t1 > t) + self.failIf(t == t1) + self.failIf(t != t) + self.failIf(t > t1) + self.failIf(t >= t1) + self.failIf(t1 < t) + self.failIf(t1 <= t) + self.assertEquals(cmp(t, t), 0) + self.assertEquals(cmp(t, t1), -1) + self.assertEquals(cmp(t1, t), 1) + self.assertEquals(t1.laterThan(t), t1) + self.assert_(t.laterThan(t1) > t1) + self.assertEquals(TimeStamp(2002,1,23), TimeStamp(2002,1,23,0,0,0)) + + +def test_suite(): + return unittest.makeSuite(TimeStampTests) + +if __name__ == '__main__': + unittest.main() + Property changes on: zope.timestamp/src/zope/tests.py ___________________________________________________________________ Name: svn:eol-style + native _______________________________________________ Zope-CVS maillist - Zope-CVS [at] zope http://mail.zope.org/mailman/listinfo/zope-cvs Zope CVS instructions: http://dev.zope.org/CVS
|