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

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

Test converter with vocabs with non-string values.

File size: 10.7 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
45from waeup.sirp.interfaces import SimpleWAeUPVocabulary
46
47colors = SimpleWAeUPVocabulary(
48    ('Red', u'red'),
49    ('Green', u'green'),
50    ('Blue', u'blue'),
51    )
52car_nums = SimpleWAeUPVocabulary(
53    ('None', 0),
54    ('One', 1),
55    ('Two', 2),
56    ('Three', 3),
57    )
58class IContact(Interface):
59    """Sample interface for sample content type used here in tests.
60    """
61    name = schema.TextLine(
62        title = u'Name',
63        default = u'Manfred'
64        )
65    age = schema.Int(
66        title = u'Age',
67        default = 23,
68        required = True,
69        )
70    city = schema.TextLine(
71        title = u'City',
72        required = True,
73        )
74    vip = schema.Bool(
75        title = u'Celebrity',
76        default = False,
77        required = True,
78        )
79    birthday = schema.Date(
80        title = u'Birthday',
81        default = None,
82        )
83    fav_color = schema.Choice(
84        title = u'Favourite color',
85        default = u'red',
86        vocabulary = colors,
87        )
88    num_cars = schema.Choice(
89        title = u'Number of cars owned',
90        default = None,
91        vocabulary = car_nums,
92        )
93    @invariant
94    def kevinIsYoung(contact):
95        if contact.age > 16 and contact.name == 'Kevin':
96            raise Invalid('Kevins are age 16 or below.')
97
98class Contact(object):
99    """Sample content type.
100    """
101    implements(IContact)
102Contact = attrs_to_fields(Contact)
103
104form_fields_select = form.Fields(IContact).select('name', 'vip')
105form_fields_omit = form.Fields(IContact).omit('name', 'vip')
106
107class ContactFactory(object):
108    """A factory for faculty containers.
109    """
110    implements(IContact)
111
112    def __call__(self, *args, **kw):
113        return Faculty()
114
115    def getInterfaces(self):
116        return implementedBy(Faculty)
117
118class ConverterTests(FunctionalTestCase):
119
120    layer = FunctionalLayer
121
122    def setUp(self):
123        super(ConverterTests, self).setUp()
124
125        # Setup a sample site for each test
126        app = University()
127        self.dc_root = tempfile.mkdtemp()
128        app['datacenter'].setStoragePath(self.dc_root)
129
130        # Prepopulate the ZODB...
131        self.getRootFolder()['app'] = app
132        self.app = self.getRootFolder()['app']
133
134        self.workdir = tempfile.mkdtemp()
135
136        # Create a factory for contacts and register it as global utility
137        factory = Factory(Contact)
138        provideUtility(factory, IFactory, 'contact')
139        return
140
141    def tearDown(self):
142        super(ConverterTests, self).tearDown()
143        shutil.rmtree(self.workdir)
144        shutil.rmtree(self.dc_root)
145        clearSite()
146        return
147
148    def test_valid_data(self):
149        contact = Contact()
150        contact.age = 33
151        input_data = dict(name='Rudi', age='99')
152        converter = IObjectConverter(IContact) # a converter to IContact
153        err, inv_err, new_contact = converter.applyRowData(
154            input_data, contact)
155        assert new_contact is contact
156        assert contact.name == 'Rudi'
157        assert contact.age == 99
158        return
159
160    def test_bool(self):
161        contact1 = Contact()
162        contact2 = Contact()
163        input_data1 = dict(vip='on')
164        input_data2 = dict(vip='')
165        converter = IObjectConverter(IContact) # a converter to IContact
166        err1, inv_err1, new_contact1 = converter.applyRowData(
167            input_data1, contact1)
168        err2, inv_err2, new_contact2 = converter.applyRowData(
169            input_data2, contact2)
170        assert contact1.vip is True
171        assert contact2.vip is False
172
173    def test_int(self):
174        contact = Contact()
175        input_data = dict(age='99')
176        converter = IObjectConverter(IContact) # a converter to IContact
177        err, inv_err, new_contact = converter.applyRowData(
178            input_data, contact)
179        assert contact.age == 99
180        return
181
182    def test_int_invalid(self):
183        contact = Contact()
184        input_data = dict(age='sweet sixteen')
185        converter = IObjectConverter(IContact) # a converter to IContact
186        err, inv_err, new_contact = converter.applyRowData(
187            input_data, contact)
188        self.assertEqual(err, [('age', u'Invalid integer data')])
189        return
190
191    def test_textline(self):
192        contact = Contact()
193        input_data = dict(name='Rudi')
194        converter = IObjectConverter(IContact) # a converter to IContact
195        err, inv_err, new_contact = converter.applyRowData(
196            input_data, contact)
197        self.assertEqual(contact.name, u'Rudi')
198        assert isinstance(contact.name, unicode)
199        return
200
201    def test_invariant(self):
202        contact = Contact()
203        input_data = dict(name='Kevin', age='22')
204        converter = IObjectConverter(IContact) # a converter to IContact
205        err, inv_err, new_contact = converter.applyRowData(
206            input_data, contact)
207        self.assertEqual(inv_err, ['Kevins are age 16 or below.'])
208        return
209
210    def test_date(self):
211        contact = Contact()
212        converter = IObjectConverter(IContact) # a converter to IContact
213        err, inv_err, new_contact = converter.applyRowData(
214            dict(birthday='1945/12/23'), contact)
215        assert contact.birthday == datetime.date(1945, 12, 23)
216        assert isinstance(contact.birthday, datetime.date)
217
218        err, inv_err, new_contact = converter.applyRowData(
219            dict(birthday='1945/23/12'), contact)
220        assert contact.birthday == datetime.date(1945, 12, 23)
221
222        err, inv_err, new_contact = converter.applyRowData(
223            dict(birthday='23/12/1945'), contact)
224        assert contact.birthday == datetime.date(1945, 12, 23)
225
226        err, inv_err, new_contact = converter.applyRowData(
227            dict(birthday='23.12.1945'), contact)
228        assert contact.birthday == datetime.date(1945, 12, 23)
229
230        err, inv_err, new_contact = converter.applyRowData(
231            dict(birthday='23-12-1945'), contact)
232        assert contact.birthday == datetime.date(1945, 12, 23)
233        return
234
235    def test_date_invalid(self):
236        contact = Contact()
237        converter = IObjectConverter(IContact) # a converter to IContact
238        err, inv_err, new_contact = converter.applyRowData(
239            dict(birthday='not-a-date'), contact)
240        self.assertEqual(err, [('birthday', u'Invalid datetime data')])
241
242    def test_inject_formfields_select(self):
243        # We can use our own formfields and select only a subset of fields
244        contact = Contact()
245        converter = IObjectConverter(IContact) # a converter to IContact
246        input_data = dict(name='Bruno', age='99', vip='on')
247        err, inv_err, new_contact = converter.applyRowData(
248            input_data, contact, form_fields=form_fields_select)
249        self.assertEqual(contact.name, 'Bruno')
250        self.assertEqual(contact.age, 23)
251        self.assertEqual(contact.vip, True)
252        return
253
254    def test_inject_formfields_omit(self):
255        # We can use our own formfields and omit some fields
256        contact = Contact()
257        converter = IObjectConverter(IContact) # a converter to IContact
258        input_data = dict(name='Bruno', age='99', vip='on')
259        err, inv_err, new_contact = converter.applyRowData(
260            input_data, contact, form_fields=form_fields_omit)
261        self.assertEqual(contact.name, 'Manfred')
262        self.assertEqual(contact.age, 99)
263        self.assertEqual(contact.vip, False)
264        return
265
266    def test_factory(self):
267        # We can use factories to create a new object
268        #
269        # This way we turn a dict of strings and some string denoting
270        # the kind of object to be created (factory name) into a real object.
271        converter = IObjectConverter(IContact) # a converter to IContact
272        # pass string ``contact`` instead of a real object
273        err, inv_err, contact = converter.applyRowData(
274            dict(name='Gabi'), 'contact')
275        # we get an object...
276        assert isinstance(contact, Contact)
277        # ...with the values from the dict set.
278        self.assertEqual(contact.name, 'Gabi')
279        return
280
281    def test_choice_vocab(self):
282        # We can handle vocabularies
283        converter = IObjectConverter(IContact) # a converter to IContact
284        err, inv_err, contact = converter.applyRowData(
285            dict(fav_color='blue'), 'contact')
286        assert contact.fav_color == u'blue'
287        assert isinstance(contact.fav_color, unicode)
288        return
289
290    def test_choice_vocab_invalid_value(self):
291        # We can handle vocabularies
292        converter = IObjectConverter(IContact) # a converter to IContact
293        err, inv_err, contact = converter.applyRowData(
294            dict(fav_color='magenta'), 'contact')
295        self.assertEqual(err, [('fav_color', u'Invalid value')])
296        assert contact.fav_color == u'red'
297        return
298
299    def test_non_string_choice(self):
300        # We can handle vocabs with non-string values
301        converter = IObjectConverter(IContact) # a converter to IContact
302        err, inv_err, contact = converter.applyRowData(
303            dict(num_cars='1'), 'contact')
304        assert contact.num_cars == 1
305        return
306
307def test_suite():
308    suite = unittest.TestSuite()
309    for testcase in [
310        ConverterTests,
311        ]:
312        suite.addTest(unittest.TestLoader().loadTestsFromTestCase(
313                testcase
314                )
315        )
316    return suite
317
Note: See TracBrowser for help on using the repository browser.