Add tests for usage of IsArray (#667)

This commit is contained in:
jugglinmike 2016-06-10 15:07:40 -04:00 committed by Leo Balter
parent 01fe0d331b
commit ee7496f713
18 changed files with 765 additions and 0 deletions

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-array.isarray
es6id: 22.1.2.2
description: Revoked proxy value produces a TypeError
info: |
1. Return IsArray(arg).
7.2.2 IsArray
[...]
3. If argument is a Proxy exotic object, then
a. If the value of the [[ProxyHandler]] internal slot of argument is null,
throw a TypeError exception.
b. Let target be the value of the [[ProxyTarget]] internal slot of
argument.
c. Return ? IsArray(target).
features: [Proxy]
---*/
var handle = Proxy.revocable([], {});
handle.revoke();
assert.throws(TypeError, function() {
Array.isArray(handle.proxy);
});

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-array.isarray
es6id: 22.1.2.2
description: Proxy of an array is treated as an array
info: |
1. Return IsArray(arg).
7.2.2 IsArray
[...]
3. If argument is a Proxy exotic object, then
a. If the value of the [[ProxyHandler]] internal slot of argument is null,
throw a TypeError exception.
b. Let target be the value of the [[ProxyTarget]] internal slot of
argument.
c. Return ? IsArray(target).
features: [Proxy]
---*/
var objectProxy = new Proxy({}, {});
var arrayProxy = new Proxy([], {});
var arrayProxyProxy = new Proxy(arrayProxy, {});
assert.sameValue(Array.isArray(objectProxy), false);
assert.sameValue(Array.isArray(arrayProxy), true, 'proxy for array');
assert.sameValue(
Array.isArray(arrayProxyProxy), true, 'proxy for proxy for array'
);

View File

@ -0,0 +1,40 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 22.1.3.1
esid: sec-array.prototype.concat
description: Species constructor of a Proxy object whose target is an array
info: |
[...]
2. Let A be ? ArraySpeciesCreate(O, 0).
[...]
7. Return A.
9.4.2.3 ArraySpeciesCreate
[...]
3. Let isArray be ? IsArray(originalArray).
7.2.2 IsArray
[...]
3. If argument is a Proxy exotic object, then
a. If the value of the [[ProxyHandler]] internal slot of argument is
null, throw a TypeError exception.
b. Let target be the value of the [[ProxyTarget]] internal slot of
argument.
c. Return ? IsArray(target).
features: [Proxy, Symbol.species]
---*/
var array = [];
var proxy = new Proxy(new Proxy(array, {}), {});
var Ctor = function() {};
var result;
array.constructor = function() {};
array.constructor[Symbol.species] = Ctor;
result = Array.prototype.concat.call(proxy);
assert.sameValue(Object.getPrototypeOf(result), Ctor.prototype);

View File

@ -0,0 +1,51 @@
// 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-isconcatspreadable
es6id: 22.1.3.1.1
description: Revoked proxy value produces a TypeError when supplied to IsArray
info: |
[...]
5. Repeat, while items is not empty
a. Remove the first element from items and let E be the value of the
element.
b. Let spreadable be ? IsConcatSpreadable(E).
c. If spreadable is true, then
[...]
e. Else E is added as a single item rather than spread,
[...]
ES6 22.1.3.1.1: Runtime Semantics: IsConcatSpreadable ( O )
1. If Type(O) is not Object, return false.
2. Let spreadable be ? Get(O, @@isConcatSpreadable).
3. If spreadable is not undefined, return ToBoolean(spreadable).
4. Return ? IsArray(O).
7.2.2 IsArray
[...]
3. If argument is a Proxy exotic object, then
a. If the value of the [[ProxyHandler]] internal slot of argument is null,
throw a TypeError exception.
b. Let target be the value of the [[ProxyTarget]] internal slot of
argument.
c. Return ? IsArray(target).
features: [Proxy, Symbol.isConcatSpreadable]
---*/
var target = [];
var handle = Proxy.revocable(target, {
get: function(_, key) {
// Defer proxy revocation until after property access to ensure that the
// expected TypeError originates from the IsArray operation.
if (key === Symbol.isConcatSpreadable) {
handle.revoke();
}
return target[key];
}
});
assert.throws(TypeError, function() {
[].concat(handle.proxy);
});

View File

@ -0,0 +1,44 @@
// 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-isconcatspreadable
es6id: 22.1.3.1.1
description: >
Revoked proxy value produces a TypeError during access of
`Symbol.isConcatSpreadable` property
info: |
[...]
5. Repeat, while items is not empty
a. Remove the first element from items and let E be the value of the
element.
b. Let spreadable be ? IsConcatSpreadable(E).
c. If spreadable is true, then
[...]
e. Else E is added as a single item rather than spread,
[...]
ES6 22.1.3.1.1: Runtime Semantics: IsConcatSpreadable ( O )
1. If Type(O) is not Object, return false.
2. Let spreadable be ? Get(O, @@isConcatSpreadable).
7.3.1 Get
[...]
3. Return ? O.[[Get]](P, O).
9.5.8 [[Get]]
[...]
2. Let handler be O.[[ProxyHandler]].
3. If handler is null, throw a TypeError exception.
features: [Proxy]
---*/
var handle = Proxy.revocable([], {});
handle.revoke();
assert.throws(TypeError, function() {
[].concat(handle.proxy);
});

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-isconcatspreadable
es6id: 22.1.3.1.1
description: >
Proxies who final targets are arrays are considered spreadable
info: |
[...]
5. Repeat, while items is not empty
a. Remove the first element from items and let E be the value of the
element.
b. Let spreadable be ? IsConcatSpreadable(E).
c. If spreadable is true, then
[...]
e. Else E is added as a single item rather than spread,
[...]
ES6 22.1.3.1.1: Runtime Semantics: IsConcatSpreadable ( O )
1. If Type(O) is not Object, return false.
2. Let spreadable be ? Get(O, @@isConcatSpreadable).
3. If spreadable is not undefined, return ToBoolean(spreadable).
4. Return ? IsArray(O).
7.2.2 IsArray
[...]
3. If argument is a Proxy exotic object, then
a. If the value of the [[ProxyHandler]] internal slot of argument is null,
throw a TypeError exception.
b. Let target be the value of the [[ProxyTarget]] internal slot of
argument.
c. Return ? IsArray(target).
features: [Proxy, Symbol.isConcatSpreadable]
---*/
var arrayProxy = new Proxy([], {});
var arrayProxyProxy = new Proxy(arrayProxy, {});
var spreadable = {};
spreadable[Symbol.isConcatSpreadable] = true;
var spreadableProxy = new Proxy(spreadable, {});
assert.sameValue([].concat(arrayProxy).length, 0, 'Proxy for an array');
assert.sameValue(
[].concat(arrayProxyProxy).length, 0, 'Proxy for a proxy for an array'
);
assert.sameValue(
[].concat(spreadableProxy).length,
0,
'Proxy for an ordinary object with a truthy @@isConcatSpreadable property'
);

View File

@ -0,0 +1,40 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 22.1.3.7
esid: sec-array.prototype.filter
description: Species constructor of a Proxy object whose target is an array
info: |
[...]
5. Let A be ? ArraySpeciesCreate(O, 0).
[...]
9. Return A.
9.4.2.3 ArraySpeciesCreate
[...]
3. Let isArray be ? IsArray(originalArray).
7.2.2 IsArray
[...]
3. If argument is a Proxy exotic object, then
a. If the value of the [[ProxyHandler]] internal slot of argument is
null, throw a TypeError exception.
b. Let target be the value of the [[ProxyTarget]] internal slot of
argument.
c. Return ? IsArray(target).
features: [Proxy, Symbol.species]
---*/
var array = [];
var proxy = new Proxy(new Proxy(array, {}), {});
var Ctor = function() {};
var result;
array.constructor = function() {};
array.constructor[Symbol.species] = Ctor;
result = Array.prototype.filter.call(proxy, function() {});
assert.sameValue(Object.getPrototypeOf(result), Ctor.prototype);

View File

@ -0,0 +1,40 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 22.1.3.15
esid: sec-array.prototype.map
description: Species constructor of a Proxy object whose target is an array
info: |
[...]
5. Let A be ? ArraySpeciesCreate(O, len).
[...]
8. Return A.
9.4.2.3 ArraySpeciesCreate
[...]
3. Let isArray be ? IsArray(originalArray).
7.2.2 IsArray
[...]
3. If argument is a Proxy exotic object, then
a. If the value of the [[ProxyHandler]] internal slot of argument is
null, throw a TypeError exception.
b. Let target be the value of the [[ProxyTarget]] internal slot of
argument.
c. Return ? IsArray(target).
features: [Proxy, Symbol.species]
---*/
var array = [];
var proxy = new Proxy(new Proxy(array, {}), {});
var Ctor = function() {};
var result;
array.constructor = function() {};
array.constructor[Symbol.species] = Ctor;
result = Array.prototype.map.call(proxy, function() {});
assert.sameValue(Object.getPrototypeOf(result), Ctor.prototype);

View File

@ -0,0 +1,40 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 22.1.3.23
esid: sec-array.prototype.slice
description: Species constructor of a Proxy object whose target is an array
info: |
[...]
8. Let A be ? ArraySpeciesCreate(O, count).
[...]
12. Return A.
9.4.2.3 ArraySpeciesCreate
[...]
3. Let isArray be ? IsArray(originalArray).
7.2.2 IsArray
[...]
3. If argument is a Proxy exotic object, then
a. If the value of the [[ProxyHandler]] internal slot of argument is
null, throw a TypeError exception.
b. Let target be the value of the [[ProxyTarget]] internal slot of
argument.
c. Return ? IsArray(target).
features: [Proxy, Symbol.species]
---*/
var array = [];
var proxy = new Proxy(new Proxy(array, {}), {});
var Ctor = function() {};
var result;
array.constructor = function() {};
array.constructor[Symbol.species] = Ctor;
result = Array.prototype.slice.call(proxy);
assert.sameValue(Object.getPrototypeOf(result), Ctor.prototype);

View File

@ -0,0 +1,40 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 22.1.3.25
esid: sec-array.prototype.splice
description: Species constructor of a Proxy object whose target is an array
info: |
[...]
9. Let A be ? ArraySpeciesCreate(O, actualDeleteCount).
[...]
20. Return A.
9.4.2.3 ArraySpeciesCreate
[...]
3. Let isArray be ? IsArray(originalArray).
7.2.2 IsArray
[...]
3. If argument is a Proxy exotic object, then
a. If the value of the [[ProxyHandler]] internal slot of argument is
null, throw a TypeError exception.
b. Let target be the value of the [[ProxyTarget]] internal slot of
argument.
c. Return ? IsArray(target).
features: [Proxy, Symbol.species]
---*/
var array = [];
var proxy = new Proxy(new Proxy(array, {}), {});
var Ctor = function() {};
var result;
array.constructor = function() {};
array.constructor[Symbol.species] = Ctor;
result = Array.prototype.splice.call(proxy);
assert.sameValue(Object.getPrototypeOf(result), Ctor.prototype);

View File

@ -0,0 +1,46 @@
// 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-json.parse
es6id: 24.3.1
description: Behavior when revived value is a revoked Proxy exotic object
info: |
[...]
7. If IsCallable(reviver) is true, then
a. Let root be ObjectCreate(%ObjectPrototype%).
b. Let rootName be the empty String.
c. Let status be CreateDataProperty(root, rootName, unfiltered).
d. Assert: status is true.
e. Return ? InternalizeJSONProperty(root, rootName).
24.3.1.1 Runtime Semantics: InternalizeJSONProperty
[...]
2. If Type(val) is Object, then
a. Let isArray be ? IsArray(val).
7.2.2 IsArray
[...]
3. If argument is a Proxy exotic object, then
a. If the value of the [[ProxyHandler]] internal slot of argument is null,
throw a TypeError exception.
b. Let target be the value of the [[ProxyTarget]] internal slot of
argument.
c. Return ? IsArray(target).
features: [Proxy]
---*/
var handle = Proxy.revocable([], {});
var returnCount = 0;
handle.revoke();
assert.throws(TypeError, function() {
JSON.parse('[null, null]', function() {
this[1] = handle.proxy;
returnCount += 1;
});
});
assert.sameValue(returnCount, 1, 'invocation returns normally');

View File

@ -0,0 +1,82 @@
// 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-json.parse
es6id: 24.3.1
description: Behavior when revived value is a Proxy exotic object
info: |
[...]
7. If IsCallable(reviver) is true, then
a. Let root be ObjectCreate(%ObjectPrototype%).
b. Let rootName be the empty String.
c. Let status be CreateDataProperty(root, rootName, unfiltered).
d. Assert: status is true.
e. Return ? InternalizeJSONProperty(root, rootName).
24.3.1.1 Runtime Semantics: InternalizeJSONProperty
[...]
2. If Type(val) is Object, then
a. Let isArray be ? IsArray(val).
b. If isArray is true, then
[...]
c. Else,
[...]
7.2.2 IsArray
[...]
3. If argument is a Proxy exotic object, then
a. If the value of the [[ProxyHandler]] internal slot of argument is null,
throw a TypeError exception.
b. Let target be the value of the [[ProxyTarget]] internal slot of
argument.
c. Return ? IsArray(target).
features: [Proxy]
---*/
var objectProxy = new Proxy({ length: 0, other: 0 }, {});
var arrayProxy = new Proxy([], {});
var arrayProxyProxy = new Proxy(arrayProxy, {});
var visitedOther, injectProxy;
arrayProxy.other = 0;
injectProxy = function(name, val) {
if (name === 'other') {
visitedOther = true;
}
this[1] = objectProxy;
return val;
};
visitedOther = false;
JSON.parse('[null, null]', injectProxy);
assert.sameValue(visitedOther, true, 'proxy for ordinary object');
injectProxy = function(name, val) {
if (name === 'other') {
visitedOther = true;
}
this[1] = arrayProxy;
return val;
};
visitedOther = false;
JSON.parse('[null, null]', injectProxy);
assert.sameValue(visitedOther, false, 'proxy for array');
injectProxy = function(name, val) {
if (name === 'other') {
visitedOther = true;
}
this[1] = arrayProxyProxy;
return val;
};
visitedOther = false;
JSON.parse('[null, null]', injectProxy);
assert.sameValue(visitedOther, false, 'proxy for array proxy');

View File

@ -0,0 +1,33 @@
// 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-json.stringify
es6id: 24.3.2
description: Revoked proxy value produces a TypeError
info: |
[...]
4. If Type(replacer) is Object, then
a. If IsCallable(replacer) is true, then
i. Let ReplacerFunction be replacer.
b. Else,
i. Let isArray be ? IsArray(replacer).
7.2.2 IsArray
[...]
3. If argument is a Proxy exotic object, then
a. If the value of the [[ProxyHandler]] internal slot of argument is null,
throw a TypeError exception.
b. Let target be the value of the [[ProxyTarget]] internal slot of
argument.
c. Return ? IsArray(target).
features: [Proxy]
---*/
var handle = Proxy.revocable([], {});
handle.revoke();
assert.throws(TypeError, function() {
JSON.stringify({}, handle.proxy);
});

View File

@ -0,0 +1,45 @@
// 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-json.stringify
es6id: 24.3.2
description: Proxy of an array is treated as an array
info: |
[...]
12. Return ? SerializeJSONProperty(the empty String, wrapper).
24.3.2.1 Runtime Semantics: SerializeJSONProperty
[...]
10. If Type(value) is Object and IsCallable(value) is false, then
a. Let isArray be ? IsArray(value).
b. If isArray is true, return ? SerializeJSONArray(value).
c. Else, return ? SerializeJSONObject(value).
[...]
7.2.2 IsArray
[...]
3. If argument is a Proxy exotic object, then
a. If the value of the [[ProxyHandler]] internal slot of argument is null,
throw a TypeError exception.
b. Let target be the value of the [[ProxyTarget]] internal slot of
argument.
c. Return ? IsArray(target).
features: [Proxy]
---*/
var objectProxy = new Proxy({}, {});
var arrayProxy = new Proxy([], {});
var arrayProxyProxy = new Proxy(arrayProxy, {});
assert.sameValue(JSON.stringify(objectProxy), '{}');
assert.sameValue(JSON.stringify(arrayProxy), '[]', 'proxy for an array');
assert.sameValue(
JSON.stringify([[arrayProxy]]), '[[[]]]', 'proxy for an array (nested)'
);
assert.sameValue(
JSON.stringify([[arrayProxyProxy]]),
'[[[]]]',
'proxy for a proxy for an array (nested)'
);

View File

@ -0,0 +1,42 @@
// 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-json.stringify
es6id: 24.3.2
description: Revoked proxy value produces a TypeError
info: |
[...]
12. Return ? SerializeJSONProperty(the empty String, wrapper).
24.3.2.1 Runtime Semantics: SerializeJSONProperty
[...]
10. If Type(value) is Object and IsCallable(value) is false, then
a. Let isArray be ? IsArray(value).
b. If isArray is true, return ? SerializeJSONArray(value).
c. Else, return ? SerializeJSONObject(value).
[...]
7.2.2 IsArray
[...]
3. If argument is a Proxy exotic object, then
a. If the value of the [[ProxyHandler]] internal slot of argument is null,
throw a TypeError exception.
b. Let target be the value of the [[ProxyTarget]] internal slot of
argument.
c. Return ? IsArray(target).
features: [Proxy]
---*/
var handle = Proxy.revocable([], {});
handle.revoke();
assert.throws(TypeError, function() {
JSON.stringify(handle.proxy);
}, 'top-level value');
assert.throws(TypeError, function() {
JSON.stringify([[[handle.proxy]]]);
}, 'nested value');

View File

@ -0,0 +1,40 @@
// 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-object.prototype.tostring
es6id: 19.1.3.6
description: Proxy of an array is treated as an array
info: |
[...]
3. Let O be ToObject(this value).
4. Let isArray be ? IsArray(O).
5. If isArray is true, let builtinTag be "Array".
[...]
7.2.2 IsArray
[...]
3. If argument is a Proxy exotic object, then
a. If the value of the [[ProxyHandler]] internal slot of argument is null,
throw a TypeError exception.
b. Let target be the value of the [[ProxyTarget]] internal slot of
argument.
c. Return ? IsArray(target).
features: [Proxy]
---*/
var objectProxy = new Proxy({}, {});
var arrayProxy = new Proxy([], {});
var arrayProxyProxy = new Proxy(arrayProxy, {});
assert.sameValue(
Object.prototype.toString.call(objectProxy), '[object Object]'
);
assert.sameValue(
Object.prototype.toString.call(arrayProxy), '[object Array]', 'array proxy'
);
assert.sameValue(
Object.prototype.toString.call(arrayProxyProxy),
'[object Array]',
'proxy for array proxy'
);

View File

@ -0,0 +1,32 @@
// 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-object.prototype.tostring
es6id: 19.1.3.6
description: Revoked proxy value produces a TypeError
info: |
[...]
3. Let O be ToObject(this value).
4. Let isArray be ? IsArray(O).
5. If isArray is true, let builtinTag be "Array".
[...]
7.2.2 IsArray
[...]
3. If argument is a Proxy exotic object, then
a. If the value of the [[ProxyHandler]] internal slot of argument is null,
throw a TypeError exception.
b. Let target be the value of the [[ProxyTarget]] internal slot of
argument.
c. Return ? IsArray(target).
features: [Proxy]
---*/
var handle = Proxy.revocable([], {});
handle.revoke();
assert.throws(TypeError, function() {
Object.prototype.toString.call(handle.proxy);
});

View File

@ -0,0 +1,40 @@
// 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-object.prototype.tostring
es6id: 19.1.3.6
description: Proxy of an array is treated as an array
info: |
[...]
3. Let O be ToObject(this value).
4. Let isArray be ? IsArray(O).
5. If isArray is true, let builtinTag be "Array".
[...]
7.2.2 IsArray
[...]
3. If argument is a Proxy exotic object, then
a. If the value of the [[ProxyHandler]] internal slot of argument is null,
throw a TypeError exception.
b. Let target be the value of the [[ProxyTarget]] internal slot of
argument.
c. Return ? IsArray(target).
features: [Proxy]
---*/
var objectProxy = new Proxy({}, {});
var arrayProxy = new Proxy([], {});
var arrayProxyProxy = new Proxy(arrayProxy, {});
assert.sameValue(
Object.prototype.toString.call(objectProxy), '[object Object]'
);
assert.sameValue(
Object.prototype.toString.call(arrayProxy), '[object Array]', 'array proxy'
);
assert.sameValue(
Object.prototype.toString.call(arrayProxyProxy),
'[object Array]',
'proxy for array proxy'
);