|
| 1 | +/* eslint-disable node-core/required-modules */ |
| 2 | +'use strict'; |
| 3 | +const assert = require('assert'); |
| 4 | +const util = require('util'); |
| 5 | + |
| 6 | +let internalTestHeap; |
| 7 | +try { |
| 8 | + internalTestHeap = require('internal/test/heap'); |
| 9 | +} catch (e) { |
| 10 | + console.log('using `test/common/heap.js` requires `--expose-internals`'); |
| 11 | + throw e; |
| 12 | +} |
| 13 | +const { createJSHeapDump, buildEmbedderGraph } = internalTestHeap; |
| 14 | + |
| 15 | +class State { |
| 16 | + constructor() { |
| 17 | + this.snapshot = createJSHeapDump(); |
| 18 | + this.embedderGraph = buildEmbedderGraph(); |
| 19 | + } |
| 20 | + |
| 21 | + validateSnapshotNodes(name, expected, { loose = false } = {}) { |
| 22 | + const snapshot = this.snapshot.filter( |
| 23 | + (node) => node.name === 'Node / ' + name && node.type !== 'string'); |
| 24 | + if (loose) |
| 25 | + assert(snapshot.length >= expected.length); |
| 26 | + else |
| 27 | + assert.strictEqual(snapshot.length, expected.length); |
| 28 | + for (const expectedNode of expected) { |
| 29 | + if (expectedNode.children) { |
| 30 | + for (const expectedChild of expectedNode.children) { |
| 31 | + const check = typeof expectedChild === 'function' ? |
| 32 | + expectedChild : |
| 33 | + (node) => [expectedChild.name, 'Node / ' + expectedChild.name] |
| 34 | + .includes(node.name); |
| 35 | + |
| 36 | + assert(snapshot.some((node) => { |
| 37 | + return node.outgoingEdges.map((edge) => edge.toNode).some(check); |
| 38 | + }), `expected to find child ${util.inspect(expectedChild)} ` + |
| 39 | + `in ${util.inspect(snapshot)}`); |
| 40 | + } |
| 41 | + } |
| 42 | + } |
| 43 | + |
| 44 | + const graph = this.embedderGraph.filter((node) => node.name === name); |
| 45 | + if (loose) |
| 46 | + assert(graph.length >= expected.length); |
| 47 | + else |
| 48 | + assert.strictEqual(graph.length, expected.length); |
| 49 | + for (const expectedNode of expected) { |
| 50 | + if (expectedNode.edges) { |
| 51 | + for (const expectedChild of expectedNode.children) { |
| 52 | + const check = typeof expectedChild === 'function' ? |
| 53 | + expectedChild : (node) => { |
| 54 | + return node.name === expectedChild.name || |
| 55 | + (node.value && |
| 56 | + node.value.constructor && |
| 57 | + node.value.constructor.name === expectedChild.name); |
| 58 | + }; |
| 59 | + |
| 60 | + assert(graph.some((node) => node.edges.some(check)), |
| 61 | + `expected to find child ${util.inspect(expectedChild)} ` + |
| 62 | + `in ${util.inspect(snapshot)}`); |
| 63 | + } |
| 64 | + } |
| 65 | + } |
| 66 | + } |
| 67 | +} |
| 68 | + |
| 69 | +function recordState() { |
| 70 | + return new State(); |
| 71 | +} |
| 72 | + |
| 73 | +function validateSnapshotNodes(...args) { |
| 74 | + return recordState().validateSnapshotNodes(...args); |
| 75 | +} |
| 76 | + |
| 77 | +module.exports = { |
| 78 | + recordState, |
| 79 | + validateSnapshotNodes |
| 80 | +}; |
0 commit comments