Fix punctuation match order and add tests
authorJeremy Stanley <fungi@yuggoth.org>
Tue, 2 Jun 2015 06:08:02 +0000 (06:08 +0000)
committerJeremy Stanley <fungi@yuggoth.org>
Tue, 2 Jun 2015 06:08:02 +0000 (06:08 +0000)
Add explicit punctuation functional tests with a conversation
between the two test sessions, and fix a nondeterministic bug this
exposed. Punctuation is now matched in a sorted order rather than
arbitrary hash table lookup order, and the sort is reversed so that
the longest match always wins.

bin/test
lib/mudpy/misc.py

index 23eaf35..35b2a99 100755 (executable)
--- a/bin/test
+++ b/bin/test
@@ -34,6 +34,25 @@ dialogue = (
     # Actor appears from nowhere
     (0, "You suddenly realize that .* is here\.", ""),
 
+    # Explicit punctuation
+    (0, "> ", "say Hello there!"),
+    (0, 'You exclaim, "Hello there\!"', ""),
+    (1, 'exclaims, "Hello there\!"', "say And you are?"),
+    (1, 'You ask, "And you are\?"', ""),
+    (0, 'asks, "And you are\?"', "say I'm me, of course."),
+    (0, 'You say, "I\'m me, of course\."', ""),
+    (1, 'says, "I\'m me, of course\."', "say I wouldn't be so sure..."),
+    (1, 'You muse, "I wouldn\'t be so sure\.\.\."', ""),
+    (0, 'muses, "I wouldn\'t be so sure\.\.\."', "say You mean,"),
+    (0, 'You begin, "You mean,"', ""),
+    (1, 'begins, "You mean,"', "say I know-"),
+    (1, 'You begin, "I know-"', ""),
+    (0, 'begins, "I know-"', "say Don't interrupt:"),
+    (0, 'You begin, "Don\'t interrupt:"', ""),
+    (1, 'begins, "Don\'t interrupt:"', "say I wasn't interrupting;"),
+    (1, 'You begin, "I wasn\'t interrupting;"', ""),
+    (0, 'begins, "I wasn\'t interrupting;"', ""),
+
     # Actor disappears
     (1, "> ", "quit"),
     (0, "You suddenly wonder where .* went\.", ""),
index 0843586..ea18ffb 100644 (file)
@@ -2043,7 +2043,9 @@ def command_say(actor, parameters):
             universe.categories["internal"]["language"].get(
                 "default_punctuation"))
         action = ""
-        for mark in actions.keys():
+
+        # reverse sort punctuation options so the longest match wins
+        for mark in sorted(actions.keys(), reverse=True):
             if not literal and message.endswith(mark):
                 action = actions[mark]
                 break