|
1 // Debugger.prototype.{addDebuggee,hasDebuggee,removeDebuggee} recognize globals |
|
2 // regardless of how they are specified. |
|
3 |
|
4 var dbg = new Debugger; |
|
5 |
|
6 // Assert that dbg's debuggees are exactly the set passed as arguments. |
|
7 // The arguments are assumed to be Debugger.Object instances referring to |
|
8 // globals without wrappers --- which is the sort returned by addDebuggee. |
|
9 function assertDebuggees() { |
|
10 print("assertDebuggees([" + [g.toSource() for each (g in arguments)] + "])"); |
|
11 var debuggees = dbg.getDebuggees(); |
|
12 assertEq(arguments.length, debuggees.length); |
|
13 for each (g in arguments) |
|
14 assertEq(debuggees.indexOf(g) != -1, true); |
|
15 } |
|
16 |
|
17 var g1 = newGlobal(); g1.toSource = function () { return "[global g1]"; }; |
|
18 var g2 = newGlobal(); g2.toSource = function () { return "[global g2]"; }; |
|
19 |
|
20 assertDebuggees(); |
|
21 |
|
22 // Produce every possible way to designate g1, for us to play with. |
|
23 // Globals can be designated by any of the following: |
|
24 // |
|
25 // - "CCW": a Cross-Compartment Wrapper (CCW) of a global object |
|
26 // - "D.O": a Debugger.Object whose referent is a global object |
|
27 // - "D.O of CCW": a Debugger.Object whose referent is a CCW of a |
|
28 // global object, where the CCW can be securely unwrapped |
|
29 // |
|
30 // There's no direct "G", since globals are always in their own |
|
31 // compartments, never the debugger's; if we ever viewed them directly, |
|
32 // that would be a compartment violation. |
|
33 |
|
34 // "dg1" means "Debugger.Object referring (directly) to g1". |
|
35 var dg1 = dbg.addDebuggee(g1); |
|
36 dg1.toSource = function() { return "[Debugger.Object for global g1]"; }; |
|
37 assertEq(dg1.global, dg1); |
|
38 assertEq(dg1.unwrap(), dg1); |
|
39 assertDebuggees(dg1); |
|
40 |
|
41 // We need to add g2 as a debuggee; that's the only way to get a D.O referring |
|
42 // to it without a wrapper. |
|
43 var dg2 = dbg.addDebuggee(g2); |
|
44 dg2.toSource = function() { return "[Debugger.Object for global g2]"; }; |
|
45 assertEq(dg2.global, dg2); |
|
46 assertEq(dg2.unwrap(), dg2); |
|
47 assertDebuggees(dg1, dg2); |
|
48 |
|
49 // "dwg1" means "Debugger.Object referring to CCW of g1". |
|
50 var dwg1 = dg2.makeDebuggeeValue(g1); |
|
51 assertEq(dwg1.global, dg2); |
|
52 assertEq(dwg1.unwrap(), dg1); |
|
53 dwg1.toSource = function() { return "[Debugger.Object for CCW of global g1]"; }; |
|
54 |
|
55 assertDebuggees(dg1, dg2); |
|
56 assertEq(dbg.removeDebuggee(g1), undefined); |
|
57 assertEq(dbg.removeDebuggee(g2), undefined); |
|
58 assertDebuggees(); |
|
59 |
|
60 // Systematically cover all the single-global possibilities: |
|
61 // |
|
62 // | added as | designated as | addDebuggee | hasDebuggee | removeDebuggee | |
|
63 // |-------------+---------------+-------------+-------------+----------------| |
|
64 // | (not added) | CCW | X | X | X | |
|
65 // | | D.O | X | X | X | |
|
66 // | | D.O of CCW | X | X | X | |
|
67 // |-------------+---------------+-------------+-------------+----------------| |
|
68 // | CCW | CCW | X | X | X | |
|
69 // | | D.O | X | X | X | |
|
70 // | | D.O of CCW | X | X | X | |
|
71 // |-------------+---------------+-------------+-------------+----------------| |
|
72 // | D.O | CCW | X | X | X | |
|
73 // | | D.O | X | X | X | |
|
74 // | | D.O of CCW | X | X | X | |
|
75 // |-------------+---------------+-------------+-------------+----------------| |
|
76 // | D.O of CCW | CCW | X | X | X | |
|
77 // | | D.O | X | X | X | |
|
78 // | | D.O of CCW | X | X | X | |
|
79 |
|
80 // Cover the "(not added)" section of the table, other than "addDebuggee": |
|
81 assertEq(dbg.hasDebuggee(g1), false); |
|
82 assertEq(dbg.hasDebuggee(dg1), false); |
|
83 assertEq(dbg.hasDebuggee(dwg1), false); |
|
84 |
|
85 assertEq(dbg.removeDebuggee(g1), undefined); assertDebuggees(); |
|
86 assertEq(dbg.removeDebuggee(dg1), undefined); assertDebuggees(); |
|
87 assertEq(dbg.removeDebuggee(dwg1), undefined); assertDebuggees(); |
|
88 |
|
89 // Try all operations adding the debuggee using |addAs|, and operating on it |
|
90 // using |designateAs|, thereby covering one row of the table (outside the '(not |
|
91 // added)' section), and one case in the '(not added)', 'designated as' section. |
|
92 // |
|
93 // |Direct| should be the Debugger.Object referring directly to the debuggee |
|
94 // global, for checking the results from addDebuggee and getDebuggees. |
|
95 function combo(addAs, designateAs, direct) { |
|
96 print("combo(" + uneval(addAs) + ", " + uneval(designateAs) + ")"); |
|
97 assertDebuggees(); |
|
98 assertEq(dbg.addDebuggee(addAs), direct); |
|
99 assertDebuggees(direct); |
|
100 assertEq(dbg.addDebuggee(designateAs), direct); |
|
101 assertDebuggees(direct); |
|
102 assertEq(dbg.hasDebuggee(designateAs), true); |
|
103 assertEq(dbg.removeDebuggee(designateAs), undefined); |
|
104 assertDebuggees(); |
|
105 } |
|
106 |
|
107 combo(g1, g1, dg1); |
|
108 combo(dg1, g1, dg1); |
|
109 combo(dwg1, g1, dg1); |
|
110 |
|
111 combo(g1, dg1, dg1); |
|
112 combo(dg1, dg1, dg1); |
|
113 combo(dwg1, dg1, dg1); |
|
114 |
|
115 combo(g1, dwg1, dg1); |
|
116 combo(dg1, dwg1, dg1); |
|
117 combo(dwg1, dwg1, dg1); |