189 lines
9.8 KiB
Python
189 lines
9.8 KiB
Python
import datetime
|
||
|
||
import pytest
|
||
|
||
from ptimeparse import Parser
|
||
from ptimeparse.err import MultipleSpecificationException, TokenUnhandledException
|
||
|
||
|
||
def test_chinese_number():
|
||
parser = Parser()
|
||
|
||
assert parser.digest_chinese_number("零") == ('', 0)
|
||
assert parser.digest_chinese_number("零喵") == ('喵', 0)
|
||
assert parser.digest_chinese_number("一喵") == ('喵', 1)
|
||
assert parser.digest_chinese_number("十喵") == ('喵', 10)
|
||
assert parser.digest_chinese_number("三千万喵") == ('喵', 3000_0000)
|
||
assert parser.digest_chinese_number("三千三百万喵") == ('喵', 3300_0000)
|
||
assert parser.digest_chinese_number("三千零三万喵") == ('喵', 3003_0000)
|
||
assert parser.digest_chinese_number("三千零三十万喵") == ('喵', 3030_0000)
|
||
assert parser.digest_chinese_number("五千四百零三万喵") == ('喵', 5403_0000)
|
||
assert parser.digest_chinese_number("五百万喵") == ('喵', 500_0000)
|
||
assert parser.digest_chinese_number("五万五千喵") == ('喵', 5_5000)
|
||
assert parser.digest_chinese_number("五万零五百喵") == ('喵', 5_0500)
|
||
assert parser.digest_chinese_number("五亿喵") == ('喵', 5_0000_0000)
|
||
assert parser.digest_chinese_number("五百亿喵") == ('喵', 500_0000_0000)
|
||
assert parser.digest_chinese_number("五百亿零五十喵") == ('喵', 500_0000_0050)
|
||
assert parser.digest_chinese_number("五百亿五十万喵") == ('喵', 500_0050_0000)
|
||
|
||
|
||
def test_hour_specification_pm():
|
||
parser = Parser(now=datetime.datetime(2025, 10, 9, 16, 34, 1, 114))
|
||
|
||
assert parser.parse("五点") == datetime.datetime(2025, 10, 9, 17, 0, 0, 0)
|
||
assert parser.parse("5点") == datetime.datetime(2025, 10, 9, 17, 0, 0, 0)
|
||
assert parser.parse("5 点") == datetime.datetime(2025, 10, 9, 17, 0, 0, 0)
|
||
|
||
assert parser.parse("六点") == datetime.datetime(2025, 10, 9, 18, 0, 0, 0)
|
||
assert parser.parse("六点整") == datetime.datetime(2025, 10, 9, 18, 0, 0, 0)
|
||
assert parser.parse("六点钟") == datetime.datetime(2025, 10, 9, 18, 0, 0, 0)
|
||
|
||
assert parser.parse("10 时") == datetime.datetime(2025, 10, 9, 10, 0, 0, 0)
|
||
assert parser.parse("10 时整") == datetime.datetime(2025, 10, 9, 10, 0, 0, 0)
|
||
assert parser.parse("10点") == datetime.datetime(2025, 10, 9, 22, 0, 0, 0)
|
||
assert parser.parse("10点整") == datetime.datetime(2025, 10, 9, 22, 0, 0, 0)
|
||
|
||
assert parser.parse("13点") == datetime.datetime(2025, 10, 9, 13, 0, 0, 0)
|
||
assert parser.parse("15点") == datetime.datetime(2025, 10, 9, 15, 0, 0, 0)
|
||
assert parser.parse("13 时") == datetime.datetime(2025, 10, 9, 13, 0, 0, 0)
|
||
assert parser.parse("15 时") == datetime.datetime(2025, 10, 9, 15, 0, 0, 0)
|
||
|
||
assert parser.parse("四点") == datetime.datetime(2025, 10, 9, 16, 0, 0, 0)
|
||
|
||
assert parser.parse("上午十点") == datetime.datetime(2025, 10, 9, 10, 0, 0, 0)
|
||
assert parser.parse("早晨十点") == datetime.datetime(2025, 10, 9, 10, 0, 0, 0)
|
||
assert parser.parse("早上十点") == datetime.datetime(2025, 10, 9, 10, 0, 0, 0)
|
||
assert parser.parse("早十") == datetime.datetime(2025, 10, 9, 10, 0, 0, 0)
|
||
assert parser.parse("早八") == datetime.datetime(2025, 10, 9, 8, 0, 0, 0)
|
||
assert parser.parse("晚六") == datetime.datetime(2025, 10, 9, 18, 0, 0, 0)
|
||
assert parser.parse("下午三点") == datetime.datetime(2025, 10, 9, 15, 0, 0, 0)
|
||
|
||
assert parser.parse("晚上十二点") == datetime.datetime(2025, 10, 10, 0, 0, 0, 0)
|
||
assert parser.parse("晚上八点") == datetime.datetime(2025, 10, 9, 20, 0, 0, 0)
|
||
assert parser.parse("凌晨零点") == datetime.datetime(2025, 10, 9, 0, 0, 0, 0)
|
||
assert parser.parse("中午十二点") == datetime.datetime(2025, 10, 9, 12, 0, 0, 0)
|
||
|
||
def test_hour_specification_am():
|
||
parser = Parser(now=datetime.datetime(2025, 10, 9, 2, 34, 1, 114))
|
||
|
||
assert parser.parse("五点") == datetime.datetime(2025, 10, 9, 5, 0, 0, 0)
|
||
assert parser.parse("5点") == datetime.datetime(2025, 10, 9, 5, 0, 0, 0)
|
||
assert parser.parse("5 点") == datetime.datetime(2025, 10, 9, 5, 0, 0, 0)
|
||
|
||
assert parser.parse("六点") == datetime.datetime(2025, 10, 9, 6, 0, 0, 0)
|
||
assert parser.parse("六点整") == datetime.datetime(2025, 10, 9, 6, 0, 0, 0)
|
||
assert parser.parse("六点钟") == datetime.datetime(2025, 10, 9, 6, 0, 0, 0)
|
||
|
||
assert parser.parse("10 时") == datetime.datetime(2025, 10, 9, 10, 0, 0, 0)
|
||
assert parser.parse("10 时整") == datetime.datetime(2025, 10, 9, 10, 0, 0, 0)
|
||
assert parser.parse("10点") == datetime.datetime(2025, 10, 9, 10, 0, 0, 0)
|
||
assert parser.parse("10点整") == datetime.datetime(2025, 10, 9, 10, 0, 0, 0)
|
||
|
||
assert parser.parse("四点") == datetime.datetime(2025, 10, 9, 4, 0, 0, 0)
|
||
assert parser.parse("一点钟") == datetime.datetime(2025, 10, 9, 13, 0, 0, 0)
|
||
|
||
|
||
def test_hour_with_minute():
|
||
parser = Parser(now=datetime.datetime(2025, 10, 9, 16, 34, 1, 114))
|
||
|
||
assert parser.parse("六点半") == datetime.datetime(2025, 10, 9, 18, 30, 0, 0)
|
||
assert parser.parse("六点半钟") == datetime.datetime(2025, 10, 9, 18, 30, 0, 0)
|
||
assert parser.parse("六点一刻") == datetime.datetime(2025, 10, 9, 18, 15, 0, 0)
|
||
assert parser.parse("六点过一刻") == datetime.datetime(2025, 10, 9, 18, 15, 0, 0)
|
||
|
||
|
||
def test_error():
|
||
parser = Parser(now=datetime.datetime(2025, 10, 9, 16, 34, 1, 114))
|
||
|
||
with pytest.raises(TokenUnhandledException):
|
||
parser.parse("六点半整")
|
||
|
||
with pytest.raises(MultipleSpecificationException):
|
||
parser.parse("六点半一刻")
|
||
|
||
|
||
def test_absolute_date():
|
||
now = datetime.datetime(2025, 10, 9, 16, 34, 1, 114)
|
||
parser = Parser(now=now)
|
||
# 完整年月日
|
||
assert parser.parse("2025年10月9日") == datetime.datetime(2025, 10, 9, 0, 0, 0, 0)
|
||
assert parser.parse("2025-10-09") == datetime.datetime(2025, 10, 9, 0, 0, 0, 0)
|
||
assert parser.parse("2025/10/09") == datetime.datetime(2025, 10, 9, 0, 0, 0, 0)
|
||
# 仅月日(默认今年)
|
||
assert parser.parse("10月9日") == datetime.datetime(2025, 10, 9, 0, 0, 0, 0)
|
||
assert parser.parse("十月九日") == datetime.datetime(2025, 10, 9, 0, 0, 0, 0)
|
||
# 年月日 + 时间
|
||
assert parser.parse("2025年10月9日 15点") == datetime.datetime(2025, 10, 9, 15, 0, 0, 0)
|
||
assert parser.parse("10月9日 下午3点") == datetime.datetime(2025, 10, 9, 15, 0, 0, 0)
|
||
assert parser.parse("十月九日 晚上八点") == datetime.datetime(2025, 10, 9, 20, 0, 0, 0)
|
||
# ISO 格式(如果支持)
|
||
assert parser.parse("2025-10-09T15:30") == datetime.datetime(2025, 10, 9, 15, 30, 0, 0)
|
||
|
||
|
||
def test_relative_date():
|
||
now = datetime.datetime(2025, 10, 9, 10, 0, 0)
|
||
parser = Parser(now=now)
|
||
assert parser.parse("明天") == datetime.datetime(2025, 10, 10, 0, 0, 0, 0)
|
||
assert parser.parse("后天") == datetime.datetime(2025, 10, 11, 0, 0, 0, 0)
|
||
assert parser.parse("昨天") == datetime.datetime(2025, 10, 8, 0, 0, 0, 0)
|
||
assert parser.parse("大前天") == datetime.datetime(2025, 10, 6, 0, 0, 0, 0)
|
||
assert parser.parse("大后天") == datetime.datetime(2025, 10, 12, 0, 0, 0, 0)
|
||
|
||
assert parser.parse("三天后") == datetime.datetime(2025, 10, 12, 0, 0, 0, 0)
|
||
assert parser.parse("五天前") == datetime.datetime(2025, 10, 4, 0, 0, 0, 0)
|
||
|
||
assert parser.parse("下周一") == datetime.datetime(2025, 10, 13, 0, 0, 0, 0)
|
||
assert parser.parse("上周五") == datetime.datetime(2025, 10, 3, 0, 0, 0, 0)
|
||
assert parser.parse("本周五") == datetime.datetime(2025, 10, 10, 0, 0, 0, 0)
|
||
|
||
end_of_month = datetime.datetime(2025, 10, 31, 10, 0, 0)
|
||
parser2 = Parser(now=end_of_month)
|
||
assert parser2.parse("两天后") == datetime.datetime(2025, 11, 2, 0, 0, 0, 0)
|
||
|
||
|
||
def test_relative_time():
|
||
now = datetime.datetime(2025, 10, 9, 16, 30, 0, 0)
|
||
parser = Parser(now=now)
|
||
|
||
assert parser.parse("五分钟后") == datetime.datetime(2025, 10, 9, 16, 35, 0, 0)
|
||
assert parser.parse("十分钟前") == datetime.datetime(2025, 10, 9, 16, 20, 0, 0)
|
||
assert parser.parse("半小时后") == datetime.datetime(2025, 10, 9, 17, 0, 0, 0)
|
||
assert parser.parse("一个半小时后") == datetime.datetime(2025, 10, 9, 18, 0, 0, 0)
|
||
|
||
assert parser.parse("两小时后") == datetime.datetime(2025, 10, 9, 18, 30, 0, 0)
|
||
assert parser.parse("一小时前") == datetime.datetime(2025, 10, 9, 15, 30, 0, 0)
|
||
|
||
late_night = datetime.datetime(2025, 10, 9, 23, 50, 0, 0)
|
||
parser3 = Parser(now=late_night)
|
||
assert parser3.parse("二十分钟后") == datetime.datetime(2025, 10, 10, 0, 10, 0, 0)
|
||
|
||
assert parser.parse("5分钟后") == datetime.datetime(2025, 10, 9, 16, 35, 0, 0)
|
||
assert parser.parse("三十分钟前") == datetime.datetime(2025, 10, 9, 16, 0, 0, 0)
|
||
|
||
|
||
|
||
def test_robustness_edge_cases():
|
||
parser = Parser(now=datetime.datetime(2025, 2, 28, 10, 0, 0))
|
||
|
||
assert parser.parse("明天") == datetime.datetime(2025, 3, 1, 0, 0, 0, 0)
|
||
|
||
parser_leap = Parser(now=datetime.datetime(2024, 2, 28, 10, 0, 0))
|
||
assert parser_leap.parse("两天后") == datetime.datetime(2024, 3, 1, 0, 0, 0, 0)
|
||
|
||
with pytest.raises(TokenUnhandledException):
|
||
parser.parse("随便乱写")
|
||
parser.parse(" 明天 ")
|
||
|
||
def test_mixed_expressions():
|
||
now = datetime.datetime(2025, 10, 9, 14, 0, 0)
|
||
parser = Parser(now=now)
|
||
# 如“明天下午三点”
|
||
assert parser.parse("明天下午三点") == datetime.datetime(2025, 10, 10, 15, 0, 0, 0)
|
||
assert parser.parse("后天早上八点") == datetime.datetime(2025, 10, 11, 8, 0, 0, 0)
|
||
assert parser.parse("大后天晚上十点") == datetime.datetime(2025, 10, 12, 22, 0, 0, 0)
|
||
# “下周三上午”
|
||
# 2025-10-09 是周四,下周三是 2025-10-15
|
||
assert parser.parse("下周三") == datetime.datetime(2025, 10, 15, 0, 0, 0, 0)
|
||
assert parser.parse("下周三早八") == datetime.datetime(2025, 10, 15, 8, 0, 0, 0) # 默认0点?或上午9点?需根据实现
|
||
# 若实现中“上午”不指定小时则设为9点,可调整;这里假设设为0点以简化
|