blob: 057414557a05db0d8dd915b8f4ab9d2efd676b2b [file] [log] [blame]
/*
* Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.xml.datatype.ptests;
import static javax.xml.datatype.DatatypeConstants.DAYS;
import static javax.xml.datatype.DatatypeConstants.HOURS;
import static javax.xml.datatype.DatatypeConstants.MINUTES;
import static javax.xml.datatype.DatatypeConstants.MONTHS;
import static javax.xml.datatype.DatatypeConstants.SECONDS;
import static javax.xml.datatype.DatatypeConstants.YEARS;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Calendar;
import java.util.function.Function;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeConstants;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.Duration;
import javax.xml.namespace.QName;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;
/*
* @test
* @library /javax/xml/jaxp/libs
* @run testng/othervm -DrunSecMngr=true javax.xml.datatype.ptests.DurationTest
* @run testng/othervm javax.xml.datatype.ptests.DurationTest
* @summary Class containing the test cases for Duration.
*/
@Listeners({jaxp.library.BasePolicy.class})
public class DurationTest {
private DatatypeFactory datatypeFactory;
/*
* Setup.
*/
@BeforeClass
public void setup() throws DatatypeConfigurationException {
datatypeFactory = DatatypeFactory.newInstance();
}
@DataProvider(name = "legal-number-duration")
public Object[][] getLegalNumberDuration() {
return new Object[][] {
// is positive, year, month, day, hour, minute, second
{ true, 1, 1, 1, 1, 1, 1 },
{ false, 1, 1, 1, 1, 1, 1 },
{ true, 1, 0, 0, 0, 0, 0 },
{ false, 1, 0, 0, 0, 0, 0 }
};
}
/*
* Test for constructor Duration(boolean isPositive,int years,int months,
* int days,int hours,int minutes,int seconds).
*/
@Test(dataProvider = "legal-number-duration")
public void checkNumberDurationPos(boolean isPositive, int years, int months, int days, int hours, int minutes, int seconds) {
datatypeFactory.newDuration(isPositive, years, months, days, hours, minutes, seconds);
}
@DataProvider(name = "illegal-number-duration")
public Object[][] getIllegalNumberDuration() {
return new Object[][] {
// is positive, year, month, day, hour, minute, second
{ true, 1, 1, -1, 1, 1, 1 },
{ false, 1, 1, -1, 1, 1, 1 },
{ true, undef, undef, undef, undef, undef, undef },
{ false, undef, undef, undef, undef, undef, undef }
};
}
/*
* Test for constructor Duration(boolean isPositive,int years,int months,
* int days,int hours,int minutes,int seconds), if any of the fields is
* negative should throw IllegalArgumentException.
*/
@Test(expectedExceptions = IllegalArgumentException.class, dataProvider = "illegal-number-duration")
public void checkDurationNumberNeg(boolean isPositive, int years, int months, int days, int hours, int minutes, int seconds) {
datatypeFactory.newDuration(isPositive, years, months, days, hours, minutes, seconds);
}
@DataProvider(name = "legal-bigint-duration")
public Object[][] getLegalBigIntegerDuration() {
return new Object[][] {
// is positive, year, month, day, hour, minute, second
{ true, zero, zero, zero, zero, zero, new BigDecimal(zero) },
{ false, zero, zero, zero, zero, zero, new BigDecimal(zero) },
{ true, one, one, one, one, one, new BigDecimal(one) },
{ false, one, one, one, one, one, new BigDecimal(one) },
{ true, null, null, null, null, null, new BigDecimal(one) },
{ false, null, null, null, null, null, new BigDecimal(one) } };
}
/*
* Test for constructor Duration(boolean isPositive,BigInteger
* years,BigInteger months, BigInteger days,BigInteger hours,BigInteger
* minutes,BigDecimal seconds).
*/
@Test(dataProvider = "legal-bigint-duration")
public void checkBigIntegerDurationPos(boolean isPositive, BigInteger years, BigInteger months, BigInteger days, BigInteger hours, BigInteger minutes,
BigDecimal seconds) {
datatypeFactory.newDuration(isPositive, years, months, days, hours, minutes, seconds);
}
@DataProvider(name = "illegal-bigint-duration")
public Object[][] getIllegalBigIntegerDuration() {
return new Object[][] {
// is positive, year, month, day, hour, minute, second
{ true, null, null, null, null, null, null },
{ false, null, null, null, null, null, null }
};
}
/*
* Test for constructor Duration(boolean isPositive,BigInteger
* years,BigInteger months, BigInteger days,BigInteger hours,BigInteger
* minutes,BigDecimal seconds), if all the fields are null should throw
* IllegalArgumentException.
*/
@Test(expectedExceptions = IllegalArgumentException.class, dataProvider = "illegal-bigint-duration")
public void checkBigIntegerDurationNeg(boolean isPositive, BigInteger years, BigInteger months, BigInteger days, BigInteger hours, BigInteger minutes,
BigDecimal seconds) {
datatypeFactory.newDuration(isPositive, years, months, days, hours, minutes, seconds);
}
@DataProvider(name = "legal-millisec-duration")
public Object[][] getLegalMilliSecondDuration() {
return new Object[][] { { 1000000 }, { 0 }, { Long.MAX_VALUE }, { Long.MIN_VALUE }
};
}
/*
* Test for constructor Duration(long durationInMilliSeconds)
*/
@Test(dataProvider = "legal-millisec-duration")
public void checkMilliSecondDuration(long millisec) {
datatypeFactory.newDuration(millisec);
}
@DataProvider(name = "legal-lexical-duration")
public Object[][] getLegalLexicalDuration() {
return new Object[][] { { "P1Y1M1DT1H1M1S" }, { "-P1Y1M1DT1H1M1S" } };
}
/*
* Test for constructor Duration(java.lang.String lexicalRepresentation)
*/
@Test(dataProvider = "legal-lexical-duration")
public void checkLexicalDurationPos(String lexRepresentation) {
datatypeFactory.newDuration(lexRepresentation);
}
@DataProvider(name = "illegal-lexical-duration")
public Object[][] getIllegalLexicalDuration() {
return new Object[][] {
{ null },
{ "P1Y1M1DT1H1M1S " },
{ " P1Y1M1DT1H1M1S" },
{ "X1Y1M1DT1H1M1S" },
{ "" },
{ "P1Y2MT" } // The designator 'T' shall be absent if all of the time items are absent in "PnYnMnDTnHnMnS"
};
}
/*
* Test for constructor Duration(java.lang.String lexicalRepresentation),
* null should throw NullPointerException, invalid lex should throw
* IllegalArgumentException
*/
@Test(expectedExceptions = { NullPointerException.class, IllegalArgumentException.class }, dataProvider = "illegal-lexical-duration")
public void checkLexicalDurationNeg(String lexRepresentation) {
datatypeFactory.newDuration(lexRepresentation);
}
@DataProvider(name = "equal-duration")
public Object[][] getEqualDurations() {
return new Object[][] { { "P1Y1M1DT1H1M1S", "P1Y1M1DT1H1M1S" } };
}
/*
* Test for compare() both durations valid and equal.
*/
@Test(dataProvider = "equal-duration")
public void checkDurationEqual(String lexRepresentation1, String lexRepresentation2) {
Duration duration1 = datatypeFactory.newDuration(lexRepresentation1);
Duration duration2 = datatypeFactory.newDuration(lexRepresentation2);
assertTrue(duration1.equals(duration2));
}
@DataProvider(name = "greater-duration")
public Object[][] getGreaterDuration() {
return new Object[][] {
{ "P1Y1M1DT1H1M2S", "P1Y1M1DT1H1M1S" },
{ "P1Y1M1DT1H1M1S", "-P1Y1M1DT1H1M2S" },
{ "P1Y1M1DT1H1M2S", "-P1Y1M1DT1H1M1S" },
{ "-P1Y1M1DT1H1M1S", "-P1Y1M1DT1H1M2S" }, };
}
/*
* Test for compare() both durations valid and lhs > rhs.
*/
@Test(dataProvider = "greater-duration")
public void checkDurationCompare(String lexRepresentation1, String lexRepresentation2) {
Duration duration1 = datatypeFactory.newDuration(lexRepresentation1);
Duration duration2 = datatypeFactory.newDuration(lexRepresentation2);
assertTrue(duration1.compare(duration2) == DatatypeConstants.GREATER);
}
@DataProvider(name = "not-equal-duration")
public Object[][] getNotEqualDurations() {
return new Object[][] {
{ "P1Y1M1DT1H1M1S", "-P1Y1M1DT1H1M1S" },
{ "P2Y1M1DT1H1M1S", "P1Y1M1DT1H1M1S" } };
}
/*
* Test for equals() both durations valid and lhs not equals rhs.
*/
@Test(dataProvider = "not-equal-duration")
public void checkDurationNotEqual(String lexRepresentation1, String lexRepresentation2) {
Duration duration1 = datatypeFactory.newDuration(lexRepresentation1);
Duration duration2 = datatypeFactory.newDuration(lexRepresentation2);
Assert.assertNotEquals(duration1, duration2);
}
@DataProvider(name = "duration-sign")
public Object[][] getDurationAndSign() {
return new Object[][] {
{ "P0Y0M0DT0H0M0S", 0 },
{ "P1Y0M0DT0H0M0S", 1 },
{ "-P1Y0M0DT0H0M0S", -1 } };
}
/*
* Test for Duration.getSign().
*/
@Test(dataProvider = "duration-sign")
public void checkDurationSign(String lexRepresentation, int sign) {
Duration duration = datatypeFactory.newDuration(lexRepresentation);
assertEquals(duration.getSign(), sign);
}
/*
* Test for Duration.negate().
*/
@Test
public void checkDurationNegate() {
Duration durationPos = datatypeFactory.newDuration("P1Y0M0DT0H0M0S");
Duration durationNeg = datatypeFactory.newDuration("-P1Y0M0DT0H0M0S");
assertEquals(durationPos.negate(), durationNeg);
assertEquals(durationNeg.negate(), durationPos);
assertEquals(durationPos.negate().negate(), durationPos);
}
/*
* Test for Duration.isShorterThan(Duration) and
* Duration.isLongerThan(Duration).
*/
@Test
public void checkDurationShorterLonger() {
Duration shorter = datatypeFactory.newDuration("P1Y1M1DT1H1M1S");
Duration longer = datatypeFactory.newDuration("P2Y1M1DT1H1M1S");
assertTrue(shorter.isShorterThan(longer));
assertFalse(longer.isShorterThan(shorter));
assertFalse(shorter.isShorterThan(shorter));
assertTrue(longer.isLongerThan(shorter));
assertFalse(shorter.isLongerThan(longer));
assertFalse(shorter.isLongerThan(shorter));
}
/*
* Test for Duration.isSet().
*/
@Test
public void checkDurationIsSet() {
Duration duration1 = datatypeFactory.newDuration(true, 1, 1, 1, 1, 1, 1);
Duration duration2 = datatypeFactory.newDuration(true, 0, 0, 0, 0, 0, 0);
assertTrue(duration1.isSet(YEARS));
assertTrue(duration1.isSet(MONTHS));
assertTrue(duration1.isSet(DAYS));
assertTrue(duration1.isSet(HOURS));
assertTrue(duration1.isSet(MINUTES));
assertTrue(duration1.isSet(SECONDS));
assertTrue(duration2.isSet(YEARS));
assertTrue(duration2.isSet(MONTHS));
assertTrue(duration2.isSet(DAYS));
assertTrue(duration2.isSet(HOURS));
assertTrue(duration2.isSet(MINUTES));
assertTrue(duration2.isSet(SECONDS));
Duration duration66 = datatypeFactory.newDuration(true, null, null, zero, null, null, null);
assertFalse(duration66.isSet(YEARS));
assertFalse(duration66.isSet(MONTHS));
assertFalse(duration66.isSet(HOURS));
assertFalse(duration66.isSet(MINUTES));
assertFalse(duration66.isSet(SECONDS));
Duration duration3 = datatypeFactory.newDuration("P1D");
assertFalse(duration3.isSet(YEARS));
assertFalse(duration3.isSet(MONTHS));
assertFalse(duration3.isSet(HOURS));
assertFalse(duration3.isSet(MINUTES));
assertFalse(duration3.isSet(SECONDS));
}
/*
* Test Duration.isSet(Field) throws NPE if the field parameter is null.
*/
@Test(expectedExceptions = NullPointerException.class)
public void checkDurationIsSetNeg() {
Duration duration = datatypeFactory.newDuration(true, 0, 0, 0, 0, 0, 0);
duration.isSet(null);
}
/*
* Test for -getField(DatatypeConstants.Field) DatatypeConstants.Field is
* null - throws NPE.
*/
@Test(expectedExceptions = NullPointerException.class)
public void checkDurationGetFieldNeg() {
Duration duration67 = datatypeFactory.newDuration("P1Y1M1DT1H1M1S");
duration67.getField(null);
}
@DataProvider(name = "duration-fields")
public Object[][] getDurationAndFields() {
return new Object[][] {
{ "P1Y1M1DT1H1M1S", one, one, one, one, one, new BigDecimal(one) },
{ "PT1M", null, null, null, null, one, null },
{ "P1M", null, one, null, null, null, null } };
}
/*
* Test for Duration.getField(DatatypeConstants.Field).
*/
@Test(dataProvider = "duration-fields")
public void checkDurationGetField(String lexRepresentation, BigInteger years, BigInteger months, BigInteger days, BigInteger hours, BigInteger minutes,
BigDecimal seconds) {
Duration duration = datatypeFactory.newDuration(lexRepresentation);
assertEquals(duration.getField(YEARS), years);
assertEquals(duration.getField(MONTHS), months);
assertEquals(duration.getField(DAYS), days);
assertEquals(duration.getField(HOURS), hours);
assertEquals(duration.getField(MINUTES), minutes);
assertEquals(duration.getField(SECONDS), seconds);
}
@DataProvider(name = "number-string")
public Object[][] getNumberAndString() {
return new Object[][] {
// is positive, year, month, day, hour, minute, second, lexical
{ true, 1, 1, 1, 1, 1, 1, "P1Y1M1DT1H1M1S" },
{ false, 1, 1, 1, 1, 1, 1, "-P1Y1M1DT1H1M1S" },
{ true, 0, 0, 0, 0, 0, 0, "P0Y0M0DT0H0M0S" },
{ false, 0, 0, 0, 0, 0, 0, "P0Y0M0DT0H0M0S" }
};
}
/*
* Test for - toString().
*/
@Test(dataProvider = "number-string")
public void checkDurationToString(boolean isPositive, int years, int months, int days, int hours, int minutes, int seconds, String lexical) {
Duration duration = datatypeFactory.newDuration(isPositive, years, months, days, hours, minutes, seconds);
assertEquals(duration.toString(), lexical);
assertEquals(datatypeFactory.newDuration(duration.toString()), duration);
}
@DataProvider(name = "duration-field")
public Object[][] getDurationAndField() {
Function<Duration, Integer> getyears = duration -> duration.getYears();
Function<Duration, Integer> getmonths = duration -> duration.getMonths();
Function<Duration, Integer> getdays = duration -> duration.getDays();
Function<Duration, Integer> gethours = duration -> duration.getHours();
Function<Duration, Integer> getminutes = duration -> duration.getMinutes();
Function<Duration, Integer> getseconds = duration -> duration.getSeconds();
return new Object[][] {
{ "P1Y1M1DT1H1M1S", getyears, 1 },
{ "P1M1DT1H1M1S", getyears, 0 },
{ "P1Y1M1DT1H1M1S", getmonths, 1 },
{ "P1Y1DT1H1M1S", getmonths, 0 },
{ "P1Y1M1DT1H1M1S", getdays, 1 },
{ "P1Y1MT1H1M1S", getdays, 0 },
{ "P1Y1M1DT1H1M1S", gethours, 1 },
{ "P1Y1M1DT1M1S", gethours, 0 },
{ "P1Y1M1DT1H1M1S", getminutes, 1 },
{ "P1Y1M1DT1H1S", getminutes, 0 },
{ "P1Y1M1DT1H1M1S", getseconds, 1 },
{ "P1Y1M1DT1H1M", getseconds, 0 },
{ "P1Y1M1DT1H1M100000000S", getseconds, 100000000 }, };
}
/*
* Test for Duration.getYears(), getMonths(), etc.
*/
@Test(dataProvider = "duration-field")
public void checkDurationGetOneField(String lexRepresentation, Function<Duration, Integer> getter, int value) {
Duration duration = datatypeFactory.newDuration(lexRepresentation);
assertEquals(getter.apply(duration).intValue(), value);
}
/*
* Test for - getField(SECONDS)
*/
@Test
public void checkDurationGetSecondsField() {
Duration duration85 = datatypeFactory.newDuration("P1Y1M1DT1H1M100000000S");
assertEquals((duration85.getField(SECONDS)).intValue(), 100000000);
}
/*
* getTimeInMillis(java.util.Calendar startInstant) returns milliseconds
* between startInstant and startInstant plus this Duration.
*/
@Test
public void checkDurationGetTimeInMillis() {
Duration duration86 = datatypeFactory.newDuration("PT1M1S");
Calendar calendar86 = Calendar.getInstance();
assertEquals(duration86.getTimeInMillis(calendar86), 61000);
}
/*
* getTimeInMillis(java.util.Calendar startInstant) returns milliseconds
* between startInstant and startInstant plus this Duration throws NPE if
* startInstant parameter is null.
*/
@Test(expectedExceptions = NullPointerException.class)
public void checkDurationGetTimeInMillisNeg() {
Duration duration87 = datatypeFactory.newDuration("PT1M1S");
Calendar calendar87 = null;
duration87.getTimeInMillis(calendar87);
}
@DataProvider(name = "duration-for-hash")
public Object[][] getDurationsForHash() {
return new Object[][] {
{ "P1Y1M1DT1H1M1S", "P1Y1M1DT1H1M1S" },
{ "P1D", "PT24H" },
{ "PT1H", "PT60M" },
{ "PT1M", "PT60S" },
{ "P1Y", "P12M" } };
}
/*
* Test for Duration.hashcode(). hashcode() should return same value for
* some equal durations.
*/
@Test(dataProvider = "duration-for-hash")
public void checkDurationHashCode(String lexRepresentation1, String lexRepresentation2) {
Duration duration1 = datatypeFactory.newDuration(lexRepresentation1);
Duration duration2 = datatypeFactory.newDuration(lexRepresentation2);
int hash1 = duration1.hashCode();
int hash2 = duration2.hashCode();
assertTrue(hash1 == hash2, " generated hash1 : " + hash1 + " generated hash2 : " + hash2);
}
@DataProvider(name = "duration-for-add")
public Object[][] getDurationsForAdd() {
return new Object[][] {
// initVal, addVal, resultVal
{ "P1Y1M1DT1H1M1S", "P1Y1M1DT1H1M1S", "P2Y2M2DT2H2M2S" },
{ "P1Y1M1DT1H1M1S", "-P1Y1M1DT1H1M1S", "P0Y0M0DT0H0M0S" },
{ "-P1Y1M1DT1H1M1S", "-P1Y1M1DT1H1M1S", "-P2Y2M2DT2H2M2S" }, };
}
/*
* Test for add(Duration rhs).
*/
@Test(dataProvider = "duration-for-add")
public void checkDurationAdd(String initVal, String addVal, String result) {
Duration durationInit = datatypeFactory.newDuration(initVal);
Duration durationAdd = datatypeFactory.newDuration(addVal);
Duration durationResult = datatypeFactory.newDuration(result);
assertEquals(durationInit.add(durationAdd), durationResult);
}
@DataProvider(name = "duration-for-addneg")
public Object[][] getDurationsForAddNeg() {
return new Object[][] {
// initVal, addVal
{ "P1Y1M1DT1H1M1S", null },
{ "P1Y", "-P1D" },
{ "-P1Y", "P1D" }, };
}
/*
* Test for add(Duration rhs) 'rhs' is null , should throw NPE. "1 year" +
* "-1 day" or "-1 year" + "1 day" should throw IllegalStateException
*/
@Test(expectedExceptions = { NullPointerException.class, IllegalStateException.class }, dataProvider = "duration-for-addneg")
public void checkDurationAddNeg(String initVal, String addVal) {
Duration durationInit = datatypeFactory.newDuration(initVal);
Duration durationAdd = addVal == null ? null : datatypeFactory.newDuration(addVal);
durationInit.add(durationAdd);
}
/*
* Test Duration#compare(Duration duration) with large durations.
*
* Bug # 4972785 UnsupportedOperationException is expected
*
*/
@Test(expectedExceptions = UnsupportedOperationException.class)
public void checkDurationCompareLarge() {
String duration1Lex = "P100000000000000000000D";
String duration2Lex = "PT2400000000000000000000H";
Duration duration1 = datatypeFactory.newDuration(duration1Lex);
Duration duration2 = datatypeFactory.newDuration(duration2Lex);
duration1.compare(duration2);
}
/*
* Test Duration#getXMLSchemaType().
*
* Bug # 5049544 Duration.getXMLSchemaType shall return the correct result
*
*/
@Test
public void checkDurationGetXMLSchemaType() {
// DURATION
Duration duration = datatypeFactory.newDuration("P1Y1M1DT1H1M1S");
QName duration_xmlSchemaType = duration.getXMLSchemaType();
assertEquals(duration_xmlSchemaType, DatatypeConstants.DURATION, "Expected DatatypeConstants.DURATION, returned " + duration_xmlSchemaType.toString());
// DURATION_DAYTIME
Duration duration_dayTime = datatypeFactory.newDuration("P1DT1H1M1S");
QName duration_dayTime_xmlSchemaType = duration_dayTime.getXMLSchemaType();
assertEquals(duration_dayTime_xmlSchemaType, DatatypeConstants.DURATION_DAYTIME, "Expected DatatypeConstants.DURATION_DAYTIME, returned "
+ duration_dayTime_xmlSchemaType.toString());
// DURATION_YEARMONTH
Duration duration_yearMonth = datatypeFactory.newDuration("P1Y1M");
QName duration_yearMonth_xmlSchemaType = duration_yearMonth.getXMLSchemaType();
assertEquals(duration_yearMonth_xmlSchemaType, DatatypeConstants.DURATION_YEARMONTH, "Expected DatatypeConstants.DURATION_YEARMONTH, returned "
+ duration_yearMonth_xmlSchemaType.toString());
}
private final int undef = DatatypeConstants.FIELD_UNDEFINED;
private final BigInteger zero = BigInteger.ZERO;
private final BigInteger one = BigInteger.ONE;
}