Remove the outermost folded frame in terse mode. (#21)
We always removed this frame if it was a core library frame,
which (until recent SDK releases) it always was. Now that the
boilerplate core library frames have been removed, we should
remove *any* folded frame.
This partially addresses dart-lang/test#555
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 53cdd37..db53c73 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,10 @@
## 1.7.2
+
+* `Trace.foldFrames()` and `Chain.foldFrames()` now remove the outermost folded
+ frame. This matches the behavior of `.terse` with core frames.
+
* Fix bug parsing a friendly frame with spaces in the member name.
+
* Fix bug parsing a friendly frame where the location is a data url.
## 1.7.1
diff --git a/lib/src/trace.dart b/lib/src/trace.dart
index eb8ecd8..9edee6e 100644
--- a/lib/src/trace.dart
+++ b/lib/src/trace.dart
@@ -285,7 +285,10 @@
var library = frame.library.replaceAll(_terseRegExp, '');
return new Frame(Uri.parse(library), null, null, frame.member);
}).toList();
- if (newFrames.length > 1 && newFrames.first.isCore) newFrames.removeAt(0);
+
+ if (newFrames.length > 1 && predicate(newFrames.first)) {
+ newFrames.removeAt(0);
+ }
}
return new Trace(newFrames.reversed);
diff --git a/test/chain/chain_test.dart b/test/chain/chain_test.dart
index 301f338..60137c8 100644
--- a/test/chain/chain_test.dart
+++ b/test/chain/chain_test.dart
@@ -269,7 +269,6 @@
expect(folded.toString(), equals(
'dart:async Zip.zap\n'
'b.dart 10:11 Bang.qux\n'
- 'a.dart Zop.zoop\n'
'===== asynchronous gap ===========================\n'
'a.dart Zip.zap\n'
'b.dart 10:11 Zop.zoop\n'));
@@ -325,4 +324,4 @@
'$userSlashCode 10:11 Foo.bar\n'
'dart:core 10:11 Bar.baz\n'));
});
-}
\ No newline at end of file
+}
diff --git a/test/trace_test.dart b/test/trace_test.dart
index 327eff0..1297932 100644
--- a/test/trace_test.dart
+++ b/test/trace_test.dart
@@ -293,8 +293,9 @@
});
group("folding", () {
- test('.terse folds core frames together bottom-up', () {
- var trace = new Trace.parse('''
+ group(".terse", () {
+ test('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)
@@ -303,30 +304,30 @@
#5 alsoNotCore (bar.dart:10:20)
''');
- expect(trace.terse.toString(), equals('''
+ 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('''
+ test('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('''
+ 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('''
+ test('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)
@@ -337,25 +338,27 @@
expect(trace.terse.toString(), equals('''
foo.dart 42:21 notCore
'''));
- });
+ });
- test(".terse won't make a trace empty", () {
- var trace = new Trace.parse('''
+ test("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('''
+ expect(trace.terse.toString(), equals('''
dart:core bottom
'''));
+ });
+
+ test("won't panic on an empty trace", () {
+ expect(new Trace.parse("").terse.toString(), equals(""));
+ });
});
- 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('''
+ group(".foldFrames", () {
+ test('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)
@@ -364,17 +367,32 @@
#5 fooBottom (dart:async-patch/future.dart:9:11)
''');
- var folded = trace.foldFrames((frame) => frame.member.startsWith('foo'));
- expect(folded.toString(), equals('''
+ 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('''
+ test('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~
+'''));
+ });
+
+ group("with terse: true", () {
+ test('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)
@@ -383,47 +401,52 @@
#5 coreBottom (dart:async-patch/future.dart:9:11)
''');
- var folded = trace.foldFrames((frame) => frame.member.startsWith('foo'),
- terse: true);
- expect(folded.toString(), equals('''
+ 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('''
+ test('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)
+#6 againNotFoo (bar.dart:20:20)
''');
- var folded = trace.foldFrames((frame) => frame.member.startsWith('foo'),
- terse: true);
- expect(folded.toString(), equals('''
+ 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
+bar.dart 20:20 againNotFoo
'''));
- });
+ });
- 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~
+ test('removes the bottom-most folded frame', () {
+ var trace = new Trace.parse('''
+#2 fooTop (package:foo/bar.dart:0:2)
+#3 notFoo (bar.dart:10:20)
+#5 fooBottom (foo/bar.dart:9:11)
''');
- 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~
+ var folded = trace.foldFrames((frame) => frame.member.startsWith('foo'),
+ terse: true);
+ expect(folded.toString(), equals('''
+package:foo fooTop
+bar.dart 10:20 notFoo
'''));
+ });
+ });
});
});
}