// Copyright 2017 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: --allow-natives-syntax

// Ensure empty keys are handled properly
(function() {
  const a = {};
  let k = Object.keys(a);
  %HeapObjectVerify(k);
  assertEquals(0, k.length);
})();

// Ensure non-enumerable keys are handled properly
(function() {
  const a = {};
  Object.defineProperty(a, 'x', {
    value: 1,
    enumerable: false
  });
  let k = Object.keys(a);
  %HeapObjectVerify(k);
  assertEquals(0, k.length);

  a.y = 2;
  k = Object.keys(a);
  %HeapObjectVerify(k);
  assertEquals(1, k.length);
})();

// Ensure that mutation of the Object.keys result doesn't affect the
// enumeration cache for fast-mode objects.
(function() {
  const a = {x:1, y:2};
  let k = Object.keys(a);
  %HeapObjectVerify(k);
  assertEquals(2, k.length);
  assertEquals("x", k[0]);
  assertEquals("y", k[1]);
  k[0] = "y";
  k[1] = "x";
  k = Object.keys(a);
  assertEquals(2, k.length);
  assertEquals("x", k[0]);
  assertEquals("y", k[1]);
})();

// Ensure that the copy-on-write keys are handled properly, even in
// the presence of Symbols.
(function() {
  const s = Symbol();
  const a = {[s]: 1};
  let k = Object.keys(a);
  %HeapObjectVerify(k);
  assertEquals(0, k.length);
  k.shift();
  assertEquals(0, k.length);
})();

// Ensure we invoke all steps on proxies.
(function ObjectKeysProxy() {
  let log = [];
  let result = Object.keys(new Proxy({}, {
    ownKeys(target) {
      log.push('ownKeys');
      return ['a', 'b', 'c'];
    },
    getOwnPropertyDescriptor(target, key) {
      log.push('getOwnPropertyDescriptor-' + key);
      if (key === 'b') return {enumerable: false, configurable: true};
      return {enumerable: true, configurable: true};
    }
  }));
  assertEquals(['a', 'c'], result);
  assertEquals(
      [
        'ownKeys', 'getOwnPropertyDescriptor-a', 'getOwnPropertyDescriptor-b',
        'getOwnPropertyDescriptor-c'
      ],
      log);

  // Test normal target.
  log = [];
  let target = {a: 1, b: 1, c: 1};
  let handler = {
    getOwnPropertyDescriptor(target, key) {
      log.push('getOwnPropertyDescriptor-' + key);
      if (key === 'b') return {enumerable: false, configurable: true};
      return {enumerable: true, configurable: true};
    }
  };
  result = Object.keys(new Proxy(target, handler));
  assertEquals(['a', 'c'], result);
  assertEquals(
      [
        'getOwnPropertyDescriptor-a', 'getOwnPropertyDescriptor-b',
        'getOwnPropertyDescriptor-c'
      ],
      log);

  // Test trap invocation with non-enumerable target properties.
  log = [];
  target = Object.create(Object.prototype, {
    a: {enumerable: true, configurable: true},
    b: {enumerable: false, configurable: true},
    c: {enumerable: true, configurable: true}
  });
  result = Object.keys(new Proxy(target, handler));
  assertEquals(['a', 'c'], result);
  assertEquals(
      [
        'getOwnPropertyDescriptor-a', 'getOwnPropertyDescriptor-b',
        'getOwnPropertyDescriptor-c'
      ],
      log);
})();
