def test_exclude_classes(self): """test that excluding CharacterClasses does not allow them through""" whitelist = char.Filter(mode="whitelist") # excluding a class from a whitelist should have no effect # since whitelists only track included classes whitelist.exclude(Human) expected = self.no_chars.copy() self.assertEqual(self.filter_test(whitelist), expected) # no classes should be added to set self.assertEqual(whitelist._classes, set()) # now testing a blacklist blacklist = char.Filter(mode="blacklist") blacklist.exclude(AlphaSlug) expected = self.all_chars expected[self.vloobuk] = False expected[AlphaSlug] = False self.assertEqual(self.filter_test(blacklist), expected) # AlphaSlug should be added to set self.assertEqual(blacklist._classes, {AlphaSlug}) # excluding another class blacklist.exclude(Bureaucrat) expected[self.bill] = False expected[self.dwight] = False expected[Bureaucrat] = False expected[Commander] = False self.assertEqual(self.filter_test(blacklist), expected) # Bureaucrat should be added to set self.assertEqual(blacklist._classes, {AlphaSlug, Bureaucrat})
def test_go_filtered(self): """test that 'go' command respects Filters""" # set interact for exit to an empty whitelist # i.e. nobody is allowed through TEST_EXIT.interact = char.Filter(mode=True) self.bill.command("go outside") self.assertEqual(self.bill.msgs, ["Exit 'outside' is inaccessible to you."]) self.assertEqual(qlist(self.phil.msgs), []) self.assertEqual(qlist(self.dana.msgs), []) self.assertTrue(self.bill.location is TEST_ROOM) self.bill.msgs.clear() # set perceive for exit to an empty whitelist # i.e. nobody can see this exit or go through now # so Bill should not be informed that this exit even exists TEST_EXIT.perceive = char.Filter(mode=True) self.bill.command("go outside") self.assertEqual(self.bill.msgs, ["No exit with name 'outside'."]) self.assertEqual(qlist(self.phil.msgs), []) self.assertEqual(qlist(self.dana.msgs), []) self.assertTrue(self.bill.location is TEST_ROOM) self.bill.msgs.clear() # BUT, if we set interact to empty blacklist (allowing anyone in) # Bill should be allowed through, even though he can't see the exit TEST_EXIT.interact = char.Filter(mode=False) self.bill.command("go outside") self.assertEqual(self.bill.msgs, []) self.assertEqual(qlist(self.phil.msgs), ["Bill left through exit 'outside'."]) self.assertEqual(qlist(self.dana.msgs), ["Bill entered."]) self.assertTrue(self.bill.location is TEST_OUT)
def test_include_classes(self): """test that including CharacterClasses allows them through""" whitelist = char.Filter(mode="whitelist") whitelist.include(AlphaSlug) # only AlphaSlugs are allowed through expected = self.no_chars.copy() expected[self.vloobuk] = True expected[AlphaSlug] = True self.assertEqual(self.filter_test(whitelist), expected) # test that AlphaSlug was added to the set self.assertEqual(whitelist._classes, {AlphaSlug}) # now all soldier and soldier-derived classes should be permited whitelist.include(Soldier) expected[self.chad] = True expected[self.zeke] = True expected[self.dwight] = True expected[Soldier] = True expected[Commander] = True self.assertEqual(self.filter_test(whitelist), expected) # test that Soldier was added to the set self.assertEqual(whitelist._classes, {AlphaSlug, Soldier}) # now test including with a blacklist blacklist = char.Filter(mode="blacklist") blacklist.include(AlphaSlug) expected = self.all_chars.copy() # it's a blacklist, and nobody was excluded, so all are permitted self.assertEqual(self.filter_test(blacklist), expected) # no classes should be added to set self.assertEqual(blacklist._classes, set())
class FireStaff(item.Equippable): """a staff that enables people to craft weapons""" target = inventory.EquipTarget("right hand") # interestingly, a staff uses can vary by class @character.Command.with_traits(filter=character.Filter( character.Filter.WHITELIST, [Wizard] )) def fireball(self, char, args): """Cast a fireball at a target.""" target = find_player(char, args[1:]) if target is not None: target.message(f"{char} hit you with a fireball.") char.message(f"You hit {target} with a fireball.") @character.Command.with_traits(filter=character.Filter( character.Filter.WHITELIST, [Brute] )) def hit(self, char, args): """Hit target with this staff.""" target = find_player(char, args[1:]) if target is not None: target.message(f"{char} hit you with a staff.") char.message(f"You hit {target} with a staff.")
def test_repr(self): """test that repr(Filter) works as expected""" filt = char.Filter(mode=False) self.assertEqual(repr(filt), "Filter(False, set(), set(), set())") filt = char.Filter(mode=True) self.assertEqual(repr(filt), "Filter(True, set(), set(), set())") filt = char.Filter(False, [Slug, AlphaSlug])
def test_blacklist_chars(self): """including/excluding Characters should overrides any class permissions for blacklists""" blacklist = char.Filter(mode="blacklist") # exclude Slug in general, but include bloog blacklist.exclude(Slug) blacklist.exclude(self.vloobuk) blacklist.include(self.bloog) expected = self.all_chars.copy() expected[Slug] = False expected[AlphaSlug] = False expected[self.vloobuk] = False expected[self.plubb] = False self.assertEqual(self.filter_test(blacklist), expected) self.assertEqual(blacklist._classes, {Slug}) self.assertEqual(set(blacklist._include_chars), {self.bloog}) self.assertEqual(set(blacklist._exclude_chars), {self.vloobuk}) # now include the Slug class in general again blacklist.include(Slug) expected[Slug] = True expected[AlphaSlug] = True expected[self.plubb] = True self.assertEqual(self.filter_test(blacklist), expected) self.assertEqual(blacklist._classes, set()) self.assertEqual(set(blacklist._include_chars), {self.bloog}) self.assertEqual(set(blacklist._exclude_chars), {self.vloobuk}) # now include vloobuk and exclude bloog blacklist.include(self.vloobuk) blacklist.exclude(self.bloog) expected[self.vloobuk] = True expected[self.bloog] = False self.assertEqual(self.filter_test(blacklist), expected) self.assertEqual(blacklist._classes, set()) self.assertEqual(set(blacklist._include_chars), {self.vloobuk}) self.assertEqual(set(blacklist._exclude_chars), {self.bloog})
def test_whitelist_chars(self): """including/excluding Characters should overrides any class permissions for whitelists""" whitelist = char.Filter(mode="whitelist") whitelist.include(Soldier) whitelist.exclude(self.dwight) expected = self.no_chars.copy() # add all soldiers, except Dwight who we excluded expected[self.chad] = True expected[self.zeke] = True expected[Soldier] = True expected[Commander] = True self.assertEqual(self.filter_test(whitelist), expected) # check that the classes and include chars work as expected self.assertEqual(whitelist._classes, {Soldier}) self.assertEqual(set(whitelist._include_chars), set()) self.assertEqual(set(whitelist._exclude_chars), {self.dwight}) # now include dwight whitelist.include(self.dwight) expected[self.dwight] = True self.assertEqual(self.filter_test(whitelist), expected) self.assertEqual(whitelist._classes, {Soldier}) self.assertEqual(set(whitelist._include_chars), {self.dwight}) self.assertEqual(set(whitelist._exclude_chars), set()) # now exclude the Soldier class whitelist.exclude(Soldier) expected = self.no_chars.copy() expected[self.dwight] = True self.assertEqual(self.filter_test(whitelist), expected) self.assertEqual(whitelist._classes, set()) self.assertEqual(set(whitelist._include_chars), {self.dwight}) self.assertEqual(set(whitelist._exclude_chars), set())
def test_mode(self): """test that __init__'s mode keyword works as expected""" # creating a whitelist and blacklist with strings whitelist = char.Filter(mode="whitelist") blacklist = char.Filter(mode="blacklist") self.assertEqual(self.filter_test(whitelist), self.no_chars) self.assertEqual(self.filter_test(blacklist), self.all_chars) # creating a whitelist and blacklist with booleans whitelist = char.Filter(mode=True) blacklist = char.Filter(mode=False) self.assertEqual(self.filter_test(whitelist), self.no_chars) self.assertEqual(self.filter_test(blacklist), self.all_chars) # creating a whitelist and blacklist with enum values whitelist = char.Filter(char.Filter.WHITELIST) blacklist = char.Filter(char.Filter.BLACKLIST) self.assertEqual(self.filter_test(whitelist), self.no_chars) self.assertEqual(self.filter_test(blacklist), self.all_chars)
def test_find_location(self): """Test that util.find works with locations. (Implictly tests that Location.find_child works.) """ shopkeep = char.Character("Bill") # the drunkard is named "outside" for some reason drunkard = char.Character("Outside") guest = char.Character("Matt") tavern = location.Location("Tavern", "A cool tavern") outside = location.Location("Outside", "It's muddy.") basement = location.Location("Tavern Basement", "This is where he stores the ale.") upstairs = location.Location("Tavern Upstairs", "There is a comfy bed for guests.") safe_room = location.Location("Tavern Safe Room", "Room only shopkeep knows about.") exit_list = [ location.Exit(outside, "out", ["outside"]), # only shopkeeper allowed downstairs location.Exit(basement, "basement", ["downstairs"], interact=char.Filter("whitelist", include_chars=[shopkeep])), # only the guest and the shopkeeper allowed upstairs location.Exit(upstairs, "upstairs", ["up"], interact=char.Filter("blacklist", exclude_chars=[drunkard])), # only the shopkeeper can see the safe_room, but others # can interact if they know about it location.Exit(safe_room, "safe room", ["safe"], perceive=char.Filter("whitelist", include_chars=[shopkeep])) ] for ex in exit_list: tavern.add_exit(ex) tavern.add_char(shopkeep) tavern.add_char(drunkard) tavern.add_char(guest) self.maxDiff = 3000 # just doing a generic find should yield everything in the location self.assertCountEqual(find(tavern), exit_list + [shopkeep, drunkard, guest]) # providing a depth less than 0 should give us no items self.assertCountEqual(find(tavern, maxdepth=-1), []) # can we filter by type? self.assertCountEqual(find(tavern, type=location.Exit), exit_list) self.assertCountEqual(find(tavern, type=char.Character), [shopkeep, guest, drunkard]) self.assertCountEqual( find(tavern, type=(char.Character, location.Exit)), exit_list + [shopkeep, drunkard, guest]) # can we look by name? self.assertCountEqual(find(tavern, name="outside"), [exit_list[0], drunkard]) self.assertCountEqual(find(tavern, name="outside", type=location.Exit), [exit_list[0]]) # name and type self.assertCountEqual(find(tavern, name="outside", type=location.Exit), [exit_list[0]]) self.assertCountEqual(find(tavern, name="up"), [exit_list[2]]) self.assertCountEqual(find(tavern, name="safe"), [exit_list[3]]) self.assertCountEqual(find(tavern, name="bill"), [shopkeep]) # testing that all the permissions checking works as expected self.assertCountEqual(find(tavern, name="bill", pov=shopkeep), [shopkeep]) # shopkeeper can see all the exits self.assertCountEqual(find(tavern, type=location.Exit, pov=shopkeep), exit_list) self.assertCountEqual(find(tavern, type=location.Exit, pov=drunkard), [exit_list[0], exit_list[3]]) self.assertCountEqual(find(tavern, type=location.Exit, pov=guest), [exit_list[0], exit_list[2], exit_list[3]]) # now adding some items tavern.add_item(HealthPotion(1)) tavern.add_item(HealthPotion(1)) tavern.add_item(HealthPotion(5)) tavern.add_item(SilverCoin()) tavern.add_item(SilverCoin()) tavern.add_item(SilverCoin()) items = [(HealthPotion(1), 2), (HealthPotion(5), 1), (SilverCoin(), 3)] # directly comparing items is hard, so we will serialize them first self.assertEqual(10, len(find(tavern))) # helper function to make comparing items easier def item_list(i_list): return [(item.save(), c) for (item, c) in i_list] self.assertCountEqual(item_list(find(tavern, type=Item)), item_list(items)) self.assertCountEqual( item_list(find(tavern, name="Health Potion")), item_list([(HealthPotion(1), 2), (HealthPotion(5), 1)])) self.assertCountEqual(item_list(find(tavern, hp=1)), item_list([(HealthPotion(1), 2)]))