| Index: mojo/public/dart/third_party/stack_trace/test/trace_test.dart
|
| diff --git a/mojo/public/dart/third_party/stack_trace/test/trace_test.dart b/mojo/public/dart/third_party/stack_trace/test/trace_test.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..d12bc71f1706822218f19b5bf2796b6376fd29a7
|
| --- /dev/null
|
| +++ b/mojo/public/dart/third_party/stack_trace/test/trace_test.dart
|
| @@ -0,0 +1,430 @@
|
| +// Copyright (c) 2013, 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.
|
| +
|
| +library trace_test;
|
| +
|
| +import 'package:path/path.dart' as path;
|
| +import 'package:stack_trace/stack_trace.dart';
|
| +import 'package:test/test.dart';
|
| +
|
| +String getStackTraceString() {
|
| + try {
|
| + throw '';
|
| + } catch (_, stackTrace) {
|
| + return stackTrace.toString();
|
| + }
|
| +}
|
| +
|
| +StackTrace getStackTraceObject() {
|
| + try {
|
| + throw '';
|
| + } catch (_, stackTrace) {
|
| + return stackTrace;
|
| + }
|
| +}
|
| +
|
| +Trace getCurrentTrace([int level]) => new Trace.current(level);
|
| +
|
| +Trace nestedGetCurrentTrace(int level) => getCurrentTrace(level);
|
| +
|
| +void main() {
|
| + // This just shouldn't crash.
|
| + test('a native stack trace is parseable', () => new Trace.current());
|
| +
|
| + group('.parse', () {
|
| + test('.parse parses a VM stack trace correctly', () {
|
| + var trace = new Trace.parse(
|
| + '#0 Foo._bar (file:///home/nweiz/code/stuff.dart:42:21)\n'
|
| + '#1 zip.<anonymous closure>.zap (dart:async/future.dart:0:2)\n'
|
| + '#2 zip.<anonymous closure>.zap (http://pub.dartlang.org/thing.'
|
| + 'dart:1:100)');
|
| +
|
| + expect(trace.frames[0].uri,
|
| + equals(Uri.parse("file:///home/nweiz/code/stuff.dart")));
|
| + expect(trace.frames[1].uri, equals(Uri.parse("dart:async/future.dart")));
|
| + expect(trace.frames[2].uri,
|
| + equals(Uri.parse("http://pub.dartlang.org/thing.dart")));
|
| + });
|
| +
|
| + test('parses a V8 stack trace correctly', () {
|
| + var trace = new Trace.parse(
|
| + 'Error\n'
|
| + ' at Foo._bar (http://pub.dartlang.org/stuff.js:42:21)\n'
|
| + ' at http://pub.dartlang.org/stuff.js:0:2\n'
|
| + ' at zip.<anonymous>.zap '
|
| + '(http://pub.dartlang.org/thing.js:1:100)');
|
| +
|
| + expect(trace.frames[0].uri,
|
| + equals(Uri.parse("http://pub.dartlang.org/stuff.js")));
|
| + expect(trace.frames[1].uri,
|
| + equals(Uri.parse("http://pub.dartlang.org/stuff.js")));
|
| + expect(trace.frames[2].uri,
|
| + equals(Uri.parse("http://pub.dartlang.org/thing.js")));
|
| +
|
| + trace = new Trace.parse(
|
| + "Exception: foo\n"
|
| + ' at Foo._bar (http://pub.dartlang.org/stuff.js:42:21)\n'
|
| + ' at http://pub.dartlang.org/stuff.js:0:2\n'
|
| + ' at zip.<anonymous>.zap '
|
| + '(http://pub.dartlang.org/thing.js:1:100)');
|
| +
|
| + expect(trace.frames[0].uri,
|
| + equals(Uri.parse("http://pub.dartlang.org/stuff.js")));
|
| + expect(trace.frames[1].uri,
|
| + equals(Uri.parse("http://pub.dartlang.org/stuff.js")));
|
| + expect(trace.frames[2].uri,
|
| + equals(Uri.parse("http://pub.dartlang.org/thing.js")));
|
| +
|
| + trace = new Trace.parse(
|
| + 'Exception: foo\n'
|
| + ' bar\n'
|
| + ' at Foo._bar (http://pub.dartlang.org/stuff.js:42:21)\n'
|
| + ' at http://pub.dartlang.org/stuff.js:0:2\n'
|
| + ' at zip.<anonymous>.zap '
|
| + '(http://pub.dartlang.org/thing.js:1:100)');
|
| +
|
| + expect(trace.frames[0].uri,
|
| + equals(Uri.parse("http://pub.dartlang.org/stuff.js")));
|
| + expect(trace.frames[1].uri,
|
| + equals(Uri.parse("http://pub.dartlang.org/stuff.js")));
|
| + expect(trace.frames[2].uri,
|
| + equals(Uri.parse("http://pub.dartlang.org/thing.js")));
|
| + });
|
| +
|
| + // JavaScriptCore traces are just like V8, except that it doesn't have a
|
| + // header and it starts with a tab rather than spaces.
|
| + test('parses a JavaScriptCore stack trace correctly', () {
|
| + var trace = new Trace.parse(
|
| + '\tat Foo._bar (http://pub.dartlang.org/stuff.js:42:21)\n'
|
| + '\tat http://pub.dartlang.org/stuff.js:0:2\n'
|
| + '\tat zip.<anonymous>.zap '
|
| + '(http://pub.dartlang.org/thing.js:1:100)');
|
| +
|
| + expect(trace.frames[0].uri,
|
| + equals(Uri.parse("http://pub.dartlang.org/stuff.js")));
|
| + expect(trace.frames[1].uri,
|
| + equals(Uri.parse("http://pub.dartlang.org/stuff.js")));
|
| + expect(trace.frames[2].uri,
|
| + equals(Uri.parse("http://pub.dartlang.org/thing.js")));
|
| +
|
| + trace = new Trace.parse(
|
| + '\tat Foo._bar (http://pub.dartlang.org/stuff.js:42:21)\n'
|
| + '\tat \n'
|
| + '\tat zip.<anonymous>.zap '
|
| + '(http://pub.dartlang.org/thing.js:1:100)');
|
| +
|
| + expect(trace.frames[0].uri,
|
| + equals(Uri.parse("http://pub.dartlang.org/stuff.js")));
|
| + expect(trace.frames[1].uri,
|
| + equals(Uri.parse("http://pub.dartlang.org/thing.js")));
|
| + });
|
| +
|
| + test('parses a Firefox/Safari stack trace correctly', () {
|
| + var trace = new Trace.parse(
|
| + 'Foo._bar@http://pub.dartlang.org/stuff.js:42\n'
|
| + 'zip/<@http://pub.dartlang.org/stuff.js:0\n'
|
| + 'zip.zap(12, "@)()/<")@http://pub.dartlang.org/thing.js:1');
|
| +
|
| + expect(trace.frames[0].uri,
|
| + equals(Uri.parse("http://pub.dartlang.org/stuff.js")));
|
| + expect(trace.frames[1].uri,
|
| + equals(Uri.parse("http://pub.dartlang.org/stuff.js")));
|
| + expect(trace.frames[2].uri,
|
| + equals(Uri.parse("http://pub.dartlang.org/thing.js")));
|
| +
|
| + trace = new Trace.parse(
|
| + 'zip/<@http://pub.dartlang.org/stuff.js:0\n'
|
| + 'Foo._bar@http://pub.dartlang.org/stuff.js:42\n'
|
| + 'zip.zap(12, "@)()/<")@http://pub.dartlang.org/thing.js:1');
|
| +
|
| + expect(trace.frames[0].uri,
|
| + equals(Uri.parse("http://pub.dartlang.org/stuff.js")));
|
| + expect(trace.frames[1].uri,
|
| + equals(Uri.parse("http://pub.dartlang.org/stuff.js")));
|
| + expect(trace.frames[2].uri,
|
| + equals(Uri.parse("http://pub.dartlang.org/thing.js")));
|
| +
|
| + trace = new Trace.parse(
|
| + 'zip.zap(12, "@)()/<")@http://pub.dartlang.org/thing.js:1\n'
|
| + 'zip/<@http://pub.dartlang.org/stuff.js:0\n'
|
| + 'Foo._bar@http://pub.dartlang.org/stuff.js:42');
|
| +
|
| + expect(trace.frames[0].uri,
|
| + equals(Uri.parse("http://pub.dartlang.org/thing.js")));
|
| + expect(trace.frames[1].uri,
|
| + equals(Uri.parse("http://pub.dartlang.org/stuff.js")));
|
| + expect(trace.frames[2].uri,
|
| + equals(Uri.parse("http://pub.dartlang.org/stuff.js")));
|
| + });
|
| +
|
| + test('parses a Firefox/Safari stack trace containing native code correctly',
|
| + () {
|
| + var trace = new Trace.parse(
|
| + 'Foo._bar@http://pub.dartlang.org/stuff.js:42\n'
|
| + 'zip/<@http://pub.dartlang.org/stuff.js:0\n'
|
| + 'zip.zap(12, "@)()/<")@http://pub.dartlang.org/thing.js:1\n'
|
| + '[native code]');
|
| +
|
| + expect(trace.frames[0].uri,
|
| + equals(Uri.parse("http://pub.dartlang.org/stuff.js")));
|
| + expect(trace.frames[1].uri,
|
| + equals(Uri.parse("http://pub.dartlang.org/stuff.js")));
|
| + expect(trace.frames[2].uri,
|
| + equals(Uri.parse("http://pub.dartlang.org/thing.js")));
|
| + expect(trace.frames.length, equals(3));
|
| + });
|
| +
|
| + test('parses a Firefox/Safari stack trace without a method name correctly',
|
| + () {
|
| + var trace = new Trace.parse(
|
| + 'http://pub.dartlang.org/stuff.js:42\n'
|
| + 'zip/<@http://pub.dartlang.org/stuff.js:0\n'
|
| + 'zip.zap(12, "@)()/<")@http://pub.dartlang.org/thing.js:1');
|
| +
|
| + expect(trace.frames[0].uri,
|
| + equals(Uri.parse("http://pub.dartlang.org/stuff.js")));
|
| + expect(trace.frames[0].member, equals('<fn>'));
|
| + expect(trace.frames[1].uri,
|
| + equals(Uri.parse("http://pub.dartlang.org/stuff.js")));
|
| + expect(trace.frames[2].uri,
|
| + equals(Uri.parse("http://pub.dartlang.org/thing.js")));
|
| + });
|
| +
|
| + test('parses a Firefox/Safari stack trace with an empty line correctly',
|
| + () {
|
| + var trace = new Trace.parse(
|
| + 'Foo._bar@http://pub.dartlang.org/stuff.js:42\n'
|
| + '\n'
|
| + 'zip/<@http://pub.dartlang.org/stuff.js:0\n'
|
| + 'zip.zap(12, "@)()/<")@http://pub.dartlang.org/thing.js:1');
|
| +
|
| + expect(trace.frames[0].uri,
|
| + equals(Uri.parse("http://pub.dartlang.org/stuff.js")));
|
| + expect(trace.frames[1].uri,
|
| + equals(Uri.parse("http://pub.dartlang.org/stuff.js")));
|
| + expect(trace.frames[2].uri,
|
| + equals(Uri.parse("http://pub.dartlang.org/thing.js")));
|
| + });
|
| +
|
| + test('parses a Firefox/Safari stack trace with a column number correctly',
|
| + () {
|
| + var trace = new Trace.parse(
|
| + 'Foo._bar@http://pub.dartlang.org/stuff.js:42:2\n'
|
| + 'zip/<@http://pub.dartlang.org/stuff.js:0\n'
|
| + 'zip.zap(12, "@)()/<")@http://pub.dartlang.org/thing.js:1');
|
| +
|
| + expect(trace.frames[0].uri,
|
| + equals(Uri.parse("http://pub.dartlang.org/stuff.js")));
|
| + expect(trace.frames[0].line, equals(42));
|
| + expect(trace.frames[0].column, equals(2));
|
| + expect(trace.frames[1].uri,
|
| + equals(Uri.parse("http://pub.dartlang.org/stuff.js")));
|
| + expect(trace.frames[2].uri,
|
| + equals(Uri.parse("http://pub.dartlang.org/thing.js")));
|
| + });
|
| +
|
| + test('parses a package:stack_trace stack trace correctly', () {
|
| + var trace = new Trace.parse(
|
| + 'http://dartlang.org/foo/bar.dart 10:11 Foo.<fn>.bar\n'
|
| + 'http://dartlang.org/foo/baz.dart Foo.<fn>.bar');
|
| +
|
| + expect(trace.frames[0].uri,
|
| + equals(Uri.parse("http://dartlang.org/foo/bar.dart")));
|
| + expect(trace.frames[1].uri,
|
| + equals(Uri.parse("http://dartlang.org/foo/baz.dart")));
|
| + });
|
| +
|
| + test('parses a package:stack_trace stack chain correctly', () {
|
| + var trace = new Trace.parse(
|
| + 'http://dartlang.org/foo/bar.dart 10:11 Foo.<fn>.bar\n'
|
| + 'http://dartlang.org/foo/baz.dart Foo.<fn>.bar\n'
|
| + '===== asynchronous gap ===========================\n'
|
| + 'http://dartlang.org/foo/bang.dart 10:11 Foo.<fn>.bar\n'
|
| + 'http://dartlang.org/foo/quux.dart Foo.<fn>.bar');
|
| +
|
| + expect(trace.frames[0].uri,
|
| + equals(Uri.parse("http://dartlang.org/foo/bar.dart")));
|
| + expect(trace.frames[1].uri,
|
| + equals(Uri.parse("http://dartlang.org/foo/baz.dart")));
|
| + expect(trace.frames[2].uri,
|
| + equals(Uri.parse("http://dartlang.org/foo/bang.dart")));
|
| + expect(trace.frames[3].uri,
|
| + equals(Uri.parse("http://dartlang.org/foo/quux.dart")));
|
| + });
|
| +
|
| + test('parses a real package:stack_trace stack trace correctly', () {
|
| + var traceString = new Trace.current().toString();
|
| + expect(new Trace.parse(traceString).toString(), equals(traceString));
|
| + });
|
| +
|
| + test('parses an empty string correctly', () {
|
| + var trace = new Trace.parse('');
|
| + expect(trace.frames, isEmpty);
|
| + expect(trace.toString(), equals(''));
|
| + });
|
| + });
|
| +
|
| + test('.toString() nicely formats the stack trace', () {
|
| + var trace = new Trace.parse('''
|
| +#0 Foo._bar (foo/bar.dart:42:21)
|
| +#1 zip.<anonymous closure>.zap (dart:async/future.dart:0:2)
|
| +#2 zip.<anonymous closure>.zap (http://pub.dartlang.org/thing.dart:1:100)
|
| +''');
|
| +
|
| + expect(trace.toString(), equals('''
|
| +${path.join('foo', 'bar.dart')} 42:21 Foo._bar
|
| +dart:async/future.dart 0:2 zip.<fn>.zap
|
| +http://pub.dartlang.org/thing.dart 1:100 zip.<fn>.zap
|
| +'''));
|
| + });
|
| +
|
| + test('.vmTrace returns a native-style trace', () {
|
| + var uri = path.toUri(path.absolute('foo'));
|
| + var trace = new Trace([
|
| + new Frame(uri, 10, 20, 'Foo.<fn>'),
|
| + new Frame(Uri.parse('http://dartlang.org/foo.dart'), null, null, 'bar'),
|
| + new Frame(Uri.parse('dart:async'), 15, null, 'baz'),
|
| + ]);
|
| +
|
| + expect(trace.vmTrace.toString(), equals(
|
| + '#1 Foo.<anonymous closure> ($uri:10:20)\n'
|
| + '#2 bar (http://dartlang.org/foo.dart:0:0)\n'
|
| + '#3 baz (dart:async:15:0)\n'));
|
| + });
|
| +
|
| + group("folding", () {
|
| + test('.terse folds core frames together bottom-up', () {
|
| + var trace = new Trace.parse('''
|
| +#1 top (dart:async/future.dart:0:2)
|
| +#2 bottom (dart:core/uri.dart:1:100)
|
| +#0 notCore (foo.dart:42:21)
|
| +#3 top (dart:io:5:10)
|
| +#4 bottom (dart:async-patch/future.dart:9:11)
|
| +#5 alsoNotCore (bar.dart:10:20)
|
| +''');
|
| +
|
| + expect(trace.terse.toString(), equals('''
|
| +dart:core bottom
|
| +foo.dart 42:21 notCore
|
| +dart:async bottom
|
| +bar.dart 10:20 alsoNotCore
|
| +'''));
|
| + });
|
| +
|
| + test('.terse folds empty async frames', () {
|
| + var trace = new Trace.parse('''
|
| +#0 top (dart:async/future.dart:0:2)
|
| +#1 empty.<<anonymous closure>_async_body> (bar.dart)
|
| +#2 bottom (dart:async-patch/future.dart:9:11)
|
| +#3 notCore (foo.dart:42:21)
|
| +''');
|
| +
|
| + expect(trace.terse.toString(), equals('''
|
| +dart:async bottom
|
| +foo.dart 42:21 notCore
|
| +'''));
|
| + });
|
| +
|
| + test('.terse removes the bottom-most async frame', () {
|
| + var trace = new Trace.parse('''
|
| +#0 notCore (foo.dart:42:21)
|
| +#1 top (dart:async/future.dart:0:2)
|
| +#2 bottom (dart:core/uri.dart:1:100)
|
| +#3 top (dart:io:5:10)
|
| +#4 bottom (dart:async-patch/future.dart:9:11)
|
| +''');
|
| +
|
| + expect(trace.terse.toString(), equals('''
|
| +foo.dart 42:21 notCore
|
| +'''));
|
| + });
|
| +
|
| + test(".terse won't make a trace empty", () {
|
| + var trace = new Trace.parse('''
|
| +#1 top (dart:async/future.dart:0:2)
|
| +#2 bottom (dart:core/uri.dart:1:100)
|
| +''');
|
| +
|
| + expect(trace.terse.toString(), equals('''
|
| +dart:core bottom
|
| +'''));
|
| + });
|
| +
|
| + test(".terse won't panic on an empty trace", () {
|
| + expect(new Trace.parse("").terse.toString(), equals(""));
|
| + });
|
| +
|
| + test('.foldFrames folds frames together bottom-up', () {
|
| + var trace = new Trace.parse('''
|
| +#0 notFoo (foo.dart:42:21)
|
| +#1 fooTop (bar.dart:0:2)
|
| +#2 fooBottom (foo.dart:1:100)
|
| +#3 alsoNotFoo (bar.dart:10:20)
|
| +#4 fooTop (dart:io/socket.dart:5:10)
|
| +#5 fooBottom (dart:async-patch/future.dart:9:11)
|
| +''');
|
| +
|
| + var folded = trace.foldFrames((frame) => frame.member.startsWith('foo'));
|
| + expect(folded.toString(), equals('''
|
| +foo.dart 42:21 notFoo
|
| +foo.dart 1:100 fooBottom
|
| +bar.dart 10:20 alsoNotFoo
|
| +dart:async-patch/future.dart 9:11 fooBottom
|
| +'''));
|
| + });
|
| +
|
| + test('.foldFrames with terse: true folds core frames as well', () {
|
| + var trace = new Trace.parse('''
|
| +#0 notFoo (foo.dart:42:21)
|
| +#1 fooTop (bar.dart:0:2)
|
| +#2 coreBottom (dart:async/future.dart:0:2)
|
| +#3 alsoNotFoo (bar.dart:10:20)
|
| +#4 fooTop (foo.dart:9:11)
|
| +#5 coreBottom (dart:async-patch/future.dart:9:11)
|
| +''');
|
| +
|
| + var folded = trace.foldFrames((frame) => frame.member.startsWith('foo'),
|
| + terse: true);
|
| + expect(folded.toString(), equals('''
|
| +foo.dart 42:21 notFoo
|
| +dart:async coreBottom
|
| +bar.dart 10:20 alsoNotFoo
|
| +'''));
|
| + });
|
| +
|
| + test('.foldFrames with terse: true shortens folded frames', () {
|
| + var trace = new Trace.parse('''
|
| +#0 notFoo (foo.dart:42:21)
|
| +#1 fooTop (bar.dart:0:2)
|
| +#2 fooBottom (package:foo/bar.dart:0:2)
|
| +#3 alsoNotFoo (bar.dart:10:20)
|
| +#4 fooTop (foo.dart:9:11)
|
| +#5 fooBottom (foo/bar.dart:9:11)
|
| +''');
|
| +
|
| + var folded = trace.foldFrames((frame) => frame.member.startsWith('foo'),
|
| + terse: true);
|
| + expect(folded.toString(), equals('''
|
| +foo.dart 42:21 notFoo
|
| +package:foo fooBottom
|
| +bar.dart 10:20 alsoNotFoo
|
| +foo fooBottom
|
| +'''));
|
| + });
|
| +
|
| + test('.foldFrames will never fold unparsed frames', () {
|
| + var trace = new Trace.parse(r'''
|
| +.g"cs$#:b";a#>sw{*{ul$"$xqwr`p
|
| +%+j-?uppx<([j@#nu{{>*+$%x-={`{
|
| +!e($b{nj)zs?cgr%!;bmw.+$j+pfj~
|
| +''');
|
| +
|
| + expect(trace.foldFrames((frame) => true).toString(), equals(r'''
|
| +.g"cs$#:b";a#>sw{*{ul$"$xqwr`p
|
| +%+j-?uppx<([j@#nu{{>*+$%x-={`{
|
| +!e($b{nj)zs?cgr%!;bmw.+$j+pfj~
|
| +'''));
|
| + });
|
| + });
|
| +}
|
|
|