@Test
  public void holdsSnipersInAdditionOrder() {
    AuctionSniper sniper2 = new AuctionSniper(new Item("item 1", 345), null);
    context.checking(
        new Expectations() {
          {
            ignoring(listener);
          }
        });

    model.sniperAdded(sniper);
    model.sniperAdded(sniper2);

    assertEquals(ITEM_ID, cellValue(0, Column.ITEM_IDENTIFIER));
    assertEquals("item 1", cellValue(1, Column.ITEM_IDENTIFIER));
  }
  @Test
  public void notifiesListenersWhenAddingASniper() {
    context.checking(
        new Expectations() {
          {
            one(listener).tableChanged(with(anInsertionAtRow(0)));
          }
        });

    assertEquals(0, model.getRowCount());

    model.sniperAdded(sniper);

    assertEquals(1, model.getRowCount());
    assertRowMatchesSnapshot(0, SniperSnapshot.joining(ITEM_ID));
  }
  @Test
  public void setsSniperValuesInColumns() {
    SniperSnapshot bidding = sniper.getSnapshot().bidding(555, 666);
    context.checking(
        new Expectations() {
          {
            allowing(listener).tableChanged(with(anyInsertionEvent()));

            one(listener).tableChanged(with(aChangeInRow(0)));
          }
        });

    model.sniperAdded(sniper);
    model.sniperStateChanged(bidding);

    assertRowMatchesSnapshot(0, bidding);
  }
  @Test
  public void updatesCorrectRowForSniper() {
    AuctionSniper sniper2 = new AuctionSniper(new Item("item 1", 345), null);
    context.checking(
        new Expectations() {
          {
            allowing(listener).tableChanged(with(anyInsertionEvent()));

            one(listener).tableChanged(with(aChangeInRow(1)));
          }
        });

    model.sniperAdded(sniper);
    model.sniperAdded(sniper2);

    SniperSnapshot winning1 = sniper2.getSnapshot().winning(123);
    model.sniperStateChanged(winning1);

    assertRowMatchesSnapshot(1, winning1);
  }
  @Test
  public void acceptsNewSniper() {
    context.checking(
        new Expectations() {
          {
            one(listener).tableChanged(with(anInsertionAtRow(0)));
          }
        });

    model.sniperAdded(sniper);

    assertRowMatchesSnapshot(0, SniperSnapshot.joining(ITEM_ID));
  }
 @Test
 public void setsUpColumnHeadings() {
   for (Column column : Column.values()) {
     assertEquals(column.name, model.getColumnName(column.ordinal()));
   }
 }
 @Test
 public void hasEnoughColumns() {
   assertThat(model.getColumnCount(), equalTo(Column.values().length));
 }
 @Before
 public void attachModelListener() {
   model.addTableModelListener(listener);
 }
 private Object cellValue(int rowIndex, Column column) {
   return model.getValueAt(rowIndex, column.ordinal());
 }
 private void assertRowMatchesSnapshot(int row, SniperSnapshot snapshot) {
   assertEquals(snapshot.itemId, cellValue(row, Column.ITEM_IDENTIFIER));
   assertEquals(snapshot.lastPrice, cellValue(row, Column.LAST_PRICE));
   assertEquals(snapshot.lastBid, cellValue(row, Column.LAST_BID));
   assertEquals(SnipersTableModel.textFor(snapshot.state), cellValue(row, Column.SNIPER_STATE));
 }
 @Test(expected = Defect.class)
 public void throwsDefectIfNoExistingSniperForAnUpdate() {
   model.sniperStateChanged(new SniperSnapshot("item 1", 123, 234, SniperState.WINNING));
 }