OLD | NEW |
(Empty) | |
| 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 |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 import 'dart:async'; |
| 6 |
| 7 import 'package:path/path.dart' as p; |
| 8 import 'package:stack_trace/stack_trace.dart'; |
| 9 import 'package:test/test.dart'; |
| 10 |
| 11 import 'utils.dart'; |
| 12 |
| 13 void main() { |
| 14 group('Chain.parse()', () { |
| 15 test('parses a real Chain', () { |
| 16 return captureFuture(() => inMicrotask(() => throw 'error')) |
| 17 .then((chain) { |
| 18 expect(new Chain.parse(chain.toString()).toString(), |
| 19 equals(chain.toString())); |
| 20 }); |
| 21 }); |
| 22 |
| 23 test('parses an empty string', () { |
| 24 var chain = new Chain.parse(''); |
| 25 expect(chain.traces, isEmpty); |
| 26 }); |
| 27 |
| 28 test('parses a chain containing empty traces', () { |
| 29 var chain = new Chain.parse( |
| 30 '===== asynchronous gap ===========================\n' |
| 31 '===== asynchronous gap ===========================\n'); |
| 32 expect(chain.traces, hasLength(3)); |
| 33 expect(chain.traces[0].frames, isEmpty); |
| 34 expect(chain.traces[1].frames, isEmpty); |
| 35 expect(chain.traces[2].frames, isEmpty); |
| 36 }); |
| 37 }); |
| 38 |
| 39 test("toString() ensures that all traces are aligned", () { |
| 40 var chain = new Chain([ |
| 41 new Trace.parse('short 10:11 Foo.bar\n'), |
| 42 new Trace.parse('loooooooooooong 10:11 Zop.zoop') |
| 43 ]); |
| 44 |
| 45 expect(chain.toString(), equals( |
| 46 'short 10:11 Foo.bar\n' |
| 47 '===== asynchronous gap ===========================\n' |
| 48 'loooooooooooong 10:11 Zop.zoop\n')); |
| 49 }); |
| 50 |
| 51 var userSlashCode = p.join('user', 'code.dart'); |
| 52 group('Chain.terse', () { |
| 53 test('makes each trace terse', () { |
| 54 var chain = new Chain([ |
| 55 new Trace.parse( |
| 56 'dart:core 10:11 Foo.bar\n' |
| 57 'dart:core 10:11 Bar.baz\n' |
| 58 'user/code.dart 10:11 Bang.qux\n' |
| 59 'dart:core 10:11 Zip.zap\n' |
| 60 'dart:core 10:11 Zop.zoop'), |
| 61 new Trace.parse( |
| 62 'user/code.dart 10:11 Bang.qux\n' |
| 63 'dart:core 10:11 Foo.bar\n' |
| 64 'package:stack_trace/stack_trace.dart 10:11 Bar.baz\n' |
| 65 'dart:core 10:11 Zip.zap\n' |
| 66 'user/code.dart 10:11 Zop.zoop') |
| 67 ]); |
| 68 |
| 69 expect(chain.terse.toString(), equals( |
| 70 'dart:core Bar.baz\n' |
| 71 '$userSlashCode 10:11 Bang.qux\n' |
| 72 '===== asynchronous gap ===========================\n' |
| 73 '$userSlashCode 10:11 Bang.qux\n' |
| 74 'dart:core Zip.zap\n' |
| 75 '$userSlashCode 10:11 Zop.zoop\n')); |
| 76 }); |
| 77 |
| 78 test('eliminates internal-only traces', () { |
| 79 var chain = new Chain([ |
| 80 new Trace.parse( |
| 81 'user/code.dart 10:11 Foo.bar\n' |
| 82 'dart:core 10:11 Bar.baz'), |
| 83 new Trace.parse( |
| 84 'dart:core 10:11 Foo.bar\n' |
| 85 'package:stack_trace/stack_trace.dart 10:11 Bar.baz\n' |
| 86 'dart:core 10:11 Zip.zap'), |
| 87 new Trace.parse( |
| 88 'user/code.dart 10:11 Foo.bar\n' |
| 89 'dart:core 10:11 Bar.baz') |
| 90 ]); |
| 91 |
| 92 expect(chain.terse.toString(), equals( |
| 93 '$userSlashCode 10:11 Foo.bar\n' |
| 94 '===== asynchronous gap ===========================\n' |
| 95 '$userSlashCode 10:11 Foo.bar\n')); |
| 96 }); |
| 97 |
| 98 test("doesn't return an empty chain", () { |
| 99 var chain = new Chain([ |
| 100 new Trace.parse( |
| 101 'dart:core 10:11 Foo.bar\n' |
| 102 'package:stack_trace/stack_trace.dart 10:11 Bar.baz\n' |
| 103 'dart:core 10:11 Zip.zap'), |
| 104 new Trace.parse( |
| 105 'dart:core 10:11 A.b\n' |
| 106 'package:stack_trace/stack_trace.dart 10:11 C.d\n' |
| 107 'dart:core 10:11 E.f') |
| 108 ]); |
| 109 |
| 110 expect(chain.terse.toString(), equals('dart:core E.f\n')); |
| 111 }); |
| 112 }); |
| 113 |
| 114 group('Chain.foldFrames', () { |
| 115 test('folds each trace', () { |
| 116 var chain = new Chain([ |
| 117 new Trace.parse( |
| 118 'a.dart 10:11 Foo.bar\n' |
| 119 'a.dart 10:11 Bar.baz\n' |
| 120 'b.dart 10:11 Bang.qux\n' |
| 121 'a.dart 10:11 Zip.zap\n' |
| 122 'a.dart 10:11 Zop.zoop'), |
| 123 new Trace.parse( |
| 124 'a.dart 10:11 Foo.bar\n' |
| 125 'a.dart 10:11 Bar.baz\n' |
| 126 'a.dart 10:11 Bang.qux\n' |
| 127 'a.dart 10:11 Zip.zap\n' |
| 128 'b.dart 10:11 Zop.zoop') |
| 129 ]); |
| 130 |
| 131 var folded = chain.foldFrames((frame) => frame.library == 'a.dart'); |
| 132 expect(folded.toString(), equals( |
| 133 'a.dart 10:11 Bar.baz\n' |
| 134 'b.dart 10:11 Bang.qux\n' |
| 135 'a.dart 10:11 Zop.zoop\n' |
| 136 '===== asynchronous gap ===========================\n' |
| 137 'a.dart 10:11 Zip.zap\n' |
| 138 'b.dart 10:11 Zop.zoop\n')); |
| 139 }); |
| 140 |
| 141 test('with terse: true, folds core frames as well', () { |
| 142 var chain = new Chain([ |
| 143 new Trace.parse( |
| 144 'a.dart 10:11 Foo.bar\n' |
| 145 'dart:async-patch/future.dart 10:11 Zip.zap\n' |
| 146 'b.dart 10:11 Bang.qux\n' |
| 147 'dart:core 10:11 Bar.baz\n' |
| 148 'a.dart 10:11 Zop.zoop'), |
| 149 new Trace.parse( |
| 150 'a.dart 10:11 Foo.bar\n' |
| 151 'a.dart 10:11 Bar.baz\n' |
| 152 'a.dart 10:11 Bang.qux\n' |
| 153 'a.dart 10:11 Zip.zap\n' |
| 154 'b.dart 10:11 Zop.zoop') |
| 155 ]); |
| 156 |
| 157 var folded = chain.foldFrames((frame) => frame.library == 'a.dart', |
| 158 terse: true); |
| 159 expect(folded.toString(), equals( |
| 160 'dart:async Zip.zap\n' |
| 161 'b.dart 10:11 Bang.qux\n' |
| 162 'a.dart Zop.zoop\n' |
| 163 '===== asynchronous gap ===========================\n' |
| 164 'a.dart Zip.zap\n' |
| 165 'b.dart 10:11 Zop.zoop\n')); |
| 166 }); |
| 167 |
| 168 test('eliminates completely-folded traces', () { |
| 169 var chain = new Chain([ |
| 170 new Trace.parse( |
| 171 'a.dart 10:11 Foo.bar\n' |
| 172 'b.dart 10:11 Bang.qux'), |
| 173 new Trace.parse( |
| 174 'a.dart 10:11 Foo.bar\n' |
| 175 'a.dart 10:11 Bang.qux'), |
| 176 new Trace.parse( |
| 177 'a.dart 10:11 Zip.zap\n' |
| 178 'b.dart 10:11 Zop.zoop') |
| 179 ]); |
| 180 |
| 181 var folded = chain.foldFrames((frame) => frame.library == 'a.dart'); |
| 182 expect(folded.toString(), equals( |
| 183 'a.dart 10:11 Foo.bar\n' |
| 184 'b.dart 10:11 Bang.qux\n' |
| 185 '===== asynchronous gap ===========================\n' |
| 186 'a.dart 10:11 Zip.zap\n' |
| 187 'b.dart 10:11 Zop.zoop\n')); |
| 188 }); |
| 189 |
| 190 test("doesn't return an empty trace", () { |
| 191 var chain = new Chain([ |
| 192 new Trace.parse( |
| 193 'a.dart 10:11 Foo.bar\n' |
| 194 'a.dart 10:11 Bang.qux') |
| 195 ]); |
| 196 |
| 197 var folded = chain.foldFrames((frame) => frame.library == 'a.dart'); |
| 198 expect(folded.toString(), equals('a.dart 10:11 Bang.qux\n')); |
| 199 }); |
| 200 }); |
| 201 |
| 202 test('Chain.toTrace eliminates asynchronous gaps', () { |
| 203 var trace = new Chain([ |
| 204 new Trace.parse( |
| 205 'user/code.dart 10:11 Foo.bar\n' |
| 206 'dart:core 10:11 Bar.baz'), |
| 207 new Trace.parse( |
| 208 'user/code.dart 10:11 Foo.bar\n' |
| 209 'dart:core 10:11 Bar.baz') |
| 210 ]).toTrace(); |
| 211 |
| 212 expect(trace.toString(), equals( |
| 213 '$userSlashCode 10:11 Foo.bar\n' |
| 214 'dart:core 10:11 Bar.baz\n' |
| 215 '$userSlashCode 10:11 Foo.bar\n' |
| 216 'dart:core 10:11 Bar.baz\n')); |
| 217 }); |
| 218 |
| 219 group('Chain.track(Future)', () { |
| 220 test('forwards the future value within Chain.capture()', () { |
| 221 Chain.capture(() { |
| 222 expect(Chain.track(new Future.value('value')), |
| 223 completion(equals('value'))); |
| 224 |
| 225 var trace = new Trace.current(); |
| 226 expect(Chain.track(new Future.error('error', trace)) |
| 227 .catchError((e, stackTrace) { |
| 228 expect(e, equals('error')); |
| 229 expect(stackTrace.toString(), equals(trace.toString())); |
| 230 }), completes); |
| 231 }); |
| 232 }); |
| 233 |
| 234 test('forwards the future value outside of Chain.capture()', () { |
| 235 expect(Chain.track(new Future.value('value')), |
| 236 completion(equals('value'))); |
| 237 |
| 238 var trace = new Trace.current(); |
| 239 expect(Chain.track(new Future.error('error', trace)) |
| 240 .catchError((e, stackTrace) { |
| 241 expect(e, equals('error')); |
| 242 expect(stackTrace.toString(), equals(trace.toString())); |
| 243 }), completes); |
| 244 }); |
| 245 }); |
| 246 |
| 247 group('Chain.track(Stream)', () { |
| 248 test('forwards stream values within Chain.capture()', () { |
| 249 Chain.capture(() { |
| 250 var controller = new StreamController() |
| 251 ..add(1)..add(2)..add(3)..close(); |
| 252 expect(Chain.track(controller.stream).toList(), |
| 253 completion(equals([1, 2, 3]))); |
| 254 |
| 255 var trace = new Trace.current(); |
| 256 controller = new StreamController()..addError('error', trace); |
| 257 expect(Chain.track(controller.stream).toList() |
| 258 .catchError((e, stackTrace) { |
| 259 expect(e, equals('error')); |
| 260 expect(stackTrace.toString(), equals(trace.toString())); |
| 261 }), completes); |
| 262 }); |
| 263 }); |
| 264 |
| 265 test('forwards stream values outside of Chain.capture()', () { |
| 266 Chain.capture(() { |
| 267 var controller = new StreamController() |
| 268 ..add(1)..add(2)..add(3)..close(); |
| 269 expect(Chain.track(controller.stream).toList(), |
| 270 completion(equals([1, 2, 3]))); |
| 271 |
| 272 var trace = new Trace.current(); |
| 273 controller = new StreamController()..addError('error', trace); |
| 274 expect(Chain.track(controller.stream).toList() |
| 275 .catchError((e, stackTrace) { |
| 276 expect(e, equals('error')); |
| 277 expect(stackTrace.toString(), equals(trace.toString())); |
| 278 }), completes); |
| 279 }); |
| 280 }); |
| 281 }); |
| 282 } |
OLD | NEW |