mirror of
https://github.com/AstrBotDevs/AstrBot
synced 2026-07-16 01:40:15 +08:00
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
98 lines
3.4 KiB
Python
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
|