package jp.sourceforge.orangesignal.ta.dataset;

import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;

import java.util.Calendar;
import java.util.TimeZone;

import org.junit.Test;

public class DateTruncaterTest {

	@Test
	public void testDateTruncater() {
		final DateTruncater truncater = new DateTruncater();
		assertNotNull(truncater.calendar);
		assertTrue(truncater.year == 1970);
		assertTrue(truncater.month == Calendar.JANUARY);
		assertTrue(truncater.date == 1);
		assertTrue(truncater.hour == 0);
		assertTrue(truncater.minute == 0);
		assertTrue(truncater.second == 0);
		assertTrue(truncater.millisecond == 0);
	}

	@Test
	public void testDateTruncaterCalendar() {
		final Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("America/New_York"));
		final DateTruncater truncater = new DateTruncater(calendar);
		assertThat(truncater.calendar, is(calendar));
	}

	@Test(expected = NullPointerException.class)
	public void testDateTruncaterCalendarNullPointerException() {
		new DateTruncater(null);
	}

	@Test
	public void testTruncate() {
		final DateTruncater truncater = new DateTruncater();
		final Calendar in = Calendar.getInstance();
		Calendar out;

		out = truncater.truncate(in, Calendar.ERA);
		assertNotNull(out);
		assertTrue(out.get(Calendar.YEAR) == truncater.year);
		assertTrue(out.get(Calendar.MONTH) == truncater.month);
		assertTrue(out.get(Calendar.DATE) == truncater.date);
		assertTrue(out.get(Calendar.HOUR_OF_DAY) == truncater.hour);
		assertTrue(out.get(Calendar.MINUTE) == truncater.minute);
		assertTrue(out.get(Calendar.SECOND) == truncater.second);
		assertTrue(out.get(Calendar.MILLISECOND) == truncater.millisecond);

		out = truncater.truncate(in, Calendar.YEAR);
		assertNotNull(out);
		assertTrue(out.get(Calendar.YEAR) == truncater.year);
		assertTrue(out.get(Calendar.MONTH) == truncater.month);
		assertTrue(out.get(Calendar.DATE) == truncater.date);
		assertTrue(out.get(Calendar.HOUR_OF_DAY) == truncater.hour);
		assertTrue(out.get(Calendar.MINUTE) == truncater.minute);
		assertTrue(out.get(Calendar.SECOND) == truncater.second);
		assertTrue(out.get(Calendar.MILLISECOND) == truncater.millisecond);

		out = truncater.truncate(in, Calendar.MONTH);
		assertNotNull(out);
		assertTrue(out.get(Calendar.YEAR) == in.get(Calendar.YEAR));
		assertTrue(out.get(Calendar.MONTH) == truncater.month);
		assertTrue(out.get(Calendar.DATE) == truncater.date);
		assertTrue(out.get(Calendar.HOUR_OF_DAY) == truncater.hour);
		assertTrue(out.get(Calendar.MINUTE) == truncater.minute);
		assertTrue(out.get(Calendar.SECOND) == truncater.second);
		assertTrue(out.get(Calendar.MILLISECOND) == truncater.millisecond);

		out = truncater.truncate(in, Calendar.DAY_OF_WEEK);
		assertNotNull(out);
		assertTrue(out.get(Calendar.YEAR) == in.get(Calendar.YEAR));
		assertTrue(out.get(Calendar.MONTH) == in.get(Calendar.MONTH));
		assertTrue(out.get(Calendar.DATE) == (in.get(Calendar.DATE) + in.getFirstDayOfWeek() - in.get(Calendar.DAY_OF_WEEK)));
		assertTrue(out.get(Calendar.HOUR_OF_DAY) == truncater.hour);
		assertTrue(out.get(Calendar.MINUTE) == truncater.minute);
		assertTrue(out.get(Calendar.SECOND) == truncater.second);
		assertTrue(out.get(Calendar.MILLISECOND) == truncater.millisecond);

		out = truncater.truncate(in, Calendar.DATE);
		assertNotNull(out);
		assertTrue(out.get(Calendar.YEAR) == in.get(Calendar.YEAR));
		assertTrue(out.get(Calendar.MONTH) == in.get(Calendar.MONTH));
		assertTrue(out.get(Calendar.DATE) == truncater.date);
		assertTrue(out.get(Calendar.HOUR_OF_DAY) == truncater.hour);
		assertTrue(out.get(Calendar.MINUTE) == truncater.minute);
		assertTrue(out.get(Calendar.SECOND) == truncater.second);
		assertTrue(out.get(Calendar.MILLISECOND) == truncater.millisecond);

		out = truncater.truncate(in, Calendar.DAY_OF_MONTH);
		assertNotNull(out);
		assertTrue(out.get(Calendar.YEAR) == in.get(Calendar.YEAR));
		assertTrue(out.get(Calendar.MONTH) == in.get(Calendar.MONTH));
		assertTrue(out.get(Calendar.DATE) == truncater.date);
		assertTrue(out.get(Calendar.HOUR_OF_DAY) == truncater.hour);
		assertTrue(out.get(Calendar.MINUTE) == truncater.minute);
		assertTrue(out.get(Calendar.SECOND) == truncater.second);
		assertTrue(out.get(Calendar.MILLISECOND) == truncater.millisecond);

		out = truncater.truncate(in, Calendar.AM_PM);
		assertNotNull(out);
		assertTrue(out.get(Calendar.YEAR) == in.get(Calendar.YEAR));
		assertTrue(out.get(Calendar.MONTH) == in.get(Calendar.MONTH));
		assertTrue(out.get(Calendar.DATE) == in.get(Calendar.DATE));
		assertTrue(out.get(Calendar.HOUR_OF_DAY) == truncater.hour);
		assertTrue(out.get(Calendar.MINUTE) == truncater.minute);
		assertTrue(out.get(Calendar.SECOND) == truncater.second);
		assertTrue(out.get(Calendar.MILLISECOND) == truncater.millisecond);

		out = truncater.truncate(in, Calendar.HOUR);
		assertNotNull(out);
		assertTrue(out.get(Calendar.YEAR) == in.get(Calendar.YEAR));
		assertTrue(out.get(Calendar.MONTH) == in.get(Calendar.MONTH));
		assertTrue(out.get(Calendar.DATE) == in.get(Calendar.DATE));
		assertTrue(out.get(Calendar.HOUR_OF_DAY) == truncater.hour);
		assertTrue(out.get(Calendar.MINUTE) == truncater.minute);
		assertTrue(out.get(Calendar.SECOND) == truncater.second);
		assertTrue(out.get(Calendar.MILLISECOND) == truncater.millisecond);

		out = truncater.truncate(in, Calendar.HOUR_OF_DAY);
		assertNotNull(out);
		assertTrue(out.get(Calendar.YEAR) == in.get(Calendar.YEAR));
		assertTrue(out.get(Calendar.MONTH) == in.get(Calendar.MONTH));
		assertTrue(out.get(Calendar.DATE) == in.get(Calendar.DATE));
		assertTrue(out.get(Calendar.HOUR_OF_DAY) == truncater.hour);
		assertTrue(out.get(Calendar.MINUTE) == truncater.minute);
		assertTrue(out.get(Calendar.SECOND) == truncater.second);
		assertTrue(out.get(Calendar.MILLISECOND) == truncater.millisecond);

		out = truncater.truncate(in, Calendar.MINUTE);
		assertNotNull(out);
		assertTrue(out.get(Calendar.YEAR) == in.get(Calendar.YEAR));
		assertTrue(out.get(Calendar.MONTH) == in.get(Calendar.MONTH));
		assertTrue(out.get(Calendar.DATE) == in.get(Calendar.DATE));
		assertTrue(out.get(Calendar.HOUR_OF_DAY) == in.get(Calendar.HOUR_OF_DAY));
		assertTrue(out.get(Calendar.MINUTE) == truncater.minute);
		assertTrue(out.get(Calendar.SECOND) == truncater.second);
		assertTrue(out.get(Calendar.MILLISECOND) == truncater.millisecond);

		out = truncater.truncate(in, Calendar.SECOND);
		assertNotNull(out);
		assertTrue(out.get(Calendar.YEAR) == in.get(Calendar.YEAR));
		assertTrue(out.get(Calendar.MONTH) == in.get(Calendar.MONTH));
		assertTrue(out.get(Calendar.DATE) == in.get(Calendar.DATE));
		assertTrue(out.get(Calendar.HOUR_OF_DAY) == in.get(Calendar.HOUR_OF_DAY));
		assertTrue(out.get(Calendar.MINUTE) == in.get(Calendar.MINUTE));
		assertTrue(out.get(Calendar.SECOND) == truncater.second);
		assertTrue(out.get(Calendar.MILLISECOND) == truncater.millisecond);

		out = truncater.truncate(in, Calendar.MILLISECOND);
		assertNotNull(out);
		assertTrue(out.get(Calendar.YEAR) == in.get(Calendar.YEAR));
		assertTrue(out.get(Calendar.MONTH) == in.get(Calendar.MONTH));
		assertTrue(out.get(Calendar.DATE) == in.get(Calendar.DATE));
		assertTrue(out.get(Calendar.HOUR_OF_DAY) == in.get(Calendar.HOUR_OF_DAY));
		assertTrue(out.get(Calendar.MINUTE) == in.get(Calendar.MINUTE));
		assertTrue(out.get(Calendar.SECOND) == in.get(Calendar.SECOND));
		assertTrue(out.get(Calendar.MILLISECOND) == truncater.millisecond);
	}

}
