Use the stack_trace library in scheduled_test. This also adds a couple features to stack_trace. Review URL: https://codereview.chromium.org//13157004 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/stack_trace@20752 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/pkgs/stack_trace/lib/src/frame.dart b/pkgs/stack_trace/lib/src/frame.dart index 5f0777c..f05b469 100644 --- a/pkgs/stack_trace/lib/src/frame.dart +++ b/pkgs/stack_trace/lib/src/frame.dart
@@ -46,6 +46,13 @@ return path.relative(fileUriToPath(uri)); } + /// Returns the name of the package this stack frame comes from, or `null` if + /// this stack frame doesn't come from a `package:` URL. + String get package { + if (uri.scheme != 'package') return null; + return uri.path.split('/').first; + } + /// A human-friendly description of the code location. /// /// For Dart core libraries, this will omit the line and column information,
diff --git a/pkgs/stack_trace/lib/src/trace.dart b/pkgs/stack_trace/lib/src/trace.dart index 1ab7695..43a598c 100644 --- a/pkgs/stack_trace/lib/src/trace.dart +++ b/pkgs/stack_trace/lib/src/trace.dart
@@ -79,19 +79,32 @@ String get fullStackTrace => toString(); /// Returns a terser version of [this]. This is accomplished by folding - /// together multiple stack frames from the core library. If multiple such - /// frames appear in a row, only the last (the one directly called by user - /// code) is kept. Core library patches are also renamed to remove their - /// `-patch` suffix. + /// together multiple stack frames from the core library, as in [foldFrames]. + /// Core library patches are also renamed to remove their `-patch` suffix. Trace get terse { + return new Trace(foldFrames((frame) => frame.isCore).frames.map((frame) { + if (!frame.isCore) return frame; + var library = frame.library.replaceAll(_patchRegExp, ''); + return new Frame( + Uri.parse(library), frame.line, frame.column, frame.member); + })); + } + + /// Returns a new [Trace] based on [this] where multiple stack frames matching + /// [predicate] are folded together. This means that whenever there are + /// multiple frames in a row that match [predicate], only the last one is + /// kept. + /// + /// This is useful for limiting the amount of library code that appears in a + /// stack trace by only showing user code and code that's called by user code. + Trace foldFrames(bool predicate(frame)) { var newFrames = <Frame>[]; for (var frame in frames.reversed) { - if (!frame.isCore) { + if (!predicate(frame)) { newFrames.add(frame); - } else if (newFrames.isEmpty || !newFrames.last.isCore) { - var library = frame.library.replaceAll(_patchRegExp, ''); + } else if (newFrames.isEmpty || !predicate(newFrames.last)) { newFrames.add(new Frame( - Uri.parse(library), frame.line, frame.column, frame.member)); + frame.uri, frame.line, frame.column, frame.member)); } }
diff --git a/pkgs/stack_trace/test/frame_test.dart b/pkgs/stack_trace/test/frame_test.dart index c65f395..02bec68 100644 --- a/pkgs/stack_trace/test/frame_test.dart +++ b/pkgs/stack_trace/test/frame_test.dart
@@ -139,6 +139,22 @@ }); }); + group('.package', () { + test('returns null for non-package URIs', () { + expect(new Frame.parse('#0 Foo (dart:async:0:0)').package, isNull); + expect(new Frame.parse('#0 Foo ' + '(http://dartlang.org/stuff/thing.dart:0:0)').package, + isNull); + }); + + test('returns the package name for package: URIs', () { + expect(new Frame.parse('#0 Foo (package:foo/foo.dart:0:0)').package, + equals('foo')); + expect(new Frame.parse('#0 Foo (package:foo/zap/bar.dart:0:0)').package, + equals('foo')); + }); + }); + group('.toString()', () { test('returns the library and line/column numbers for non-core ' 'libraries', () {
diff --git a/pkgs/stack_trace/test/trace_test.dart b/pkgs/stack_trace/test/trace_test.dart index ed8fa6b..cbbf90b 100644 --- a/pkgs/stack_trace/test/trace_test.dart +++ b/pkgs/stack_trace/test/trace_test.dart
@@ -133,4 +133,23 @@ dart:async bottom ''')); }); + + 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:5:10) +#5 fooBottom (dart:async-patch: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 fooBottom +''')); + }); }