| 'use strict'; |
| |
| // This tests the v8.queryObjects() API. |
| |
| const common = require('../common'); |
| const v8 = require('v8'); |
| const assert = require('assert'); |
| const { inspect } = require('util'); |
| |
| function format(obj) { |
| return inspect(obj, { depth: 0 }); |
| } |
| |
| common.expectWarning( |
| 'ExperimentalWarning', |
| 'v8.queryObjects() is an experimental feature and might change at any time', |
| ); |
| |
| { |
| for (const invalid of [undefined, 1, null, false, {}, 'foo']) { |
| assert.throws(() => v8.queryObjects(invalid), { code: 'ERR_INVALID_ARG_TYPE' }); |
| } |
| for (const invalid of [1, null, false, 'foo']) { |
| assert.throws(() => v8.queryObjects(() => {}, invalid), { code: 'ERR_INVALID_ARG_TYPE' }); |
| } |
| assert.throws(() => v8.queryObjects(() => {}, { format: 'invalid' }), { code: 'ERR_INVALID_ARG_VALUE' }); |
| } |
| |
| { |
| class TestV8QueryObjectsClass {} |
| // By default, returns count of objects with the constructor on the prototype. |
| assert.strictEqual(v8.queryObjects(TestV8QueryObjectsClass), 0); |
| assert.strictEqual(v8.queryObjects(TestV8QueryObjectsClass, { format: 'count' }), 0); |
| // 'summary' format returns an array. |
| assert.deepStrictEqual(v8.queryObjects(TestV8QueryObjectsClass, { format: 'summary' }), []); |
| |
| // Create an instance and check that it shows up in the results. |
| const obj = new TestV8QueryObjectsClass(); |
| assert.strictEqual(v8.queryObjects(TestV8QueryObjectsClass), 1); |
| assert.strictEqual(v8.queryObjects(TestV8QueryObjectsClass, { format: 'count' }), 1); |
| assert.deepStrictEqual( |
| v8.queryObjects(TestV8QueryObjectsClass, { format: 'summary' }), |
| [ format(obj)] |
| ); |
| } |
| |
| { |
| // ES6 class inheritance. |
| class TestV8QueryObjectsBaseClass {} |
| class TestV8QueryObjectsChildClass extends TestV8QueryObjectsBaseClass {} |
| const summary = v8.queryObjects(TestV8QueryObjectsBaseClass, { format: 'summary' }); |
| // TestV8QueryObjectsChildClass's prototype's [[Prototype]] slot is |
| // TestV8QueryObjectsBaseClass's prototype so it shows up in the query. |
| assert.deepStrictEqual(summary, [ |
| format(TestV8QueryObjectsChildClass.prototype), |
| ]); |
| const obj = new TestV8QueryObjectsChildClass(); |
| assert.deepStrictEqual( |
| v8.queryObjects(TestV8QueryObjectsBaseClass, { format: 'summary' }).sort(), |
| [ |
| format(TestV8QueryObjectsChildClass.prototype), |
| format(obj), |
| ].sort() |
| ); |
| assert.deepStrictEqual( |
| v8.queryObjects(TestV8QueryObjectsChildClass, { format: 'summary' }), |
| [ format(obj) ], |
| ); |
| } |
| |
| { |
| function TestV8QueryObjectsCtor() {} |
| assert.strictEqual(v8.queryObjects(TestV8QueryObjectsCtor), 0); |
| assert.strictEqual(v8.queryObjects(TestV8QueryObjectsCtor, { format: 'count' }), 0); |
| assert.deepStrictEqual(v8.queryObjects(TestV8QueryObjectsCtor, { format: 'summary' }), []); |
| |
| // Create an instance and check that it shows up in the results. |
| const obj = new TestV8QueryObjectsCtor(); |
| assert.strictEqual(v8.queryObjects(TestV8QueryObjectsCtor), 1); |
| assert.strictEqual(v8.queryObjects(TestV8QueryObjectsCtor, { format: 'count' }), 1); |
| assert.deepStrictEqual( |
| v8.queryObjects(TestV8QueryObjectsCtor, { format: 'summary' }), |
| [ format(obj)] |
| ); |
| } |
| |
| { |
| // Classic inheritance. |
| function TestV8QueryObjectsBaseCtor() {} |
| |
| function TestV8QueryObjectsChildCtor() {} |
| Object.setPrototypeOf(TestV8QueryObjectsChildCtor.prototype, TestV8QueryObjectsBaseCtor.prototype); |
| Object.setPrototypeOf(TestV8QueryObjectsChildCtor, TestV8QueryObjectsBaseCtor); |
| |
| const summary = v8.queryObjects(TestV8QueryObjectsBaseCtor, { format: 'summary' }); |
| assert.deepStrictEqual(summary, [ |
| format(TestV8QueryObjectsChildCtor.prototype), |
| ]); |
| const obj = new TestV8QueryObjectsChildCtor(); |
| assert.deepStrictEqual( |
| v8.queryObjects(TestV8QueryObjectsChildCtor, { format: 'summary' }), |
| [ format(obj) ], |
| ); |
| } |