From: Christian Heller Date: Thu, 8 Aug 2024 03:40:51 +0000 (+0200) Subject: Simplify InputParser code/usage. X-Git-Url: https://plomlompom.com/repos/%7B%7Bprefix%7D%7D/static/task?a=commitdiff_plain;h=08264accb5a5958c0eb97987b209621548bd618f;p=plomtask Simplify InputParser code/usage. --- diff --git a/plomtask/http.py b/plomtask/http.py index 2c8eecb..25e377d 100644 --- a/plomtask/http.py +++ b/plomtask/http.py @@ -36,82 +36,69 @@ class TaskServer(HTTPServer): class InputsParser: """Wrapper for validating and retrieving dict-like HTTP inputs.""" - def __init__(self, dict_: dict[str, list[str]], - strictness: bool = True) -> None: + def __init__(self, dict_: dict[str, list[str]]) -> None: self.inputs = dict_ - self.strict = strictness # return None on absence of key, or fail? - def get_str(self, key: str, default: str = '', - ignore_strict: bool = False) -> str: - """Retrieve single/first string value of key, or default.""" - if key not in self.inputs.keys() or 0 == len(self.inputs[key]): - if self.strict and not ignore_strict: - raise NotFoundException(f'no value found for key {key}') - return default - return self.inputs[key][0] + def get_all_str(self, key: str) -> list[str]: + """Retrieve list of string values at key (empty if no key).""" + if key not in self.inputs.keys(): + return [] + return self.inputs[key] - def get_first_strings_starting(self, prefix: str) -> dict[str, str]: - """Retrieve dict of (first) strings at key starting with prefix.""" - ret = {} - for key in [k for k in self.inputs.keys() if k.startswith(prefix)]: - ret[key] = self.inputs[key][0] - return ret + def get_all_int(self, key: str) -> list[int]: + """Retrieve list of int values at key.""" + all_str = self.get_all_str(key) + try: + return [int(s) for s in all_str if len(s) > 0] + except ValueError as e: + msg = f'cannot int a form field value for key {key} in: {all_str}' + raise BadFormatException(msg) from e - def get_int(self, key: str) -> int: - """Retrieve single/first value of key as int, error if empty.""" - val = self.get_int_or_none(key) - if val is None: - raise BadFormatException(f'unexpected empty value for: {key}') - return val + def get_str(self, key: str, default: str | None = None) -> str | None: + """Retrieve single/first string value of key, or default.""" + vals = self.get_all_str(key) + if vals: + return vals[0] + return default + + def get_str_or_fail(self, key: str, default: str | None = None) -> str: + """Retrieve first string value of key, if none: fail or default.""" + vals = self.get_all_str(key) + if not vals: + if default is not None: + return default + raise BadFormatException(f'no value found for key: {key}') + return vals[0] def get_int_or_none(self, key: str) -> int | None: """Retrieve single/first value of key as int, return None if empty.""" - val = self.get_str(key, ignore_strict=True) + val = self.get_str_or_fail(key, '') if val == '': return None try: return int(val) - except ValueError as e: + except (ValueError, TypeError) as e: msg = f'cannot int form field value for key {key}: {val}' raise BadFormatException(msg) from e - def get_float(self, key: str) -> float: - """Retrieve float value of key from self.postvars.""" - val = self.get_str(key) - try: - return float(val) - except ValueError as e: - msg = f'cannot float form field value for key {key}: {val}' - raise BadFormatException(msg) from e - - def get_float_or_none(self, key: str) -> float | None: - """Retrieve float value of key from self.postvars, None if empty.""" - val = self.get_str(key) - if '' == val: - return None - try: - return float(val) - except ValueError as e: - msg = f'cannot float form field value for key {key}: {val}' - raise BadFormatException(msg) from e - def get_bool(self, key: str) -> bool: - """Return if key occurs and maps to a boolean Truth.""" - return bool(self.get_all_str(key)) + """Return if key occurs _and_ its value maps to a boolean Truth.""" + return self.get_str(key) not in {None, 'False'} - def get_all_str(self, key: str) -> list[str]: - """Retrieve list of string values at key.""" - if key not in self.inputs.keys(): - return [] - return self.inputs[key] + def get_firsts_of_key_prefixed(self, prefix: str) -> dict[str, str]: + """Retrieve dict of (first) strings at key starting with prefix.""" + ret = {} + for key in [k for k in self.inputs.keys() if k.startswith(prefix)]: + ret[key] = self.inputs[key][0] + return ret - def get_all_int(self, key: str) -> list[int]: - """Retrieve list of int values at key.""" - all_str = self.get_all_str(key) + def get_float_or_fail(self, key: str) -> float: + """Retrieve float value of key from self.postvars, fail if none.""" + val = self.get_str_or_fail(key) try: - return [int(s) for s in all_str if len(s) > 0] + return float(val) except ValueError as e: - msg = f'cannot int a form field value for key {key} in: {all_str}' + msg = f'cannot float form field value for key {key}: {val}' raise BadFormatException(msg) from e def get_all_floats_or_nones(self, key: str) -> list[float | None]: @@ -135,7 +122,7 @@ class TaskHandler(BaseHTTPRequestHandler): server: TaskServer conn: DatabaseConnection _site: str - _form_data: InputsParser + _form: InputsParser _params: InputsParser def _send_page( @@ -253,8 +240,10 @@ class TaskHandler(BaseHTTPRequestHandler): self.conn = DatabaseConnection(self.server.db) parsed_url = urlparse(self.path) self._site = path_split(parsed_url.path)[1] - params = parse_qs(parsed_url.query, strict_parsing=True) - self._params = InputsParser(params, False) + params = parse_qs(parsed_url.query, + keep_blank_values=True, + strict_parsing=True) + self._params = InputsParser(params) handler_name = f'do_{http_method}_{self._site}' if hasattr(self, handler_name): handler = getattr(self, handler_name) @@ -294,8 +283,8 @@ class TaskHandler(BaseHTTPRequestHandler): """Handle POST with handler, prepare redirection to result.""" length = int(self.headers['content-length']) postvars = parse_qs(self.rfile.read(length).decode(), - keep_blank_values=True, strict_parsing=True) - self._form_data = InputsParser(postvars) + keep_blank_values=True) + self._form = InputsParser(postvars) redir_target = handler() self.conn.commit() return redir_target @@ -332,8 +321,9 @@ class TaskHandler(BaseHTTPRequestHandler): same, the only difference being the HTML template they are rendered to, which .do_GET selects from their method name. """ - start, end = self._params.get_str('start'), self._params.get_str('end') - end = end if end else date_in_n_days(366) + start = self._params.get_str_or_fail('start', '') + end = self._params.get_str_or_fail('end', '') + end = end if end != '' else date_in_n_days(366) days, start, end = Day.by_date_range_with_limits(self.conn, (start, end), 'id') days = Day.with_filled_gaps(days, start, end) @@ -350,9 +340,9 @@ class TaskHandler(BaseHTTPRequestHandler): def do_GET_day(self) -> dict[str, object]: """Show single Day of ?date=.""" - date = self._params.get_str('date', date_in_n_days(0)) + date = self._params.get_str_or_fail('date', date_in_n_days(0)) day = Day.by_id_or_create(self.conn, date) - make_type = self._params.get_str('make_type') + make_type = self._params.get_str_or_fail('make_type', '') conditions_present = [] enablers_for = {} disablers_for = {} @@ -451,11 +441,11 @@ class TaskHandler(BaseHTTPRequestHandler): def do_GET_todos(self) -> dict[str, object]: """Show Todos from ?start= to ?end=, of ?process=, ?comment= pattern""" - sort_by = self._params.get_str('sort_by') - start = self._params.get_str('start') - end = self._params.get_str('end') + sort_by = self._params.get_str_or_fail('sort_by', '') + start = self._params.get_str_or_fail('start', '') + end = self._params.get_str_or_fail('end', '') process_id = self._params.get_int_or_none('process_id') - comment_pattern = self._params.get_str('comment_pattern') + comment_pattern = self._params.get_str_or_fail('comment_pattern', '') todos = [] ret = Todo.by_date_range_with_limits(self.conn, (start, end)) todos_by_date_range, start, end = ret @@ -469,8 +459,8 @@ class TaskHandler(BaseHTTPRequestHandler): def do_GET_conditions(self) -> dict[str, object]: """Show all Conditions.""" - pattern = self._params.get_str('pattern') - sort_by = self._params.get_str('sort_by') + pattern = self._params.get_str_or_fail('pattern', '') + sort_by = self._params.get_str_or_fail('sort_by', '') conditions = Condition.matching(self.conn, pattern) sort_by = Condition.sort_by(conditions, sort_by) return {'conditions': conditions, @@ -542,8 +532,8 @@ class TaskHandler(BaseHTTPRequestHandler): def do_GET_processes(self) -> dict[str, object]: """Show all Processes.""" - pattern = self._params.get_str('pattern') - sort_by = self._params.get_str('sort_by') + pattern = self._params.get_str_or_fail('pattern', '') + sort_by = self._params.get_str_or_fail('sort_by', '') processes = Process.matching(self.conn, pattern) sort_by = Process.sort_by(processes, sort_by) return {'processes': processes, 'sort_by': sort_by, 'pattern': pattern} @@ -560,7 +550,7 @@ class TaskHandler(BaseHTTPRequestHandler): # (because pylint here fails to detect the use of wrapper as a # method to self with respective access privileges) id_ = self._params.get_int_or_none('id') - for _ in self._form_data.get_all_str('delete'): + for _ in self._form.get_all_str('delete'): if id_ is None: msg = 'trying to delete non-saved ' +\ f'{target_class.__name__}' @@ -581,7 +571,7 @@ class TaskHandler(BaseHTTPRequestHandler): id_ = self._params.get_int_or_none('id') item = cls.by_id(self.conn, id_) attr = getattr(item, attr_name) - for k, v in self._form_data.get_first_strings_starting('at:').items(): + for k, v in self._form.get_firsts_of_key_prefixed('at:').items(): old = k[3:] if old[19:] != v: attr.reset_timestamp(old, f'{v}.0') @@ -591,17 +581,14 @@ class TaskHandler(BaseHTTPRequestHandler): def do_POST_day(self) -> str: """Update or insert Day of date and Todos mapped to it.""" # pylint: disable=too-many-locals - try: - date = self._params.get_str('date') - day_comment = self._form_data.get_str('day_comment') - make_type = self._form_data.get_str('make_type') - except NotFoundException as e: - raise BadFormatException from e - old_todos = self._form_data.get_all_int('todo_id') - new_todos_by_process = self._form_data.get_all_int('new_todo') - comments = self._form_data.get_all_str('comment') - efforts = self._form_data.get_all_floats_or_nones('effort') - done_todos = self._form_data.get_all_int('done') + date = self._params.get_str_or_fail('date') + day_comment = self._form.get_str_or_fail('day_comment') + make_type = self._form.get_str_or_fail('make_type') + old_todos = self._form.get_all_int('todo_id') + new_todos_by_process = self._form.get_all_int('new_todo') + comments = self._form.get_all_str('comment') + efforts = self._form.get_all_floats_or_nones('effort') + done_todos = self._form.get_all_int('done') for _ in [id_ for id_ in done_todos if id_ not in old_todos]: raise BadFormatException('"done" field refers to unknown Todo') is_done = [t_id in done_todos for t_id in old_todos] @@ -635,20 +622,26 @@ class TaskHandler(BaseHTTPRequestHandler): """Update Todo and its children.""" # pylint: disable=too-many-locals # pylint: disable=too-many-branches - adopted_child_ids = self._form_data.get_all_int('adopt') - to_make = {'full': self._form_data.get_all_int('make_full'), - 'empty': self._form_data.get_all_int('make_empty')} - step_fillers = self._form_data.get_all_str('step_filler') - to_update = { - 'is_done': self._form_data.get_bool('done'), - 'calendarize': self._form_data.get_bool('calendarize'), - 'comment': self._form_data.get_str('comment', ignore_strict=True)} - cond_rels = [self._form_data.get_all_int(name) for name in + adopted_child_ids = self._form.get_all_int('adopt') + to_make = {'full': self._form.get_all_int('make_full'), + 'empty': self._form.get_all_int('make_empty')} + step_fillers = self._form.get_all_str('step_filler') + to_update: dict[str, Any] = { + 'is_done': self._form.get_bool('done'), + 'calendarize': self._form.get_bool('calendarize'), + 'comment': self._form.get_str_or_fail('comment', '')} + cond_rels = [self._form.get_all_int(name) for name in ['conditions', 'blockers', 'enables', 'disables']] - try: - to_update['effort'] = self._form_data.get_float_or_none('effort') - except NotFoundException: - pass + effort_or_not = self._form.get_str('effort') + if effort_or_not is not None: + if effort_or_not == '': + to_update['effort'] = None + else: + try: + to_update['effort'] = float(effort_or_not) + except ValueError as e: + msg = 'cannot float form field value for key: effort' + raise BadFormatException(msg) from e todo.set_condition_relations(self.conn, *cond_rels) for filler in [f for f in step_fillers if f != 'ignore']: target_id: int @@ -707,23 +700,20 @@ class TaskHandler(BaseHTTPRequestHandler): def do_POST_process(self, process: Process) -> str: """Update or insert Process of ?id= and fields defined in postvars.""" # pylint: disable=too-many-locals - try: - versioned = {'title': self._form_data.get_str('title'), - 'description': self._form_data.get_str('description'), - 'effort': self._form_data.get_float('effort')} - except NotFoundException as e: - raise BadFormatException from e - cond_rels = [self._form_data.get_all_int(s) for s + versioned = {'title': self._form.get_str_or_fail('title'), + 'description': self._form.get_str_or_fail('description'), + 'effort': self._form.get_float_or_fail('effort')} + cond_rels = [self._form.get_all_int(s) for s in ['conditions', 'blockers', 'enables', 'disables']] - calendarize = self._form_data.get_bool('calendarize') - step_of = self._form_data.get_all_str('step_of') - suppresses = self._form_data.get_all_int('suppresses') - kept_steps = self._form_data.get_all_int('kept_steps') - new_top_steps = self._form_data.get_all_str('new_top_step') + calendarize = self._form.get_bool('calendarize') + step_of = self._form.get_all_str('step_of') + suppresses = self._form.get_all_int('suppresses') + kept_steps = self._form.get_all_int('kept_steps') + new_top_steps = self._form.get_all_str('new_top_step') new_steps_to = {} for step_id in kept_steps: name = f'new_step_to_{step_id}' - new_steps_to[step_id] = self._form_data.get_all_int(name) + new_steps_to[step_id] = self._form.get_all_int(name) for k, v in versioned.items(): getattr(process, k).set(v) process.set_condition_relations(self.conn, *cond_rels) @@ -785,12 +775,9 @@ class TaskHandler(BaseHTTPRequestHandler): @_delete_or_post(Condition, '/conditions') def do_POST_condition(self, condition: Condition) -> str: """Update/insert Condition of ?id= and fields defined in postvars.""" - try: - title = self._form_data.get_str('title') - description = self._form_data.get_str('description') - except NotFoundException as e: - raise BadFormatException(e) from e - condition.is_active = self._form_data.get_bool('is_active') + title = self._form.get_str_or_fail('title') + description = self._form.get_str_or_fail('description') + condition.is_active = self._form.get_bool('is_active') condition.title.set(title) condition.description.set(description) condition.save(self.conn) diff --git a/tests/conditions.py b/tests/conditions.py index 333267f..cc208fb 100644 --- a/tests/conditions.py +++ b/tests/conditions.py @@ -79,7 +79,6 @@ class TestsWithServer(TestCaseWithServer): url = '/condition' self.check_post({}, url, 400) self.check_post({'title': ''}, url, 400) - self.check_post({'title': '', 'description': ''}, url, 400) self.check_post({'title': '', 'is_active': False}, url, 400) self.check_post({'description': '', 'is_active': False}, url, 400) # check valid POST payload on bad paths diff --git a/tests/misc.py b/tests/misc.py index ce5f87a..8ac82f5 100644 --- a/tests/misc.py +++ b/tests/misc.py @@ -2,208 +2,158 @@ from unittest import TestCase from tests.utils import TestCaseWithServer from plomtask.http import InputsParser -from plomtask.exceptions import BadFormatException, NotFoundException +from plomtask.exceptions import BadFormatException class TestsSansServer(TestCase): """Tests that do not require DB setup or a server.""" + def test_InputsParser_get_str_or_fail(self) -> None: + """Test InputsParser.get_str.""" + parser = InputsParser({}) + with self.assertRaises(BadFormatException): + parser.get_str_or_fail('foo') + self.assertEqual('bar', parser.get_str_or_fail('foo', 'bar')) + parser = InputsParser({'foo': []}) + with self.assertRaises(BadFormatException): + parser.get_str_or_fail('foo') + self.assertEqual('bar', parser.get_str_or_fail('foo', 'bar')) + parser = InputsParser({'foo': ['baz']}) + self.assertEqual('baz', parser.get_str_or_fail('foo', 'bar')) + parser = InputsParser({'foo': ['baz', 'quux']}) + self.assertEqual('baz', parser.get_str_or_fail('foo', 'bar')) + def test_InputsParser_get_str(self) -> None: - """Test InputsParser.get_str on strict and non-strictk.""" - parser = InputsParser({}, False) - self.assertEqual('', parser.get_str('foo')) + """Test InputsParser.get_str.""" + parser = InputsParser({}) + self.assertEqual(None, parser.get_str('foo')) self.assertEqual('bar', parser.get_str('foo', 'bar')) - parser.strict = True - with self.assertRaises(NotFoundException): - parser.get_str('foo') - with self.assertRaises(NotFoundException): - parser.get_str('foo', 'bar') - parser = InputsParser({'foo': []}, False) + parser = InputsParser({'foo': []}) + self.assertEqual(None, parser.get_str('foo')) self.assertEqual('bar', parser.get_str('foo', 'bar')) - with self.assertRaises(NotFoundException): - InputsParser({'foo': []}, True).get_str('foo', 'bar') - for strictness in (False, True): - parser = InputsParser({'foo': ['baz']}, strictness) - self.assertEqual('baz', parser.get_str('foo', 'bar')) - parser = InputsParser({'foo': ['baz', 'quux']}, strictness) - self.assertEqual('baz', parser.get_str('foo', 'bar')) - - def test_InputsParser_get_first_strings_starting(self) -> None: - """Test InputsParser.get_first_strings_starting [non-]strict.""" - for strictness in (False, True): - parser = InputsParser({}, strictness) - self.assertEqual({}, - parser.get_first_strings_starting('')) - parser = InputsParser({}, strictness) - self.assertEqual({}, - parser.get_first_strings_starting('foo')) - parser = InputsParser({'foo': ['bar']}, strictness) - self.assertEqual({'foo': 'bar'}, - parser.get_first_strings_starting('')) - parser = InputsParser({'x': ['y']}, strictness) - self.assertEqual({'x': 'y'}, - parser.get_first_strings_starting('x')) - parser = InputsParser({'xx': ['y']}, strictness) - self.assertEqual({'xx': 'y'}, - parser.get_first_strings_starting('x')) - parser = InputsParser({'xx': ['y']}, strictness) - self.assertEqual({}, - parser.get_first_strings_starting('xxx')) - d = {'xxx': ['x'], 'xxy': ['y'], 'xyy': ['z']} - parser = InputsParser(d, strictness) - self.assertEqual({'xxx': 'x', 'xxy': 'y'}, - parser.get_first_strings_starting('xx')) - d = {'xxx': ['x', 'y', 'z'], 'xxy': ['y', 'z']} - parser = InputsParser(d, strictness) - self.assertEqual({'xxx': 'x', 'xxy': 'y'}, - parser.get_first_strings_starting('xx')) + parser = InputsParser({'foo': ['baz']}) + self.assertEqual('baz', parser.get_str('foo', 'bar')) + parser = InputsParser({'foo': ['baz', 'quux']}) + self.assertEqual('baz', parser.get_str('foo', 'bar')) - def test_InputsParser_get_int(self) -> None: - """Test InputsParser.get_int on strict and non-strict.""" - for strictness in (False, True): - with self.assertRaises(BadFormatException): - InputsParser({}, strictness).get_int('foo') - with self.assertRaises(BadFormatException): - InputsParser({'foo': []}, strictness).get_int('foo') - with self.assertRaises(BadFormatException): - InputsParser({'foo': ['']}, strictness).get_int('foo') - with self.assertRaises(BadFormatException): - InputsParser({'foo': ['bar']}, strictness).get_int('foo') - with self.assertRaises(BadFormatException): - InputsParser({'foo': ['0.1']}).get_int('foo') - parser = InputsParser({'foo': ['0']}, strictness) - self.assertEqual(0, parser.get_int('foo')) - parser = InputsParser({'foo': ['17', '23']}, strictness) - self.assertEqual(17, parser.get_int('foo')) + def test_InputsParser_get_firsts_of_key_prefixed(self) -> None: + """Test InputsParser.get_firsts_of_key_prefixed.""" + parser = InputsParser({}) + self.assertEqual({}, + parser.get_firsts_of_key_prefixed('')) + self.assertEqual({}, + parser.get_firsts_of_key_prefixed('foo')) + parser = InputsParser({'foo': ['bar']}) + self.assertEqual({'foo': 'bar'}, + parser.get_firsts_of_key_prefixed('')) + parser = InputsParser({'x': ['y']}) + self.assertEqual({'x': 'y'}, + parser.get_firsts_of_key_prefixed('x')) + parser = InputsParser({'xx': ['y']}) + self.assertEqual({'xx': 'y'}, + parser.get_firsts_of_key_prefixed('x')) + parser = InputsParser({'xx': ['y']}) + self.assertEqual({}, + parser.get_firsts_of_key_prefixed('xxx')) + parser = InputsParser({'xxx': ['x'], 'xxy': ['y'], 'xyy': ['z']}) + self.assertEqual({'xxx': 'x', 'xxy': 'y'}, + parser.get_firsts_of_key_prefixed('xx')) + parser = InputsParser({'xxx': ['x', 'y', 'z'], 'xxy': ['y', 'z']}) + self.assertEqual({'xxx': 'x', 'xxy': 'y'}, + parser.get_firsts_of_key_prefixed('xx')) def test_InputsParser_get_int_or_none(self) -> None: - """Test InputsParser.get_int_or_none on strict and non-strict.""" - for strictness in (False, True): - parser = InputsParser({}, strictness) - self.assertEqual(None, parser.get_int_or_none('foo')) - parser = InputsParser({'foo': []}, strictness) - self.assertEqual(None, parser.get_int_or_none('foo')) - parser = InputsParser({'foo': ['']}, strictness) - self.assertEqual(None, parser.get_int_or_none('foo')) - parser = InputsParser({'foo': ['0']}, strictness) - self.assertEqual(0, parser.get_int_or_none('foo')) - with self.assertRaises(BadFormatException): - InputsParser({'foo': ['None']}, - strictness).get_int_or_none('foo') - with self.assertRaises(BadFormatException): - InputsParser({'foo': ['0.1']}, - strictness).get_int_or_none('foo') - parser = InputsParser({'foo': ['23']}, strictness) - self.assertEqual(23, parser.get_int_or_none('foo')) - - def test_InputsParser_get_float(self) -> None: - """Test InputsParser.get_float on strict and non-strict.""" - for strictness in (False, True): - with self.assertRaises(BadFormatException): - InputsParser({'foo': ['']}, strictness).get_float('foo') - with self.assertRaises(BadFormatException): - InputsParser({'foo': ['bar']}, strictness).get_float('foo') - parser = InputsParser({'foo': ['0']}, strictness) - self.assertEqual(0, parser.get_float('foo')) - parser = InputsParser({'foo': ['0.1']}, strictness) - self.assertEqual(0.1, parser.get_float('foo')) - parser = InputsParser({'foo': ['1.23', '456']}, strictness) - self.assertEqual(1.23, parser.get_float('foo')) - if strictness: - with self.assertRaises(NotFoundException): - InputsParser({}, strictness).get_float('foo') - with self.assertRaises(NotFoundException): - InputsParser({'foo': []}, strictness).get_float('foo') - else: - with self.assertRaises(BadFormatException): - InputsParser({}, strictness).get_float('foo') - with self.assertRaises(BadFormatException): - InputsParser({'foo': []}, strictness).get_float('foo') + """Test InputsParser.get_int_or_none.""" + parser = InputsParser({}) + self.assertEqual(None, parser.get_int_or_none('foo')) + parser = InputsParser({'foo': []}) + self.assertEqual(None, parser.get_int_or_none('foo')) + parser = InputsParser({'foo': ['']}) + self.assertEqual(None, parser.get_int_or_none('foo')) + parser = InputsParser({'foo': ['0']}) + self.assertEqual(0, parser.get_int_or_none('foo')) + with self.assertRaises(BadFormatException): + InputsParser({'foo': ['None']}).get_int_or_none('foo') + with self.assertRaises(BadFormatException): + InputsParser({'foo': ['0.1']}).get_int_or_none('foo') + parser = InputsParser({'foo': ['23']}) + self.assertEqual(23, parser.get_int_or_none('foo')) - def test_InputsParser_get_float_or_none(self) -> None: - """Test InputsParser.get_float_or_none on strict and non-strict.""" - for strictness in (False, True): - with self.assertRaises(BadFormatException): - InputsParser({'foo': ['bar']}, strictness).\ - get_float_or_none('foo') - parser = InputsParser({'foo': ['']}, strictness) - self.assertEqual(None, parser.get_float_or_none('foo')) - parser = InputsParser({'foo': ['0']}, strictness) - self.assertEqual(0, parser.get_float_or_none('foo')) - parser = InputsParser({'foo': ['0.1']}, strictness) - self.assertEqual(0.1, parser.get_float_or_none('foo')) - parser = InputsParser({'foo': ['1.23', '456']}, strictness) - self.assertEqual(1.23, parser.get_float_or_none('foo')) - if strictness: - with self.assertRaises(NotFoundException): - InputsParser({}, strictness).get_float_or_none('foo') - with self.assertRaises(NotFoundException): - InputsParser({'foo': []}, strictness).get_float_or_none('foo') - else: - parser = InputsParser({}, strictness) - self.assertEqual(None, parser.get_float_or_none('foo')) - parser = InputsParser({'foo': []}, strictness) - self.assertEqual(None, parser.get_float_or_none('foo')) + def test_InputsParser_get_float_or_fail(self) -> None: + """Test InputsParser.get_float_or_fail.""" + with self.assertRaises(BadFormatException): + InputsParser({}).get_float_or_fail('foo') + with self.assertRaises(BadFormatException): + InputsParser({'foo': ['']}).get_float_or_fail('foo') + with self.assertRaises(BadFormatException): + InputsParser({'foo': ['bar']}).get_float_or_fail('foo') + parser = InputsParser({'foo': ['0']}) + self.assertEqual(0, parser.get_float_or_fail('foo')) + parser = InputsParser({'foo': ['0.1']}) + self.assertEqual(0.1, parser.get_float_or_fail('foo')) + parser = InputsParser({'foo': ['1.23', '456']}) + self.assertEqual(1.23, parser.get_float_or_fail('foo')) + with self.assertRaises(BadFormatException): + InputsParser({}).get_float_or_fail('foo') + with self.assertRaises(BadFormatException): + InputsParser({'foo': []}).get_float_or_fail('foo') def test_InputsParser_get_bool(self) -> None: - """Test InputsParser.get_all_str on strict and non-strict.""" - for strictness in (False, True): - parser = InputsParser({}, strictness) - self.assertEqual(False, parser.get_bool('foo')) - parser = InputsParser({'val': ['true']}, strictness) - self.assertEqual(False, parser.get_bool('foo')) - parser = InputsParser({'val': ['True']}, strictness) - self.assertEqual(False, parser.get_bool('foo')) - parser = InputsParser({'val': ['1']}, strictness) - self.assertEqual(False, parser.get_bool('foo')) - parser = InputsParser({'val': ['foo']}, strictness) - self.assertEqual(False, parser.get_bool('foo')) - parser = InputsParser({'foo': []}, strictness) - self.assertEqual(False, parser.get_bool('foo')) - parser = InputsParser({'foo': ['None']}, strictness) - self.assertEqual(True, parser.get_bool('foo')) - parser = InputsParser({'foo': ['0']}, strictness) - self.assertEqual(True, parser.get_bool('foo')) - parser = InputsParser({'foo': ['']}, strictness) - self.assertEqual(True, parser.get_bool('foo')) - parser = InputsParser({'foo': ['bar']}, strictness) - self.assertEqual(True, parser.get_bool('foo')) - parser = InputsParser({'foo': ['bar', 'baz']}, strictness) - self.assertEqual(True, parser.get_bool('foo')) - parser = InputsParser({'foo': ['False']}, strictness) - self.assertEqual(True, parser.get_bool('foo')) + """Test InputsParser.get_all_str.""" + parser = InputsParser({}) + self.assertEqual(False, parser.get_bool('foo')) + parser = InputsParser({'val': ['true']}) + self.assertEqual(False, parser.get_bool('foo')) + parser = InputsParser({'val': ['True']}) + self.assertEqual(False, parser.get_bool('foo')) + parser = InputsParser({'val': ['1']}) + self.assertEqual(False, parser.get_bool('foo')) + parser = InputsParser({'val': ['foo']}) + self.assertEqual(False, parser.get_bool('foo')) + parser = InputsParser({'foo': []}) + self.assertEqual(False, parser.get_bool('foo')) + parser = InputsParser({'foo': ['None']}) + self.assertEqual(True, parser.get_bool('foo')) + parser = InputsParser({'foo': ['0']}) + self.assertEqual(True, parser.get_bool('foo')) + parser = InputsParser({'foo': ['']}) + self.assertEqual(True, parser.get_bool('foo')) + parser = InputsParser({'foo': ['bar']}) + self.assertEqual(True, parser.get_bool('foo')) + parser = InputsParser({'foo': ['bar', 'baz']}) + self.assertEqual(True, parser.get_bool('foo')) + parser = InputsParser({'foo': ['False']}) + self.assertEqual(False, parser.get_bool('foo')) def test_InputsParser_get_all_str(self) -> None: - """Test InputsParser.get_all_str on strict and non-strict.""" - for strictness in (False, True): - parser = InputsParser({}, strictness) - self.assertEqual([], parser.get_all_str('foo')) - parser = InputsParser({'foo': []}, strictness) - self.assertEqual([], parser.get_all_str('foo')) - parser = InputsParser({'foo': ['bar']}, strictness) - self.assertEqual(['bar'], parser.get_all_str('foo')) - parser = InputsParser({'foo': ['bar', 'baz']}, strictness) - self.assertEqual(['bar', 'baz'], parser.get_all_str('foo')) + """Test InputsParser.get_all_str.""" + parser = InputsParser({}) + self.assertEqual([], parser.get_all_str('foo')) + parser = InputsParser({'foo': []}) + self.assertEqual([], parser.get_all_str('foo')) + parser = InputsParser({'foo': ['bar']}) + self.assertEqual(['bar'], parser.get_all_str('foo')) + parser = InputsParser({'foo': ['bar', 'baz']}) + self.assertEqual(['bar', 'baz'], parser.get_all_str('foo')) def test_InputsParser_strict_get_all_int(self) -> None: - """Test InputsParser.get_all_int on strict and non-strict.""" - for strictness in (False, True): - parser = InputsParser({}, strictness) - self.assertEqual([], parser.get_all_int('foo')) - parser = InputsParser({'foo': []}, strictness) - self.assertEqual([], parser.get_all_int('foo')) - parser = InputsParser({'foo': ['']}, strictness) - self.assertEqual([], parser.get_all_int('foo')) - parser = InputsParser({'foo': ['0']}, strictness) - self.assertEqual([0], parser.get_all_int('foo')) - parser = InputsParser({'foo': ['0', '17']}, strictness) - self.assertEqual([0, 17], parser.get_all_int('foo')) - parser = InputsParser({'foo': ['0.1', '17']}, strictness) - with self.assertRaises(BadFormatException): - parser.get_all_int('foo') - parser = InputsParser({'foo': ['None', '17']}, strictness) - with self.assertRaises(BadFormatException): - parser.get_all_int('foo') + """Test InputsParser.get_all_int.""" + parser = InputsParser({}) + self.assertEqual([], parser.get_all_int('foo')) + parser = InputsParser({'foo': []}) + self.assertEqual([], parser.get_all_int('foo')) + parser = InputsParser({'foo': ['']}) + self.assertEqual([], parser.get_all_int('foo')) + parser = InputsParser({'foo': ['0']}) + self.assertEqual([0], parser.get_all_int('foo')) + parser = InputsParser({'foo': ['0', '17']}) + self.assertEqual([0, 17], parser.get_all_int('foo')) + parser = InputsParser({'foo': ['0.1', '17']}) + with self.assertRaises(BadFormatException): + parser.get_all_int('foo') + parser = InputsParser({'foo': ['None', '17']}) + with self.assertRaises(BadFormatException): + parser.get_all_int('foo') class TestsWithServer(TestCaseWithServer):