@@ -846,6 +846,80 @@ public void hourOfDayInvalidArguments() {
846846
847847 }
848848
849+ private void checkForExpectedDay (
850+ FunctionExpression functionExpression ,
851+ String expectedDay ,
852+ String testExpr ) {
853+ assertEquals (DATE , functionExpression .type ());
854+ assertEquals (new ExprDateValue (expectedDay ), eval (functionExpression ));
855+ assertEquals (testExpr , functionExpression .toString ());
856+ }
857+
858+ private static Stream <Arguments > getTestDataForLastDay () {
859+ return Stream .of (
860+ Arguments .of (new ExprDateValue ("2017-01-20" ), "2017-01-31" , "last_day(DATE '2017-01-20')" ),
861+ //Leap year
862+ Arguments .of (new ExprDateValue ("2020-02-20" ), "2020-02-29" , "last_day(DATE '2020-02-20')" ),
863+ //Non leap year
864+ Arguments .of (new ExprDateValue ("2017-02-20" ), "2017-02-28" , "last_day(DATE '2017-02-20')" ),
865+ Arguments .of (new ExprDateValue ("2017-03-20" ), "2017-03-31" , "last_day(DATE '2017-03-20')" ),
866+ Arguments .of (new ExprDateValue ("2017-04-20" ), "2017-04-30" , "last_day(DATE '2017-04-20')" ),
867+ Arguments .of (new ExprDateValue ("2017-05-20" ), "2017-05-31" , "last_day(DATE '2017-05-20')" ),
868+ Arguments .of (new ExprDateValue ("2017-06-20" ), "2017-06-30" , "last_day(DATE '2017-06-20')" ),
869+ Arguments .of (new ExprDateValue ("2017-07-20" ), "2017-07-31" , "last_day(DATE '2017-07-20')" ),
870+ Arguments .of (new ExprDateValue ("2017-08-20" ), "2017-08-31" , "last_day(DATE '2017-08-20')" ),
871+ Arguments .of (new ExprDateValue ("2017-09-20" ), "2017-09-30" , "last_day(DATE '2017-09-20')" ),
872+ Arguments .of (new ExprDateValue ("2017-10-20" ), "2017-10-31" , "last_day(DATE '2017-10-20')" ),
873+ Arguments .of (new ExprDateValue ("2017-11-20" ), "2017-11-30" , "last_day(DATE '2017-11-20')" ),
874+ Arguments .of (new ExprDateValue ("2017-12-20" ), "2017-12-31" , "last_day(DATE '2017-12-20')" )
875+ );
876+ }
877+
878+ @ ParameterizedTest (name = "{2}" )
879+ @ MethodSource ("getTestDataForLastDay" )
880+ public void testLastDay (ExprValue testedDateTime , String expectedResult , String expectedQuery ) {
881+ lenient ().when (nullRef .valueOf (env )).thenReturn (nullValue ());
882+ lenient ().when (missingRef .valueOf (env )).thenReturn (missingValue ());
883+
884+ checkForExpectedDay (
885+ DSL .last_day (functionProperties , DSL .literal (testedDateTime )),
886+ expectedResult ,
887+ expectedQuery
888+ );
889+ }
890+
891+ @ Test
892+ public void testLastDayWithTimeType () {
893+ lenient ().when (nullRef .valueOf (env )).thenReturn (nullValue ());
894+ lenient ().when (missingRef .valueOf (env )).thenReturn (missingValue ());
895+
896+ FunctionExpression expression = DSL .last_day (
897+ functionProperties , DSL .literal (new ExprTimeValue ("12:23:34" )));
898+
899+ LocalDate expected = LocalDate .now (functionProperties .getQueryStartClock ());
900+ LocalDate result = eval (expression ).dateValue ();
901+
902+
903+ assertAll (
904+ () -> assertEquals ((expected .lengthOfMonth ()), result .getDayOfMonth ()),
905+ () -> assertEquals ("last_day(TIME '12:23:34')" , expression .toString ())
906+ );
907+ }
908+
909+ private void lastDay (String date ) {
910+ FunctionExpression expression = DSL .day_of_week (
911+ functionProperties , DSL .literal (new ExprDateValue (date )));
912+ eval (expression );
913+ }
914+
915+ @ Test
916+ public void testLastDayInvalidArgument () {
917+ lenient ().when (nullRef .valueOf (env )).thenReturn (nullValue ());
918+ lenient ().when (missingRef .valueOf (env )).thenReturn (missingValue ());
919+
920+ assertThrows (SemanticCheckException .class , () -> lastDay ("asdfasdf" ));
921+ }
922+
849923 @ Test
850924 public void microsecond () {
851925 when (nullRef .type ()).thenReturn (TIME );
0 commit comments