Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(209)

Side by Side Diff: pkg/matcher/lib/src/pretty_print.dart

Issue 306283002: pkg/matcher: cleanup, updates, deprecations, fixes (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 matcher.pretty_print; 5 library matcher.pretty_print;
6 6
7 import 'description.dart'; 7 import 'description.dart';
8 import 'interfaces.dart'; 8 import 'interfaces.dart';
9 import 'utils.dart';
10 9
11 /** 10 /// Returns a pretty-printed representation of [object].
12 * Returns a pretty-printed representation of [object]. 11 ///
13 * 12 /// If [maxLineLength] is passed, this will attempt to ensure that each line is
14 * If [maxLineLength] is passed, this will attempt to ensure that each line is 13 /// no longer than [maxLineLength] characters long. This isn't guaranteed, since
15 * no longer than [maxLineLength] characters long. This isn't guaranteed, since 14 /// individual objects may have string representations that are too long, but
16 * individual objects may have string representations that are too long, but 15 /// most lines will be less than [maxLineLength] long.
17 * most lines will be less than [maxLineLength] long. 16 ///
18 * 17 /// If [maxItems] is passed, [Iterable]s and [Map]s will only print their first
19 * If [maxItems] is passed, [Iterable]s and [Map]s will only print their first 18 /// [maxItems] members or key/value pairs, respectively.
20 * [maxItems] members or key/value pairs, respectively.
21 */
22 String prettyPrint(object, {int maxLineLength, int maxItems}) { 19 String prettyPrint(object, {int maxLineLength, int maxItems}) {
23 String _prettyPrint(object, int indent, Set seen, bool top) { 20 String _prettyPrint(object, int indent, Set seen, bool top) {
24 // If the object is a matcher, use its description. 21 // If the object is a matcher, use its description.
25 if (object is Matcher) { 22 if (object is Matcher) {
26 var description = new StringDescription(); 23 var description = new StringDescription();
27 object.describe(description); 24 object.describe(description);
28 return "<$description>"; 25 return "<$description>";
29 } 26 }
30 27
31 // Avoid looping infinitely on recursively-nested data structures. 28 // Avoid looping infinitely on recursively-nested data structures.
32 if (seen.contains(object)) return "(recursive)"; 29 if (seen.contains(object)) return "(recursive)";
33 seen = seen.union(new Set.from([object])); 30 seen = seen.union(new Set.from([object]));
34 String pp(child) => _prettyPrint(child, indent + 2, seen, false); 31 String pp(child) => _prettyPrint(child, indent + 2, seen, false);
35 32
36 if (object is Iterable) { 33 if (object is Iterable) {
37 // Print the type name for non-List iterables. 34 // Print the type name for non-List iterables.
38 var type = object is List ? "" : typeName(object) + ":"; 35 var type = object is List ? "" : _typeName(object) + ":";
39 36
40 // Truncate the list of strings if it's longer than [maxItems]. 37 // Truncate the list of strings if it's longer than [maxItems].
41 var strings = object.map(pp).toList(); 38 var strings = object.map(pp).toList();
42 if (maxItems != null && strings.length > maxItems) { 39 if (maxItems != null && strings.length > maxItems) {
43 strings.replaceRange(maxItems - 1, strings.length, ['...']); 40 strings.replaceRange(maxItems - 1, strings.length, ['...']);
44 } 41 }
45 42
46 // If the printed string is short and doesn't contain a newline, print it 43 // If the printed string is short and doesn't contain a newline, print it
47 // as a single line. 44 // as a single line.
48 var singleLine = "$type[${strings.join(', ')}]"; 45 var singleLine = "$type[${strings.join(', ')}]";
(...skipping 27 matching lines...) Expand all
76 return singleLine; 73 return singleLine;
77 } 74 }
78 75
79 // Otherwise, print each key/value pair on its own line. 76 // Otherwise, print each key/value pair on its own line.
80 return "{\n" + strings.map((string) { 77 return "{\n" + strings.map((string) {
81 return _indent(indent + 2) + string; 78 return _indent(indent + 2) + string;
82 }).join(",\n") + "\n" + _indent(indent) + "}"; 79 }).join(",\n") + "\n" + _indent(indent) + "}";
83 } else if (object is String) { 80 } else if (object is String) {
84 // Escape strings and print each line on its own line. 81 // Escape strings and print each line on its own line.
85 var lines = object.split("\n"); 82 var lines = object.split("\n");
86 return "'" + lines.map(escapeString) 83 return "'" + lines.map(_escapeString)
87 .join("\\n'\n${_indent(indent + 2)}'") + "'"; 84 .join("\\n'\n${_indent(indent + 2)}'") + "'";
88 } else { 85 } else {
89 var value = object.toString().replaceAll("\n", _indent(indent) + "\n"); 86 var value = object.toString().replaceAll("\n", _indent(indent) + "\n");
90 var defaultToString = value.startsWith("Instance of "); 87 var defaultToString = value.startsWith("Instance of ");
91 88
92 // If this is the top-level call to [prettyPrint], wrap the value on angle 89 // If this is the top-level call to [prettyPrint], wrap the value on angle
93 // brackets to set it apart visually. 90 // brackets to set it apart visually.
94 if (top) value = "<$value>"; 91 if (top) value = "<$value>";
95 92
96 // Print the type of objects with custom [toString] methods. Primitive 93 // Print the type of objects with custom [toString] methods. Primitive
97 // objects and objects that don't implement a custom [toString] don't need 94 // objects and objects that don't implement a custom [toString] don't need
98 // to have their types printed. 95 // to have their types printed.
99 if (object is num || object is bool || object is Function || 96 if (object is num || object is bool || object is Function ||
100 object == null || defaultToString) { 97 object == null || defaultToString) {
101 return value; 98 return value;
102 } else { 99 } else {
103 return "${typeName(object)}:$value"; 100 return "${_typeName(object)}:$value";
104 } 101 }
105 } 102 }
106 } 103 }
107 104
108 return _prettyPrint(object, 0, new Set(), true); 105 return _prettyPrint(object, 0, new Set(), true);
109 } 106 }
110 107
111 String _indent(int length) => new List.filled(length, ' ').join(''); 108 String _indent(int length) => new List.filled(length, ' ').join('');
109
110 /// Returns the name of the type of [x], or "Unknown" if the type name can't be
111 /// determined.
112 String _typeName(x) {
113 // dart2js blows up on some objects (e.g. window.navigator).
114 // So we play safe here.
115 try {
116 if (x == null) return "null";
117 var type = x.runtimeType.toString();
118 // TODO(nweiz): if the object's type is private, find a public superclass to
119 // display once there's a portable API to do that.
120 return type.startsWith("_") ? "?" : type;
121 } catch (e) {
122 return "?";
123 }
124 }
125
126 /// Returns [source] with any control characters replaced by their escape
127 /// sequences.
128 ///
129 /// This doesn't add quotes to the string, but it does escape single quote
130 /// characters so that single quotes can be applied externally.
131 String _escapeString(String source) =>
132 source.split("").map(_escapeChar).join("");
133
134 /// Return the escaped form of a character [ch].
135 String _escapeChar(String ch) {
136 if (ch == "'")
137 return "\\'";
138 else if (ch == '\n')
139 return '\\n';
140 else if (ch == '\r')
141 return '\\r';
142 else if (ch == '\t')
143 return '\\t';
144 else
145 return ch;
146 }
147
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698