source: main/waeup.kofa/trunk/src/waeup/kofa/utils/tests/test_helpers.py @ 8185

Last change on this file since 8185 was 8185, checked in by uli, 12 years ago

Add datetime/timezone helpers urgently needed.

  • Property svn:keywords set to Id
File size: 10.9 KB
Line 
1# -*- coding: utf-8 -*-
2
3## $Id: test_helpers.py 8185 2012-04-16 23:17:35Z uli $
4##
5## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
6## This program is free software; you can redistribute it and/or modify
7## it under the terms of the GNU General Public License as published by
8## the Free Software Foundation; either version 2 of the License, or
9## (at your option) any later version.
10##
11## This program is distributed in the hope that it will be useful,
12## but WITHOUT ANY WARRANTY; without even the implied warranty of
13## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14## GNU General Public License for more details.
15##
16## You should have received a copy of the GNU General Public License
17## along with this program; if not, write to the Free Software
18## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19##
20
21import datetime
22import os
23import pytz
24import shutil
25import tempfile
26import unittest
27import doctest
28from cStringIO import StringIO
29from zope import schema
30from zope.interface import Interface, Attribute, implements
31from zope.security.testing import Principal, Participation
32from zope.security.management import newInteraction, endInteraction
33from waeup.kofa.utils import helpers
34
35class IFakeObject(Interface):
36    """Some marker interface."""
37
38class FakeObject(object):
39    implements(IFakeObject)
40
41class RemoveFileOrDirectoryTestCase(unittest.TestCase):
42
43    def setUp(self):
44        self.dirpath = tempfile.mkdtemp()
45        self.filepath = os.path.join(self.dirpath, 'somefile')
46        self.non_file = os.path.join(self.dirpath, 'nonfile')
47        open(self.filepath, 'wb').write('Hi!')
48        return
49
50    def tearDown(self):
51        if os.path.exists(self.dirpath):
52            shutil.rmtree(self.dirpath)
53        return
54
55    def test_handle_not_existing_path(self):
56        result = helpers.remove_file_or_directory(self.non_file)
57        self.assertTrue(result is None)
58        return
59
60    def test_handle_dir(self):
61        helpers.remove_file_or_directory(self.dirpath)
62        self.assertFalse(
63            os.path.exists(self.dirpath)
64            )
65        return
66
67    def test_handle_file(self):
68        helpers.remove_file_or_directory(self.filepath)
69        self.assertFalse(
70            os.path.exists(self.filepath)
71            )
72        return
73
74class CopyFileSystemTreeTestCase(unittest.TestCase):
75    # Test edge cases of copy_filesystem_tree().
76    #
77    # This is a typical case of tests not written as doctest as it is
78    # normally not interesting for developers and we only want to make
79    # sure everything works as expected.
80    def setUp(self):
81        self.existing_src = tempfile.mkdtemp()
82        self.filepath = os.path.join(self.existing_src, 'somefile')
83        open(self.filepath, 'wb').write('Hi!')
84        self.existing_dst = tempfile.mkdtemp()
85        self.not_existing_dir = tempfile.mkdtemp()
86        shutil.rmtree(self.not_existing_dir)
87
88        pass
89
90    def tearDown(self):
91        shutil.rmtree(self.existing_src)
92        shutil.rmtree(self.existing_dst)
93        pass
94
95    def test_source_and_dst_existing(self):
96        helpers.copy_filesystem_tree(self.existing_src, self.existing_dst)
97        self.assertTrue(
98            os.path.exists(
99                os.path.join(self.existing_dst, 'somefile')
100                )
101            )
102        return
103
104    def test_source_not_existing(self):
105        self.assertRaises(
106            ValueError,
107            helpers.copy_filesystem_tree,
108            self.not_existing_dir,
109            self.existing_dst
110            )
111        return
112
113    def test_dest_not_existing(self):
114        self.assertRaises(
115            ValueError,
116            helpers.copy_filesystem_tree,
117            self.existing_src,
118            self.not_existing_dir
119            )
120        return
121
122    def test_src_not_a_dir(self):
123        self.assertRaises(
124            ValueError,
125            helpers.copy_filesystem_tree,
126            self.filepath,
127            self.existing_dst
128            )
129        return
130
131    def test_dst_not_a_dir(self):
132        self.assertRaises(
133            ValueError,
134            helpers.copy_filesystem_tree,
135            self.existing_src,
136            self.filepath
137            )
138        return
139
140class ReST2HTMLTestCase(unittest.TestCase):
141
142    def setUp(self):
143        self.expected = u'<div class="document">\n\n\n<p>Some '
144        self.expected += u'test with \xfcmlaut</p>\n</div>'
145        return
146
147    def test_ascii_umlauts(self):
148        # Make sure we convert umlauts correctly to unicode.
149        source = 'Some test with ümlaut'
150        result = helpers.ReST2HTML(source)
151        self.assertEqual(result, self.expected)
152
153    def test_unicode_umlauts(self):
154        # Make sure we convert umlauts correctly to unicode.
155        source = u'Some test with ümlaut'
156        result = helpers.ReST2HTML(source)
157        self.assertEqual(result, self.expected)
158
159    def test_unicode_output_from_ascii(self):
160        source = 'Some test with ümlaut'
161        self.assertTrue(isinstance(helpers.ReST2HTML(source), unicode))
162
163    def test_unicode_output_from_unicode(self):
164        source = u'Some test with ümlaut'
165        self.assertTrue(isinstance(helpers.ReST2HTML(source), unicode))
166
167
168class FactoryBaseTestCase(unittest.TestCase):
169
170    def test_ifaces(self):
171        # We test all relevant parts in the docstring. But the interfaces
172        # method has to be tested to please the coverage report as well.
173        factory = helpers.FactoryBase()
174        factory.factory = FakeObject
175        self.assertTrue(factory.getInterfaces()(IFakeObject))
176        return
177
178class CurrentPrincipalTestCase(unittest.TestCase):
179
180    def tearDown(test):
181        endInteraction() # Just in case, one is still lingering around
182
183    def test_existing_principal(self):
184        # We can get the current principal if one is involved
185        principal = Principal('myprincipal')
186        newInteraction(Participation(principal))
187        result = helpers.get_current_principal()
188        self.assertTrue(result is principal)
189
190    def test_no_participation(self):
191        # Interactions without participation are handled correctly
192        newInteraction()
193        result = helpers.get_current_principal()
194        self.assertTrue(result is None)
195
196    def test_not_existing_principal(self):
197        # Missing interactions do not raise errors.
198        result = helpers.get_current_principal()
199        self.assertTrue(result is None)
200
201class CmpFilesTestCase(unittest.TestCase):
202
203    def setUp(self):
204        self.workdir = tempfile.mkdtemp()
205
206    def tearDown(self):
207        shutil.rmtree(self.workdir)
208
209    def test_equal(self):
210        p1 = os.path.join(self.workdir, 'sample1')
211        p2 = os.path.join(self.workdir, 'sample2')
212        open(p1, 'wb').write('Hi!')
213        open(p2, 'wb').write('Hi!')
214        assert helpers.cmp_files(open(p1, 'r'), open(p2, 'r')) is True
215
216    def test_unequal(self):
217        p1 = os.path.join(self.workdir, 'sample1')
218        p2 = os.path.join(self.workdir, 'sample2')
219        open(p1, 'wb').write('Hi!')
220        open(p2, 'wb').write('Ho!')
221        assert helpers.cmp_files(open(p1, 'r'), open(p2, 'r')) is False
222
223class FileSizeTestCase(unittest.TestCase):
224
225    def setUp(self):
226        self.workdir = tempfile.mkdtemp()
227
228    def tearDown(self):
229        shutil.rmtree(self.workdir)
230
231    def test_real_file(self):
232        # we can get the size of real files
233        path = os.path.join(self.workdir, 'sample.txt')
234        open(path, 'wb').write('My content')
235        self.assertEqual(
236            int(helpers.file_size(open(path, 'rb'))), 10)
237        return
238
239    def test_stringio_file(self):
240        # we can get the size of file-like objects
241        self.assertEqual(
242            helpers.file_size(StringIO('my sample content')), 17)
243
244class IfaceNamesTestCase(unittest.TestCase):
245
246    def test_iface_names(self):
247        class I1(Interface):
248            foo = Attribute("""Some Foo""")
249            def bar(blah):
250                pass
251            i1_name = schema.TextLine(title=u'i1 name')
252        class I2(I1):
253            baz = schema.TextLine(title=u'some baz')
254
255        result1 = helpers.iface_names(I2)
256        result2 = helpers.iface_names(I1)
257        result3 = helpers.iface_names(I2, exclude_attribs=False)
258        result4 = helpers.iface_names(I2, exclude_methods=False)
259        result5 = helpers.iface_names(I2, omit='i1_name')
260        self.assertEqual(sorted(result1), ['baz', 'i1_name'])
261        self.assertEqual(sorted(result2), ['i1_name'])
262        self.assertEqual(sorted(result3), ['baz', 'foo', 'i1_name'])
263        self.assertEqual(sorted(result4), ['bar', 'baz', 'i1_name'])
264        self.assertEqual(sorted(result5), ['baz'])
265        return
266
267class DateTimeHelpersTestCase(unittest.TestCase):
268
269    def test_now(self):
270        tz_berlin = pytz.timezone('Europe/Berlin')
271        result1 = helpers.now()
272        result2 = helpers.now(tz_berlin)
273        self.assertEqual(result1.tzinfo, pytz.utc)
274        self.assertFalse(result2.tzinfo == pytz.utc)
275        self.assertFalse(result2.tzinfo is None)
276        return
277
278    def test_to_timezone(self):
279        fmt = '%Y-%m-%d %H:%M:%S %Z%z'
280        tz_berlin = pytz.timezone('Europe/Berlin')
281        tz_lagos = pytz.timezone('Africa/Lagos')
282        dt1 = datetime.datetime(2012, 1, 1, 0, 0)
283        dt2 = datetime.datetime(2012, 1, 1, 0, 0, tzinfo=tz_berlin)
284        dt3 = datetime.datetime(2012, 6, 1, 0, 0, tzinfo=tz_lagos)
285        dt4 = datetime.datetime(2012, 6, 1, 0, 0, tzinfo=tz_berlin)
286        result1 = helpers.to_timezone(dt1)
287        result2 = helpers.to_timezone(dt1, pytz.utc)
288        result3 = helpers.to_timezone(dt2)
289        result4 = helpers.to_timezone(dt2, tz_lagos)
290        result5 = helpers.to_timezone(dt3, tz_berlin)
291        result6 = helpers.to_timezone(dt4, tz_lagos)
292        self.assertEqual(
293            result1.strftime(fmt), '2012-01-01 00:00:00 UTC+0000')
294        self.assertEqual(
295            result2.strftime(fmt), '2012-01-01 00:00:00 UTC+0000')
296        self.assertEqual(
297            result3.strftime(fmt), '2011-12-31 23:00:00 UTC+0000')
298        self.assertEqual(
299            result4.strftime(fmt), '2012-01-01 00:00:00 WAT+0100')
300        self.assertEqual(
301            result5.strftime(fmt), '2012-06-01 01:46:00 CEST+0200')
302        self.assertEqual(
303            result6.strftime(fmt), '2012-06-01 00:00:00 WAT+0100')
304        return
305
306
307def test_suite():
308    suite = unittest.TestSuite()
309    # Register local test cases...
310    for testcase in [
311        ReST2HTMLTestCase,
312        FactoryBaseTestCase,
313        CopyFileSystemTreeTestCase,
314        RemoveFileOrDirectoryTestCase,
315        CurrentPrincipalTestCase,
316        CmpFilesTestCase,
317        FileSizeTestCase,
318        IfaceNamesTestCase,
319        DateTimeHelpersTestCase,
320        ]:
321        suite.addTests(
322            unittest.TestLoader().loadTestsFromTestCase(testcase)
323            )
324    # Add tests from docstrings in helpers.py...
325    suite.addTests(
326        doctest.DocTestSuite(
327            helpers,
328            optionflags = doctest.ELLIPSIS + doctest.REPORT_NDIFF,
329            )
330        )
331    return suite
332
333if __name__ == '__main__':
334    unittest.main(defaultTest='test_suite')
Note: See TracBrowser for help on using the repository browser.