Beispiel #1
0
	def setup_locations(self):
		self.lighthouse_location = Location(12, 0x1, Labels("Lighthouse", "at a lighthouse", " by the sea."))
		self.beach_location = Location(13, 0x1, Labels("Beach", "on a beach", " of black sand"))
		self.locations_by_id = {
			12 : self.lighthouse_location,
			13 : self.beach_location,
		}
	def setup_locations(self):
		self.initial_location = Location(9, 0x1, Labels("Lighthouse", "at a lighthouse", " by the sea."))
		self.beach_location = Location(13, 0x1, Labels("Beach", "on a beach", " of black sand"))
		self.data.get_location.side_effect = lambda x: {
			9 : self.initial_location,
			13 : self.beach_location,
		}.get(x)
Beispiel #3
0
    def setUp(self):

        self.inventory = Inventory(
            0, 0x1,
            Labels("Main Inventory", "in the main inventory",
                   ", where items live usually."), 3)
        self.book = Item(1105, 0x2,
                         Labels("book", "a book", "a book of fairytales"), 2,
                         "The Pied Piper", {})
        self.lamp = Item(1043, 0x10101A,
                         Labels("lamp", "a lamp", "a small lamp"), 2, None, {})
        self.coin = Item(1000, 0x2, Labels("coin", "a coin", "a silver coin"),
                         1, None, {})
        self.medal = Item(1001, 0x2, Labels("medal", "a medal",
                                            "a gold medal"), 1, None, {})
        self.suit = UsableItem(1046, 0x402,
                               Labels("suit", "a suit", "a space-suit"), 2,
                               None, {}, Item.ATTRIBUTE_GIVES_AIR)
        self.water = Item(1109, 0x22902,
                          Labels("water", "some water", "some water"), 1, None,
                          {})
        self.basket = ContainerItem(
            1107, 0x3, Labels("basket", "a basket", "a large basket"), 6, None,
            {})
        self.non_essential_drop_location = Location(
            12, 0x1, Labels("Lighthouse", "at a lighthouse", " by the sea."))
        self.essential_drop_location = Location(
            9, 0x0, Labels("Cave", "in a cave", ". It is dark"))
 def setup_locations(self):
     self.lighthouse_location = Location(
         12, 0x603, Labels("Lighthouse", "at a lighthouse", " by the sea."))
     self.beach_location = Location(
         13, 0x603, Labels("Beach", "on a beach", " of black sand"))
     self.locations_by_id = {}
     self.locations_by_id[12] = self.lighthouse_location
     self.locations_by_id[13] = self.beach_location
     self.location_collection = LocationCollection(self.locations_by_id)
Beispiel #5
0
 def setup_locations(self):
     self.beach_location = Location(
         13, 0x1, Labels("Beach", "on a beach", " of black sand"))
     self.cave_location = Location(
         9, 0x0, Labels("Cave", "in a cave", ". It is dark"))
     self.lighthouse_location = Location(
         12, 0x1, Labels("Lighthouse", "at a lighthouse", " by the sea."))
     self.mine_location = Location(
         11, 0x0,
         Labels("Mines", "in the mines",
                ". There are dark passages everywhere."))
     self.sun_location = Location(
         10, 0x11, Labels("Sun", "in the sun", ". It is hot."))
Beispiel #6
0
 def setUp(self):
     self.lighthouse_location = Location(
         12, 0x603, Labels("Lighthouse", "at a lighthouse", " by the sea."))
     self.beach_location = Location(
         13, 0x603, Labels("Beach", "on a beach", " of black sand"))
     self.cave_location = Location(
         9, 0x402, Labels("Cave", "in a cave", ". It is dark"))
     self.inventory = Inventory(
         0, 0x1,
         Labels("Main Inventory", "in the main inventory",
                ", where items live usually."), 13)
     self.player = Player(1, 0x3, self.lighthouse_location,
                          self.cave_location, self.beach_location,
                          self.cave_location, self.inventory)
Beispiel #7
0
	def parse_location(self, location_input, links, validation):
		location_id = location_input["data_id"]
		attributes = int(location_input["attributes"], 16)
		labels = self.parse_labels(location_input["labels"])

		location = Location(location_id, attributes, labels)
		links[location] = self.parse_links(location_input["directions"], validation, location_id)

		return location
Beispiel #8
0
    def setUp(self):
        self.library_location = Location(
            80, 0x1,
            Labels("Library", "in the Library", ", a tall, bright room"))
        self.lighthouse_location = Location(
            81, 0x1, Labels("Lighthouse", "at a lighthouse", " by the sea."))
        self.box = ContainerItem(1108, 0x3,
                                 Labels("box", "a box", "a small box"), 3,
                                 None, {})
        self.ash = Item(1109, 0x2, Labels("ash", "some ash", "some black ash"),
                        1, None, {})
        self.candle = Item(1110, 0x2,
                           Labels("candle", "a candle", "a small candle"), 2,
                           None, {})
        self.kindling = Item(
            1111, 0x2, Labels("kindling", "some kindling", "some kindling"), 2,
            None, {})
        self.desk = Item(1112, 0x20000,
                         Labels("desk", "a desk", "a large mahogany desk"), 6,
                         None, {})
        self.elements = {
            80: self.library_location,
            81: self.lighthouse_location,
            1108: self.box,
            1109: self.ash,
            1110: self.candle,
            1111: self.kindling,
            1112: self.desk,
        }

        self.burn_command = Command(6, 0x0, 0x0, [], ["burn"], {})
        self.non_switching_command = Command(17, 0x0, 0x0, [], ["throw"], {})
        self.switching_command = Command(19, 0x200, 0x0, [], ["switch"], {})
        self.commands_by_id = {
            6: self.burn_command,
            17: self.non_switching_command,
            19: self.switching_command,
        }
    def test_validate_location_no_floor_no_down(self):
        self.locations_by_id[17] = Location(
            17, 0x50F,
            Labels("Precipice", "on a precipice", ", high in the air"))

        validation = self.validator.validate(self.data_collection)

        self.assertEqual(1, len(validation))
        validation_line = validation[0]
        self.assertEqual(
            "Location {0} has no floor, but does not specify a link in direction {1}.",
            validation_line.template)
        self.assertEqual(Severity.ERROR, validation_line.severity)
        self.assertEqual((17, "DOWN"), validation_line.args)
    def test_validate_location_no_land_no_floor(self):
        mid_air_location = Location(
            19, 0x10F,
            Labels("Mid-air", "in mid-air", "; you are not sure how high"))
        mid_air_location.directions[Direction.DOWN] = self.lighthouse_location
        self.locations_by_id[19] = mid_air_location

        validation = self.validator.validate(self.data_collection)

        self.assertEqual(1, len(validation))
        validation_line = validation[0]
        self.assertEqual(
            "Location {0} has no land, but also no floor. Locations without land must have a floor.",
            validation_line.template)
        self.assertEqual(Severity.ERROR, validation_line.severity)
        self.assertEqual((19, ), validation_line.args)
Beispiel #11
0
	def setUp(self):
		extended_descriptions = [". The walls are dark and cold", ". The walls are glowing"]
		self.lighthouse_location = Location(12, 0x1, Labels("Lighthouse", "at a lighthouse", " by the sea."))
		self.mine_location = Location(11, 0x0, Labels("Mines", "in the mines", ". There are dark passages everywhere", extended_descriptions))
		self.lower_mine_location = Location(10, 0x200, Labels("Lower mines", "in the lower mines", ". This is the bottom of the mines", extended_descriptions))

		self.book = Item(1105, 2, Labels("book", "a book", "a book of fairytales"), 2, "The Pied Piper", {})
		self.desk = Item(1000, 0x20000, Labels("desk", "a desk", "a large mahogany desk"), 6, None, {})
		self.obstruction = Item(1000, 0x4, Labels("obstruction", "an obstruction", "an obstruction blocking you"), 8, None, {})
		self.basket = ContainerItem(1107, 0x3, Labels("basket", "a basket", "a large basket"), 6, None, {})
		self.box = ContainerItem(1108, 0x3, Labels("box", "a box", "a small box"), 3, None, {})
def GoBuilding(game, *args, **kwargs):
    if game.state.location==game.world.locations['ON A BUSY STREET']:
        game.GoTo('LOBBY')
        if not game.Has('BADGE'):
            game.GoTo('LOBBY')
            return ""
        else:
            m = game.Look()
            m += '\nTHE DOOR MAN LOOKS AT MY BADGE AND THEN THROWS ME OUT.\n'
            game.GoTo('STREET')
            m += game.Look()
            return m

locations = (
    Location('STREET', 'ON A BUSY STREET', (0, 0, 0, 0)),
    Location('VISITOR', 'IN A VISITOR\'S ROOM', (0,  0,  'LOBBY',  0)),
    Location('LOBBY', 'IN THE LOBBY OF THE BUILDING', ('STREET', 0, 'ANTEROOM', 'VISITOR'),
         go(ifHas='BADGE', goTo='STREET', message="THE DOOR MAN LOOKS AT MY BADGE AND THEN THROWS ME OUT.", result=Response.MaybeLater)),
    Location('ANTEROOM', 'IN A DINGY ANTE ROOM', (0, 0, 0, 'LOBBY')),
    Location('CEO', 'IN THE COMPANY PRESIDENT\'S OFFICE', (0, 0, 0, 'ANTEROOM')),
    Location('CUBICLE', 'IN A SMALL SOUND PROOFED CUBICLE', (0, 'PLAIN', 0, 0), (
        go(ifNotSet='wallButtonPushed', message="SIRENS GO OFF ALL AROUND ME!\nGUARDS RUN IN AND SHOOT ME TO DEATH!", result=Response.Fatal),
        go(condition=lambda g:g.world.locations['CUBICLE'].moves[Direction.EAST] != 0, setMove=(('CUBICLE', 'EAST', 0)), message="A SECRET DOOR SLAMS DOWN BEHIND ME!"))),
    Location('SECURITY', 'IN A SECURITY OFFICE', (0, 0, 'HALLWAY', 0)),
    Location('HALLWAY', 'IN A SMALL HALLWAY', (0, 'CAFETERIA', 'ELEVATOR', 'SECURITY')),
    Location('ELEVATOR', 'IN A SMALL ROOM', ('LOBBY', 0, 0, 0)),
    Location('CORRIDOR', 'IN A SHORT CORRIDOR', (0, 'SIDE', 0, 'ELEVATOR'), (
        go(ifNotHas='A CHAOS I.D. CARD', goTo='ELEVATOR', message="THE GUARD LOOKS AT ME SUSPICIOUSLY, THEN THROWS ME BACK.", result=Response.MaybeLater),
        go(ifSet='guardAwakened', message="THE GUARD DRAWS HIS GUN AND SHOOTS ME!", result=Response.Fatal))),
    Location('METAL', 'IN A HALLWAY MADE OF METAL', (0, 0, 'PLAIN', 'CORRIDOR'), go(ifNotSet='electricityOff', message="THE FLOOR IS WIRED WITH ELECDRICITY!\nI'M BEING ELECTROCUTED!", result=Response.Fatal)),
from adventure.location import Location

locations = (
    Location('Living',
             ('This room has a couch, chairs and TV.',
              'You have entered the living room. You can watch TV here.',
              'This room has two sofas, chairs and a chandelier.',
              'A huge television that is great for watching games.'),
             (0, 'Bedroom', 'Garden', 0)),
    Location('Garden',
             ('This space has a swing, flowers and trees.',
              'You have arrived at the garden. You can exercise here',
              'This area has plants, grass and rabbits.',
              'A nice shiny bike that is fun to ride.'),
             (0, 'Kitchen', 0, 'Living')),
    Location(
        'Kitchen',
        ('This room has a fridge, oven, and a sink.',
         'You have arrived in the kitchen. You can find food and drinks here.',
         'This living area has pizza, coke, and icecream.',
         'A red juicy fruit.'), ('Garden', 0, 0, 'Bedroom')),
    Location('Bedroom', ('This area has a bed, desk and a dresser.',
                         'You have arrived in the bedroom. You can rest here.',
                         'You see a wooden cot and a mattress on top of it.',
                         'A nice, comfortable bed with pillows and sheets.'),
             ('Living', 0, 'Kitchen', 0)))
Beispiel #14
0
    def setUp(self):
        self.book = Item(1105, 0x2,
                         Labels("book", "a book", "a book of fairytales"), 2,
                         "The Pied Piper", {})
        self.desk = Item(1106, 0x20000,
                         Labels("desk", "a desk", "a large mahogany desk"), 6,
                         None, {})

        rope_list_templates = {
            ListTemplateType.LOCATION: "{0} (coiled neatly)",
            ListTemplateType.CARRYING: "{0} (tied safely)"
        }
        self.rope = Item(1123, 0x2,
                         Labels("rope", "some rope", "a small length of rope"),
                         2, None, rope_list_templates)

        basket_list_templates = {ListTemplateType.DEFAULT: "{0} (upright)"}
        self.basket = ContainerItem(
            1107, 0x3, Labels("basket", "a basket", "a large basket"), 6, None,
            basket_list_templates)
        box_list_templates = {ListTemplateType.DEFAULT: "{0} (open)"}
        self.box = ContainerItem(1108, 0x3,
                                 Labels("box", "a box", "a small box"), 3,
                                 None, box_list_templates)

        lamp_list_templates = {ListTemplateType.DEFAULT: "{0} ({1})"}
        lamp_switching_info = SwitchInfo(Item.ATTRIBUTE_GIVES_LIGHT, "off",
                                         "on")
        self.lamp = SwitchableItem(1043, 0x100A,
                                   Labels("lamp", "a lamp",
                                          "a small lamp"), 2, None,
                                   lamp_list_templates, lamp_switching_info)

        button_list_templates = {ListTemplateType.DEFAULT: "{0} ({1})"}
        button_switching_info = SwitchInfo(Item.ATTRIBUTE_GIVES_LIGHT, "up",
                                           "down")
        self.button = SwitchableItem(
            1044, 0x8,
            Labels("button", "a button", "a red button",
                   [". It is dark", ". It is glowing"]), 2, None,
            button_list_templates, button_switching_info)

        lever_list_templates = {ListTemplateType.DEFAULT: "{0} ({1})"}
        lever_switching_info = SwitchInfo(Location.ATTRIBUTE_GIVES_LIGHT,
                                          "down", "up")
        self.lever = SwitchableItem(
            1045, 0x8, Labels("lever", "a lever", "a mysterious lever"), 2,
            None, lever_list_templates, lever_switching_info)

        suit_list_templates = {ListTemplateType.USING: "{0} (being worn)"}
        self.suit = UsableItem(1046, 0x402,
                               Labels("suit", "a suit",
                                      "a space-suit"), 2, None,
                               suit_list_templates, Item.ATTRIBUTE_GIVES_AIR)

        self.cat = SentientItem(1047, 0x80002,
                                Labels("cat", "a cat", "a black cat"), 3, None,
                                {})
        self.water = Item(
            1109, 0x22902,
            Labels("water", "some water", "some water",
                   [". It is cold", ". It is hot"]), 1, None, {})
        self.mine_location = Location(
            11, 0x0,
            Labels("Mines", "in the mines",
                   ". There are dark passages everywhere."))
        self.inventory = Inventory(
            0, 0x1,
            Labels("Main Inventory", "in the main inventory",
                   ", where items live usually."), 100)

        self.steam = Item(1117, 0x2,
                          Labels("steam", "some steam", "some hot steam"), 1,
                          None, {})
        self.water.transformations[98] = self.steam
class TestEventResolver(unittest.TestCase):
    def setUp(self):

        self.setup_data()
        self.setup_player()

        self.resolver = EventResolver()
        self.resolver.init_data(self.data)

    def setup_data(self):
        self.data = Mock()
        self.setup_commands()
        self.setup_locations()
        self.setup_items()

        self.data.get_element_by_id.side_effect = lambda x: {
            1003: self.bean,
            1108: self.bottle,
            1043: self.lamp,
            1058: self.potion,
            1203: self.wand,
            12: self.lighthouse_location
        }.get(x)

    def setup_commands(self):
        self.drink_command = Command(14, 0x0, [], [], "drink", {})
        self.pour_command = Command(40, 0x0, [], [], "pour", {})
        self.rub_command = Command(48, 0x10, [], [], ["rub"], {})
        self.wave_command = Command(150, 0x0, [], [], ["wave"], {})

    def setup_locations(self):
        self.lighthouse_location = Location(
            12, 0x1, Labels("Lighthouse", "at a lighthouse", " by the sea."))
        self.beach_location = Location(
            13, 0x1, Labels("Beach", "on a beach", " of black sand"))

    def setup_items(self):
        self.bean = Item(1003, 0x2, Labels("bean", "a bean", "a magic bean"),
                         2, None, {})
        self.bottle = ContainerItem(
            1108, 0x203, Labels("bottle", "a bottle", "a small bottle"), 3,
            None, {})
        lamp_switching_info = SwitchInfo(Item.ATTRIBUTE_GIVES_LIGHT, "off",
                                         "on")
        self.lamp = SwitchableItem(1043, 0x101A,
                                   Labels("lamp", "a lamp", "a small lamp"), 2,
                                   None, {}, lamp_switching_info)
        self.potion = Item(
            1058, 0x800, Labels("potion", "some potion",
                                "some magical potion"), 1, None, {})
        self.wand = Item(1203, 0x2, Labels("wand", "a wand", "a magical wand"),
                         2, None, {})

    def setup_player(self):
        self.player = Mock()

    def test_resolve_event_without_match(self):
        self.data.get_events.side_effect = lambda x: {}.get(x)

        response = self.resolver.resolve_event(self.wave_command, self.player,
                                               self.wand)

        self.assertEqual((True, [], [self.wand], []), response)

    def test_resolve_event_with_match_to_non_copyable_item(self):
        rub_lamp_event_match = EventMatch(command=self.rub_command,
                                          arguments=[self.lamp],
                                          prerequisites=[])
        rub_lamp_event_outcome = EventOutcome(text_key="event_response_key",
                                              actions=[])
        rub_lamp_event = Event(event_id=3001,
                               attributes=0x0,
                               match=rub_lamp_event_match,
                               outcome=rub_lamp_event_outcome)
        self.data.get_events.side_effect = lambda x: {
            (self.rub_command, self.lamp): [rub_lamp_event],
        }.get(x)

        response = self.resolver.resolve_event(self.rub_command, self.player,
                                               self.lamp)

        self.assertEqual(
            (True, ["event_response_key"], [self.lamp], [self.lamp]), response)

    def test_resolve_event_with_match_to_copyable_item(self):
        drink_potion_event_match = EventMatch(command=self.drink_command,
                                              arguments=[self.potion],
                                              prerequisites=[])
        drink_potion_event_outcome = EventOutcome(
            text_key="event_response_key", actions=[])
        drink_potion_event = Event(event_id=3002,
                                   attributes=0x0,
                                   match=drink_potion_event_match,
                                   outcome=drink_potion_event_outcome)
        self.data.get_events.side_effect = lambda x: {
            (self.drink_command, self.potion): [drink_potion_event],
        }.get(x)
        potion_copy = copy(self.potion)

        response = self.resolver.resolve_event(self.drink_command, self.player,
                                               potion_copy)

        self.assertEqual(
            (True, ["event_response_key"], [potion_copy], [potion_copy]),
            response)

    def test_resolve_event_with_match_to_two_args(self):
        pour_potion_bean_event_match = EventMatch(
            command=self.pour_command,
            arguments=[self.potion, self.bean],
            prerequisites=[])
        destroy_bean_destination = ItemEventOutcomeActionDestination(
            kind=ItemEventOutcomeActionDestinationKind.DESTROY,
            named_data_element=None)
        destroy_bean_action = ItemEventOutcomeAction(
            kind=EventOutcomeActionKind.ITEM,
            item=self.bean,
            destination=destroy_bean_destination)
        pour_potion_bean_event_outcome = EventOutcome(
            text_key="event_response_key", actions=[destroy_bean_action])
        pour_potion_bean_event = Event(event_id=3003,
                                       attributes=0x0,
                                       match=pour_potion_bean_event_match,
                                       outcome=pour_potion_bean_event_outcome)
        self.data.get_events.side_effect = lambda x: {
            (self.pour_command, self.potion, self.bean):
            [pour_potion_bean_event],
        }.get(x)

        response = self.resolver.resolve_event(self.pour_command, self.player,
                                               self.potion, self.bean)

        self.assertEqual(
            (True, ["event_response_key"], [self.potion, self.bean
                                            ], [self.potion, self.bean]),
            response)

    def test_resolve_event_with_item_outcome_action_destroy(self):
        pour_potion_bean_event_match = EventMatch(
            command=self.pour_command,
            arguments=[self.potion, self.bean],
            prerequisites=[])
        destroy_bean_destination = ItemEventOutcomeActionDestination(
            kind=ItemEventOutcomeActionDestinationKind.DESTROY,
            named_data_element=None)
        destroy_bean_action = ItemEventOutcomeAction(
            kind=EventOutcomeActionKind.ITEM,
            item=self.bean,
            destination=destroy_bean_destination)
        pour_potion_bean_event_outcome = EventOutcome(
            text_key="event_response_key", actions=[destroy_bean_action])
        pour_potion_bean_event = Event(event_id=3003,
                                       attributes=0x0,
                                       match=pour_potion_bean_event_match,
                                       outcome=pour_potion_bean_event_outcome)
        self.data.get_events.side_effect = lambda x: {
            (self.pour_command, self.potion, self.bean):
            [pour_potion_bean_event],
        }.get(x)
        self.lighthouse_location.add(self.bean)

        response = self.resolver.resolve_event(self.pour_command, self.player,
                                               self.potion, self.bean)

        self.assertEqual(
            (True, ["event_response_key"], [self.potion, self.bean
                                            ], [self.potion, self.bean]),
            response)
        self.assertFalse(self.lighthouse_location.contains(self.bean))

    def test_resolve_event_with_item_outcome_action_current_location(self):
        wave_wand_event_match = EventMatch(command=self.wave_command,
                                           arguments=[self.wand],
                                           prerequisites=[])
        wand_destination = ItemEventOutcomeActionDestination(
            kind=ItemEventOutcomeActionDestinationKind.CURRENT_LOCATION,
            named_data_element=None)
        wand_action = ItemEventOutcomeAction(kind=EventOutcomeActionKind.ITEM,
                                             item=self.bean,
                                             destination=wand_destination)
        wave_wand_event_outcome = EventOutcome(text_key="event_response_key",
                                               actions=[wand_action])
        wave_wand_event = Event(event_id=3004,
                                attributes=0x0,
                                match=wave_wand_event_match,
                                outcome=wave_wand_event_outcome)
        self.data.get_events.side_effect = lambda x: {
            (self.wave_command, self.wand): [wave_wand_event],
        }.get(x)

        response = self.resolver.resolve_event(self.wave_command, self.player,
                                               self.wand)

        self.assertEqual(
            (True, ["event_response_key"], [self.wand], [self.wand]), response)
        self.player.drop_item.assert_called_once_with(self.bean)

    def test_resolve_event_with_item_outcome_action_current_inventory(self):
        wave_wand_event_match = EventMatch(command=self.wave_command,
                                           arguments=[self.wand],
                                           prerequisites=[])
        wand_destination = ItemEventOutcomeActionDestination(
            kind=ItemEventOutcomeActionDestinationKind.CURRENT_INVENTORY,
            named_data_element=None)
        wand_action = ItemEventOutcomeAction(kind=EventOutcomeActionKind.ITEM,
                                             item=self.bean,
                                             destination=wand_destination)
        wave_wand_event_outcome = EventOutcome(text_key="event_response_key",
                                               actions=[wand_action])
        wave_wand_event = Event(event_id=3005,
                                attributes=0x0,
                                match=wave_wand_event_match,
                                outcome=wave_wand_event_outcome)
        self.data.get_events.side_effect = lambda x: {
            (self.wave_command, self.wand): [wave_wand_event],
        }.get(x)

        response = self.resolver.resolve_event(self.wave_command, self.player,
                                               self.wand)

        self.assertEqual(
            (True, ["event_response_key"], [self.wand], [self.wand]), response)
        self.player.take_item.assert_called_once_with(self.bean)

    def test_resolve_event_with_item_outcome_action_absolute_container_non_copyable(
            self):
        wave_wand_event_match = EventMatch(command=self.wave_command,
                                           arguments=[self.wand],
                                           prerequisites=[])
        wand_destination = ItemEventOutcomeActionDestination(
            kind=ItemEventOutcomeActionDestinationKind.ABSOLUTE_CONTAINER,
            named_data_element=self.lighthouse_location)
        wand_action = ItemEventOutcomeAction(kind=EventOutcomeActionKind.ITEM,
                                             item=self.bean,
                                             destination=wand_destination)
        wave_wand_event_outcome = EventOutcome(text_key="event_response_key",
                                               actions=[wand_action])
        wave_wand_event = Event(event_id=3006,
                                attributes=0x0,
                                match=wave_wand_event_match,
                                outcome=wave_wand_event_outcome)
        self.data.get_events.side_effect = lambda x: {
            (self.wave_command, self.wand): [wave_wand_event],
        }.get(x)

        response = self.resolver.resolve_event(self.wave_command, self.player,
                                               self.wand)

        self.assertEqual(
            (True, ["event_response_key"], [self.wand], [self.wand]), response)
        self.assertTrue(self.lighthouse_location.contains(self.bean))

    def test_resolve_event_with_item_outcome_action_absolute_container_copyable(
            self):
        wave_wand_event_match = EventMatch(command=self.wave_command,
                                           arguments=[self.wand],
                                           prerequisites=[])
        wand_destination = ItemEventOutcomeActionDestination(
            kind=ItemEventOutcomeActionDestinationKind.ABSOLUTE_CONTAINER,
            named_data_element=self.bottle)
        wand_action = ItemEventOutcomeAction(kind=EventOutcomeActionKind.ITEM,
                                             item=self.potion,
                                             destination=wand_destination)
        wave_wand_event_outcome = EventOutcome(text_key="event_response_key",
                                               actions=[wand_action])
        wave_wand_event = Event(event_id=3006,
                                attributes=0x0,
                                match=wave_wand_event_match,
                                outcome=wave_wand_event_outcome)
        self.data.get_events.side_effect = lambda x: {
            (self.wave_command, self.wand): [wave_wand_event]
        }.get(x)

        response = self.resolver.resolve_event(self.wave_command, self.player,
                                               self.wand)

        self.assertEqual(
            (True, ["event_response_key"], [self.wand], [self.wand]), response)
        self.assertFalse(self.bottle.contains(self.potion))
        potion_copy = self.bottle.get_allow_copy(self.potion)
        self.assertTrue(potion_copy.is_allow_copy(self.potion))

    def test_resolve_event_with_item_outcome_action_replace(self):
        wave_wand_event_match = EventMatch(command=self.wave_command,
                                           arguments=[self.wand],
                                           prerequisites=[])
        wand_destination = ItemEventOutcomeActionDestination(
            kind=ItemEventOutcomeActionDestinationKind.REPLACE,
            named_data_element=self.lamp)
        wand_action = ItemEventOutcomeAction(kind=EventOutcomeActionKind.ITEM,
                                             item=self.bean,
                                             destination=wand_destination)
        wave_wand_event_outcome = EventOutcome(text_key="event_response_key",
                                               actions=[wand_action])
        wave_wand_event = Event(event_id=3005,
                                attributes=0x0,
                                match=wave_wand_event_match,
                                outcome=wave_wand_event_outcome)
        self.data.get_events.side_effect = lambda x: {
            (self.wave_command, self.wand): [wave_wand_event],
        }.get(x)
        self.lighthouse_location.add(self.bean)

        response = self.resolver.resolve_event(self.wave_command, self.player,
                                               self.wand)

        self.assertEqual(
            (True, ["event_response_key"], [self.wand], [self.wand]), response)
        self.assertFalse(self.lighthouse_location.contains(self.bean))
        self.assertTrue(self.lighthouse_location.contains(self.lamp))

    def test_resolve_event_with_item_any_container_prerequisite_without_match(
            self):
        prerequisite_kind = EventMatchPrerequisiteKind.ITEM
        prerequisite_item = self.bean
        prerequisite_container_kind = ItemEventMatchPrerequisiteContainerKind.ANY
        prerequisite_container = ItemEventMatchPrerequisiteContainer(
            prerequisite_container_kind, None)
        prerequisite = ItemEventMatchPrerequisite(prerequisite_kind, False,
                                                  prerequisite_item,
                                                  prerequisite_container)

        pour_potion_bean_event_match = EventMatch(
            command=self.pour_command,
            arguments=[self.potion, self.bean],
            prerequisites=[prerequisite])
        destroy_bean_destination = ItemEventOutcomeActionDestination(
            kind=ItemEventOutcomeActionDestinationKind.DESTROY,
            named_data_element=None)
        destroy_bean_action = ItemEventOutcomeAction(
            kind=EventOutcomeActionKind.ITEM,
            item=self.bean,
            destination=destroy_bean_destination)
        pour_potion_bean_event_outcome = EventOutcome(
            text_key="event_response_key", actions=[destroy_bean_action])
        pour_potion_bean_event = Event(event_id=3003,
                                       attributes=0x0,
                                       match=pour_potion_bean_event_match,
                                       outcome=pour_potion_bean_event_outcome)

        self.data.get_events.side_effect = lambda x: {
            (self.pour_command, self.potion, self.bean):
            [pour_potion_bean_event],
        }.get(x)
        self.player.get_location.return_value = self.lighthouse_location

        response = self.resolver.resolve_event(self.pour_command, self.player,
                                               self.potion, self.bean)

        self.assertEqual(
            (True, ["event_response_key"], [self.potion, self.bean
                                            ], [self.potion, self.bean]),
            response)
        self.assertFalse(self.lighthouse_location.contains(self.bean))

    def test_resolve_event_with_item_current_location_prerequisite_without_match(
            self):
        prerequisite_kind = EventMatchPrerequisiteKind.ITEM
        prerequisite_item = self.bean
        prerequisite_container_kind = ItemEventMatchPrerequisiteContainerKind.CURRENT_LOCATION
        prerequisite_container = ItemEventMatchPrerequisiteContainer(
            prerequisite_container_kind, None)
        prerequisite = ItemEventMatchPrerequisite(prerequisite_kind, False,
                                                  prerequisite_item,
                                                  prerequisite_container)

        pour_potion_bean_event_match = EventMatch(
            command=self.pour_command,
            arguments=[self.potion, self.bean],
            prerequisites=[prerequisite])
        destroy_bean_destination = ItemEventOutcomeActionDestination(
            kind=ItemEventOutcomeActionDestinationKind.DESTROY,
            named_data_element=None)
        destroy_bean_action = ItemEventOutcomeAction(
            kind=EventOutcomeActionKind.ITEM,
            item=self.bean,
            destination=destroy_bean_destination)
        pour_potion_bean_event_outcome = EventOutcome(
            text_key="event_response_key", actions=[destroy_bean_action])
        pour_potion_bean_event = Event(event_id=3003,
                                       attributes=0x0,
                                       match=pour_potion_bean_event_match,
                                       outcome=pour_potion_bean_event_outcome)

        self.data.get_events.side_effect = lambda x: {
            (self.pour_command, self.potion, self.bean):
            [pour_potion_bean_event],
        }.get(x)
        self.player.get_location.return_value = self.lighthouse_location

        response = self.resolver.resolve_event(self.pour_command, self.player,
                                               self.potion, self.bean)

        self.assertEqual((True, [], [self.potion, self.bean], []), response)
        self.assertFalse(self.lighthouse_location.contains(self.bean))

    def test_resolve_event_with_item_current_location_prerequisite_with_match(
            self):
        prerequisite_kind = EventMatchPrerequisiteKind.ITEM
        prerequisite_item = self.bean
        prerequisite_container_kind = ItemEventMatchPrerequisiteContainerKind.CURRENT_LOCATION
        prerequisite_container = ItemEventMatchPrerequisiteContainer(
            prerequisite_container_kind, None)
        prerequisite = ItemEventMatchPrerequisite(prerequisite_kind, False,
                                                  prerequisite_item,
                                                  prerequisite_container)

        pour_potion_bean_event_match = EventMatch(
            command=self.pour_command,
            arguments=[self.potion, self.bean],
            prerequisites=[prerequisite])
        destroy_bean_destination = ItemEventOutcomeActionDestination(
            kind=ItemEventOutcomeActionDestinationKind.DESTROY,
            named_data_element=None)
        destroy_bean_action = ItemEventOutcomeAction(
            kind=EventOutcomeActionKind.ITEM,
            item=self.bean,
            destination=destroy_bean_destination)
        pour_potion_bean_event_outcome = EventOutcome(
            text_key="event_response_key", actions=[destroy_bean_action])
        pour_potion_bean_event = Event(event_id=3003,
                                       attributes=0x0,
                                       match=pour_potion_bean_event_match,
                                       outcome=pour_potion_bean_event_outcome)

        self.data.get_events.side_effect = lambda x: {
            (self.pour_command, self.potion, self.bean):
            [pour_potion_bean_event],
        }.get(x)
        self.player.get_location.return_value = self.lighthouse_location
        self.lighthouse_location.add(self.bean)

        response = self.resolver.resolve_event(self.pour_command, self.player,
                                               self.potion, self.bean)

        self.assertEqual(
            (True, ["event_response_key"], [self.potion, self.bean
                                            ], [self.potion, self.bean]),
            response)
        self.assertFalse(self.lighthouse_location.contains(self.bean))

    def test_resolve_event_with_location_prerequisite_without_match(self):
        prerequisite_kind = EventMatchPrerequisiteKind.LOCATION
        prerequisite_location = self.lighthouse_location
        prerequisite = LocationEventMatchPrerequisite(prerequisite_kind, False,
                                                      prerequisite_location)

        pour_potion_bean_event_match = EventMatch(
            command=self.pour_command,
            arguments=[self.potion, self.bean],
            prerequisites=[prerequisite])
        destroy_bean_destination = ItemEventOutcomeActionDestination(
            kind=ItemEventOutcomeActionDestinationKind.DESTROY,
            named_data_element=None)
        destroy_bean_action = ItemEventOutcomeAction(
            kind=EventOutcomeActionKind.ITEM,
            item=self.bean,
            destination=destroy_bean_destination)
        pour_potion_bean_event_outcome = EventOutcome(
            text_key="event_response_key", actions=[destroy_bean_action])
        pour_potion_bean_event = Event(event_id=3003,
                                       attributes=0x0,
                                       match=pour_potion_bean_event_match,
                                       outcome=pour_potion_bean_event_outcome)

        self.data.get_events.side_effect = lambda x: {
            (self.pour_command, self.potion, self.bean):
            [pour_potion_bean_event],
        }.get(x)
        self.lighthouse_location.add(self.bean)

        response = self.resolver.resolve_event(self.pour_command, self.player,
                                               self.potion, self.bean)

        self.assertEqual((True, [], [self.potion, self.bean], []), response)
        self.assertTrue(self.lighthouse_location.contains(self.bean))

    def test_resolve_event_with_location_prerequisite_with_match(self):
        prerequisite_kind = EventMatchPrerequisiteKind.LOCATION
        prerequisite_location = self.lighthouse_location
        prerequisite = LocationEventMatchPrerequisite(prerequisite_kind, False,
                                                      prerequisite_location)

        pour_potion_bean_event_match = EventMatch(
            command=self.pour_command,
            arguments=[self.potion, self.bean],
            prerequisites=[prerequisite])
        destroy_bean_destination = ItemEventOutcomeActionDestination(
            kind=ItemEventOutcomeActionDestinationKind.DESTROY,
            named_data_element=None)
        destroy_bean_action = ItemEventOutcomeAction(
            kind=EventOutcomeActionKind.ITEM,
            item=self.bean,
            destination=destroy_bean_destination)
        pour_potion_bean_event_outcome = EventOutcome(
            text_key="event_response_key", actions=[destroy_bean_action])
        pour_potion_bean_event = Event(event_id=3003,
                                       attributes=0x0,
                                       match=pour_potion_bean_event_match,
                                       outcome=pour_potion_bean_event_outcome)

        self.data.get_events.side_effect = lambda x: {
            (self.pour_command, self.potion, self.bean):
            [pour_potion_bean_event],
        }.get(x)
        self.player.get_location.return_value = self.lighthouse_location
        self.lighthouse_location.add(self.bean)

        response = self.resolver.resolve_event(self.pour_command, self.player,
                                               self.potion, self.bean)

        self.assertEqual(
            (True, ["event_response_key"], [self.potion, self.bean
                                            ], [self.potion, self.bean]),
            response)
        self.assertFalse(self.lighthouse_location.contains(self.bean))

    def test_resolve_event_with_event_prerequisite_without_match(self):
        prerequisite_kind = EventMatchPrerequisiteKind.EVENT
        prerequisite_location = 3002
        prerequisite = EventEventMatchPrerequisite(prerequisite_kind, False,
                                                   prerequisite_location)

        pour_potion_bean_event_match = EventMatch(
            command=self.pour_command,
            arguments=[self.potion, self.bean],
            prerequisites=[prerequisite])
        destroy_bean_destination = ItemEventOutcomeActionDestination(
            kind=ItemEventOutcomeActionDestinationKind.DESTROY,
            named_data_element=None)
        destroy_bean_action = ItemEventOutcomeAction(
            kind=EventOutcomeActionKind.ITEM,
            item=self.bean,
            destination=destroy_bean_destination)
        pour_potion_bean_event_outcome = EventOutcome(
            text_key="event_response_key", actions=[destroy_bean_action])
        pour_potion_bean_event = Event(event_id=3003,
                                       attributes=0x0,
                                       match=pour_potion_bean_event_match,
                                       outcome=pour_potion_bean_event_outcome)

        self.data.get_events.side_effect = lambda x: {
            (self.pour_command, self.potion, self.bean):
            [pour_potion_bean_event],
        }.get(x)
        self.player.has_completed_event.return_value = False
        self.lighthouse_location.add(self.bean)

        response = self.resolver.resolve_event(self.pour_command, self.player,
                                               self.potion, self.bean)

        self.assertEqual((True, [], [self.potion, self.bean], []), response)
        self.assertTrue(self.lighthouse_location.contains(self.bean))

    def test_resolve_event_with_event_prerequisite_with_match(self):
        prerequisite_kind = EventMatchPrerequisiteKind.EVENT
        prerequisite_location = 3002
        prerequisite = EventEventMatchPrerequisite(prerequisite_kind, False,
                                                   prerequisite_location)

        pour_potion_bean_event_match = EventMatch(
            command=self.pour_command,
            arguments=[self.potion, self.bean],
            prerequisites=[prerequisite])
        destroy_bean_destination = ItemEventOutcomeActionDestination(
            kind=ItemEventOutcomeActionDestinationKind.DESTROY,
            named_data_element=None)
        destroy_bean_action = ItemEventOutcomeAction(
            kind=EventOutcomeActionKind.ITEM,
            item=self.bean,
            destination=destroy_bean_destination)
        pour_potion_bean_event_outcome = EventOutcome(
            text_key="event_response_key", actions=[destroy_bean_action])
        pour_potion_bean_event = Event(event_id=3003,
                                       attributes=0x0,
                                       match=pour_potion_bean_event_match,
                                       outcome=pour_potion_bean_event_outcome)

        self.data.get_events.side_effect = lambda x: {
            (self.pour_command, self.potion, self.bean):
            [pour_potion_bean_event],
        }.get(x)
        self.player.has_completed_event.return_value = True
        self.lighthouse_location.add(self.bean)

        response = self.resolver.resolve_event(self.pour_command, self.player,
                                               self.potion, self.bean)

        self.assertEqual(
            (True, ["event_response_key"], [self.potion, self.bean
                                            ], [self.potion, self.bean]),
            response)
        self.assertFalse(self.lighthouse_location.contains(self.bean))

    def test_resolve_event_with_event_prerequisite_with_match_invert(self):
        prerequisite_kind = EventMatchPrerequisiteKind.EVENT
        prerequisite_location = 3002
        prerequisite = EventEventMatchPrerequisite(prerequisite_kind, True,
                                                   prerequisite_location)

        pour_potion_bean_event_match = EventMatch(
            command=self.pour_command,
            arguments=[self.potion, self.bean],
            prerequisites=[prerequisite])
        destroy_bean_destination = ItemEventOutcomeActionDestination(
            kind=ItemEventOutcomeActionDestinationKind.DESTROY,
            named_data_element=None)
        destroy_bean_action = ItemEventOutcomeAction(
            kind=EventOutcomeActionKind.ITEM,
            item=self.bean,
            destination=destroy_bean_destination)
        pour_potion_bean_event_outcome = EventOutcome(
            text_key="event_response_key", actions=[destroy_bean_action])
        pour_potion_bean_event = Event(event_id=3003,
                                       attributes=0x0,
                                       match=pour_potion_bean_event_match,
                                       outcome=pour_potion_bean_event_outcome)

        self.data.get_events.side_effect = lambda x: {
            (self.pour_command, self.potion, self.bean):
            [pour_potion_bean_event],
        }.get(x)
        self.player.has_completed_event.return_value = True
        self.lighthouse_location.add(self.bean)

        response = self.resolver.resolve_event(self.pour_command, self.player,
                                               self.potion, self.bean)

        self.assertEqual((True, [], [self.potion, self.bean], []), response)
        self.assertTrue(self.lighthouse_location.contains(self.bean))

    def test_resolve_event_with_multiple_events(self):
        prerequisite_kind_0 = EventMatchPrerequisiteKind.LOCATION
        prerequisite_location_0 = self.lighthouse_location
        prerequisite_0 = LocationEventMatchPrerequisite(
            prerequisite_kind_0, False, prerequisite_location_0)

        pour_potion_bean_event_0_match = EventMatch(
            command=self.pour_command,
            arguments=[self.potion, self.bean],
            prerequisites=[prerequisite_0])
        destroy_bean_destination_0 = ItemEventOutcomeActionDestination(
            kind=ItemEventOutcomeActionDestinationKind.DESTROY,
            named_data_element=None)
        destroy_bean_action_0 = ItemEventOutcomeAction(
            kind=EventOutcomeActionKind.ITEM,
            item=self.bean,
            destination=destroy_bean_destination_0)
        pour_potion_bean_event_outcome_0 = EventOutcome(
            text_key="event_response_key", actions=[destroy_bean_action_0])
        pour_potion_bean_event_0 = Event(
            event_id=3003,
            attributes=0x0,
            match=pour_potion_bean_event_0_match,
            outcome=pour_potion_bean_event_outcome_0)

        pour_potion_bean_event_1_match = EventMatch(
            command=self.pour_command,
            arguments=[self.potion, self.bean],
            prerequisites=[])
        pour_potion_bean_event_outcome_1 = EventOutcome(
            text_key="event_response_key", actions=[])
        pour_potion_bean_event_1 = Event(
            event_id=3003,
            attributes=0x0,
            match=pour_potion_bean_event_1_match,
            outcome=pour_potion_bean_event_outcome_1)

        self.data.get_events.side_effect = lambda x: {
            (self.pour_command, self.potion, self.bean):
            [pour_potion_bean_event_0, pour_potion_bean_event_1],
        }.get(x)
        self.lighthouse_location.add(self.bean)

        response = self.resolver.resolve_event(self.pour_command, self.player,
                                               self.potion, self.bean)

        self.assertEqual(
            (True, ["event_response_key"], [self.potion, self.bean
                                            ], [self.potion, self.bean]),
            response)
        self.assertTrue(self.lighthouse_location.contains(self.bean))

    def test_resolve_event_without_special_player_outcomes(self):
        rub_lamp_event_match = EventMatch(command=self.rub_command,
                                          arguments=[self.lamp],
                                          prerequisites=[])
        rub_lamp_event_outcome = EventOutcome(text_key="event_response_key",
                                              actions=[])
        rub_lamp_event = Event(event_id=3001,
                               attributes=0x0,
                               match=rub_lamp_event_match,
                               outcome=rub_lamp_event_outcome)
        self.data.get_events.side_effect = lambda x: {
            (self.rub_command, self.lamp): [rub_lamp_event],
        }.get(x)

        response = self.resolver.resolve_event(self.rub_command, self.player,
                                               self.lamp)

        self.assertEqual(
            (True, ["event_response_key"], [self.lamp], [self.lamp]), response)
        self.player.complete_event.assert_called_once_with(3001)
        self.player.solve_puzzle.assert_not_called()
        self.player.set_playing.assert_not_called()

    def test_resolve_event_end_game(self):
        rub_lamp_event_match = EventMatch(command=self.rub_command,
                                          arguments=[self.lamp],
                                          prerequisites=[])
        rub_lamp_event_outcome = EventOutcome(text_key="event_response_key",
                                              actions=[])
        rub_lamp_event = Event(event_id=3001,
                               attributes=0x1,
                               match=rub_lamp_event_match,
                               outcome=rub_lamp_event_outcome)
        self.data.get_events.side_effect = lambda x: {
            (self.rub_command, self.lamp): [rub_lamp_event],
        }.get(x)

        response = self.resolver.resolve_event(self.rub_command, self.player,
                                               self.lamp)

        self.assertEqual(
            (True, ["event_response_key"], [self.lamp], [self.lamp]), response)
        self.player.set_playing.assert_called_once_with(False)

    def test_resolve_event_puzzle(self):
        wave_wand_event_match = EventMatch(command=self.wave_command,
                                           arguments=[self.wand],
                                           prerequisites=[])
        wave_wand_event_outcome = EventOutcome(text_key="event_response_key",
                                               actions=[])
        wave_wand_event = Event(event_id=3004,
                                attributes=0x4,
                                match=wave_wand_event_match,
                                outcome=wave_wand_event_outcome)
        self.data.get_events.side_effect = lambda x: {
            (self.wave_command, self.wand): [wave_wand_event],
        }.get(x)

        response = self.resolver.resolve_event(self.wave_command, self.player,
                                               self.wand)

        self.assertEqual(
            (True, ["event_response_key"], [self.wand], [self.wand]), response)
        self.player.solve_puzzle.assert_called_once_with(3004)

    def test_resolve_event_with_player_outcome_action_set_attribute(self):
        wave_wand_event_match = EventMatch(command=self.wave_command,
                                           arguments=[self.wand],
                                           prerequisites=[])
        action = PlayerEventOutcomeAction(kind=EventOutcomeActionKind.PLAYER,
                                          attribute=0x8,
                                          on=True)
        wave_wand_event_outcome = EventOutcome(text_key="event_response_key",
                                               actions=[action])
        wave_wand_event = Event(event_id=3004,
                                attributes=0x4,
                                match=wave_wand_event_match,
                                outcome=wave_wand_event_outcome)
        self.data.get_events.side_effect = lambda x: {
            (self.wave_command, self.wand): [wave_wand_event],
        }.get(x)

        response = self.resolver.resolve_event(self.wave_command, self.player,
                                               self.wand)

        self.assertEqual(
            (True, ["event_response_key"], [self.wand], [self.wand]), response)
        self.player.set_attribute.assert_called_once_with(0x8)

    def test_resolve_event_with_player_outcome_action_unset_attribute(self):
        wave_wand_event_match = EventMatch(command=self.wave_command,
                                           arguments=[self.wand],
                                           prerequisites=[])
        action = PlayerEventOutcomeAction(kind=EventOutcomeActionKind.PLAYER,
                                          attribute=0x8,
                                          on=False)
        wave_wand_event_outcome = EventOutcome(text_key="event_response_key",
                                               actions=[action])
        wave_wand_event = Event(event_id=3004,
                                attributes=0x4,
                                match=wave_wand_event_match,
                                outcome=wave_wand_event_outcome)
        self.data.get_events.side_effect = lambda x: {
            (self.wave_command, self.wand): [wave_wand_event],
        }.get(x)

        response = self.resolver.resolve_event(self.wave_command, self.player,
                                               self.wand)

        self.assertEqual(
            (True, ["event_response_key"], [self.wand], [self.wand]), response)
        self.player.unset_attribute.assert_called_once_with(0x8)

    def test_resolve_event_with_location_outcome_action_set_attribute(self):
        wave_wand_event_match = EventMatch(command=self.wave_command,
                                           arguments=[self.wand],
                                           prerequisites=[])
        action = LocationEventOutcomeAction(
            kind=EventOutcomeActionKind.LOCATION,
            location=self.lighthouse_location,
            attribute=0x2,
            on=True)
        wave_wand_event_outcome = EventOutcome(text_key="event_response_key",
                                               actions=[action])
        wave_wand_event = Event(event_id=3004,
                                attributes=0x4,
                                match=wave_wand_event_match,
                                outcome=wave_wand_event_outcome)
        self.data.get_events.side_effect = lambda x: {
            (self.wave_command, self.wand): [wave_wand_event],
        }.get(x)

        response = self.resolver.resolve_event(self.wave_command, self.player,
                                               self.wand)

        self.assertEqual(
            (True, ["event_response_key"], [self.wand], [self.wand]), response)
        self.assertTrue(self.lighthouse_location.gives_air())

    def test_resolve_event_with_location_outcome_action_unset_attribute(self):
        wave_wand_event_match = EventMatch(command=self.wave_command,
                                           arguments=[self.wand],
                                           prerequisites=[])
        action = LocationEventOutcomeAction(
            kind=EventOutcomeActionKind.LOCATION,
            location=self.lighthouse_location,
            attribute=0x1,
            on=False)
        wave_wand_event_outcome = EventOutcome(text_key="event_response_key",
                                               actions=[action])
        wave_wand_event = Event(event_id=3004,
                                attributes=0x4,
                                match=wave_wand_event_match,
                                outcome=wave_wand_event_outcome)
        self.data.get_events.side_effect = lambda x: {
            (self.wave_command, self.wand): [wave_wand_event],
        }.get(x)

        response = self.resolver.resolve_event(self.wave_command, self.player,
                                               self.wand)

        self.assertEqual(
            (True, ["event_response_key"], [self.wand], [self.wand]), response)
        self.assertFalse(self.lighthouse_location.gives_light())

    def test_resolve_event_with_link_outcome_action_add_link(self):
        wave_wand_event_match = EventMatch(command=self.wave_command,
                                           arguments=[self.wand],
                                           prerequisites=[])
        action = LinkEventOutcomeAction(kind=EventOutcomeActionKind.LINK,
                                        source=self.lighthouse_location,
                                        direction=Direction.NORTH,
                                        destination=self.beach_location)
        wave_wand_event_outcome = EventOutcome(text_key="event_response_key",
                                               actions=[action])
        wave_wand_event = Event(event_id=3004,
                                attributes=0x4,
                                match=wave_wand_event_match,
                                outcome=wave_wand_event_outcome)
        self.data.get_events.side_effect = lambda x: {
            (self.wave_command, self.wand): [wave_wand_event],
        }.get(x)

        response = self.resolver.resolve_event(self.wave_command, self.player,
                                               self.wand)

        self.assertEqual(
            (True, ["event_response_key"], [self.wand], [self.wand]), response)
        self.assertEqual(self.beach_location,
                         self.lighthouse_location.directions[Direction.NORTH])

    def test_resolve_event_with_link_outcome_action_remove_link_already_exists(
            self):
        self.lighthouse_location.directions[
            Direction.EAST] = self.beach_location

        wave_wand_event_match = EventMatch(command=self.wave_command,
                                           arguments=[self.wand],
                                           prerequisites=[])
        action = LinkEventOutcomeAction(kind=EventOutcomeActionKind.LINK,
                                        source=self.lighthouse_location,
                                        direction=Direction.EAST,
                                        destination=None)
        wave_wand_event_outcome = EventOutcome(text_key="event_response_key",
                                               actions=[action])
        wave_wand_event = Event(event_id=3004,
                                attributes=0x4,
                                match=wave_wand_event_match,
                                outcome=wave_wand_event_outcome)
        self.data.get_events.side_effect = lambda x: {
            (self.wave_command, self.wand): [wave_wand_event],
        }.get(x)

        response = self.resolver.resolve_event(self.wave_command, self.player,
                                               self.wand)

        self.assertEqual(
            (True, ["event_response_key"], [self.wand], [self.wand]), response)
        self.assertFalse(Direction.EAST in self.lighthouse_location.directions)

    def test_resolve_event_with_link_outcome_action_remove_link_does_not_already_exist(
            self):
        wave_wand_event_match = EventMatch(command=self.wave_command,
                                           arguments=[self.wand],
                                           prerequisites=[])
        action = LinkEventOutcomeAction(kind=EventOutcomeActionKind.LINK,
                                        source=self.lighthouse_location,
                                        direction=Direction.EAST,
                                        destination=None)
        wave_wand_event_outcome = EventOutcome(text_key="event_response_key",
                                               actions=[action])
        wave_wand_event = Event(event_id=3004,
                                attributes=0x4,
                                match=wave_wand_event_match,
                                outcome=wave_wand_event_outcome)
        self.data.get_events.side_effect = lambda x: {
            (self.wave_command, self.wand): [wave_wand_event],
        }.get(x)

        response = self.resolver.resolve_event(self.wave_command, self.player,
                                               self.wand)

        self.assertEqual(
            (True, ["event_response_key"], [self.wand], [self.wand]), response)
        self.assertFalse(Direction.EAST in self.lighthouse_location.directions)

    def test_resolve_event_with_description_outcome_action(self):
        wave_wand_event_match = EventMatch(command=self.wave_command,
                                           arguments=[self.wand],
                                           prerequisites=[])
        action = DescriptionEventOutcomeAction(
            kind=EventOutcomeActionKind.DESCRIPTION,
            named_data_element=self.lighthouse_location,
            extended_description_index=1)
        wave_wand_event_outcome = EventOutcome(text_key="event_response_key",
                                               actions=[action])
        wave_wand_event = Event(event_id=3004,
                                attributes=0x4,
                                match=wave_wand_event_match,
                                outcome=wave_wand_event_outcome)
        self.data.get_events.side_effect = lambda x: {
            (self.wave_command, self.wand): [wave_wand_event],
        }.get(x)

        response = self.resolver.resolve_event(self.wave_command, self.player,
                                               self.wand)

        self.assertEqual(
            (True, ["event_response_key"], [self.wand], [self.wand]), response)
        self.assertEqual(1,
                         self.lighthouse_location.extended_description_index)
Beispiel #16
0
class TestInventory(unittest.TestCase):
    def setUp(self):

        self.inventory = Inventory(
            0, 0x1,
            Labels("Main Inventory", "in the main inventory",
                   ", where items live usually."), 3)
        self.book = Item(1105, 0x2,
                         Labels("book", "a book", "a book of fairytales"), 2,
                         "The Pied Piper", {})
        self.lamp = Item(1043, 0x10101A,
                         Labels("lamp", "a lamp", "a small lamp"), 2, None, {})
        self.coin = Item(1000, 0x2, Labels("coin", "a coin", "a silver coin"),
                         1, None, {})
        self.medal = Item(1001, 0x2, Labels("medal", "a medal",
                                            "a gold medal"), 1, None, {})
        self.suit = UsableItem(1046, 0x402,
                               Labels("suit", "a suit", "a space-suit"), 2,
                               None, {}, Item.ATTRIBUTE_GIVES_AIR)
        self.water = Item(1109, 0x22902,
                          Labels("water", "some water", "some water"), 1, None,
                          {})
        self.basket = ContainerItem(
            1107, 0x3, Labels("basket", "a basket", "a large basket"), 6, None,
            {})
        self.non_essential_drop_location = Location(
            12, 0x1, Labels("Lighthouse", "at a lighthouse", " by the sea."))
        self.essential_drop_location = Location(
            9, 0x0, Labels("Cave", "in a cave", ". It is dark"))

    def test_insert_non_copyable(self):
        self.inventory.insert(self.book)

        self.assertTrue(self.inventory.contains(self.book))

    def test_insert_copyable(self):
        self.inventory.insert(self.water)

        self.assertFalse(self.inventory.contains(self.water))
        water_copy = self.inventory.get_allow_copy(self.water)
        self.assertTrue(water_copy)
        self.assertEqual(self.water.data_id, water_copy.data_id)
        self.assertIs(self.water, water_copy.copied_from)
        self.assertTrue(water_copy in self.water.copied_to)

    def test_can_accommodate_below_capacity(self):
        self.assertTrue(self.inventory.can_accommodate(self.book))

    def test_can_accommodate_to_capacity(self):
        self.inventory.insert(self.book)

        self.assertTrue(self.inventory.can_accommodate(self.coin))

    def test_can_accommodate_at_capacity(self):
        self.inventory.insert(self.book)
        self.inventory.insert(self.medal)

        self.assertFalse(self.inventory.can_accommodate(self.coin))

    def test_can_accommodate_above_capacity_non_wearable(self):
        self.inventory.insert(self.book)

        self.assertFalse(self.inventory.can_accommodate(self.lamp))

    def test_can_accommodate_above_capacity_wearable_not_being_used(self):
        self.inventory.insert(self.suit)
        self.suit.being_used = False

        self.assertFalse(self.inventory.can_accommodate(self.lamp))

    def test_can_accommodate_above_capacity_wearable_being_used(self):
        self.inventory.insert(self.suit)
        self.suit.being_used = True

        self.assertTrue(self.inventory.can_accommodate(self.lamp))

    def test_can_accommodate_remove_above_capacity_wearable_being_used(self):
        self.inventory.insert(self.lamp)
        self.suit.being_used = True

        self.assertFalse(self.inventory.can_accommodate_remove(self.suit))

    def test_drop_all_items_none(self):
        self.inventory.drop_all_items(self.non_essential_drop_location,
                                      self.essential_drop_location)

        self.assertFalse(self.inventory.has_items())
        self.assertFalse(self.non_essential_drop_location.has_items())
        self.assertFalse(self.essential_drop_location.has_items())

    def test_drop_all_items_single(self):
        self.inventory.insert(self.book)

        self.inventory.drop_all_items(self.non_essential_drop_location,
                                      self.essential_drop_location)

        self.assertFalse(self.inventory.has_items())
        self.assertTrue(self.non_essential_drop_location.contains(self.book))
        self.assertFalse(self.essential_drop_location.has_items())

    def test_drop_all_items_multiple_with_only_non_essential(self):
        self.inventory.insert(self.coin)
        self.inventory.insert(self.medal)
        self.inventory.insert(self.book)

        self.inventory.drop_all_items(self.non_essential_drop_location,
                                      self.essential_drop_location)

        self.assertFalse(self.inventory.has_items())
        self.assertTrue(self.non_essential_drop_location.contains(self.coin))
        self.assertTrue(self.non_essential_drop_location.contains(self.medal))
        self.assertTrue(self.non_essential_drop_location.contains(self.book))
        self.assertFalse(self.essential_drop_location.has_items())

    def test_drop_all_items_multiple_with_essential_item_simple(self):
        self.inventory.insert(self.book)
        self.inventory.insert(self.lamp)

        self.inventory.drop_all_items(self.non_essential_drop_location,
                                      self.essential_drop_location)

        self.assertFalse(self.inventory.has_items())
        self.assertTrue(self.non_essential_drop_location.contains(self.book))
        self.assertFalse(self.non_essential_drop_location.contains(self.lamp))
        self.assertTrue(self.essential_drop_location.has_items())
        self.assertFalse(self.essential_drop_location.contains(self.book))
        self.assertTrue(self.essential_drop_location.contains(self.lamp))

    def test_drop_all_items_multiple_with_essential_item_nested(self):
        self.basket.insert(self.lamp)
        self.inventory.insert(self.basket)

        self.inventory.drop_all_items(self.non_essential_drop_location,
                                      self.essential_drop_location)

        self.assertFalse(self.inventory.has_items())
        self.assertFalse(self.non_essential_drop_location.has_items())
        self.assertTrue(self.essential_drop_location.has_items())
        self.assertFalse(self.lamp in self.essential_drop_location.items)
        self.assertTrue(self.basket in self.essential_drop_location.items)
        self.assertTrue(self.basket.contains(self.lamp))
Beispiel #17
0
class TestLocation(unittest.TestCase):

	def setUp(self):
		extended_descriptions = [". The walls are dark and cold", ". The walls are glowing"]
		self.lighthouse_location = Location(12, 0x1, Labels("Lighthouse", "at a lighthouse", " by the sea."))
		self.mine_location = Location(11, 0x0, Labels("Mines", "in the mines", ". There are dark passages everywhere", extended_descriptions))
		self.lower_mine_location = Location(10, 0x200, Labels("Lower mines", "in the lower mines", ". This is the bottom of the mines", extended_descriptions))

		self.book = Item(1105, 2, Labels("book", "a book", "a book of fairytales"), 2, "The Pied Piper", {})
		self.desk = Item(1000, 0x20000, Labels("desk", "a desk", "a large mahogany desk"), 6, None, {})
		self.obstruction = Item(1000, 0x4, Labels("obstruction", "an obstruction", "an obstruction blocking you"), 8, None, {})
		self.basket = ContainerItem(1107, 0x3, Labels("basket", "a basket", "a large basket"), 6, None, {})
		self.box = ContainerItem(1108, 0x3, Labels("box", "a box", "a small box"), 3, None, {})


	def test_contains_simple(self):
		self.mine_location.insert(self.book)

		self.assertEqual(1, len(self.book.containers))
		self.assertTrue(self.mine_location in self.book.containers)
		self.assertTrue(self.mine_location.contains(self.book))


	def test_contains_container_single(self):
		self.box.insert(self.book)
		self.mine_location.insert(self.box)

		self.assertTrue(self.mine_location.contains(self.box))


	def test_contains_container_multi(self):
		self.basket.insert(self.box)
		self.box.insert(self.book)
		self.mine_location.insert(self.basket)

		self.assertTrue(self.mine_location.contains(self.book))


	def test_get_allow_copy_simple(self):
		book_copy = copy(self.book)
		self.mine_location.add(book_copy)

		self.assertFalse(self.mine_location.contains(self.book))
		self.assertEqual(book_copy, self.mine_location.get_allow_copy(self.book))


	def test_get_allow_copy_container(self):
		book_copy = copy(self.book)
		self.box.insert(book_copy)
		self.mine_location.insert(self.box)

		self.assertFalse(self.mine_location.contains(self.book))
		self.assertEqual(book_copy, self.mine_location.get_allow_copy(self.book))


	def test_get_arrival_description_not_seen_not_verbose(self):
		description = self.mine_location.get_arrival_description(False)

		self.assertEqual(["in the mines. There are dark passages everywhere. The walls are dark and cold", ""], description)


	def test_get_arrival_description_not_seen_verbose(self):
		description = self.mine_location.get_arrival_description(True)

		self.assertEqual(["in the mines. There are dark passages everywhere. The walls are dark and cold", ""], description)


	def test_get_arrival_description_seen_not_verbose(self):
		self.mine_location.seen = True

		description = self.mine_location.get_arrival_description(False)

		self.assertEqual(["in the mines", ""], description)


	def test_get_arrival_description_seen_verbose(self):
		self.mine_location.seen = True

		description = self.mine_location.get_arrival_description(True)

		self.assertEqual(["in the mines. There are dark passages everywhere. The walls are dark and cold", ""], description)


	def test_get_full_description_non_silent(self):
		self.mine_location.seen = True
		self.mine_location.insert(self.book)

		description = self.mine_location.get_full_description()

		self.assertEqual(["in the mines. There are dark passages everywhere. The walls are dark and cold", "\n\ta book"], description)


	def test_get_full_description_silent(self):
		self.mine_location.seen = True
		self.mine_location.insert(self.desk)

		description = self.mine_location.get_full_description()

		self.assertEqual(["in the mines. There are dark passages everywhere. The walls are dark and cold", ""], description)


	def test_get_drop_location_has_floor(self):
		self.assertIs(self.lower_mine_location, self.lower_mine_location.get_drop_location())


	def test_get_drop_location_one_below_has_floor(self):
		self.mine_location.directions[Direction.DOWN] = self.lower_mine_location

		self.assertIs(self.lower_mine_location, self.mine_location.get_drop_location())


	def test_get_drop_location_two_below_has_floor(self):
		self.lighthouse_location.directions[Direction.DOWN] = self.mine_location
		self.mine_location.directions[Direction.DOWN] = self.lower_mine_location

		self.assertIs(self.lower_mine_location, self.lighthouse_location.get_drop_location())


	def test_get_obstructions(self):
		self.mine_location.insert(self.book)
		self.mine_location.insert(self.obstruction)

		obstructions = self.mine_location.get_obstructions()

		self.assertEqual(1, len(obstructions))
		self.assertIs(self.obstruction, obstructions[0])


	def test_can_reach_no_ways(self):
		self.assertFalse(self.mine_location.can_reach(self.lighthouse_location))


	def test_can_reach_one_way(self):
		self.mine_location.directions[Direction.SOUTH] = self.lighthouse_location

		self.assertTrue(self.mine_location.can_reach(self.lighthouse_location))


	def test_can_reach_multiple_ways(self):
		self.mine_location.directions[Direction.SOUTH] = self.lighthouse_location
		self.mine_location.directions[Direction.NORTHEAST] = self.lighthouse_location
		self.mine_location.directions[Direction.DOWN] = self.lighthouse_location

		self.assertTrue(self.mine_location.can_reach(self.lighthouse_location))


	def test_gives_tether_with_gravity_with_ceiling(self):
		self.mine_location.set_attribute(Location.ATTRIBUTE_GIVES_GRAVITY)
		self.mine_location.set_attribute(Location.ATTRIBUTE_HAS_CEILING)

		self.assertTrue(self.mine_location.gives_tether())


	def test_gives_tether_with_gravity_without_ceiling(self):
		self.mine_location.set_attribute(Location.ATTRIBUTE_GIVES_GRAVITY)
		self.mine_location.unset_attribute(Location.ATTRIBUTE_HAS_CEILING)

		self.assertTrue(self.mine_location.gives_tether())


	def test_gives_tether_without_gravity_with_ceiling(self):
		self.mine_location.unset_attribute(Location.ATTRIBUTE_GIVES_GRAVITY)
		self.mine_location.set_attribute(Location.ATTRIBUTE_HAS_CEILING)

		self.assertTrue(self.mine_location.gives_tether())


	def test_gives_tether_without_gravity_without_ceiling_with_location_above_that_gives_tether(self):
		self.mine_location.unset_attribute(Location.ATTRIBUTE_GIVES_GRAVITY)
		self.mine_location.unset_attribute(Location.ATTRIBUTE_HAS_CEILING)
		self.mine_location.directions[Direction.UP] = self.lighthouse_location
		self.lighthouse_location.set_attribute(Location.ATTRIBUTE_GIVES_GRAVITY)
		self.lighthouse_location.set_attribute(Location.ATTRIBUTE_HAS_CEILING)

		self.assertTrue(self.mine_location.gives_tether())


	def test_gives_tether_without_gravity_without_ceiling_with_location_above_that_gives_no_tether(self):
		self.mine_location.unset_attribute(Location.ATTRIBUTE_GIVES_GRAVITY)
		self.mine_location.unset_attribute(Location.ATTRIBUTE_HAS_CEILING)
		self.mine_location.directions[Direction.UP] = self.lighthouse_location
		self.lighthouse_location.unset_attribute(Location.ATTRIBUTE_GIVES_GRAVITY)
		self.lighthouse_location.unset_attribute(Location.ATTRIBUTE_HAS_CEILING)

		self.assertFalse(self.mine_location.gives_tether())


	def test_gives_tether_without_gravity_without_ceiling_without_location_above(self):
		self.mine_location.unset_attribute(Location.ATTRIBUTE_GIVES_GRAVITY)
		self.mine_location.unset_attribute(Location.ATTRIBUTE_HAS_CEILING)

		self.assertFalse(self.mine_location.gives_tether())
Beispiel #18
0
class TestItem(unittest.TestCase):
    def setUp(self):
        self.book = Item(1105, 0x2,
                         Labels("book", "a book", "a book of fairytales"), 2,
                         "The Pied Piper", {})
        self.desk = Item(1106, 0x20000,
                         Labels("desk", "a desk", "a large mahogany desk"), 6,
                         None, {})

        rope_list_templates = {
            ListTemplateType.LOCATION: "{0} (coiled neatly)",
            ListTemplateType.CARRYING: "{0} (tied safely)"
        }
        self.rope = Item(1123, 0x2,
                         Labels("rope", "some rope", "a small length of rope"),
                         2, None, rope_list_templates)

        basket_list_templates = {ListTemplateType.DEFAULT: "{0} (upright)"}
        self.basket = ContainerItem(
            1107, 0x3, Labels("basket", "a basket", "a large basket"), 6, None,
            basket_list_templates)
        box_list_templates = {ListTemplateType.DEFAULT: "{0} (open)"}
        self.box = ContainerItem(1108, 0x3,
                                 Labels("box", "a box", "a small box"), 3,
                                 None, box_list_templates)

        lamp_list_templates = {ListTemplateType.DEFAULT: "{0} ({1})"}
        lamp_switching_info = SwitchInfo(Item.ATTRIBUTE_GIVES_LIGHT, "off",
                                         "on")
        self.lamp = SwitchableItem(1043, 0x100A,
                                   Labels("lamp", "a lamp",
                                          "a small lamp"), 2, None,
                                   lamp_list_templates, lamp_switching_info)

        button_list_templates = {ListTemplateType.DEFAULT: "{0} ({1})"}
        button_switching_info = SwitchInfo(Item.ATTRIBUTE_GIVES_LIGHT, "up",
                                           "down")
        self.button = SwitchableItem(
            1044, 0x8,
            Labels("button", "a button", "a red button",
                   [". It is dark", ". It is glowing"]), 2, None,
            button_list_templates, button_switching_info)

        lever_list_templates = {ListTemplateType.DEFAULT: "{0} ({1})"}
        lever_switching_info = SwitchInfo(Location.ATTRIBUTE_GIVES_LIGHT,
                                          "down", "up")
        self.lever = SwitchableItem(
            1045, 0x8, Labels("lever", "a lever", "a mysterious lever"), 2,
            None, lever_list_templates, lever_switching_info)

        suit_list_templates = {ListTemplateType.USING: "{0} (being worn)"}
        self.suit = UsableItem(1046, 0x402,
                               Labels("suit", "a suit",
                                      "a space-suit"), 2, None,
                               suit_list_templates, Item.ATTRIBUTE_GIVES_AIR)

        self.cat = SentientItem(1047, 0x80002,
                                Labels("cat", "a cat", "a black cat"), 3, None,
                                {})
        self.water = Item(
            1109, 0x22902,
            Labels("water", "some water", "some water",
                   [". It is cold", ". It is hot"]), 1, None, {})
        self.mine_location = Location(
            11, 0x0,
            Labels("Mines", "in the mines",
                   ". There are dark passages everywhere."))
        self.inventory = Inventory(
            0, 0x1,
            Labels("Main Inventory", "in the main inventory",
                   ", where items live usually."), 100)

        self.steam = Item(1117, 0x2,
                          Labels("steam", "some steam", "some hot steam"), 1,
                          None, {})
        self.water.transformations[98] = self.steam

    def test_copy(self):
        water_copy = copy(self.water)
        self.assertEqual(self.water.data_id, water_copy.data_id)
        self.assertEqual(self.water.shortname, water_copy.shortname)
        self.assertEqual(self.water.longname, water_copy.longname)
        self.assertEqual(self.water.description, water_copy.description)
        self.assertEqual(self.water.extended_descriptions,
                         water_copy.extended_descriptions)
        self.assertFalse(water_copy.is_copyable())
        self.assertIs(self.steam, water_copy.transformations[98])
        self.assertIs(self.water, water_copy.copied_from)
        self.assertTrue(water_copy in self.water.copied_to)

    def test_get_original_not_copied(self):
        self.assertEqual(self.book, self.book.get_original())

    def test_get_original_copied_once(self):
        water_copy = copy(self.water)

        self.assertEqual(self.water, water_copy.get_original())

    def test_get_original_copied_twice(self):
        water_copy = copy(self.water)
        water_copy_copy = copy(water_copy)

        self.assertEqual(self.water, water_copy_copy.get_original())

    def test_break_open_non_container(self):
        self.assertIsNone(self.lamp.break_open())

    def test_get_list_name_location_no_list_templates(self):
        self.assertEqual("\n\ta book", self.book.get_list_name_location())

    def test_get_list_name_inventory_no_list_templates(self):
        self.assertEqual("\n\ta book", self.book.get_list_name_inventory())

    def test_get_list_name_location_with_list_template(self):
        self.assertEqual("\n\tsome rope (coiled neatly)",
                         self.rope.get_list_name_location())

    def test_get_list_name_inventory_with_list_template(self):
        self.assertEqual("\n\tsome rope (tied safely)",
                         self.rope.get_list_name_inventory())

    def test_get_full_description_without_extended_descriptions(self):
        self.assertEqual(["a book of fairytales"],
                         self.book.get_full_description())

    def test_get_full_description_with_extended_descriptions(self):
        self.assertEqual(["some water. It is cold"],
                         self.water.get_full_description())

    def test_break_open_container(self):
        self.box.insert(self.book)

        self.assertEqual(self.book, self.box.break_open())

    def test_get_list_name_location_empty(self):
        self.assertEqual("\n\ta box (open) (---)",
                         self.box.get_list_name_location())

    def test_get_list_name_location_container_nonempty_single(self):
        self.box.insert(self.book)

        self.assertEqual("\n\ta box (open) +\n\t\ta book",
                         self.box.get_list_name_location())

    def test_get_list_name_location_container_nonempty_multi(self):
        self.basket.insert(self.box)
        self.box.insert(self.book)

        self.assertEqual(
            "\n\ta basket (upright) +\n\t\ta box (open) +\n\t\t\ta book",
            self.basket.get_list_name_location())

    def test_contains_simple(self):
        self.assertFalse(self.desk.contains(self.book))

    def test_contains_container_empty(self):
        self.assertFalse(self.basket.contains(self.book))

    def test_contains_container_nonempty_single(self):
        self.box.insert(self.book)

        self.assertTrue(self.box.contains(self.book))

    def test_contains_container_nonempty_multi(self):
        self.basket.insert(self.box)
        self.box.insert(self.book)

        self.assertTrue(self.basket.contains(self.box))
        self.assertTrue(self.box.contains(self.book))
        self.assertTrue(self.basket.contains(self.book))

    def test_get_allow_copy_single(self):
        book_copy = copy(self.book)
        self.box.insert(book_copy)

        self.assertFalse(self.box.contains(self.book))
        self.assertEqual(book_copy, self.box.get_allow_copy(self.book))

    def test_get_allow_copy_multi(self):
        book_copy = copy(self.book)
        self.box.insert(book_copy)
        self.basket.insert(self.box)

        self.assertFalse(self.basket.contains(self.book))
        self.assertEqual(book_copy, self.basket.get_allow_copy(self.book))

    def test_get_outermost_container_location(self):
        self.mine_location.insert(self.book)

        self.assertEqual(self.mine_location,
                         self.book.get_outermost_container())

    def test_get_outermost_container_inventory(self):
        self.inventory.insert(self.book)

        self.assertEqual(self.inventory, self.book.get_outermost_container())

    def test_get_outermost_container_multi(self):
        self.mine_location.insert(self.basket)
        self.basket.insert(self.box)
        self.box.insert(self.book)

        self.assertEqual(self.mine_location,
                         self.book.get_outermost_container())

    def test_get_list_name_location_sentient(self):
        self.assertEqual("\n\ta cat", self.cat.get_list_name_location())

    def test_get_list_name_sentient_carrying_item(self):
        self.cat.insert(self.book)

        self.assertEqual("\n\ta cat +\n\t\ta book",
                         self.cat.get_list_name_location())

    def test_switch_on_self(self):
        self.lamp.switched_element = self.lamp

        self.lamp.switch_on()

        self.assertTrue(self.lamp.gives_light())

    def test_switch_off_self(self):
        self.lamp.switched_element = self.lamp

        self.lamp.switch_off()

        self.assertFalse(self.lamp.gives_light())

    def test_switch_on_other_item(self):
        self.button.switched_element = self.lamp

        self.button.switch_on()

        self.assertTrue(self.lamp.gives_light())

    def test_switch_off_other_item(self):
        self.button.switched_element = self.lamp

        self.button.switch_off()

        self.assertFalse(self.lamp.gives_light())

    def test_switch_on_other_location(self):
        self.lever.switched_element = self.mine_location

        self.lever.switch_on()

        self.assertTrue(self.mine_location.gives_light())

    def test_switch_off_other_location(self):
        self.lever.switched_element = self.mine_location

        self.lever.switch_off()

        self.assertFalse(self.mine_location.gives_light())

    def test_get_list_name_location_switchable_off(self):
        self.lamp.switched_element = self.lamp
        self.lamp.switch_off()

        self.assertEqual("\n\ta lamp (off)",
                         self.lamp.get_list_name_location())

    def test_get_list_name_location_switchable_on(self):
        self.lever.switched_element = self.mine_location
        self.lever.switch_on()

        self.assertEqual("\n\ta lever (up)",
                         self.lever.get_list_name_location())

    def test_get_full_description_switchable_without_extended_descriptions(
            self):
        self.lamp.switched_element = self.lamp
        self.lamp.switch_off()

        self.assertEqual(["a small lamp", "off"],
                         self.lamp.get_full_description())

    def test_get_full_description_switchable_with_extended_descriptions(self):
        self.button.switched_element = self.lamp
        self.button.switch_off()

        self.assertEqual(["a red button. It is dark", "up"],
                         self.button.get_full_description())

    def test_has_attribute_wearable_not_being_used(self):
        self.suit.being_used = False

        self.assertFalse(self.suit.gives_air())

    def test_has_attribute_wearable_being_used(self):
        self.suit.being_used = True

        self.assertTrue(self.suit.gives_air())

    def test_list_name_inventory_wearable_not_being_used(self):
        self.suit.being_used = False

        self.assertEqual("\n\ta suit", self.suit.get_list_name_inventory())

    def test_list_name_inventory_wearable_being_used(self):
        self.suit.being_used = True

        self.assertEqual("\n\ta suit (being worn)",
                         self.suit.get_list_name_inventory())