Chromium Code Reviews| Index: test/source_report_test.dart |
| diff --git a/test/source_report_test.dart b/test/source_report_test.dart |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..7fdf8e52c385332ac7772096d7f898e08a482045 |
| --- /dev/null |
| +++ b/test/source_report_test.dart |
| @@ -0,0 +1,218 @@ |
| +// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
| +// for details. All rights reserved. Use of this source code is governed by a |
| +// BSD-style license that can be found in the LICENSE file. |
| + |
| +import 'package:source_span/source_span.dart'; |
| +import 'package:test/test.dart'; |
| +import 'package:vm_service_client/vm_service_client.dart'; |
| + |
| +import 'utils.dart'; |
| + |
| +const _mainContent = r""" |
| +print("one"); |
|
nweiz
2016/05/04 23:05:52
What is going on with this indentation? Why are th
kevmoo
2016/05/05 20:46:27
Right?
|
| + print("two"); |
| + |
| + if (false) { |
| + print("three"); |
| + print("four"); |
| + }"""; |
| + |
| +void main() { |
| + VMServiceClient client; |
| + VMIsolateRef isolate; |
| + |
| + tearDown(() { |
| + if (client != null) client.close(); |
| + }); |
| + |
| + group('a script with one range', () { |
| + setUp(() async { |
| + client = await runAndConnect(main: _mainContent); |
| + |
| + isolate = (await client.getVM()).isolates.single; |
| + |
| + await isolate.pause(); |
| + }); |
| + |
| + test("and no options", () async { |
|
nweiz
2016/05/04 23:05:52
The group name plus the test name should be a sent
kevmoo
2016/05/05 20:46:28
Done.
nweiz
2016/05/11 23:03:31
"behaves correctly" doesn't actually describe any
|
| + var report = await isolate.getSourceReport(); |
| + |
| + expect(report.ranges, hasLength(greaterThan(1))); |
| + |
| + var range = report.ranges.singleWhere((range) => |
| + range.script.uri.toString().startsWith('data:application/dart')); |
| + |
| + expect(range.compiled, isTrue); |
| + |
| + var script = await range.script.load(); |
| + |
| + var startLocation = script.sourceLocation(range.location.token); |
| + expect(startLocation.line, 4); |
| + expect(startLocation.column, 0); |
|
nweiz
2016/05/04 23:05:52
Testing the explicit line and column is brittle, a
kevmoo
2016/05/05 20:46:27
Done.
|
| + |
| + var endLocation = script.sourceLocation(range.location.end); |
| + expect(endLocation.line, 14); |
| + expect(endLocation.column, 0); |
| + |
| + expect(range.hits, isNull); |
| + expect(range.misses, isNull); |
| + expect(range.possibleBreakpoints, isNull); |
| + }); |
| + |
| + test("including coverage", () async { |
| + var report = await isolate.getSourceReport(includeCoverageReport: true); |
| + |
| + var range = report.ranges.singleWhere((range) => |
| + range.script.uri.toString().startsWith('data:application/dart')); |
| + expect(range.possibleBreakpoints, isNull); |
| + |
| + var script = await range.script.load(); |
| + |
| + var hitLocations = |
| + range.hits.map((token) => script.sourceLocation(token).line); |
| + |
| + expect(hitLocations, [6, 7, 8, 14]); |
|
nweiz
2016/05/04 23:05:52
Add a comment explaining what actual lines these r
kevmoo
2016/05/05 20:46:27
Done.
|
| + |
| + var missLocations = |
| + range.misses.map((token) => script.sourceLocation(token).line); |
| + |
| + expect(missLocations, [11, 12]); |
| + }); |
| + |
| + test("including possible breakpoints", () async { |
| + var report = |
| + await isolate.getSourceReport(includePossibleBreakpoints: true); |
| + |
| + var range = report.ranges.singleWhere((range) => |
| + range.script.uri.toString().startsWith('data:application/dart')); |
| + |
| + expect(range.hits, isNull); |
| + expect(range.misses, isNull); |
| + |
| + var script = await range.script.load(); |
| + |
| + expect(range.possibleBreakpoints, isNotEmpty); |
| + |
| + var breakPointLines = range.possibleBreakpoints |
| + .map((token) => script.sourceLocation(token).line); |
| + |
| + expect(breakPointLines, [4, 6, 7, 8, 11, 12, 14]); |
| + }); |
| + |
| + test("including coverage and possible breakpoints", () async { |
| + var report = await isolate.getSourceReport( |
| + includeCoverageReport: true, includePossibleBreakpoints: true); |
| + |
| + var range = report.ranges.singleWhere((range) => |
| + range.script.uri.toString().startsWith('data:application/dart')); |
| + |
| + expect(range.hits, isNotEmpty); |
| + expect(range.misses, isNotEmpty); |
| + expect(range.possibleBreakpoints, isNotEmpty); |
| + }); |
| + }); |
| + |
| + group('a script with multiple ranges', () { |
| + VMScript script; |
| + VMLibrary rootLib; |
| + VMSourceLocation mainFunctionLocation; |
|
nweiz
2016/05/04 23:05:52
I think just "mainLocation" would be fine here.
kevmoo
2016/05/05 20:46:28
Done.
nweiz
2016/05/11 23:03:31
This comment was intended to also apply to other s
|
| + FileSpan mainFunctionSpan; |
| + VMSourceLocation unusedFunc2Location; |
|
nweiz
2016/05/04 23:05:52
"Func" -> "Function"
kevmoo
2016/05/05 20:46:27
Done.
|
| + |
| + setUp(() async { |
| + client = await runAndConnect( |
| + topLevel: r'''final unusedField = 5; |
| + |
| +int unusedFunction(a, b) { |
| + return a + b; |
| +} |
| + |
| +void unusedFunction2(value) { |
| + print(value); |
| +}''', |
| + main: _mainContent); |
| + |
| + isolate = (await client.getVM()).isolates.single; |
| + |
| + await isolate.pause(); |
| + |
| + var runnableIsolate = await isolate.loadRunnable(); |
| + rootLib = await runnableIsolate.rootLibrary.load(); |
| + script = await rootLib.scripts.single.load(); |
| + |
| + var mainFunc = await rootLib.functions['main'].load(); |
|
nweiz
2016/05/04 23:05:53
"Func" -> "Function"
kevmoo
2016/05/05 20:46:27
Done.
|
| + mainFunctionLocation = mainFunc.location; |
| + mainFunctionSpan = script.sourceSpan(mainFunctionLocation); |
| + |
| + var unusedFunction2 = await rootLib.functions['unusedFunction2'].load(); |
| + unusedFunc2Location = unusedFunc2Location = unusedFunction2.location; |
|
nweiz
2016/05/04 23:05:52
Extra assignment.
kevmoo
2016/05/05 20:46:28
Done.
|
| + }); |
| + |
| + test("not force compiled", () async { |
| + var report = await script.getSourceReport( |
| + includeCoverageReport: true, includePossibleBreakpoints: true); |
| + |
| + expect(report.ranges, hasLength(3)); |
| + |
| + var firstRange = report.ranges.first; |
| + expect(firstRange.compiled, isFalse); |
|
nweiz
2016/05/04 23:05:53
Make assertions about the other properties as well
kevmoo
2016/05/05 20:46:28
Done.
|
| + var firstRangeLocation = |
|
nweiz
2016/05/04 23:05:53
Why is this called "Location" if it's an offset?
kevmoo
2016/05/05 20:46:27
Acknowledged.
|
| + script.sourceLocation(firstRange.location.end).offset; |
| + expect(firstRangeLocation, lessThan(mainFunctionSpan.start.offset)); |
|
nweiz
2016/05/04 23:05:53
You can just do
expect(script.sourceSpan(firstR
kevmoo
2016/05/05 20:46:27
Sadly, `lessThan` only uses the `>` operator.
We
|
| + |
| + var lastRange = report.ranges.last; |
| + expect(lastRange.compiled, isTrue); |
| + var lastRangeOffset = |
| + script.sourceLocation(lastRange.location.token).offset; |
| + expect(lastRangeOffset, mainFunctionSpan.start.offset); |
| + }); |
| + |
| + test("force compiled", () async { |
| + var report = await script.getSourceReport( |
| + includeCoverageReport: true, |
| + includePossibleBreakpoints: true, |
| + forceCompile: true); |
| + |
| + expect(report.ranges, hasLength(3)); |
| + |
| + var firstRange = report.ranges.first; |
| + expect(firstRange.compiled, isTrue); |
| + |
| + var secondRange = report.ranges.last; |
| + expect(secondRange.compiled, isTrue); |
| + }); |
| + |
| + test("with tokenPos set", () async { |
|
nweiz
2016/05/04 23:05:52
It's not called "tokenPos" (or "endTokenPos") anym
kevmoo
2016/05/05 20:46:27
Acknowledged.
|
| + var report = await script.getSourceReport( |
| + includeCoverageReport: true, |
| + includePossibleBreakpoints: true, |
| + start: mainFunctionLocation.token); |
| + |
| + var rangeOffset = |
| + script.sourceLocation(report.ranges.single.location.token).offset; |
| + |
| + expect(rangeOffset, mainFunctionSpan.start.offset); |
| + }); |
| + |
| + test("with endTokenPos set", () async { |
| + var report = await script.getSourceReport( |
| + includeCoverageReport: true, |
| + includePossibleBreakpoints: true, |
| + end: unusedFunc2Location.token); |
| + |
| + expect(report.ranges, hasLength(2), |
| + reason: 'Includes the range containing only unusedFunction2, main.'); |
| + }); |
| + |
| + test("with an empty token range", () async { |
| + var report = await script.getSourceReport( |
| + includeCoverageReport: true, |
| + includePossibleBreakpoints: true, |
| + start: unusedFunc2Location.token, |
| + end: unusedFunc2Location.end); |
| + |
| + expect(report.ranges, hasLength(1), |
| + reason: 'Includes the range containing only unusedFunction2.'); |
|
nweiz
2016/05/04 23:05:52
Assert that this is in fact the range it contains.
kevmoo
2016/05/05 20:46:28
Done.
|
| + }); |
| + }); |
| +} |