source: main/waeup.sirp/trunk/src/waeup/sirp/utils/tests/test_converters.py @ 6266

Last change on this file since 6266 was 6266, checked in by uli, 13 years ago

Show that the converter can create new instances when given a factory
name, this way really turning a set of strings into new objects as we
expect it from an importer in 'create' mode.

File size: 9.2 KB
Line 
1##
2## test_converters.py
3## Login : <uli@pu.smp.net>
4## Started on  Tue May 31 08:34:44 2011 Uli Fouquet
5## $Id$
6##
7## Copyright (C) 2011 Uli Fouquet
8## This program is free software; you can redistribute it and/or modify
9## it under the terms of the GNU General Public License as published by
10## the Free Software Foundation; either version 2 of the License, or
11## (at your option) any later version.
12##
13## This program is distributed in the hope that it will be useful,
14## but WITHOUT ANY WARRANTY; without even the implied warranty of
15## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16## GNU General Public License for more details.
17##
18## You should have received a copy of the GNU General Public License
19## along with this program; if not, write to the Free Software
20## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21##
22"""
23Tests for converterts.
24"""
25import datetime
26import os
27import shutil
28import tempfile
29import unittest
30from zope import schema
31from zope.app.testing.functional import FunctionalTestCase
32from zope.component import provideUtility
33from zope.component.factory import Factory
34from zope.component.hooks import setSite, clearSite
35from zope.component.interfaces import IFactory
36from zope.formlib import form
37from zope.interface import (
38    Interface, implements, invariant, Invalid, implementedBy)
39from zope.interface.verify import verifyClass, verifyObject
40
41from waeup.sirp.app import University
42from waeup.sirp.testing import FunctionalLayer, doctestsuite_for_module
43from waeup.sirp.utils.converters import IObjectConverter
44from waeup.sirp.utils.helpers import attrs_to_fields
45
46class IContact(Interface):
47    """Sample interface for sample content type used here in tests.
48    """
49    name = schema.TextLine(
50        title = u'Name',
51        default = u'Manfred'
52        )
53    age = schema.Int(
54        title = u'Age',
55        default = 23,
56        required = True,
57        )
58    city = schema.TextLine(
59        title = u'City',
60        required = True,
61        )
62    vip = schema.Bool(
63        title = u'Celebrity',
64        default = False,
65        required = True,
66        )
67    birthday = schema.Date(
68        title = u'Birthday',
69        default = None,
70        )
71    @invariant
72    def kevinIsYoung(contact):
73        if contact.age > 16 and contact.name == 'Kevin':
74            raise Invalid('Kevins are age 16 or below.')
75
76class Contact(object):
77    """Sample content type.
78    """
79    implements(IContact)
80Contact = attrs_to_fields(Contact)
81
82form_fields_select = form.Fields(IContact).select('name', 'vip')
83form_fields_omit = form.Fields(IContact).omit('name', 'vip')
84
85class ContactFactory(object):
86    """A factory for faculty containers.
87    """
88    implements(IContact)
89
90    def __call__(self, *args, **kw):
91        return Faculty()
92
93    def getInterfaces(self):
94        return implementedBy(Faculty)
95
96class ConverterTests(FunctionalTestCase):
97
98    layer = FunctionalLayer
99
100    def setUp(self):
101        super(ConverterTests, self).setUp()
102
103        # Setup a sample site for each test
104        app = University()
105        self.dc_root = tempfile.mkdtemp()
106        app['datacenter'].setStoragePath(self.dc_root)
107
108        # Prepopulate the ZODB...
109        self.getRootFolder()['app'] = app
110        self.app = self.getRootFolder()['app']
111
112        self.workdir = tempfile.mkdtemp()
113
114        # Create a factory for contacts and register it as global utility
115        factory = Factory(Contact)
116        provideUtility(factory, IFactory, 'contact')
117        return
118
119    def tearDown(self):
120        super(ConverterTests, self).tearDown()
121        shutil.rmtree(self.workdir)
122        shutil.rmtree(self.dc_root)
123        clearSite()
124        return
125
126    def test_valid_data(self):
127        contact = Contact()
128        contact.age = 33
129        input_data = dict(name='Rudi', age='99')
130        converter = IObjectConverter(IContact) # a converter to IContact
131        err, inv_err, new_contact = converter.applyRowData(
132            input_data, contact)
133        assert new_contact is contact
134        assert contact.name == 'Rudi'
135        assert contact.age == 99
136        return
137
138    def test_bool(self):
139        contact1 = Contact()
140        contact2 = Contact()
141        input_data1 = dict(vip='on')
142        input_data2 = dict(vip='')
143        converter = IObjectConverter(IContact) # a converter to IContact
144        err1, inv_err1, new_contact1 = converter.applyRowData(
145            input_data1, contact1)
146        err2, inv_err2, new_contact2 = converter.applyRowData(
147            input_data2, contact2)
148        assert contact1.vip is True
149        assert contact2.vip is False
150
151    def test_int(self):
152        contact = Contact()
153        input_data = dict(age='99')
154        converter = IObjectConverter(IContact) # a converter to IContact
155        err, inv_err, new_contact = converter.applyRowData(
156            input_data, contact)
157        assert contact.age == 99
158        return
159
160    def test_int_invalid(self):
161        contact = Contact()
162        input_data = dict(age='sweet sixteen')
163        converter = IObjectConverter(IContact) # a converter to IContact
164        err, inv_err, new_contact = converter.applyRowData(
165            input_data, contact)
166        self.assertEqual(err, [('age', u'Invalid integer data')])
167        return
168
169    def test_textline(self):
170        contact = Contact()
171        input_data = dict(name='Rudi')
172        converter = IObjectConverter(IContact) # a converter to IContact
173        err, inv_err, new_contact = converter.applyRowData(
174            input_data, contact)
175        self.assertEqual(contact.name, u'Rudi')
176        assert isinstance(contact.name, unicode)
177        return
178
179    def test_invariant(self):
180        contact = Contact()
181        input_data = dict(name='Kevin', age='22')
182        converter = IObjectConverter(IContact) # a converter to IContact
183        err, inv_err, new_contact = converter.applyRowData(
184            input_data, contact)
185        self.assertEqual(inv_err, ['Kevins are age 16 or below.'])
186        return
187
188    def test_date(self):
189        contact = Contact()
190        converter = IObjectConverter(IContact) # a converter to IContact
191        err, inv_err, new_contact = converter.applyRowData(
192            dict(birthday='1945/12/23'), contact)
193        assert contact.birthday == datetime.date(1945, 12, 23)
194        assert isinstance(contact.birthday, datetime.date)
195
196        err, inv_err, new_contact = converter.applyRowData(
197            dict(birthday='1945/23/12'), contact)
198        assert contact.birthday == datetime.date(1945, 12, 23)
199
200        err, inv_err, new_contact = converter.applyRowData(
201            dict(birthday='23/12/1945'), contact)
202        assert contact.birthday == datetime.date(1945, 12, 23)
203
204        err, inv_err, new_contact = converter.applyRowData(
205            dict(birthday='23.12.1945'), contact)
206        assert contact.birthday == datetime.date(1945, 12, 23)
207
208        err, inv_err, new_contact = converter.applyRowData(
209            dict(birthday='23-12-1945'), contact)
210        assert contact.birthday == datetime.date(1945, 12, 23)
211        return
212
213    def test_date_invalid(self):
214        contact = Contact()
215        converter = IObjectConverter(IContact) # a converter to IContact
216        err, inv_err, new_contact = converter.applyRowData(
217            dict(birthday='not-a-date'), contact)
218        self.assertEqual(err, [('birthday', u'Invalid datetime data')])
219
220    def test_inject_formfields_select(self):
221        # We can use our own formfields and select only a subset of fields
222        contact = Contact()
223        converter = IObjectConverter(IContact) # a converter to IContact
224        input_data = dict(name='Bruno', age='99', vip='on')
225        err, inv_err, new_contact = converter.applyRowData(
226            input_data, contact, form_fields=form_fields_select)
227        self.assertEqual(contact.name, 'Bruno')
228        self.assertEqual(contact.age, 23)
229        self.assertEqual(contact.vip, True)
230        return
231
232    def test_inject_formfields_omit(self):
233        # We can use our own formfields and omit some fields
234        contact = Contact()
235        converter = IObjectConverter(IContact) # a converter to IContact
236        input_data = dict(name='Bruno', age='99', vip='on')
237        err, inv_err, new_contact = converter.applyRowData(
238            input_data, contact, form_fields=form_fields_omit)
239        self.assertEqual(contact.name, 'Manfred')
240        self.assertEqual(contact.age, 99)
241        self.assertEqual(contact.vip, False)
242        return
243
244    def test_factory(self):
245        # We can use factories to create a new object
246        #
247        # This way we turn a dict of strings and some string denoting
248        # the kind of object to be created (factory name) into a real object.
249        converter = IObjectConverter(IContact) # a converter to IContact
250        # pass string ``contact`` instead of a real object
251        err, inv_err, contact = converter.applyRowData(
252            dict(name='Gabi'), 'contact')
253        # we get an object...
254        assert isinstance(contact, Contact)
255        # ...with the values from the dict set.
256        self.assertEqual(contact.name, 'Gabi')
257        return
258
259def test_suite():
260    suite = unittest.TestSuite()
261    for testcase in [
262        ConverterTests,
263        ]:
264        suite.addTest(unittest.TestLoader().loadTestsFromTestCase(
265                testcase
266                )
267        )
268    return suite
269
Note: See TracBrowser for help on using the repository browser.