#!/usr/bin/env python3 import sys import unittest from pathlib import Path PROJECT_ROOT = Path(__file__).resolve().parents[1] OFFICIAL_SRC = ( PROJECT_ROOT / "packages" / "jwebot-official-extensions" / "src" ) SDK_SRC = PROJECT_ROOT / "packages" / "jwebot-sdk" / "src" sys.path[:0] = [str(SDK_SRC), str(OFFICIAL_SRC)] from jwebot_official_extensions import ( # noqa: E402 DIRECT_KERNEL_COMMAND_KINDS, JWEBOT_AUTHOR, LOCAL_COMMAND_ALIASES, LOCAL_EXTENSIONS, OFFICIAL_AUTHOR, extension_for_kind, render_feature_list, ) class LocalExtensionInventoryTests(unittest.TestCase): def test_every_command_kind_is_direct_or_has_exactly_one_owner(self): expected = set(LOCAL_COMMAND_ALIASES.values()) owned = [ kind for extension in LOCAL_EXTENSIONS for kind in extension.command_kinds ] self.assertEqual( set(owned) | set(DIRECT_KERNEL_COMMAND_KINDS), expected, ) self.assertEqual(len(owned), len(set(owned))) self.assertFalse(set(owned) & set(DIRECT_KERNEL_COMMAND_KINDS)) def test_every_alias_is_exposed_by_its_owner(self): for alias, kind in LOCAL_COMMAND_ALIASES.items(): with self.subTest(alias=alias, kind=kind): owner = extension_for_kind(kind) if kind in DIRECT_KERNEL_COMMAND_KINDS: self.assertIsNone(owner) continue self.assertIsNotNone(owner) assert owner is not None self.assertIn(f"/{alias}", owner.commands) def test_extension_ids_and_commands_do_not_collide(self): ids = [extension.extension_id for extension in LOCAL_EXTENSIONS] commands = [ command.casefold() for extension in LOCAL_EXTENSIONS for command in extension.commands ] self.assertEqual(len(ids), len(set(ids))) self.assertEqual(len(commands), len(set(commands))) def test_help_is_generated_from_every_plugin_description(self): help_text = render_feature_list() self.assertLessEqual(len(help_text), 900) for extension in LOCAL_EXTENSIONS: with self.subTest(extension=extension.extension_id): self.assertTrue(extension.description) self.assertTrue(extension.help_entries) self.assertIn(extension.description, help_text) for entry in extension.help_entries: self.assertIn(entry, help_text) def test_expected_granular_plugins_and_authors_are_present(self): self.assertEqual( { extension.extension_id: extension.author for extension in LOCAL_EXTENSIONS }, { "context-summary": OFFICIAL_AUTHOR, "person-directory": OFFICIAL_AUTHOR, "single-player-games": JWEBOT_AUTHOR, "cs-major-autochess": JWEBOT_AUTHOR, "person-memory": OFFICIAL_AUTHOR, "server-status": OFFICIAL_AUTHOR, "jwebot-version": OFFICIAL_AUTHOR, "debug-telemetry": OFFICIAL_AUTHOR, "dice": JWEBOT_AUTHOR, "coin": JWEBOT_AUTHOR, "coin-transfer": JWEBOT_AUTHOR, "coin-ranking": JWEBOT_AUTHOR, "coin-loan": JWEBOT_AUTHOR, "random-number": JWEBOT_AUTHOR, "draw-lot": JWEBOT_AUTHOR, "daily-fortune": JWEBOT_AUTHOR, "guess-number": JWEBOT_AUTHOR, "rock-paper-scissors": JWEBOT_AUTHOR, "scan-ranking": JWEBOT_AUTHOR, "repeat-ranking": JWEBOT_AUTHOR, "history-search": JWEBOT_AUTHOR, "steam-presence": JWEBOT_AUTHOR, }, ) def test_only_approved_collections_combine_function_kinds(self): combined = { extension.extension_id: extension.command_kinds for extension in LOCAL_EXTENSIONS if len(extension.command_kinds) > 1 } self.assertEqual( combined, { "single-player-games": ( "wallet", "prize_draw", "lottery", "blackjack", "game_history", "game_rules", ), "person-directory": ("person_directory", "person_info"), "person-memory": ( "remember", "my_memory", "forget_memory", "person_memory", "memory_help", ), "coin-loan": ("loan", "repay"), "server-status": ("local_status", "server_status"), "dice": ("dice", "dice_challenge"), }, ) def test_kernel_direct_commands_are_not_plugins(self): self.assertEqual( DIRECT_KERNEL_COMMAND_KINDS, frozenset( { "feature_list", "deepseek_balance", } ), ) if __name__ == "__main__": unittest.main()