/**
* Copyright (C) 2014 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.strata.basics.date;
import static com.opengamma.strata.basics.date.Tenor.TENOR_10M;
import static com.opengamma.strata.basics.date.Tenor.TENOR_12M;
import static com.opengamma.strata.basics.date.Tenor.TENOR_18M;
import static com.opengamma.strata.basics.date.Tenor.TENOR_1D;
import static com.opengamma.strata.basics.date.Tenor.TENOR_1M;
import static com.opengamma.strata.basics.date.Tenor.TENOR_1W;
import static com.opengamma.strata.basics.date.Tenor.TENOR_1Y;
import static com.opengamma.strata.basics.date.Tenor.TENOR_2D;
import static com.opengamma.strata.basics.date.Tenor.TENOR_2M;
import static com.opengamma.strata.basics.date.Tenor.TENOR_2W;
import static com.opengamma.strata.basics.date.Tenor.TENOR_2Y;
import static com.opengamma.strata.basics.date.Tenor.TENOR_3D;
import static com.opengamma.strata.basics.date.Tenor.TENOR_3M;
import static com.opengamma.strata.basics.date.Tenor.TENOR_3W;
import static com.opengamma.strata.basics.date.Tenor.TENOR_3Y;
import static com.opengamma.strata.basics.date.Tenor.TENOR_4M;
import static com.opengamma.strata.basics.date.Tenor.TENOR_4Y;
import static com.opengamma.strata.basics.date.Tenor.TENOR_6W;
import static com.opengamma.strata.collect.TestHelper.assertJodaConvert;
import static com.opengamma.strata.collect.TestHelper.assertSerialization;
import static com.opengamma.strata.collect.TestHelper.assertThrows;
import static com.opengamma.strata.collect.TestHelper.assertThrowsIllegalArg;
import static java.time.temporal.ChronoUnit.CENTURIES;
import static java.time.temporal.ChronoUnit.DAYS;
import static java.time.temporal.ChronoUnit.MONTHS;
import static java.time.temporal.ChronoUnit.YEARS;
import static org.testng.Assert.assertEquals;
import java.time.LocalDate;
import java.time.OffsetDateTime;
import java.time.Period;
import java.time.ZoneOffset;
import java.time.temporal.UnsupportedTemporalTypeException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
/**
* Tests for the tenor class.
*/
@Test
public class TenorTest {
@DataProvider(name = "ofPeriod")
static Object[][] data_ofPeriod() {
return new Object[][] {
{Period.ofDays(1), Period.ofDays(1), "1D"},
{Period.ofDays(7), Period.ofDays(7), "1W"},
{Period.ofDays(10), Period.ofDays(10), "10D"},
{Period.ofWeeks(2), Period.ofDays(14), "2W"},
{Period.ofMonths(1), Period.ofMonths(1), "1M"},
{Period.ofMonths(2), Period.ofMonths(2), "2M"},
{Period.ofMonths(12), Period.ofMonths(12), "12M"},
{Period.ofYears(1), Period.ofYears(1), "1Y"},
{Period.ofMonths(20), Period.ofMonths(20), "20M"},
{Period.ofMonths(24), Period.ofMonths(24), "24M"},
{Period.ofYears(2), Period.ofYears(2), "2Y"},
{Period.ofMonths(30), Period.ofMonths(30), "30M"},
{Period.of(2, 6, 0), Period.of(2, 6, 0), "2Y6M"},
};
}
@Test(dataProvider = "ofPeriod")
public void test_ofPeriod(Period period, Period stored, String str) {
assertEquals(Tenor.of(period).getPeriod(), stored);
assertEquals(Tenor.of(period).toString(), str);
}
@DataProvider(name = "ofMonths")
static Object[][] data_ofMonths() {
return new Object[][] {
{1, Period.ofMonths(1), "1M"},
{2, Period.ofMonths(2), "2M"},
{12, Period.ofMonths(12), "12M"},
{20, Period.ofMonths(20), "20M"},
{24, Period.ofMonths(24), "24M"},
{30, Period.ofMonths(30), "30M"},
};
}
@Test(dataProvider = "ofMonths")
public void test_ofMonths(int months, Period stored, String str) {
assertEquals(Tenor.ofMonths(months).getPeriod(), stored);
assertEquals(Tenor.ofMonths(months).toString(), str);
}
@DataProvider(name = "ofYears")
static Object[][] data_ofYears() {
return new Object[][] {
{1, Period.ofYears(1), "1Y"},
{2, Period.ofYears(2), "2Y"},
{3, Period.ofYears(3), "3Y"},
};
}
@Test(dataProvider = "ofYears")
public void test_ofYears(int years, Period stored, String str) {
assertEquals(Tenor.ofYears(years).getPeriod(), stored);
assertEquals(Tenor.ofYears(years).toString(), str);
}
public void test_of_int() {
assertEquals(Tenor.ofDays(1), TENOR_1D);
assertEquals(Tenor.ofDays(7), TENOR_1W);
assertEquals(Tenor.ofWeeks(2), TENOR_2W);
assertEquals(Tenor.ofMonths(1), TENOR_1M);
assertEquals(Tenor.ofYears(1), TENOR_1Y);
}
public void test_of_notZero() {
assertThrowsIllegalArg(() -> Tenor.of(Period.ofDays(0)));
assertThrowsIllegalArg(() -> Tenor.ofDays(0));
assertThrowsIllegalArg(() -> Tenor.ofWeeks(0));
assertThrowsIllegalArg(() -> Tenor.ofMonths(0));
assertThrowsIllegalArg(() -> Tenor.ofYears(0));
}
public void test_of_notNegative() {
assertThrowsIllegalArg(() -> Tenor.of(Period.ofDays(-1)));
assertThrowsIllegalArg(() -> Tenor.ofDays(-1));
assertThrowsIllegalArg(() -> Tenor.ofWeeks(-1));
assertThrowsIllegalArg(() -> Tenor.ofMonths(-1));
assertThrowsIllegalArg(() -> Tenor.ofYears(-1));
}
//-------------------------------------------------------------------------
public void test_parse_String_roundTrip() {
assertEquals(Tenor.parse(TENOR_10M.toString()), TENOR_10M);
}
@DataProvider(name = "parseGood")
static Object[][] data_parseGood() {
return new Object[][] {
{"2D", TENOR_2D},
{"2W", TENOR_2W},
{"6W", TENOR_6W},
{"2M", TENOR_2M},
{"12M", TENOR_12M},
{"1Y", TENOR_1Y},
{"2Y", TENOR_2Y},
};
}
@Test(dataProvider = "parseGood")
public void test_parse_String_good_noP(String input, Tenor expected) {
assertEquals(Tenor.parse(input), expected);
}
@Test(dataProvider = "parseGood")
public void test_parse_String_good_withP(String input, Tenor expected) {
assertEquals(Tenor.parse("P" + input), expected);
}
@DataProvider(name = "parseBad")
static Object[][] data_parseBad() {
return new Object[][] {
{""},
{"2"},
{"2K"},
{"-2D"},
};
}
@Test(dataProvider = "parseBad", expectedExceptions = IllegalArgumentException.class)
public void test_parse_String_bad(String input) {
Tenor.parse(input);
}
//-------------------------------------------------------------------------
public void test_getPeriod() {
assertEquals(TENOR_3D.getPeriod(), Period.ofDays(3));
assertEquals(TENOR_3W.getPeriod(), Period.ofDays(21));
assertEquals(TENOR_3M.getPeriod(), Period.ofMonths(3));
assertEquals(TENOR_3Y.getPeriod(), Period.ofYears(3));
}
//-------------------------------------------------------------------------
@DataProvider(name = "normalized")
static Object[][] data_normalized() {
return new Object[][] {
{Period.ofDays(1), Period.ofDays(1)},
{Period.ofDays(7), Period.ofDays(7)},
{Period.ofDays(10), Period.ofDays(10)},
{Period.ofWeeks(2), Period.ofDays(14)},
{Period.ofMonths(1), Period.ofMonths(1)},
{Period.ofMonths(2), Period.ofMonths(2)},
{Period.ofMonths(12), Period.ofMonths(12)},
{Period.ofYears(1), Period.ofMonths(12)},
{Period.ofMonths(20), Period.of(1, 8, 0)},
{Period.ofMonths(24), Period.ofYears(2)},
{Period.ofYears(2), Period.ofYears(2)},
{Period.ofMonths(30), Period.of(2, 6, 0)},
};
}
@Test(dataProvider = "normalized")
public void test_normalized(Period period, Period normalized) {
assertEquals(Tenor.of(period).normalized().getPeriod(), normalized);
}
//-------------------------------------------------------------------------
@DataProvider(name = "based")
static Object[][] data_based() {
return new Object[][] {
{Tenor.ofDays(1), false, false},
{Tenor.ofDays(2), false, false},
{Tenor.ofDays(6), false, false},
{Tenor.ofDays(7), true, false},
{Tenor.ofWeeks(1), true, false},
{Tenor.ofWeeks(3), true, false},
{Tenor.ofMonths(1), false, true},
{Tenor.ofMonths(3), false, true},
{Tenor.ofYears(1), false, true},
{Tenor.ofYears(3), false, true},
{Tenor.of(Period.of(1, 2, 3)), false, false},
};
}
@Test(dataProvider = "based")
public void test_isWeekBased(Tenor test, boolean weekBased, boolean monthBased) {
assertEquals(test.isWeekBased(), weekBased);
}
@Test(dataProvider = "based")
public void test_isMonthBased(Tenor test, boolean weekBased, boolean monthBased) {
assertEquals(test.isMonthBased(), monthBased);
}
//-------------------------------------------------------------------------
public void test_addTo() {
assertEquals(TENOR_3D.addTo(LocalDate.of(2014, 6, 30)), LocalDate.of(2014, 7, 3));
assertEquals(TENOR_1W.addTo(
OffsetDateTime.of(2014, 6, 30, 0, 0, 0, 0, ZoneOffset.UTC)),
OffsetDateTime.of(2014, 7, 7, 0, 0, 0, 0, ZoneOffset.UTC));
}
public void test_subtractFrom() {
assertEquals(TENOR_3D.subtractFrom(LocalDate.of(2014, 6, 30)), LocalDate.of(2014, 6, 27));
assertEquals(TENOR_1W.subtractFrom(
OffsetDateTime.of(2014, 6, 30, 0, 0, 0, 0, ZoneOffset.UTC)),
OffsetDateTime.of(2014, 6, 23, 0, 0, 0, 0, ZoneOffset.UTC));
}
//-------------------------------------------------------------------------
public void test_temporalAmount() {
assertEquals(TENOR_3D.getUnits(), ImmutableList.of(YEARS, MONTHS, DAYS));
assertEquals(TENOR_3D.get(DAYS), 3);
assertEquals(LocalDate.of(2014, 6, 30).plus(TENOR_1W), LocalDate.of(2014, 7, 7));
assertEquals(LocalDate.of(2014, 6, 30).minus(TENOR_1W), LocalDate.of(2014, 6, 23));
assertThrows(() -> TENOR_10M.get(CENTURIES), UnsupportedTemporalTypeException.class);
}
//-------------------------------------------------------------------------
public void test_compare() {
List<Tenor> tenors = ImmutableList.of(
Tenor.ofDays(1),
Tenor.ofDays(3),
Tenor.ofDays(7),
Tenor.ofWeeks(2),
Tenor.ofWeeks(4),
Tenor.ofDays(30),
Tenor.ofMonths(1),
Tenor.ofDays(31),
Tenor.of(Period.of(0, 1, 1)),
Tenor.ofDays(60),
Tenor.ofMonths(2),
Tenor.ofDays(61),
Tenor.ofDays(91),
Tenor.ofMonths(3),
Tenor.ofDays(92),
Tenor.ofDays(182),
Tenor.ofMonths(6),
Tenor.ofDays(183),
Tenor.ofDays(365),
Tenor.ofYears(1),
Tenor.ofDays(366));
List<Tenor> test = new ArrayList<>(tenors);
Collections.shuffle(test);
Collections.sort(test);
assertEquals(test, tenors);
}
//-------------------------------------------------------------------------
public void test_equals_hashCode() {
Tenor a1 = TENOR_3D;
Tenor a2 = Tenor.ofDays(3);
Tenor b = TENOR_4M;
assertEquals(a1.equals(a1), true);
assertEquals(a1.equals(b), false);
assertEquals(a1.equals(a2), true);
assertEquals(a2.equals(a1), true);
assertEquals(a2.equals(a2), true);
assertEquals(a2.equals(b), false);
assertEquals(b.equals(a1), false);
assertEquals(b.equals(a2), false);
assertEquals(b.equals(b), true);
assertEquals(a1.hashCode(), a2.hashCode());
}
public void test_equals_bad() {
assertEquals(TENOR_3D.equals(null), false);
assertEquals(TENOR_3D.equals("String"), false);
assertEquals(TENOR_3D.equals(new Object()), false);
}
//-------------------------------------------------------------------------
public void test_toString() {
assertEquals(TENOR_3D.toString(), "3D");
assertEquals(TENOR_2W.toString(), "2W");
assertEquals(TENOR_4M.toString(), "4M");
assertEquals(TENOR_12M.toString(), "12M");
assertEquals(TENOR_1Y.toString(), "1Y");
assertEquals(TENOR_18M.toString(), "18M");
assertEquals(TENOR_4Y.toString(), "4Y");
}
//-----------------------------------------------------------------------
public void test_serialization() {
assertSerialization(TENOR_3D);
assertSerialization(TENOR_4M);
assertSerialization(TENOR_3Y);
}
public void test_jodaConvert() {
assertJodaConvert(Tenor.class, TENOR_3D);
assertJodaConvert(Tenor.class, TENOR_4M);
assertJodaConvert(Tenor.class, TENOR_3Y);
}
}