1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests if the profiler's tree view implementation works properly and
* creates the correct column structure after expanding some of the nodes.
* Also tests that demangling works.
*/
const { ThreadNode } = require("devtools/client/performance/modules/logic/tree-model");
const { CallView } = require("devtools/client/performance/modules/widgets/tree-view");
const { synthesizeProfile } = require("devtools/client/performance/test/helpers/synth-utils");
const MANGLED_FN = "__Z3FooIiEvv";
const UNMANGLED_FN = "void Foo<int>()";
add_task(function () {
// Create a profile and mangle a function inside the string table.
let profile = synthesizeProfile();
profile.threads[0].stringTable[1] =
profile.threads[0].stringTable[1].replace("A (", `${MANGLED_FN} (`);
let threadNode = new ThreadNode(profile.threads[0], { startTime: 0, endTime: 20 });
// Don't display the synthesized (root) and the real (root) node twice.
threadNode.calls = threadNode.calls[0].calls;
let treeRoot = new CallView({ frame: threadNode });
let container = document.createElement("vbox");
treeRoot.autoExpandDepth = 0;
treeRoot.attachTo(container);
let $$ = node => container.querySelectorAll(node);
let $fun = (node, ancestor) => (ancestor || container).querySelector(
".call-tree-cell[type=function] > " + node);
let $$fun = (node, ancestor) => (ancestor || container).querySelectorAll(
".call-tree-cell[type=function] > " + node);
let $$dur = i => container.querySelectorAll(".call-tree-cell[type=duration]")[i];
let $$per = i => container.querySelectorAll(".call-tree-cell[type=percentage]")[i];
let $$sam = i => container.querySelectorAll(".call-tree-cell[type=samples]")[i];
is(container.childNodes.length, 1,
"The container node should have one child available.");
is(container.childNodes[0].className, "call-tree-item",
"The root node in the tree has the correct class name.");
is($$dur(0).textContent.trim(), "20 ms",
"The root's duration cell displays the correct value.");
is($$per(0).textContent.trim(), "100%",
"The root's percentage cell displays the correct value.");
is($$sam(0).textContent.trim(), "0",
"The root's samples cell displays the correct value.");
is($$fun(".call-tree-name")[0].textContent.trim(), "(root)",
"The root's function cell displays the correct name.");
is($$fun(".call-tree-url")[0], null,
"The root's function cell displays no url.");
is($$fun(".call-tree-line")[0], null,
"The root's function cell displays no line.");
is($$fun(".call-tree-host")[0], null,
"The root's function cell displays no host.");
is($$fun(".call-tree-category")[0], null,
"The root's function cell displays no category.");
treeRoot.expand();
is(container.childNodes.length, 2,
"The container node should have two children available.");
is(container.childNodes[0].className, "call-tree-item",
"The root node in the tree has the correct class name.");
is(container.childNodes[1].className, "call-tree-item",
"The .A node in the tree has the correct class name.");
// Test demangling in the profiler tree.
is($$dur(1).textContent.trim(), "20 ms",
"The .A node's duration cell displays the correct value.");
is($$per(1).textContent.trim(), "100%",
"The .A node's percentage cell displays the correct value.");
is($$sam(1).textContent.trim(), "0",
"The .A node's samples cell displays the correct value.");
is($fun(".call-tree-name", $$(".call-tree-item")[1]).textContent.trim(), UNMANGLED_FN,
"The .A node's function cell displays the correct name.");
is($fun(".call-tree-url", $$(".call-tree-item")[1]).textContent.trim(), "baz",
"The .A node's function cell displays the correct url.");
is($fun(".call-tree-line", $$(".call-tree-item")[1]).textContent.trim(), ":12",
"The .A node's function cell displays the correct line.");
is($fun(".call-tree-host", $$(".call-tree-item")[1]).textContent.trim(), "foo",
"The .A node's function cell displays the correct host.");
is($fun(".call-tree-category", $$(".call-tree-item")[1]).textContent.trim(), "Gecko",
"The .A node's function cell displays the correct category.");
ok($$(".call-tree-item")[1].getAttribute("tooltiptext").includes(MANGLED_FN),
"The .A node's row's tooltip contains the original mangled name.");
let A = treeRoot.getChild();
A.expand();
is(container.childNodes.length, 4,
"The container node should have four children available.");
is(container.childNodes[0].className, "call-tree-item",
"The root node in the tree has the correct class name.");
is(container.childNodes[1].className, "call-tree-item",
"The .A node in the tree has the correct class name.");
is(container.childNodes[2].className, "call-tree-item",
"The .B node in the tree has the correct class name.");
is(container.childNodes[3].className, "call-tree-item",
"The .E node in the tree has the correct class name.");
is($$dur(2).textContent.trim(), "15 ms",
"The .A.B node's duration cell displays the correct value.");
is($$per(2).textContent.trim(), "75%",
"The .A.B node's percentage cell displays the correct value.");
is($$sam(2).textContent.trim(), "0",
"The .A.B node's samples cell displays the correct value.");
is($fun(".call-tree-name", $$(".call-tree-item")[2]).textContent.trim(), "B",
"The .A.B node's function cell displays the correct name.");
is($fun(".call-tree-url", $$(".call-tree-item")[2]).textContent.trim(), "baz",
"The .A.B node's function cell displays the correct url.");
ok($fun(".call-tree-url", $$(".call-tree-item")[2]).getAttribute("tooltiptext").includes("http://foo/bar/baz"),
"The .A.B node's function cell displays the correct url tooltiptext.");
is($fun(".call-tree-line", $$(".call-tree-item")[2]).textContent.trim(), ":34",
"The .A.B node's function cell displays the correct line.");
is($fun(".call-tree-host", $$(".call-tree-item")[2]).textContent.trim(), "foo",
"The .A.B node's function cell displays the correct host.");
is($fun(".call-tree-category", $$(".call-tree-item")[2]).textContent.trim(), "Styles",
"The .A.B node's function cell displays the correct category.");
is($$dur(3).textContent.trim(), "5 ms",
"The .A.E node's duration cell displays the correct value.");
is($$per(3).textContent.trim(), "25%",
"The .A.E node's percentage cell displays the correct value.");
is($$sam(3).textContent.trim(), "0",
"The .A.E node's samples cell displays the correct value.");
is($fun(".call-tree-name", $$(".call-tree-item")[3]).textContent.trim(), "E",
"The .A.E node's function cell displays the correct name.");
is($fun(".call-tree-url", $$(".call-tree-item")[3]).textContent.trim(), "baz",
"The .A.E node's function cell displays the correct url.");
ok($fun(".call-tree-url", $$(".call-tree-item")[3]).getAttribute("tooltiptext").includes("http://foo/bar/baz"),
"The .A.E node's function cell displays the correct url tooltiptext.");
is($fun(".call-tree-line", $$(".call-tree-item")[3]).textContent.trim(), ":90",
"The .A.E node's function cell displays the correct line.");
is($fun(".call-tree-host", $$(".call-tree-item")[3]).textContent.trim(), "foo",
"The .A.E node's function cell displays the correct host.");
is($fun(".call-tree-category", $$(".call-tree-item")[3]).textContent.trim(), "GC",
"The .A.E node's function cell displays the correct category.");
});
|