package org.marketcetera.event.impl; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.util.Date; import java.util.concurrent.atomic.AtomicLong; import org.junit.Test; import org.marketcetera.event.Event; import org.marketcetera.event.Messages; import org.marketcetera.event.beans.EventBean; import org.marketcetera.event.beans.HasEventBean; import org.marketcetera.module.ExpectedFailure; import org.marketcetera.util.test.EqualityAssert; /* $License$ */ /** * Tests {@link AbstractEventBuilderImpl} portion of an {@link EventBuilder}. * * @author <a href="mailto:colin@marketcetera.com">Colin DuPlantis</a> * @version $Id: AbstractEventBuilderTestBase.java 16154 2012-07-14 16:34:05Z colin $ * @since 2.0.0 */ public abstract class AbstractEventBuilderTestBase<E extends Event,B extends AbstractEventBuilderImpl<E>> implements Messages { /** * Tests {@link AbstractEventBuilderImpl#withMessageId(long)}. * * @throws Exception if an unexpected error occurs */ @Test public void withMessageId() throws Exception { B builder = getBuilder(); setDefaults(builder); builder.withMessageId(Long.MIN_VALUE); assertEquals(Long.MIN_VALUE, builder.getEvent().getMessageId()); builder.withMessageId(-1); assertEquals(-1, builder.getEvent().getMessageId()); builder.withMessageId(Long.MAX_VALUE); assertEquals(Long.MAX_VALUE, builder.getEvent().getMessageId()); verify(builder); } /** * Tests {@link AbstractEventBuilderImpl#withTimestamp(Date)}. * * @throws Exception if an unexpected error occurs */ @Test public void withTimestamp() throws Exception { B builder = getBuilder(); setDefaults(builder); // null timestamp builder.withTimestamp(null); assertEquals(null, builder.getEvent().getTimestamp()); // regular timestamp Date timestamp = new Date(); builder.withTimestamp(timestamp); assertEquals(timestamp, builder.getEvent().getTimestamp()); // make a weird timestamp timestamp = new Date(-1); builder.withTimestamp(timestamp); assertEquals(timestamp, builder.create().getTimestamp()); verify(builder); } /** * Tests {@link AbstractEventBuilderImpl#withSource(Object)}. * * @throws Exception if an unexpected error occurs */ @Test public void withSource() throws Exception { B builder = getBuilder(); setDefaults(builder); // null source builder.withSource(null); assertEquals(null, builder.getEvent().getSource()); // non-null source builder.withSource(this); assertEquals(this, builder.getEvent().getSource()); verify(builder); } /** * Tests event <code>hashCode</code> and <code>equals</code>. * * @throws Exception if an unexpected error occurs */ @Test public void hashCodeAndEquals() throws Exception { B builder = getBuilder(); E event1 = setDefaults(builder).create(); E event2 = builder.create(); E event3 = setDefaults(builder).create(); assertEquals(event1.getMessageId(), event2.getMessageId()); assertFalse(event2.getMessageId() == event3.getMessageId()); EqualityAssert.assertEquality(event1, event2, event3, null, this); } /** * Tests basic event validation. * * <p>Subclasses may override this method but should call the parent * method. * * @throws Exception if an unexpected error occurs */ @Test public void validation() throws Exception { final B builder = setDefaults(getBuilder()); // check messageId builder.withMessageId(-1); new ExpectedFailure<IllegalArgumentException>(VALIDATION_INVALID_MESSAGEID.getText(builder.getEvent().getMessageId())) { @Override protected void run() throws Exception { builder.create(); } }; setDefaults(builder); // 0 is ok builder.withMessageId(0); verify(builder); // minimum value is ok (asks for a generated id) setDefaults(builder).withMessageId(Long.MIN_VALUE); verify(builder); // maximum value is ok setDefaults(builder).withMessageId(Long.MAX_VALUE); verify(builder); // timestamp // negative timestamp ok (not even sure what this means, maybe 1ms before epoch?) builder.withTimestamp(new Date(-1)); verify(builder); // 0 timestamp setDefaults(builder).withTimestamp(new Date(0)); verify(builder); // null timestamp (requests a new timestamp) setDefaults(builder).withTimestamp(null); verify(builder); // normal timestamp setDefaults(builder).withTimestamp(new Date()); verify(builder); } /** * Sets valid defaults in the given builder. * * <p>Subclasses may override this method to set their own defaults * but should call the parent method. * * @param inBuilder a <code>B</code> value * @return a <code>B</code> value * @throws Exception if an unexpected error occurs */ protected B setDefaults(B inBuilder) throws Exception { inBuilder.withMessageId(counter.incrementAndGet()); inBuilder.withTimestamp(new Date()); inBuilder.withSource(this); return inBuilder; } /** * Gets the builder to use for testing. * * @return a <code>B</code> value */ protected abstract B getBuilder(); /** * Verifies that the given builder can produce an event of the * correct type with the builder's attributes. * * <p>Note that the builder is assumed to be in a state that * can produce an event without error. * * <p>Subclasses should override this method to test the * attributes of the subclass and invoke the parent method. * * @param inBuilder a <code>B</code> value * @return an <code>E</code> value * @throws Exception if an unexpected error occurs */ protected E verify(B inBuilder) throws Exception { assertNotNull(inBuilder); assertNotNull(inBuilder.toString()); E event = inBuilder.create(); assertNotNull(event); assertNotNull(event.toString()); EventBean eventBean = null; if(event instanceof HasEventBean) { eventBean = ((HasEventBean)event).getEventBean(); } // there is a special case for messageId - if equal to Long.MIN_VALUE // then it will be some value >= 0 if(inBuilder.getEvent().getMessageId() == Long.MIN_VALUE) { assertTrue(event.getMessageId() >= 0); if(eventBean != null) { assertTrue(eventBean.getMessageId() >= 0); } } else { assertEquals(inBuilder.getEvent().getMessageId(), event.getMessageId()); if(eventBean != null) { assertEquals(inBuilder.getEvent().getMessageId(), eventBean.getMessageId()); } } // there's a special case for timestamp, too if(inBuilder.getEvent().getTimestamp() == null) { assertNotNull(event.getTimestamp()); assertEquals(event.getTimestamp().getTime(), event.getTimeMillis()); } else { assertEquals(inBuilder.getEvent().getTimestamp(), event.getTimestamp()); assertEquals(inBuilder.getEvent().getTimestamp().getTime(), event.getTimeMillis()); } assertEquals(inBuilder.getEvent().getSource(), event.getSource()); Object newSource = new Object(); event.setSource(newSource); assertEquals(newSource, event.getSource()); return event; } /** * counter used to guarantee unique events */ private static final AtomicLong counter = new AtomicLong(0); }