94 lines
3.2 KiB
Python
94 lines
3.2 KiB
Python
#!/usr/bin/env python3
|
|
|
|
import sys
|
|
import unittest
|
|
from pathlib import Path
|
|
|
|
|
|
PROJECT_ROOT = Path(__file__).resolve().parents[1]
|
|
SDK_SRC = PROJECT_ROOT / "packages" / "jwebot-sdk" / "src"
|
|
KERNEL_SRC = PROJECT_ROOT / "packages" / "jwebot-kernel" / "src"
|
|
sys.path[:0] = [str(SDK_SRC), str(KERNEL_SRC)]
|
|
|
|
from jwebot_kernel import ( # noqa: E402
|
|
CatalogError,
|
|
ExtensionCatalog,
|
|
parse_manifest,
|
|
)
|
|
|
|
|
|
def manifest(plugin_id: str, command: str):
|
|
module_name = plugin_id.replace("-", "_")
|
|
return parse_manifest(
|
|
{
|
|
"id": plugin_id,
|
|
"author": "tester",
|
|
"description": f"Handle {command}",
|
|
"help": [command],
|
|
"version": "1.0.0",
|
|
"api_version": "1",
|
|
"entrypoint": f"{module_name}:plugin",
|
|
"type": "command",
|
|
"capabilities": {
|
|
"commands": [command],
|
|
"storage": False,
|
|
"network_profiles": [],
|
|
},
|
|
}
|
|
)
|
|
|
|
|
|
class ExtensionCatalogTests(unittest.TestCase):
|
|
def test_registration_is_open_then_frozen(self):
|
|
catalog = ExtensionCatalog()
|
|
catalog.register(manifest("hello-command", "/hello"))
|
|
self.assertFalse(catalog.frozen)
|
|
catalog.freeze()
|
|
self.assertTrue(catalog.frozen)
|
|
with self.assertRaisesRegex(CatalogError, "frozen"):
|
|
catalog.register(manifest("weather-command", "/weather"))
|
|
|
|
def test_duplicate_plugin_id_is_rejected(self):
|
|
catalog = ExtensionCatalog()
|
|
catalog.register(manifest("hello-command", "/hello"))
|
|
with self.assertRaisesRegex(CatalogError, "duplicate plugin id"):
|
|
catalog.register(manifest("hello-command", "/hello2"))
|
|
|
|
def test_command_collision_is_rejected_case_insensitively(self):
|
|
catalog = ExtensionCatalog()
|
|
catalog.register(manifest("hello-command", "/Hello"))
|
|
with self.assertRaisesRegex(CatalogError, "already belongs"):
|
|
catalog.register(manifest("other-command", "/hello"))
|
|
|
|
def test_routing_requires_a_frozen_catalog(self):
|
|
catalog = ExtensionCatalog()
|
|
with self.assertRaisesRegex(CatalogError, "must be frozen"):
|
|
catalog.resolve_command("/hello")
|
|
|
|
def test_frozen_catalog_resolves_arguments(self):
|
|
catalog = ExtensionCatalog()
|
|
catalog.register(manifest("hello-command", "/hello"))
|
|
catalog.freeze()
|
|
match = catalog.resolve_command("/hello world")
|
|
self.assertIsNotNone(match)
|
|
assert match is not None
|
|
self.assertEqual(match.plugin_id, "hello-command")
|
|
self.assertEqual(match.command, "/hello")
|
|
self.assertEqual(match.arguments, "world")
|
|
|
|
def test_command_name_does_not_match_a_longer_token(self):
|
|
catalog = ExtensionCatalog()
|
|
catalog.register(manifest("hello-command", "/hello"))
|
|
catalog.freeze()
|
|
self.assertIsNone(catalog.resolve_command("/hello-world"))
|
|
|
|
def test_catalog_views_are_read_only(self):
|
|
catalog = ExtensionCatalog()
|
|
catalog.register(manifest("hello-command", "/hello"))
|
|
with self.assertRaises(TypeError):
|
|
catalog.commands["/other"] = "other-command" # type: ignore[index]
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|