1'use strict'; 2const Path = require('path'); 3 4const { test } = require('tap'); 5 6const startCLI = require('./start-cli'); 7 8test('stepping through breakpoints', (t) => { 9 const script = Path.join('examples', 'break.js'); 10 const cli = startCLI([script]); 11 12 function onFatal(error) { 13 cli.quit(); 14 throw error; 15 } 16 17 return cli.waitForInitialBreak() 18 .then(() => cli.waitForPrompt()) 19 .then(() => { 20 t.match( 21 cli.breakInfo, 22 { filename: script, line: 1 }, 23 'pauses in the first line of the script'); 24 t.match( 25 cli.output, 26 /> 1 (?:\(function \([^)]+\) \{ )?const x = 10;/, 27 'shows the source and marks the current line'); 28 }) 29 .then(() => cli.stepCommand('n')) 30 .then(() => { 31 t.match( 32 cli.output, 33 `break in ${script}:2`, 34 'pauses in next line of the script'); 35 t.match( 36 cli.output, 37 '> 2 let name = \'World\';', 38 'marks the 2nd line'); 39 }) 40 .then(() => cli.stepCommand('next')) 41 .then(() => { 42 t.match( 43 cli.output, 44 `break in ${script}:3`, 45 'pauses in next line of the script'); 46 t.match( 47 cli.output, 48 '> 3 name = \'Robin\';', 49 'marks the 3nd line'); 50 }) 51 .then(() => cli.stepCommand('cont')) 52 .then(() => { 53 t.match( 54 cli.output, 55 `break in ${script}:10`, 56 'pauses on the next breakpoint'); 57 t.match( 58 cli.output, 59 '>10 debugger;', 60 'marks the debugger line'); 61 }) 62 63 // Prepare additional breakpoints 64 .then(() => cli.command('sb("break.js", 6)')) 65 .then(() => t.notMatch(cli.output, 'Could not resolve breakpoint')) 66 .then(() => cli.command('sb("otherFunction()")')) 67 .then(() => cli.command('sb(16)')) 68 .then(() => t.notMatch(cli.output, 'Could not resolve breakpoint')) 69 .then(() => cli.command('breakpoints')) 70 .then(() => { 71 t.match(cli.output, `#0 ${script}:6`); 72 t.match(cli.output, `#1 ${script}:16`); 73 }) 74 75 .then(() => cli.command('list()')) 76 .then(() => { 77 t.match(cli.output, '>10 debugger;', 'prints and marks current line'); 78 t.strictDeepEqual( 79 cli.parseSourceLines(), 80 [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], 81 'prints 5 lines before and after'); 82 }) 83 .then(() => cli.command('list(2)')) 84 .then(() => { 85 t.match(cli.output, '>10 debugger;', 'prints and marks current line'); 86 t.strictDeepEqual( 87 cli.parseSourceLines(), 88 [8, 9, 10, 11, 12], 89 'prints 2 lines before and after'); 90 }) 91 92 .then(() => cli.stepCommand('s')) 93 .then(() => cli.stepCommand('')) 94 .then(() => { 95 t.match( 96 cli.output, 97 'break in timers.js', 98 'entered timers.js'); 99 }) 100 .then(() => cli.stepCommand('cont')) 101 .then(() => { 102 t.match( 103 cli.output, 104 `break in ${script}:16`, 105 'found breakpoint we set above w/ line number only'); 106 }) 107 .then(() => cli.stepCommand('cont')) 108 .then(() => { 109 t.match( 110 cli.output, 111 `break in ${script}:6`, 112 'found breakpoint we set above w/ line number & script'); 113 }) 114 .then(() => cli.stepCommand('')) 115 .then(() => { 116 t.match( 117 cli.output, 118 `debugCommand in ${script}:14`, 119 'found function breakpoint we set above'); 120 }) 121 .then(() => cli.quit()) 122 .then(null, onFatal); 123}); 124 125test('sb before loading file', (t) => { 126 const script = Path.join('examples', 'cjs', 'index.js'); 127 const otherScript = Path.join('examples', 'cjs', 'other.js'); 128 const cli = startCLI([script]); 129 130 function onFatal(error) { 131 cli.quit(); 132 throw error; 133 } 134 135 return cli.waitForInitialBreak() 136 .then(() => cli.waitForPrompt()) 137 .then(() => cli.command('sb("other.js", 2)')) 138 .then(() => { 139 t.match( 140 cli.output, 141 'not loaded yet', 142 'warns that the script was not loaded yet'); 143 }) 144 .then(() => cli.stepCommand('cont')) 145 .then(() => { 146 t.match( 147 cli.output, 148 `break in ${otherScript}:2`, 149 'found breakpoint in file that was not loaded yet'); 150 }) 151 .then(() => cli.quit()) 152 .then(null, onFatal); 153}); 154 155test('clearBreakpoint', (t) => { 156 const script = Path.join('examples', 'break.js'); 157 const cli = startCLI([script]); 158 159 function onFatal(error) { 160 cli.quit(); 161 throw error; 162 } 163 164 return cli.waitForInitialBreak() 165 .then(() => cli.waitForPrompt()) 166 .then(() => cli.command('sb("break.js", 3)')) 167 .then(() => cli.command('sb("break.js", 9)')) 168 .then(() => cli.command('breakpoints')) 169 .then(() => { 170 t.match(cli.output, `#0 ${script}:3`); 171 t.match(cli.output, `#1 ${script}:9`); 172 }) 173 .then(() => cli.command('clearBreakpoint("break.js", 4)')) 174 .then(() => { 175 t.match(cli.output, 'Could not find breakpoint'); 176 }) 177 .then(() => cli.command('clearBreakpoint("not-such-script.js", 3)')) 178 .then(() => { 179 t.match(cli.output, 'Could not find breakpoint'); 180 }) 181 .then(() => cli.command('clearBreakpoint("break.js", 3)')) 182 .then(() => cli.command('breakpoints')) 183 .then(() => { 184 t.match(cli.output, `#0 ${script}:9`); 185 }) 186 .then(() => cli.stepCommand('cont')) 187 .then(() => { 188 t.match( 189 cli.output, 190 `break in ${script}:9`, 191 'hits the 2nd breakpoint because the 1st was cleared'); 192 }) 193 .then(() => cli.quit()) 194 .then(null, onFatal); 195}); 196