Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | |
| 2 // for details. All rights reserved. Use of this source code is governed by a | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 import 'package:source_span/source_span.dart'; | |
| 6 import 'package:test/test.dart'; | |
| 7 import 'package:vm_service_client/vm_service_client.dart'; | |
| 8 | |
| 9 import 'utils.dart'; | |
| 10 | |
| 11 const _mainContent = r""" | |
| 12 print("one"); | |
| 13 print("two"); | |
| 14 | |
| 15 if (false) { | |
| 16 print("three"); | |
| 17 print("four"); | |
| 18 } | |
| 19 | |
| 20 Isolate.current.kill();"""; | |
|
nweiz
2016/05/17 20:54:41
Why did you make this change?
If the trailing quo
kevmoo
2016/05/17 22:12:01
Acknowledged.
| |
| 21 | |
| 22 void main() { | |
| 23 VMServiceClient client; | |
| 24 VMIsolateRef isolate; | |
| 25 | |
| 26 tearDown(() { | |
| 27 if (client != null) client.close(); | |
| 28 }); | |
| 29 | |
| 30 group('getSourceReport for a script with one range', () { | |
| 31 setUp(() async { | |
| 32 client = await runAndConnect(main: _mainContent); | |
| 33 | |
| 34 isolate = (await client.getVM()).isolates.single; | |
| 35 | |
| 36 await isolate.waitUntilPaused(); | |
| 37 }); | |
| 38 | |
| 39 test("returns a valid source report", () async { | |
| 40 var report = await isolate.getSourceReport( | |
| 41 includeCoverageReport: false, includePossibleBreakpoints: false); | |
| 42 | |
| 43 expect(report.ranges, hasLength(greaterThan(1))); | |
| 44 | |
| 45 var range = report.ranges.singleWhere((range) => | |
| 46 range.script.uri.toString().startsWith('data:application/dart')); | |
| 47 | |
| 48 expect(range.compiled, isTrue); | |
| 49 | |
| 50 var script = await range.script.load(); | |
| 51 | |
| 52 var runnableIsolate = await isolate.loadRunnable(); | |
| 53 | |
| 54 var rootLib = await runnableIsolate.rootLibrary.load(); | |
| 55 var mainFunction = await rootLib.functions['main'].load(); | |
| 56 | |
| 57 var mainLocation = script.sourceSpan(mainFunction.location); | |
| 58 | |
| 59 var startLocation = script.sourceLocation(range.location.token); | |
| 60 expect(startLocation, mainLocation.start); | |
| 61 | |
| 62 var endLocation = script.sourceLocation(range.location.end); | |
| 63 expect(endLocation, mainLocation.end); | |
| 64 | |
| 65 expect(range.hits, isNull); | |
| 66 expect(range.misses, isNull); | |
| 67 expect(range.possibleBreakpoints, isNull); | |
| 68 }); | |
| 69 | |
| 70 test("reports accurate coverage information", () async { | |
| 71 var report = | |
| 72 await isolate.getSourceReport(includePossibleBreakpoints: false); | |
| 73 | |
| 74 var range = report.ranges.singleWhere((range) => | |
| 75 range.script.uri.toString().startsWith('data:application/dart')); | |
| 76 expect(range.possibleBreakpoints, isNull); | |
| 77 | |
| 78 var script = await range.script.load(); | |
| 79 | |
| 80 var hitLines = | |
| 81 range.hits.map((token) => script.sourceLocation(token).line).toSet(); | |
| 82 expect(hitLines, [ | |
| 83 6, // new ReceivePort(); | |
| 84 7, // print("one"); | |
| 85 8, // print("two"); | |
| 86 15, // Isolate.current.kill(); | |
| 87 16 // VM inserts an extra hit on the last line of an async function | |
| 88 ]); | |
| 89 | |
| 90 // The line that are not executed – two within the `if (false)` block | |
| 91 var missedLines = | |
| 92 range.misses.map((token) => script.sourceLocation(token).line); | |
| 93 expect(missedLines, [11, 12]); | |
| 94 }); | |
| 95 | |
| 96 test("reports accurate breakpoint information", () async { | |
| 97 var report = await isolate.getSourceReport(includeCoverageReport: false); | |
| 98 | |
| 99 var range = report.ranges.singleWhere((range) => | |
| 100 range.script.uri.toString().startsWith('data:application/dart')); | |
| 101 | |
| 102 expect(range.hits, isNull); | |
| 103 expect(range.misses, isNull); | |
| 104 | |
| 105 var script = await range.script.load(); | |
| 106 expect(range.possibleBreakpoints, isNotEmpty); | |
| 107 | |
| 108 // represents the unique set of lines that can have breakpoints | |
| 109 var breakPointLines = range.possibleBreakpoints | |
| 110 .map((token) => script.sourceLocation(token).line) | |
| 111 .toSet(); | |
| 112 expect(breakPointLines, [ | |
| 113 4, // main entry point | |
| 114 6, // new ReceivePort(); | |
| 115 7, // print("one"); | |
| 116 8, // print("two"); | |
| 117 11, // print("three"); | |
| 118 12, // print("four"); | |
| 119 15, // Isolate.current.kill(); | |
| 120 16 // VM considers the last line of an async function breakpoint-able | |
| 121 ]); | |
| 122 }); | |
| 123 | |
| 124 test("behaves correctly including coverage and breakpoints", () async { | |
| 125 var report = await isolate.getSourceReport( | |
| 126 includeCoverageReport: true, includePossibleBreakpoints: true); | |
| 127 | |
| 128 var range = report.ranges.singleWhere((range) => | |
| 129 range.script.uri.toString().startsWith('data:application/dart')); | |
| 130 | |
| 131 expect(range.hits, isNotEmpty); | |
| 132 expect(range.misses, isNotEmpty); | |
| 133 expect(range.possibleBreakpoints, isNotEmpty); | |
| 134 }); | |
| 135 }); | |
| 136 | |
| 137 group('getSourceReport with a multi-range script', () { | |
| 138 VMScript script; | |
| 139 VMLibrary rootLib; | |
| 140 VMSourceLocation mainLocation; | |
| 141 FileSpan mainFunctionSpan; | |
| 142 VMSourceLocation unusedFunction2Location; | |
| 143 | |
| 144 setUp(() async { | |
| 145 client = await runAndConnect( | |
| 146 topLevel: r'''final unusedField = 5; | |
| 147 | |
| 148 int unusedFunction(a, b) { | |
| 149 return a + b; | |
| 150 } | |
| 151 | |
| 152 void unusedFunction2(value) { | |
| 153 print(value); | |
| 154 }''', | |
| 155 main: _mainContent); | |
| 156 | |
| 157 isolate = (await client.getVM()).isolates.single; | |
| 158 | |
| 159 await isolate.waitUntilPaused(); | |
| 160 | |
| 161 var runnableIsolate = await isolate.loadRunnable(); | |
| 162 rootLib = await runnableIsolate.rootLibrary.load(); | |
| 163 script = await rootLib.scripts.single.load(); | |
| 164 | |
| 165 var mainFunction = await rootLib.functions['main'].load(); | |
| 166 mainLocation = mainFunction.location; | |
| 167 mainFunctionSpan = script.sourceSpan(mainLocation); | |
| 168 | |
| 169 var unusedFunction2 = await rootLib.functions['unusedFunction2'].load(); | |
| 170 unusedFunction2Location = unusedFunction2.location; | |
| 171 }); | |
| 172 | |
| 173 test("reports valid data with default arguments", () async { | |
| 174 var report = await script.getSourceReport(); | |
| 175 | |
| 176 expect(report.ranges, hasLength(3)); | |
| 177 | |
| 178 var firstRange = report.ranges.first; | |
| 179 expect(firstRange.compiled, isFalse); | |
| 180 expect(firstRange.hits, isNull); | |
| 181 expect(firstRange.misses, isNull); | |
| 182 expect(firstRange.possibleBreakpoints, isNull); | |
| 183 | |
| 184 // TODO(kevmoo): use lessThan in matcher when | |
| 185 // https://github.com/dart-lang/matcher/issues/33 is fixed | |
| 186 expect(script.sourceSpan(firstRange.location).compareTo(mainFunctionSpan), | |
| 187 isNegative); | |
| 188 | |
| 189 var lastRange = report.ranges.last; | |
| 190 expect(lastRange.compiled, isTrue); | |
| 191 expect(script.sourceSpan(lastRange.location), equals(mainFunctionSpan)); | |
| 192 }); | |
| 193 | |
| 194 test("reports all ranged compiled with forceCompile: true", () async { | |
| 195 var report = await script.getSourceReport(forceCompile: true); | |
| 196 | |
| 197 expect(report.ranges, hasLength(3)); | |
| 198 | |
| 199 var firstRange = report.ranges.first; | |
| 200 expect(firstRange.compiled, isTrue); | |
| 201 | |
| 202 var secondRange = report.ranges.last; | |
| 203 expect(secondRange.compiled, isTrue); | |
| 204 }); | |
| 205 | |
| 206 test("reports a valid subrange with the start argument", () async { | |
| 207 var report = await script.getSourceReport(start: mainLocation.token); | |
| 208 | |
| 209 expect(script.sourceSpan(report.ranges.single.location), | |
| 210 equals(mainFunctionSpan)); | |
| 211 }); | |
| 212 | |
| 213 test("reports a valid subrange with the end argument", () async { | |
| 214 var report = | |
| 215 await script.getSourceReport(end: unusedFunction2Location.token); | |
| 216 | |
| 217 expect(report.ranges, hasLength(2), | |
| 218 reason: 'Includes the range containing only unusedFunction2, main.'); | |
| 219 }); | |
| 220 | |
| 221 test("reports a valid subrange with the start and end argument", () async { | |
| 222 var report = await script.getSourceReport( | |
| 223 start: unusedFunction2Location.token, | |
| 224 end: unusedFunction2Location.end); | |
| 225 | |
| 226 expect(report.ranges, hasLength(1)); | |
| 227 expect(script.sourceSpan(report.ranges.single.location), | |
| 228 equals(script.sourceSpan(unusedFunction2Location))); | |
| 229 }); | |
| 230 }); | |
| 231 } | |
| OLD | NEW |