Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4709)

Unified Diff: test/mjsunit/harmony/unscopables.js

Issue 384963002: ES6 Unscopables (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Use new GetHolder Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: test/mjsunit/harmony/unscopables.js
diff --git a/test/mjsunit/harmony/unscopables.js b/test/mjsunit/harmony/unscopables.js
new file mode 100644
index 0000000000000000000000000000000000000000..da24601b7b5f9d852ea5637baadc58c585716c82
--- /dev/null
+++ b/test/mjsunit/harmony/unscopables.js
@@ -0,0 +1,614 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-unscopables
+// Flags: --harmony-collections
+
+var global = this;
+var globalProto = Object.getPrototypeOf(global);
+
+// Number of objects being tested. There is an assert ensuring this is correct.
+var objectCount = 21;
+
+
+function runTest(f) {
+ function restore(object, oldProto) {
+ Object.setPrototypeOf(object, oldProto);
+ delete object[Symbol.unscopables];
+ delete object.x;
+ delete object.x_;
+ delete object.y;
+ delete object.z;
+ }
+
+ function getObject(i) {
+ var objects = [
+ {},
+ [],
+ function() {},
+ function() {
+ return arguments;
+ }(),
+ function() {
+ 'use strict';
+ return arguments;
+ }(),
+ Object(1),
+ Object(true),
+ Object('bla'),
+ new Date,
+ new RegExp,
+ new Set,
+ new Map,
+ new WeakMap,
+ new WeakSet,
+ new ArrayBuffer(10),
+ new Int32Array(5),
+ Object,
+ Function,
+ Date,
+ RegExp,
+ global
+ ];
+
+ assertEquals(objectCount, objects.length);
+ return objects[i];
+ }
+
+ if (f.length === 1) {
+ for (var i = 0; i < objectCount; i++) {
+ var object = getObject(i);
+ var oldObjectProto = Object.getPrototypeOf(object);
+ f(object);
+ restore(object, oldObjectProto);
+ }
+ } else {
+ for (var i = 0; i < objectCount; i++) {
+ for (var j = 0; j < objectCount; j++) {
+ var object = getObject(i);
+ var proto = getObject(j);
+ if (object === proto) {
+ continue;
+ }
+ var oldObjectProto = Object.getPrototypeOf(object);
+ var oldProtoProto = Object.getPrototypeOf(proto);
+ f(object, proto);
+ restore(object, oldObjectProto);
+ restore(proto, oldProtoProto);
+ }
+ }
+ }
+}
+
+
+function TestBasics(object) {
+ var x = 1;
+ var y = 2;
+ var z = 3;
+ object.x = 4;
+ object.y = 5;
+
+ with (object) {
+ assertEquals(4, x);
+ assertEquals(5, y);
+ assertEquals(3, z);
+ }
+
+ object[Symbol.unscopables] = {x: true};
+ with (object) {
+ assertEquals(1, x);
+ assertEquals(5, y);
+ assertEquals(3, z);
+ }
+
+ object[Symbol.unscopables] = {x: 0, y: true};
+ with (object) {
+ assertEquals(1, x);
+ assertEquals(2, y);
+ assertEquals(3, z);
+ }
+}
+runTest(TestBasics);
+
+
+function TestBasicsSet(object) {
+ var x = 1;
+ object.x = 2;
+
+ with (object) {
+ assertEquals(2, x);
+ }
+
+ object[Symbol.unscopables] = {x: true};
+ with (object) {
+ assertEquals(1, x);
+ x = 3;
+ assertEquals(3, x);
+ }
+
+ assertEquals(3, x);
+ assertEquals(2, object.x);
+}
+runTest(TestBasicsSet);
+
+
+function TestOnProto(object, proto) {
+ var x = 1;
+ var y = 2;
+ var z = 3;
+ proto.x = 4;
+
+ Object.setPrototypeOf(object, proto);
+ object.y = 5;
+
+ with (object) {
+ assertEquals(4, x);
+ assertEquals(5, y);
+ assertEquals(3, z);
+ }
+
+ proto[Symbol.unscopables] = {x: true};
+ with (object) {
+ assertEquals(1, x);
+ assertEquals(5, y);
+ assertEquals(3, z);
+ }
+
+ object[Symbol.unscopables] = {y: true};
+ with (object) {
+ assertEquals(1, x);
+ assertEquals(2, y);
+ assertEquals(3, z);
+ }
+
+ proto[Symbol.unscopables] = {y: true};
+ object[Symbol.unscopables] = {x: true};
+ with (object) {
+ assertEquals(4, x);
+ assertEquals(5, y);
+ assertEquals(3, z);
+ }
+}
+runTest(TestOnProto);
+
+
+function TestNonObject(object) {
+ var x = 1;
+ var y = 2;
+ object.x = 3;
+ object.y = 4;
+
+ object[Symbol.unscopables] = 'xy';
+ with (object) {
+ assertEquals(3, x);
+ assertEquals(4, y);
+ }
+
+ object[Symbol.unscopables] = null;
+ with (object) {
+ assertEquals(3, x);
+ assertEquals(4, y);
+ }
+}
+runTest(TestNonObject);
+
+
+function TestChangeDuringWith(object) {
+ var x = 1;
+ var y = 2;
+ object.x = 3;
+ object.y = 4;
+
+ with (object) {
+ assertEquals(3, x);
+ assertEquals(4, y);
+ object[Symbol.unscopables] = {x: true};
+ assertEquals(1, x);
+ assertEquals(4, y);
+ }
+}
+runTest(TestChangeDuringWith);
+
+
+function TestChangeDuringWithWithPossibleOptimization(object) {
+ var x = 1;
+ object.x = 2;
+ with (object) {
+ for (var i = 0; i < 1000; i++) {
+ if (i === 500) object[Symbol.unscopables] = {x: true};
+ assertEquals(i < 500 ? 2: 1, x);
+ }
+ }
+}
+TestChangeDuringWithWithPossibleOptimization({});
+
+
+function TestChangeDuringWithWithPossibleOptimization2(object) {
+ var x = 1;
+ object.x = 2;
+ object[Symbol.unscopables] = {x: true};
+ with (object) {
+ for (var i = 0; i < 1000; i++) {
+ if (i === 500) delete object[Symbol.unscopables];
+ assertEquals(i < 500 ? 1 : 2, x);
+ }
+ }
+}
+TestChangeDuringWithWithPossibleOptimization2({});
+
+
+function TestChangeDuringWithWithPossibleOptimization3(object) {
+ var x = 1;
+ object.x = 2;
+ object[Symbol.unscopables] = {};
+ with (object) {
+ for (var i = 0; i < 1000; i++) {
+ if (i === 500) object[Symbol.unscopables].x = true;
+ assertEquals(i < 500 ? 2 : 1, x);
+ }
+ }
+}
+TestChangeDuringWithWithPossibleOptimization3({});
+
+
+function TestChangeDuringWithWithPossibleOptimization4(object) {
+ var x = 1;
+ object.x = 2;
+ object[Symbol.unscopables] = {x: true};
+ with (object) {
+ for (var i = 0; i < 1000; i++) {
+ if (i === 500) delete object[Symbol.unscopables].x;
+ assertEquals(i < 500 ? 1 : 2, x);
+ }
+ }
+}
+TestChangeDuringWithWithPossibleOptimization4({});
+
+
+(function TestGlobal() {
+ global.values = 'global.values';
+ Array.prototype.values = 'Array.prototype.values';
+ Array.prototype[Symbol.unscopables] = {values: true};
+ Array.prototype.__proto__ = {values: 42};
+ var array = [];
+ with (array) {
+ assertEquals(42, values);
+ }
+})();
+
+
+function TestAccessorReceiver(object, proto) {
+ var x = 'local';
+
+ Object.defineProperty(proto, 'x', {
+ get: function() {
+ assertEquals(object, this);
+ return this.x_;
+ },
+ configurable: true
+ });
+ proto.x_ = 'proto';
+
+ Object.setPrototypeOf(object, proto);
+ proto.x_ = 'object';
+
+ with (object) {
+ assertEquals('object', x);
+ }
+}
+runTest(TestAccessorReceiver);
+
+
+function TestUnscopablesGetter(object) {
+ // This test gets really messy when object is the global since the assert
+ // functions are properties on the global object and the call count gets
+ // completely different.
+ if (object === global) return;
+
+ var x = 'local';
+ object.x = 'object';
+
+ var callCount = 0;
+ Object.defineProperty(object, Symbol.unscopables, {
+ get: function() {
+ callCount++;
+ return {};
+ },
+ configurable: true
+ });
+ with (object) {
+ assertEquals('object', x);
+ }
+ // Once for HasBinding and once for GetBindingValue
+ assertEquals(2, callCount);
+
+ callCount = 0;
+ Object.defineProperty(object, Symbol.unscopables, {
+ get: function() {
+ callCount++;
+ return {x: true};
+ },
+ configurable: true
+ });
+ with (object) {
+ assertEquals('local', x);
+ }
+ // Once for HasBinding
+ assertEquals(1, callCount);
+
+ callCount = 0;
+ Object.defineProperty(object, Symbol.unscopables, {
+ get: function() {
+ callCount++;
+ return callCount === 1 ? {} : {x: true};
+ },
+ configurable: true
+ });
+ with (object) {
+ assertEquals(void 0, x);
+ }
+ // Once for HasBinding, once for GetBindingValue.
+ assertEquals(2, callCount);
+
+ callCount = 0;
+ Object.defineProperty(object, Symbol.unscopables, {
+ get: function() {
+ callCount++;
+ return callCount === 1 ? {} : {x: true};
+ },
+ configurable: true
+ });
+ with (object) {
+ x = 1;
+ }
+ // Once for HasBinding
+ assertEquals(1, callCount);
+ assertEquals(1, object.x);
+ assertEquals('local', x);
+ with (object) {
+ x = 2;
+ }
+ // One more HasBinding.
+ assertEquals(2, callCount);
+ assertEquals(1, object.x);
+ assertEquals(2, x);
+}
+runTest(TestUnscopablesGetter);
+
+
+var global = this;
+(function TestUnscopablesGetter2() {
+ var x = 'local';
+
+ var protos = [{}, [], function() {}, global];
+ var objects = [{}, [], function() {}];
+
+ protos.forEach(function(proto) {
+ objects.forEach(function(object) {
+ Object.defineProperty(proto, 'x', {
+ get: function() {
+ assertEquals(object, this);
+ return 'proto';
+ },
+ configurable: true
+ });
+
+ object.__proto__ = proto;
+ Object.defineProperty(object, 'x', {
+ get: function() {
+ assertEquals(object, this);
+ return 'object';
+ },
+ configurable: true
+ });
+
+ with (object) {
+ assertEquals('object', x);
+ }
+
+ object[Symbol.unscopables] = {x: true};
+ with (object) {
+ assertEquals('proto', x);
+ }
+
+ delete proto[Symbol.unscopables];
+ delete object[Symbol.unscopables];
+ });
+ });
+})();
+
+
+function TestSetterOnBlacklisted(object, proto) {
+ Object.defineProperty(proto, 'x', {
+ set: function(x) {
+ assertUnreachable();
+ },
+ get: function() {
+ return 'proto';
+ },
+ configurable: true
+ });
+ Object.setPrototypeOf(object, proto);
+ Object.defineProperty(object, 'x', {
+ get: function() {
+ return this.x_;
+ },
+ set: function(x) {
+ this.x_ = x;
+ },
+ configurable: true
+ });
+ object.x_ = 1;
+
+ with (object) {
+ x = 2;
+ assertEquals(2, x);
+ }
+
+ assertEquals(2, object.x);
+
+ object[Symbol.unscopables] = {x: true};
+
+ with (object) {
+ x = 3;
+ assertEquals('proto', x);
+ }
+
+ assertEquals(3, object.x);
+}
+runTest(TestSetterOnBlacklisted);
+
+
+function TestObjectsAsUnscopables(object, unscopables) {
+ var x = 1;
+ object.x = 2;
+
+ with (object) {
+ assertEquals(2, x);
+ object[Symbol.unscopables] = unscopables;
+ assertEquals(2, x);
+ }
+}
+runTest(TestAccessorOnUnscopables);
+
+
+function TestAccessorOnUnscopables(object) {
+ var x = 1;
+ object.x = 2;
+
+ var unscopables = {
+ get x() {
+ assertUnreachable();
+ }
+ };
+
+ with (object) {
+ assertEquals(2, x);
+ object[Symbol.unscopables] = unscopables;
+ assertEquals(1, x);
+ }
+}
+runTest(TestAccessorOnUnscopables);
+
+
+function TestLengthUnscopables(object, proto) {
+ var length = 2;
+ with (object) {
+ assertEquals(1, length);
+ object[Symbol.unscopables] = {length: true};
+ assertEquals(0, length); // From prototype
+ proto[Symbol.unscopables] = {length: true};
+ assertEquals(2, length);
+ delete proto[Symbol.unscopables];
+ assertEquals(0, length); // From prototype
+ }
+}
+TestLengthUnscopables([1], Array.prototype);
+TestLengthUnscopables(function(x) {}, Function.prototype);
+TestLengthUnscopables(new String('x'), String.prototype);
+
+
+function TestFunctionNameUnscopables(object) {
+ var name = 'local';
+ with (object) {
+ assertEquals('f', name);
+ object[Symbol.unscopables] = {name: true};
+ assertEquals('Empty', name); // From prototype
+ Object.getPrototypeOf(object)[Symbol.unscopables] = {name: true};
+ assertEquals('local', name);
+ delete Object.getPrototypeOf(object)[Symbol.unscopables];
+ assertEquals('Empty', name); // From prototype
+ }
+}
+TestFunctionNameUnscopables(function f() {});
+
+
+function TestFunctionPrototypeUnscopables() {
+ var prototype = 'local';
+ var f = function() {};
+ var g = function() {};
+ Object.setPrototypeOf(f, g);
+ var fp = f.prototype;
+ var gp = g.prototype;
+ with (f) {
+ assertEquals(fp, prototype);
+ f[Symbol.unscopables] = {prototype: true};
+ assertEquals(gp, prototype);
+ g[Symbol.unscopables] = {prototype: true};
+ assertEquals('local', prototype);
+ }
+}
+TestFunctionPrototypeUnscopables(function() {});
+
+
+function TestFunctionArgumentsUnscopables() {
+ var func = function() {
+ var arguments = 'local';
+ var args = func.arguments;
+ with (func) {
+ assertEquals(args, arguments);
+ func[Symbol.unscopables] = {arguments: true};
+ assertEquals(null, arguments); // From prototype
+ Function.prototype[Symbol.unscopables] = {arguments: true};
+ assertEquals('local', arguments);
+ delete Function.prototype[Symbol.unscopables];
+ assertEquals(null, arguments); // From prototype
+ }
+ }
+ func(1);
+}
+TestFunctionArgumentsUnscopables();
+
+
+function TestArgumentsLengthUnscopables() {
+ var func = function() {
+ var length = 'local';
+ with (arguments) {
+ assertEquals(1, length);
+ arguments[Symbol.unscopables] = {length: true};
+ assertEquals('local', length);
+ }
+ }
+ func(1);
+}
+TestArgumentsLengthUnscopables();
+
+
+function TestFunctionCallerUnscopables() {
+ var func = function() {
+ var caller = 'local';
+ with (func) {
+ assertEquals(TestFunctionCallerUnscopables, caller);
+ func[Symbol.unscopables] = {caller: true};
+ assertEquals(null, caller); // From prototype
+ Function.prototype[Symbol.unscopables] = {caller: true};
+ assertEquals('local', caller);
+ delete Function.prototype[Symbol.unscopables];
+ assertEquals(null, caller); // From prototype
+ }
+ }
+ func(1);
+}
+TestFunctionCallerUnscopables();
+
+
+function TestGetUnscopablesGetterThrows() {
+ var object = {
+ get x() {
+ assertUnreachable();
+ }
+ };
+ function CustomError() {}
+ Object.defineProperty(object, Symbol.unscopables, {
+ get: function() {
+ throw new CustomError();
+ }
+ });
+ assertThrows(function() {
+ with (object) {
+ x;
+ }
+ }, CustomError);
+}
+TestGetUnscopablesGetterThrows();

Powered by Google App Engine
This is Rietveld 408576698