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 p; | |
| 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")); | |
|
nweiz
2016/12/12 22:04:56
Please remove unrelated formatting changes.
Jacob
2016/12/13 18:01:54
Done.
| |
| 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("include JS frames from external libraries with source map bundle", () { | |
|
nweiz
2016/12/12 22:04:56
"includes"
I'm not sure what "external" means her
Jacob
2016/12/13 18:01:54
jquery.js is external library
foo.dart.js is inter
nweiz
2016/12/13 22:05:46
Maybe "JS files not covered by the source map bund
Jacob
2016/12/13 23:13:05
Done.
| |
| 63 var trace = new Trace.parse(""" | |
| 64 foo.dart.js 10:11 foo | |
| 65 jquery.js 10:1 foo | |
| 66 """); | |
| 67 var builder = new SourceMapBuilder() | |
| 68 ..addSpan( | |
| 69 new SourceMapSpan.identifier( | |
| 70 new SourceLocation(1, | |
| 71 line: 1, column: 3, sourceUrl: "packages/foo/foo.dart"), | |
| 72 "qux"), | |
| 73 new SourceSpan(new SourceLocation(8, line: 5, column: 0), | |
| 74 new SourceLocation(12, line: 9, column: 1), "\n" * 4)); | |
| 75 var sourceMapJson = builder.build("foo.dart.js.map"); | |
| 76 sourceMapJson['file'] = "foo.dart.js"; | |
| 77 | |
| 78 var bundle = [sourceMapJson]; | |
| 79 var mapping = parseJsonExtended(bundle); | |
| 80 var frames = _mapTrace(mapping, trace, | |
| 81 packageResolver: new SyncPackageResolver.root("packages/")) | |
| 82 .frames; | |
| 83 | |
| 84 expect(frames.length, equals(2)); | |
| 85 | |
| 86 var frame = frames.first; | |
| 87 expect(frame.uri, equals(Uri.parse("package:foo/foo.dart"))); | |
| 88 expect(frame.line, equals(2)); | |
| 89 expect(frame.column, equals(4)); | |
| 90 | |
| 91 frame = frames.last; | |
| 92 expect(p.basename(frame.uri.toString()), equals("jquery.js")); | |
| 93 expect(frame.line, equals(10)); | |
| 94 }); | |
| 95 | |
|
nweiz
2016/12/12 22:04:56
Also test a source map bundle contains multiple so
Jacob
2016/12/13 18:01:54
that is the sort of test that belongs in the sourc
nweiz
2016/12/13 22:05:46
This CL concretely changes the behavior with respe
Jacob
2016/12/13 23:13:05
Integration level testing of that behavior exists
nweiz
2016/12/13 23:43:48
That's not clear from a black-box perspective. The
| |
| 65 test("falls back to column 0 for unlisted column", () { | 96 test("falls back to column 0 for unlisted column", () { |
| 66 var trace = new Trace.parse("foo.dart.js 10 foo"); | 97 var trace = new Trace.parse("foo.dart.js 10 foo"); |
| 67 var builder = new SourceMapBuilder() | 98 var builder = new SourceMapBuilder() |
| 68 ..addSpan( | 99 ..addSpan( |
| 69 new SourceMapSpan.identifier( | 100 new SourceMapSpan.identifier( |
| 70 new SourceLocation(1, | 101 new SourceLocation(1, line: 1, column: 3, sourceUrl: "foo.dart"), |
| 71 line: 1, column: 3, sourceUrl: "foo.dart"), | 102 "qux"), |
| 72 "qux"), | 103 new SourceSpan(new SourceLocation(8, line: 5, column: 0), |
| 73 new SourceSpan( | 104 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 | 105 |
| 78 var mapping = parseJson(builder.build("foo.dart.js.map")); | 106 var mapping = parseJson(builder.build("foo.dart.js.map")); |
| 79 var frame = _mapTrace(mapping, trace).frames.first; | 107 var frame = _mapTrace(mapping, trace).frames.first; |
| 80 expect(frame.uri, equals(Uri.parse("foo.dart"))); | 108 expect(frame.uri, equals(Uri.parse("foo.dart"))); |
| 81 expect(frame.line, equals(2)); | 109 expect(frame.line, equals(2)); |
| 82 expect(frame.column, equals(4)); | 110 expect(frame.column, equals(4)); |
| 83 }); | 111 }); |
| 84 | 112 |
| 85 test("uses package: URIs for frames within packageRoot", () { | 113 test("uses package: URIs for frames within packageRoot", () { |
| 86 var trace = new Trace.parse("foo.dart.js 10 foo"); | 114 var trace = new Trace.parse("foo.dart.js 10 foo"); |
| 87 var builder = new SourceMapBuilder() | 115 var builder = new SourceMapBuilder() |
| 88 ..addSpan( | 116 ..addSpan( |
| 89 new SourceMapSpan.identifier( | 117 new SourceMapSpan.identifier( |
| 90 new SourceLocation(1, | 118 new SourceLocation(1, |
| 91 line: 1, column: 3, sourceUrl: "packages/foo/foo.dart"), | 119 line: 1, column: 3, sourceUrl: "packages/foo/foo.dart"), |
| 92 "qux"), | 120 "qux"), |
| 93 new SourceSpan( | 121 new SourceSpan(new SourceLocation(8, line: 5, column: 0), |
| 94 new SourceLocation(8, line: 5, column: 0), | 122 new SourceLocation(12, line: 9, column: 1), "\n" * 4)); |
| 95 new SourceLocation(12, line: 9, column: 1), | |
| 96 "\n" * 4)); | |
| 97 | 123 |
| 98 var mapping = parseJson(builder.build("foo.dart.js.map")); | 124 var mapping = parseJson(builder.build("foo.dart.js.map")); |
| 99 var frame = _mapTrace(mapping, trace, packageRoot: "packages/") | 125 var frame = |
| 100 .frames.first; | 126 _mapTrace(mapping, trace, packageRoot: "packages/").frames.first; |
| 101 expect(frame.uri, equals(Uri.parse("package:foo/foo.dart"))); | 127 expect(frame.uri, equals(Uri.parse("package:foo/foo.dart"))); |
| 102 expect(frame.line, equals(2)); | 128 expect(frame.line, equals(2)); |
| 103 expect(frame.column, equals(4)); | 129 expect(frame.column, equals(4)); |
| 104 }); | 130 }); |
| 105 | 131 |
| 106 test("uses package: URIs for frames within packageResolver.packageRoot", () { | 132 test("uses package: URIs for frames within packageResolver.packageRoot", () { |
| 107 var trace = new Trace.parse("foo.dart.js 10 foo"); | 133 var trace = new Trace.parse("foo.dart.js 10 foo"); |
| 108 var builder = new SourceMapBuilder() | 134 var builder = new SourceMapBuilder() |
| 109 ..addSpan( | 135 ..addSpan( |
| 110 new SourceMapSpan.identifier( | 136 new SourceMapSpan.identifier( |
| 111 new SourceLocation(1, | 137 new SourceLocation(1, |
| 112 line: 1, column: 3, sourceUrl: "packages/foo/foo.dart"), | 138 line: 1, column: 3, sourceUrl: "packages/foo/foo.dart"), |
| 113 "qux"), | 139 "qux"), |
| 114 new SourceSpan( | 140 new SourceSpan(new SourceLocation(8, line: 5, column: 0), |
| 115 new SourceLocation(8, line: 5, column: 0), | 141 new SourceLocation(12, line: 9, column: 1), "\n" * 4)); |
| 116 new SourceLocation(12, line: 9, column: 1), | |
| 117 "\n" * 4)); | |
| 118 | 142 |
| 119 var mapping = parseJson(builder.build("foo.dart.js.map")); | 143 var mapping = parseJson(builder.build("foo.dart.js.map")); |
| 120 var mappedTrace = _mapTrace(mapping, trace, | 144 var mappedTrace = _mapTrace(mapping, trace, |
| 121 packageResolver: new SyncPackageResolver.root("packages/")); | 145 packageResolver: new SyncPackageResolver.root("packages/")); |
| 122 var frame = mappedTrace.frames.first; | 146 var frame = mappedTrace.frames.first; |
| 123 expect(frame.uri, equals(Uri.parse("package:foo/foo.dart"))); | 147 expect(frame.uri, equals(Uri.parse("package:foo/foo.dart"))); |
| 124 expect(frame.line, equals(2)); | 148 expect(frame.line, equals(2)); |
| 125 expect(frame.column, equals(4)); | 149 expect(frame.column, equals(4)); |
| 126 }); | 150 }); |
| 127 | 151 |
| 128 test("uses package: URIs for frames within a packageResolver.packageMap URL", | 152 test("uses package: URIs for frames within a packageResolver.packageMap URL", |
| 129 () { | 153 () { |
| 130 var trace = new Trace.parse("foo.dart.js 10 foo"); | 154 var trace = new Trace.parse("foo.dart.js 10 foo"); |
| 131 var builder = new SourceMapBuilder() | 155 var builder = new SourceMapBuilder() |
| 132 ..addSpan( | 156 ..addSpan( |
| 133 new SourceMapSpan.identifier( | 157 new SourceMapSpan.identifier( |
| 134 new SourceLocation(1, | 158 new SourceLocation(1, |
| 135 line: 1, column: 3, sourceUrl: "packages/foo/foo.dart"), | 159 line: 1, column: 3, sourceUrl: "packages/foo/foo.dart"), |
| 136 "qux"), | 160 "qux"), |
| 137 new SourceSpan( | 161 new SourceSpan(new SourceLocation(8, line: 5, column: 0), |
| 138 new SourceLocation(8, line: 5, column: 0), | 162 new SourceLocation(12, line: 9, column: 1), "\n" * 4)); |
| 139 new SourceLocation(12, line: 9, column: 1), | |
| 140 "\n" * 4)); | |
| 141 | 163 |
| 142 var mapping = parseJson(builder.build("foo.dart.js.map")); | 164 var mapping = parseJson(builder.build("foo.dart.js.map")); |
| 143 var mappedTrace = _mapTrace(mapping, trace, | 165 var mappedTrace = _mapTrace(mapping, trace, |
| 144 packageResolver: new SyncPackageResolver.config({ | 166 packageResolver: |
| 145 "foo": Uri.parse("packages/foo") | 167 new SyncPackageResolver.config({"foo": Uri.parse("packages/foo")})); |
| 146 })); | |
| 147 var frame = mappedTrace.frames.first; | 168 var frame = mappedTrace.frames.first; |
| 148 expect(frame.uri, equals(Uri.parse("package:foo/foo.dart"))); | 169 expect(frame.uri, equals(Uri.parse("package:foo/foo.dart"))); |
| 149 expect(frame.line, equals(2)); | 170 expect(frame.line, equals(2)); |
| 150 expect(frame.column, equals(4)); | 171 expect(frame.column, equals(4)); |
| 151 }); | 172 }); |
| 152 | 173 |
| 153 test("uses dart: URIs for frames within sdkRoot", () { | 174 test("uses dart: URIs for frames within sdkRoot", () { |
| 154 var trace = new Trace.parse("foo.dart.js 10 foo"); | 175 var trace = new Trace.parse("foo.dart.js 10 foo"); |
| 155 var builder = new SourceMapBuilder() | 176 var builder = new SourceMapBuilder() |
| 156 ..addSpan( | 177 ..addSpan( |
| 157 new SourceMapSpan.identifier( | 178 new SourceMapSpan.identifier( |
| 158 new SourceLocation(1, | 179 new SourceLocation(1, |
| 159 line: 1, column: 3, sourceUrl: "sdk/lib/async/foo.dart"), | 180 line: 1, column: 3, sourceUrl: "sdk/lib/async/foo.dart"), |
| 160 "qux"), | 181 "qux"), |
| 161 new SourceSpan( | 182 new SourceSpan(new SourceLocation(8, line: 5, column: 0), |
| 162 new SourceLocation(8, line: 5, column: 0), | 183 new SourceLocation(12, line: 9, column: 1), "\n" * 4)); |
| 163 new SourceLocation(12, line: 9, column: 1), | |
| 164 "\n" * 4)); | |
| 165 | 184 |
| 166 var mapping = parseJson(builder.build("foo.dart.js.map")); | 185 var mapping = parseJson(builder.build("foo.dart.js.map")); |
| 167 var frame = _mapTrace(mapping, trace, sdkRoot: "sdk/").frames.first; | 186 var frame = _mapTrace(mapping, trace, sdkRoot: "sdk/").frames.first; |
| 168 expect(frame.uri, equals(Uri.parse("dart:async/foo.dart"))); | 187 expect(frame.uri, equals(Uri.parse("dart:async/foo.dart"))); |
| 169 expect(frame.line, equals(2)); | 188 expect(frame.line, equals(2)); |
| 170 expect(frame.column, equals(4)); | 189 expect(frame.column, equals(4)); |
| 171 }); | 190 }); |
| 172 | 191 |
| 173 test("converts a stack chain", () { | 192 test("converts a stack chain", () { |
| 174 var trace = new Chain([ | 193 var trace = new Chain([ |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 205 expect(_prettify(r"foo$1$bar"), equals("foo")); | 224 expect(_prettify(r"foo$1$bar"), equals("foo")); |
| 206 expect(_prettify(r"foo$123$bar$bang$qux"), equals("foo")); | 225 expect(_prettify(r"foo$123$bar$bang$qux"), equals("foo")); |
| 207 }); | 226 }); |
| 208 | 227 |
| 209 test("closures", () { | 228 test("closures", () { |
| 210 expect(_prettify("foo_closure.call"), equals("foo.<fn>")); | 229 expect(_prettify("foo_closure.call"), equals("foo.<fn>")); |
| 211 }); | 230 }); |
| 212 | 231 |
| 213 test("nested closures", () { | 232 test("nested closures", () { |
| 214 expect(_prettify("foo__closure.call"), equals("foo.<fn>.<fn>")); | 233 expect(_prettify("foo__closure.call"), equals("foo.<fn>.<fn>")); |
| 215 expect(_prettify("foo____closure.call"), | 234 expect( |
| 216 equals("foo.<fn>.<fn>.<fn>.<fn>")); | 235 _prettify("foo____closure.call"), equals("foo.<fn>.<fn>.<fn>.<fn>")); |
| 217 }); | 236 }); |
| 218 | 237 |
| 219 test(".call", () { | 238 test(".call", () { |
| 220 expect(_prettify("foo.call"), equals("foo")); | 239 expect(_prettify("foo.call"), equals("foo")); |
| 221 }); | 240 }); |
| 222 | 241 |
| 223 test("top-level functions", () { | 242 test("top-level functions", () { |
| 224 expect(_prettify("dart.foo"), equals("foo")); | 243 expect(_prettify("dart.foo"), equals("foo")); |
| 225 }); | 244 }); |
| 226 | 245 |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 239 test("lots of stuff", () { | 258 test("lots of stuff", () { |
| 240 expect(_prettify(r"lib$Foo.static.lib$Foo_closure.call$0/<"), | 259 expect(_prettify(r"lib$Foo.static.lib$Foo_closure.call$0/<"), |
| 241 equals("Foo.<fn>")); | 260 equals("Foo.<fn>")); |
| 242 }); | 261 }); |
| 243 }); | 262 }); |
| 244 } | 263 } |
| 245 | 264 |
| 246 /// Like [mapStackTrace], but is guaranteed to return a [Trace] so it can be | 265 /// Like [mapStackTrace], but is guaranteed to return a [Trace] so it can be |
| 247 /// inspected. | 266 /// inspected. |
| 248 Trace _mapTrace(Mapping sourceMap, StackTrace stackTrace, | 267 Trace _mapTrace(Mapping sourceMap, StackTrace stackTrace, |
| 249 {bool minified: false, SyncPackageResolver packageResolver, sdkRoot, | 268 {bool minified: false, |
| 269 SyncPackageResolver packageResolver, | |
| 270 sdkRoot, | |
| 250 packageRoot}) { | 271 packageRoot}) { |
| 251 return new Trace.from(mapStackTrace(sourceMap, stackTrace, | 272 return new Trace.from(mapStackTrace(sourceMap, stackTrace, |
| 252 minified: minified, packageResolver: packageResolver, sdkRoot: sdkRoot, | 273 minified: minified, |
| 274 packageResolver: packageResolver, | |
| 275 sdkRoot: sdkRoot, | |
| 253 packageRoot: packageRoot)); | 276 packageRoot: packageRoot)); |
| 254 } | 277 } |
| 255 | 278 |
| 256 /// Like [mapStackTrace], but is guaranteed to return a [Chain] so it can be | 279 /// Like [mapStackTrace], but is guaranteed to return a [Chain] so it can be |
| 257 /// inspected. | 280 /// inspected. |
| 258 Chain _mapChain(Mapping sourceMap, StackTrace stackTrace, | 281 Chain _mapChain(Mapping sourceMap, StackTrace stackTrace, |
| 259 {bool minified: false, SyncPackageResolver packageResolver, sdkRoot, | 282 {bool minified: false, |
| 283 SyncPackageResolver packageResolver, | |
| 284 sdkRoot, | |
| 260 packageRoot}) { | 285 packageRoot}) { |
| 261 return new Chain.forTrace(mapStackTrace(sourceMap, stackTrace, | 286 return new Chain.forTrace(mapStackTrace(sourceMap, stackTrace, |
| 262 minified: minified, packageResolver: packageResolver, sdkRoot: sdkRoot, | 287 minified: minified, |
| 288 packageResolver: packageResolver, | |
| 289 sdkRoot: sdkRoot, | |
| 263 packageRoot: packageRoot)); | 290 packageRoot: packageRoot)); |
| 264 } | 291 } |
| 265 | 292 |
| 266 /// Runs the mapper's prettification logic on [member] and returns the result. | 293 /// Runs the mapper's prettification logic on [member] and returns the result. |
| 267 String _prettify(String member) { | 294 String _prettify(String member) { |
| 268 var trace = new Trace([new Frame(Uri.parse("foo.dart.js"), 10, 11, member)]); | 295 var trace = new Trace([new Frame(Uri.parse("foo.dart.js"), 10, 11, member)]); |
| 269 return _mapTrace(_simpleMapping, trace).frames.first.member; | 296 return _mapTrace(_simpleMapping, trace).frames.first.member; |
| 270 } | 297 } |
| OLD | NEW |