| <!doctype html> | |
| <html> | |
| <head> | |
| <script src="../../http/tests/inspector/resources/inspector-test.js"></script> | |
| <script src="../../http/tests/inspector/debugger/debugger-test.js"></script> | |
| <script src="./resources/tail-recursion.js"></script> | |
| <script> | |
| function test() | |
| { | |
| var scriptObject; | |
| function remoteObjectJSONFilter(key, value) { | |
| if (key === "_target" || key === "_listeners") | |
| return undefined; | |
| if (key === "_objectId" || key === "_stackTrace") | |
| return "<filtered>"; | |
| return value; | |
| } | |
| function startTest() { | |
| InspectorTest.log("Starting Test"); | |
| // 0 based indices. | |
| var testInfos = [{line : 3, column : 8}, {line : 4, column : 8}]; | |
| for (let testInfo of testInfos) { | |
| let location = scriptObject.createSourceCodeLocation(testInfo.line, testInfo.column); | |
| let breakpoint = new WI.JavaScriptBreakpoint(location); | |
| WI.debuggerManager.addBreakpoint(breakpoint); | |
| } | |
| InspectorTest.evaluateInPage("startRecurse()"); | |
| } | |
| let numBreakpointHits = 0; | |
| WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.CallFramesDidChange, function(event) { | |
| var activeCallFrame = WI.debuggerManager.activeCallFrame; | |
| if (!activeCallFrame) | |
| return; | |
| numBreakpointHits++; | |
| var stopLocation = "line: " + activeCallFrame.sourceCodeLocation.lineNumber + ", column: " + activeCallFrame.sourceCodeLocation.columnNumber; | |
| InspectorTest.log("\n\n------------------------------------"); | |
| InspectorTest.log("Hit breakpoint at " + stopLocation); | |
| InspectorTest.log("numBreakpointHits: " + numBreakpointHits); | |
| const numFramesToInspect = 50; | |
| InspectorTest.log("Going to look at the top " + numFramesToInspect + " frames."); | |
| InspectorTest.log("------------------------------------"); | |
| let targetData = WI.debuggerManager.dataForTarget(WI.debuggerManager.activeCallFrame.target); | |
| let callFrames = targetData.stackTrace.callFrames; | |
| InspectorTest.assert(callFrames.length > numFramesToInspect); // We just look at top 50. This isn't a precise number. But it gets at the gist of the debugging experience. | |
| for (let i = 0; i < numFramesToInspect; i++) { | |
| let callFrame = callFrames[i]; | |
| InspectorTest.assert(callFrame.functionName === "recurse"); | |
| let topScope = callFrame.scopeChain[0]; | |
| if (i > 0) | |
| InspectorTest.assert(callFrame.isTailDeleted); | |
| else | |
| InspectorTest.assert(!callFrame.isTailDeleted); | |
| topScope.objects[0].getPropertyDescriptors(function(properties) { | |
| let found = false; | |
| for (let propertyDescriptor of properties) { | |
| if (propertyDescriptor.name === 'i') { | |
| found = true; | |
| InspectorTest.log("Looking at frame number: " + i); | |
| InspectorTest.log(" variable 'i': " + JSON.stringify(propertyDescriptor.value, remoteObjectJSONFilter)); | |
| InspectorTest.assert(propertyDescriptor.value.type === 'number'); | |
| if (numBreakpointHits === 2 && i === 0) | |
| InspectorTest.assert(propertyDescriptor.value.value === i + 1); // this tests the i++ inside tail-recurse.js | |
| else | |
| InspectorTest.assert(propertyDescriptor.value.value === i); | |
| } | |
| } | |
| InspectorTest.assert(found); | |
| }); | |
| } | |
| WI.debuggerManager.resume(); | |
| }); | |
| WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.Resumed, function(event) { | |
| if (numBreakpointHits === 2) { | |
| InspectorTest.log("Tests done"); | |
| InspectorTest.completeTest(); | |
| } | |
| }); | |
| WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.ScriptAdded, function(event) { | |
| eventScriptObject = event.data.script; | |
| if (/tail-recursion\.js$/.test(eventScriptObject.url)) { | |
| scriptObject = eventScriptObject; | |
| startTest(); | |
| return; | |
| } | |
| }); | |
| InspectorTest.reloadPage(); | |
| } | |
| </script> | |
| </head> | |
| <body onload="runTest()"> | |
| <p>Testing that we keep around tail deleted frames in the inspector. </p> | |
| </body> | |
| </html> |