summaryrefslogtreecommitdiffstats
path: root/js/src/tests/non262/Set/shell.js
blob: d6bd2e2083f32315618cb46b1b0210d82368a1ca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
(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);