OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 library test.utils; | 5 library test.utils; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 import 'dart:convert'; | 8 import 'dart:convert'; |
9 import 'dart:math' as math; | 9 import 'dart:math' as math; |
10 | 10 |
11 import 'package:crypto/crypto.dart'; | 11 import 'package:crypto/crypto.dart'; |
12 import 'package:path/path.dart' as p; | 12 import 'package:path/path.dart' as p; |
13 import 'package:shelf/shelf.dart' as shelf; | 13 import 'package:shelf/shelf.dart' as shelf; |
14 import 'package:stack_trace/stack_trace.dart'; | 14 import 'package:stack_trace/stack_trace.dart'; |
15 | 15 |
16 import 'backend/operating_system.dart'; | 16 import 'backend/operating_system.dart'; |
17 import 'util/path_handler.dart'; | 17 import 'util/path_handler.dart'; |
18 | 18 |
| 19 /// The maximum console line length. |
| 20 const _lineLength = 100; |
| 21 |
19 /// A typedef for a possibly-asynchronous function. | 22 /// A typedef for a possibly-asynchronous function. |
20 /// | 23 /// |
21 /// The return type should only ever by [Future] or void. | 24 /// The return type should only ever by [Future] or void. |
22 typedef AsyncFunction(); | 25 typedef AsyncFunction(); |
23 | 26 |
24 /// A typedef for a zero-argument callback function. | 27 /// A typedef for a zero-argument callback function. |
25 typedef void Callback(); | 28 typedef void Callback(); |
26 | 29 |
27 /// A converter that decodes bytes using UTF-8 and splits them on newlines. | 30 /// A converter that decodes bytes using UTF-8 and splits them on newlines. |
28 final lineSplitter = UTF8.decoder.fuse(const LineSplitter()); | 31 final lineSplitter = UTF8.decoder.fuse(const LineSplitter()); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
76 /// | 79 /// |
77 /// Many exceptions include the exception class name at the beginning of their | 80 /// Many exceptions include the exception class name at the beginning of their |
78 /// [toString], so we remove that if it exists. | 81 /// [toString], so we remove that if it exists. |
79 String getErrorMessage(error) => | 82 String getErrorMessage(error) => |
80 error.toString().replaceFirst(_exceptionPrefix, ''); | 83 error.toString().replaceFirst(_exceptionPrefix, ''); |
81 | 84 |
82 /// Indent each line in [str] by two spaces. | 85 /// Indent each line in [str] by two spaces. |
83 String indent(String str) => | 86 String indent(String str) => |
84 str.replaceAll(new RegExp("^", multiLine: true), " "); | 87 str.replaceAll(new RegExp("^", multiLine: true), " "); |
85 | 88 |
| 89 /// Returns a sentence fragment listing the elements of [iter]. |
| 90 /// |
| 91 /// This converts each element of [iter] to a string and separates them with |
| 92 /// commas and/or "and" where appropriate. |
| 93 String toSentence(Iterable iter) { |
| 94 if (iter.length == 1) return iter.first.toString(); |
| 95 var result = iter.take(iter.length - 1).join(", "); |
| 96 if (iter.length > 2) result += ","; |
| 97 return "$result and ${iter.last}"; |
| 98 } |
| 99 |
| 100 /// Wraps [text] so that it fits within [lineLength], which defaults to 100 |
| 101 /// characters. |
| 102 /// |
| 103 /// This preserves existing newlines and doesn't consider terminal color escapes |
| 104 /// part of a word's length. |
| 105 String wordWrap(String text, {int lineLength}) { |
| 106 if (lineLength == null) lineLength = _lineLength; |
| 107 return text.split("\n").map((originalLine) { |
| 108 var buffer = new StringBuffer(); |
| 109 var lengthSoFar = 0; |
| 110 for (var word in originalLine.split(" ")) { |
| 111 var wordLength = withoutColors(word).length; |
| 112 if (wordLength > lineLength) { |
| 113 if (lengthSoFar != 0) buffer.writeln(); |
| 114 buffer.writeln(word); |
| 115 } else if (lengthSoFar == 0) { |
| 116 buffer.write(word); |
| 117 lengthSoFar = wordLength; |
| 118 } else if (lengthSoFar + 1 + wordLength > lineLength) { |
| 119 buffer.writeln(); |
| 120 buffer.write(word); |
| 121 lengthSoFar = wordLength; |
| 122 } else { |
| 123 buffer.write(" $word"); |
| 124 lengthSoFar += 1 + wordLength; |
| 125 } |
| 126 } |
| 127 return buffer.toString(); |
| 128 }).join("\n"); |
| 129 } |
| 130 |
86 /// A regular expression matching terminal color codes. | 131 /// A regular expression matching terminal color codes. |
87 final _colorCode = new RegExp('\u001b\\[[0-9;]+m'); | 132 final _colorCode = new RegExp('\u001b\\[[0-9;]+m'); |
88 | 133 |
89 /// Returns [str] without any color codes. | 134 /// Returns [str] without any color codes. |
90 String withoutColors(String str) => str.replaceAll(_colorCode, ''); | 135 String withoutColors(String str) => str.replaceAll(_colorCode, ''); |
91 | 136 |
92 /// A regular expression matching the path to a temporary file used to start an | 137 /// A regular expression matching the path to a temporary file used to start an |
93 /// isolate. | 138 /// isolate. |
94 /// | 139 /// |
95 /// These paths aren't relevant and are removed from stack traces. | 140 /// These paths aren't relevant and are removed from stack traces. |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
345 } | 390 } |
346 } | 391 } |
347 | 392 |
348 /// Returns middleware that nests all requests beneath the URL prefix [beneath]. | 393 /// Returns middleware that nests all requests beneath the URL prefix [beneath]. |
349 shelf.Middleware nestingMiddleware(String beneath) { | 394 shelf.Middleware nestingMiddleware(String beneath) { |
350 return (handler) { | 395 return (handler) { |
351 var pathHandler = new PathHandler()..add(beneath, handler); | 396 var pathHandler = new PathHandler()..add(beneath, handler); |
352 return pathHandler.handler; | 397 return pathHandler.handler; |
353 }; | 398 }; |
354 } | 399 } |
OLD | NEW |