From: richard Date: Tue, 22 Jan 2002 00:12:07 +0000 (+0000) Subject: Wrote more unit tests for htmltemplate, and while I was at it, I polished X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=bf62bec99541dec1be5c65192a5f8e9c5f02e39c;p=roundup.git Wrote more unit tests for htmltemplate, and while I was at it, I polished off the implementation of some of the functions so they behave sanely. git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/trunk@575 57a73879-2fb5-44c3-a270-3262357dd7e2 --- diff --git a/CHANGES.txt b/CHANGES.txt index 10091cf..8e66a26 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -12,6 +12,8 @@ Feature: . modified unit test to check nosy and assignedto when specified as arguments . you can now use the roundup-admin tool pack the database + . unit tests for html templating (and re-enabled the listbox field for + multilinks) Fixed: . handle attachments with no name (eg tnef) diff --git a/roundup/htmltemplate.py b/roundup/htmltemplate.py index e029d42..6c59c94 100644 --- a/roundup/htmltemplate.py +++ b/roundup/htmltemplate.py @@ -15,7 +15,7 @@ # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. # -# $Id: htmltemplate.py,v 1.64 2002-01-21 03:25:59 richard Exp $ +# $Id: htmltemplate.py,v 1.65 2002-01-22 00:12:06 richard Exp $ __doc__ = """ Template engine. @@ -109,43 +109,61 @@ class TemplateFunctions: return s return StructuredText(s,level=1,header=0) - def do_field(self, property, size=None, height=None, showid=0): - ''' display a property like the plain displayer, but in a text field - to be edited + def determine_value(self, property): + '''determine the value of a property using the node, form or + filterspec ''' - if not self.nodeid and self.form is None and self.filterspec is None: - return _('[Field: not called from item]') propclass = self.properties[property] - if (isinstance(propclass, hyperdb.Link) or - isinstance(propclass, hyperdb.Multilink)): - linkcl = self.db.classes[propclass.classname] - def sortfunc(a, b, cl=linkcl): - if cl.getprops().has_key('order'): - sort_on = 'order' - else: - sort_on = cl.labelprop() - r = cmp(cl.get(a, sort_on), cl.get(b, sort_on)) - return r if self.nodeid: value = self.cl.get(self.nodeid, property, None) - # TODO: remove this from the code ... it's only here for - # handling schema changes, and they should be handled outside - # of this code... if isinstance(propclass, hyperdb.Multilink) and value is None: - value = [] + return [] + return value elif self.filterspec is not None: if isinstance(propclass, hyperdb.Multilink): - value = self.filterspec.get(property, []) + return self.filterspec.get(property, []) else: - value = self.filterspec.get(property, '') + return self.filterspec.get(property, '') + # TODO: pull the value from the form + if isinstance(propclass, hyperdb.Multilink): + return [] else: - # TODO: pull the value from the form - if isinstance(propclass, hyperdb.Multilink): value = [] - else: value = '' + return '' + + def make_sort_function(self, classname): + '''Make a sort function for a given class + ''' + linkcl = self.db.classes[classname] + if linkcl.getprops().has_key('order'): + sort_on = 'order' + else: + sort_on = linkcl.labelprop() + def sortfunc(a, b, linkcl=linkcl, sort_on=sort_on): + return cmp(linkcl.get(a, sort_on), linkcl.get(b, sort_on)) + return sortfunc + + def do_field(self, property, size=None, showid=0): + ''' display a property like the plain displayer, but in a text field + to be edited + + Note: if you would prefer an option list style display for + link or multilink editing, use menu(). + ''' + if not self.nodeid and self.form is None and self.filterspec is None: + return _('[Field: not called from item]') + + if size is None: + size = 30 + + propclass = self.properties[property] + + # get the value + value = self.determine_value(property) + + # now display if (isinstance(propclass, hyperdb.String) or isinstance(propclass, hyperdb.Date) or isinstance(propclass, hyperdb.Interval)): - size = size or 30 if value is None: value = '' else: @@ -153,9 +171,13 @@ class TemplateFunctions: value = '"'.join(value.split('"')) s = ''%(property, value, size) elif isinstance(propclass, hyperdb.Password): - size = size or 30 s = ''%(property, size) elif isinstance(propclass, hyperdb.Link): + sortfunc = self.make_sort_function(propclass.classname) + linkcl = self.db.classes[propclass.classname] + options = linkcl.list() + options.sort(sortfunc) + # TODO: make this a field display, not a menu one! l = ['') s = '\n'.join(l) elif isinstance(propclass, hyperdb.Multilink): + sortfunc = self.make_sort_function(propclass.classname) + linkcl = self.db.classes[propclass.classname] list = linkcl.list() list.sort(sortfunc) l = [] # map the id to the label property - # TODO: allow reversion to the older '%(property, - size, ','.join(value))) - s = "
\n".join(l) + value = cgi.escape(','.join(value)) + s = ''%(property, size, value) else: s = _('Plain: bad propclass "%(propclass)s"')%locals() return s @@ -200,13 +219,23 @@ class TemplateFunctions: def do_menu(self, property, size=None, height=None, showid=0): ''' for a Link property, display a menu of the available choices ''' + if not self.nodeid and self.form is None and self.filterspec is None: + return _('[Field: not called from item]') + propclass = self.properties[property] - if self.nodeid: - value = self.cl.get(self.nodeid, property) - else: - # TODO: pull the value from the form - if isinstance(propclass, hyperdb.Multilink): value = [] - else: value = None + + # make sure this is a link property + if not (isinstance(propclass, hyperdb.Link) or + isinstance(propclass, hyperdb.Multilink)): + return _('[Menu: not a link]') + + # sort function + sortfunc = self.make_sort_function(propclass.classname) + + # get the value + value = self.determine_value(property) + + # display if isinstance(propclass, hyperdb.Link): linkcl = self.db.classes[propclass.classname] l = ['') return '\n'.join(l) if isinstance(propclass, hyperdb.Multilink): linkcl = self.db.classes[propclass.classname] - list = linkcl.list() - height = height or min(len(list), 7) + options = linkcl.list() + options.sort(sortfunc) + height = height or min(len(options), 7) l = ['') return '\n'.join(l) return _('[Menu: not a link]') @@ -1002,6 +1043,9 @@ class NewItemTemplate(TemplateFunctions): # # $Log: not supported by cvs2svn $ +# Revision 1.64 2002/01/21 03:25:59 richard +# oops +# # Revision 1.63 2002/01/21 02:59:10 richard # Fixed up the HTML display of history so valid links are actually displayed. # Oh for some unit tests! :( diff --git a/test/__init__.py b/test/__init__.py index 7501f98..f3cf566 100644 --- a/test/__init__.py +++ b/test/__init__.py @@ -15,7 +15,7 @@ # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. # -# $Id: __init__.py,v 1.13 2002-01-21 11:05:48 richard Exp $ +# $Id: __init__.py,v 1.14 2002-01-22 00:12:06 richard Exp $ import unittest import os, tempfile @@ -26,14 +26,14 @@ import test_init, test_token, test_mailgw, test_htmltemplate def go(): suite = unittest.TestSuite(( - test_dates.suite(), - test_schema.suite(), - test_db.suite(), - test_init.suite(), - test_multipart.suite(), - test_mailsplit.suite(), - test_mailgw.suite(), - test_token.suite(), +# test_dates.suite(), +# test_schema.suite(), +# test_db.suite(), +# test_init.suite(), +# test_multipart.suite(), +# test_mailsplit.suite(), +# test_mailgw.suite(), +# test_token.suite(), test_htmltemplate.suite(), )) runner = unittest.TextTestRunner() @@ -42,6 +42,9 @@ def go(): # # $Log: not supported by cvs2svn $ +# Revision 1.13 2002/01/21 11:05:48 richard +# New tests for htmltemplate (well, it's a beginning) +# # Revision 1.12 2002/01/14 06:53:28 richard # had commented out some tests # diff --git a/test/test_htmltemplate.py b/test/test_htmltemplate.py index 3765aca..3c7143b 100644 --- a/test/test_htmltemplate.py +++ b/test/test_htmltemplate.py @@ -8,13 +8,14 @@ # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # -# $Id: test_htmltemplate.py,v 1.1 2002-01-21 11:05:48 richard Exp $ +# $Id: test_htmltemplate.py,v 1.2 2002-01-22 00:12:07 richard Exp $ import unittest, cgi from roundup.htmltemplate import TemplateFunctions from roundup import date -from roundup.hyperdb import String, Date, Interval, Link, Multilink +from roundup import password +from roundup.hyperdb import String, Password, Date, Interval, Link, Multilink class Class: def get(self, nodeid, attribute, default=None): @@ -28,6 +29,8 @@ class Class: return '1' elif attribute == 'multilink': return ['1', '2'] + elif attribute == 'password': + return password.Password('sekrit') elif attribute == 'key': return 'the key' elif attribute == 'html': @@ -37,7 +40,7 @@ class Class: def getprops(self): return {'string': String(), 'date': Date(), 'interval': Interval(), 'link': Link('other'), 'multilink': Multilink('other'), - 'html': String(), 'key': String()} + 'password': Password(), 'html': String(), 'key': String()} def labelprop(self): return 'key' @@ -63,6 +66,9 @@ class NodeCase(unittest.TestCase): s = 'Node 1: I am a string' self.assertEqual(self.tf.do_plain('string'), s) + def testPlain_password(self): + self.assertEqual(self.tf.do_plain('password'), '*encrypted*') + def testPlain_html(self): s = 'hello, I am HTML' self.assertEqual(self.tf.do_plain('html', escape=0), s) @@ -82,22 +88,37 @@ class NodeCase(unittest.TestCase): self.assertEqual(self.tf.do_plain('multilink'), '1, 2') -# def do_field(self, property, size=None, height=None, showid=0): +# def do_field(self, property, size=None, showid=0): def testField_string(self): self.assertEqual(self.tf.do_field('string'), '') + self.assertEqual(self.tf.do_field('string', size=10), + '') + + def testField_password(self): + self.assertEqual(self.tf.do_field('password'), + '') + self.assertEqual(self.tf.do_field('password', size=10), + '') def testField_html(self): self.assertEqual(self.tf.do_field('html'), '') + self.assertEqual(self.tf.do_field('html', size=10), + '') def testField_date(self): self.assertEqual(self.tf.do_field('date'), '') + self.assertEqual(self.tf.do_field('date', size=10), + '') def testField_interval(self): self.assertEqual(self.tf.do_field('interval'), '') + self.assertEqual(self.tf.do_field('interval', size=10), + '') def testField_link(self): self.assertEqual(self.tf.do_field('link'), '''') + self.assertEqual(self.tf.do_field('multilink', size=10), '') +# def do_menu(self, property, size=None, height=None, showid=0): + def testMenu_link(self): + self.assertEqual(self.tf.do_menu('link'), '''''') + self.assertEqual(self.tf.do_menu('link', size=6), + '''''') + self.assertEqual(self.tf.do_menu('link', showid=1), + '''''') + + def testMenu_multilink(self): + self.assertEqual(self.tf.do_menu('multilink', height=10), + '''''') + self.assertEqual(self.tf.do_menu('multilink', size=6, height=10), + '''''') + self.assertEqual(self.tf.do_menu('multilink', showid=1), + '''''') + def suite(): return unittest.makeSuite(NodeCase, 'test') # # $Log: not supported by cvs2svn $ +# Revision 1.1 2002/01/21 11:05:48 richard +# New tests for htmltemplate (well, it's a beginning) +# # # # vim: set filetype=python ts=4 sw=4 et si