mirror of https://github.com/svaarala/duktape.git
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.
513 lines
13 KiB
513 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.)
|
|
*/
|
|
|