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

Side by Side Diff: mojo/public/dart/third_party/test/lib/src/util/io.dart

Issue 1346773002: Stop running pub get at gclient sync time and fix build bugs (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 3 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
OLDNEW
(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 library test.util.io;
6
7 import 'dart:async';
8 import 'dart:convert';
9 import 'dart:io';
10 import 'dart:mirrors';
11
12 import 'package:path/path.dart' as p;
13 import 'package:pub_semver/pub_semver.dart';
14
15 import '../backend/operating_system.dart';
16 import '../runner/application_exception.dart';
17 import '../util/stream_queue.dart';
18 import '../utils.dart';
19
20 /// The ASCII code for a newline character.
21 const _newline = 0xA;
22
23 /// The ASCII code for a carriage return character.
24 const _carriageReturn = 0xD;
25
26 /// The root directory of the Dart SDK.
27 final String sdkDir = p.dirname(p.dirname(Platform.resolvedExecutable));
28
29 /// The version of the Dart SDK currently in use.
30 final Version _sdkVersion = new Version.parse(
31 new File(p.join(sdkDir, 'version'))
32 .readAsStringSync().trim());
33
34 /// Returns the current operating system.
35 final OperatingSystem currentOS = (() {
36 var name = Platform.operatingSystem;
37 var os = OperatingSystem.findByIoName(name);
38 if (os != null) return os;
39
40 throw new UnsupportedError('Unsupported operating system "$name".');
41 })();
42
43 /// A queue of lines of standard input.
44 final stdinLines = new StreamQueue(
45 UTF8.decoder.fuse(const LineSplitter()).bind(stdin));
46
47 /// The root directory below which to nest temporary directories created by the
48 /// test runner.
49 ///
50 /// This is configurable so that the test code can validate that the runner
51 /// cleans up after itself fully.
52 final _tempDir = Platform.environment.containsKey("_UNITTEST_TEMP_DIR")
53 ? Platform.environment["_UNITTEST_TEMP_DIR"]
54 : Directory.systemTemp.path;
55
56 /// The path to the `lib` directory of the `test` package.
57 String libDir({String packageRoot}) {
58 var pathToIo = libraryPath(#test.util.io, packageRoot: packageRoot);
59 return p.dirname(p.dirname(p.dirname(pathToIo)));
60 }
61
62 // TODO(nweiz): Make this check [stdioType] once that works within "pub run".
63 /// Whether "special" strings such as Unicode characters or color escapes are
64 /// safe to use.
65 ///
66 /// On Windows or when not printing to a terminal, only printable ASCII
67 /// characters should be used.
68 bool get canUseSpecialChars =>
69 Platform.operatingSystem != 'windows' &&
70 Platform.environment["_UNITTEST_USE_COLOR"] != "false";
71
72 /// Creates a temporary directory and returns its path.
73 String createTempDir() =>
74 new Directory(_tempDir).createTempSync('dart_test_').path;
75
76 /// Creates a temporary directory and passes its path to [fn].
77 ///
78 /// Once the [Future] returned by [fn] completes, the temporary directory and
79 /// all its contents are deleted. [fn] can also return `null`, in which case
80 /// the temporary directory is deleted immediately afterwards.
81 ///
82 /// Returns a future that completes to the value that the future returned from
83 /// [fn] completes to.
84 Future withTempDir(Future fn(String path)) {
85 return new Future.sync(() {
86 var tempDir = createTempDir();
87 return new Future.sync(() => fn(tempDir))
88 .whenComplete(() => new Directory(tempDir).deleteSync(recursive: true));
89 });
90 }
91
92 /// Return a transformation of [input] with all null bytes removed.
93 ///
94 /// This works around the combination of issue 23295 and 22667 by removing null
95 /// bytes. This workaround can be removed when either of those are fixed in the
96 /// oldest supported SDK.
97 ///
98 /// It also somewhat works around issue 23303 by removing any carriage returns
99 /// that are followed by newlines, to ensure that carriage returns aren't
100 /// doubled up in the output. This can be removed when the issue is fixed in the
101 /// oldest supported SDk.
102 Stream<List<int>> sanitizeForWindows(Stream<List<int>> input) {
103 if (!Platform.isWindows) return input;
104
105 return input.map((list) {
106 var previous;
107 return list.reversed.where((byte) {
108 if (byte == 0) return false;
109 if (byte == _carriageReturn && previous == _newline) return false;
110 previous = byte;
111 return true;
112 }).toList().reversed.toList();
113 });
114 }
115
116 /// Print a warning containing [message].
117 ///
118 /// This automatically wraps lines if they get too long. If [color] is passed,
119 /// it controls whether the warning header is color; otherwise, it defaults to
120 /// [canUseSpecialChars].
121 void warn(String message, {bool color}) {
122 if (color == null) color = canUseSpecialChars;
123 var header = color
124 ? "\u001b[33mWarning:\u001b[0m"
125 : "Warning:";
126 stderr.writeln(wordWrap("$header $message\n"));
127 }
128
129 /// Creates a URL string for [address]:[port].
130 ///
131 /// Handles properly formatting IPv6 addresses.
132 Uri baseUrlForAddress(InternetAddress address, int port) {
133 if (address.isLoopback) {
134 return new Uri(scheme: "http", host: "localhost", port: port);
135 }
136
137 // IPv6 addresses in URLs need to be enclosed in square brackets to avoid
138 // URL ambiguity with the ":" in the address.
139 if (address.type == InternetAddressType.IP_V6) {
140 return new Uri(scheme: "http", host: "[${address.address}]", port: port);
141 }
142
143 return new Uri(scheme: "http", host: address.address, port: port);
144 }
145
146 /// Returns the package root at [root].
147 ///
148 /// If [override] is passed, that's used. If the package root doesn't exist, an
149 /// [ApplicationException] is thrown.
150 String packageRootFor(String root, [String override]) {
151 if (root == null) root = p.current;
152 var packageRoot = override == null ? p.join(root, 'packages') : override;
153
154 if (!new Directory(packageRoot).existsSync()) {
155 throw new ApplicationException(
156 "Directory ${p.prettyUri(p.toUri(packageRoot))} does not exist.");
157 }
158
159 return packageRoot;
160 }
161
162 /// The library name must be globally unique, or the wrong library path may be
163 /// returned.
164 String libraryPath(Symbol libraryName, {String packageRoot}) {
165 var lib = currentMirrorSystem().findLibrary(libraryName);
166 if (lib.uri.scheme != 'package') return p.fromUri(lib.uri);
167
168 // TODO(nweiz): is there a way to avoid assuming this is being run next to a
169 // packages directory?.
170 if (packageRoot == null) packageRoot = p.absolute('packages');
171 return p.join(packageRoot, p.fromUri(lib.uri.path));
172 }
173
174 /// Repeatedly finds a probably-unused port on localhost and passes it to
175 /// [tryPort] until it binds successfully.
176 ///
177 /// [tryPort] should return a non-`null` value or a Future completing to a
178 /// non-`null` value once it binds successfully. This value will be returned
179 /// by [getUnusedPort] in turn.
180 ///
181 /// This is necessary for ensuring that our port binding isn't flaky for
182 /// applications that don't print out the bound port.
183 Future getUnusedPort(tryPort(int port)) {
184 var value;
185 return Future.doWhile(() async {
186 value = await tryPort(await getUnsafeUnusedPort());
187 return value == null;
188 }).then((_) => value);
189 }
190
191 /// Returns a port that is probably, but not definitely, not in use.
192 ///
193 /// This has a built-in race condition: another process may bind this port at
194 /// any time after this call has returned. If at all possible, callers should
195 /// use [getUnusedPort] instead.
196 Future<int> getUnsafeUnusedPort() async {
197 var socket = await RawServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0);
198 var port = socket.port;
199 await socket.close();
200 return port;
201 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698