| // Copyright 2013 the V8 project authors. All rights reserved. |
| // Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. |
| // |
| // Redistribution and use in source and binary forms, with or without |
| // modification, are permitted provided that the following conditions |
| // are met: |
| // 1. Redistributions of source code must retain the above copyright |
| // notice, this list of conditions and the following disclaimer. |
| // 2. Redistributions in binary form must reproduce the above copyright |
| // notice, this list of conditions and the following disclaimer in the |
| // documentation and/or other materials provided with the distribution. |
| // |
| // THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY |
| // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| // DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY |
| // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON |
| // ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| |
| description( |
| "This tests if the Date setters handle invalid parameters correctly resulting in a NaN date and if a recovery from such a NaN date is only possible by using the date.setTime() and date.set[[UTC]Full]Year() functions." |
| ); |
| |
| var dateFunctionNameRoots = [ |
| "Time", |
| "Milliseconds", |
| "UTCMilliseconds", |
| "Seconds", |
| "UTCSeconds", |
| "Minutes", |
| "UTCMinutes", |
| "Hours", |
| "UTCHours", |
| "Date", |
| "UTCDate", |
| "Month", |
| "UTCMonth", |
| "FullYear", |
| "UTCFullYear", |
| "Year" |
| ]; |
| |
| var dateFunctionParameterNum = [ |
| 1, |
| 1, |
| 1, |
| 2, |
| 2, |
| 3, |
| 3, |
| 4, |
| 4, |
| 1, |
| 1, |
| 2, |
| 2, |
| 3, |
| 3, |
| 1 |
| ]; |
| |
| var testValues = [ |
| 0, |
| Number.NaN, |
| Number.POSITIVE_INFINITY, |
| Number.NEGATIVE_INFINITY |
| ]; |
| |
| function testDateFunctionWithValueNoRecoverNaN(functionNameRoot, steps) |
| { |
| var date = new Date(); |
| var setValue = date["get" + functionNameRoot](); |
| date.setMilliseconds(Number.NaN); |
| var params = [ |
| "", |
| ", 0", |
| ", 0, 0", |
| ", 0, 0, 0" |
| ]; |
| var setResult = (1 == steps) ? date["set" + functionNameRoot](setValue) |
| : ((2 == steps) ? date["set" + functionNameRoot](setValue, 0) |
| : ((3 == steps) ? date["set" + functionNameRoot](setValue, 0, 0) |
| : date["set" + functionNameRoot](setValue, 0, 0, 0))); |
| if (!isNaN(setResult)) { |
| testFailed("date(NaN).set" + functionNameRoot + "(" + setValue + params[steps - 1] |
| + ") was " + setResult + " instead of NaN"); |
| return false; |
| } |
| var getResult = date["get" + functionNameRoot](); |
| if (!isNaN(getResult)) { |
| testFailed("date.get" + functionNameRoot + "() was " + getResult + " instead of NaN"); |
| return false; |
| } |
| testPassed ("no recovering from NaN date using date.set" + functionNameRoot |
| + "(arg0" + params[steps - 1] + ")"); |
| return true; |
| } |
| |
| function testDateFunctionWithValueRecoverTime(functionNameRoot) |
| { |
| var date = new Date(); |
| var setValue = date["get" + functionNameRoot](); |
| date.setMilliseconds(Number.NaN); |
| var setResult = date["set" + functionNameRoot](setValue); |
| if (setValue != setResult) { |
| testFailed("date(NaN).set" + functionNameRoot + "(" + setValue + ") was " + setResult + " instead of " + setValue); |
| return false; |
| } |
| var getResult = date["get" + functionNameRoot](); |
| if (getResult != setValue) { |
| testFailed("date.get" + functionNameRoot + "() was " + getResult + " instead of " + setValue); |
| return false; |
| } |
| testPassed ("recover from NaN date using date.set" + functionNameRoot + "()"); |
| return true; |
| } |
| |
| function testDateFunctionWithValueRecoverFullYear(functionNameRoot) |
| { |
| var result = true; |
| var date = new Date(); |
| var setValue = date["get" + functionNameRoot](); |
| date.setMilliseconds(Number.NaN); |
| var setResult = date["set" + functionNameRoot](setValue); |
| var getResult = date["get" + functionNameRoot](); |
| if (getResult != setValue) { |
| testFailed("date.get" + functionNameRoot + "() was " + getResult + " instead of " + setValue); |
| result = false; |
| } |
| getResult = date.getMilliseconds(); |
| if (getResult != 0) { |
| testFailed("date.getMilliseconds() was " + getResult + " instead of 0"); |
| result = false; |
| } |
| getResult = date.getSeconds(); |
| if (getResult != 0) { |
| testFailed("date.getSeconds() was " + getResult + " instead of 0"); |
| result = false; |
| } |
| getResult = date.getMinutes(); |
| if (getResult != 0) { |
| testFailed("date.getMinutes() was " + getResult + " instead of 0"); |
| result = false; |
| } |
| getResult = date.getHours(); |
| if (getResult != 0) { |
| testFailed("date.getHours() was " + getResult + " instead of 0"); |
| result = false; |
| } |
| getResult = date.getDate(); |
| if (getResult != 1) { |
| testFailed("date.getDate() was " + getResult + " instead of 1"); |
| result = false; |
| } |
| getResult = date.getMonth(); |
| if (getResult != 0) { |
| testFailed("date.getMonth() was " + getResult + " instead of 0"); |
| result = false; |
| } |
| if (result) |
| testPassed ("recover from NaN date using date.setFullYear()"); |
| else |
| testFailed ("recover from NaN date using date.setFullYear()"); |
| return result; |
| } |
| |
| function testDateFunctionWithValueRecoverUTCFullYear(functionNameRoot) |
| { |
| var result = true; |
| var date = new Date(); |
| var setValue = date["get" + functionNameRoot](); |
| date.setMilliseconds(Number.NaN); |
| var setResult = date["set" + functionNameRoot](setValue); |
| var getResult = date["get" + functionNameRoot](); |
| if (getResult != setValue) { |
| testFailed("date.get" + functionNameRoot + "() was " + getResult + " instead of " + setValue); |
| result = false; |
| } |
| getResult = date.getUTCMilliseconds(); |
| if (getResult != 0) { |
| testFailed("date.getUTCMilliseconds() was " + getResult + " instead of 0"); |
| result = false; |
| } |
| getResult = date.getUTCSeconds(); |
| if (getResult != 0) { |
| testFailed("date.getUTCSeconds() was " + getResult + " instead of 0"); |
| result = false; |
| } |
| getResult = date.getUTCMinutes(); |
| if (getResult != 0) { |
| testFailed("date.getUTCMinutes() was " + getResult + " instead of 0"); |
| result = false; |
| } |
| getResult = date.getUTCHours(); |
| if (getResult != 0) { |
| testFailed("date.getUTCHours() was " + getResult + " instead of 0"); |
| result = false; |
| } |
| getResult = date.getUTCDate(); |
| if (getResult != 1) { |
| testFailed("date.getUTCDate() was " + getResult + " instead of 1"); |
| result = false; |
| } |
| getResult = date.getUTCMonth(); |
| if (getResult != 0) { |
| testFailed("date.getUTCMonth() was " + getResult + " instead of 0"); |
| result = false; |
| } |
| if (result) |
| testPassed ("recover from NaN date using date.setUTCFullYear()"); |
| else |
| testFailed ("recover from NaN date using date.setUTCFullYear()"); |
| return result; |
| } |
| |
| function testDateFunctionWithValueRecoverYear(functionNameRoot) |
| { |
| var result = true; |
| var is13Compatible = true; |
| |
| var date = new Date(); |
| var setValue = date["get" + functionNameRoot](); |
| var fullYears = date.getFullYear() - 1900; |
| if (setValue != fullYears) { |
| testFailed("date.get" + functionNameRoot + "() was " + setValue + " instead of " + fullYears); |
| is13Compatible = false; |
| } else |
| testPassed("date.getYear() is compatible to JavaScript 1.3 and later"); |
| |
| date.setMilliseconds(Number.NaN); |
| var setResult = date["set" + functionNameRoot](setValue + 1900); |
| var getResult = date["get" + functionNameRoot](); |
| if (getResult != setValue) { |
| testFailed("date.get" + functionNameRoot + "() was " + getResult + " instead of " + setValue); |
| result = false; |
| } |
| getResult = date.getMilliseconds(); |
| if (getResult != 0) { |
| testFailed("date.getMilliseconds() was " + getResult + " instead of 0"); |
| result = false; |
| } |
| getResult = date.getSeconds(); |
| if (getResult != 0) { |
| testFailed("date.getSeconds() was " + getResult + " instead of 0"); |
| result = false; |
| } |
| getResult = date.getMinutes(); |
| if (getResult != 0) { |
| testFailed("date.getMinutes() was " + getResult + " instead of 0"); |
| result = false; |
| } |
| getResult = date.getHours(); |
| if (getResult != 0) { |
| testFailed("date.getHours() was " + getResult + " instead of 0"); |
| result = false; |
| } |
| getResult = date.getDate(); |
| if (getResult != 1) { |
| testFailed("date.getDate() was " + getResult + " instead of 1"); |
| result = false; |
| } |
| getResult = date.getMonth(); |
| if (getResult != 0) { |
| testFailed("date.getMonth() was " + getResult + " instead of 0"); |
| result = false; |
| } |
| if (result) |
| testPassed ("recover from NaN date using date.setUTCFullYear()"); |
| else |
| testFailed ("recover from NaN date using date.setUTCFullYear()"); |
| return result && is13Compatible; |
| } |
| |
| function makeIEHappy(functionNameRoot, value) |
| { |
| var date = new Date(); |
| var setResult = date["set" + functionNameRoot](value); |
| if (!isNaN(setResult)) { |
| testFailed("date.set" + functionNameRoot |
| + "() was " |
| + setResult + " instead of NaN"); |
| return false; |
| } |
| var getResult = date["get" + functionNameRoot](); |
| if (!isNaN(getResult)) { |
| testFailed("date.get" + functionNameRoot + "() was " |
| + getResult + " instead of NaN"); |
| return false; |
| } |
| return true |
| } |
| |
| function testDateFunctionWithValueExpectingNaN1(functionNameRoot) |
| { |
| var result = true; |
| for (var idx0 in testValues) |
| if (idx0 != 0) { |
| var date = new Date(); |
| var setResult = date["set" + functionNameRoot](testValues[idx0]); |
| if (!isNaN(setResult)) { |
| testFailed("date.set" + functionNameRoot + "(" |
| + testValues[idx0] + ") was " |
| + setResult + " instead of NaN"); |
| result = false; |
| } |
| var getResult = date["get" + functionNameRoot](); |
| if (!isNaN(getResult)) { |
| testFailed("date.get" + functionNameRoot + "() was " |
| + getResult + " instead of NaN"); |
| result = false; |
| } |
| } else if (!makeIEHappy(functionNameRoot)) |
| result = false; |
| if (result) { |
| testPassed("date.set" + functionNameRoot + "(arg0)"); |
| testPassed("date.set" + functionNameRoot + "()"); |
| } |
| return result; |
| } |
| |
| function testDateFunctionWithValueExpectingNaN2(functionNameRoot) |
| { |
| var result = true; |
| for (var idx0 in testValues) |
| for (var idx1 in testValues) |
| if (idx0 != 0 || idx1 != 0) { |
| var date = new Date(); |
| var setResult = date["set" + functionNameRoot](testValues[idx0], |
| testValues[idx1]); |
| |
| if (!isNaN(setResult)) { |
| testFailed("date.set" + functionNameRoot + "(" |
| + testValues[idx0] + ", " |
| + testValues[idx1] + ") was " |
| + setResult + " instead of NaN"); |
| result = false; |
| } |
| var getResult = date["get" + functionNameRoot](); |
| if (!isNaN(getResult)) { |
| testFailed("date.get" + functionNameRoot + "() was " |
| + getResult + " instead of NaN"); |
| result = false; |
| } |
| } |
| |
| if (result) |
| testPassed("date.set" + functionNameRoot + "(arg0, arg1)"); |
| return result; |
| } |
| |
| function testDateFunctionWithValueExpectingNaN3(functionNameRoot) |
| { |
| var result = true; |
| for (var idx0 in testValues) |
| for (var idx1 in testValues) |
| for (var idx2 in testValues) |
| if (idx0 != 0 || idx1 != 0 || idx2 != 0) { |
| var date = new Date(); |
| var setResult = date["set" + functionNameRoot](testValues[idx0], |
| testValues[idx1], |
| testValues[idx2]); |
| if (!isNaN(setResult)) { |
| testFailed("date.set" + functionNameRoot + "(" |
| + testValues[idx0] + ", " |
| + testValues[idx1] + ", " |
| + testValues[idx2] + ") was " |
| + setResult + " instead of NaN"); |
| result = false; |
| } |
| var getResult = date["get" + functionNameRoot](); |
| if (!isNaN(getResult)) { |
| testFailed("date.get" + functionNameRoot + "() was " |
| + getResult + " instead of NaN"); |
| result = false; |
| } |
| } |
| |
| if (result) |
| testPassed("date.set" + functionNameRoot + "(arg0, arg1, arg2)"); |
| return result; |
| } |
| |
| function testDateFunctionWithValueExpectingNaN4(functionNameRoot) |
| { |
| var result = true; |
| for (var idx0 in testValues) |
| for (var idx1 in testValues) |
| for (var idx2 in testValues) |
| for (var idx3 in testValues) |
| if (idx0 != 0 || idx1 != 0 || idx2 != 0 || idx3 != 0) { |
| var date = new Date(); |
| var setResult = date["set" + functionNameRoot](testValues[idx0], |
| testValues[idx1], |
| testValues[idx2], |
| testValues[idx3]); |
| if (!isNaN(setResult)) { |
| testFailed("date.set" + functionNameRoot + "(" |
| + testValues[idx0] + ", " |
| + testValues[idx1] + ", " |
| + testValues[idx2] + ", " |
| + testValues[idx3] + ") was " |
| + setResult + " instead of NaN"); |
| result = false; |
| } |
| var getResult = date["get" + functionNameRoot](); |
| if (!isNaN(getResult)) { |
| testFailed("date.get" + functionNameRoot + "() was " |
| + getResult + " instead of NaN"); |
| result = false; |
| } |
| } |
| if (result) |
| testPassed("date.set" + functionNameRoot + "(arg0, arg1, arg2, arg3)"); |
| return result; |
| } |
| |
| |
| |
| function testDateFunction(functionNameRoot, functionParamNum) |
| { |
| var success = true; |
| |
| switch (functionParamNum) { |
| case 4: |
| success &= testDateFunctionWithValueExpectingNaN4(functionNameRoot); |
| if (functionNameRoot != "Time" && |
| functionNameRoot != "FullYear" && |
| functionNameRoot != "UTCFullYear" && |
| functionNameRoot != "Year") |
| success &= testDateFunctionWithValueNoRecoverNaN(functionNameRoot, 4); |
| |
| case 3: |
| success &= testDateFunctionWithValueExpectingNaN3(functionNameRoot); |
| if (functionNameRoot != "Time" && |
| functionNameRoot != "FullYear" && |
| functionNameRoot != "UTCFullYear" && |
| functionNameRoot != "Year") |
| success &= testDateFunctionWithValueNoRecoverNaN(functionNameRoot, 3); |
| |
| case 2: |
| success &= testDateFunctionWithValueExpectingNaN2(functionNameRoot); |
| if (functionNameRoot != "Time" && |
| functionNameRoot != "FullYear" && |
| functionNameRoot != "UTCFullYear" && |
| functionNameRoot != "Year") |
| success &= testDateFunctionWithValueNoRecoverNaN(functionNameRoot, 2); |
| |
| case 1: |
| success &= testDateFunctionWithValueExpectingNaN1(functionNameRoot); |
| if (functionNameRoot == "Time") |
| success &= testDateFunctionWithValueRecoverTime(functionNameRoot); |
| else if (functionNameRoot == "FullYear") |
| success &= testDateFunctionWithValueRecoverFullYear(functionNameRoot); |
| else if (functionNameRoot == "UTCFullYear") |
| success &= testDateFunctionWithValueRecoverUTCFullYear(functionNameRoot); |
| else if (functionNameRoot == "Year") |
| success &= testDateFunctionWithValueRecoverYear(functionNameRoot); |
| else |
| success &= testDateFunctionWithValueNoRecoverNaN(functionNameRoot, 1); |
| } |
| |
| if (success) |
| testPassed("date.set" + functionNameRoot + " passed all tests"); |
| } |
| |
| for (var x in dateFunctionNameRoots) |
| { |
| testDateFunction(dateFunctionNameRoots[x], dateFunctionParameterNum[x]); |
| } |