| <html> |
| <head> |
| <script src="../../http/tests/inspector/inspector-test.js"></script> |
| |
| <script> |
| |
| function test() |
| { |
| var uiSourceCodes = {}; |
| |
| var defaultMapping = { |
| rawLocationToUILocation: function(rawLocation) |
| { |
| return new WebInspector.UILocation(uiSourceCodes[rawLocation.scriptId], rawLocation.lineNumber, 0); |
| }, |
| |
| uiLocationToRawLocation: function(uiSourceCode, lineNumber) |
| { |
| if (!uiSourceCodes[uiSourceCode.url]) |
| return null; |
| return new WebInspector.DebuggerModel.Location(uiSourceCode.url, lineNumber, 0); |
| }, |
| |
| isIdentity: function() |
| { |
| return true; |
| } |
| }; |
| |
| var shiftingMapping = { |
| rawLocationToUILocation: function(rawLocation) |
| { |
| if (this._disabled) |
| return null; |
| return new WebInspector.UILocation(uiSourceCodes[rawLocation.scriptId], rawLocation.lineNumber + 10, 0); |
| }, |
| |
| uiLocationToRawLocation: function(uiSourceCode, lineNumber) |
| { |
| return new WebInspector.DebuggerModel.Location(uiSourceCode.url, lineNumber - 10, 0); |
| }, |
| |
| isIdentity: function() |
| { |
| return false; |
| } |
| }; |
| |
| function DebuggerModelMock(sourceMapping) |
| { |
| this._scripts = {}; |
| this._sourceMapping = sourceMapping; |
| this._breakpoints = {}; |
| } |
| |
| DebuggerModelMock.prototype = { |
| _addScript: function(scriptId, url) |
| { |
| this._scripts[scriptId] = new WebInspector.Script(scriptId, url); |
| this._scripts[scriptId].pushSourceMapping(this._sourceMapping); |
| }, |
| |
| _scriptForURL: function(url) |
| { |
| for (var scriptId in this._scripts) { |
| var script = this._scripts[scriptId]; |
| if (script.sourceURL === url) |
| return script; |
| } |
| }, |
| |
| _scheduleSetBeakpointCallback: function(callback, breakpointId, locations) |
| { |
| setTimeout(innerCallback.bind(this), 0); |
| |
| function innerCallback() |
| { |
| if (callback) |
| callback(breakpointId, locations); |
| if (window.setBreakpointCallback) { |
| var savedCallback = window.setBreakpointCallback; |
| delete window.setBreakpointCallback; |
| savedCallback(); |
| } |
| } |
| }, |
| |
| setBreakpointByURL: function(url, lineNumber, columnNumber, condition, callback) |
| { |
| var breakpointId = url + ":" + lineNumber; |
| if (this._breakpoints[breakpointId]) { |
| this._scheduleSetBeakpointCallback(callback, null); |
| return; |
| } |
| |
| this._breakpoints[breakpointId] = true; |
| InspectorTest.addResult(" debuggerModel.setBreakpoint(" + [url, lineNumber, condition].join(":") + ")"); |
| |
| var locations = []; |
| var script = this._scriptForURL(url); |
| if (script) { |
| var location = new WebInspector.DebuggerModel.Location(script.scriptId, lineNumber, 0); |
| locations.push(location); |
| } |
| |
| this._scheduleSetBeakpointCallback(callback, breakpointId, locations); |
| }, |
| |
| setBreakpointByScriptLocation: function(location, condition, callback) |
| { |
| var breakpointId = location.scriptId + ":" + location.lineNumber; |
| if (this._breakpoints[breakpointId]) { |
| this._scheduleSetBeakpointCallback(callback, null); |
| return; |
| } |
| |
| this._breakpoints[breakpointId] = true; |
| InspectorTest.addResult(" debuggerModel.setBreakpoint(" + [location.scriptId, location.lineNumber, condition].join(":") + ")"); |
| |
| if (location.lineNumber >= 2000) { |
| this._scheduleSetBeakpointCallback(callback, breakpointId, []); |
| return; |
| } |
| if (location.lineNumber >= 1000) { |
| var shiftedLocation = {scriptId: location.scriptId, lineNumber: location.lineNumber + 10, columnNumber: location.columnNumber }; |
| this._scheduleSetBeakpointCallback(callback, breakpointId, [shiftedLocation]); |
| return; |
| } |
| |
| this._scheduleSetBeakpointCallback(callback, breakpointId, [location]); |
| }, |
| |
| removeBreakpoint: function(breakpointId, callback) |
| { |
| InspectorTest.addResult(" debuggerModel.removeBreakpoint(" + breakpointId + ")"); |
| delete this._breakpoints[breakpointId]; |
| if (callback) |
| callback(); |
| }, |
| |
| setBreakpointsActive: function() { }, |
| |
| createLiveLocation: function(rawLocation, updateDelegate) |
| { |
| return this._scripts[rawLocation.scriptId].createLiveLocation(rawLocation, updateDelegate); |
| }, |
| |
| scriptForId: function(scriptId) |
| { |
| return this._scripts[scriptId]; |
| }, |
| |
| reset: function() |
| { |
| InspectorTest.addResult(" Resetting debugger."); |
| this._scripts = {}; |
| }, |
| |
| pushSourceMapping: function(sourceMapping) |
| { |
| for (var scriptId in this._scripts) |
| this._scripts[scriptId].pushSourceMapping(sourceMapping); |
| }, |
| |
| disableSourceMapping: function(sourceMapping) |
| { |
| sourceMapping._disabled = true; |
| for (var scriptId in this._scripts) |
| this._scripts[scriptId].updateLocations(); |
| } |
| } |
| DebuggerModelMock.prototype.__proto__ = WebInspector.Object.prototype; |
| |
| var dummySetting = { |
| get: function() { return []; }, |
| set: function(breakpoints) { } |
| }; |
| |
| function resetWorkspace(breakpointManager) |
| { |
| InspectorTest.addResult(" Resetting workspace."); |
| breakpointManager._networkWorkspaceProvider.reset(); |
| breakpointManager._debuggerWorkspaceProvider.reset(); |
| } |
| |
| function breakpointAdded(event) |
| { |
| var breakpoint = event.data.breakpoint; |
| var uiLocation = event.data.uiLocation; |
| InspectorTest.addResult(" breakpointAdded(" + [uiLocation.uiSourceCode.originURL(), uiLocation.lineNumber, breakpoint.condition(), breakpoint.enabled()].join(", ") + ")"); |
| } |
| |
| function breakpointRemoved(event) |
| { |
| var uiLocation = event.data.uiLocation; |
| InspectorTest.addResult(" breakpointRemoved(" + [uiLocation.uiSourceCode.originURL(), uiLocation.lineNumber].join(", ") + ")"); |
| } |
| |
| InspectorTest.addSniffer(WebInspector.Script.prototype, "createLiveLocation", function(rawLocation) |
| { |
| InspectorTest.addResult(" Location created: " + rawLocation.scriptId + ":" + rawLocation.lineNumber); |
| }, true); |
| InspectorTest.addSniffer(WebInspector.Script.Location.prototype, "dispose", function() |
| { |
| InspectorTest.addResult(" Location disposed: " + this._rawLocation.scriptId + ":" + this._rawLocation.lineNumber); |
| }, true); |
| |
| function addUISourceCode(breakpointManager, url) |
| { |
| breakpointManager._debuggerModel._addScript(url, url); |
| InspectorTest.addResult(" Adding UISourceCode: " + url); |
| var contentProvider = new WebInspector.StaticContentProvider(WebInspector.resourceTypes.Script, "", "text/javascript"); |
| var uiSourceCode = breakpointManager._networkWorkspaceProvider.addFileForURL(url, contentProvider, true); |
| uiSourceCodes[url] = uiSourceCode; |
| uiSourceCode.setSourceMapping(defaultMapping); |
| return uiSourceCode; |
| } |
| |
| function addTemporaryUISourceCode(breakpointManager, url) |
| { |
| |
| breakpointManager._debuggerModel._addScript(url, url); |
| InspectorTest.addResult(" Adding temporary UISourceCode: " + url); |
| var contentProvider = new WebInspector.StaticContentProvider(WebInspector.resourceTypes.Script, "", "text/javascript"); |
| var uiSourceCode = breakpointManager._debuggerWorkspaceProvider.addUniqueFileForURL(url, contentProvider, true); |
| uiSourceCode.setSourceMapping(defaultMapping); |
| uiSourceCodes[url] = uiSourceCode; |
| return uiSourceCode; |
| } |
| |
| function createBreakpoint(uiSourceCodeId, lineNumber, condition, enabled) |
| { |
| return { sourceFileId: uiSourceCodeId, lineNumber: lineNumber, condition: condition, enabled: enabled }; |
| } |
| |
| var serializedBreakpoints = []; |
| serializedBreakpoints.push(createBreakpoint("a.js", 10, "foo == bar", true)); |
| serializedBreakpoints.push(createBreakpoint("a.js", 20, "", false)); |
| serializedBreakpoints.push(createBreakpoint("b.js", 3, "", true)); |
| |
| function createBreakpointManager(persistentBreakpoints, sourceMapping) |
| { |
| persistentBreakpoints = persistentBreakpoints || []; |
| var setting = { |
| get: function() { return persistentBreakpoints; }, |
| set: function(breakpoints) { persistentBreakpoints = breakpoints; } |
| }; |
| |
| var sourceMapping = sourceMapping || defaultMapping; |
| var debuggerModel = new DebuggerModelMock(sourceMapping); |
| var workspace = new WebInspector.Workspace(); |
| var breakpointManager = new WebInspector.BreakpointManager(setting, debuggerModel, workspace); |
| breakpointManager._networkWorkspaceProvider = new WebInspector.SimpleWorkspaceProvider(workspace, WebInspector.projectTypes.Network); |
| breakpointManager._debuggerWorkspaceProvider = new WebInspector.SimpleWorkspaceProvider(workspace, WebInspector.projectTypes.Debugger); |
| breakpointManager.addEventListener(WebInspector.BreakpointManager.Events.BreakpointAdded, breakpointAdded); |
| breakpointManager.addEventListener(WebInspector.BreakpointManager.Events.BreakpointRemoved, breakpointRemoved); |
| InspectorTest.addResult(" Created breakpoints manager"); |
| dumpBreakpointStorage(breakpointManager); |
| return breakpointManager; |
| } |
| |
| function setBreakpoint(breakpointManager, uiSourceCode, lineNumber, condition, enabled) |
| { |
| InspectorTest.addResult(" Setting breakpoint at " + uiSourceCode.originURL() + ":" + lineNumber + " enabled:" + enabled + " condition:" + condition); |
| return breakpointManager.setBreakpoint(uiSourceCode, lineNumber, condition, enabled); |
| } |
| |
| function removeBreakpoint(breakpointManager, uiSourceCode, lineNumber) |
| { |
| InspectorTest.addResult(" Removing breakpoint at " + uiSourceCode.originURL() + ":" + lineNumber); |
| breakpointManager.findBreakpoint(uiSourceCode, lineNumber).remove(); |
| } |
| |
| function dumpBreakpointStorage(breakpointManager) |
| { |
| var breakpoints = breakpointManager._storage._setting.get(); |
| InspectorTest.addResult(" Dumping Storage"); |
| for (var i = 0; i < breakpoints.length; ++i) |
| InspectorTest.addResult(" " + breakpoints[i].sourceFileId + ":" + breakpoints[i].lineNumber + " enabled:" + breakpoints[i].enabled + " condition:" + breakpoints[i].condition); |
| } |
| |
| function resetBreakpointManager(breakpointManager, next) |
| { |
| dumpBreakpointStorage(breakpointManager); |
| InspectorTest.addResult(" Resetting breakpoint manager"); |
| breakpointManager.reset(); |
| uiSourceCodes = {}; |
| next(); |
| } |
| |
| InspectorTest.runTestSuite([ |
| function testSetBreakpoint(next) |
| { |
| var breakpointManager = createBreakpointManager(); |
| var uiSourceCode = addUISourceCode(breakpointManager, "a.js"); |
| setBreakpoint(breakpointManager, uiSourceCode, 30, "", true); |
| window.setBreakpointCallback = step2.bind(this); |
| |
| function step2() |
| { |
| resetBreakpointManager(breakpointManager, next); |
| } |
| }, |
| |
| function testSetDisabledBreakpoint(next) |
| { |
| var breakpointManager = createBreakpointManager(); |
| var uiSourceCode = addUISourceCode(breakpointManager, "a.js"); |
| var breakpoint = setBreakpoint(breakpointManager, uiSourceCode, 30, "", false); |
| dumpBreakpointStorage(breakpointManager); |
| InspectorTest.addResult(" Enabling breakpoint"); |
| breakpoint.setEnabled(true); |
| window.setBreakpointCallback = step2.bind(this); |
| |
| function step2() |
| { |
| resetBreakpointManager(breakpointManager, next); |
| } |
| }, |
| |
| function testSetConditionalBreakpoint(next) |
| { |
| var breakpointManager = createBreakpointManager(); |
| var uiSourceCode = addUISourceCode(breakpointManager, "a.js"); |
| var breakpoint = setBreakpoint(breakpointManager, uiSourceCode, 30, "condition", true); |
| window.setBreakpointCallback = step2.bind(this); |
| |
| function step2() |
| { |
| dumpBreakpointStorage(breakpointManager); |
| InspectorTest.addResult(" Updating condition"); |
| breakpoint.setCondition(""); |
| window.setBreakpointCallback = step3.bind(this); |
| } |
| |
| function step3() |
| { |
| resetBreakpointManager(breakpointManager, next); |
| } |
| }, |
| |
| function testRestoreBreakpoints(next) |
| { |
| var breakpointManager = createBreakpointManager(serializedBreakpoints); |
| addUISourceCode(breakpointManager, "a.js"); |
| window.setBreakpointCallback = step2.bind(this); |
| |
| function step2() |
| { |
| resetBreakpointManager(breakpointManager, next); |
| } |
| }, |
| |
| function testRestoreBreakpointsTwice(next) |
| { |
| var breakpointManager = createBreakpointManager(serializedBreakpoints); |
| addUISourceCode(breakpointManager, "a.js"); |
| addUISourceCode(breakpointManager, "a.js"); |
| window.setBreakpointCallback = step2.bind(this); |
| |
| function step2() |
| { |
| resetBreakpointManager(breakpointManager, next); |
| } |
| }, |
| |
| function testRemoveBreakpoints(next) |
| { |
| var breakpointManager = createBreakpointManager(serializedBreakpoints); |
| var uiSourceCode = addUISourceCode(breakpointManager, "a.js"); |
| window.setBreakpointCallback = step2.bind(this); |
| |
| function step2() |
| { |
| setBreakpoint(breakpointManager, uiSourceCode, 30, "", true); |
| window.setBreakpointCallback = step3.bind(this); |
| } |
| |
| function step3() |
| { |
| removeBreakpoint(breakpointManager, uiSourceCode, 30); |
| removeBreakpoint(breakpointManager, uiSourceCode, 10); |
| removeBreakpoint(breakpointManager, uiSourceCode, 20); |
| resetBreakpointManager(breakpointManager, next); |
| } |
| }, |
| |
| function testSetBreakpointThatShifts(next) |
| { |
| var breakpointManager = createBreakpointManager(); |
| var uiSourceCode = addUISourceCode(breakpointManager, "a.js"); |
| setBreakpoint(breakpointManager, uiSourceCode, 1015, "", true); |
| window.setBreakpointCallback = step2.bind(this); |
| |
| function step2() |
| { |
| resetBreakpointManager(breakpointManager, next); |
| } |
| }, |
| |
| function testSetBreakpointThatShiftsTwice(next) |
| { |
| var breakpointManager = createBreakpointManager(); |
| var uiSourceCode = addUISourceCode(breakpointManager, "a.js"); |
| setBreakpoint(breakpointManager, uiSourceCode, 1015, "", true); |
| window.setBreakpointCallback = step2.bind(this); |
| |
| function step2() |
| { |
| setBreakpoint(breakpointManager, uiSourceCode, 1015, "", true); |
| window.setBreakpointCallback = step3.bind(this); |
| } |
| |
| function step3() |
| { |
| resetBreakpointManager(breakpointManager, next); |
| } |
| }, |
| |
| function testSetBreakpointOutsideScript(next) |
| { |
| var breakpointManager = createBreakpointManager([]); |
| var uiSourceCode = addUISourceCode(breakpointManager, "a.js"); |
| breakpointManager.setBreakpoint(uiSourceCode, 2500, "", true); |
| window.setBreakpointCallback = step2.bind(this); |
| |
| function step2() |
| { |
| resetBreakpointManager(breakpointManager, next); |
| } |
| }, |
| |
| function testNavigation(next) |
| { |
| var breakpointManager = createBreakpointManager(serializedBreakpoints); |
| var uiSourceCodeA = addUISourceCode(breakpointManager, "a.js"); |
| window.setBreakpointCallback = step2.bind(this); |
| |
| function step2() |
| { |
| InspectorTest.addResult("\n Navigating to B."); |
| breakpointManager._debuggerModel.reset(); |
| resetWorkspace(breakpointManager); |
| var uiSourceCodeB = addUISourceCode(breakpointManager, "b.js"); |
| window.setBreakpointCallback = step3.bind(this); |
| } |
| |
| function step3() |
| { |
| InspectorTest.addResult("\n Navigating back to A."); |
| breakpointManager._debuggerModel.reset(); |
| resetWorkspace(breakpointManager); |
| InspectorTest.addResult(" Resolving provisional breakpoint."); |
| addTemporaryUISourceCode(breakpointManager, "a.js") |
| var eventData = { breakpointId: "a.js:10", location: { scriptId: "a.js", lineNumber: 11, columnNumber: 5 }}; |
| breakpointManager._debuggerModel.dispatchEventToListeners(WebInspector.DebuggerModel.Events.BreakpointResolved, eventData); |
| addUISourceCode(breakpointManager, "a.js"); |
| window.setBreakpointCallback = step4.bind(this); |
| } |
| |
| function step4() |
| { |
| resetBreakpointManager(breakpointManager, next); |
| } |
| }, |
| |
| function testSourceMapping(next) |
| { |
| // Source mapping will shift everthing 10 lines ahead so that breakpoint 1 clashed with breakpoint 2. |
| var serializedBreakpoints = []; |
| serializedBreakpoints.push(createBreakpoint("a.js", 10, "foo == bar", true)); |
| serializedBreakpoints.push(createBreakpoint("a.js", 20, "", true)); |
| |
| var breakpointManager = createBreakpointManager(serializedBreakpoints); |
| var uiSourceCodeA = addUISourceCode(breakpointManager, "a.js"); |
| window.setBreakpointCallback = step2.bind(this); |
| |
| function step2() |
| { |
| window.setBreakpointCallback = step3.bind(this); |
| } |
| |
| function step3() |
| { |
| InspectorTest.addResult("\n Toggling source mapping."); |
| breakpointManager._debuggerModel.pushSourceMapping(shiftingMapping); |
| InspectorTest.addResult("\n Toggling source mapping back."); |
| breakpointManager._debuggerModel.disableSourceMapping(shiftingMapping); |
| resetBreakpointManager(breakpointManager, next); |
| } |
| }, |
| |
| function testProvisionalBreakpointsResolve(next) |
| { |
| var serializedBreakpoints = []; |
| serializedBreakpoints.push(createBreakpoint("a.js", 10, "foo == bar", true)); |
| |
| var breakpointManager = createBreakpointManager(serializedBreakpoints); |
| var uiSourceCode = addUISourceCode(breakpointManager, "a.js"); |
| window.setBreakpointCallback = step2.bind(this); |
| |
| function step2() |
| { |
| breakpointManager._debuggerModel.reset(); |
| resetWorkspace(breakpointManager); |
| InspectorTest.addResult(" Resolving provisional breakpoint."); |
| addTemporaryUISourceCode(breakpointManager, "a.js") |
| var eventData = { breakpointId: "a.js:10", location: { scriptId: "a.js", lineNumber: 11, columnNumber: 5 }}; |
| breakpointManager._debuggerModel.dispatchEventToListeners(WebInspector.DebuggerModel.Events.BreakpointResolved, eventData); |
| var breakpoints = breakpointManager._breakpoints.keys(); |
| InspectorTest.assertEquals(breakpoints.length, 1, "Exactly one breakpoint should be registered in breakpoint manager."); |
| InspectorTest.assertTrue(!breakpoints[0]._primaryUILocation, "_primaryUILocation field should be cleared for provisional breapoint."); |
| resetBreakpointManager(breakpointManager, next); |
| } |
| } |
| ]); |
| }; |
| |
| </script> |
| |
| </head> |
| |
| <body onload="runTest()"> |
| <p>Tests BreakpointManager class.</p> |
| |
| </body> |
| </html> |