@Test
  public void testItAbbreviatesDayNames() {
    // simulate Feb month
    when(calendar.get(Calendar.DAY_OF_WEEK)).thenReturn(1);
    when(calendar.get(Calendar.MONTH)).thenReturn(1);
    when(calendar.getActualMaximum(Calendar.DAY_OF_MONTH)).thenReturn(28);

    underTest.setGrowProgress(
        1000); // set grow progress so that it simulates the calendar being open
    underTest.setLocale(Locale.FRANCE);
    reset(canvas); // reset because invalidate is called
    underTest.setUseWeekDayAbbreviation(true);
    reset(canvas); // reset because invalidate is called
    underTest.drawMonth(canvas, calendar, 0);

    DateFormatSymbols dateFormatSymbols = new DateFormatSymbols(Locale.FRANCE);
    String[] dayNames = dateFormatSymbols.getShortWeekdays();

    InOrder inOrder = inOrder(canvas);
    inOrder.verify(canvas).drawText(eq(dayNames[2]), anyInt(), anyInt(), eq(paint));
    inOrder.verify(canvas).drawText(eq(dayNames[3]), anyInt(), anyInt(), eq(paint));
    inOrder.verify(canvas).drawText(eq(dayNames[4]), anyInt(), anyInt(), eq(paint));
    inOrder.verify(canvas).drawText(eq(dayNames[5]), anyInt(), anyInt(), eq(paint));
    inOrder.verify(canvas).drawText(eq(dayNames[6]), anyInt(), anyInt(), eq(paint));
    inOrder.verify(canvas).drawText(eq(dayNames[7]), anyInt(), anyInt(), eq(paint));
    inOrder.verify(canvas).drawText(eq(dayNames[1]), anyInt(), anyInt(), eq(paint));
  }
  @Test
  public void testItDrawsDaysOnCalender() {
    // simulate Feb month
    underTest.setGrowProgress(
        1000); // set grow progress so that it simulates the calendar being open
    when(calendar.get(Calendar.DAY_OF_WEEK)).thenReturn(1);
    when(calendar.get(Calendar.MONTH)).thenReturn(1);
    when(calendar.getActualMaximum(Calendar.DAY_OF_MONTH)).thenReturn(28);

    underTest.drawMonth(canvas, calendar, 0);

    for (int dayColumn = 0, dayRow = 0; dayColumn <= 6; dayRow++) {
      if (dayRow == 7) {
        dayRow = 0;
        if (dayColumn <= 6) {
          dayColumn++;
        }
      }
      if (dayColumn == dayColumnNames.length) {
        break;
      }
      if (dayColumn == 0) {
        verify(canvas).drawText(eq(dayColumnNames[dayColumn]), anyInt(), anyInt(), eq(paint));
      } else {
        int day = ((dayRow - 1) * 7 + dayColumn + 1) - 6;
        if (day > 0 && day <= 28) {
          verify(canvas).drawText(eq(String.valueOf(day)), anyInt(), anyInt(), eq(paint));
        }
      }
    }
  }
  @Test
  public void testItScrollsToNextMonth() {
    // Sun, 08 Feb 2015 00:00:00 GMT
    underTest.setCurrentDate(new Date(1423353600000L));

    underTest.showNextMonth();
    Date actualDate = underTest.getFirstDayOfCurrentMonth();

    // Sun, 01 Mar 2015 00:00:00 GMT - expected
    assertEquals(new Date(1425168000000L), actualDate);
  }
  @Test
  public void testItReturnsFirstDayOfMonthAfterDateHasBeenSet() {
    // Sun, 01 Feb 2015 00:00:00 GMT
    Date expectedDate = new Date(1422748800000L);

    // Sun, 08 Feb 2015 00:00:00 GMT
    underTest.setCurrentDate(new Date(1423353600000L));

    Date actualDate = underTest.getFirstDayOfCurrentMonth();
    assertEquals(expectedDate, actualDate);
  }
  @Test
  public void testItScrollsToPreviousMonth() {
    // Sun, 08 Feb 2015 00:00:00 GMT
    underTest.setCurrentDate(new Date(1423353600000L));

    underTest.showPreviousMonth();
    Date actualDate = underTest.getFirstDayOfCurrentMonth();

    // Thu, 01 Jan 2015 00:00:00 GMT - expected
    assertEquals(new Date(1420070400000L), actualDate);
  }
  @Test
  public void testManualScrollAndGestureScrollPlayNicelyTogether() {
    // Set width of view so that scrolling will return a correct value
    underTest.onMeasure(720, 1080, 0, 0);

    Calendar cal = Calendar.getInstance();

    // Sun, 08 Feb 2015 00:00:00 GMT
    underTest.setCurrentDate(new Date(setTimeToMidnightAndGet(cal, 1423353600000L)));

    underTest.showNextMonth();

    // Sun, 01 Mar 2015 00:00:00 GMT - expected
    assertEquals(
        new Date(setTimeToMidnightAndGet(cal, 1425168000000L)),
        underTest.getFirstDayOfCurrentMonth());

    when(motionEvent.getAction()).thenReturn(MotionEvent.ACTION_UP);

    // Scroll enough to push calender to next month
    underTest.onScroll(motionEvent, motionEvent, 600, 0);
    underTest.onDraw(canvas);
    underTest.onTouch(motionEvent);

    // Wed, 01 Apr 2015 00:00:00 GMT
    assertEquals(
        new Date(setTimeToMidnightAndGet(cal, 1427842800000L)),
        underTest.getFirstDayOfCurrentMonth());
  }
 @Test
 public void testItRemovesEvents() {
   List<Event> events = getSingleEvents(0, 30, 1433701251000L);
   underTest.removeEvents(events);
   verify(eventsContainer).removeEvents(events);
   verifyNoMoreInteractions(eventsContainer);
 }
 @Test
 public void testItRemovesEvent() {
   Event event = getSingleEvents(0, 30, 1433701251000L).get(0);
   underTest.removeEvent(event);
   verify(eventsContainer).removeEvent(event);
   verifyNoMoreInteractions(eventsContainer);
 }
  @Test
  public void testItDrawsMultipleEventDaysOnCalendar() {
    // Sun, 07 Jun 2015 18:20:51 GMT
    // get 60 events in total
    List<Events> events = getDayEventWith2EventsPerDay(0, 30, 1433701251000L);
    when(eventsContainer.getEventsForMonthAndYear(5, 2015)).thenReturn(events);
    when(calendar.get(Calendar.MONTH)).thenReturn(5);
    when(calendar.get(Calendar.YEAR)).thenReturn(2015);

    underTest.setGrowProgress(
        1000); // set grow progress so that it simulates the calendar being open
    underTest.drawEvents(canvas, calendar, 0);

    // draw events 58 times because we don't draw events for the current selected day since it wil
    // be highlighted with another indicator
    verify(canvas, times(58)).drawCircle(anyFloat(), anyFloat(), anyFloat(), eq(paint));
  }
  @Test
  public void testItDrawsMultipleEventDaysOnCalendarWithPlusIndicator() {
    // Sun, 07 Jun 2015 18:20:51 GMT
    // get 120 events in total but only draw 3 event indicators per a day
    List<Events> events = getDayEventWithMultipleEventsPerDay(0, 30, 1433701251000L);
    when(eventsContainer.getEventsForMonthAndYear(5, 2015)).thenReturn(events);
    when(calendar.get(Calendar.MONTH)).thenReturn(5);
    when(calendar.get(Calendar.YEAR)).thenReturn(2015);

    underTest.setGrowProgress(
        1000); // set grow progress so that it simulates the calendar being open
    underTest.drawEvents(canvas, calendar, 0);

    // draw events 58 times because we don't draw more than 3 indicators
    verify(canvas, times(58)).drawCircle(anyFloat(), anyFloat(), anyFloat(), eq(paint));

    // draw event indicator with lines
    // 2 calls for each plus event indicator since it takes 2 draw calls to make a plus sign
    verify(canvas, times(58)).drawLine(anyFloat(), anyFloat(), anyFloat(), anyFloat(), eq(paint));
  }
  @Test
  public void testItDrawsFirstLetterOfEachDay() {
    // simulate Feb month
    when(calendar.get(Calendar.DAY_OF_WEEK)).thenReturn(1);
    when(calendar.get(Calendar.MONTH)).thenReturn(1);
    when(calendar.getActualMaximum(Calendar.DAY_OF_MONTH)).thenReturn(28);

    underTest.setGrowProgress(
        1000); // set grow progress so that it simulates the calendar being open
    underTest.drawMonth(canvas, calendar, 0);

    InOrder inOrder = inOrder(canvas);
    inOrder.verify(canvas).drawText(eq("M"), anyInt(), anyInt(), eq(paint));
    inOrder.verify(canvas).drawText(eq("T"), anyInt(), anyInt(), eq(paint));
    inOrder.verify(canvas).drawText(eq("W"), anyInt(), anyInt(), eq(paint));
    inOrder.verify(canvas).drawText(eq("T"), anyInt(), anyInt(), eq(paint));
    inOrder.verify(canvas).drawText(eq("F"), anyInt(), anyInt(), eq(paint));
    inOrder.verify(canvas).drawText(eq("S"), anyInt(), anyInt(), eq(paint));
    inOrder.verify(canvas).drawText(eq("S"), anyInt(), anyInt(), eq(paint));
  }
  @Test
  public void testItDrawsSundayAsFirstDay() {
    // simulate Feb month
    when(calendar.get(Calendar.DAY_OF_WEEK)).thenReturn(1);
    when(calendar.get(Calendar.MONTH)).thenReturn(1);
    when(calendar.getActualMaximum(Calendar.DAY_OF_MONTH)).thenReturn(28);

    underTest.setGrowProgress(
        1000); // set grow progress so that it simulates the calendar being open
    underTest.setShouldShowMondayAsFirstDay(false);
    underTest.setUseWeekDayAbbreviation(true);
    underTest.drawMonth(canvas, calendar, 0);

    InOrder inOrder = inOrder(canvas);
    inOrder.verify(canvas).drawText(eq("Sun"), anyInt(), anyInt(), eq(paint));
    inOrder.verify(canvas).drawText(eq("Mon"), anyInt(), anyInt(), eq(paint));
    inOrder.verify(canvas).drawText(eq("Tue"), anyInt(), anyInt(), eq(paint));
    inOrder.verify(canvas).drawText(eq("Wed"), anyInt(), anyInt(), eq(paint));
    inOrder.verify(canvas).drawText(eq("Thu"), anyInt(), anyInt(), eq(paint));
    inOrder.verify(canvas).drawText(eq("Fri"), anyInt(), anyInt(), eq(paint));
    inOrder.verify(canvas).drawText(eq("Sat"), anyInt(), anyInt(), eq(paint));
  }
  @Test
  public void testItSetsDayColumns() {
    // simulate Feb month
    when(calendar.get(Calendar.DAY_OF_WEEK)).thenReturn(1);
    when(calendar.get(Calendar.MONTH)).thenReturn(1);
    when(calendar.getActualMaximum(Calendar.DAY_OF_MONTH)).thenReturn(28);

    String[] dayNames = {"Mon", "Tue", "Wed", "Thur", "Fri", "Sat", "Sun"};
    underTest.setGrowProgress(
        1000); // set grow progress so that it simulates the calendar being open
    underTest.setDayColumnNames(dayNames);
    underTest.drawMonth(canvas, calendar, 0);

    InOrder inOrder = inOrder(canvas);
    inOrder.verify(canvas).drawText(eq("Mon"), anyInt(), anyInt(), eq(paint));
    inOrder.verify(canvas).drawText(eq("Tue"), anyInt(), anyInt(), eq(paint));
    inOrder.verify(canvas).drawText(eq("Wed"), anyInt(), anyInt(), eq(paint));
    inOrder.verify(canvas).drawText(eq("Thur"), anyInt(), anyInt(), eq(paint));
    inOrder.verify(canvas).drawText(eq("Fri"), anyInt(), anyInt(), eq(paint));
    inOrder.verify(canvas).drawText(eq("Sat"), anyInt(), anyInt(), eq(paint));
    inOrder.verify(canvas).drawText(eq("Sun"), anyInt(), anyInt(), eq(paint));
  }
  @Test
  public void testItReturnsFirstDayOfMonth() {
    Calendar currentCalender = Calendar.getInstance();
    currentCalender.set(Calendar.DAY_OF_MONTH, 1);
    currentCalender.set(Calendar.HOUR_OF_DAY, 0);
    currentCalender.set(Calendar.MINUTE, 0);
    currentCalender.set(Calendar.SECOND, 0);
    currentCalender.set(Calendar.MILLISECOND, 0);
    Date expectFirstDayOfMonth = currentCalender.getTime();

    Date actualDate = underTest.getFirstDayOfCurrentMonth();

    assertEquals(expectFirstDayOfMonth, actualDate);
  }
  @Test
  public void testListenerIsCalledOnMonthScroll() {
    // Sun, 01 Mar 2015 00:00:00 GMT
    Date expectedDateOnScroll = new Date(1425168000000L);

    when(motionEvent.getAction()).thenReturn(MotionEvent.ACTION_UP);

    // Set width of view so that scrolling will return a correct value
    underTest.onMeasure(720, 1080, 0, 0);

    // Sun, 08 Feb 2015 00:00:00 GMT
    underTest.setCurrentDate(new Date(1423353600000L));

    // Scroll enough to push calender to next month
    underTest.onScroll(motionEvent, motionEvent, 600, 0);
    underTest.onDraw(canvas);
    underTest.onTouch(motionEvent);
    assertEquals(expectedDateOnScroll, underTest.getFirstDayOfCurrentMonth());
  }
 @Test(expected = IllegalArgumentException.class)
 public void testItThrowsWhenDayColumnsIsNotLengthSeven() {
   String[] dayNames = {"Mon", "Tue", "Wed", "Thur", "Fri"};
   underTest.setDayColumnNames(dayNames);
 }
 @Test
 public void testItRemovesAllEvents() {
   underTest.removeAllEvents();
   verify(eventsContainer).removeAllEvents();
   verifyNoMoreInteractions(eventsContainer);
 }
 @Test
 public void testItRemovesCalendarEventsForADate() {
   underTest.removeEventsFor(1433701251000L);
   verify(eventsContainer).removeEventByEpochMillis(1433701251000L);
   verifyNoMoreInteractions(eventsContainer);
 }
 @Test
 public void testItGetCalendarEventsForADate() {
   underTest.getCalendarEventsFor(1433701251000L);
   verify(eventsContainer).getEventsFor(1433701251000L);
   verifyNoMoreInteractions(eventsContainer);
 }