You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

514 lines
13 KiB

/*
* Testcases for E5 to E5.1 corrections, Appendix F of the
* E5.1 specification.
*/
/*===
foobar
barfoo
===*/
/* 7.8.4: CV definitions added for DoubleStringCharacter :: LineContinuation and SingleStringCharacter ::
* LineContinuation.
*
* (The character value (CV) is defined to be the empty character.)
*/
try {
print("foo\
bar");
print('bar\
foo');
} catch (e) {
print(e);
}
/*===
imm1
function
function
imm2
function
TypeError
should not be modified
===*/
/* 10.2.1.1.3: The argument S is not ignored. It controls whether an exception is
* thrown when attempting to set an immutable binding.
*
* (There are not very many immutable bindings in the spec. One of them is
* the name of a named function expression. Assigning to it should be silently
* ignored in non-strict mode and a TypeError in strict mode.)
*/
var func = 'should not be modified';
var immutable1 = function func() { print('imm1'); print(typeof func); func = 123; print(typeof func); }
var immutable2 = function func() { 'use strict'; print('imm2'); print(typeof func); func = 123; print(typeof func); }
try { immutable1(); } catch(e) { print(e); }
try { immutable2(); } catch(e) { print(e.name); }
print(func);
/*===
===*/
/* 10.2.1.2.2: In algorithm step 5, true is passed as the last argument to [[DefineOwnProperty]].
*
* (Step 3 asserts that the property does not exist to begin with, so this
* looks like a purely technical change with no behavioral impact.)
*/
/*===
===*/
/* 10.5: Former algorithm step 5.e is now 5.f and a new step 5.e was added to restore compatibility with 3rd
* Edition when redefining global functions.
*
* (Separate testcases: test-spec-redeclare-global*.js)
*/
/*===
===*/
/* 11.5.3: In the final bullet item, use of IEEE 754 round-to-nearest mode is specified.
*
* (No test.)
*/
/*===
for 1st
for 2nd
===*/
/* 12.6.3: Missing ToBoolean restored in step 3.a.ii of both algorithms.
*
* (Already implemented this way, easily demonstrated with a test.)
*/
function forToBooleanTest() {
var i;
// 0 is 'falsy' and terminates loop
print('for 1st');
for (i = 0; 0; i++) {
print('never here');
break; // in case we are, break out
}
print('for 2nd');
for (var j = 0; 0; j++) {
print('never here');
break;
}
}
try {
forToBooleanTest();
} catch (e) {
print(e);
}
/*===
===*/
/* 12.6.4: Additional final sentences in each of the last two paragraphs clarify certain
* property enumeration requirements.
*
* (Already covered by enumeration tests.)
*/
/*===
switch-break
undefined
for-continue
undefined
function-return
undefined
===*/
/* 12.7, 12.8, 12.9: BNF modified to clarify that a continue or break statement without an
* Identifier or a return statement without an Expression may have a LineTerminator before
* the semi-colon.
*
* (If automatic semicolon insertion kicks in instead, the following semi-colon
* would be interpreted as an empty statement. This doesn't usually matter but
* it does matter e.g. in a naked "if () X else Y".)
*/
/* break/continue tests are simply syntax tests */
try {
print('switch-break');
print(eval('(function() { switch(123) { case 123: break\n; }; })()'));
} catch (e) {
print(e);
}
try {
print('for-continue');
print(eval('(function() { for (;;) { break; continue\n; } })()'));
} catch (e) {
print(e);
}
try {
/* if 'return\n;' is parsed as 'return; ;' it would make the if-statement
* invalid, so this is a more useful test.
*/
print('function-return');
print(eval('(function() { if (true) return\n;else return 234 })()'));
} catch (e) {
print(e);
}
/*===
===*/
/* 12.14: Step 3 of algorithm 1 and step 2.a of algorithm 3 are corrected such
* that the value field of B is passed as a parameter rather than B itself.
*
* (No relevant test.)
*/
/*===
NaN
NaN
===*/
/* 15.1.2.2: In step 2 of algorithm, clarify that S may be the empty string.
*
* (Already works, demonstrate with empty string: NaN is provided by step 12.)
*/
try {
print(parseInt(''));
print(parseInt(' '));
} catch (e) {
print(e);
}
/*===
NaN
NaN
===*/
/* 15.1.2.3: In step 2 of algorithm clarify that trimmedString may be the empty string.
*
* (Already works, demonstrate with empty string: NaN is provided by step 3,
* as empty string doesn't match StrDecimalLiteral.)
*/
try {
print(parseFloat(''));
print(parseFloat(' '));
} catch (e) {
print(e);
}
/*===
%23[]!'()*
#%5B%5D!'()*
===*/
/* 15.1.3: Added notes clarifying that ECMAScript‘s URI syntax is based upon RFC 2396
* and not the newer RFC 3986. In the algorithm for Decode, a step was removed that
* immediately preceded the current step 4.d.vii.10.a because it tested for a condition
* that cannot occur.
*
* (The URI syntax changes between RFC 2396 and RFC 3986 don't affect URI
* decoding in Ecmascript, but e.g. reserved character set has changed. See
* doc/uri.txt for discussion.)
*/
try {
print(decodeURI("%23%5B%5D%21%27%28%29%2A"));
print(encodeURI("#[]!'()*"));
} catch (e) {
print(e);
}
/*===
===*/
/* 15.2.3.7: Corrected use of variable P in steps 5 and 6 of algorithm.
*
* (No test.)
*/
/*===
[object Undefined]
[object Null]
===*/
/* 15.2.4.2: Edition 5 handling of undefined and null as this value caused existing code to fail. Specification
* modified to maintain compatibility with such code. New steps 1 and 2 added to the algorithm.
*/
try { print(Object.prototype.toString.call(undefined)); } catch (e) { print(e); }
try { print(Object.prototype.toString.call(null)); } catch (e) { print(e); }
/*===
apply: mythis foo bar quux
apply: mythis undefined undefined undefined
apply: mythis undefined undefined undefined
apply: mythis undefined undefined undefined
apply: mythis undefined undefined undefined
apply: mythis foo undefined undefined
===*/
/* 15.3.4.3: Steps 5 and 7 of Edition 5 algorithm have been deleted because they imposed requirements upon
* the argArray argument that are inconsistent with other uses of generic array-like objects.
*
* (This only affects apply() calls where argArray is an object, but not an
* Array, so it may have an arbitrary or missing 'length' value. E5.1 states
* that ToUint32() coercion is blindly done: undefined/null length coerces to
* 0 instead of causing a TypeError.)
*/
function applyTest(x,y,z) { print('apply:', this, x, y, z); }
try { applyTest.apply('mythis', [ 'foo', 'bar', 'quux' ]) } catch (e) { print(e); }
// no length -> 0
try { applyTest.apply('mythis', { "0": 'foo', "1": 'bar', "2": 'quux' }) } catch (e) { print(e); }
// undefined or null length -> 0
try { applyTest.apply('mythis', { "0": 'foo', "1": 'bar', "2": 'quux', "length": undefined }) } catch (e) { print(e); }
try { applyTest.apply('mythis', { "0": 'foo', "1": 'bar', "2": 'quux', "length": null }) } catch (e) { print(e); }
// already required by E5, false->0, true->1
try { applyTest.apply('mythis', { "0": 'foo', "1": 'bar', "2": 'quux', "length": false }) } catch (e) { print(e); }
try { applyTest.apply('mythis', { "0": 'foo', "1": 'bar', "2": 'quux', "length": true }) } catch (e) { print(e); }
/*===
===*/
/* 15.4.4.12: In step 9.a, incorrect reference to relativeStart was replaced
* with a reference to actualStart.
*
* (Implementation already worked in E5.1 fashion.)
*/
/*===
===*/
/* 15.4.4.15: Clarified that the default value for fromIndex is the length
* minus 1 of the array.
*
* (Implemented already worked in E5.1 fashion.)
*/
/*===
forEach: 1
forEach: 2
forEach: 3
undefined
===*/
/* 15.4.4.18: In step 9 of the algorithm, undefined is now the specified return value. */
try {
print([1,2,3].forEach(function(x) { print('forEach:', x); }));
} catch (e) {
print(e);
}
/*===
reduce: 1 2 1 1,2,3
reduce this: undefined undefined
reduce: 3 3 2 1,2,3
reduce this: undefined undefined
6
reduceRight: 3 2 1 1,2,3
reduceRight this: undefined undefined
reduceRight: 5 1 0 1,2,3
reduceRight this: undefined undefined
6
===*/
/* 15.4.4.22: In step 9.c.ii the first argument to the [[Call]] internal method has been
* changed to undefined for consistency with the definition of Array.prototype.reduce.
*
* (Test 'this' binding, must use a strict function to get in unmangled.)
*/
try {
print([1,2,3].reduce(function(accumulator, kValue, k, O) {
'use strict';
print('reduce:', accumulator, kValue, k, O);
print('reduce this:', typeof this, this);
return accumulator + kValue; // sum
}));
} catch (e) {
print(e);
}
try {
print([1,2,3].reduceRight(function(accumulator, kValue, k, O) {
'use strict';
print('reduceRight:', accumulator, kValue, k, O);
print('reduceRight this:', typeof this, this);
return accumulator + kValue; // sum
}));
} catch (e) {
print(e);
}
/*===
===*/
/* 15.4.5.1: In Algorithm steps 3.l.ii and 3.l.iii the variable name was inverted resulting
* in an incorrectly inverted test.
*
* (Handled correctly by handle_put_array_length_smaller() in duk_hobject_props.c.)
*/
/*===
===*/
/* 15.5.4.9: Normative requirement concerning canonically equivalent strings deleted from paragraph following
* algorithm because it is listed as a recommendation in NOTE 2.
*
* (No test.)
*/
/*===
===*/
/* 15.5.4.14: In split algorithm step 11.a and 13.a, the positional order of the arguments to SplitMatch was
* corrected to match the actual parameter signature of SplitMatch. In step 13.a.iii.7.d, lengthA replaces A.length.
*
* (Obvious typo fixes, no test. Current implementation is based on E5.1 anyway.)
*/
/*===
===*/
/* 15.5.5.2: In first paragraph, removed the implication that the individual character property access had array
* index semantics. Modified algorithm steps 3 and 5 such that they do not enforce array index requirement.
*
* (This change matters only for strings longer than 4G characters which Duktape
* doesn't support at the moment anyway, so there is no way to test. Added a Ditz
* issue for tracking that a fix is done if it becomes relevant.)
*/
/*===
===*/
/* 15.9.1.15: Specified legal value ranges for fields that lacked them. Eliminated time-only formats. Specified
* default values for all optional fields.
*
* (Already implemented to E5.1 requirements, no test.)
*/
/*===
===*/
/* 15.10.2.2: The step numbers of the algorithm for the internal closure produced by step 2 were incorrectly
* numbered in a manner that implied that they were steps of the outer algorithm.
*
* (Obvious typo.)
*/
/*===
===*/
/* 15.10.2.6: In the abstract operation IsWordChar the first character in the list in step 3 is a rather than A.
*
* (Obvious typo.)
*/
/*===
===*/
/* 15.10.2.8: In the algorithm for the closure returned by the abstract operation CharacterSetMatcher, the variable
* defined by step 3 and passed as an argument in step 4 was renamed to ch in order to avoid a name conflict
* with a formal parameter of the closure.
*
* (No test.)
*/
/*===
===*/
/* 15.10.6.2: Step 9.e was deleted because It performed an extra increment of i.
*
* (Obvious typo, handled correctly in regexp code; no test.)
*/
/*===
object
object
undefined
""
===*/
/* 15.11.1.1: Removed requirement that the message own property is set to the empty String when the message
* argument is undefined.
*
* (It's preferable not to set the own property 'message' when the argument
* is undefined because it saves a property slot; an empty message is
* inherited automatically anyway. Funnily enough, this entry appears three
* times in the E5.1 Appendix F, and two of the occurrences refer a non-existent
* Section 15.11.1.2 :-)
*/
function errMessageTest1() {
var e1 = new Error('foo');
var e2 = new Error('');
var e3 = new Error();
print(typeof Object.getOwnPropertyDescriptor(e1, 'message'));
print(typeof Object.getOwnPropertyDescriptor(e2, 'message'));
print(typeof Object.getOwnPropertyDescriptor(e3, 'message'));
print(JSON.stringify(e3.message));
}
try {
errMessageTest1();
} catch (e) {
print(e);
}
/*===
"Error"
"Error"
===*/
/* 15.11.4.4: Steps 6-10 modified/added to correctly deal with missing or empty message property value. */
function errMessageTest2() {
var e1 = new Error();
var e2 = new Error('');
print(JSON.stringify(e1.toString()));
print(JSON.stringify(e2.toString()));
}
try {
errMessageTest2();
} catch (e) {
print(e);
}
/*===
===*/
/* 15.12.3: In step 10.b.iii of the JA internal operation, the last element of the concatenation is ].
*
* (No test, obvious typo fix in spec.)
*/
/*===
===*/
/* B.2.1: Added to NOTE that the encoding is based upon RFC 1738 rather than the newer RFC 3986.
*
* (No test, as there is no change in the algorithm itself.)
*/
/*===
===*/
/* Annex C: An item was added corresponding to 7.6.12 regarding FutureReservedWords in strict mode.
*
* (No test.)
*/