Source code
Revision control
Copy as Markdown
Other Tools
/*---
defines: [assertSetContainsExactOrderedItems, SetLike, SetIteratorLike, LoggingProxy]
allow_unused: True
---*/
(function(global) {
// Save the primordial values.
const {Array, Error, Object, Proxy, Reflect, Set} = global;
const ArrayIsArray = Array.isArray;
const ReflectApply = Reflect.apply;
const ReflectDefineProperty = Reflect.defineProperty;
const ReflectGet = Reflect.get;
const ReflectGetPrototypeOf = Reflect.getPrototypeOf;
const SetPrototype = Set.prototype;
const SetPrototypeHas = SetPrototype.has;
const SetPrototypeSize = Object.getOwnPropertyDescriptor(SetPrototype, "size").get;
const SetPrototypeKeys = SetPrototype.keys;
const SetIteratorPrototypeNext = new Set().values().next;
function assertSetContainsExactOrderedItems(actual, expected) {
assertEq(ReflectGetPrototypeOf(actual), SetPrototype, "actual is a native Set object");
assertEq(ArrayIsArray(expected), true, "expected is an Array object");
assertEq(ReflectApply(SetPrototypeSize, actual, []), expected.length);
let index = 0;
let keys = ReflectApply(SetPrototypeKeys, actual, []);
while (true) {
let {done, value: item} = ReflectApply(SetIteratorPrototypeNext, keys, []);
if (done) {
break;
}
assertEq(item, expected[index], `Element at index ${index}:`);
index++;
}
}
global.assertSetContainsExactOrderedItems = assertSetContainsExactOrderedItems;
class SetLike {
#set;
constructor(values) {
this.#set = new Set(values);
}
get size() {
return ReflectApply(SetPrototypeSize, this.#set, []);
}
has(value) {
return ReflectApply(SetPrototypeHas, this.#set, [value]);
}
keys() {
let keys = ReflectApply(SetPrototypeKeys, this.#set, []);
return new SetIteratorLike(keys);
}
}
global.SetLike = SetLike;
class SetIteratorLike {
#keys;
constructor(keys) {
this.#keys = keys;
}
next() {
return ReflectApply(SetIteratorPrototypeNext, this.#keys, []);
}
// The |return| method of the iterator protocol is never called.
return() {
throw new Error("Unexpected call to |return| method");
}
// The |throw| method of the iterator protocol is never called.
throw() {
throw new Error("Unexpected call to |throw| method");
}
}
function LoggingProxy(obj, log) {
assertEq(ArrayIsArray(log), true);
let handler = new Proxy({
get(t, pk, r) {
ReflectDefineProperty(log, log.length, {
value: pk, writable: true, enumerable: true, configurable: true,
});
return ReflectGet(t, pk, r);
}
}, {
get(t, pk, r) {
ReflectDefineProperty(log, log.length, {
value: `[[${pk}]]`, writable: true, enumerable: true, configurable: true,
});
return ReflectGet(t, pk, r);
}
});
return {obj, proxy: new Proxy(obj, handler)};
}
global.LoggingProxy = LoggingProxy;
})(this);