changeset 12:f9f15ee39ed7

New Status class that handles several fields
author Bernhard Herzog <bh@intevation.de>
date Fri, 09 Mar 2007 18:23:09 +0100 (2007-03-09)
parents 6efe0bd3d8c1
children 3e6aa2a7f905
files test/runtests.py test/test_status.py treepkg/status.py
diffstat 3 files changed, 237 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtests.py	Fri Mar 09 18:23:09 2007 +0100
@@ -0,0 +1,72 @@
+# Copyright (C) 2007 by Intevation GmbH
+# Authors:
+# Bernhard Herzog <bh@intevation.de>
+#
+# This program is free software under the GPL (>=v2)
+# Read the file COPYING coming with the software for details.
+
+"""
+Main entry point for the test suite.
+
+Just run this file as a python script to execute all tests
+"""
+
+import os
+import sys
+import unittest
+import optparse
+
+test_dir = os.path.dirname(__file__)
+sys.path.append(os.path.join(test_dir, os.pardir))
+
+def find_test_modules(dirname, package = None):
+    """Return a list the names of the test modules in the directory dirname
+
+    The return value is a list of names that can be passed to
+    unittest.defaultTestLoader.loadTestsFromNames.  Each name of the
+    list is the name of a pure python module, one for each file in
+    dirname whose name starts with 'test' and ends with '.py'.
+
+    The optional parameter package should be the name of the python
+    package whose directory is dirname.  If package is given all names
+    in the returned list will be prefixed with package and a dot.
+    """
+    if package:
+        prefix = package + "."
+    else:
+        prefix = ""
+
+    suffix = ".py"
+    return [prefix + name[:-len(suffix)]
+            for name in os.listdir(dirname)
+                if name.startswith("test") and name.endswith(suffix)]
+
+
+def main():
+    """Run all the tests in the test suite"""
+
+    parser = optparse.OptionParser()
+    parser.set_defaults(verbosity=1)
+    parser.add_option("-v", "--verbose", action="store_const", const=2,
+                      dest="verbosity")
+    opts, rest = parser.parse_args()
+
+    # Build the list of test names.  If names were given on the command
+    # line, run exactly those.  Othwerwise build a default list of
+    # names.
+    if rest:
+        names = rest
+    else:
+        # All Python files starting with 'test' in the current directory
+        # and some directories in Extensions contain test cases.
+        # FIXME: It should be possible to run runtests.py even when not in
+        # the test directory
+        names = find_test_modules(test_dir)
+    suite = unittest.defaultTestLoader.loadTestsFromNames(names)
+    runner = unittest.TextTestRunner(verbosity=opts.verbosity)
+    result = runner.run(suite)
+    sys.exit(not result.wasSuccessful())
+
+
+if __name__ == "__main__":
+    main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/test_status.py	Fri Mar 09 18:23:09 2007 +0100
@@ -0,0 +1,62 @@
+# Copyright (C) 2007 by Intevation GmbH
+# Authors:
+# Bernhard Herzog <bh@intevation.de>
+#
+# This program is free software under the GPL (>=v2)
+# Read the file COPYING coming with the software for details.
+
+"""Tests for the Status class"""
+
+import os
+import unittest
+from datetime import datetime
+
+from treepkg.status import Status
+from treepkg.util import ensure_directory, writefile
+
+
+
+class TestStatus(unittest.TestCase):
+
+    def tempfilename(self):
+        tempdir = os.path.join(os.path.dirname(__file__), "temp")
+        ensure_directory(tempdir)
+        return os.path.join(tempdir, self.id())
+
+    def setUp(self):
+        self.filename = self.tempfilename()
+        if os.path.exists(self.filename):
+            os.remove(self.filename)
+
+    def test_status(self):
+        status = Status(self.filename)
+        status.status = "testing"
+
+        otherstatus = Status(self.filename)
+        self.assertEquals(otherstatus.status, "testing")
+
+    def test_getting_unknown_fields(self):
+        status = Status(self.filename)
+        self.assertRaises(AttributeError, getattr, status, "unknown_field")
+
+    def test_setting_unknown_fields(self):
+        status = Status(self.filename)
+        self.assertRaises(AttributeError,
+                          setattr, status, "unknown_field", "some value")
+
+    def test_default_value(self):
+        status = Status(self.filename)
+        self.assertEquals(status.start, None)
+
+    def test_date(self):
+        timestamp = datetime(2007, 3, 9, 17, 32, 55)
+        status = Status(self.filename)
+        status.start = timestamp
+
+        otherstatus = Status(self.filename)
+        self.assertEquals(otherstatus.start, timestamp)
+
+    def test_magic(self):
+        writefile(self.filename,
+                  "Some other magic\nstart: 2007-03-09 17:32:55\n")
+        self.assertRaises(ValueError, Status, self.filename)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/treepkg/status.py	Fri Mar 09 18:23:09 2007 +0100
@@ -0,0 +1,103 @@
+# Copyright (C) 2007 by Intevation GmbH
+# Authors:
+# Bernhard Herzog <bh@intevation.de>
+#
+# This program is free software under the GPL (>=v2)
+# Read the file COPYING coming with the software for details.
+
+import os
+import datetime
+import time
+
+import util
+
+
+# special object to indicate no default value
+nodefault = object()
+
+def serialize_datetime(d):
+    return d.strftime("%Y-%m-%d %H:%M:%S")
+
+def deserialize_datetime(s):
+    return datetime.datetime(*time.strptime(s.strip(), "%Y-%m-%d %H:%M:%S")[:6])
+
+
+class FieldDesc(object):
+
+    def __init__(self, serialize, deserialize, default=nodefault):
+        self.serialize = serialize
+        self.deserialize = deserialize
+        self.default = default
+
+    def has_default(self):
+        return self.default is not nodefault
+
+class StringFieldDesc(FieldDesc):
+
+    def __init__(self, **kw):
+        super(StringFieldDesc, self).__init__(str, lambda s: s.strip(), **kw)
+
+class DateFieldDesc(FieldDesc):
+
+    def __init__(self, **kw):
+        super(DateFieldDesc, self).__init__(serialize_datetime,
+                                            deserialize_datetime, **kw)
+
+
+class Status(object):
+
+    fields = dict(status=StringFieldDesc(),
+                  start=DateFieldDesc(default=None))
+
+    attrs = set(["filename", "values"])
+
+    magic = "TreePackagerStatus 0.0\n"
+
+    def __init__(self, filename):
+        assert os.path.isabs(filename)
+        self.filename = filename
+        self.read()
+
+    def _init_values(self):
+        self.values = {}
+
+    def read(self):
+        self._init_values()
+        if not os.path.exists(self.filename):
+            return
+        f = open(self.filename)
+        try:
+            magic = f.next()
+            if magic != self.magic:
+                raise ValueError("File %r has wrong magic" % self.filename)
+            for line in f:
+                field, value = line.split(":", 1)
+                self.values[field] = self.fields[field].deserialize(value)
+        finally:
+            f.close()
+
+    def write(self):
+        lines = [self.magic]
+        for field, desc in self.fields.items():
+            if field in self.values:
+                lines.append("%s: %s\n"
+                             % (field, desc.serialize(self.values[field])))
+        util.writefile(self.filename, "".join(lines))
+
+    def __getattr__(self, attr):
+        desc = self.fields.get(attr)
+        if desc is not None:
+            if attr in self.values:
+                return self.values[attr]
+            elif desc.has_default():
+                return desc.default
+        raise AttributeError(attr)
+
+    def __setattr__(self, attr, value):
+        if attr in self.fields:
+            self.values[attr] = value
+            self.write()
+        elif attr in self.attrs:
+            self.__dict__[attr] = value
+        else:
+            raise AttributeError(attr)
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)