Files
AstrBot/tests/unit/test_command_parser.py
LIghtJUNction 169a856a3a test: mass-coverage push — ~1000+ new unit tests
Coverage improvements:
- agent/tool/core: 150+ tests (FunctionTool, ToolSet, ToolSchema, run_context, messages, registry)
- provider: 152 tests (entities, Provider ABC, register, manager)
- star module: 58 tests (Context, PluginManager, StarHandler)
- platform: 71 tests (Platform ABC, manager, MessageSession)
- pipeline: 130 tests (process/respond stages, scheduler, bootstrap, conversation_mgr)
- kb+skills: 96 tests (mgr, helpers, chunkers, skill_manager)
- config+builtins: 92 tests (astrbot_config, config_mgr, default, LTM, star main)
- cron+db+event_bus: 89 tests (cron events/manager, PO models, BaseDatabase, EventBus)
- dashboard routes: expanded smoke tests for all route modules
2026-04-29 08:40:26 +08:00

98 lines
3.4 KiB
Python

"""Unit tests for astrbot.core.utils.command_parser.
Covers CommandTokens data-holder and CommandParserMixin parse/regex helpers.
"""
from astrbot.core.utils.command_parser import CommandParserMixin, CommandTokens
# ---------------------------------------------------------------------------
# CommandTokens
# ---------------------------------------------------------------------------
class TestCommandTokens:
def test_default_attributes(self):
tokens = CommandTokens()
assert tokens.tokens == []
assert tokens.len == 0
def test_get_returns_none_for_out_of_bounds_negative(self):
tokens = CommandTokens()
assert tokens.get(-1) is None
def test_get_returns_none_for_out_of_bounds_positive(self):
tokens = CommandTokens()
tokens.tokens = ["a", "b"]
tokens.len = 2
assert tokens.get(2) is None
assert tokens.get(100) is None
def test_get_returns_stripped_token(self):
tokens = CommandTokens()
tokens.tokens = [" hello ", "world "]
tokens.len = 2
assert tokens.get(0) == "hello"
assert tokens.get(1) == "world"
def test_get_from_empty_list(self):
tokens = CommandTokens()
tokens.tokens = []
tokens.len = 0
assert tokens.get(0) is None
# ---------------------------------------------------------------------------
# CommandParserMixin
# ---------------------------------------------------------------------------
class _ConcreteParser(CommandParserMixin):
"""Minimal concrete subclass so the mixin can be instantiated."""
class TestCommandParserMixin:
def setup_method(self) -> None:
self.parser = _ConcreteParser()
def test_parse_commands_returns_command_tokens(self):
result = self.parser.parse_commands("hello world")
assert isinstance(result, CommandTokens)
assert result.len == 2
def test_parse_commands_splits_on_whitespace(self):
result = self.parser.parse_commands("one two\tthree\nfour")
assert result.tokens == ["one", "two", "three", "four"]
assert result.len == 4
def test_parse_commands_empty_string_yields_single_empty_token(self):
result = self.parser.parse_commands("")
assert result.tokens == [""]
assert result.len == 1
def test_parse_commands_only_whitespace(self):
result = self.parser.parse_commands(" \t \n ")
assert result.tokens == ["", ""] # \S+ splits on whitespace runs
# Actually re.split(r"\s+", " \t \n ") = ['', '']
def test_regex_match_returns_true_on_match(self):
assert self.parser.regex_match("hello world", "hello") is True
def test_regex_match_returns_false_on_no_match(self):
assert self.parser.regex_match("hello world", "goodbye") is False
def test_regex_match_multiline(self):
text = "line1\nline2\nline3"
assert self.parser.regex_match(text, "^line2$") is True
def test_regex_match_with_digits(self):
assert self.parser.regex_match("abc123def", r"\d+") is True
def test_regex_match_with_special_regex_chars(self):
"""Special regex characters should be treated as regex, not literal."""
assert self.parser.regex_match("price is 10.50", r"\d+\.\d+") is True
def test_regex_match_empty_pattern(self):
"""An empty pattern matches any string (re.search always finds '')."""
assert self.parser.regex_match("anything", "") is True