<!doctype html>
<html>
<head>
<script src="../../http/tests/inspector/resources/inspector-test.js"></script>
<script>
function test()
{
    // Simple HeapSnapshot representation.

    WI.TestHeapSnapshotNode = class TestHeapSnapshotNode
    {
        constructor(identifier, className, size, flags)
        {
            this.id = identifier;
            this.className = className;
            this.size = size; 
            this.internal = flags & (1 << 0) ? true : false;
            this.isObjectType = flags & (1 << 1) ? true : false;
            this.gcRoot = false;
            this.outgoingEdges = [];
            this.incomingEdges = [];
        }
    }

    WI.TestHeapSnapshotEdge = class TestHeapSnapshotEdge
    {
        constructor(from, to, type, data)
        {
            this.from = from;
            this.to = to;
            this.type = type;
            this.data = data;
        }
    };

    WI.TestHeapSnapshot = class TestHeapSnapshot
    {
        constructor(rootNode, nodes, nodeMap)
        {
            console.assert(rootNode instanceof WI.TestHeapSnapshotNode);
            console.assert(nodes.every((n) => n instanceof WI.TestHeapSnapshotNode));

            this.rootNode = rootNode;
            this.nodes = nodes;
            this.nodeMap = nodeMap;
            this.totalSize = nodes.reduce((sum, node) => sum += node.size, 0);
            this.totalObjectCount = nodes.length - 1; // <root>.
        }

        static fromPayload(payload)
        {
            let {version, nodes, nodeClassNames, edges, edgeTypes, edgeNames} = payload;
            console.assert(version === 1, "Only know how to handle JavaScriptCore Heap Snapshot Format Version 1");

            let nodeMap = new Map;

            // Turn nodes into real nodes.
            let processedNodes = [];
            for (let i = 0, length = nodes.length; i < length;) {
                let id = nodes[i++];
                let size = nodes[i++];
                let classNameIndex = nodes[i++];
                let flags = nodes[i++];

                let node = new WI.TestHeapSnapshotNode(id, nodeClassNames[classNameIndex], size, flags);
                nodeMap.set(id, node);
                processedNodes.push(node);
            }

            // Turn edges into real edges and set them on the nodes.
            for (let i = 0, length = edges.length; i < length;) {
                let fromIdentifier = edges[i++];
                let toIdentifier = edges[i++];
                let edgeTypeIndex = edges[i++];
                let data = edges[i++];

                let from = nodeMap.get(fromIdentifier);
                let to = nodeMap.get(toIdentifier);
                let type = edgeTypes[edgeTypeIndex];
                if (type === "Property" || type === "Variable")
                    data = edgeNames[data];

                let edge = new WI.TestHeapSnapshotEdge(from, to, type, data);
                from.outgoingEdges.push(edge);
                to.incomingEdges.push(edge);
            }

            // Root node.
            let rootNode = nodeMap.get(0);
            console.assert(rootNode, "Node with identifier 0 is the synthetic <root> node.");
            console.assert(rootNode.outgoingEdges.length > 0, "This had better have children!");
            console.assert(rootNode.incomingEdges.length === 0, "This had better not have back references!");

            // Mark GC roots.
            let rootNodeEdges = rootNode.outgoingEdges;
            for (let i = 0, length = rootNodeEdges.length; i < length; ++i)
                rootNodeEdges[i].to.gcRoot = true;

            return new WI.TestHeapSnapshot(rootNode, processedNodes, nodeMap);
        }

        // Public

        instancesWithClassName(className)
        {
            let results = [];
            // Skip <root>.
            for (let i = 1; i < this.nodes.length; ++i) {
                let node = this.nodes[i];
                if (node.className === className)
                    results.push(node);
            }
            return results;
        }
    };

    // ------

    let suite = InspectorTest.createAsyncSuite("HeapSnapshot");

    let snapshot = null;
    let snapshotNodeForWindowObject = null;
    let testSnapshot = null;
    let testSnapshotNodeForWindowObject = null;

    function compareNodes(node1, node2) {
        return node1.id === node2.id
            && node1.size === node2.size
            && node1.className === node2.className
            && node1.internal === node2.internal
            && node1.isObjectType === node2.isObjectType
            && node1.gcRoot === node2.gcRoot;
    }

    suite.addTestCase({
        name: "HeapSnapshotProxy data",
        test(resolve, reject) {
            HeapAgent.snapshot((error, timestamp, snapshotStringData) => {
                InspectorTest.expectThat(!error, "Should not have an error creating a snapshot.");
                testSnapshot = WI.TestHeapSnapshot.fromPayload(JSON.parse(snapshotStringData));
                let workerProxy = WI.HeapSnapshotWorkerProxy.singleton();
                workerProxy.createSnapshot(snapshotStringData, ({objectId, snapshot: serializedSnapshot}) => {
                    snapshot = WI.HeapSnapshotProxy.deserialize(objectId, serializedSnapshot);
                    InspectorTest.assert(testSnapshot, "Created TestHeapSnapshot");
                    InspectorTest.assert(snapshot, "Created HeapSnapshotProxy");
                    InspectorTest.expectThat(snapshot.totalSize === testSnapshot.totalSize, "Snapshots totalSize should match.");
                    InspectorTest.expectThat(snapshot.totalObjectCount === testSnapshot.totalObjectCount, "Snapshots totalObjectCount should match.");
                    resolve();
                });
            });
        }
    });

    suite.addTestCase({
        name: "HeapSnapshotProxy.prototype.instancesWithClassName",
        test(resolve, reject) {
            let windowObjects = testSnapshot.instancesWithClassName("Window")
            let windowObjectCount = windowObjects.length;
            let functionObjectCount = testSnapshot.instancesWithClassName("Function").length;
            let stringCount = testSnapshot.instancesWithClassName("string").length;

            snapshot.instancesWithClassName("Window", (windows) => {
                testSnapshotNodeForWindowObject = windowObjects[0]; // Used by later tests.
                snapshotNodeForWindowObject = windows[0]; // Used by later tests.

                InspectorTest.expectThat(windows.length > 0, "Should be at least 1 Window.");
                InspectorTest.expectThat(windows.length === windowObjectCount, "Window object count is expected.");
                InspectorTest.expectThat(windows.every((node) => node.className === "Window"), "Every className should be 'Window'.");
            });

            snapshot.instancesWithClassName("Function", (functions) => {
                InspectorTest.expectThat(functions.length > 0, "Should be at least 1 Function.");
                InspectorTest.expectThat(functions.length === functionObjectCount, "Function object count is expected.");
                InspectorTest.expectThat(functions.every((node) => node.className === "Function"), "Every className should be 'Function'.");
            });

            snapshot.instancesWithClassName("string", (strings) => {
                InspectorTest.expectThat(strings.length > 0, "Should be at least 1 string.");
                InspectorTest.expectThat(strings.length === stringCount, "string count is expected.");
                InspectorTest.expectThat(strings.every((node) => node.className === "string"), "Every className should be 'string'.");
                resolve();
            });
        }
    });

    suite.addTestCase({
        name: "HeapSnapshotProxy.prototype.nodeWithIdentifier and HeapSnapshotNodeProxy data",
        test(resolve, reject) {
            snapshot.nodeWithIdentifier(testSnapshotNodeForWindowObject.id, (heapSnapshotNode) => {
                InspectorTest.expectThat(heapSnapshotNode.className === "Window", "Node className should be 'Window'.");
                InspectorTest.expectThat(heapSnapshotNode.id === testSnapshotNodeForWindowObject.id, "Node identifier should match.")
                InspectorTest.expectThat(heapSnapshotNode.size === testSnapshotNodeForWindowObject.size, "Node size should match.");
                InspectorTest.expectThat(heapSnapshotNode.internal === testSnapshotNodeForWindowObject.internal, "Node internal state should match.");
                InspectorTest.expectThat(heapSnapshotNode.isObjectType === testSnapshotNodeForWindowObject.isObjectType, "Node isObjectType state should match.");
                InspectorTest.expectThat(heapSnapshotNode.gcRoot === testSnapshotNodeForWindowObject.gcRoot, "Node gcRoot state should match.");
                InspectorTest.expectThat(heapSnapshotNode.retainedSize >= heapSnapshotNode.size, "Node retainedSize should at least be the size.");
                resolve();
            });
        }
    });

    suite.addTestCase({
        name: "HeapSnapshotProxy.prototype.allocationBucketCounts",
        test(resolve, reject) {
            let testSmall = 0, testMedium = 0, testLarge = 0;
            const smallSize = 32, mediumSize = 128;
            // Skip <root>.
            for (let i = 1; i < testSnapshot.nodes.length; ++i) {
                let {size} = testSnapshot.nodes[i];
                if (size < smallSize)
                    testSmall++;
                else if (size < mediumSize)
                    testMedium++;
                else
                    testLarge++;
            }

            snapshot.allocationBucketCounts([smallSize, mediumSize], (results) => {
                let [small, medium, large] = results;
                InspectorTest.expectThat(results.length === 3, "Result should have 3 buckets, for small/medium/large.");
                InspectorTest.expectThat(small === testSmall, "Small count should match.");
                InspectorTest.expectThat(medium === testMedium, "Medium count should match.");
                InspectorTest.expectThat(large === testLarge, "Large count should match.");
                resolve();
            });
        }
    });

    suite.addTestCase({
        name: "HeapSnapshotNodeProxy.prototype.retainedNodes",
        test(resolve, reject) {
            let expectedNodes = testSnapshotNodeForWindowObject.outgoingEdges.map((edge) => edge.to);
            expectedNodes.sort((a, b) => a.id - b.id);

            snapshotNodeForWindowObject.retainedNodes((nodes, edges) => {
                nodes.sort((a, b) => a.id - b.id);
                InspectorTest.assert(nodes.length > 0, "Test only makes since if there are retained nodes");
                InspectorTest.expectThat(nodes.length === expectedNodes.length, "Number of retained nodes should match.");
                InspectorTest.expectThat(nodes.length === edges.length, "Number of edges should match the number of nodes.");
                InspectorTest.expectThat(nodes.every((node, i) => compareNodes(node, expectedNodes[i])), "Node values should match.");
                resolve();
            });
        }
    });

    suite.addTestCase({
        name: "HeapSnapshotNodeProxy.prototype.retainers",
        test(resolve, reject) {
            let expectedNodes = testSnapshotNodeForWindowObject.incomingEdges.map((edge) => edge.from);
            expectedNodes.sort((a, b) => a.id - b.id);

            snapshotNodeForWindowObject.retainers((nodes, edges) => {
                nodes.sort((a, b) => a.id - b.id);
                InspectorTest.assert(nodes.length > 0, "Test only makes since if there are retainer nodes");
                InspectorTest.expectThat(nodes.length === expectedNodes.length, "Number of retainer nodes should match.");
                InspectorTest.expectThat(nodes.length === edges.length, "Number of edges should match the number of nodes.");
                InspectorTest.expectThat(nodes.every((node, i) => compareNodes(node, expectedNodes[i])), "Node values should match.");
                resolve();
            });
        }
    });

    suite.runTestCasesAndFinish();
}
</script>
</head>
<body onload="runTest()">
    <p>Testing HeapSnapshot Worker and Proxy objects.</p>
</body>
</html>
