~divmod-dev/divmod.org/trunk

« back to all changes in this revision

Viewing changes to Imaginary/ExampleGame/examplegame/test/test_japanese.py

  • Committer: Jean-Paul Calderone
  • Date: 2014-06-07 13:26:27 UTC
  • mfrom: (2741.2.2 1320678-remove-imaginary)
  • Revision ID: exarkun@twistedmatrix.com-20140607132627-jz2zhbk9jajamk43
Remove Imaginary.  Find it at <https://github.com/twisted/imaginary>.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
import weakref
2
 
 
3
 
from twisted.internet import task
4
 
from twisted.trial import unittest
5
 
 
6
 
from axiom import store
7
 
 
8
 
from imaginary import iimaginary, objects, events, action
9
 
 
10
 
from imaginary.test import commandutils
11
 
 
12
 
from examplegame import mice
13
 
from examplegame import japanese
14
 
 
15
 
class MouseChallengeMixin(object):
16
 
    """
17
 
    A mixin meant to be used in TestCases which want to assert things
18
 
    about mouse challenges.
19
 
 
20
 
    The subclass must be sure to provide a C{player} instance
21
 
    attribute, which is the L{IThing<iimaginary.IThing>} provider of
22
 
    the player which observes the mouse, and a C{mouseName} attribute
23
 
    which should be the mouse's name.
24
 
    """
25
 
    def assertChallenge(self, concept):
26
 
        """
27
 
        Assert that the given concept is a challenge from the mouse
28
 
        named self.mouseName, as observed by self.player.
29
 
        """
30
 
        said = commandutils.flatten(concept.plaintext(self.player))
31
 
        self.failUnless(said.startswith(u"A %s says, '" % (self.mouseName,)), repr(said))
32
 
        self.failUnlessIn(said[-3], japanese.hiragana)
33
 
        self.failUnless(said.endswith("'\n"), repr(said))
34
 
 
35
 
 
36
 
 
37
 
class HiraganaMouseTestCase(MouseChallengeMixin, unittest.TestCase):
38
 
    """
39
 
    Test that there is a mouse that says hiragana and stuff
40
 
    """
41
 
 
42
 
    def setUp(self):
43
 
        self.store = store.Store()
44
 
 
45
 
        self.clock = objects.Thing(store=self.store, name=u"Clock")
46
 
        self.clockContainer = objects.Container.createFor(self.clock, capacity=10)
47
 
 
48
 
        self.mouseName = u"\N{KATAKANA LETTER PI}\N{KATAKANA LETTER SMALL YU}"
49
 
        self.mouse = mice.createHiraganaMouse(
50
 
            store=self.store,
51
 
            name=self.mouseName)
52
 
        self.mouseActor = iimaginary.IActor(self.mouse)
53
 
        self.mousehood = self.mouseActor.getIntelligence()
54
 
        self.mouse.moveTo(self.clock)
55
 
 
56
 
        (self.player,
57
 
         self.playerActor,
58
 
         self.playerIntelligence) = commandutils.createPlayer(self.store,
59
 
                                                              u"Mean Old Man")
60
 
 
61
 
 
62
 
        self.player.moveTo(self.clock)
63
 
 
64
 
        self.reactorTime = task.Clock()
65
 
        self.mousehood._callLater = self.reactorTime.callLater
66
 
 
67
 
 
68
 
    def test_mouseCanSqueak(self):
69
 
        """
70
 
        When explicitly told to challenge with a given romaji syllable, the
71
 
        mouse should say a hiragana letter.
72
 
        """
73
 
        events.runEventTransaction(
74
 
            self.store,
75
 
            self.mousehood.challenge,
76
 
            character=u"\N{HIRAGANA LETTER A}")
77
 
 
78
 
        self.assertEquals(len(self.playerIntelligence.concepts), 1)
79
 
        event = self.playerIntelligence.concepts[0]
80
 
        self.assertEquals(
81
 
            commandutils.flatten(event.otherMessage.plaintext(self.player)),
82
 
            u"A %s says, '\N{HIRAGANA LETTER A}'" % (self.mouseName,))
83
 
 
84
 
 
85
 
    def test_randomHiragana(self):
86
 
        """
87
 
        When explicitly told to challenge without specifying a syllable, the
88
 
        mouse should say a random one.
89
 
        """
90
 
        events.runEventTransaction(self.store, self.mousehood.challenge)
91
 
        self.assertEquals(len(self.playerIntelligence.concepts), 1)
92
 
        event = self.playerIntelligence.concepts[0]
93
 
        self.assertChallenge(event)
94
 
 
95
 
 
96
 
    def test_ji(self):
97
 
        """
98
 
        Two hiragana characters map to the romaji 'ji'.  Test that we do the
99
 
        right thing for them.
100
 
        """
101
 
        self.mousehood.challenge(character=u"\N{HIRAGANA LETTER DI}")
102
 
        self.failUnless(self.mousehood.vetteChallengeResponse(u"ji"))
103
 
        self.mousehood.challenge(character=u"\N{HIRAGANA LETTER ZI}")
104
 
        self.failUnless(self.mousehood.vetteChallengeResponse(u"ji"))
105
 
 
106
 
 
107
 
    def test_zu(self):
108
 
        """
109
 
        Two hiragana characters map to the romaji 'zu'.  Test that we do the
110
 
        right thing for them.
111
 
        """
112
 
        self.mousehood.challenge(character=u"\N{HIRAGANA LETTER DU}")
113
 
        self.failUnless(self.mousehood.vetteChallengeResponse(u"zu"))
114
 
        self.mousehood.challenge(character=u"\N{HIRAGANA LETTER ZU}")
115
 
        self.failUnless(self.mousehood.vetteChallengeResponse(u"zu"))
116
 
 
117
 
 
118
 
    def test_mouseStartsChallengingWhenPlayersArrive(self):
119
 
        """
120
 
        When a player arrives, the mouse should go into the 'I am
121
 
        challenging' state.
122
 
        """
123
 
        # Whitebox
124
 
        self.assertEquals(self.mousehood.challenging, False)
125
 
 
126
 
        evt = events.ArrivalEvent(actor=self.player)
127
 
        self.mouseActor.send(evt)
128
 
 
129
 
        self.assertEquals(self.mousehood.challenging, True)
130
 
 
131
 
 
132
 
    def test_mouseSchedulesChallenges(self):
133
 
        """
134
 
        After telling a mouse to start challenging, it should schedule timed
135
 
        events to say challenges.
136
 
        """
137
 
        self.mousehood.startChallenging()
138
 
        self.reactorTime.advance(self.mousehood.challengeInterval)
139
 
        concepts = self.playerIntelligence.concepts
140
 
        self.assertEquals(len(concepts), 1)
141
 
        self.assertChallenge(concepts[0])
142
 
 
143
 
 
144
 
    def test_mouseStopsChallengingWhenPlayersLeave(self):
145
 
        """
146
 
        When the 'last' player leaves, the mouse stops challenging.
147
 
        """
148
 
        # Whitebox
149
 
        self.mousehood.startChallenging()
150
 
 
151
 
        evt = events.DepartureEvent(location=self.clock,
152
 
                                    actor=self.player)
153
 
        self.player.moveTo(None)
154
 
        self.mouseActor.send(evt)
155
 
 
156
 
        self.assertEquals(self.mousehood.challenging, False)
157
 
 
158
 
 
159
 
    def test_mouseStopsSchedulingChallenges(self):
160
 
        """
161
 
        When a mouse is told to stop challenging, it should cancel any
162
 
        challenges it had scheduled.
163
 
        """
164
 
        self.mousehood.startChallenging()
165
 
        self.mousehood.stopChallenging()
166
 
 
167
 
        self.reactorTime.advance(self.mousehood.challengeInterval)
168
 
        self.assertEquals(self.playerIntelligence.concepts, [])
169
 
 
170
 
 
171
 
    def test_stopChallengingWhenNotChallengingFails(self):
172
 
        """
173
 
        Don't stop challenging when you're not challenging.
174
 
        """
175
 
        self.assertRaises(mice.ChallengeVacuum, self.mousehood.stopChallenging)
176
 
 
177
 
 
178
 
    def test_startChallengingTwiceFails(self):
179
 
        """
180
 
        Don't start challenging twice.
181
 
        """
182
 
        self.mousehood.startChallenging()
183
 
        self.assertRaises(mice.ChallengeCollision, self.mousehood.startChallenging)
184
 
 
185
 
 
186
 
    def test_challengeRecurrence(self):
187
 
        """
188
 
        After a challenge is issued another one should be issued later.
189
 
        """
190
 
        self.mousehood.startChallenging()
191
 
        self.reactorTime.advance(self.mousehood.challengeInterval)
192
 
 
193
 
        self.assertIn(self.mousehood.getCurrentChallenge(), japanese.hiragana)
194
 
 
195
 
        self.mousehood._currentChallenge = None # Clear his challenge evilly
196
 
 
197
 
        self.reactorTime.advance(self.mousehood.challengeInterval)
198
 
 
199
 
        self.assertIn(self.mousehood.getCurrentChallenge(), japanese.hiragana)
200
 
 
201
 
 
202
 
    def test_twoMenEnter(self):
203
 
        """
204
 
        Test that when *TWO* players join, the mouse doesn't schedule too many
205
 
        challenges.
206
 
        """
207
 
        otherPlayer = commandutils.createPlayer(self.store,
208
 
                                                u"Polite Young Man")[0]
209
 
 
210
 
        # Send an arrival event because setUp doesn't
211
 
        firstEvent = events.ArrivalEvent(actor=self.player)
212
 
 
213
 
        self.mouseActor.send(firstEvent)
214
 
        otherPlayer.moveTo(self.clock, arrivalEventFactory=events.MovementArrivalEvent)
215
 
 
216
 
        self.playerIntelligence.concepts = []
217
 
        self.reactorTime.advance(self.mousehood.challengeInterval)
218
 
 
219
 
        self.assertEquals(len(self.playerIntelligence.concepts), 1)
220
 
        self.assertChallenge(self.playerIntelligence.concepts[0])
221
 
 
222
 
 
223
 
    def test_twoMenLeave(self):
224
 
        """
225
 
        Test that when two players are near the mouse, the mouse doesn't
226
 
        unschedule its challenge until they both leave.
227
 
        """
228
 
        otherPlayer = commandutils.createPlayer(self.store,
229
 
                                                u"Polite Young Man")[0]
230
 
        otherPlayer.moveTo(self.clock)
231
 
 
232
 
        self.mousehood.startChallenging()
233
 
 
234
 
        firstEvent = events.DepartureEvent(location=self.clock,
235
 
                                           actor=self.player)
236
 
        secondEvent = events.DepartureEvent(location=self.clock,
237
 
                                            actor=otherPlayer)
238
 
 
239
 
        otherPlayer.moveTo(None)
240
 
        self.mouseActor.send(secondEvent)
241
 
 
242
 
        self.playerIntelligence.concepts = []
243
 
 
244
 
        self.reactorTime.advance(self.mousehood.challengeInterval)
245
 
 
246
 
        self.assertEquals(len(self.playerIntelligence.concepts), 1)
247
 
        self.assertChallenge(self.playerIntelligence.concepts[0])
248
 
 
249
 
        self.player.moveTo(None)
250
 
        self.mouseActor.send(firstEvent)
251
 
 
252
 
        self.failIf(self.mousehood.challenging)
253
 
 
254
 
 
255
 
    def test_getCurrentChallenge(self):
256
 
        """
257
 
        Test that we can introspect the current challenge of a mouse.
258
 
        """
259
 
        self.mousehood.startChallenging()
260
 
        self.reactorTime.advance(self.mousehood.challengeInterval)
261
 
        self.failUnlessIn(self.mousehood.getCurrentChallenge(), japanese.hiragana)
262
 
 
263
 
        self.mousehood.stopChallenging()
264
 
        self.assertIdentical(self.mousehood.getCurrentChallenge(), None)
265
 
 
266
 
 
267
 
    def test_vetteChallengeResponse(self):
268
 
        """
269
 
        Test that the correct response to the current challenge is accepted by
270
 
        the mouse.
271
 
        """
272
 
        self.mousehood.startChallenging()
273
 
        self.reactorTime.advance(self.mousehood.challengeInterval)
274
 
 
275
 
        romaji = japanese.hiragana[self.mousehood.getCurrentChallenge()]
276
 
        self.failUnless(self.mousehood.vetteChallengeResponse(romaji))
277
 
 
278
 
        for romaji in japanese.hiragana.values():
279
 
            if romaji != japanese.hiragana[self.mousehood.getCurrentChallenge()]:
280
 
                self.failIf(self.mousehood.vetteChallengeResponse(romaji))
281
 
 
282
 
 
283
 
    def test_respondToChallengeCorrectly(self):
284
 
        """
285
 
        Test that when a correct response is received, the current challenge is
286
 
        expired and the mouse salutes you.
287
 
        """
288
 
        self.mousehood.startChallenging()
289
 
        self.reactorTime.advance(self.mousehood.challengeInterval)
290
 
 
291
 
        correctResponse = japanese.hiragana[
292
 
            self.mousehood.getCurrentChallenge()]
293
 
 
294
 
        self.mousehood.responseReceived(self.player, correctResponse)
295
 
        self.reactorTime.advance(0)
296
 
 
297
 
        self.assertIdentical(self.mousehood.getCurrentChallenge(), None)
298
 
 
299
 
        self.assertEquals(len(self.playerIntelligence.concepts), 2)
300
 
        c = self.playerIntelligence.concepts[1]
301
 
        self.assertEquals(
302
 
            commandutils.flatten(c.plaintext(self.player)),
303
 
            u"%s salutes you!\n" % (self.mouseName,))
304
 
 
305
 
 
306
 
    def test_respondToChallengeInorrectly(self):
307
 
        """
308
 
        Test that when an incorrect response is received, the current challenge
309
 
        is not expired and the mouse bites you.
310
 
        """
311
 
        self.mousehood.startChallenging()
312
 
        self.reactorTime.advance(self.mousehood.challengeInterval)
313
 
 
314
 
        correctResponse = japanese.hiragana[
315
 
            self.mousehood.getCurrentChallenge()]
316
 
 
317
 
        for ch in japanese.hiragana.values():
318
 
            if ch != correctResponse:
319
 
                self.mousehood.responseReceived(self.player, ch)
320
 
                break
321
 
        else:
322
 
            self.fail("Buggy test")
323
 
 
324
 
        self.reactorTime.advance(0)
325
 
 
326
 
        self.assertIn(self.mousehood.getCurrentChallenge(),
327
 
                      japanese.romajiToHiragana[correctResponse])
328
 
 
329
 
        self.assertEquals(len(self.playerIntelligence.concepts), 2)
330
 
        c = self.playerIntelligence.concepts[1]
331
 
        self.assertEquals(
332
 
            commandutils.flatten(c.plaintext(self.player)),
333
 
            u"%s bites you!\n" % (self.mouseName,))
334
 
 
335
 
 
336
 
    def test_playerSaysCorrectThing(self):
337
 
        """
338
 
        Test that when someone gives voice to the correct response to a mouse's
339
 
        current challenge, the mouse acknowledges this with a salute.
340
 
        """
341
 
        self.mousehood.startChallenging()
342
 
        self.reactorTime.advance(self.mousehood.challengeInterval)
343
 
        action.Say().do(
344
 
            # http://divmod.org/trac/ticket/2917
345
 
            iimaginary.IActor(self.player),
346
 
            None,
347
 
            japanese.hiragana[self.mousehood.getCurrentChallenge()])
348
 
 
349
 
        self.assertIdentical(self.mousehood.getCurrentChallenge(), None)
350
 
        self.reactorTime.advance(0)
351
 
 
352
 
        self.assertEquals(len(self.playerIntelligence.concepts), 3)
353
 
        c = self.playerIntelligence.concepts[2]
354
 
        self.assertEquals(
355
 
            commandutils.flatten(c.plaintext(self.player)),
356
 
            u"%s salutes you!\n" % (self.mouseName,))
357
 
 
358
 
 
359
 
    def test_playerSaysIncorrectThing(self):
360
 
        """
361
 
        Test that when someone gives voice to the correct response to a mouse's
362
 
        current challenge, the mouse acknowledges this with a salute.
363
 
        """
364
 
        self.mousehood.startChallenging()
365
 
        self.reactorTime.advance(self.mousehood.challengeInterval)
366
 
 
367
 
        action.Say().do(
368
 
            # http://divmod.org/trac/ticket/2917
369
 
            iimaginary.IActor(self.player), None, u"lolololo pew")
370
 
 
371
 
        self.failIfIdentical(self.mousehood.getCurrentChallenge(), None)
372
 
        self.reactorTime.advance(0)
373
 
 
374
 
        self.assertEquals(len(self.playerIntelligence.concepts), 3)
375
 
        c = self.playerIntelligence.concepts[2]
376
 
        self.assertEquals(
377
 
            commandutils.flatten(c.plaintext(self.player)),
378
 
            u"%s bites you!\n" % (self.mouseName,))
379
 
 
380
 
 
381
 
    def test_activationUsesReactorScheduling(self):
382
 
        """
383
 
        Test that the default scheduler of the mouse is the Twisted
384
 
        reactor, since that is the scheduler that needs to be used
385
 
        with the actual Imaginary server.
386
 
        """
387
 
        deletions = []
388
 
        ref = weakref.ref(self.mousehood, deletions.append)
389
 
        # This is a hack to reload the mouse since it gets its
390
 
        # _callLater set in setUp.
391
 
        del self.mouse
392
 
        del self.mouseActor
393
 
        del self.mousehood
394
 
        self.assertEquals(deletions, [ref])
395
 
        mousehood = self.store.findUnique(mice.HiraganaMouse)
396
 
        from twisted.internet import reactor
397
 
        self.assertEquals(mousehood._callLater, reactor.callLater)
398
 
 
399
 
 
400
 
 
401
 
class HiraganaMouseCommandTestCase(commandutils.CommandTestCaseMixin, unittest.TestCase):
402
 
    """
403
 
    H-mouse tests which use the command system.
404
 
    """
405
 
 
406
 
    mouseName = u"\N{KATAKANA LETTER PI}\N{KATAKANA LETTER SMALL YU}"
407
 
    hiraganaCharacterPattern = u"'[" + u''.join(japanese.hiragana.keys()) + u"]'"
408
 
    speechPattern = mouseName + u" says, " + hiraganaCharacterPattern
409
 
 
410
 
    def test_oneManEnters(self):
411
 
        """
412
 
        Test that when a fellow jaunts into a venue inhabited by a mouse of the
413
 
        Nipponese persuasion, a hiragana allocution follows.
414
 
        """
415
 
        clock = task.Clock()
416
 
 
417
 
        closetContainer = commandutils.createLocation(
418
 
            self.store, u"Closet", None)
419
 
        closet = closetContainer.thing
420
 
 
421
 
        mouse = mice.createHiraganaMouse(
422
 
            store=self.store,
423
 
            name=self.mouseName,
424
 
            proper=True)
425
 
        mouseActor = iimaginary.IActor(mouse)
426
 
        mousehood = mouseActor.getIntelligence()
427
 
        mousehood._callLater = clock.callLater
428
 
        mouse.moveTo(closet)
429
 
 
430
 
        objects.Exit.link(self.location, closet, u"north")
431
 
 
432
 
        self._test(
433
 
            "north",
434
 
            [commandutils.E("[ Closet ]"),
435
 
             commandutils.E("( south )"),
436
 
             commandutils.E(u"Here, you see " + self.mouseName + u".")],
437
 
            ["Test Player leaves north."])
438
 
 
439
 
        clock.advance(mousehood.challengeInterval)
440
 
 
441
 
        self._test(None, [self.speechPattern])
442
 
 
443
 
 
444
 
    def test_creation(self):
445
 
        """
446
 
        Test the creation of a hiragana-speaking mouse using the thing creation
447
 
        plugin system.
448
 
        """
449
 
        self._test(
450
 
            u"create the 'hiragana mouse' named " + self.mouseName,
451
 
            [commandutils.E(u"You create " + self.mouseName + u".")],
452
 
            [commandutils.E(u"Test Player creates %s." % (self.mouseName,))])
453
 
 
454
 
        for thing in self.location.findProviders(iimaginary.IThing, 0):
455
 
            if thing.name == self.mouseName:
456
 
                break
457
 
        else:
458
 
            self.fail("Could not find the mouse!  Test bug.")
459
 
 
460
 
        clock = task.Clock()
461
 
        jimhood = iimaginary.IActor(thing).getIntelligence()
462
 
        jimhood._callLater = clock.callLater
463
 
 
464
 
        self._test(
465
 
            u"drop " + self.mouseName,
466
 
            [commandutils.E(u"You drop %s." % (self.mouseName,))],
467
 
            [commandutils.E(u"Test Player drops %s." % (self.mouseName,))])
468
 
 
469
 
        clock.advance(jimhood.challengeInterval)
470
 
 
471
 
        self._test(
472
 
            None,
473
 
            [self.speechPattern],
474
 
            [self.speechPattern])