Final unit tests for evmenu templating
This commit is contained in:
parent
a94e723d6b
commit
1746aaf06b
3 changed files with 77 additions and 30 deletions
|
|
@ -290,10 +290,20 @@ def goto_command_demo_room(caller, raw_string, **kwargs):
|
||||||
_maintain_demo_room(caller)
|
_maintain_demo_room(caller)
|
||||||
caller.cmdset.remove(DemoCommandSetHelp)
|
caller.cmdset.remove(DemoCommandSetHelp)
|
||||||
caller.cmdset.remove(DemoCommandSetComms)
|
caller.cmdset.remove(DemoCommandSetComms)
|
||||||
caller.cmdset.add(DemoCommandSetRoom) # TODO - make persistent
|
caller.cmdset.add(DemoCommandSetRoom)
|
||||||
return "command_demo_room"
|
return "command_demo_room"
|
||||||
|
|
||||||
|
|
||||||
|
def goto_cleanup_cmdsets(caller, raw_strings, **kwargs):
|
||||||
|
"""
|
||||||
|
Cleanup all cmdsets.
|
||||||
|
"""
|
||||||
|
caller.cmdset.remove(DemoCommandSetHelp)
|
||||||
|
caller.cmdset.remove(DemoCommandSetComms)
|
||||||
|
caller.cmdset.remove(DemoCommandSetRoom)
|
||||||
|
return kwargs.get("gotonode")
|
||||||
|
|
||||||
|
|
||||||
# register all callables that can be used in the menu template
|
# register all callables that can be used in the menu template
|
||||||
|
|
||||||
GOTO_CALLABLES = {
|
GOTO_CALLABLES = {
|
||||||
|
|
@ -302,6 +312,7 @@ GOTO_CALLABLES = {
|
||||||
"goto_command_demo_help": goto_command_demo_help,
|
"goto_command_demo_help": goto_command_demo_help,
|
||||||
"goto_command_demo_comms": goto_command_demo_comms,
|
"goto_command_demo_comms": goto_command_demo_comms,
|
||||||
"goto_command_demo_room": goto_command_demo_room,
|
"goto_command_demo_room": goto_command_demo_room,
|
||||||
|
"goto_cleanup_cmdsets": goto_cleanup_cmdsets,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -365,7 +376,7 @@ gaming style you like and possibly any new ones you can come up with!
|
||||||
## OPTIONS
|
## OPTIONS
|
||||||
|
|
||||||
next;n: About Evennia -> about_evennia
|
next;n: About Evennia -> about_evennia
|
||||||
back to start;start;t: start
|
back to start;back;start;t: start
|
||||||
>: about_evennia
|
>: about_evennia
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------------
|
||||||
|
|
@ -498,7 +509,7 @@ those channels ...
|
||||||
## OPTIONS
|
## OPTIONS
|
||||||
|
|
||||||
next;n: Talk on Channels -> talk on channels
|
next;n: Talk on Channels -> talk on channels
|
||||||
back;b: Using the webclient -> using webclient
|
back;b: Using the webclient -> goto_cleanup_cmdsets(gotonode='using webclient')
|
||||||
back to start;start: start
|
back to start;start: start
|
||||||
>: talk on channels
|
>: talk on channels
|
||||||
|
|
||||||
|
|
@ -556,7 +567,7 @@ include other people/objects in the emote, reference things by a short-descripti
|
||||||
## OPTIONS
|
## OPTIONS
|
||||||
|
|
||||||
next;n: Paging people -> paging_people
|
next;n: Paging people -> paging_people
|
||||||
back;b: Talk on Channels -> talk on channels
|
back;b: Talk on Channels -> goto_command_demo_help(gotonode='talk on channels')
|
||||||
back to start;start: start
|
back to start;start: start
|
||||||
>: paging_people
|
>: paging_people
|
||||||
|
|
||||||
|
|
@ -627,7 +638,7 @@ color codes printed, try
|
||||||
## OPTIONS
|
## OPTIONS
|
||||||
|
|
||||||
next;n: Moving and Exploring -> goto_command_demo_room()
|
next;n: Moving and Exploring -> goto_command_demo_room()
|
||||||
back;b: Paging people -> paging_people
|
back;b: Paging people -> goto_command_demo_comms(gotonode='paging_people')
|
||||||
back to start;start: start
|
back to start;start: start
|
||||||
>: goto_command_demo_room()
|
>: goto_command_demo_room()
|
||||||
|
|
||||||
|
|
@ -650,7 +661,7 @@ around in. Explore a little and use |ynext|n when you are done.
|
||||||
## OPTIONS
|
## OPTIONS
|
||||||
|
|
||||||
next;n: Conclusions -> conclusions
|
next;n: Conclusions -> conclusions
|
||||||
back;b: Channel commands -> testing_colors
|
back;b: Channel commands -> goto_command_demo_comms(gotonode='testing_colors')
|
||||||
back to start;start: start
|
back to start;start: start
|
||||||
>: conclusions
|
>: conclusions
|
||||||
|
|
||||||
|
|
@ -667,13 +678,11 @@ if you get stuck!
|
||||||
Write |ynext|n to end this wizard and continue to the tutorial-world quest!
|
Write |ynext|n to end this wizard and continue to the tutorial-world quest!
|
||||||
If you want there is also some |wextra|n info for where to go beyond that.
|
If you want there is also some |wextra|n info for where to go beyond that.
|
||||||
|
|
||||||
Good luck!
|
|
||||||
|
|
||||||
## OPTIONS
|
## OPTIONS
|
||||||
|
|
||||||
extra: Some more help on where to go next -> post scriptum
|
extra: Where to go next -> post scriptum
|
||||||
next;next;n: end
|
next;next;n: End -> end
|
||||||
back;b: goto_command_demo_room()
|
back;b: Moving and Exploring -> goto_command_demo_room()
|
||||||
back to start;start: start
|
back to start;start: start
|
||||||
>: end
|
>: end
|
||||||
|
|
||||||
|
|
@ -718,7 +727,7 @@ back: conclusions
|
||||||
|
|
||||||
## NODE end
|
## NODE end
|
||||||
|
|
||||||
Thanks for trying out the tutorial!
|
|gGood luck!|n
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1634,7 +1634,7 @@ _RE_NODE = re.compile(r"##\s*?NODE\s+?(?P<nodename>\S[\S\s]*?)$", re.I + re.M)
|
||||||
_RE_OPTIONS_SEP = re.compile(r"##\s*?OPTIONS\s*?$", re.I + re.M)
|
_RE_OPTIONS_SEP = re.compile(r"##\s*?OPTIONS\s*?$", re.I + re.M)
|
||||||
_RE_CALLABLE = re.compile(r"\S+?\(\)", re.I + re.M)
|
_RE_CALLABLE = re.compile(r"\S+?\(\)", re.I + re.M)
|
||||||
_RE_CALLABLE = re.compile(
|
_RE_CALLABLE = re.compile(
|
||||||
r"(?P<funcname>\S+?)(?:\((?P<kwargs>[\S\s]+?=[\S\s]+?)\)|\(\))", re.I + re.M
|
r"(?P<funcname>\S+?)(?:\((?P<kwargs>[\S\s]+?)\)|\(\))", re.I + re.M
|
||||||
)
|
)
|
||||||
|
|
||||||
_HELP_NO_OPTION_MATCH = _("Choose an option or try 'help'.")
|
_HELP_NO_OPTION_MATCH = _("Choose an option or try 'help'.")
|
||||||
|
|
@ -1664,13 +1664,12 @@ def _process_callable(caller, goto, goto_callables, raw_string,
|
||||||
gotokwargs = match.group("kwargs") or ""
|
gotokwargs = match.group("kwargs") or ""
|
||||||
if gotofunc in goto_callables:
|
if gotofunc in goto_callables:
|
||||||
for kwarg in gotokwargs.split(","):
|
for kwarg in gotokwargs.split(","):
|
||||||
if kwarg and "=" in kwarg:
|
|
||||||
key, value = [part.strip() for part in kwarg.split("=", 1)]
|
key, value = [part.strip() for part in kwarg.split("=", 1)]
|
||||||
if key in ("evmenu_goto", "evmenu_gotomap", "_current_nodename",
|
if key in ("evmenu_goto", "evmenu_gotomap", "_current_nodename",
|
||||||
"evmenu_current_nodename", "evmenu_goto_callables"):
|
"evmenu_current_nodename", "evmenu_goto_callables"):
|
||||||
raise RuntimeError(
|
raise RuntimeError(
|
||||||
f"EvMenu template error: goto-callable '{goto}' uses a "
|
f"EvMenu template error: goto-callable '{goto}' uses a "
|
||||||
f"kwarg ({key}) that is reserved for the EvMenu templating "
|
f"kwarg ({kwarg}) that is reserved for the EvMenu templating "
|
||||||
"system. Rename the kwarg.")
|
"system. Rename the kwarg.")
|
||||||
try:
|
try:
|
||||||
key = literal_eval(key)
|
key = literal_eval(key)
|
||||||
|
|
@ -1681,6 +1680,7 @@ def _process_callable(caller, goto, goto_callables, raw_string,
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
kwargs[key] = value
|
kwargs[key] = value
|
||||||
|
|
||||||
goto = goto_callables[gotofunc](caller, raw_string, **kwargs)
|
goto = goto_callables[gotofunc](caller, raw_string, **kwargs)
|
||||||
if goto is None:
|
if goto is None:
|
||||||
return goto, {"generated_nodename": current_nodename}
|
return goto, {"generated_nodename": current_nodename}
|
||||||
|
|
@ -1755,6 +1755,23 @@ def parse_menu_template(caller, menu_template, goto_callables=None):
|
||||||
dict: A `{"node": nodefunc}` menutree suitable to pass into EvMenu.
|
dict: A `{"node": nodefunc}` menutree suitable to pass into EvMenu.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
def _validate_kwarg(goto, kwarg):
|
||||||
|
"""
|
||||||
|
Validate goto-callable kwarg is on correct form.
|
||||||
|
"""
|
||||||
|
if not "=" in kwarg:
|
||||||
|
raise RuntimeError(
|
||||||
|
f"EvMenu template error: goto-callable '{goto}' has a "
|
||||||
|
f"non-kwarg argument ({kwarg}). All callables in the "
|
||||||
|
"template must have only keyword-arguments, or no "
|
||||||
|
"args at all.")
|
||||||
|
key, _ = [part.strip() for part in kwarg.split("=", 1)]
|
||||||
|
if key in ("evmenu_goto", "evmenu_gotomap", "_current_nodename",
|
||||||
|
"evmenu_current_nodename", "evmenu_goto_callables"):
|
||||||
|
raise RuntimeError(
|
||||||
|
f"EvMenu template error: goto-callable '{goto}' uses a "
|
||||||
|
f"kwarg ({kwarg}) that is reserved for the EvMenu templating "
|
||||||
|
"system. Rename the kwarg.")
|
||||||
|
|
||||||
def _parse_options(nodename, optiontxt, goto_callables):
|
def _parse_options(nodename, optiontxt, goto_callables):
|
||||||
"""
|
"""
|
||||||
|
|
@ -1779,6 +1796,14 @@ def parse_menu_template(caller, menu_template, goto_callables=None):
|
||||||
if _OPTION_CALL_MARKER in goto:
|
if _OPTION_CALL_MARKER in goto:
|
||||||
desc, goto = [part.strip() for part in goto.split(_OPTION_CALL_MARKER, 1)]
|
desc, goto = [part.strip() for part in goto.split(_OPTION_CALL_MARKER, 1)]
|
||||||
|
|
||||||
|
# validate callable
|
||||||
|
match = _RE_CALLABLE.match(goto)
|
||||||
|
if match:
|
||||||
|
kwargs = match.group("kwargs")
|
||||||
|
if kwargs:
|
||||||
|
for kwarg in kwargs.split(','):
|
||||||
|
_validate_kwarg(goto, kwarg)
|
||||||
|
|
||||||
# parse key [;aliases|pattern]
|
# parse key [;aliases|pattern]
|
||||||
key = [part.strip() for part in key.split(_OPTION_ALIAS_MARKER)]
|
key = [part.strip() for part in key.split(_OPTION_ALIAS_MARKER)]
|
||||||
if not key:
|
if not key:
|
||||||
|
|
|
||||||
|
|
@ -327,3 +327,16 @@ class TestMenuTemplateParse(EvenniaTest):
|
||||||
|
|
||||||
def test_template2menu(self):
|
def test_template2menu(self):
|
||||||
evmenu.template2menu(self.char1, self.menu_template, self.goto_callables)
|
evmenu.template2menu(self.char1, self.menu_template, self.goto_callables)
|
||||||
|
|
||||||
|
def test_parse_menu_fail(self):
|
||||||
|
template = """
|
||||||
|
## NODE
|
||||||
|
|
||||||
|
Text
|
||||||
|
|
||||||
|
## OPTIONS
|
||||||
|
|
||||||
|
next: callnode2(invalid)
|
||||||
|
"""
|
||||||
|
with self.assertRaises(RuntimeError):
|
||||||
|
evmenu.parse_menu_template(self.char1, template, self.goto_callables)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue