get-properties.js 6.08 KB
Newer Older
1 2 3
// Copyright 2016 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.
4
//
5
// Flags: --harmony-private-fields --allow-natives-syntax
6

7
let {session, contextGroup, Protocol} = InspectorTest.start('Checks Runtime.getProperties method');
8 9

InspectorTest.runAsyncTestSuite([
10 11
  function testObject5() {
    return logExpressionProperties('(function(){var r = Object(5); r.foo = \'cat\';return r;})()');
12 13
  },

14 15
  function testNotOwn() {
    return logExpressionProperties('({ a: 2, set b(_) {}, get b() {return 5;}, __proto__: { a: 3, c: 4, get d() {return 6;} }})', { ownProperties: false });
16 17
  },

18 19
  function testAccessorsOnly() {
    return logExpressionProperties('({ a: 2, set b(_) {}, get b() {return 5;}, c: \'c\', set d(_){} })', { ownProperties: true, accessorPropertiesOnly: true});
20 21
  },

22 23
  function testArray() {
    return logExpressionProperties('[\'red\', \'green\', \'blue\']');
24 25
  },

26 27
  function testBound() {
    return logExpressionProperties('Number.bind({}, 5)');
28 29
  },

30 31
  function testObjectThrowsLength() {
    return logExpressionProperties('({get length() { throw \'Length called\'; }})');
32 33
  },

34 35 36 37
  function testTypedArrayWithoutLength() {
    return logExpressionProperties('({__proto__: Uint8Array.prototype})');
  },

38 39 40 41 42 43
  function testClassWithPrivateFields() {
    return logExpressionProperties('new class { #foo = 2; #bar = 3; baz = 4; }')
      .then(() => logExpressionProperties('new class extends class { #baz = 1 } { #foo = 2; #bar = 3; baz = 4; }'))
      .then(() => logExpressionProperties('new class extends class { #hidden = 1; constructor() { return new Proxy({}, {}); } } { #foo = 2; #bar = 3; baz = 4; }'));
  },

44
  async function testArrayBuffer() {
45
    let objectId = await evaluateToObjectId('new Uint8Array([1, 1, 1, 1, 1, 1, 1, 1]).buffer');
46
    let props = await Protocol.Runtime.getProperties({ objectId, ownProperties: true });
47 48 49 50
    for (let prop of props.result.result) {
      InspectorTest.log(prop.name);
      await logGetPropertiesResult(prop.value.objectId);
    }
51
    for (let prop of props.result.internalProperties) {
52
      InspectorTest.log(prop.name);
53 54
      if (prop.value.objectId)
        await logGetPropertiesResult(prop.value.objectId);
55
    }
56
  },
57

58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
  async function testArrayBufferFromWebAssemblyMemory() {
    let objectId = await evaluateToObjectId('new WebAssembly.Memory({initial: 1}).buffer');
    let props = await Protocol.Runtime.getProperties({ objectId, ownProperties: true });
    for (let prop of props.result.result) {
      InspectorTest.log(prop.name);
      await logGetPropertiesResult(prop.value.objectId);
    }
    for (let prop of props.result.internalProperties) {
      InspectorTest.log(prop.name);
      // Skip printing the values of the virtual typed arrays.
      if (/\[\[.*Array\]\]/.test(prop.name))
        continue;
      if (prop.value.objectId)
        await logGetPropertiesResult(prop.value.objectId);
    }
  },

75 76 77 78 79 80 81 82 83 84 85
  async function testDetachedArrayBuffer() {
    await Protocol.Runtime.evaluate({ expression: 'var a = new ArrayBuffer(16)' });
    await Protocol.Runtime.evaluate({ expression: 'var b = new Uint32Array(a)' });
    let objectId = await evaluateToObjectId('a');
    await Protocol.Runtime.evaluate({ expression: '%ArrayBufferDetach(a)' });
    await Protocol.Runtime.evaluate({ expression: 'b', generatePreview: true })
    let props = await Protocol.Runtime.getProperties({ objectId, ownProperties: true });
    for (let prop of props.result.result) {
      InspectorTest.log(prop.name);
      await logGetPropertiesResult(prop.value.objectId);
    }
86 87 88
    for (let prop of props.result.internalProperties) {
      InspectorTest.log(prop.name + ' ' + prop.value.value);
    }
89 90
  },

91 92 93 94 95
  async function testArrayBufferWithBrokenUintCtor() {
    await evaluateToObjectId(`(function() {
      this.uint8array_old = this.Uint8Array;
      this.Uint8Array = 42;
    })()`);
96
    await logExpressionProperties('new Int8Array([1, 1, 1, 1, 1, 1, 1]).buffer');
97 98 99 100
    await evaluateToObjectId(`(function() {
      this.Uint8Array = this.uint8array_old;
      delete this.uint8array_old;
    })()`);
101 102 103 104
  },

  async function testObjectWithProtoProperty() {
    await logExpressionProperties('Object.defineProperty({}, "__proto__", {enumerable: true, value: {b:"aaa"}})');
105
  }
106 107
]);

108 109 110 111 112 113 114 115 116 117
async function logExpressionProperties(expression, flags) {
  const objectId = await evaluateToObjectId(expression);
  return await logGetPropertiesResult(objectId, flags);
}

async function evaluateToObjectId(expression) {
  return (await Protocol.Runtime.evaluate({ expression })).result.result.objectId;
}

async function logGetPropertiesResult(objectId, flags = { ownProperties: true }) {
118
  function hasGetterSetter(property, fieldName) {
119
    var v = property[fieldName];
120
    if (!v) return false;
121 122 123
    return v.type !== "undefined"
  }

124 125 126
  flags.objectId = objectId;
  let props = await Protocol.Runtime.getProperties(flags);
  var propertyArray = props.result.result;
127 128 129 130 131 132
  propertyArray.sort(NamedThingComparator);
  for (var i = 0; i < propertyArray.length; i++) {
    var p = propertyArray[i];
    var v = p.value;
    var own = p.isOwn ? "own" : "inherited";
    if (v)
133
      InspectorTest.log(`  ${p.name} ${own} ${v.type} ${v.value}`);
134 135 136 137
    else
      InspectorTest.log("  " + p.name + " " + own + " no value" +
        (hasGetterSetter(p, "get") ? ", getter" : "") + (hasGetterSetter(p, "set") ? ", setter" : ""));
  }
138 139 140 141 142 143 144

  function printFields(type, array) {
    if (!array) { return; }
    InspectorTest.log(type);
    array.sort(NamedThingComparator);
    for (var i = 0; i < array.length; i++) {
      var p = array[i];
145
      var v = p.value;
146 147 148 149 150
      if (p.name == "[[ArrayBufferData]]")
        // Hex value for pointer is non-deterministic
        InspectorTest.log(`  ${p.name} ${v.type} ${v.value.substr(0, 2)}...`);
      else
        InspectorTest.log(`  ${p.name} ${v.type} ${v.value}`);
151 152 153
    }
  }

154 155 156
  printFields("Internal properties", props.result.internalProperties);
  printFields("Private properties", props.result.privateProperties);

157
  function NamedThingComparator(o1, o2) {
158 159 160
    return o1.name === o2.name ? 0 : (o1.name < o2.name ? -1 : 1);
  }
}