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.math.BigDecimal; import java.util.Date; import java.util.concurrent.atomic.AtomicLong; import org.junit.Test; import org.marketcetera.event.*; import org.marketcetera.marketdata.DateUtils; import org.marketcetera.module.ExpectedFailure; import org.marketcetera.trade.Equity; import org.marketcetera.util.test.EqualityAssert; /* $License$ */ /** * Tests {@link DividendEventBuilder} and {@link DividendEventImpl}. * * @author <a href="mailto:colin@marketcetera.com">Colin DuPlantis</a> * @version $Id: DividendEventTest.java 16154 2012-07-14 16:34:05Z colin $ * @since 2.0.0 */ public class DividendEventTest implements Messages { /** * Tests {@link DividendEventBuilder#withMessageId(long)}. * * @throws Exception if an unexpected error occurs */ @Test public void withMessageId() throws Exception { DividendEventBuilder builder = getBuilder(); setDefaults(builder); builder.withMessageId(Long.MIN_VALUE); assertEquals(Long.MIN_VALUE, builder.getDividend().getMessageId()); builder.withMessageId(-1); assertEquals(-1, builder.getDividend().getMessageId()); builder.withMessageId(Long.MAX_VALUE); assertEquals(Long.MAX_VALUE, builder.getDividend().getMessageId()); verify(builder); } /** * Tests {@link DividendEventBuilder#withTimestamp(Date)}. * * @throws Exception if an unexpected error occurs */ @Test public void withTimestamp() throws Exception { DividendEventBuilder builder = getBuilder(); setDefaults(builder); // null timestamp builder.withTimestamp(null); assertEquals(null, builder.getDividend().getTimestamp()); // regular timestamp Date timestamp = new Date(); builder.withTimestamp(timestamp); assertEquals(timestamp, builder.getDividend().getTimestamp()); // make a weird timestamp timestamp = new Date(-1); builder.withTimestamp(timestamp); assertEquals(timestamp, builder.create().getTimestamp()); verify(builder); } /** * Tests {@link DividendEventBuilder#withSource(Object)}. * * @throws Exception if an unexpected error occurs */ @Test public void withSource() throws Exception { DividendEventBuilder builder = getBuilder(); setDefaults(builder); // null source builder.withSource(null); assertEquals(null, builder.getDividend().getSource()); // non-null source builder.withSource(this); assertEquals(this, builder.getDividend().getSource()); verify(builder); } /** * Tests {@link DividendEventBuilder#withEventType(org.marketcetera.event.EventType)}. * * @throws Exception if an unexpected error occurs */ @Test public void withEventType() throws Exception { DividendEventBuilder builder = setDefaults(getBuilder()); EventType type = null; builder.withEventType(type); assertEquals(type, builder.getDividend().getEventType()); type = EventType.UNKNOWN; builder.withEventType(type); assertEquals(type, builder.getDividend().getEventType()); type = EventType.SNAPSHOT_PART; builder.withEventType(type); assertEquals(type, builder.getDividend().getEventType()); verify(builder); } /** * Tests {@link DividendEventBuilder#withEquity(Equity)}. * * @throws Exception if an unexpected error occurs */ @Test public void withEquity() throws Exception { DividendEventBuilder builder = getBuilder(); setDefaults(builder); // null equity builder.withEquity(null); assertEquals(null, builder.getDividend().getEquity()); // non-null equity builder.withEquity(equity); assertEquals(equity, builder.getDividend().getEquity()); verify(builder); } /** * Tests {@link DividendEventBuilder#withAmount(BigDecimal)}. * * @throws Exception if an unexpected error occurs */ @Test public void withAmount() throws Exception { DividendEventBuilder builder = getBuilder(); setDefaults(builder); // null amount builder.withAmount(null); assertEquals(null, builder.getDividend().getAmount()); // non-null amount builder.withAmount(BigDecimal.ONE); assertEquals(BigDecimal.ONE, builder.getDividend().getAmount()); verify(builder); } /** * Tests {@link DividendEventBuilder#withCurrency(String)}. * * @throws Exception if an unexpected error occurs */ @Test public void withCurrency() throws Exception { DividendEventBuilder builder = getBuilder(); setDefaults(builder); // null currency builder.withCurrency(null); assertEquals(null, builder.getDividend().getCurrency()); // empty currency builder.withCurrency(""); assertEquals("", builder.getDividend().getCurrency()); // non-null currency builder.withCurrency("Peanuts"); assertEquals("Peanuts", builder.getDividend().getCurrency()); verify(builder); } /** * Tests {@link DividendEventBuilder#withDeclareDate(String)}. * * @throws Exception if an unexpected error occurs */ @Test public void withDeclareDate() throws Exception { DividendEventBuilder builder = getBuilder(); setDefaults(builder); // null DeclareDate builder.withDeclareDate(null); assertEquals(null, builder.getDividend().getDeclareDate()); // empty DeclareDate builder.withDeclareDate(""); assertEquals("", builder.getDividend().getDeclareDate()); // non-null DeclareDate (invalid date) builder.withDeclareDate("this-is-not-a-date"); assertEquals("this-is-not-a-date", builder.getDividend().getDeclareDate()); // non-null (valid date) String date = DateUtils.dateToString(new Date()); builder.withDeclareDate(date); assertEquals(date, builder.getDividend().getDeclareDate()); verify(builder); } /** * Tests {@link DividendEventBuilder#withExecutionDate(String)}. * * @throws Exception if an unexpected error occurs */ @Test public void withExecutionDate() throws Exception { DividendEventBuilder builder = getBuilder(); setDefaults(builder); // null ExecutionDate builder.withExecutionDate(null); assertEquals(null, builder.getDividend().getExecutionDate()); // empty ExecutionDate builder.withExecutionDate(""); assertEquals("", builder.getDividend().getExecutionDate()); // non-null ExecutionDate (invalid date) builder.withExecutionDate("this-is-not-a-date"); assertEquals("this-is-not-a-date", builder.getDividend().getExecutionDate()); // non-null (valid date) String date = DateUtils.dateToString(new Date()); builder.withExecutionDate(date); assertEquals(date, builder.getDividend().getExecutionDate()); verify(builder); } /** * Tests {@link DividendEventBuilder#withPaymentDate(String)}. * * @throws Exception if an unexpected error occurs */ @Test public void withPaymentDate() throws Exception { DividendEventBuilder builder = getBuilder(); setDefaults(builder); // null PaymentDate builder.withPaymentDate(null); assertEquals(null, builder.getDividend().getPaymentDate()); // empty PaymentDate builder.withPaymentDate(""); assertEquals("", builder.getDividend().getPaymentDate()); // non-null PaymentDate (invalid date) builder.withPaymentDate("this-is-not-a-date"); assertEquals("this-is-not-a-date", builder.getDividend().getPaymentDate()); // non-null (valid date) String date = DateUtils.dateToString(new Date()); builder.withPaymentDate(date); assertEquals(date, builder.getDividend().getPaymentDate()); verify(builder); } /** * Tests {@link DividendEventBuilder#withRecordDate(String)}. * * @throws Exception if an unexpected error occurs */ @Test public void withRecordDate() throws Exception { DividendEventBuilder builder = getBuilder(); setDefaults(builder); // null RecordDate builder.withRecordDate(null); assertEquals(null, builder.getDividend().getRecordDate()); // empty RecordDate builder.withRecordDate(""); assertEquals("", builder.getDividend().getRecordDate()); // non-null RecordDate (invalid date) builder.withRecordDate("this-is-not-a-date"); assertEquals("this-is-not-a-date", builder.getDividend().getRecordDate()); // non-null (valid date) String date = DateUtils.dateToString(new Date()); builder.withRecordDate(date); assertEquals(date, builder.getDividend().getRecordDate()); verify(builder); } /** * Tests {@link DividendEventBuilder#withFrequency(DividendFrequency)}. * * @throws Exception if an unexpected error occurs */ @Test public void withFrequency() throws Exception { DividendEventBuilder builder = getBuilder(); setDefaults(builder); // null Frequency builder.withFrequency(null); assertEquals(null, builder.getDividend().getFrequency()); // non-null Frequency builder.withFrequency(DividendFrequency.MONTHLY); assertEquals(DividendFrequency.MONTHLY, builder.getDividend().getFrequency()); verify(builder); } /** * Tests {@link DividendEventBuilder#withStatus(DividendStatus)}. * * @throws Exception if an unexpected error occurs */ @Test public void withStatus() throws Exception { DividendEventBuilder builder = getBuilder(); setDefaults(builder); // null Status builder.withStatus(null); assertEquals(null, builder.getDividend().getStatus()); // non-null Status builder.withStatus(DividendStatus.UNOFFICIAL); assertEquals(DividendStatus.UNOFFICIAL, builder.getDividend().getStatus()); verify(builder); } /** * Tests event <code>hashCode</code> and <code>equals</code>. * * @throws Exception if an unexpected error occurs */ @Test public void hashCodeAndEquals() throws Exception { DividendEventBuilder builder = getBuilder(); DividendEvent event1 = setDefaults(builder).create(); DividendEvent event2 = builder.create(); DividendEvent event3 = setDefaults(builder).create(); assertEquals(event1.getMessageId(), event2.getMessageId()); assertFalse(event2.getMessageId() == event3.getMessageId()); EqualityAssert.assertEquality(event1, event2, event3, null, this); } /** * Tests {@link DividendEventImpl} validation. * * @throws Exception if an unexpected error occurs */ @Test public void validation() throws Exception { final DividendEventBuilder builder = setDefaults(getBuilder()); // check messageId builder.withMessageId(-1); new ExpectedFailure<IllegalArgumentException>(VALIDATION_INVALID_MESSAGEID.getText(builder.getDividend().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); // add validation for other attributes setDefaults(builder).withEquity(null); new ExpectedFailure<IllegalArgumentException>(VALIDATION_NULL_EQUITY.getText()) { @Override protected void run() throws Exception { builder.create(); } }; setDefaults(builder).withAmount(null); new ExpectedFailure<IllegalArgumentException>(VALIDATION_NULL_AMOUNT.getText()) { @Override protected void run() throws Exception { builder.create(); } }; setDefaults(builder).withCurrency(null); new ExpectedFailure<IllegalArgumentException>(VALIDATION_NULL_CURRENCY.getText()) { @Override protected void run() throws Exception { builder.create(); } }; setDefaults(builder).withCurrency(""); new ExpectedFailure<IllegalArgumentException>(VALIDATION_NULL_CURRENCY.getText()) { @Override protected void run() throws Exception { builder.create(); } }; // this value is ok setDefaults(builder).withDeclareDate("not-a-date"); verify(builder); setDefaults(builder).withDeclareDate(DateUtils.dateToString(new Date())); verify(builder); setDefaults(builder).withExecutionDate(null); new ExpectedFailure<IllegalArgumentException>(VALIDATION_NULL_EXECUTION_DATE.getText()) { @Override protected void run() throws Exception { builder.create(); } }; setDefaults(builder).withExecutionDate(""); new ExpectedFailure<IllegalArgumentException>(VALIDATION_NULL_EXECUTION_DATE.getText()) { @Override protected void run() throws Exception { builder.create(); } }; // this value is ok setDefaults(builder).withExecutionDate("not-a-date"); verify(builder); setDefaults(builder).withExecutionDate(DateUtils.dateToString(new Date())); verify(builder); // this value is ok setDefaults(builder).withPaymentDate("not-a-date"); verify(builder); setDefaults(builder).withPaymentDate(DateUtils.dateToString(new Date())); verify(builder); setDefaults(builder).withRecordDate(null); verify(builder); setDefaults(builder).withRecordDate(""); verify(builder); // this value is ok setDefaults(builder).withRecordDate("not-a-date"); verify(builder); setDefaults(builder).withRecordDate(DateUtils.dateToString(new Date())); verify(builder); setDefaults(builder).withFrequency(null); new ExpectedFailure<IllegalArgumentException>(VALIDATION_NULL_FREQUENCY.getText()) { @Override protected void run() throws Exception { builder.create(); } }; setDefaults(builder).withStatus(null); new ExpectedFailure<IllegalArgumentException>(VALIDATION_NULL_STATUS.getText()) { @Override protected void run() throws Exception { builder.create(); } }; setDefaults(builder).withType(null); new ExpectedFailure<IllegalArgumentException>(VALIDATION_NULL_TYPE.getText()) { @Override protected void run() throws Exception { builder.create(); } }; } /** * 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. * * @param inBuilder a <code>DividendEventBuilder</code> value * @return a <code>DividendEvent</code> value * @throws Exception if an unexpected error occurs */ private DividendEvent verify(DividendEventBuilder inBuilder) throws Exception { assertNotNull(inBuilder); assertNotNull(inBuilder.toString()); DividendEvent event = inBuilder.create(); assertNotNull(event); assertNotNull(event.toString()); // compare event to builder assertEquals(inBuilder.getDividend().getAmount(), event.getAmount()); assertEquals(inBuilder.getDividend().getCurrency(), event.getCurrency()); assertEquals(inBuilder.getDividend().getDeclareDate(), event.getDeclareDate()); assertEquals(inBuilder.getDividend().getEquity(), event.getEquity()); assertEquals(inBuilder.getDividend().getEquity(), event.getInstrument()); assertEquals(inBuilder.getDividend().getExecutionDate(), event.getExecutionDate()); assertEquals(inBuilder.getDividend().getFrequency(), event.getFrequency()); assertEquals(inBuilder.getDividend().getInstrumentAsString(), event.getInstrumentAsString()); assertEquals(inBuilder.getDividend().getEventType(), event.getEventType()); assertFalse(event.getEventType() == EventType.SNAPSHOT_FINAL); event.setEventType(EventType.SNAPSHOT_FINAL); assertEquals(EventType.SNAPSHOT_FINAL, event.getEventType()); // there is a special case for messageId - if equal to Long.MIN_VALUE // then it will be some value >= 0 if(inBuilder.getDividend().getMessageId() == Long.MIN_VALUE) { assertTrue(event.getMessageId() >= 0); } else { assertEquals(inBuilder.getDividend().getMessageId(), event.getMessageId()); } assertEquals(inBuilder.getDividend().getPaymentDate(), event.getPaymentDate()); assertEquals(inBuilder.getDividend().getRecordDate(), event.getRecordDate()); assertEquals(inBuilder.getDividend().getSource(), event.getSource()); assertEquals(inBuilder.getDividend().getStatus(), event.getStatus()); // there's a special case for timestamp, too if(inBuilder.getDividend().getTimestamp() == null) { assertNotNull(event.getTimestamp()); assertEquals(event.getTimestamp().getTime(), event.getTimeMillis()); } else { assertEquals(inBuilder.getDividend().getTimestamp(), event.getTimestamp()); assertEquals(inBuilder.getDividend().getTimeMillis(), event.getTimeMillis()); } assertEquals(inBuilder.getDividend().getType(), event.getType()); Object newSource = new Object(); event.setSource(newSource); assertEquals(newSource, event.getSource()); return event; } /** * Sets valid defaults in the given builder. * * @param inBuilder a <code>DividendEventBuilder</code> value * @return a <code>DividendEventBuilder</code> value * @throws Exception if an unexpected error occurs */ private DividendEventBuilder setDefaults(DividendEventBuilder inBuilder) throws Exception { long timestampMillis = System.currentTimeMillis(); inBuilder.withAmount(BigDecimal.ONE); inBuilder.withCurrency("US Dollars"); inBuilder.withDeclareDate(DateUtils.dateToString(new Date(timestampMillis + (1000 * 60 * 60 * 24)*1))); inBuilder.withEquity(equity); inBuilder.withEventType(EventType.UPDATE_FINAL); inBuilder.withExecutionDate(DateUtils.dateToString(new Date(timestampMillis + (1000 * 60 * 60 * 24)*2))); inBuilder.withFrequency(DividendFrequency.ANNUALLY); inBuilder.withMessageId(idCounter.incrementAndGet()); inBuilder.withPaymentDate(DateUtils.dateToString(new Date(timestampMillis + (1000 * 60 * 60 * 24)*3))); inBuilder.withRecordDate(DateUtils.dateToString(new Date(timestampMillis + (1000 * 60 * 60 * 24)*4))); inBuilder.withSource(this); inBuilder.withStatus(DividendStatus.OFFICIAL); inBuilder.withTimestamp(new Date(timestampMillis + (1000 * 60 * 60 * 24)*5)); inBuilder.withType(DividendType.CURRENT); return inBuilder; } /** * Gets the builder to use for testing. * * @return a <code>DividendEventBuilder</code> value */ private DividendEventBuilder getBuilder() { return DividendEventBuilder.dividend(); } /** * test instrument */ private Equity equity = new Equity("METC"); /** * id counter used to guarantee unique events */ private static final AtomicLong idCounter = new AtomicLong(0); }