Add tests for Annex B extns to global object (#624)

Extend tests for the `escape` and `unescape` built-ins to assert their
behavior. Rely on the latest ECMAScript draft, which specifies that
`escape` returns hexadecimal codes in upper case.
This commit is contained in:
jugglinmike 2016-05-16 13:53:30 -04:00 committed by Leo Balter
parent ee5356b86a
commit cb40133425
18 changed files with 702 additions and 0 deletions

View File

@ -0,0 +1,17 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-escape-string
es6id: B.2.1.1
description: Input is the empty string
info: |
1. Let string be ? ToString(string).
2. Let length be the number of code units in string.
3. Let R be the empty string.
4. Let k be 0.
5. Repeat, while k < length,
[...]
6. Return R.
---*/
assert.sameValue(escape(''), '');

View File

@ -0,0 +1,30 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-escape-string
es6id: B.2.1.1
description: Escaping of code units above 255
info: |
[...]
5. Repeat, while k < length,
a. Let char be the code unit (represented as a 16-bit unsigned integer)
at index k within string.
[...]
c. Else if char 256, then
i. Let S be a String containing six code units "%uwxyz" where wxyz
are the code units of the four uppercase hexadecimal digits
encoding the value of char.
[...]
---*/
assert.sameValue(
escape('\u0100\u0101\u0102'), '%u0100%u0101%u0102', '\\u0100\\u0101\\u0102'
);
assert.sameValue(
escape('\ufffd\ufffe\uffff'), '%uFFFD%uFFFE%uFFFF', '\\ufffd\\ufffd\\ufffd'
);
assert.sameValue(
escape('\ud834\udf06'), '%uD834%uDF06', '\\ud834\\udf06 (surrogate pairs)'
);

View File

@ -0,0 +1,54 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-escape-string
es6id: B.2.1.1
description: Escaping of code units below 255
info: |
[...]
5. Repeat, while k < length,
a. Let char be the code unit (represented as a 16-bit unsigned integer)
at index k within string.
[...]
d. Else char < 256,
i. Let S be a String containing three code units "%xy" where xy are
the code units of two uppercase hexadecimal digits encoding the
value of char.
[...]
---*/
assert.sameValue(
escape('\x00\x01\x02\x03'),
'%00%01%02%03',
'characters: \\x00\\x01\\x02\\x03'
);
assert.sameValue(
escape('!"#$%&\'()'),
'%21%22%23%24%25%26%27%28%29',
'characters preceeding "*": !"#$%&\'()'
);
assert.sameValue(escape(','), '%2C', 'character between "+" and "-": ,');
assert.sameValue(
escape(':;<=>?'),
'%3A%3B%3C%3D%3E%3F',
'characters between "9" and "@": :;<=>?'
);
assert.sameValue(
escape('[\\]^'), '%5B%5C%5D%5E', 'characters between "Z" and "_": [\\]^'
);
assert.sameValue(escape('`'), '%60', 'character between "_" and "a": `');
assert.sameValue(
escape('{|}~\x7f\x80'),
'%7B%7C%7D%7E%7F%80',
'characters following "z": {|}~\\x7f\\x80'
);
assert.sameValue(
escape('\xfd\xfe\xff'), '%FD%FE%FF', '\\xfd\\xfe\\xff'
);

View File

@ -0,0 +1,16 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-escape-string
es6id: B.2.1.1
description: Abrupt completion from `ToString` operation (Symbol value)
info: |
1. Let string be ? ToString(string).
features: [Symbol]
---*/
var s = Symbol('');
assert.throws(TypeError, function() {
escape(s);
});

View File

@ -0,0 +1,19 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-escape-string
es6id: B.2.1.1
description: Abrupt completion from `ToString` operation
info: |
1. Let string be ? ToString(string).
---*/
var obj = {
toString: function() {
throw new Test262Error();
}
};
assert.throws(Test262Error, function() {
escape(obj);
});

View File

@ -0,0 +1,52 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-escape-string
es6id: B.2.1.1
description: Observable operations from string coercion
info: |
1. Let string be ? ToString(string).
---*/
var log, obj;
log = '';
obj = {
toString: function() {
log += 'toString';
},
valueOf: function() {
log += 'valueOf';
}
};
escape(obj);
assert.sameValue(log, 'toString');
log = '';
obj = {
toString: null,
valueOf: function() {
log += 'valueOf';
}
};
escape(obj);
assert.sameValue(log, 'valueOf');
log = '';
obj = {
toString: function() {
log += 'toString';
return {};
},
valueOf: function() {
log += 'valueOf';
}
};
escape(obj);
assert.sameValue(log, 'toStringvalueOf');

View File

@ -0,0 +1,21 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-escape-string
es6id: B.2.1.1
description: Do not escape a specific set of characters
info: |
[...]
5. Repeat, while k < length,
a. Let char be the code unit (represented as a 16-bit unsigned integer)
at index k within string.
b. If char is one of the code units in
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@*_+-./",
then
i. Let S be a String containing the single code unit char.
[...]
---*/
var passthrough = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@*_+-./';
assert.sameValue(escape(passthrough), passthrough);

View File

@ -0,0 +1,17 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-unescape-string
es6id: B.2.1.2
description: Input is the empty string
info: |
1. Let string be ? ToString(string).
2. Let length be the number of code units in string.
3. Let R be the empty string.
4. Let k be 0.
5. Repeat, while k length,
[...]
6. Return R.
---*/
assert.sameValue(unescape(''), '');

View File

@ -0,0 +1,28 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-unescape-string
es6id: B.2.1.2
description: >
Does not transform four-character patterns that are not prefixed with the
character "u"
info: |
[...]
5. Repeat, while k length,
[...]
a. Let c be the code unit at index k within string.
b. If c is %, then
i. If k length-6 and the code unit at index k+1 within string is u
and the four code units at indices k+2, k+3, k+4, and k+5 within
string are all hexadecimal digits, then
1. Let c be the code unit whose value is the integer represented
by the four hexadecimal digits at indices k+2, k+3, k+4, and
k+5 within string.
2. Increase k by 5.
[...]
---*/
assert.sameValue(unescape('%U0000'), '%U0000');
assert.sameValue(unescape('%t0000'), '%t0000');
assert.sameValue(unescape('%v0000'), '%v0000');
assert.sameValue(unescape('%%0000'), '%\x0000');

View File

@ -0,0 +1,94 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-unescape-string
es6id: B.2.1.2
description: >
Does not transform four-character patterns that are interrupted by the end
of the string
info: |
[...]
5. Repeat, while k length,
[...]
a. Let c be the code unit at index k within string.
b. If c is %, then
i. If k length-6 and the code unit at index k+1 within string is u
and the four code units at indices k+2, k+3, k+4, and k+5 within
string are all hexadecimal digits, then
1. Let c be the code unit whose value is the integer represented
by the four hexadecimal digits at indices k+2, k+3, k+4, and
k+5 within string.
2. Increase k by 5.
[...]
---*/
assert.sameValue(unescape('%u'), '%u');
assert.sameValue(unescape('%u0'), '%u0');
assert.sameValue(unescape('%u1'), '%u1');
assert.sameValue(unescape('%u2'), '%u2');
assert.sameValue(unescape('%u3'), '%u3');
assert.sameValue(unescape('%u4'), '%u4');
assert.sameValue(unescape('%u5'), '%u5');
assert.sameValue(unescape('%u6'), '%u6');
assert.sameValue(unescape('%u7'), '%u7');
assert.sameValue(unescape('%u8'), '%u8');
assert.sameValue(unescape('%u9'), '%u9');
assert.sameValue(unescape('%ua'), '%ua');
assert.sameValue(unescape('%uA'), '%uA');
assert.sameValue(unescape('%ub'), '%ub');
assert.sameValue(unescape('%uB'), '%uB');
assert.sameValue(unescape('%uc'), '%uc');
assert.sameValue(unescape('%uC'), '%uC');
assert.sameValue(unescape('%ud'), '%ud');
assert.sameValue(unescape('%uD'), '%uD');
assert.sameValue(unescape('%ue'), '%ue');
assert.sameValue(unescape('%uE'), '%uE');
assert.sameValue(unescape('%uf'), '%uf');
assert.sameValue(unescape('%uF'), '%uF');
assert.sameValue(unescape('%u00'), '%u00');
assert.sameValue(unescape('%u01'), '%u01');
assert.sameValue(unescape('%u02'), '%u02');
assert.sameValue(unescape('%u03'), '%u03');
assert.sameValue(unescape('%u04'), '%u04');
assert.sameValue(unescape('%u05'), '%u05');
assert.sameValue(unescape('%u06'), '%u06');
assert.sameValue(unescape('%u07'), '%u07');
assert.sameValue(unescape('%u08'), '%u08');
assert.sameValue(unescape('%u09'), '%u09');
assert.sameValue(unescape('%u0a'), '%u0a');
assert.sameValue(unescape('%u0A'), '%u0A');
assert.sameValue(unescape('%u0b'), '%u0b');
assert.sameValue(unescape('%u0B'), '%u0B');
assert.sameValue(unescape('%u0c'), '%u0c');
assert.sameValue(unescape('%u0C'), '%u0C');
assert.sameValue(unescape('%u0d'), '%u0d');
assert.sameValue(unescape('%u0D'), '%u0D');
assert.sameValue(unescape('%u0e'), '%u0e');
assert.sameValue(unescape('%u0E'), '%u0E');
assert.sameValue(unescape('%u0f'), '%u0f');
assert.sameValue(unescape('%u0F'), '%u0F');
assert.sameValue(unescape('%u000'), '%u000');
assert.sameValue(unescape('%u001'), '%u001');
assert.sameValue(unescape('%u002'), '%u002');
assert.sameValue(unescape('%u003'), '%u003');
assert.sameValue(unescape('%u004'), '%u004');
assert.sameValue(unescape('%u005'), '%u005');
assert.sameValue(unescape('%u006'), '%u006');
assert.sameValue(unescape('%u007'), '%u007');
assert.sameValue(unescape('%u008'), '%u008');
assert.sameValue(unescape('%u009'), '%u009');
assert.sameValue(unescape('%u00a'), '%u00a');
assert.sameValue(unescape('%u00A'), '%u00A');
assert.sameValue(unescape('%u00b'), '%u00b');
assert.sameValue(unescape('%u00B'), '%u00B');
assert.sameValue(unescape('%u00c'), '%u00c');
assert.sameValue(unescape('%u00C'), '%u00C');
assert.sameValue(unescape('%u00d'), '%u00d');
assert.sameValue(unescape('%u00D'), '%u00D');
assert.sameValue(unescape('%u00e'), '%u00e');
assert.sameValue(unescape('%u00E'), '%u00E');
assert.sameValue(unescape('%u00f'), '%u00f');
assert.sameValue(unescape('%u00F'), '%u00F');

View File

@ -0,0 +1,43 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-unescape-string
es6id: B.2.1.2
description: >
Does not transform four-character patterns that contain non-hexadecimal
digits
info: |
[...]
5. Repeat, while k length,
[...]
a. Let c be the code unit at index k within string.
b. If c is %, then
i. If k length-6 and the code unit at index k+1 within string is u
and the four code units at indices k+2, k+3, k+4, and k+5 within
string are all hexadecimal digits, then
1. Let c be the code unit whose value is the integer represented
by the four hexadecimal digits at indices k+2, k+3, k+4, and
k+5 within string.
2. Increase k by 5.
[...]
---*/
assert.sameValue(unescape('%u000%0'), '%u000%0');
assert.sameValue(unescape('%u000g0'), '%u000g0');
assert.sameValue(unescape('%u000G0'), '%u000G0');
assert.sameValue(unescape('%u00g00'), '%u00g00');
assert.sameValue(unescape('%u00G00'), '%u00G00');
assert.sameValue(unescape('%u0g000'), '%u0g000');
assert.sameValue(unescape('%u0G000'), '%u0G000');
assert.sameValue(unescape('%ug0000'), '%ug0000');
assert.sameValue(unescape('%uG0000'), '%uG0000');
assert.sameValue(unescape('%u000u0'), '%u000u0');
assert.sameValue(unescape('%u000U0'), '%u000U0');
assert.sameValue(unescape('%u00u00'), '%u00u00');
assert.sameValue(unescape('%u00U00'), '%u00U00');
assert.sameValue(unescape('%u0u000'), '%u0u000');
assert.sameValue(unescape('%u0U000'), '%u0U000');
assert.sameValue(unescape('%uu0000'), '%uu0000');
assert.sameValue(unescape('%uU0000'), '%uU0000');

View File

@ -0,0 +1,73 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-unescape-string
es6id: B.2.1.2
description: Translation of patterns with four digits
info: |
[...]
5. Repeat, while k length,
[...]
a. Let c be the code unit at index k within string.
b. If c is %, then
i. If k length-6 and the code unit at index k+1 within string is u
and the four code units at indices k+2, k+3, k+4, and k+5 within
string are all hexadecimal digits, then
1. Let c be the code unit whose value is the integer represented
by the four hexadecimal digits at indices k+2, k+3, k+4, and
k+5 within string.
2. Increase k by 5.
[...]
---*/
assert.sameValue(unescape('%0%u00000'), '%0\x000', '%u0000');
assert.sameValue(unescape('%0%u00010'), '%0\x010', '%u0001');
assert.sameValue(unescape('%0%u00290'), '%0)0', '%002900');
assert.sameValue(unescape('%0%u002a0'), '%0*0', '%002a00');
assert.sameValue(unescape('%0%u002A0'), '%0*0', '%002A00');
assert.sameValue(unescape('%0%u002b0'), '%0+0', '%002b00');
assert.sameValue(unescape('%0%u002B0'), '%0+0', '%002B00');
assert.sameValue(unescape('%0%u002c0'), '%0,0', '%002c00');
assert.sameValue(unescape('%0%u002C0'), '%0,0', '%002C00');
assert.sameValue(unescape('%0%u002d0'), '%0-0', '%002d00');
assert.sameValue(unescape('%0%u002D0'), '%0-0', '%002D00');
assert.sameValue(unescape('%0%u00390'), '%090', '%003900');
assert.sameValue(unescape('%0%u003a0'), '%0:0', '%003A00');
assert.sameValue(unescape('%0%u003A0'), '%0:0', '%003A00');
assert.sameValue(unescape('%0%u003f0'), '%0?0', '%003f00');
assert.sameValue(unescape('%0%u003F0'), '%0?0', '%003F00');
assert.sameValue(unescape('%0%u00400'), '%0@0', '%004000');
assert.sameValue(unescape('%0%u005a0'), '%0Z0', '%005a00');
assert.sameValue(unescape('%0%u005A0'), '%0Z0', '%005A00');
assert.sameValue(unescape('%0%u005b0'), '%0[0', '%005b00');
assert.sameValue(unescape('%0%u005B0'), '%0[0', '%005B00');
assert.sameValue(unescape('%0%u005e0'), '%0^0', '%005e00');
assert.sameValue(unescape('%0%u005E0'), '%0^0', '%005E00');
assert.sameValue(unescape('%0%u005f0'), '%0_0', '%005f00');
assert.sameValue(unescape('%0%u005F0'), '%0_0', '%005F00');
assert.sameValue(unescape('%0%u00600'), '%0`0', '%006000');
assert.sameValue(unescape('%0%u00610'), '%0a0', '%006100');
assert.sameValue(unescape('%0%u007a0'), '%0z0', '%007a00');
assert.sameValue(unescape('%0%u007A0'), '%0z0', '%007A00');
assert.sameValue(unescape('%0%u007b0'), '%0{0', '%007b00');
assert.sameValue(unescape('%0%u007B0'), '%0{0', '%007B00');
assert.sameValue(unescape('%0%ufffe0'), '%0\ufffe0', '%ufffe');
assert.sameValue(unescape('%0%uFffe0'), '%0\ufffe0', '%uFffe');
assert.sameValue(unescape('%0%ufFfe0'), '%0\ufffe0', '%ufFfe');
assert.sameValue(unescape('%0%uffFe0'), '%0\ufffe0', '%uffFe');
assert.sameValue(unescape('%0%ufffE0'), '%0\ufffe0', '%ufffE');
assert.sameValue(unescape('%0%uFFFE0'), '%0\ufffe0', '%uFFFE');
assert.sameValue(unescape('%0%uffff0'), '%0\uffff0', '%uffff');
assert.sameValue(unescape('%0%uFfff0'), '%0\uffff0', '%uFfff');
assert.sameValue(unescape('%0%ufFff0'), '%0\uffff0', '%ufFff');
assert.sameValue(unescape('%0%uffFf0'), '%0\uffff0', '%uffFf');
assert.sameValue(unescape('%0%ufffF0'), '%0\uffff0', '%ufffF');
assert.sameValue(unescape('%0%uFFFF0'), '%0\uffff0', '%uFFFF');

View File

@ -0,0 +1,16 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-unescape-string
es6id: B.2.1.2
description: Abrupt completion from `ToString` operation (Symbol value)
info: |
1. Let string be ? ToString(string).
features: [Symbol]
---*/
var s = Symbol('');
assert.throws(TypeError, function() {
unescape(s);
});

View File

@ -0,0 +1,19 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-unescape-string
es6id: B.2.1.2
description: Abrupt completion from `ToString` operation
info: |
1. Let string be ? ToString(string).
---*/
var obj = {
toString: function() {
throw new Test262Error();
}
};
assert.throws(Test262Error, function() {
unescape(obj);
});

View File

@ -0,0 +1,52 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-unescape-string
es6id: B.2.1.2
description: Observable operations from string coercion
info: |
1. Let string be ? ToString(string).
---*/
var log, obj;
log = '';
obj = {
toString: function() {
log += 'toString';
},
valueOf: function() {
log += 'valueOf';
}
};
unescape(obj);
assert.sameValue(log, 'toString');
log = '';
obj = {
toString: null,
valueOf: function() {
log += 'valueOf';
}
};
unescape(obj);
assert.sameValue(log, 'valueOf');
log = '';
obj = {
toString: function() {
log += 'toString';
return {};
},
valueOf: function() {
log += 'valueOf';
}
};
unescape(obj);
assert.sameValue(log, 'toStringvalueOf');

View File

@ -0,0 +1,47 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-unescape-string
es6id: B.2.1.2
description: >
Does not transform two-character patterns that are interrupted by the end
of the string
info: |
[...]
5. Repeat, while k length,
[...]
a. Let c be the code unit at index k within string.
b. If c is %, then
[...]
ii. Else if k length-3 and the two code units at indices k+1 and
k+2 within string are both hexadecimal digits, then
1. Let c be the code unit whose value is the integer represented
by two zeroes plus the two hexadecimal digits at indices k+1
and k+2 within string.
2. Increase k by 2.
[...]
---*/
assert.sameValue(unescape('%'), '%');
assert.sameValue(unescape('%0'), '%0');
assert.sameValue(unescape('%1'), '%1');
assert.sameValue(unescape('%2'), '%2');
assert.sameValue(unescape('%3'), '%3');
assert.sameValue(unescape('%4'), '%4');
assert.sameValue(unescape('%5'), '%5');
assert.sameValue(unescape('%6'), '%6');
assert.sameValue(unescape('%7'), '%7');
assert.sameValue(unescape('%8'), '%8');
assert.sameValue(unescape('%9'), '%9');
assert.sameValue(unescape('%a'), '%a');
assert.sameValue(unescape('%A'), '%A');
assert.sameValue(unescape('%b'), '%b');
assert.sameValue(unescape('%B'), '%B');
assert.sameValue(unescape('%c'), '%c');
assert.sameValue(unescape('%C'), '%C');
assert.sameValue(unescape('%d'), '%d');
assert.sameValue(unescape('%D'), '%D');
assert.sameValue(unescape('%e'), '%e');
assert.sameValue(unescape('%E'), '%E');
assert.sameValue(unescape('%f'), '%f');
assert.sameValue(unescape('%F'), '%F');

View File

@ -0,0 +1,35 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-unescape-string
es6id: B.2.1.2
description: >
Does not transform two-character patterns that contain non-hexadecimal
digits
info: |
[...]
5. Repeat, while k length,
[...]
a. Let c be the code unit at index k within string.
b. If c is %, then
[...]
ii. Else if k length-3 and the two code units at indices k+1 and
k+2 within string are both hexadecimal digits, then
1. Let c be the code unit whose value is the integer represented
by two zeroes plus the two hexadecimal digits at indices k+1
and k+2 within string.
2. Increase k by 2.
[...]
---*/
assert.sameValue(unescape('%0%0'), '%0%0');
assert.sameValue(unescape('%0g0'), '%0g0');
assert.sameValue(unescape('%0G0'), '%0G0');
assert.sameValue(unescape('%g00'), '%g00');
assert.sameValue(unescape('%G00'), '%G00');
assert.sameValue(unescape('%0u0'), '%0u0');
assert.sameValue(unescape('%0U0'), '%0U0');
assert.sameValue(unescape('%u00'), '%u00');
assert.sameValue(unescape('%U00'), '%U00');

View File

@ -0,0 +1,69 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-unescape-string
es6id: B.2.1.2
description: Translation of patterns with two digits
info: |
[...]
5. Repeat, while k length,
[...]
a. Let c be the code unit at index k within string.
b. If c is %, then
[...]
ii. Else if k length-3 and the two code units at indices k+1 and
k+2 within string are both hexadecimal digits, then
1. Let c be the code unit whose value is the integer represented
by two zeroes plus the two hexadecimal digits at indices k+1
and k+2 within string.
2. Increase k by 2.
[...]
---*/
assert.sameValue(unescape('%0%0000'), '%0\x0000', '%00');
assert.sameValue(unescape('%0%0100'), '%0\x0100', '%01');
assert.sameValue(unescape('%0%2900'), '%0)00', '%29');
assert.sameValue(unescape('%0%2a00'), '%0*00', '%2a');
assert.sameValue(unescape('%0%2A00'), '%0*00', '%2A');
assert.sameValue(unescape('%0%2b00'), '%0+00', '%2b');
assert.sameValue(unescape('%0%2B00'), '%0+00', '%2B');
assert.sameValue(unescape('%0%2c00'), '%0,00', '%2c');
assert.sameValue(unescape('%0%2C00'), '%0,00', '%2C');
assert.sameValue(unescape('%0%2d00'), '%0-00', '%2d');
assert.sameValue(unescape('%0%2D00'), '%0-00', '%2D');
assert.sameValue(unescape('%0%3900'), '%0900', '%39');
assert.sameValue(unescape('%0%3a00'), '%0:00', '%3A');
assert.sameValue(unescape('%0%3A00'), '%0:00', '%3A');
assert.sameValue(unescape('%0%3f00'), '%0?00', '%3f');
assert.sameValue(unescape('%0%3F00'), '%0?00', '%3F');
assert.sameValue(unescape('%0%4000'), '%0@00', '%40');
assert.sameValue(unescape('%0%5a00'), '%0Z00', '%5a');
assert.sameValue(unescape('%0%5A00'), '%0Z00', '%5A');
assert.sameValue(unescape('%0%5b00'), '%0[00', '%5b');
assert.sameValue(unescape('%0%5B00'), '%0[00', '%5B');
assert.sameValue(unescape('%0%5e00'), '%0^00', '%5e');
assert.sameValue(unescape('%0%5E00'), '%0^00', '%5E');
assert.sameValue(unescape('%0%5f00'), '%0_00', '%5f');
assert.sameValue(unescape('%0%5F00'), '%0_00', '%5F');
assert.sameValue(unescape('%0%6000'), '%0`00', '%60');
assert.sameValue(unescape('%0%6100'), '%0a00', '%61');
assert.sameValue(unescape('%0%7a00'), '%0z00', '%7a');
assert.sameValue(unescape('%0%7A00'), '%0z00', '%7A');
assert.sameValue(unescape('%0%7b00'), '%0{00', '%7b');
assert.sameValue(unescape('%0%7B00'), '%0{00', '%7B');
assert.sameValue(unescape('%0%fe00'), '%0\xfe00', '%fe');
assert.sameValue(unescape('%0%Fe00'), '%0\xfe00', '%Fe');
assert.sameValue(unescape('%0%fE00'), '%0\xfe00', '%fE');
assert.sameValue(unescape('%0%FE00'), '%0\xfe00', '%FE');
assert.sameValue(unescape('%0%ff00'), '%0\xff00', '%ff');
assert.sameValue(unescape('%0%Ff00'), '%0\xff00', '%Ff');
assert.sameValue(unescape('%0%fF00'), '%0\xff00', '%fF');
assert.sameValue(unescape('%0%FF00'), '%0\xff00', '%FF');