Mercurial > p > roundup > code
changeset 6832:234fefd7568a
issue2550559 - Pretty printing / formatting for Number types.
add pretty(format='%0.3f') method to NumberHTMLProperty.
| author | John Rouillard <rouilj@ieee.org> |
|---|---|
| date | Tue, 16 Aug 2022 22:39:04 -0400 |
| parents | e0b29e3fe995 |
| children | da9a78957bd4 |
| files | CHANGES.txt doc/customizing.txt roundup/cgi/templating.py test/test_templating.py |
| diffstat | 4 files changed, 146 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/CHANGES.txt Tue Aug 16 18:31:09 2022 -0400 +++ b/CHANGES.txt Tue Aug 16 22:39:04 2022 -0400 @@ -37,6 +37,10 @@ pip, setting UID tracker is run under. (John Rouillard) - issue2551140 - Added redis as a session and otk database for use with anydbm and sqlite primary databases. (John Rouillard) +- issue2550559 - Pretty printing / formatting for Number types. + Added pretty(format='%0.3f') method to NumberHTMLProperty to + print numeric values. If value is None, return empty string + otherwise str() of value. 2022-07-13 2.2.0
--- a/doc/customizing.txt Tue Aug 16 18:31:09 2022 -0400 +++ b/doc/customizing.txt Tue Aug 16 22:39:04 2022 -0400 @@ -3397,6 +3397,11 @@ format (eg. "yesterday"). The format arguments are those used in the standard ``strftime`` call (see the `Python Library Reference: time module`__) + + Number properties - takes a printf style format argument + (default: '%0.3f') and formats the number accordingly. + If the value can't be converted, '' is returned if the + value is ``None`` otherwise it is converted to a string. popcal Generate a link to a popup calendar which may be used to edit the date field, for example::
--- a/roundup/cgi/templating.py Tue Aug 16 18:31:09 2022 -0400 +++ b/roundup/cgi/templating.py Tue Aug 16 22:39:04 2022 -0400 @@ -1957,6 +1957,21 @@ return str(self._value) + def pretty(self, format="%0.3f"): + '''Pretty print number using printf format specifier. + + If value is not convertable, returns str(_value) or "" + if None. + ''' + try: + return format%self._value + except TypeError: + value = self._value + if value is None: + return '' + else: + return str(value) + def field(self, size=30, **kwargs): """ Render a form edit field for the property.
--- a/test/test_templating.py Tue Aug 16 18:31:09 2022 -0400 +++ b/test/test_templating.py Tue Aug 16 22:39:04 2022 -0400 @@ -305,6 +305,128 @@ self.assertEqual(True, greater_than <= now - timestamp < (greater_than + 1) ) + def test_number__int__(self): + # test with number + p = NumberHTMLProperty(self.client, 'testnum', '1', None, 'test', + 2345678.2345678) + self.assertEqual(p.__int__(), 2345678) + + property = MockNull(get_default_value = lambda: None) + p = NumberHTMLProperty(self.client, 'testnum', '1', property, + 'test', None) + with self.assertRaises(TypeError) as e: + p.__int__() + + def test_number__float__(self): + # test with number + p = NumberHTMLProperty(self.client, 'testnum', '1', None, 'test', + 2345678.2345678) + self.assertEqual(p.__float__(), 2345678.2345678) + + property = MockNull(get_default_value = lambda: None) + p = NumberHTMLProperty(self.client, 'testnum', '1', property, + 'test', None) + with self.assertRaises(TypeError) as e: + p.__float__() + + def test_number_field(self): + import sys + + _py3 = sys.version_info[0] > 2 + + # python2 truncates while python3 rounds. Sigh. + if _py3: + expected_val = 2345678.2345678 + else: + expected_val = 2345678.23457 + + # test with number + p = NumberHTMLProperty(self.client, 'testnum', '1', None, 'test', + 2345678.2345678) + self.assertEqual(p.field(), + ('<input name="testnum1@test" size="30" type="text" ' + 'value="%s">')%expected_val) + self.assertEqual(p.field(size=10), + ('<input name="testnum1@test" size="10" type="text" ' + 'value="%s">')%expected_val) + self.assertEqual(p.field(size=10, dataprop="foo", dataprop2=5), + ('<input dataprop="foo" dataprop2="5" ' + 'name="testnum1@test" size="10" type="text" ' + 'value="%s">'%expected_val)) + + self.assertEqual(p.field(size=10, klass="class1", + **{ "class": "class2 class3", + "data-prop": "foo", + "data-prop2": 5}), + ('<input class="class2 class3" data-prop="foo" ' + 'data-prop2="5" klass="class1" ' + 'name="testnum1@test" size="10" type="text" ' + 'value="%s">')%expected_val) + + # get plain representation if user can't edit + p.is_edit_ok = lambda: False + self.assertEqual(p.field(), p.plain()) + + # test with string which is wrong type + p = NumberHTMLProperty(self.client, 'testnum', '1', None, 'test', + "2345678.2345678") + self.assertEqual(p.field(), + ('<input name="testnum1@test" size="30" type="text" ' + 'value="2345678.2345678">')) + + # test with None value, pretend property.__default_value = Null which + # is the default. It would be returned by get_default_value + # which I mock. + property = MockNull(get_default_value = lambda: None) + p = NumberHTMLProperty(self.client, 'testnum', '1', property, + 'test', None) + self.assertEqual(p.field(), + ('<input name="testnum1@test" size="30" type="text" ' + 'value="">')) + + def test_number_plain(self): + import sys + + _py3 = sys.version_info[0] > 2 + + # python2 truncates while python3 rounds. Sigh. + if _py3: + expected_val = 2345678.2345678 + else: + expected_val = 2345678.23457 + + p = NumberHTMLProperty(self.client, 'testnum', '1', None, 'test', + 2345678.2345678) + + self.assertEqual(p.plain(), "%s"%expected_val) + + def test_number_pretty(self): + # test with number + p = NumberHTMLProperty(self.client, 'testnum', '1', None, 'test', + 2345678.2345678) + self.assertEqual(p.pretty(), "2345678.235") + + # test with string which is wrong type + p = NumberHTMLProperty(self.client, 'testnum', '1', None, 'test', + "2345678.2345678") + self.assertEqual(p.pretty(), "2345678.2345678") + + # test with boolean + p = NumberHTMLProperty(self.client, 'testnum', '1', None, 'test', + True) + self.assertEqual(p.pretty(), "1.000") + + # test with None value, pretend property.__default_value = Null which + # is the default. It would be returned by get_default_value + # which I mock. + property = MockNull(get_default_value = lambda: None) + p = NumberHTMLProperty(self.client, 'testnum', '1', property, + 'test', None) + self.assertEqual(p.pretty(), '') + + with self.assertRaises(ValueError) as e: + p.pretty('%0.3') + def test_string_url_quote(self): ''' test that urlquote quotes the string ''' p = StringHTMLProperty(self.client, 'test', '1', None, 'test', 'test string< foo@bar')
