Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 import 'package:package_resolver/package_resolver.dart'; | 5 import 'package:package_resolver/package_resolver.dart'; |
| 6 import 'package:path/path.dart' as path; | |
|
nweiz
2016/12/08 23:34:31
as p
Jacob
2016/12/09 02:18:28
Done.
| |
| 6 import 'package:source_maps/source_maps.dart'; | 7 import 'package:source_maps/source_maps.dart'; |
| 7 import 'package:source_span/source_span.dart'; | 8 import 'package:source_span/source_span.dart'; |
| 8 import 'package:stack_trace/stack_trace.dart'; | 9 import 'package:stack_trace/stack_trace.dart'; |
| 9 import 'package:source_map_stack_trace/source_map_stack_trace.dart'; | 10 import 'package:source_map_stack_trace/source_map_stack_trace.dart'; |
| 10 import 'package:test/test.dart'; | 11 import 'package:test/test.dart'; |
| 11 | 12 |
| 12 /// A simple [Mapping] for tests that don't need anything special. | 13 /// A simple [Mapping] for tests that don't need anything special. |
| 13 final _simpleMapping = parseJson( | 14 final _simpleMapping = parseJson((new SourceMapBuilder() |
| 14 (new SourceMapBuilder() | 15 ..addSpan( |
| 15 ..addSpan( | 16 new SourceMapSpan.identifier( |
| 16 new SourceMapSpan.identifier( | 17 new SourceLocation(1, line: 1, column: 3, sourceUrl: "foo.dart"), |
| 17 new SourceLocation(1, | 18 "qux"), |
| 18 line: 1, column: 3, sourceUrl: "foo.dart"), | 19 new SourceSpan(new SourceLocation(8, line: 5, column: 0), |
| 19 "qux"), | 20 new SourceLocation(18, line: 15, column: 0), "\n" * 10))) |
| 20 new SourceSpan( | 21 .build("foo.dart.js.map")); |
| 21 new SourceLocation(8, line: 5, column: 0), | |
| 22 new SourceLocation(18, line: 15, column: 0), | |
| 23 "\n" * 10))) | |
| 24 .build("foo.dart.js.map")); | |
| 25 | 22 |
| 26 void main() { | 23 void main() { |
| 27 test("maps a JS line and column to a Dart line and span", () { | 24 test("maps a JS line and column to a Dart line and span", () { |
| 28 var trace = new Trace.parse("foo.dart.js 10:11 foo"); | 25 var trace = new Trace.parse("foo.dart.js 10:11 foo"); |
| 29 var frame = _mapTrace(_simpleMapping, trace).frames.first; | 26 var frame = _mapTrace(_simpleMapping, trace).frames.first; |
| 30 expect(frame.uri, equals(Uri.parse("foo.dart"))); | 27 expect(frame.uri, equals(Uri.parse("foo.dart"))); |
| 31 | 28 |
| 32 // These are +1 because stack_trace is 1-based whereas source_span is | 29 // These are +1 because stack_trace is 1-based whereas source_span is |
| 33 // 0-basd. | 30 // 0-basd. |
| 34 expect(frame.line, equals(2)); | 31 expect(frame.line, equals(2)); |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 55 foo.dart.js 10:11 baz | 52 foo.dart.js 10:11 baz |
| 56 """); | 53 """); |
| 57 | 54 |
| 58 var frames = _mapTrace(_simpleMapping, trace).frames; | 55 var frames = _mapTrace(_simpleMapping, trace).frames; |
| 59 | 56 |
| 60 expect(frames.length, equals(2)); | 57 expect(frames.length, equals(2)); |
| 61 expect(frames.first.member, equals("foo")); | 58 expect(frames.first.member, equals("foo")); |
| 62 expect(frames.last.member, equals("baz")); | 59 expect(frames.last.member, equals("baz")); |
| 63 }); | 60 }); |
| 64 | 61 |
| 62 test("shows JS frames without corresponding spans", () { | |
|
nweiz
2016/12/08 23:34:31
Put these in a "with includeUnmappedFrames" group.
Jacob
2016/12/09 02:18:28
obsolete as all but one test doesn't matter given
| |
| 63 var trace = new Trace.parse(""" | |
| 64 foo.dart.js 10:11 foo | |
| 65 foo.dart.js 1:1 bar | |
| 66 foo.dart.js 10:11 baz | |
| 67 """); | |
| 68 | |
| 69 var frames = | |
| 70 _mapTrace(_simpleMapping, trace, includeUnmappedFrames: true).frames; | |
| 71 | |
| 72 expect(frames.length, equals(3)); | |
| 73 expect(frames.first.member, equals("foo")); | |
| 74 expect(frames[1].member, equals("bar")); | |
| 75 expect(frames.last.member, equals("baz")); | |
| 76 | |
| 77 expect(path.basename(frames.first.uri.toString()), equals("foo.dart")); | |
| 78 expect(path.basename(frames[1].uri.toString()), equals("foo.dart.js")); | |
| 79 }); | |
| 80 | |
| 81 test("ignore frames that do not match files in source map bundle", () { | |
| 82 var trace = new Trace.parse(""" | |
| 83 foo.dart.js 10 foo | |
| 84 wrong_file.dart.js 10 foo | |
| 85 """); | |
| 86 var builder = new SourceMapBuilder() | |
| 87 ..addSpan( | |
| 88 new SourceMapSpan.identifier( | |
| 89 new SourceLocation(1, | |
| 90 line: 1, column: 3, sourceUrl: "packages/foo/foo.dart"), | |
| 91 "qux"), | |
| 92 new SourceSpan(new SourceLocation(8, line: 5, column: 0), | |
| 93 new SourceLocation(12, line: 9, column: 1), "\n" * 4)); | |
| 94 var sourceMapJson = builder.build("foo.dart.js.map"); | |
| 95 sourceMapJson['file'] = "foo.dart.js"; | |
| 96 var bundle = [sourceMapJson]; | |
| 97 var mapping = parseJsonExtended(bundle); | |
| 98 var frames = _mapTrace(mapping, trace, | |
| 99 packageRoot: "packages/", includeUnmappedFrames: true) | |
|
nweiz
2016/12/08 23:34:31
packageRoot is deprecated; use packageResolver ins
Jacob
2016/12/09 02:18:28
Done.
| |
| 100 .frames; | |
| 101 expect(frames.length, equals(2)); | |
| 102 var frame = frames.first; | |
| 103 expect(frame.uri, equals(Uri.parse("package:foo/foo.dart"))); | |
| 104 expect(frame.line, equals(2)); | |
| 105 expect(frame.column, equals(4)); | |
| 106 frame = frames.last; | |
| 107 expect(path.basename(frame.uri.toString()), equals("wrong_file.dart.js")); | |
| 108 expect(frame.line, equals(10)); | |
|
nweiz
2016/12/08 23:34:31
Add some empty lines here, this is difficult to re
Jacob
2016/12/09 02:18:28
Done.
| |
| 109 }); | |
| 110 | |
| 65 test("falls back to column 0 for unlisted column", () { | 111 test("falls back to column 0 for unlisted column", () { |
| 66 var trace = new Trace.parse("foo.dart.js 10 foo"); | 112 var trace = new Trace.parse("foo.dart.js 10 foo"); |
| 67 var builder = new SourceMapBuilder() | 113 var builder = new SourceMapBuilder() |
| 68 ..addSpan( | 114 ..addSpan( |
| 69 new SourceMapSpan.identifier( | 115 new SourceMapSpan.identifier( |
| 70 new SourceLocation(1, | 116 new SourceLocation(1, line: 1, column: 3, sourceUrl: "foo.dart"), |
| 71 line: 1, column: 3, sourceUrl: "foo.dart"), | 117 "qux"), |
| 72 "qux"), | 118 new SourceSpan(new SourceLocation(8, line: 5, column: 0), |
| 73 new SourceSpan( | 119 new SourceLocation(12, line: 9, column: 1), "\n" * 4)); |
| 74 new SourceLocation(8, line: 5, column: 0), | |
| 75 new SourceLocation(12, line: 9, column: 1), | |
| 76 "\n" * 4)); | |
| 77 | 120 |
| 78 var mapping = parseJson(builder.build("foo.dart.js.map")); | 121 var mapping = parseJson(builder.build("foo.dart.js.map")); |
| 79 var frame = _mapTrace(mapping, trace).frames.first; | 122 var frame = _mapTrace(mapping, trace).frames.first; |
| 80 expect(frame.uri, equals(Uri.parse("foo.dart"))); | 123 expect(frame.uri, equals(Uri.parse("foo.dart"))); |
| 81 expect(frame.line, equals(2)); | 124 expect(frame.line, equals(2)); |
| 82 expect(frame.column, equals(4)); | 125 expect(frame.column, equals(4)); |
| 83 }); | 126 }); |
| 84 | 127 |
| 85 test("uses package: URIs for frames within packageRoot", () { | 128 test("uses package: URIs for frames within packageRoot", () { |
| 86 var trace = new Trace.parse("foo.dart.js 10 foo"); | 129 var trace = new Trace.parse("foo.dart.js 10 foo"); |
| 87 var builder = new SourceMapBuilder() | 130 var builder = new SourceMapBuilder() |
| 88 ..addSpan( | 131 ..addSpan( |
| 89 new SourceMapSpan.identifier( | 132 new SourceMapSpan.identifier( |
| 90 new SourceLocation(1, | 133 new SourceLocation(1, |
| 91 line: 1, column: 3, sourceUrl: "packages/foo/foo.dart"), | 134 line: 1, column: 3, sourceUrl: "packages/foo/foo.dart"), |
| 92 "qux"), | 135 "qux"), |
| 93 new SourceSpan( | 136 new SourceSpan(new SourceLocation(8, line: 5, column: 0), |
| 94 new SourceLocation(8, line: 5, column: 0), | 137 new SourceLocation(12, line: 9, column: 1), "\n" * 4)); |
| 95 new SourceLocation(12, line: 9, column: 1), | |
| 96 "\n" * 4)); | |
| 97 | 138 |
| 98 var mapping = parseJson(builder.build("foo.dart.js.map")); | 139 var mapping = parseJson(builder.build("foo.dart.js.map")); |
| 99 var frame = _mapTrace(mapping, trace, packageRoot: "packages/") | 140 var frame = |
| 100 .frames.first; | 141 _mapTrace(mapping, trace, packageRoot: "packages/").frames.first; |
| 101 expect(frame.uri, equals(Uri.parse("package:foo/foo.dart"))); | 142 expect(frame.uri, equals(Uri.parse("package:foo/foo.dart"))); |
| 102 expect(frame.line, equals(2)); | 143 expect(frame.line, equals(2)); |
| 103 expect(frame.column, equals(4)); | 144 expect(frame.column, equals(4)); |
| 104 }); | 145 }); |
| 105 | 146 |
| 106 test("uses package: URIs for frames within packageResolver.packageRoot", () { | 147 test("uses package: URIs for frames within packageResolver.packageRoot", () { |
| 107 var trace = new Trace.parse("foo.dart.js 10 foo"); | 148 var trace = new Trace.parse("foo.dart.js 10 foo"); |
| 108 var builder = new SourceMapBuilder() | 149 var builder = new SourceMapBuilder() |
| 109 ..addSpan( | 150 ..addSpan( |
| 110 new SourceMapSpan.identifier( | 151 new SourceMapSpan.identifier( |
| 111 new SourceLocation(1, | 152 new SourceLocation(1, |
| 112 line: 1, column: 3, sourceUrl: "packages/foo/foo.dart"), | 153 line: 1, column: 3, sourceUrl: "packages/foo/foo.dart"), |
| 113 "qux"), | 154 "qux"), |
| 114 new SourceSpan( | 155 new SourceSpan(new SourceLocation(8, line: 5, column: 0), |
| 115 new SourceLocation(8, line: 5, column: 0), | 156 new SourceLocation(12, line: 9, column: 1), "\n" * 4)); |
| 116 new SourceLocation(12, line: 9, column: 1), | |
| 117 "\n" * 4)); | |
| 118 | 157 |
| 119 var mapping = parseJson(builder.build("foo.dart.js.map")); | 158 var mapping = parseJson(builder.build("foo.dart.js.map")); |
| 120 var mappedTrace = _mapTrace(mapping, trace, | 159 var mappedTrace = _mapTrace(mapping, trace, |
| 121 packageResolver: new SyncPackageResolver.root("packages/")); | 160 packageResolver: new SyncPackageResolver.root("packages/")); |
| 122 var frame = mappedTrace.frames.first; | 161 var frame = mappedTrace.frames.first; |
| 123 expect(frame.uri, equals(Uri.parse("package:foo/foo.dart"))); | 162 expect(frame.uri, equals(Uri.parse("package:foo/foo.dart"))); |
| 124 expect(frame.line, equals(2)); | 163 expect(frame.line, equals(2)); |
| 125 expect(frame.column, equals(4)); | 164 expect(frame.column, equals(4)); |
| 126 }); | 165 }); |
| 127 | 166 |
| 128 test("uses package: URIs for frames within a packageResolver.packageMap URL", | 167 test("uses package: URIs for frames within a packageResolver.packageMap URL", |
| 129 () { | 168 () { |
| 130 var trace = new Trace.parse("foo.dart.js 10 foo"); | 169 var trace = new Trace.parse("foo.dart.js 10 foo"); |
| 131 var builder = new SourceMapBuilder() | 170 var builder = new SourceMapBuilder() |
| 132 ..addSpan( | 171 ..addSpan( |
| 133 new SourceMapSpan.identifier( | 172 new SourceMapSpan.identifier( |
| 134 new SourceLocation(1, | 173 new SourceLocation(1, |
| 135 line: 1, column: 3, sourceUrl: "packages/foo/foo.dart"), | 174 line: 1, column: 3, sourceUrl: "packages/foo/foo.dart"), |
| 136 "qux"), | 175 "qux"), |
| 137 new SourceSpan( | 176 new SourceSpan(new SourceLocation(8, line: 5, column: 0), |
| 138 new SourceLocation(8, line: 5, column: 0), | 177 new SourceLocation(12, line: 9, column: 1), "\n" * 4)); |
| 139 new SourceLocation(12, line: 9, column: 1), | |
| 140 "\n" * 4)); | |
| 141 | 178 |
| 142 var mapping = parseJson(builder.build("foo.dart.js.map")); | 179 var mapping = parseJson(builder.build("foo.dart.js.map")); |
| 143 var mappedTrace = _mapTrace(mapping, trace, | 180 var mappedTrace = _mapTrace(mapping, trace, |
| 144 packageResolver: new SyncPackageResolver.config({ | 181 packageResolver: |
| 145 "foo": Uri.parse("packages/foo") | 182 new SyncPackageResolver.config({"foo": Uri.parse("packages/foo")})); |
| 146 })); | |
| 147 var frame = mappedTrace.frames.first; | 183 var frame = mappedTrace.frames.first; |
| 148 expect(frame.uri, equals(Uri.parse("package:foo/foo.dart"))); | 184 expect(frame.uri, equals(Uri.parse("package:foo/foo.dart"))); |
| 149 expect(frame.line, equals(2)); | 185 expect(frame.line, equals(2)); |
| 150 expect(frame.column, equals(4)); | 186 expect(frame.column, equals(4)); |
| 151 }); | 187 }); |
| 152 | 188 |
| 153 test("uses dart: URIs for frames within sdkRoot", () { | 189 test("uses dart: URIs for frames within sdkRoot", () { |
| 154 var trace = new Trace.parse("foo.dart.js 10 foo"); | 190 var trace = new Trace.parse("foo.dart.js 10 foo"); |
| 155 var builder = new SourceMapBuilder() | 191 var builder = new SourceMapBuilder() |
| 156 ..addSpan( | 192 ..addSpan( |
| 157 new SourceMapSpan.identifier( | 193 new SourceMapSpan.identifier( |
| 158 new SourceLocation(1, | 194 new SourceLocation(1, |
| 159 line: 1, column: 3, sourceUrl: "sdk/lib/async/foo.dart"), | 195 line: 1, column: 3, sourceUrl: "sdk/lib/async/foo.dart"), |
| 160 "qux"), | 196 "qux"), |
| 161 new SourceSpan( | 197 new SourceSpan(new SourceLocation(8, line: 5, column: 0), |
| 162 new SourceLocation(8, line: 5, column: 0), | 198 new SourceLocation(12, line: 9, column: 1), "\n" * 4)); |
| 163 new SourceLocation(12, line: 9, column: 1), | |
| 164 "\n" * 4)); | |
| 165 | 199 |
| 166 var mapping = parseJson(builder.build("foo.dart.js.map")); | 200 var mapping = parseJson(builder.build("foo.dart.js.map")); |
| 167 var frame = _mapTrace(mapping, trace, sdkRoot: "sdk/").frames.first; | 201 var frame = _mapTrace(mapping, trace, sdkRoot: "sdk/").frames.first; |
| 168 expect(frame.uri, equals(Uri.parse("dart:async/foo.dart"))); | 202 expect(frame.uri, equals(Uri.parse("dart:async/foo.dart"))); |
| 169 expect(frame.line, equals(2)); | 203 expect(frame.line, equals(2)); |
| 170 expect(frame.column, equals(4)); | 204 expect(frame.column, equals(4)); |
| 171 }); | 205 }); |
| 172 | 206 |
| 173 test("converts a stack chain", () { | 207 test("converts a stack chain", () { |
| 174 var trace = new Chain([ | 208 var trace = new Chain([ |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 205 expect(_prettify(r"foo$1$bar"), equals("foo")); | 239 expect(_prettify(r"foo$1$bar"), equals("foo")); |
| 206 expect(_prettify(r"foo$123$bar$bang$qux"), equals("foo")); | 240 expect(_prettify(r"foo$123$bar$bang$qux"), equals("foo")); |
| 207 }); | 241 }); |
| 208 | 242 |
| 209 test("closures", () { | 243 test("closures", () { |
| 210 expect(_prettify("foo_closure.call"), equals("foo.<fn>")); | 244 expect(_prettify("foo_closure.call"), equals("foo.<fn>")); |
| 211 }); | 245 }); |
| 212 | 246 |
| 213 test("nested closures", () { | 247 test("nested closures", () { |
| 214 expect(_prettify("foo__closure.call"), equals("foo.<fn>.<fn>")); | 248 expect(_prettify("foo__closure.call"), equals("foo.<fn>.<fn>")); |
| 215 expect(_prettify("foo____closure.call"), | 249 expect( |
| 216 equals("foo.<fn>.<fn>.<fn>.<fn>")); | 250 _prettify("foo____closure.call"), equals("foo.<fn>.<fn>.<fn>.<fn>")); |
| 217 }); | 251 }); |
| 218 | 252 |
| 219 test(".call", () { | 253 test(".call", () { |
| 220 expect(_prettify("foo.call"), equals("foo")); | 254 expect(_prettify("foo.call"), equals("foo")); |
| 221 }); | 255 }); |
| 222 | 256 |
| 223 test("top-level functions", () { | 257 test("top-level functions", () { |
| 224 expect(_prettify("dart.foo"), equals("foo")); | 258 expect(_prettify("dart.foo"), equals("foo")); |
| 225 }); | 259 }); |
| 226 | 260 |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 239 test("lots of stuff", () { | 273 test("lots of stuff", () { |
| 240 expect(_prettify(r"lib$Foo.static.lib$Foo_closure.call$0/<"), | 274 expect(_prettify(r"lib$Foo.static.lib$Foo_closure.call$0/<"), |
| 241 equals("Foo.<fn>")); | 275 equals("Foo.<fn>")); |
| 242 }); | 276 }); |
| 243 }); | 277 }); |
| 244 } | 278 } |
| 245 | 279 |
| 246 /// Like [mapStackTrace], but is guaranteed to return a [Trace] so it can be | 280 /// Like [mapStackTrace], but is guaranteed to return a [Trace] so it can be |
| 247 /// inspected. | 281 /// inspected. |
| 248 Trace _mapTrace(Mapping sourceMap, StackTrace stackTrace, | 282 Trace _mapTrace(Mapping sourceMap, StackTrace stackTrace, |
| 249 {bool minified: false, SyncPackageResolver packageResolver, sdkRoot, | 283 {bool minified: false, |
| 250 packageRoot}) { | 284 SyncPackageResolver packageResolver, |
| 285 sdkRoot, | |
| 286 packageRoot, | |
| 287 bool includeUnmappedFrames: false}) { | |
| 251 return new Trace.from(mapStackTrace(sourceMap, stackTrace, | 288 return new Trace.from(mapStackTrace(sourceMap, stackTrace, |
| 252 minified: minified, packageResolver: packageResolver, sdkRoot: sdkRoot, | 289 minified: minified, |
| 253 packageRoot: packageRoot)); | 290 packageResolver: packageResolver, |
| 291 sdkRoot: sdkRoot, | |
| 292 packageRoot: packageRoot, | |
| 293 includeUnmappedFrames: includeUnmappedFrames)); | |
| 254 } | 294 } |
| 255 | 295 |
| 256 /// Like [mapStackTrace], but is guaranteed to return a [Chain] so it can be | 296 /// Like [mapStackTrace], but is guaranteed to return a [Chain] so it can be |
| 257 /// inspected. | 297 /// inspected. |
| 258 Chain _mapChain(Mapping sourceMap, StackTrace stackTrace, | 298 Chain _mapChain(Mapping sourceMap, StackTrace stackTrace, |
| 259 {bool minified: false, SyncPackageResolver packageResolver, sdkRoot, | 299 {bool minified: false, |
| 260 packageRoot}) { | 300 SyncPackageResolver packageResolver, |
| 301 sdkRoot, | |
| 302 packageRoot, | |
| 303 bool includeUnmappedFrames: false}) { | |
| 261 return new Chain.forTrace(mapStackTrace(sourceMap, stackTrace, | 304 return new Chain.forTrace(mapStackTrace(sourceMap, stackTrace, |
| 262 minified: minified, packageResolver: packageResolver, sdkRoot: sdkRoot, | 305 minified: minified, |
| 263 packageRoot: packageRoot)); | 306 packageResolver: packageResolver, |
| 307 sdkRoot: sdkRoot, | |
| 308 packageRoot: packageRoot, | |
| 309 includeUnmappedFrames: includeUnmappedFrames)); | |
| 264 } | 310 } |
| 265 | 311 |
| 266 /// Runs the mapper's prettification logic on [member] and returns the result. | 312 /// Runs the mapper's prettification logic on [member] and returns the result. |
| 267 String _prettify(String member) { | 313 String _prettify(String member) { |
| 268 var trace = new Trace([new Frame(Uri.parse("foo.dart.js"), 10, 11, member)]); | 314 var trace = new Trace([new Frame(Uri.parse("foo.dart.js"), 10, 11, member)]); |
| 269 return _mapTrace(_simpleMapping, trace).frames.first.member; | 315 return _mapTrace(_simpleMapping, trace).frames.first.member; |
| 270 } | 316 } |
| OLD | NEW |