select option texts without non-printable characters; bugfixes

This commit is contained in:
Daniil Fajnberg 2022-01-01 18:56:17 +01:00
parent c6dbcda947
commit 309a9b678e
2 changed files with 14 additions and 6 deletions

View File

@ -1,6 +1,6 @@
[metadata]
name = yamlhttpforms
version = 0.0.4
version = 0.0.5
author = Daniil F.
author_email = mail@placeholder123.to
description = HTTP forms defined in YAML

View File

@ -1,4 +1,6 @@
import sys
from typing import Dict, TYPE_CHECKING
from bs4.element import Tag
if TYPE_CHECKING:
@ -8,6 +10,8 @@ if TYPE_CHECKING:
INPUT, SELECT, OPTION = 'input', 'select', 'option'
NAME, VALUE, SELECTED = 'name', 'value', 'selected'
NON_PRINTABLE_TO_NONE = {code: None for code in range(sys.maxunicode + 1) if not chr(code).isprintable()}
class WrongInterface(Exception):
pass
@ -29,6 +33,10 @@ class UnknownField(WrongInterface):
pass
def printable_only(string: str) -> str:
return string.translate(NON_PRINTABLE_TO_NONE)
def check_select_field_options(field_tag: Tag, field_interface: 'FormField', check_defaults: bool = True) -> None:
"""
Compares the `options` and `default` attributes of a `'FormField'` object with the options of its HTML counterpart.
@ -45,7 +53,7 @@ def check_select_field_options(field_tag: Tag, field_interface: 'FormField', che
`FieldInterfaceWrong`
if the `default` is not equal to the value of the <option> tag which has the `selected` attribute
"""
html_options = {(tag[VALUE], tag.get_text(strip=True)) for tag in field_tag.find_all(OPTION)}
html_options = {(tag[VALUE], printable_only(tag.get_text(strip=True))) for tag in field_tag.find_all(OPTION)}
interface_options = set(field_interface.options.items())
missing_in_interface = html_options - interface_options
not_in_html = interface_options - html_options
@ -59,9 +67,9 @@ def check_select_field_options(field_tag: Tag, field_interface: 'FormField', che
if s:
raise SelectOptionsWrong(f"Wrong options in field '{field_interface.name}'." + s)
if check_defaults:
default = field_tag.find(lambda tag: tag.name == OPTION and tag.has_attr(SELECTED))[VALUE]
if default != field_interface.default:
raise FieldInterfaceWrong(f"Default option '{default}' missing for {field_interface}")
default_option = field_tag.find(lambda tag: tag.name == OPTION and tag.has_attr(SELECTED))
if default_option is not None and default_option[VALUE] != field_interface.default:
raise FieldInterfaceWrong(f"Default option '{default_option[VALUE]}' missing for {field_interface}")
def check_field_interface(field_tag: Tag, field_interface: 'FormField', check_defaults: bool = True) -> None:
@ -109,7 +117,7 @@ def check_form_interface(form_tag: Tag, form_interface: 'Form', check_defaults:
"""
field_tags: Dict[str, Tag] = {tag[NAME]: tag for tag in form_tag.find_all(INPUT) + form_tag.find_all(SELECT)}
for field in form_interface.fields.values():
tag = field_tags.pop(field.name)
tag = field_tags.pop(field.name, None)
if tag is None:
raise UnknownField(f"The defined field does not exist in the form: {field}")
check_field_interface(tag, field, check_defaults=check_defaults)