@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 added_items_are_added_to_available_items_text() {
    Location l = new Location("", "Location description.", null, null);
    l.addItem(makeMockItem("name"));
    l.addItem(makeMockItem("name2"));
    l.addItem(makeMockItem("name3"));

    assertEquals("There is a name, a name2 and a name3 here.\n", l.availableItemsText());
  }
  @Test
  public void when_first_item_in_list_plural_use_There_are() {
    Location l = new Location("", "Location description.", null, null);
    Item item1 = makeMockItem("names");
    when(item1.countableNounPrefix()).thenReturn("some");
    when(item1.plural()).thenReturn(true);
    l.addItem(item1);
    l.addItem(makeMockItem("name2"));

    assertEquals("There are some names and a name2 here.\n", l.availableItemsText());
  }
  @Test
  public void item_must_be_visible_to_effect_choice_of_There_are() {
    Location l = new Location("", "Location description.", null, null);
    Item invisibleSingularItem = makeMockItem("invisible singular item");
    when(invisibleSingularItem.visible()).thenReturn(false);
    when(invisibleSingularItem.plural()).thenReturn(false);
    l.addItem(invisibleSingularItem);
    Item pluralItem = makeMockItem("plural items");
    when(pluralItem.countableNounPrefix()).thenReturn("some");
    when(pluralItem.visible()).thenReturn(true);
    when(pluralItem.plural()).thenReturn(true);
    l.addItem(pluralItem);

    assertThat(l.availableItemsText(), containsString("There are "));
  }
 @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 names_without_a_countable_noun_prefix_have_no_prefix_added() {
    Location l = new Location("", "Location description.", null, null);
    Item item = makeMockItem("Elvis");
    when(item.countableNounPrefix()).thenReturn("");
    l.addItem(item);

    assertThat(l.availableItemsText(), containsString("is Elvis here"));
  }
  @Test
  public void added_items_are_retrieveable() {
    Item item = mock(Item.class);
    Location l = createLocation();

    l.addItem(item);

    assertThat(l.items(), equalTo(list(item)));
  }
  @Test
  public void only_visible_items_can_be_spoken_to() {
    Item visibleItem = mock(Item.class);
    when(visibleItem.canTalkTo()).thenReturn(true);
    when(visibleItem.visible()).thenReturn(true);
    Item notVisibleItem = mock(Item.class);
    when(notVisibleItem.canTalkTo()).thenReturn(true);
    when(notVisibleItem.visible()).thenReturn(false);
    TalkToAction talkToAction = mock(TalkToAction.class);
    ActionFactory actionFactory = mock(ActionFactory.class);
    when(actionFactory.createTalkToAction(visibleItem)).thenReturn(talkToAction);

    Location l = new Location("", "", null, actionFactory);
    l.addItem(visibleItem);
    l.addItem(notVisibleItem);

    assertThat(l.actions(), hasItem(talkToAction));
    verify(actionFactory, never()).createTalkToAction(notVisibleItem);
  }
  @Test
  public void actions_uses_action_factory_to_create_TalkTo_action_for_all_canTalkTo_items() {
    Item talkableItem = mock(Item.class);
    when(talkableItem.canTalkTo()).thenReturn(true);
    when(talkableItem.visible()).thenReturn(true);
    Item notTalkPhraseSourceItem = mock(Item.class);
    when(notTalkPhraseSourceItem.canTalkTo()).thenReturn(false);
    when(notTalkPhraseSourceItem.visible()).thenReturn(true);
    TalkToAction talkToAction = mock(TalkToAction.class);
    ActionFactory actionFactory = mock(ActionFactory.class);
    when(actionFactory.createTalkToAction(talkableItem)).thenReturn(talkToAction);

    Location l = new Location("", "", null, actionFactory);
    l.addItem(talkableItem);
    l.addItem(notTalkPhraseSourceItem);

    assertThat(l.actions(), hasItem(talkToAction));
    verify(actionFactory, never()).createTalkToAction(notTalkPhraseSourceItem);
  }
 @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();
 }