@Test
 public void removing_all_items_from_a_location_removes_TakeAnItem_action_from_action_list() {
   final Item takeableItem = mockery.mock(Item.class);
   final ActionFactory actionFactory = mockery.mock(ActionFactory.class);
   final Location l = new Location("", "", null, actionFactory);
   mockery.checking(
       new Expectations() {
         {
           allowing(takeableItem).visible();
           will(returnValue(true));
           allowing(takeableItem).takeable();
           will(returnValue(true));
           ignoring(takeableItem);
           never(actionFactory)
               .createTakeAnItemAction(
                   with(any(List.class)),
                   with(any(UserInventory.class)),
                   with(any(ModelLocation.class)));
           ignoring(actionFactory);
         }
       });
   l.addItem(takeableItem);
   l.removeItem(takeableItem);
   l.actions();
 }
  @Test
  public void actions_uses_action_factory_to_create_ExamineAnItem_action_for_all_visible_items() {
    final Item visibleItem = mockery.mock(Item.class, "visible item");
    final Item invisibleItem = mockery.mock(Item.class, "invisible item");
    final ActionFactory actionFactory = mockery.mock(ActionFactory.class);
    final Action examineAnItemAction = mockery.mock(Action.class);
    final List<Item> visibleItems = new ArrayList<Item>();
    visibleItems.add(visibleItem);
    mockery.checking(
        new Expectations() {
          {
            allowing(visibleItem).visible();
            will(returnValue(true));
            ignoring(visibleItem);
            allowing(invisibleItem).visible();
            will(returnValue(false));
            ignoring(invisibleItem);
            oneOf(actionFactory).createExamineAnItemAction(with(equal(visibleItems)));
            will(returnValue(examineAnItemAction));
            ignoring(actionFactory);
          }
        });
    Location l = new Location("", "", null, actionFactory);
    l.addItem(visibleItem);
    l.addItem(invisibleItem);

    List<Action> actions = l.actions();
    assertTrue(actions.size() > 0);
    assertThat(actions.get(0), is(examineAnItemAction));
  }
  @Test
  public void available_items_text_includes_only_visible_items() {
    final Item visibleItem = mockery.mock(Item.class, "visible item");
    final Item invisibleItem = mockery.mock(Item.class, "invisible item");
    mockery.checking(
        new Expectations() {
          {
            allowing(visibleItem).visible();
            will(returnValue(true));
            allowing(visibleItem).countableNounPrefix();
            will(returnValue("a"));
            allowing(visibleItem).midSentenceCasedName();
            will(returnValue("visible item"));
            ignoring(visibleItem);
            allowing(invisibleItem).visible();
            will(returnValue(false));
            allowing(invisibleItem).midSentenceCasedName();
            will(returnValue("invisible item"));
            ignoring(invisibleItem);
          }
        });
    Location l = new Location("", "Location description.", null, null);
    l.addItem(visibleItem);
    l.addItem(invisibleItem);

    assertEquals("There is a visible item here.\n", l.availableItemsText());
  }
  @Test
  public void all_valid_exits_are_retrieveable() {
    final Exit exit1 = mockery.mock(Exit.class, "exit1");
    final Exit exit2 = mockery.mock(Exit.class, "exit2");
    mockery.checking(
        new Expectations() {
          {
            allowing(exit1).visible();
            will(returnValue(true));
            ignoring(exit1);
            allowing(exit2).visible();
            will(returnValue(true));
            ignoring(exit2);
          }
        });
    List<Exit> exits = new ArrayList<Exit>();
    exits.add(exit1);
    exits.add(exit2);

    Location l = createLocation();
    l.addExit(exit1);
    l.addExit(exit2);

    assertEquals(exits, l.visibleExits());
  }
  @Test
  public void using_an_item_causes_the_target_item_to_be_used() {
    final Item original = mockery.mock(Item.class, "original");
    final Item target = mockery.mock(Item.class, "target");
    mockery.checking(
        new Expectations() {
          {
            allowing(original).id();
            will(returnValue("originalid"));
            ignoring(original);
            oneOf(target).useWith(original);
            ignoring(target);
          }
        });
    UseWithSpecificItem action = new UseWithSpecificItem(original, target);

    action.trigger();
  }
 @Test
 public void exits_that_havent_been_added_are_not_exitable() {
   final Exit exit = mockery.mock(Exit.class);
   mockery.checking(
       new Expectations() {
         {
           ignoring(exit);
         }
       });
   Location l = createLocation();
   assertFalse(l.exitable(exit));
 }
  @Test
  public void using_an_item_changes_the_user_text_to_the_use_with_message_of_the_target_item() {
    final Item original = mockery.mock(Item.class, "original");
    final Item target = mockery.mock(Item.class, "target");
    mockery.checking(
        new Expectations() {
          {
            ignoring(original);
            allowing(target).canBeUsedWith(original);
            will(returnValue(true));
            allowing(target).useWith(original);
            will(returnValue("use with text"));
            ignoring(target);
          }
        });
    UseWithSpecificItem action = new UseWithSpecificItem(original, target);

    action.trigger();

    assertThat(action.userText(), stringEndsWith("use with text"));
  }
 @Test
 public void exit_destination_is_retrievable() {
   final Exit exit = mockery.mock(Exit.class);
   mockery.checking(
       new Expectations() {
         {
           allowing(exit).destination();
           will(returnValue("destination"));
           ignoring(exit);
         }
       });
   Location l = createLocation();
   assertEquals("destination", l.exitDestinationFor(exit));
 }
 @Test
 public void non_visible_exits_are_not_in_the_exits_list() {
   final Exit exit = mockery.mock(Exit.class);
   mockery.checking(
       new Expectations() {
         {
           allowing(exit).visible();
           will(returnValue(false));
           ignoring(exit);
         }
       });
   Location l = createLocation();
   l.addExit(exit);
   assertEquals(0, l.visibleExits().size());
 }
 @Test
 public void non_visible_exits_are_not_exitable() {
   final Exit exit = mockery.mock(Exit.class);
   mockery.checking(
       new Expectations() {
         {
           allowing(exit).visible();
           will(returnValue(false));
           ignoring(exit);
         }
       });
   Location l = createLocation();
   l.addExit(exit);
   assertFalse(l.exitable(exit));
 }
 @Test
 public void added_exit_makes_the_exit_exitable() {
   final Exit exit = mockery.mock(Exit.class);
   mockery.checking(
       new Expectations() {
         {
           allowing(exit).visible();
           will(returnValue(true));
           ignoring(exit);
         }
       });
   Location l = createLocation();
   l.addExit(exit);
   assertTrue(l.exitable(exit));
 }
 @Test
 public void location_action_to_take_an_item_is_not_included_if_only_untakeable_items_available() {
   final Item untakeableItem = mockery.mock(Item.class, "untakeable item");
   final ActionFactory actionFactory = mockery.mock(ActionFactory.class);
   final Location l = new Location("", "", null, actionFactory);
   mockery.checking(
       new Expectations() {
         {
           allowing(untakeableItem).visible();
           will(returnValue(true));
           allowing(untakeableItem).takeable();
           will(returnValue(false));
           ignoring(untakeableItem);
           never(actionFactory)
               .createTakeAnItemAction(
                   with(any(List.class)),
                   with(any(UserInventory.class)),
                   with(any(ModelLocation.class)));
           ignoring(actionFactory);
         }
       });
   l.addItem(untakeableItem);
   l.actions();
 }
  @Test
  public void label_is_target_item_name() {
    final Item item = mockery.mock(Item.class);
    mockery.checking(
        new Expectations() {
          {
            allowing(item).name();
            will(returnValue("Item name"));
            ignoring(item);
          }
        });
    UseWithSpecificItem action = new UseWithSpecificItem(null, item);

    assertEquals("Item name", action.label());
  }
 @Test
 public void a_location_without_items_does_not_need_a_TakeAnItem_action() {
   final ActionFactory actionFactory = mockery.mock(ActionFactory.class);
   final Location l = new Location("", "", null, actionFactory);
   mockery.checking(
       new Expectations() {
         {
           never(actionFactory)
               .createTakeAnItemAction(
                   with(any(List.class)),
                   with(any(UserInventory.class)),
                   with(any(ModelLocation.class)));
           ignoring(actionFactory);
         }
       });
   l.actions();
 }