Skip to content
Snippets Groups Projects
Commit 7f694d47 authored by Kevin Gibbons's avatar Kevin Gibbons Committed by Rick Waldron
Browse files

Object.fromEntries: add basic tests

parent 8ae2a51e
No related branches found
No related tags found
No related merge requests found
Showing
with 505 additions and 0 deletions
......@@ -7,6 +7,10 @@
#
# https://github.com/tc39/process-document
# Object.fromEntries
# https://github.com/tc39/proposal-object-from-entries
Object.fromEntries
# BigInt
# https://github.com/tc39/proposal-bigint
BigInt
......
// Copyright (C) 2018 Kevin Gibbons. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Evaluation order is iterator.next(), get '0', get '1', toPropertyKey, repeat.
esid: sec-object.fromentries
includes: [compareArray.js]
features: [Symbol.iterator, Object.fromEntries]
---*/
var effects = [];
function makeEntry(label) {
return {
get '0'() {
effects.push('access property "0" of ' + label + ' entry');
return {
toString: function() {
effects.push('toString of ' + label + ' key');
return label + ' key';
},
};
},
get '1'() {
effects.push('access property "1" of ' + label + ' entry');
return label + ' value';
},
};
}
var iterable = {
[Symbol.iterator]: function() {
effects.push('get Symbol.iterator');
var count = 0;
return {
next: function() {
effects.push('next ' + count);
if (count === 0) {
++count;
return {
done: false,
value: makeEntry('first', 'first key', 'first value'),
};
} else if (count === 1) {
++count;
return {
done: false,
value: makeEntry('second', 'second key', 'second value'),
};
} else {
return {
done: true,
};
}
},
};
},
};
var result = Object.fromEntries(iterable);
assert.compareArray(effects, [
'get Symbol.iterator',
'next 0',
'access property "0" of first entry',
'access property "1" of first entry',
'toString of first key',
'next 1',
'access property "0" of second entry',
'access property "1" of second entry',
'toString of second key',
'next 2',
], 'Object.fromEntries evaluation order');
assert.sameValue(result['first key'], 'first value');
assert.sameValue(result['second key'], 'second value');
// Copyright (C) 2018 Kevin Gibbons. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Closes iterators when they return entries which are null.
esid: sec-object.fromentries
features: [Symbol.iterator, Object.fromEntries]
---*/
var returned = false;
var iterable = {
[Symbol.iterator]: function() {
var advanced = false;
return {
next: function() {
if (advanced) {
throw new Test262Error('should only advance once');
}
advanced = true;
return {
done: false,
value: 'null',
};
},
return: function() {
if (returned) {
throw new Test262Error('should only return once');
}
returned = true;
},
};
},
};
assert.throws(TypeError, function() {
Object.fromEntries(iterable);
});
assert(returned, 'iterator should be closed when entry is null');
// Copyright (C) 2018 Kevin Gibbons. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Closes iterators when they return entries which are strings.
esid: sec-object.fromentries
features: [Symbol.iterator, Object.fromEntries]
---*/
var returned = false;
var iterable = {
[Symbol.iterator]: function() {
var advanced = false;
return {
next: function() {
if (advanced) {
throw new Test262Error('should only advance once');
}
advanced = true;
return {
done: false,
value: 'ab',
};
},
return: function() {
if (returned) {
throw new Test262Error('should only return once');
}
returned = true;
},
};
},
};
assert.throws(TypeError, function() {
Object.fromEntries(iterable);
});
assert(returned, 'iterator should be closed when entry is a string');
// Copyright (C) 2018 Kevin Gibbons. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Closes iterators when accessing an entry's properties throws.
esid: sec-object.fromentries
features: [Symbol.iterator, Object.fromEntries]
---*/
function DummyError() {}
var returned = false;
var iterable = {
[Symbol.iterator]: function() {
var advanced = false;
return {
next: function() {
if (advanced) {
throw new Test262Error('should only advance once');
}
advanced = true;
return {
done: false,
value: {
get '0'() {
throw new DummyError();
},
},
};
},
return: function() {
if (returned) {
throw new Test262Error('should only return once');
}
returned = true;
},
};
},
};
assert.throws(DummyError, function() {
Object.fromEntries(iterable);
});
assert(returned, 'iterator should be closed when entry property access throws');
// Copyright (C) 2018 Kevin Gibbons. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Closes iterators when toString on a key throws.
esid: sec-object.fromentries
features: [Symbol.iterator, Object.fromEntries]
---*/
function DummyError() {}
var returned = false;
var iterable = {
[Symbol.iterator]: function() {
var advanced = false;
return {
next: function() {
if (advanced) {
throw new Test262Error('should only advance once');
}
advanced = true;
return {
done: false,
value: {
0: {
toString: function() {
throw new DummyError();
},
},
},
};
},
return: function() {
if (returned) {
throw new Test262Error('should only return once');
}
returned = true;
},
};
},
};
assert.throws(DummyError, function() {
Object.fromEntries(iterable);
});
assert(returned, 'iterator should be closed when key toString throws');
// Copyright (C) 2018 Kevin Gibbons. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Does not close iterators with a `next` method which returns a non-object.
esid: sec-object.fromentries
features: [Symbol.iterator, Object.fromEntries]
---*/
var iterable = {
[Symbol.iterator]: function() {
return {
next: function() {
return null;
},
return: function() {
throw new Test262Error('should not call return');
},
};
},
};
assert.throws(TypeError, function() {
Object.fromEntries(iterable);
});
// Copyright (C) 2018 Kevin Gibbons. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Does not close iterators with a `done` accessor which throws.
esid: sec-object.fromentries
features: [Symbol.iterator, Object.fromEntries]
---*/
function DummyError() {}
var returned = false;
var iterable = {
[Symbol.iterator]: function() {
return {
next: function() {
return {
get done() {
throw new DummyError();
},
};
},
return: function() {
throw new Test262Error('should not call return');
},
};
},
};
assert.throws(DummyError, function() {
Object.fromEntries(iterable);
});
// Copyright (C) 2018 Kevin Gibbons. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Does not close iterators with a `next` method which throws.
esid: sec-object.fromentries
features: [Symbol.iterator, Object.fromEntries]
---*/
function DummyError() {}
var iterable = {
[Symbol.iterator]: function() {
return {
next: function() {
throw new DummyError();
},
return: function() {
throw new Test262Error('should not call return');
},
};
},
};
assert.throws(DummyError, function() {
Object.fromEntries(iterable);
});
// Copyright (C) 2018 Kevin Gibbons. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Does not close iterators with an uncallable `next` property.
esid: sec-object.fromentries
features: [Symbol.iterator, Object.fromEntries]
---*/
var iterable = {
[Symbol.iterator]: function() {
return {
next: null,
return: function() {
throw new Test262Error('should not call return');
},
};
},
};
assert.throws(TypeError, function() {
Object.fromEntries(iterable);
});
// Copyright (C) 2018 Kevin Gibbons. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Key enumeration order of result objects matches the order of entries in the iterable.
esid: sec-object.fromentries
includes: [compareArray.js]
features: [Object.fromEntries]
---*/
var entries = [
['z', 1],
['y', 2],
['x', 3],
['y', 4],
];
var result = Object.fromEntries(entries);
assert.sameValue(result['z'], 1);
assert.sameValue(result['y'], 4);
assert.sameValue(result['x'], 3);
assert.compareArray(Object.keys(result), ['z', 'y', 'x']);
// Copyright (C) 2018 Kevin Gibbons. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Object.fromEntries.length is 1.
esid: sec-object.fromentries
includes: [propertyHelper.js]
features: [Object.fromEntries]
---*/
assert.sameValue(Object.fromEntries.length, 1);
verifyNotEnumerable(Object.fromEntries, "length");
verifyNotWritable(Object.fromEntries, "length");
verifyConfigurable(Object.fromEntries, "length");
// Copyright (C) 2018 Kevin Gibbons. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Object.fromEntries.name is "fromEntries".
esid: sec-object.fromentries
includes: [propertyHelper.js]
features: [Object.fromEntries]
---*/
assert.sameValue(Object.fromEntries.name, "fromEntries");
verifyNotEnumerable(Object.fromEntries, "name");
verifyNotWritable(Object.fromEntries, "name");
verifyConfigurable(Object.fromEntries, "name");
// Copyright (C) 2018 Kevin Gibbons. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Throws when called without an argument.
esid: sec-object.fromentries
features: [Object.fromEntries]
---*/
assert.throws(TypeError, function() {
Object.fromEntries();
});
// Copyright (C) 2018 Kevin Gibbons. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Creates data properties which are enumerable, writable, and configurable.
esid: sec-object.fromentries
includes: [propertyHelper.js]
features: [Object.fromEntries]
---*/
var result = Object.fromEntries([['key', 'value']]);
verifyEnumerable(result, 'key');
verifyWritable(result, 'key');
verifyConfigurable(result, 'key');
// Copyright (C) 2018 Kevin Gibbons. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Succeeds when an entry object is a boxed string.
esid: sec-object.fromentries
features: [Object.fromEntries]
---*/
var result = Object.fromEntries([Object('ab')]);
assert.sameValue(result['a'], 'b');
// Copyright (C) 2018 Kevin Gibbons. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Throws when an entry object is a primitive string.
esid: sec-object.fromentries
features: [Object.fromEntries]
---*/
assert.throws(TypeError, function() {
Object.fromEntries(['ab']);
});
// Copyright (C) 2018 Kevin Gibbons. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Allows symbol keys.
esid: sec-object.fromentries
features: [Symbol, Object.fromEntries]
---*/
var key = Symbol();
var result = Object.fromEntries([[key, 'value']]);
assert.sameValue(result[key], 'value');
// Copyright (C) 2018 Kevin Gibbons. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Coerces keys to strings using ToPropertyKey.
esid: sec-object.fromentries
features: [Symbol.toPrimitive, Object.fromEntries]
---*/
var key = {
[Symbol.toPrimitive]: function(hint) {
assert.sameValue(hint, 'string');
return 'key';
},
};
var result = Object.fromEntries([[key, 'value']]);
assert.sameValue(result.key, 'value');
// Copyright (C) 2018 Kevin Gibbons. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Uses [[DefineOwnProperty]] rather than [[Set]].
esid: sec-object.fromentries
features: [Object.fromEntries]
---*/
Object.defineProperty(Object.prototype, 'property', {
get: function() {
throw new Test262Error('should not trigger getter on Object.prototype');
},
set: function() {
throw new Test262Error('should not trigger setter on Object.prototype');
},
});
var result = Object.fromEntries([['property', 'value']]);
assert.sameValue(result['property'], 'value', '');
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment