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

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

More usage of logger-aware testing components.
Remove unnecessary imports/testsuite registrations.

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