--- /dev/null 2015-01-29 01:57:10.288752478 -0800 +++ new/test/javax/xml/jaxp/functional/javax/xml/datatype/ptests/DurationTest.java 2015-01-29 00:33:02.623834025 -0800 @@ -0,0 +1,587 @@ +/* + * Copyright (c) 1999, 2015, 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 jaxp.library.JAXPBaseTest; + +import org.testng.Assert; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/* + * @summary Class containing the test cases for Duration. + */ +public class DurationTest extends JAXPBaseTest { + + 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 getyears = duration -> duration.getYears(); + Function getmonths = duration -> duration.getMonths(); + Function getdays = duration -> duration.getDays(); + Function gethours = duration -> duration.getHours(); + Function getminutes = duration -> duration.getMinutes(); + Function 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 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; + +}