3 <script src="../../http/tests/inspector/inspector-test.js"></script>
9 var uiSourceCodes = {};
11 var defaultMapping = {
12 rawLocationToUILocation: function(rawLocation)
14 return new WebInspector.UILocation(uiSourceCodes[rawLocation.scriptId], rawLocation.lineNumber, 0);
17 uiLocationToRawLocation: function(uiSourceCode, lineNumber)
19 if (!uiSourceCodes[uiSourceCode.url])
21 return new WebInspector.DebuggerModel.Location(uiSourceCode.url, lineNumber, 0);
25 var shiftingMapping = {
26 rawLocationToUILocation: function(rawLocation)
30 return new WebInspector.UILocation(uiSourceCodes[rawLocation.scriptId], rawLocation.lineNumber + 10, 0);
33 uiLocationToRawLocation: function(uiSourceCode, lineNumber)
35 return new WebInspector.DebuggerModel.Location(uiSourceCode.url, lineNumber - 10, 0);
39 function createSourceMapping(uiSourceCodeA, uiSourceCodeB)
42 rawLocationToUILocation: function(rawLocation)
46 return new WebInspector.UILocation(uiSourceCodeB, rawLocation.lineNumber + 10, 0);
49 uiLocationToRawLocation: function(uiSourceCode, lineNumber)
51 return new WebInspector.DebuggerModel.Location(uiSourceCodeA.url, lineNumber - 10, 0);
58 function DebuggerModelMock(sourceMapping)
61 this._sourceMapping = sourceMapping;
62 this._breakpoints = {};
65 DebuggerModelMock.prototype = {
66 _addScript: function(scriptId, url)
68 this._scripts[scriptId] = new WebInspector.Script(scriptId, url);
69 this._scripts[scriptId].pushSourceMapping(this._sourceMapping);
72 _scriptForURL: function(url)
74 for (var scriptId in this._scripts) {
75 var script = this._scripts[scriptId];
76 if (script.sourceURL === url)
81 _scheduleSetBeakpointCallback: function(callback, breakpointId, locations)
83 setTimeout(innerCallback.bind(this), 0);
85 function innerCallback()
88 callback(breakpointId, locations);
89 if (window.setBreakpointCallback) {
90 var savedCallback = window.setBreakpointCallback;
91 delete window.setBreakpointCallback;
97 setBreakpointByURL: function(url, lineNumber, columnNumber, condition, callback)
99 InspectorTest.addResult(" debuggerModel.setBreakpoint(" + [url, lineNumber, condition].join(":") + ")");
101 var breakpointId = url + ":" + lineNumber;
102 if (this._breakpoints[breakpointId]) {
103 this._scheduleSetBeakpointCallback(callback, null);
106 this._breakpoints[breakpointId] = true;
109 var script = this._scriptForURL(url);
111 var location = new WebInspector.DebuggerModel.Location(script.scriptId, lineNumber, 0);
112 locations.push(location);
115 this._scheduleSetBeakpointCallback(callback, breakpointId, locations);
118 setBreakpointByScriptLocation: function(location, condition, callback)
120 InspectorTest.addResult(" debuggerModel.setBreakpoint(" + [location.scriptId, location.lineNumber, condition].join(":") + ")");
122 var breakpointId = location.scriptId + ":" + location.lineNumber;
123 if (this._breakpoints[breakpointId]) {
124 this._scheduleSetBeakpointCallback(callback, null);
127 this._breakpoints[breakpointId] = true;
129 if (location.lineNumber >= 2000) {
130 this._scheduleSetBeakpointCallback(callback, breakpointId, []);
133 if (location.lineNumber >= 1000) {
134 var shiftedLocation = {scriptId: location.scriptId, lineNumber: location.lineNumber + 10, columnNumber: location.columnNumber };
135 this._scheduleSetBeakpointCallback(callback, breakpointId, [shiftedLocation]);
139 this._scheduleSetBeakpointCallback(callback, breakpointId, [location]);
142 removeBreakpoint: function(breakpointId, callback)
144 InspectorTest.addResult(" debuggerModel.removeBreakpoint(" + breakpointId + ")");
145 delete this._breakpoints[breakpointId];
150 setBreakpointsActive: function() { },
152 createLiveLocation: function(rawLocation, updateDelegate)
154 return this._scripts[rawLocation.scriptId].createLiveLocation(rawLocation, updateDelegate);
157 scriptForId: function(scriptId)
159 return this._scripts[scriptId];
164 InspectorTest.addResult(" Resetting debugger.");
168 pushSourceMapping: function(sourceMapping)
170 for (var scriptId in this._scripts)
171 this._scripts[scriptId].pushSourceMapping(sourceMapping);
174 disableSourceMapping: function(sourceMapping)
176 sourceMapping._disabled = true;
177 for (var scriptId in this._scripts)
178 this._scripts[scriptId].updateLocations();
181 DebuggerModelMock.prototype.__proto__ = WebInspector.Object.prototype;
184 get: function() { return []; },
185 set: function(breakpoints) { }
188 function resetWorkspace(breakpointManager)
190 InspectorTest.addResult(" Resetting workspace.");
191 breakpointManager._networkWorkspaceProvider.reset();
192 breakpointManager._debuggerWorkspaceProvider.reset();
195 function breakpointAdded(event)
197 var breakpoint = event.data.breakpoint;
198 var uiLocation = event.data.uiLocation;
199 InspectorTest.addResult(" breakpointAdded(" + [uiLocation.uiSourceCode.originURL(), uiLocation.lineNumber, breakpoint.condition(), breakpoint.enabled()].join(", ") + ")");
202 function breakpointRemoved(event)
204 var uiLocation = event.data.uiLocation;
205 InspectorTest.addResult(" breakpointRemoved(" + [uiLocation.uiSourceCode.originURL(), uiLocation.lineNumber].join(", ") + ")");
208 InspectorTest.addSniffer(WebInspector.Script.prototype, "createLiveLocation", function(rawLocation)
210 InspectorTest.addResult(" Location created: " + rawLocation.scriptId + ":" + rawLocation.lineNumber);
212 InspectorTest.addSniffer(WebInspector.Script.Location.prototype, "dispose", function()
214 InspectorTest.addResult(" Location disposed: " + this._rawLocation.scriptId + ":" + this._rawLocation.lineNumber);
217 function addUISourceCode(breakpointManager, url, doNotSetSourceMapping)
219 breakpointManager._debuggerModel._addScript(url, url);
220 InspectorTest.addResult(" Adding UISourceCode: " + url);
221 var contentProvider = new WebInspector.StaticContentProvider(WebInspector.resourceTypes.Script, "");
222 var uiSourceCode = breakpointManager._networkWorkspaceProvider.addFileForURL(url, contentProvider, true);
223 uiSourceCodes[url] = uiSourceCode;
224 if (!doNotSetSourceMapping)
225 uiSourceCode.setSourceMapping(defaultMapping);
229 function addTemporaryUISourceCode(breakpointManager, url)
232 breakpointManager._debuggerModel._addScript(url, url);
233 InspectorTest.addResult(" Adding temporary UISourceCode: " + url);
234 var contentProvider = new WebInspector.StaticContentProvider(WebInspector.resourceTypes.Script, "");
235 var uiSourceCode = breakpointManager._debuggerWorkspaceProvider.addUniqueFileForURL(url, contentProvider, true);
236 uiSourceCode.setSourceMapping(defaultMapping);
237 uiSourceCodes[url] = uiSourceCode;
241 function createBreakpoint(uiSourceCodeId, lineNumber, condition, enabled)
243 return { sourceFileId: uiSourceCodeId, lineNumber: lineNumber, condition: condition, enabled: enabled };
246 var serializedBreakpoints = [];
247 serializedBreakpoints.push(createBreakpoint("a.js", 10, "foo == bar", true));
248 serializedBreakpoints.push(createBreakpoint("a.js", 20, "", false));
249 serializedBreakpoints.push(createBreakpoint("b.js", 3, "", true));
251 function createBreakpointManager(persistentBreakpoints, sourceMapping)
253 persistentBreakpoints = persistentBreakpoints || [];
255 get: function() { return persistentBreakpoints; },
256 set: function(breakpoints) { persistentBreakpoints = breakpoints; }
259 var sourceMapping = sourceMapping || defaultMapping;
260 var debuggerModel = new DebuggerModelMock(sourceMapping);
261 var workspace = new WebInspector.Workspace();
262 var breakpointManager = new WebInspector.BreakpointManager(setting, debuggerModel, workspace);
263 breakpointManager._networkWorkspaceProvider = new WebInspector.SimpleWorkspaceProvider(workspace, WebInspector.projectTypes.Network);
264 breakpointManager._debuggerWorkspaceProvider = new WebInspector.SimpleWorkspaceProvider(workspace, WebInspector.projectTypes.Debugger);
265 breakpointManager.addEventListener(WebInspector.BreakpointManager.Events.BreakpointAdded, breakpointAdded);
266 breakpointManager.addEventListener(WebInspector.BreakpointManager.Events.BreakpointRemoved, breakpointRemoved);
267 InspectorTest.addResult(" Created breakpoints manager");
268 dumpBreakpointStorage(breakpointManager);
269 return breakpointManager;
272 function setBreakpoint(breakpointManager, uiSourceCode, lineNumber, condition, enabled)
274 InspectorTest.addResult(" Setting breakpoint at " + uiSourceCode.originURL() + ":" + lineNumber + " enabled:" + enabled + " condition:" + condition);
275 return breakpointManager.setBreakpoint(uiSourceCode, lineNumber, condition, enabled);
278 function removeBreakpoint(breakpointManager, uiSourceCode, lineNumber)
280 InspectorTest.addResult(" Removing breakpoint at " + uiSourceCode.originURL() + ":" + lineNumber);
281 breakpointManager.findBreakpoint(uiSourceCode, lineNumber).remove();
284 function dumpBreakpointStorage(breakpointManager)
286 var breakpoints = breakpointManager._storage._setting.get();
287 InspectorTest.addResult(" Dumping Storage");
288 for (var i = 0; i < breakpoints.length; ++i)
289 InspectorTest.addResult(" " + breakpoints[i].sourceFileId + ":" + breakpoints[i].lineNumber + " enabled:" + breakpoints[i].enabled + " condition:" + breakpoints[i].condition);
292 function resetBreakpointManager(breakpointManager, next)
294 dumpBreakpointStorage(breakpointManager);
295 InspectorTest.addResult(" Resetting breakpoint manager");
296 breakpointManager.removeAllBreakpoints();
297 breakpointManager.removeProvisionalBreakpoints();
302 InspectorTest.runTestSuite([
303 function testSetBreakpoint(next)
305 var breakpointManager = createBreakpointManager();
306 var uiSourceCode = addUISourceCode(breakpointManager, "a.js");
307 setBreakpoint(breakpointManager, uiSourceCode, 30, "", true);
308 window.setBreakpointCallback = step2.bind(this);
312 resetBreakpointManager(breakpointManager, next);
316 function testSetDisabledBreakpoint(next)
318 var breakpointManager = createBreakpointManager();
319 var uiSourceCode = addUISourceCode(breakpointManager, "a.js");
320 var breakpoint = setBreakpoint(breakpointManager, uiSourceCode, 30, "", false);
321 dumpBreakpointStorage(breakpointManager);
322 InspectorTest.addResult(" Enabling breakpoint");
323 breakpoint.setEnabled(true);
324 window.setBreakpointCallback = step2.bind(this);
328 resetBreakpointManager(breakpointManager, next);
332 function testSetConditionalBreakpoint(next)
334 var breakpointManager = createBreakpointManager();
335 var uiSourceCode = addUISourceCode(breakpointManager, "a.js");
336 var breakpoint = setBreakpoint(breakpointManager, uiSourceCode, 30, "condition", true);
337 window.setBreakpointCallback = step2.bind(this);
341 dumpBreakpointStorage(breakpointManager);
342 InspectorTest.addResult(" Updating condition");
343 breakpoint.setCondition("");
344 window.setBreakpointCallback = step3.bind(this);
349 resetBreakpointManager(breakpointManager, next);
353 function testRestoreBreakpoints(next)
355 var breakpointManager = createBreakpointManager(serializedBreakpoints);
356 addUISourceCode(breakpointManager, "a.js");
357 window.setBreakpointCallback = step2.bind(this);
361 resetBreakpointManager(breakpointManager, next);
365 function testRestoreBreakpointsTwice(next)
367 var breakpointManager = createBreakpointManager(serializedBreakpoints);
368 addUISourceCode(breakpointManager, "a.js");
369 addUISourceCode(breakpointManager, "a.js");
370 window.setBreakpointCallback = step2.bind(this);
374 resetBreakpointManager(breakpointManager, next);
378 function testRemoveBreakpoints(next)
380 var breakpointManager = createBreakpointManager(serializedBreakpoints);
381 var uiSourceCode = addUISourceCode(breakpointManager, "a.js");
382 window.setBreakpointCallback = step2.bind(this);
386 setBreakpoint(breakpointManager, uiSourceCode, 30, "", true);
387 window.setBreakpointCallback = step3.bind(this);
392 removeBreakpoint(breakpointManager, uiSourceCode, 30);
393 removeBreakpoint(breakpointManager, uiSourceCode, 10);
394 removeBreakpoint(breakpointManager, uiSourceCode, 20);
395 resetBreakpointManager(breakpointManager, next);
399 function testSetBreakpointThatShifts(next)
401 var breakpointManager = createBreakpointManager();
402 var uiSourceCode = addUISourceCode(breakpointManager, "a.js");
403 setBreakpoint(breakpointManager, uiSourceCode, 1015, "", true);
404 window.setBreakpointCallback = step2.bind(this);
408 resetBreakpointManager(breakpointManager, next);
412 function testSetBreakpointThatShiftsTwice(next)
414 var breakpointManager = createBreakpointManager();
415 var uiSourceCode = addUISourceCode(breakpointManager, "a.js");
416 setBreakpoint(breakpointManager, uiSourceCode, 1015, "", true);
417 window.setBreakpointCallback = step2.bind(this);
421 setBreakpoint(breakpointManager, uiSourceCode, 1015, "", true);
422 window.setBreakpointCallback = step3.bind(this);
427 resetBreakpointManager(breakpointManager, next);
431 function testSetBreakpointOutsideScript(next)
433 var breakpointManager = createBreakpointManager([]);
434 var uiSourceCode = addUISourceCode(breakpointManager, "a.js");
435 breakpointManager.setBreakpoint(uiSourceCode, 2500, "", true);
436 window.setBreakpointCallback = step2.bind(this);
440 resetBreakpointManager(breakpointManager, next);
444 function testNavigation(next)
446 var breakpointManager = createBreakpointManager(serializedBreakpoints);
447 var uiSourceCodeA = addUISourceCode(breakpointManager, "a.js");
448 window.setBreakpointCallback = step2.bind(this);
452 InspectorTest.addResult("\n Navigating to B.");
453 breakpointManager._debuggerModel.reset();
454 resetWorkspace(breakpointManager);
455 var uiSourceCodeB = addUISourceCode(breakpointManager, "b.js");
456 window.setBreakpointCallback = step3.bind(this);
461 InspectorTest.addResult("\n Navigating back to A.");
462 breakpointManager._debuggerModel.reset();
463 resetWorkspace(breakpointManager);
464 InspectorTest.addResult(" Resolving provisional breakpoint.");
465 addTemporaryUISourceCode(breakpointManager, "a.js");
466 var eventData = { breakpointId: "a.js:10", location: { scriptId: "a.js", lineNumber: 11, columnNumber: 5 }};
467 breakpointManager._debuggerModel.dispatchEventToListeners(WebInspector.DebuggerModel.Events.BreakpointResolved, eventData);
468 addUISourceCode(breakpointManager, "a.js");
469 window.setBreakpointCallback = step4.bind(this);
474 resetBreakpointManager(breakpointManager, next);
478 function testSourceMapping(next)
480 // Source mapping will shift everthing 10 lines ahead so that breakpoint 1 clashed with breakpoint 2.
481 var serializedBreakpoints = [];
482 serializedBreakpoints.push(createBreakpoint("a.js", 10, "foo == bar", true));
483 serializedBreakpoints.push(createBreakpoint("a.js", 20, "", true));
485 var breakpointManager = createBreakpointManager(serializedBreakpoints);
486 var uiSourceCodeA = addUISourceCode(breakpointManager, "a.js");
487 window.setBreakpointCallback = step2.bind(this);
491 window.setBreakpointCallback = step3.bind(this);
496 InspectorTest.addResult("\n Toggling source mapping.");
497 breakpointManager._debuggerModel.pushSourceMapping(shiftingMapping);
498 InspectorTest.addResult("\n Toggling source mapping back.");
499 breakpointManager._debuggerModel.disableSourceMapping(shiftingMapping);
500 resetBreakpointManager(breakpointManager, next);
504 function testProvisionalBreakpointsResolve(next)
506 var serializedBreakpoints = [];
507 serializedBreakpoints.push(createBreakpoint("a.js", 10, "foo == bar", true));
509 var breakpointManager = createBreakpointManager(serializedBreakpoints);
510 var uiSourceCode = addUISourceCode(breakpointManager, "a.js");
511 window.setBreakpointCallback = step2.bind(this);
515 breakpointManager._debuggerModel.reset();
516 resetWorkspace(breakpointManager);
517 InspectorTest.addResult(" Resolving provisional breakpoint.");
518 addTemporaryUISourceCode(breakpointManager, "a.js")
519 var eventData = { breakpointId: "a.js:10", location: { scriptId: "a.js", lineNumber: 11, columnNumber: 5 }};
520 breakpointManager._debuggerModel.dispatchEventToListeners(WebInspector.DebuggerModel.Events.BreakpointResolved, eventData);
521 var breakpoints = breakpointManager.allBreakpoints();
522 InspectorTest.assertEquals(breakpoints.length, 1, "Exactly one provisional breakpoint should be registered in breakpoint manager.");
523 resetBreakpointManager(breakpointManager, next);
527 function testSourceMappingReload(next)
529 // Source mapping will shift everthing 10 lines ahead.
530 var serializedBreakpoints = [createBreakpoint("b.js", 20, "foo == bar", true)];
531 var breakpointManager = createBreakpointManager(serializedBreakpoints);
532 InspectorTest.addResult("\n Adding files:");
533 var uiSourceCodeA = addUISourceCode(breakpointManager, "a.js");
534 var uiSourceCodeB = addUISourceCode(breakpointManager, "b.js", true);
535 InspectorTest.addResult("\n Toggling source mapping.");
536 var sourceMapping = createSourceMapping(uiSourceCodeA, uiSourceCodeB);
537 breakpointManager._debuggerModel.pushSourceMapping(sourceMapping);
538 window.setBreakpointCallback = step2.bind(this);
539 uiSourceCodeB.setSourceMapping(sourceMapping);
543 InspectorTest.addResult("\n Reloading:");
544 breakpointManager._debuggerModel.reset();
545 resetWorkspace(breakpointManager);
547 InspectorTest.addResult("\n Adding files:");
548 addTemporaryUISourceCode(breakpointManager, "a.js");
549 var eventData = { breakpointId: "a.js:10", location: { scriptId: "a.js", lineNumber: 10, columnNumber: 5 }};
550 breakpointManager._debuggerModel.dispatchEventToListeners(WebInspector.DebuggerModel.Events.BreakpointResolved, eventData);
551 uiSourceCodeA = addUISourceCode(breakpointManager, "a.js");
552 uiSourceCodeB = addUISourceCode(breakpointManager, "b.js", true);
553 InspectorTest.addResult("\n Toggling source mapping.");
554 var sourceMapping = createSourceMapping(uiSourceCodeA, uiSourceCodeB);
555 breakpointManager._debuggerModel.pushSourceMapping(sourceMapping);
556 window.setBreakpointCallback = step3.bind(this);
557 uiSourceCodeB.setSourceMapping(sourceMapping);
562 resetBreakpointManager(breakpointManager, next);
572 <body onload="runTest()">
573 <p>Tests BreakpointManager class.</p>