michael@0: // getLineOffsets identifies multiple ways to land on a line. michael@0: michael@0: var g = newGlobal(); michael@0: g.line0 = null; michael@0: var dbg = Debugger(g); michael@0: var where; michael@0: dbg.onDebuggerStatement = function (frame) { michael@0: var s = frame.script, lineno, offs; michael@0: michael@0: lineno = g.line0 + where; michael@0: offs = s.getLineOffsets(lineno); michael@0: for (var i = 0; i < offs.length; i++) { michael@0: assertEq(s.getOffsetLine(offs[i]), lineno); michael@0: s.setBreakpoint(offs[i], {hit: function () { g.log += 'B'; }}); michael@0: } michael@0: michael@0: lineno++; michael@0: offs = s.getLineOffsets(lineno); michael@0: for (var i = 0; i < offs.length; i++) { michael@0: assertEq(s.getOffsetLine(offs[i]), lineno); michael@0: s.setBreakpoint(offs[i], {hit: function () { g.log += 'C'; }}); michael@0: } michael@0: michael@0: g.log += 'A'; michael@0: }; michael@0: michael@0: function test(s) { michael@0: assertEq(s.charAt(s.length - 1), '\n'); michael@0: var count = (s.split(/\n/).length - 1); // number of lines in s michael@0: g.log = ''; michael@0: where = 1 + count; michael@0: g.eval("line0 = Error().lineNumber;\n" + michael@0: "debugger;\n" + // line0 + 1 michael@0: s + // line0 + 2 ... line0 + where michael@0: "log += 'D';\n"); michael@0: assertEq(g.log, 'AB!CD'); michael@0: } michael@0: michael@0: // if-statement with yes and no paths on a single line michael@0: g.i = 0; michael@0: test("if (i === 0)\n" + michael@0: " log += '!'; else log += 'X';\n"); michael@0: test("if (i === 2)\n" + michael@0: " log += 'X'; else log += '!';\n"); michael@0: michael@0: // break to a line that has code inside and outside the loop michael@0: g.i = 2; michael@0: test("while (1) {\n" + michael@0: " if (i === 2) break;\n" + michael@0: " log += 'X'; } log += '!';\n"); michael@0: michael@0: // leaving a while loop by failing the test, when the last line has stuff both inside and outside the loop michael@0: g.i = 0; michael@0: test("while (i > 0) {\n" + michael@0: " if (i === 70) log += 'X';\n" + michael@0: " --i; } log += '!';\n"); michael@0: michael@0: // multiple case-labels on the same line michael@0: g.i = 0; michael@0: test("switch (i) {\n" + michael@0: " case 0: case 1: log += '!'; break; }\n"); michael@0: test("switch ('' + i) {\n" + michael@0: " case '0': case '1': log += '!'; break; }\n"); michael@0: test("switch (i) {\n" + michael@0: " case 'ok' + i: case i - i: log += '!'; break; }\n");