test_protocol_watchFronts.js (3917B)
1 /* Any copyright is dedicated to the Public Domain. 2 http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 /** 7 * Test Front.watchFronts method. 8 */ 9 10 const protocol = require("resource://devtools/shared/protocol.js"); 11 const { RetVal } = protocol; 12 13 const childSpec = protocol.generateActorSpec({ 14 typeName: "childActor", 15 16 methods: { 17 release: { 18 release: true, 19 }, 20 }, 21 }); 22 23 class ChildActor extends protocol.Actor { 24 constructor(conn, id) { 25 super(conn, childSpec); 26 this.childID = id; 27 } 28 29 release() {} 30 31 form() { 32 return { 33 actor: this.actorID, 34 childID: this.childID, 35 foo: "bar", 36 }; 37 } 38 } 39 40 const rootSpec = protocol.generateActorSpec({ 41 typeName: "root", 42 43 methods: { 44 createChild: { 45 request: {}, 46 response: { actor: RetVal("childActor") }, 47 }, 48 }, 49 }); 50 51 class RootActor extends protocol.Actor { 52 constructor(conn) { 53 super(conn, rootSpec); 54 55 this.actorID = "root"; 56 57 // Root actor owns itself. 58 this.manage(this); 59 60 this.sequence = 0; 61 } 62 63 sayHello() { 64 return { 65 from: "root", 66 applicationType: "xpcshell-tests", 67 traits: [], 68 }; 69 } 70 71 createChild() { 72 return new ChildActor(this.conn, this.sequence++); 73 } 74 } 75 76 class ChildFront extends protocol.FrontClassWithSpec(childSpec) { 77 form(form) { 78 this.childID = form.childID; 79 this.foo = form.foo; 80 } 81 } 82 protocol.registerFront(ChildFront); 83 84 class RootFront extends protocol.FrontClassWithSpec(rootSpec) { 85 constructor(client) { 86 super(client); 87 this.actorID = "root"; 88 // Root owns itself. 89 this.manage(this); 90 } 91 92 connect() {} 93 } 94 protocol.registerFront(RootFront); 95 96 add_task(async function run_test() { 97 DevToolsServer.createRootActor = conn => new RootActor(conn); 98 DevToolsServer.init(); 99 100 const trace = connectPipeTracing(); 101 const client = new DevToolsClient(trace); 102 await client.connect(); 103 104 const rootFront = client.mainRoot; 105 106 const fronts = []; 107 const listener = front => { 108 equal( 109 front.foo, 110 "bar", 111 "Front's form is set before watchFronts listeners are called" 112 ); 113 fronts.push(front); 114 }; 115 rootFront.watchFronts("childActor", listener); 116 117 const firstChild = await rootFront.createChild(); 118 ok( 119 firstChild instanceof ChildFront, 120 "createChild returns a ChildFront instance" 121 ); 122 equal(firstChild.childID, 0, "First child has ID=0"); 123 124 equal( 125 fronts.length, 126 1, 127 "watchFronts fires the callback, even if the front is created in the future" 128 ); 129 equal( 130 fronts[0], 131 firstChild, 132 "watchFronts fires the callback with the right front instance" 133 ); 134 135 const watchFrontsAfter = await new Promise(resolve => { 136 rootFront.watchFronts("childActor", resolve); 137 }); 138 equal( 139 watchFrontsAfter, 140 firstChild, 141 "watchFronts fires the callback, even if the front is already created, " + 142 " with the same front instance" 143 ); 144 145 equal( 146 fronts.length, 147 1, 148 "There is still only one front reported from the first listener" 149 ); 150 151 const secondChild = await rootFront.createChild(); 152 153 equal( 154 fronts.length, 155 2, 156 "After a second call to createChild, two fronts are reported" 157 ); 158 equal(fronts[1], secondChild, "And the new front is the right instance"); 159 160 // Test unregistering a front listener 161 rootFront.unwatchFronts("childActor", listener); 162 163 const thirdChild = await rootFront.createChild(); 164 equal( 165 fronts.length, 166 2, 167 "After calling unwatchFronts, the listener is no longer called" 168 ); 169 170 // Test front destruction 171 const destroyed = []; 172 rootFront.watchFronts("childActor", null, front => { 173 destroyed.push(front); 174 }); 175 await thirdChild.release(); 176 equal( 177 destroyed.length, 178 1, 179 "After the destruction of the front, one destruction is reported" 180 ); 181 equal(destroyed[0], thirdChild, "And the destroyed front is the right one"); 182 183 trace.close(); 184 await client.close(); 185 });