Merge pull request #453 from ljharb/object_values_entries

Object.{values,entries} tests
This commit is contained in:
Gorkem Yakin 2016-01-12 17:43:08 -08:00
commit 34a917f55b
34 changed files with 744 additions and 0 deletions

View File

@ -0,0 +1,48 @@
// Copyright (C) 2015 Jordan Harband. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Object.entries should perform observable operations in the correct order
es7id: pending
author: Jordan Harband
features: [Proxy]
---*/
var log = "";
var object = { a: 0, b: 0, c: 0 };
var handler = {
get: function (target, propertyKey, receiver) {
assert.sameValue(target, object, "get target");
assert.sameValue(receiver, proxy, "get receiver");
log += "|get:" + propertyKey;
return target[propertyKey];
},
getOwnPropertyDescriptor: function (target, propertyKey) {
assert.sameValue(target, object, "getOwnPropertyDescriptor");
log += "|getOwnPropertyDescriptor:" + propertyKey;
return Object.getOwnPropertyDescriptor(target, propertyKey);
},
ownKeys: function (target) {
assert.sameValue(target, object, "ownKeys");
log += "|ownKeys";
return Object.getOwnPropertyNames(target);
},
deleteProperty: function (oTarget, sKey) {
throw new Test262Error('properties should not be deleted');
},
defineProperty: function (oTarget, sKey, oDesc) {
throw new Test262Error('properties should not be defined');
},
set: function (oTarget, sKey, vValue) {
throw new Test262Error('properties should not be assigned');
}
};
var check = {
get: function (target, propertyKey, receiver) {
assert(propertyKey in target, "handler check: " + propertyKey);
return target[propertyKey];
}
};
var proxy = new Proxy(object, new Proxy(handler, check));
var result = Object.entries(proxy);
assert.sameValue(log, "|ownKeys|getOwnPropertyDescriptor:a|get:a|getOwnPropertyDescriptor:b|get:b|getOwnPropertyDescriptor:c|get:c", log);

View File

@ -0,0 +1,48 @@
// Copyright (C) 2015 Jordan Harband. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Object.values should perform observable operations in the correct order
es7id: pending
author: Jordan Harband
features: [Proxy]
---*/
var log = "";
var object = { a: 0, b: 0, c: 0 };
var handler = {
get: function (target, propertyKey, receiver) {
assert.sameValue(target, object, "get target");
assert.sameValue(receiver, proxy, "get receiver");
log += "|get:" + propertyKey;
return target[propertyKey];
},
getOwnPropertyDescriptor: function (target, propertyKey) {
assert.sameValue(target, object, "getOwnPropertyDescriptor");
log += "|getOwnPropertyDescriptor:" + propertyKey;
return Object.getOwnPropertyDescriptor(target, propertyKey);
},
ownKeys: function (target) {
assert.sameValue(target, object, "ownKeys");
log += "|ownKeys";
return Object.getOwnPropertyNames(target);
},
deleteProperty: function (oTarget, sKey) {
throw new Test262Error('properties should not be deleted');
},
defineProperty: function (oTarget, sKey, oDesc) {
throw new Test262Error('properties should not be defined');
},
set: function (oTarget, sKey, vValue) {
throw new Test262Error('properties should not be assigned');
}
};
var check = {
get: function (target, propertyKey, receiver) {
assert(propertyKey in target, "handler check: " + propertyKey);
return target[propertyKey];
}
};
var proxy = new Proxy(object, new Proxy(handler, check));
var result = Object.values(proxy);
assert.sameValue(log, "|ownKeys|getOwnPropertyDescriptor:a|get:a|getOwnPropertyDescriptor:b|get:b|getOwnPropertyDescriptor:c|get:c", log);

View File

@ -0,0 +1,21 @@
// Copyright (C) 2015 Jordan Harband. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Object.entries should terminate if getting a value throws an exception
es7id: pending
author: Jordan Harband
---*/
var trappedKey = {
get a() {
throw new RangeError('This error should be re-thrown');
},
get b() {
$ERROR('Should not try to get the second element');
}
};
assert.throws(RangeError, function () {
Object.entries(trappedKey);
});

View File

@ -0,0 +1,16 @@
// Copyright (C) 2015 Jordan Harband. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Object.entries should fail if given a null or undefined value
es7id: pending
author: Jordan Harband
---*/
assert.throws(TypeError, function () {
Object.entries(null);
});
assert.throws(TypeError, function () {
Object.entries(undefined);
});

View File

@ -0,0 +1,15 @@
// Copyright (C) 2015 Jordan Harband. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Object.entries should have length 1
es7id: pending
author: Jordan Harband
includes: [propertyHelper.js]
---*/
assert.sameValue(Object.entries.length, 1, 'Expected Object.entries.length to be 1');
verifyNotEnumerable(Object.entries, 'length');
verifyNotWritable(Object.entries, 'length');
verifyConfigurable(Object.entries, 'length');

View File

@ -0,0 +1,19 @@
// Copyright (C) 2015 Jordan Harband. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Object.entries should have name property with value 'entries'
es7id: pending
author: Jordan Harband
includes: [propertyHelper.js]
---*/
assert.sameValue(
Object.entries.name,
'entries',
'Expected Object.entries.name to be "entries"'
);
verifyNotEnumerable(Object.entries, 'name');
verifyNotWritable(Object.entries, 'name');
verifyConfigurable(Object.entries, 'name');

View File

@ -0,0 +1,13 @@
// Copyright (C) 2015 Jordan Harband. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Object.entries should be writable, non-enumerable, and configurable
es7id: pending
author: Jordan Harband
includes: [propertyHelper.js]
---*/
verifyNotEnumerable(Object, 'entries');
verifyWritable(Object, 'entries');
verifyConfigurable(Object, 'entries');

View File

@ -0,0 +1,29 @@
// Copyright (C) 2015 Jordan Harband. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Object.entries does not see a new element added by a getter that is hit during iteration
es7id: pending
author: Jordan Harband
---*/
var bAddsC = {
a: 'A',
get b() {
this.c = 'C';
return 'B';
}
};
var result = Object.entries(bAddsC);
assert.sameValue(Array.isArray(result), true, 'result is an array');
assert.sameValue(result.length, 2, 'result has 2 items');
assert.sameValue(Array.isArray(result[0]), true, 'first entry is an array');
assert.sameValue(Array.isArray(result[1]), true, 'second entry is an array');
assert.sameValue(result[0][0], 'a', 'first entry has key "a"');
assert.sameValue(result[0][1], 'A', 'first entry has value "A"');
assert.sameValue(result[1][0], 'b', 'second entry has key "b"');
assert.sameValue(result[1][1], 'B', 'second entry has value "B"');

View File

@ -0,0 +1,32 @@
// Copyright (C) 2015 Jordan Harband. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Object.entries does not see an element made non-enumerable by a getter that is hit during iteration
es7id: pending
author: Jordan Harband
---*/
var bDeletesC = {
a: 'A',
get b() {
Object.defineProperty(this, 'c', {
enumerable: false
});
return 'B';
},
c: 'C'
};
var result = Object.entries(bDeletesC);
assert.sameValue(Array.isArray(result), true, 'result is an array');
assert.sameValue(result.length, 2, 'result has 2 items');
assert.sameValue(Array.isArray(result[0]), true, 'first entry is an array');
assert.sameValue(Array.isArray(result[1]), true, 'second entry is an array');
assert.sameValue(result[0][0], 'a', 'first entry has key "a"');
assert.sameValue(result[0][1], 'A', 'first entry has value "A"');
assert.sameValue(result[1][0], 'b', 'second entry has key "b"');
assert.sameValue(result[1][1], 'B', 'second entry has value "B"');

View File

@ -0,0 +1,30 @@
// Copyright (C) 2015 Jordan Harband. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Object.entries does not see an element removed by a getter that is hit during iteration
es7id: pending
author: Jordan Harband
---*/
var bDeletesC = {
a: 'A',
get b() {
delete this.c;
return 'B';
},
c: 'C'
};
var result = Object.entries(bDeletesC);
assert.sameValue(Array.isArray(result), true, 'result is an array');
assert.sameValue(result.length, 2, 'result has 2 items');
assert.sameValue(Array.isArray(result[0]), true, 'first entry is an array');
assert.sameValue(Array.isArray(result[1]), true, 'second entry is an array');
assert.sameValue(result[0][0], 'a', 'first entry has key "a"');
assert.sameValue(result[0][1], 'A', 'first entry has value "A"');
assert.sameValue(result[1][0], 'b', 'second entry has key "b"');
assert.sameValue(result[1][1], 'B', 'second entry has value "B"');

View File

@ -0,0 +1,29 @@
// Copyright (C) 2015 Jordan Harband. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Object.entries does not see inherited properties.
es7id: pending
author: Jordan Harband
---*/
var F = function G() {};
F.prototype.a = {};
F.prototype.b = {};
var f = new F();
f.b = {}; // shadow the prototype
f.c = {}; // solely an own property
var result = Object.entries(f);
assert.sameValue(Array.isArray(result), true, 'result is an array');
assert.sameValue(result.length, 2, 'result has 2 items');
assert.sameValue(Array.isArray(result[0]), true, 'first entry is an array');
assert.sameValue(Array.isArray(result[1]), true, 'second entry is an array');
assert.sameValue(result[0][0], 'b', 'first entry has key "b"');
assert.sameValue(result[0][1], f.b, 'first entry has value f.b');
assert.sameValue(result[1][0], 'c', 'second entry has key "c"');
assert.sameValue(result[1][1], f.c, 'second entry has value f.c');

View File

@ -0,0 +1,18 @@
// Copyright (C) 2015 Jordan Harband. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Object.entries accepts boolean primitives.
es7id: pending
author: Jordan Harband
---*/
var trueResult = Object.entries(true);
assert.sameValue(Array.isArray(trueResult), true, 'trueResult is an array');
assert.sameValue(trueResult.length, 0, 'trueResult has 0 items');
var falseResult = Object.entries(false);
assert.sameValue(Array.isArray(falseResult), true, 'falseResult is an array');
assert.sameValue(falseResult.length, 0, 'falseResult has 0 items');

View File

@ -0,0 +1,15 @@
// Copyright (C) 2015 Jordan Harband. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Object.entries accepts number primitives.
es7id: pending
author: Jordan Harband
---*/
assert.sameValue(Object.entries(0).length, 0, '0 has zero entries');
assert.sameValue(Object.entries(-0).length, 0, '-0 has zero entries');
assert.sameValue(Object.entries(Infinity).length, 0, 'Infinity has zero entries');
assert.sameValue(Object.entries(-Infinity).length, 0, '-Infinity has zero entries');
assert.sameValue(Object.entries(NaN).length, 0, 'NaN has zero entries');
assert.sameValue(Object.entries(Math.PI).length, 0, 'Math.PI has zero entries');

View File

@ -0,0 +1,20 @@
// Copyright (C) 2015 Jordan Harband. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Object.entries accepts string primitives.
es7id: pending
author: Jordan Harband
---*/
var result = Object.entries('abc');
assert.sameValue(Array.isArray(result), true, 'result is an array');
assert.sameValue(result.length, 3, 'result has 3 items');
assert.sameValue(result[0][0], '0', 'first entry has key "0"');
assert.sameValue(result[0][1], 'a', 'first entry has value "a"');
assert.sameValue(result[1][0], '1', 'second entry has key "1"');
assert.sameValue(result[1][1], 'b', 'second entry has value "b"');
assert.sameValue(result[2][0], '2', 'third entry has key "2"');
assert.sameValue(result[2][1], 'c', 'third entry has value "c"');

View File

@ -0,0 +1,14 @@
// Copyright (C) 2015 Jordan Harband. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Object.entries accepts Symbol primitives.
es7id: pending
author: Jordan Harband
features: [Symbol]
---*/
var result = Object.entries(Symbol());
assert.sameValue(Array.isArray(result), true, 'result is an array');
assert.sameValue(result.length, 0, 'result has 0 items');

View File

@ -0,0 +1,28 @@
// Copyright (C) 2015 Jordan Harband. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Object.entries does not include Symbol keys.
es7id: pending
author: Jordan Harband
features: [Symbol]
---*/
var value = {};
var enumSym = Symbol('enum');
var nonEnumSym = Symbol('nonenum');
var symValue = Symbol('value');
var obj = { key: symValue };
obj[enumSym] = value;
Object.defineProperty(obj, nonEnumSym, { enumerable: false, value: value });
var result = Object.entries(obj);
assert.sameValue(Array.isArray(result), true, 'result is an array');
assert.sameValue(result.length, 1, 'result has 1 item');
assert.sameValue(Array.isArray(result[0]), true, 'first entry is an array');
assert.sameValue(result[0][0], 'key', 'first entry has key "key"');
assert.sameValue(result[0][1], symValue, 'first entry has value `symValue`');

View File

@ -0,0 +1,20 @@
// Copyright (C) 2015 Jordan Harband. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Object.entries should not have its behavior impacted by modifications to the global property Object
es7id: pending
author: Jordan Harband
---*/
function fakeObject() {
$ERROR('The overriden version of Object was called!');
}
fakeObject.entries = Object.entries;
var global = Function('return this;')();
global.Object = fakeObject;
assert.sameValue(Object, fakeObject, 'Sanity check failed: could not modify the global Object');
assert.sameValue(Object.entries(1).length, 0, 'Expected number primitive to have zero entries');

View File

@ -0,0 +1,18 @@
// Copyright (C) 2015 Jordan Harband. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Object.entries should not have its behavior impacted by modifications to Object.keys
es7id: pending
author: Jordan Harband
---*/
function fakeObjectKeys() {
$ERROR('The overriden version of Object.keys was called!');
}
Object.keys = fakeObjectKeys;
assert.sameValue(Object.keys, fakeObjectKeys, 'Sanity check failed: could not modify the global Object.keys');
assert.sameValue(Object.entries({ a: 1 }).length, 1, 'Expected object with 1 key to have 1 entry');

View File

@ -0,0 +1,21 @@
// Copyright (C) 2015 Jordan Harband. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Object.values should terminate if getting a value throws an exception
es7id: pending
author: Jordan Harband
---*/
var trappedKey = {
get a() {
throw new RangeError('This error should be re-thrown');
},
get b() {
$ERROR('Should not try to get the second element');
}
};
assert.throws(RangeError, function () {
Object.values(trappedKey);
});

View File

@ -0,0 +1,16 @@
// Copyright (C) 2015 Jordan Harband. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Object.values should fail if given a null or undefined value
es7id: pending
author: Jordan Harband
---*/
assert.throws(TypeError, function () {
Object.values(null);
});
assert.throws(TypeError, function () {
Object.values(undefined);
});

View File

@ -0,0 +1,15 @@
// Copyright (C) 2015 Jordan Harband. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Object.values should have length 1
es7id: pending
author: Jordan Harband
includes: [propertyHelper.js]
---*/
assert.sameValue(Object.values.length, 1, 'Expected Object.values.length to be 1');
verifyNotEnumerable(Object.values, 'length');
verifyNotWritable(Object.values, 'length');
verifyConfigurable(Object.values, 'length');

View File

@ -0,0 +1,19 @@
// Copyright (C) 2015 Jordan Harband. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Object.values should have name property with value 'values'
es7id: pending
author: Jordan Harband
includes: [propertyHelper.js]
---*/
assert.sameValue(
Object.values.name,
'values',
'Expected Object.values.name to be "values"'
);
verifyNotEnumerable(Object.values, 'name');
verifyNotWritable(Object.values, 'name');
verifyConfigurable(Object.values, 'name');

View File

@ -0,0 +1,13 @@
// Copyright (C) 2015 Jordan Harband. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Object.values should be writable, non-enumerable, and configurable
es7id: pending
author: Jordan Harband
includes: [propertyHelper.js]
---*/
verifyNotEnumerable(Object, 'values');
verifyWritable(Object, 'values');
verifyConfigurable(Object, 'values');

View File

@ -0,0 +1,24 @@
// Copyright (C) 2015 Jordan Harband. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Object.values does not see a new element added by a getter that is hit during iteration
es7id: pending
author: Jordan Harband
---*/
var bAddsC = {
a: 'A',
get b() {
this.c = 'C';
return 'B';
}
};
var result = Object.values(bAddsC);
assert.sameValue(Array.isArray(result), true, 'result is an array');
assert.sameValue(result.length, 2, 'result has 2 items');
assert.sameValue(result[0], 'A', 'first value is "A"');
assert.sameValue(result[1], 'B', 'second value is "B"');

View File

@ -0,0 +1,27 @@
// Copyright (C) 2015 Jordan Harband. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Object.values does not see an element made non-enumerable by a getter that is hit during iteration
es7id: pending
author: Jordan Harband
---*/
var bDeletesC = {
a: 'A',
get b() {
Object.defineProperty(this, 'c', {
enumerable: false
});
return 'B';
},
c: 'C'
};
var result = Object.values(bDeletesC);
assert.sameValue(Array.isArray(result), true, 'result is an array');
assert.sameValue(result.length, 2, 'result has 2 items');
assert.sameValue(result[0], 'A', 'first value is "A"');
assert.sameValue(result[1], 'B', 'second value is "B"');

View File

@ -0,0 +1,25 @@
// Copyright (C) 2015 Jordan Harband. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Object.values does not see an element removed by a getter that is hit during iteration
es7id: pending
author: Jordan Harband
---*/
var bDeletesC = {
a: 'A',
get b() {
delete this.c;
return 'B';
},
c: 'C'
};
var result = Object.values(bDeletesC);
assert.sameValue(Array.isArray(result), true, 'result is an array');
assert.sameValue(result.length, 2, 'result has 2 items');
assert.sameValue(result[0], 'A', 'first value is "A"');
assert.sameValue(result[1], 'B', 'second value is "B"');

View File

@ -0,0 +1,24 @@
// Copyright (C) 2015 Jordan Harband. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Object.values does not see inherited properties.
es7id: pending
author: Jordan Harband
---*/
var F = function G() {};
F.prototype.a = {};
F.prototype.b = {};
var f = new F();
f.b = {}; // shadow the prototype
f.c = {}; // solely an own property
var result = Object.values(f);
assert.sameValue(Array.isArray(result), true, 'result is an array');
assert.sameValue(result.length, 2, 'result has 2 items');
assert.sameValue(result[0], f.b, 'first value is f.b');
assert.sameValue(result[1], f.c, 'second value is f.c');

View File

@ -0,0 +1,18 @@
// Copyright (C) 2015 Jordan Harband. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Object.values accepts boolean primitives.
es7id: pending
author: Jordan Harband
---*/
var trueResult = Object.values(true);
assert.sameValue(Array.isArray(trueResult), true, 'trueResult is an array');
assert.sameValue(trueResult.length, 0, 'trueResult has 0 items');
var falseResult = Object.values(false);
assert.sameValue(Array.isArray(falseResult), true, 'falseResult is an array');
assert.sameValue(falseResult.length, 0, 'falseResult has 0 items');

View File

@ -0,0 +1,15 @@
// Copyright (C) 2015 Jordan Harband. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Object.values accepts number primitives.
es7id: pending
author: Jordan Harband
---*/
assert.sameValue(Object.values(0).length, 0, '0 has zero values');
assert.sameValue(Object.values(-0).length, 0, '-0 has zero values');
assert.sameValue(Object.values(Infinity).length, 0, 'Infinity has zero values');
assert.sameValue(Object.values(-Infinity).length, 0, '-Infinity has zero values');
assert.sameValue(Object.values(NaN).length, 0, 'NaN has zero values');
assert.sameValue(Object.values(Math.PI).length, 0, 'Math.PI has zero values');

View File

@ -0,0 +1,17 @@
// Copyright (C) 2015 Jordan Harband. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Object.values accepts string primitives.
es7id: pending
author: Jordan Harband
---*/
var result = Object.values('abc');
assert.sameValue(Array.isArray(result), true, 'result is an array');
assert.sameValue(result.length, 3, 'result has 3 items');
assert.sameValue(result[0], 'a', 'first value is "a"');
assert.sameValue(result[1], 'b', 'second value is "b"');
assert.sameValue(result[2], 'c', 'third value is "c"');

View File

@ -0,0 +1,14 @@
// Copyright (C) 2015 Jordan Harband. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Object.values accepts Symbol primitives.
es7id: pending
author: Jordan Harband
features: [Symbol]
---*/
var result = Object.values(Symbol());
assert.sameValue(Array.isArray(result), true, 'result is an array');
assert.sameValue(result.length, 0, 'result has 0 items');

View File

@ -0,0 +1,25 @@
// Copyright (C) 2015 Jordan Harband. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Object.values does not include Symbol keys.
es7id: pending
author: Jordan Harband
features: [Symbol]
---*/
var value = {};
var enumSym = Symbol('enum');
var nonEnumSym = Symbol('nonenum');
var symValue = Symbol('value');
var obj = { key: symValue };
obj[enumSym] = value;
Object.defineProperty(obj, nonEnumSym, { enumerable: false, value: value });
var result = Object.values(obj);
assert.sameValue(Array.isArray(result), true, 'result is an array');
assert.sameValue(result.length, 1, 'result has 1 item');
assert.sameValue(result[0], symValue, 'first value is `symValue`');

View File

@ -0,0 +1,20 @@
// Copyright (C) 2015 Jordan Harband. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Object.values should not have its behavior impacted by modifications to the global property Object
es7id: pending
author: Jordan Harband
---*/
function fakeObject() {
$ERROR('The overriden version of Object was called!');
}
fakeObject.values = Object.values;
var global = Function('return this;')();
global.Object = fakeObject;
assert.sameValue(Object, fakeObject, 'Sanity check failed: could not modify the global Object');
assert.sameValue(Object.values(1).length, 0, 'Expected number primitive to have zero values');

View File

@ -0,0 +1,18 @@
// Copyright (C) 2015 Jordan Harband. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: >
Object.values should not have its behavior impacted by modifications to Object.keys
es7id: pending
author: Jordan Harband
---*/
function fakeObjectKeys() {
$ERROR('The overriden version of Object.keys was called!');
}
Object.keys = fakeObjectKeys;
assert.sameValue(Object.keys, fakeObjectKeys, 'Sanity check failed: could not modify the global Object.keys');
assert.sameValue(Object.values({ a: 1 }).length, 1, 'Expected object with 1 key to have 1 value');