验证格式化邮件

2024-10-05 10:14:07 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在写一个软件,它对输入进行一些分析并返回一个结果。部分需求包括生成零个或多个警告或错误,并包括结果中的警告或错误。我还编写了单元测试,特别是有一些人为的数据来验证是否发出了正确的警告

我需要能够解析警告/错误,并验证预期的消息是否正确发出。我想我应该把这些消息存储在一个容器中,并用一个消息ID来引用它们,这个ID与我过去进行本地化的方式非常相似

errormessages.py现在看起来很像:

from enum import IntEnum
NO_MESSAGE = ('')
HELLO = ('Hello, World')
GOODBYE = ('Goodbye')

class MsgId(IntEnum):
    NO_MESSAGE = 0
    HELLO = 1
    GOODBYE = 2

Msg = {
    MessageId.NO_MESSAGE: NO_MESSAGE,
    MessageId.HELLO: HELLO,
    MessageId.GOODBYE: GOODBYE,
}

因此,分析结果可以类似于:

from errormessages import Msg, MsgId
def analyse(_):
    errors = []
    errors.append(Msg[MsgId.HELLO])
    return _, errors

在单元测试中,我可以做一些类似于

from errormessages import Msg, MsgId
from my import analyse
def test_hello():
    _, errors = analyse('toy')
    assert Msg[MsgId.HELLO] in errors

但是有些消息被格式化了,我认为这会给解析单元测试的消息带来麻烦。我在想我应该增加信息的味道;一个用于格式化,另一个用于解析:

更新errormessages.py

from enum import IntEnum
import re
FORMAT_NO_MESSAGE = ('')
FORMAT_HELLO = ('Hello, {}')
FORMAT_GOODBYE = ('Goodbye')

PARSE_NO_MESSAGE = re.compile(r'^$')
PARSE_HELLO = re.compile(r'^Hello, (.*)$')
PARSE_GOODBYE = re.compile('^Goodbye$')

class MsgId(IntEnum):
    NO_MESSAGE = 0
    HELLO = 1
    GOODBYE = 2

Msg = {
    MessageId.NO_MESSAGE: (FORMAT_NO_MESSAGE, PARSE_NO_MESSAGE),
    MessageId.HELLO: (FORMAT_HELLO, PARSE_HELLO),
    MessageId.GOODBYE: (FORMAT_GOODBYE, PARSE_GOODBYE),
}

因此,分析可以如下所示:

from errormessages import Msg, MsgId
def analyse(_):
    errors = []
    errors.append(Msg[MsgId.HELLO][0].format('World'))
    return _, errors

在单元测试中我可以做到:

from errormessages import Msg, MsgId
from my import analyse
import re
def test_hello():
    _, errors = analyse('toy')
    expected = {v: [] for v in MsgId}
    expected[MsgId.HELLO] = [
        Msg[MsgId.HELLO][1].match(msg)
        for msg in errors
    ]
    for _,v in expected.items():
        if _ == MsgId.HELLO:
            assert v
        else:
            assert not v

我想知道是否有更好/更简单的方法?特别地,消息被有效地重复两次;一次用于格式化程序,一次用于正则表达式。有没有一种方法可以将单个字符串用于格式化和正则表达式捕获


Tags: nofromimportformat消息messagehelloparse
1条回答
网友
1楼 · 发布于 2024-10-05 10:14:07

假设消息都存储为格式字符串模板(例如"Hello",或"Hello, {}""Hello, {firstname} {surname}"),则可以直接从模板生成正则表达式:

import re
import random
import string

def format_string_to_regex(format_string: str) -> re.Pattern:
    """Convert a format string template to a regex."""
    unique_string = ''.join(random.choices(string.ascii_letters, k=24))
    stripped_fields = re.sub(r"\{[^\{\}]*\}(?!\})", unique_string, format_string)
    pattern = re.escape(stripped_fields).replace(unique_string, "(.*)")
    pattern = pattern.replace("\{\{","\{").replace("\}\}", "\}")
    return re.compile(f"^{pattern}$")

def is_error_message(error: str, expected_message: MessageId) -> bool:
    """Returns whether the error plausibly matches the MessageId."""
    expected_format = format_string_to_regex(Msg[expected_message])
    return bool(expected_format.match(error))

相关问题 更多 >

    热门问题