From 293b420f60b88a05e3f704708ec5d47f1168fc56 Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Sun, 6 Dec 2020 14:57:33 -0600 Subject: [PATCH] Report error when multi-valued setting has one value --- src/pgwui_server/exceptions.py | 13 +++++++++++++ src/pgwui_server/pgwui_server.py | 16 +++++++++++----- tests/test_pgwui_server.py | 33 ++++++++++++++++++++++++++++++-- 3 files changed, 55 insertions(+), 7 deletions(-) diff --git a/src/pgwui_server/exceptions.py b/src/pgwui_server/exceptions.py index d312dd1..5ab339d 100644 --- a/src/pgwui_server/exceptions.py +++ b/src/pgwui_server/exceptions.py @@ -42,6 +42,19 @@ class AutoconfigureConflict(ServerInfo): 'Autoconfigure is True and there is a pyramid.include setting') +class MissingEqualError(ServerError): + def __init__(self, line): + super().__init__( + 'Expecting text containing an equals (=) sign, but ' + f'instead got ({line})') + + +class BadValueError(ServerError): + def __init__(self, setting, ex): + super().__init__( + f'Bad setting value supplied to ({setting}): {ex}') + + class BadSettingsAbort(ServerError): def __init__(self): super().__init__('Aborting due to bad setting(s)') diff --git a/src/pgwui_server/pgwui_server.py b/src/pgwui_server/pgwui_server.py index b950206..46615f3 100644 --- a/src/pgwui_server/pgwui_server.py +++ b/src/pgwui_server/pgwui_server.py @@ -83,7 +83,10 @@ def parse_multiline_assignments(lines, result): stripped = line.lstrip() if stripped != '': # Multiple values on different lines means a list - key, val = result[-1] + try: + key, val = result[-1] + except IndexError: + raise server_ex.MissingEqualError(stripped) if not isinstance(val, list): val = [val] val.append(stripped) @@ -102,12 +105,15 @@ def parse_assignments(lines): return result -def dot_to_multiline_setting(settings, key, pgwui_key): +def dot_to_multiline_setting(errors, settings, key, pgwui_key): '''Put a multi-line setting into its own dict, adding to what's already there ''' multi_setting = settings['pgwui'].setdefault(pgwui_key, dict()) - multi_setting.update(dict(parse_assignments(settings[key]))) + try: + multi_setting.update(dict(parse_assignments(settings[key]))) + except server_ex.MissingEqualError as ex: + errors.append(server_ex.BadValueError(f'pgwui:{pgwui_key}', ex)) del settings[key] @@ -115,7 +121,7 @@ def component_setting_into_dict( errors, component_checkers, key, settings, component): '''Put a component's settings in its own dict and validate them ''' - comp_settings = dot_to_multiline_setting(settings, key, component) + comp_settings = dot_to_multiline_setting(errors, settings, key, component) if component in component_checkers: errors.extend( component_checkers[component](comp_settings)) @@ -135,7 +141,7 @@ def setting_into_dict( if new_key in SETTINGS: dot_to_dict(settings, key, new_key) elif new_key in MULTI_SETTINGS: - dot_to_multiline_setting(settings, key, new_key) + dot_to_multiline_setting(errors, settings, key, new_key) else: errors.append(common_ex.UnknownSettingKeyError(key)) diff --git a/tests/test_pgwui_server.py b/tests/test_pgwui_server.py index ac44921..7cd136b 100644 --- a/tests/test_pgwui_server.py +++ b/tests/test_pgwui_server.py @@ -33,6 +33,7 @@ from pgwui_testing import testing import pgwui_server.checkset import pgwui_server.pgwui_server as pgwui_server +import pgwui_server.exceptions as server_ex # Mark all tests with "unittest" @@ -79,6 +80,7 @@ mock_add_routes = testing.make_mock_fixture( def test_dot_to_multiline_setting_new(mock_parse_assignments): '''Adds a new dict and puts the settings in it ''' + errors = [] comp_settings = {'foo': 'foo', 'bar': 'bar'} component = 'pgwui_component' key = 'pgwui.' + component @@ -88,14 +90,16 @@ def test_dot_to_multiline_setting_new(mock_parse_assignments): mock_parse_assignments.return_value = comp_settings pgwui_server.dot_to_multiline_setting( - settings, key, component) + errors, settings, key, component) assert settings == expected + assert errors == [] def test_dot_to_multiline_setting_old(mock_parse_assignments): '''Extends an existing dict in the settings ''' + errors = [] comp_settings = {'foo': 'foo', 'bar': 'bar'} component = 'pgwui_component' key = 'pgwui.' + component @@ -106,9 +110,27 @@ def test_dot_to_multiline_setting_old(mock_parse_assignments): mock_parse_assignments.return_value = comp_settings pgwui_server.dot_to_multiline_setting( - settings, key, component) + errors, settings, key, component) assert settings == expected + assert errors == [] + + +def test_dot_to_multiline_setting_bad(mock_parse_assignments): + '''When the value is bad we get the expected error + ''' + errors = [] + component = 'pgwui_component' + key = 'pgwui.' + component + settings = {'pgwui': {}, + key: 'ignored'} + + mock_parse_assignments.side_effect = server_ex.MissingEqualError('text') + pgwui_server.dot_to_multiline_setting( + errors, settings, key, component) + + assert len(errors) == 1 + assert isinstance(errors[0], server_ex.BadValueError) mock_dot_to_multiline_setting = testing.make_mock_fixture( @@ -192,6 +214,13 @@ def test_parse_multiline_assignments_str(): ('key3', 'value3=withequals')] +def test_parse_multiline_assignments_no_equal(): + '''When the line contains no equal sign the right exception is raised + ''' + with pytest.raises(server_ex.MissingEqualError): + pgwui_server.parse_multiline_assignments('noequal\n', []) + + mock_parse_multiline_assignments = testing.make_mock_fixture( pgwui_server, 'parse_multiline_assignments') -- 2.34.1