@Test
  public void isLastId_tableTwoItemsAdded_returnsTrueForLastAddedItem() throws SQLException {
    container.addItem();

    Object id2 = container.addItem();

    assertTrue(container.isLastId(id2));
  }
  @Test
  public void getIdByIndex_tableAddedItemRemoved_resultChanges() throws SQLException {
    Object id = container.addItem();
    container.addItem();
    int index = container.indexOfId(id);

    assertTrue(container.removeItem(id));
    Assert.assertNotSame(id, container.getIdByIndex(index));
  }
  @Test
  public void prevItemId_tableAddedItemRemoved_skipsRemovedItem() throws SQLException {
    Object first = container.lastItemId();
    Object second = container.addItem();
    Object third = container.addItem();

    assertTrue(container.removeItem(second));
    assertEquals(first, container.prevItemId(third));
  }
  @Test
  public void firstItemId_tableNewlyAddedFirstItemRemoved_resultChanges() throws SQLException {
    SQLContainer garbageContainer = getGarbageContainer();

    Object first = garbageContainer.addItem();
    Object second = garbageContainer.addItem();

    Assert.assertSame(first, garbageContainer.firstItemId());
    assertTrue(garbageContainer.removeItem(first));
    Assert.assertSame(second, garbageContainer.firstItemId());
  }
  @Test
  public void isFirstId_tableAddedFirstItemRemoved_returnsFalse() throws SQLException {
    SQLContainer garbageContainer = getGarbageContainer();

    Object first = garbageContainer.addItem();
    garbageContainer.addItem();

    Assert.assertSame(first, garbageContainer.firstItemId());
    assertTrue(garbageContainer.removeItem(first));
    Assert.assertFalse(garbageContainer.isFirstId(first));
  }
 @Test
 public void lastItemId_tableNewlyAddedItem_returnsNewlyAdded() throws SQLException {
   Object lastId = container.lastItemId();
   Object id = container.addItem();
   assertEquals(id, container.lastItemId());
   Assert.assertNotSame(lastId, container.lastItemId());
 }
 @Test
 public void addItem_tableAddOneNewItem_autoCommit_sizeIsIncreased() throws SQLException {
   container.setAutoCommit(true);
   int originalSize = container.size();
   container.addItem();
   assertEquals(originalSize + 1, container.size());
 }
  @Test
  public void prevItemId_tableTwoNewlyAddedItems_returnsFirstAddedItem() throws SQLException {
    Object id1 = container.addItem();
    Object id2 = container.addItem();

    assertEquals(id1, container.prevItemId(id2));
  }
  @Test
  public void getIdByIndex_tableOneItemAddedLastIndexInContainer_returnsAddedItem()
      throws SQLException {
    Object id = container.addItem();

    assertEquals(id, container.getIdByIndex(container.size() - 1));
  }
  @Test
  public void commit_tableTwoAddedItems_shouldBeWrittenToDB() throws SQLException {
    Object id = container.addItem();
    Object id2 = container.addItem();
    container.getContainerProperty(id, NAME).setValue("Herbert");
    container.getContainerProperty(id2, NAME).setValue("Larry");
    assertTrue(id2 instanceof TemporaryRowId);
    Assert.assertSame(id2, container.lastItemId());
    container.commit();
    Object nextToLast = container.getIdByIndex(container.size() - 2);

    Assert.assertFalse(nextToLast instanceof TemporaryRowId);
    assertEquals("Herbert", container.getContainerProperty(nextToLast, NAME).getValue());
    Assert.assertFalse(container.lastItemId() instanceof TemporaryRowId);
    assertEquals("Larry", container.getContainerProperty(container.lastItemId(), NAME).getValue());
  }
  @Test
  public void indexOfId_tableAddedItemRemoved_returnsNegOne() throws SQLException {
    Object id = container.addItem();

    assertTrue(container.indexOfId(id) != -1);
    assertTrue(container.removeItem(id));
    assertEquals(-1, container.indexOfId(id));
  }
  @Test
  public void getItem_tableAddedItemRemoved_returnsNull() throws SQLException {
    Object id = container.addItem();

    Assert.assertNotNull(container.getItem(id));
    assertTrue(container.removeItem(id));
    Assert.assertNull(container.getItem(id));
  }
 @Test
 public void addItem_tableAddOneNewItem_autoCommit_returnsFinalItemId() throws SQLException {
   container.setAutoCommit(true);
   Object itemId = container.addItem();
   Assert.assertNotNull(itemId);
   assertTrue(itemId instanceof RowId);
   Assert.assertFalse(itemId instanceof TemporaryRowId);
 }
  @Test
  public void isLastId_tableAddedLastItemRemoved_returnsFalse() throws SQLException {
    Object last = container.addItem();

    Assert.assertSame(last, container.lastItemId());
    assertTrue(container.removeItem(last));
    Assert.assertFalse(container.isLastId(last));
  }
  @Test
  public void containsId_tableAddedItemRemoved_returnsFalse() throws SQLException {
    Object id = container.addItem();

    assertTrue(container.containsId(id));
    assertTrue(container.removeItem(id));
    Assert.assertFalse(container.containsId(id));
  }
  @Test
  public void lastItemId_tableAddedLastItemRemoved_resultChanges() throws SQLException {
    Object last = container.addItem();

    Assert.assertSame(last, container.lastItemId());
    assertTrue(container.removeItem(last));
    Assert.assertNotSame(last, container.lastItemId());
  }
 @Test
 public void getContainerProperty_tableNewlyAddedItem_returnsPropertyOfNewlyAddedItem()
     throws SQLException {
   Object id = container.addItem();
   Item item = container.getItem(id);
   item.getItemProperty(NAME).setValue("asdf");
   assertEquals("asdf", container.getContainerProperty(id, NAME).getValue());
 }
  @Test
  public void removeAllItems_tableAddedItems_shouldSucceed() throws SQLException {
    container.addItem();
    container.addItem();

    assertTrue(container.removeAllItems());
    assertEquals(0, container.size());
  }
  @Test
  public void getItemIds_tableAddedItemRemoved_shouldNotContainRemovedItem() throws SQLException {
    Object id = container.addItem();

    assertTrue(container.getItemIds().contains(id));
    assertTrue(container.removeItem(id));
    Assert.assertFalse(container.getItemIds().contains(id));
  }
  @Test
  public void isFirstId_tableEmptyResultSet_returnsFirstAddedItem() throws SQLException {
    SQLContainer garbageContainer = getGarbageContainer();

    Object id = garbageContainer.addItem();

    assertTrue(garbageContainer.isFirstId(id));
  }
  @Test
  public void firstItemId_tableEmptyResultSet_returnsFirstAddedItem() throws SQLException {
    SQLContainer garbageContainer = getGarbageContainer();

    Object id = garbageContainer.addItem();

    Assert.assertSame(id, garbageContainer.firstItemId());
  }
 @Test
 public void addItem_tableAddTwoNewItems_shouldChangeSize() throws SQLException {
   int size = container.size();
   Object id1 = container.addItem();
   Object id2 = container.addItem();
   assertEquals(size + 2, container.size());
   Assert.assertNotSame(id1, id2);
   Assert.assertFalse(id1.equals(id2));
 }
  @Test
  public void removeItem_tableOneAddedItem_removesTheAddedItem() throws SQLException {
    Object id = container.addItem();
    int size = container.size();

    assertTrue(container.removeItem(id));
    Assert.assertFalse(container.containsId(id));
    assertEquals(size - 1, container.size());
  }
  @Test
  public void newItemIsAdded() throws SQLException {
    Object id = container.addItem();
    getItem(id).getItemProperty(NAME).setValue("foo");

    container.commit();

    Item item = getItem(container.lastItemId());
    assertThat(item.getItemProperty(NAME).getValue().toString(), is("foo"));
  }
  @Test
  public void addFilter_tableBufferedItems_alsoFiltersBufferedItems() throws SQLException {
    // Ville, Kalle, Pelle, Börje
    assertEquals(4, container.size());
    assertEquals("Börje", container.getContainerProperty(container.lastItemId(), NAME).getValue());

    Object id1 = container.addItem();
    container.getContainerProperty(id1, NAME).setValue("Palle");
    Object id2 = container.addItem();
    container.getContainerProperty(id2, NAME).setValue("Bengt");

    container.addContainerFilter(new Like(NAME, "%lle"));

    // Ville, Kalle, Pelle, Palle
    assertEquals(4, container.size());
    assertEquals(
        "Ville", container.getContainerProperty(container.getIdByIndex(0), NAME).getValue());
    assertEquals(
        "Kalle", container.getContainerProperty(container.getIdByIndex(1), NAME).getValue());
    assertEquals(
        "Pelle", container.getContainerProperty(container.getIdByIndex(2), NAME).getValue());
    assertEquals(
        "Palle", container.getContainerProperty(container.getIdByIndex(3), NAME).getValue());

    try {
      container.getIdByIndex(4);
      Assert.fail(
          "SQLContainer.getIdByIndex() returned a value for an index beyond the end of the container");
    } catch (IndexOutOfBoundsException e) {
      // should throw exception - item is filtered out
    }
    Assert.assertNull(container.nextItemId(container.getIdByIndex(3)));

    Assert.assertFalse(container.containsId(id2));
    Assert.assertFalse(container.getItemIds().contains(id2));

    Assert.assertNull(container.getItem(id2));
    assertEquals(-1, container.indexOfId(id2));

    Assert.assertNotSame(id2, container.lastItemId());
    Assert.assertSame(id1, container.lastItemId());
  }
  @Test
  public void itemSetChangeListeners_table_shouldFire() throws SQLException {
    ItemSetChangeListener listener = EasyMock.createMock(ItemSetChangeListener.class);
    listener.containerItemSetChange(EasyMock.isA(ItemSetChangeEvent.class));
    EasyMock.replay(listener);

    container.addListener(listener);
    container.addItem();

    EasyMock.verify(listener);
  }
  @Test
  public void removeListener_table_shouldNotFire() throws SQLException {
    ItemSetChangeListener listener = EasyMock.createMock(ItemSetChangeListener.class);
    EasyMock.replay(listener);

    container.addListener(listener);
    container.removeListener(listener);
    container.addItem();

    EasyMock.verify(listener);
  }
 @Test
 public void rollback_tableItemAdded_discardsAddedItem() throws SQLException {
   int size = container.size();
   Object id = container.addItem();
   container.getContainerProperty(id, NAME).setValue("foo");
   assertEquals(size + 1, container.size());
   container.rollback();
   assertEquals(size, container.size());
   Assert.assertFalse(
       "foo".equals(container.getContainerProperty(container.lastItemId(), NAME).getValue()));
 }
  @Test
  public void commit_tableAddedItem_shouldBeWrittenToDB() throws SQLException {
    Object id = container.addItem();
    container.getContainerProperty(id, NAME).setValue("New Name");

    assertTrue(id instanceof TemporaryRowId);
    Assert.assertSame(id, container.lastItemId());
    container.commit();
    Assert.assertFalse(container.lastItemId() instanceof TemporaryRowId);
    assertEquals(
        "New Name", container.getContainerProperty(container.lastItemId(), NAME).getValue());
  }
  @Test
  public void sort_tableBufferedItems_sortsBufferedItemsLastInOrderAdded() throws SQLException {
    // Ville, Kalle, Pelle, Börje
    assertEquals("Ville", container.getContainerProperty(container.firstItemId(), NAME).getValue());
    assertEquals("Börje", container.getContainerProperty(container.lastItemId(), NAME).getValue());

    Object id1 = container.addItem();
    container.getContainerProperty(id1, NAME).setValue("Wilbert");
    Object id2 = container.addItem();
    container.getContainerProperty(id2, NAME).setValue("Albert");

    container.sort(new Object[] {NAME}, new boolean[] {true});

    // Börje, Kalle, Pelle, Ville, Wilbert, Albert
    assertEquals("Börje", container.getContainerProperty(container.firstItemId(), NAME).getValue());
    assertEquals(
        "Wilbert",
        container
            .getContainerProperty(container.getIdByIndex(container.size() - 2), NAME)
            .getValue());
    assertEquals("Albert", container.getContainerProperty(container.lastItemId(), NAME).getValue());
  }