content: /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
  * this work for additional information regarding copyright ownership.
  * The ASF licenses this file to You under the Apache License, Version 2.0
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
  *    http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  
  package org.apache.spark.unsafe.types;
  
  import org.junit.Test;
  
  import static org.junit.Assert.*;
  import static org.apache.spark.unsafe.types.CalendarInterval.*;
  
  public class CalendarIntervalSuite {
  
    @Test
    public void equalsTest() {
      CalendarInterval i1 = new CalendarInterval(3, 123);
      CalendarInterval i2 = new CalendarInterval(3, 321);
      CalendarInterval i3 = new CalendarInterval(1, 123);
      CalendarInterval i4 = new CalendarInterval(3, 123);
  
      assertNotSame(i1, i2);
      assertNotSame(i1, i3);
      assertNotSame(i2, i3);
      assertEquals(i1, i4);
    }
  
    @Test
    public void toStringTest() {
      CalendarInterval i;
  
      i = new CalendarInterval(34, 0);
      assertEquals("interval 2 years 10 months", i.toString());
  
      i = new CalendarInterval(-34, 0);
      assertEquals("interval -2 years -10 months", i.toString());
  
      i = new CalendarInterval(0, 3 * MICROS_PER_WEEK + 13 * MICROS_PER_HOUR + 123);
      assertEquals("interval 3 weeks 13 hours 123 microseconds", i.toString());
  
      i = new CalendarInterval(0, -3 * MICROS_PER_WEEK - 13 * MICROS_PER_HOUR - 123);
      assertEquals("interval -3 weeks -13 hours -123 microseconds", i.toString());
  
      i = new CalendarInterval(34, 3 * MICROS_PER_WEEK + 13 * MICROS_PER_HOUR + 123);
      assertEquals("interval 2 years 10 months 3 weeks 13 hours 123 microseconds", i.toString());
    }
  
    @Test
    public void fromStringTest() {
      testSingleUnit("year", 3, 36, 0);
      testSingleUnit("month", 3, 3, 0);
      testSingleUnit("week", 3, 0, 3 * MICROS_PER_WEEK);
      testSingleUnit("day", 3, 0, 3 * MICROS_PER_DAY);
      testSingleUnit("hour", 3, 0, 3 * MICROS_PER_HOUR);
      testSingleUnit("minute", 3, 0, 3 * MICROS_PER_MINUTE);
      testSingleUnit("second", 3, 0, 3 * MICROS_PER_SECOND);
      testSingleUnit("millisecond", 3, 0, 3 * MICROS_PER_MILLI);
      testSingleUnit("microsecond", 3, 0, 3);
  
      String input;
  
      input = "interval   -5  years  23   month";
      CalendarInterval result = new CalendarInterval(-5 * 12 + 23, 0);
      assertEquals(fromString(input), result);
  
      input = "interval   -5  years  23   month   ";
      assertEquals(fromString(input), result);
  
      input = "  interval   -5  years  23   month   ";
      assertEquals(fromString(input), result);
  
      // Error cases
      input = "interval   3month 1 hour";
      assertNull(fromString(input));
  
      input = "interval 3 moth 1 hour";
      assertNull(fromString(input));
  
      input = "interval";
      assertNull(fromString(input));
  
      input = "int";
      assertNull(fromString(input));
  
      input = "";
      assertNull(fromString(input));
  
      input = null;
      assertNull(fromString(input));
    }
  
    @Test
    public void fromYearMonthStringTest() {
      String input;
      CalendarInterval i;
  
      input = "99-10";
      i = new CalendarInterval(99 * 12 + 10, 0L);
      assertEquals(fromYearMonthString(input), i);
  
      input = "-8-10";
      i = new CalendarInterval(-8 * 12 - 10, 0L);
      assertEquals(fromYearMonthString(input), i);
  
      try {
        input = "99-15";
        fromYearMonthString(input);
        fail("Expected to throw an exception for the invalid input");
      } catch (IllegalArgumentException e) {
        assertTrue(e.getMessage().contains("month 15 outside range"));
      }
    }
  
    @Test
    public void fromDayTimeStringTest() {
      String input;
      CalendarInterval i;
  
      input = "5 12:40:30.999999999";
      i = new CalendarInterval(0, 5 * MICROS_PER_DAY + 12 * MICROS_PER_HOUR +
        40 * MICROS_PER_MINUTE + 30 * MICROS_PER_SECOND + 999999L);
      assertEquals(fromDayTimeString(input), i);
  
      input = "10 0:12:0.888";
      i = new CalendarInterval(0, 10 * MICROS_PER_DAY + 12 * MICROS_PER_MINUTE);
      assertEquals(fromDayTimeString(input), i);
  
      input = "-3 0:0:0";
      i = new CalendarInterval(0, -3 * MICROS_PER_DAY);
      assertEquals(fromDayTimeString(input), i);
  
      try {
        input = "5 30:12:20";
        fromDayTimeString(input);
        fail("Expected to throw an exception for the invalid input");
      } catch (IllegalArgumentException e) {
        assertTrue(e.getMessage().contains("hour 30 outside range"));
      }
  
      try {
        input = "5 30-12";
        fromDayTimeString(input);
        fail("Expected to throw an exception for the invalid input");
      } catch (IllegalArgumentException e) {
        assertTrue(e.getMessage().contains("not match day-time format"));
      }
    }
  
    @Test
    public void fromSingleUnitStringTest() {
      String input;
      CalendarInterval i;
  
      input = "12";
      i = new CalendarInterval(12 * 12, 0L);
      assertEquals(fromSingleUnitString("year", input), i);
  
      input = "100";
      i = new CalendarInterval(0, 100 * MICROS_PER_DAY);
      assertEquals(fromSingleUnitString("day", input), i);
  
      input = "1999.38888";
      i = new CalendarInterval(0, 1999 * MICROS_PER_SECOND + 38);
      assertEquals(fromSingleUnitString("second", input), i);
  
      try {
        input = String.valueOf(Integer.MAX_VALUE);
        fromSingleUnitString("year", input);
        fail("Expected to throw an exception for the invalid input");
      } catch (IllegalArgumentException e) {
        assertTrue(e.getMessage().contains("outside range"));
      }
  
      try {
        input = String.valueOf(Long.MAX_VALUE / MICROS_PER_HOUR + 1);
        fromSingleUnitString("hour", input);
        fail("Expected to throw an exception for the invalid input");
      } catch (IllegalArgumentException e) {
        assertTrue(e.getMessage().contains("outside range"));
      }
    }
  
    @Test
    public void addTest() {
      String input = "interval 3 month 1 hour";
      String input2 = "interval 2 month 100 hour";
  
      CalendarInterval interval = fromString(input);
      CalendarInterval interval2 = fromString(input2);
  
      assertEquals(interval.add(interval2), new CalendarInterval(5, 101 * MICROS_PER_HOUR));
  
      input = "interval -10 month -81 hour";
      input2 = "interval 75 month 200 hour";
  
      interval = fromString(input);
      interval2 = fromString(input2);
  
      assertEquals(interval.add(interval2), new CalendarInterval(65, 119 * MICROS_PER_HOUR));
    }
  
    @Test
    public void subtractTest() {
      String input = "interval 3 month 1 hour";
      String input2 = "interval 2 month 100 hour";
  
      CalendarInterval interval = fromString(input);
      CalendarInterval interval2 = fromString(input2);
  
      assertEquals(interval.subtract(interval2), new CalendarInterval(1, -99 * MICROS_PER_HOUR));
  
      input = "interval -10 month -81 hour";
      input2 = "interval 75 month 200 hour";
  
      interval = fromString(input);
      interval2 = fromString(input2);
  
      assertEquals(interval.subtract(interval2), new CalendarInterval(-85, -281 * MICROS_PER_HOUR));
    }
  
    private static void testSingleUnit(String unit, int number, int months, long microseconds) {
      String input1 = "interval " + number + " " + unit;
      String input2 = "interval " + number + " " + unit + "s";
      CalendarInterval result = new CalendarInterval(months, microseconds);
      assertEquals(fromString(input1), result);
      assertEquals(fromString(input2), result);
    }
  }
  