From 9c1bfee97fac2bd3cb4f5d939106d6c3bdfc5f62 Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Sat, 28 Dec 2024 20:10:37 -0600 Subject: [PATCH 1/2] fix: add simple rendering logic for currency values and errors --- src/wuttjamaican/app.py | 34 +++++++++++++++++++++++++++++++- src/wuttjamaican/util.py | 19 ++++++++++++++++++ tests/test_app.py | 42 ++++++++++++++++++++++++++++++++++++++++ tests/test_util.py | 17 ++++++++++++++++ 4 files changed, 111 insertions(+), 1 deletion(-) diff --git a/src/wuttjamaican/app.py b/src/wuttjamaican/app.py index a6ea9b3..69ba3a9 100644 --- a/src/wuttjamaican/app.py +++ b/src/wuttjamaican/app.py @@ -34,7 +34,7 @@ import humanize from wuttjamaican.util import (load_entry_points, load_object, make_title, make_uuid, make_true_uuid, - progress_loop, resource_path) + progress_loop, resource_path, simple_error) class AppHandler: @@ -676,6 +676,28 @@ class AppHandler: # common value renderers ############################## + def render_currency(self, value, scale=2, **kwargs): + """ + Return a human-friendly display string for the given currency + value, e.g. ``Decimal('4.20')`` becomes ``"$4.20"``. + + :param value: Either a :class:`python:decimal.Decimal` or + :class:`python:float` value. + + :param scale: Number of decimal digits to be displayed. + + :returns: Display string for the value. + """ + if value is None: + return '' + + if value < 0: + fmt = f"(${{:0,.{scale}f}})" + return fmt.format(0 - value) + + fmt = f"${{:0,.{scale}f}}" + return fmt.format(value) + display_format_date = '%Y-%m-%d' """ Format string to use when displaying :class:`python:datetime.date` @@ -717,6 +739,16 @@ class AppHandler: if value is not None: return value.strftime(self.display_format_datetime) + def render_error(self, error): + """ + Return a "human-friendly" display string for the error, e.g. + when showing it to the user. + + By default, this is a convenience wrapper for + :func:`~wuttjamaican.util.simple_error()`. + """ + return simple_error(error) + def render_time_ago(self, value): """ Return a human-friendly string, indicating how long ago diff --git a/src/wuttjamaican/util.py b/src/wuttjamaican/util.py index 5574020..dfb9b13 100644 --- a/src/wuttjamaican/util.py +++ b/src/wuttjamaican/util.py @@ -338,3 +338,22 @@ def resource_path(path): return str(path) return path + + +def simple_error(error): + """ + Return a "simple" string for the given error. Result will look + like:: + + "ErrorClass: Description for the error" + + However the logic checks to ensure the error has a descriptive + message first; if it doesn't the result will just be:: + + "ErrorClass" + """ + cls = type(error).__name__ + msg = str(error) + if msg: + return f"{cls}: {msg}" + return cls diff --git a/tests/test_app.py b/tests/test_app.py index 71a4066..7168164 100644 --- a/tests/test_app.py +++ b/tests/test_app.py @@ -1,6 +1,7 @@ # -*- coding: utf-8; -*- import datetime +import decimal import os import shutil import sys @@ -422,6 +423,31 @@ app_title = WuttaTest session = self.app.get_session(user) self.assertIs(session, mysession) + def test_render_currency(self): + + # null + self.assertEqual(self.app.render_currency(None), '') + + # basic decimal example + value = decimal.Decimal('42.00') + self.assertEqual(self.app.render_currency(value), '$42.00') + + # basic float example + value = 42.00 + self.assertEqual(self.app.render_currency(value), '$42.00') + + # decimal places will be rounded + value = decimal.Decimal('42.12345') + self.assertEqual(self.app.render_currency(value), '$42.12') + + # but we can declare the scale + value = decimal.Decimal('42.12345') + self.assertEqual(self.app.render_currency(value, scale=4), '$42.1234') + + # negative numbers get parens + value = decimal.Decimal('-42.42') + self.assertEqual(self.app.render_currency(value), '($42.42)') + def test_render_date(self): self.assertIsNone(self.app.render_date(None)) @@ -434,6 +460,22 @@ app_title = WuttaTest dt = datetime.datetime(2024, 12, 11, 8, 30, tzinfo=datetime.timezone.utc) self.assertEqual(self.app.render_datetime(dt), '2024-12-11 08:30+0000') + def test_simple_error(self): + + # with description + try: + raise RuntimeError("just testin") + except Exception as error: + result = self.app.render_error(error) + self.assertEqual(result, "RuntimeError: just testin") + + # without description + try: + raise RuntimeError + except Exception as error: + result = self.app.render_error(error) + self.assertEqual(result, "RuntimeError") + def test_render_time_ago(self): with patch.object(mod, 'humanize') as humanize: humanize.naturaltime.return_value = 'now' diff --git a/tests/test_util.py b/tests/test_util.py index 3d350cd..8015ff0 100644 --- a/tests/test_util.py +++ b/tests/test_util.py @@ -317,3 +317,20 @@ class TestResourcePath(TestCase): # absolute path returned as-is self.assertEqual(mod.resource_path('/tmp/doesnotexist.txt'), '/tmp/doesnotexist.txt') + + +class TestSimpleError(TestCase): + + def test_with_description(self): + try: + raise RuntimeError("just testin") + except Exception as error: + result = mod.simple_error(error) + self.assertEqual(result, "RuntimeError: just testin") + + def test_without_description(self): + try: + raise RuntimeError + except Exception as error: + result = mod.simple_error(error) + self.assertEqual(result, "RuntimeError") From a68df98297b037d2a34cdf7ccd479244c5b65680 Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Sat, 28 Dec 2024 21:13:22 -0600 Subject: [PATCH 2/2] =?UTF-8?q?bump:=20version=200.19.0=20=E2=86=92=200.19?= =?UTF-8?q?.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 6 ++++++ pyproject.toml | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c52586c..1a39299 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to WuttJamaican will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## v0.19.1 (2024-12-28) + +### Fix + +- add simple rendering logic for currency values and errors + ## v0.19.0 (2024-12-23) ### Feat diff --git a/pyproject.toml b/pyproject.toml index 6afc263..9cd1790 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,7 @@ build-backend = "hatchling.build" [project] name = "WuttJamaican" -version = "0.19.0" +version = "0.19.1" description = "Base package for Wutta Framework" readme = "README.md" authors = [{name = "Lance Edgar", email = "lance@wuttaproject.org"}]