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(); | |
| 21 """; | |
| 22 | |
| 23 void main() { | |
| 24 VMServiceClient client; | |
| 25 VMIsolateRef isolate; | |
| 26 | |
| 27 tearDown(() { | |
| 28 if (client != null) client.close(); | |
| 29 }); | |
| 30 | |
| 31 group('getSourceReport for a script with one range', () { | |
| 32 setUp(() async { | |
| 33 client = await runAndConnect(main: _mainContent); | |
| 34 | |
| 35 isolate = (await client.getVM()).isolates.single; | |
| 36 | |
| 37 await isolate.waitUntilPaused(); | |
| 38 }); | |
| 39 | |
| 40 test("returns a valid source report", () async { | |
| 41 var report = await isolate.getSourceReport( | |
| 42 includeCoverageReport: false, includePossibleBreakpoints: false); | |
| 43 | |
| 44 expect(report.ranges, hasLength(greaterThan(1))); | |
| 45 | |
| 46 var range = report.ranges.singleWhere((range) => | |
| 47 range.script.uri.toString().startsWith('data:application/dart')); | |
| 48 | |
| 49 expect(range.compiled, isTrue); | |
| 50 | |
| 51 var script = await range.script.load(); | |
| 52 | |
| 53 var runnableIsolate = await isolate.loadRunnable(); | |
| 54 | |
| 55 var rootLib = await runnableIsolate.rootLibrary.load(); | |
| 56 var mainFunction = await rootLib.functions['main'].load(); | |
| 57 | |
| 58 var mainLocation = script.sourceSpan(mainFunction.location); | |
| 59 | |
| 60 var startLocation = script.sourceLocation(range.location.token); | |
| 61 expect(startLocation, mainLocation.start); | |
| 62 | |
| 63 var endLocation = script.sourceLocation(range.location.end); | |
| 64 expect(endLocation, mainLocation.end); | |
| 65 | |
| 66 expect(range.hits, isNull); | |
| 67 expect(range.misses, isNull); | |
| 68 expect(range.possibleBreakpoints, isNull); | |
| 69 }); | |
| 70 | |
| 71 test("reports accurate coverage information", () async { | |
| 72 var report = | |
| 73 await isolate.getSourceReport(includePossibleBreakpoints: false); | |
| 74 | |
| 75 var range = report.ranges.singleWhere((range) => | |
| 76 range.script.uri.toString().startsWith('data:application/dart')); | |
| 77 expect(range.possibleBreakpoints, isNull); | |
| 78 | |
| 79 var script = await range.script.load(); | |
| 80 | |
| 81 var hitLines = | |
| 82 range.hits.map((token) => script.sourceLocation(token).line).toSet(); | |
| 83 expect(hitLines, [ | |
| 84 6, // new ReceivePort(); | |
| 85 7, // print("one"); | |
| 86 8, // print("two"); | |
| 87 15, // Isolate.current.kill(); | |
| 88 17 // VM inserts an extra hit on the last line of an async function | |
| 89 ]); | |
| 90 | |
| 91 // The line that are not executed – two within the `if (false)` block | |
| 92 var missedLines = | |
| 93 range.misses.map((token) => script.sourceLocation(token).line); | |
| 94 expect(missedLines, [11, 12]); | |
| 95 }); | |
| 96 | |
| 97 test("reports accurate breakpoint information", () async { | |
| 98 var report = await isolate.getSourceReport(includeCoverageReport: false); | |
| 99 | |
| 100 var range = report.ranges.singleWhere((range) => | |
| 101 range.script.uri.toString().startsWith('data:application/dart')); | |
| 102 | |
| 103 expect(range.hits, isNull); | |
| 104 expect(range.misses, isNull); | |
| 105 | |
| 106 var script = await range.script.load(); | |
| 107 expect(range.possibleBreakpoints, isNotEmpty); | |
| 108 | |
| 109 // represents the unique set of lines that can have breakpoints | |
| 110 var breakPointLines = range.possibleBreakpoints | |
| 111 .map((token) => script.sourceLocation(token).line) | |
| 112 .toSet(); | |
| 113 expect(breakPointLines, [ | |
| 114 4, // main entry point | |
| 115 6, // new ReceivePort(); | |
| 116 7, // print("one"); | |
| 117 8, // print("two"); | |
| 118 11, // print("three"); | |
| 119 12, // print("four"); | |
| 120 15, // Isolate.current.kill(); | |
| 121 17 // VM considers the last line of an async function breakpoint-able | |
| 122 ]); | |
| 123 }); | |
| 124 | |
| 125 test("behaves correctly including coverage and breakpoints", () async { | |
| 126 var report = await isolate.getSourceReport( | |
| 127 includeCoverageReport: true, includePossibleBreakpoints: true); | |
| 128 | |
| 129 var range = report.ranges.singleWhere((range) => | |
| 130 range.script.uri.toString().startsWith('data:application/dart')); | |
| 131 | |
| 132 expect(range.hits, isNotEmpty); | |
| 133 expect(range.misses, isNotEmpty); | |
| 134 expect(range.possibleBreakpoints, isNotEmpty); | |
| 135 }); | |
| 136 }); | |
| 137 | |
| 138 group('getSourceReport with a multi-range script', () { | |
| 139 VMScript script; | |
| 140 VMLibrary rootLib; | |
| 141 VMSourceLocation mainLocation; | |
| 142 FileSpan mainFunctionSpan; | |
| 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 | |
| 170 test("reports valid data with default arguments", () async { | |
| 171 var report = await script.getSourceReport(); | |
| 172 | |
| 173 expect(report.ranges, hasLength(3)); | |
| 174 | |
| 175 var firstRange = report.ranges.first; | |
| 176 expect(firstRange.compiled, isFalse); | |
| 177 expect(firstRange.hits, isNull); | |
| 178 expect(firstRange.misses, isNull); | |
| 179 expect(firstRange.possibleBreakpoints, isNull); | |
| 180 | |
| 181 // TODO(kevmoo): use lessThan in matcher when | |
| 182 // https://github.com/dart-lang/matcher/issues/33 is fixed | |
| 183 expect(script.sourceSpan(firstRange.location).compareTo(mainFunctionSpan), | |
| 184 isNegative); | |
| 185 | |
| 186 var lastRange = report.ranges.last; | |
| 187 expect(lastRange.compiled, isTrue); | |
| 188 expect(script.sourceSpan(lastRange.location), equals(mainFunctionSpan)); | |
| 189 }); | |
| 190 | |
| 191 test("reports all ranged compiled with forceCompile: true", () async { | |
| 192 var report = await script.getSourceReport(forceCompile: true); | |
| 193 | |
| 194 expect(report.ranges, hasLength(3)); | |
| 195 | |
| 196 var firstRange = report.ranges.first; | |
| 197 expect(firstRange.compiled, isTrue); | |
| 198 | |
| 199 var secondRange = report.ranges.last; | |
| 200 expect(secondRange.compiled, isTrue); | |
| 201 }); | |
| 202 | |
| 203 test("reports a valid subrange with the location argument", () async { | |
| 204 var report = await script.getSourceReport(location: mainLocation); | |
| 205 | |
| 206 expect(script.sourceSpan(report.ranges.single.location), | |
| 207 equals(mainFunctionSpan)); | |
| 208 }); | |
|
nweiz
2016/05/19 21:11:13
Test what happens with a point location (that is,
kevmoo
2016/05/19 21:59:46
Acknowledged.
| |
| 209 }); | |
| 210 } | |
| OLD | NEW |