| Index: lib/src/utils.dart
|
| diff --git a/lib/src/utils.dart b/lib/src/utils.dart
|
| index 7d1094edd970080d7e04b8690353efb78633cad2..37f2e6639248a30d20dd15e6d7293f54bd11b286 100644
|
| --- a/lib/src/utils.dart
|
| +++ b/lib/src/utils.dart
|
| @@ -5,11 +5,15 @@
|
| library test.utils;
|
|
|
| import 'dart:async';
|
| +import 'dart:math' as math;
|
|
|
| +import 'package:crypto/crypto.dart';
|
| import 'package:path/path.dart' as p;
|
| +import 'package:shelf/shelf.dart' as shelf;
|
| import 'package:stack_trace/stack_trace.dart';
|
|
|
| import 'backend/operating_system.dart';
|
| +import 'util/path_handler.dart';
|
|
|
| /// A typedef for a possibly-asynchronous function.
|
| ///
|
| @@ -179,3 +183,62 @@ Stream mergeStreams(Iterable<Stream> streamIter) {
|
|
|
| return controller.stream;
|
| }
|
| +
|
| +/// Returns a random base64 string containing [bytes] bytes of data.
|
| +///
|
| +/// [seed] is passed to [math.Random]; [urlSafe] and [addLineSeparator] are
|
| +/// passed to [CryptoUtils.bytesToBase64].
|
| +String randomBase64(int bytes, {int seed, bool urlSafe: false,
|
| + bool addLineSeparator: false}) {
|
| + var random = new math.Random(seed);
|
| + var data = [];
|
| + for (var i = 0; i < bytes; i++) {
|
| + data.add(random.nextInt(256));
|
| + }
|
| + return CryptoUtils.bytesToBase64(data,
|
| + urlSafe: urlSafe, addLineSeparator: addLineSeparator);
|
| +}
|
| +
|
| +// TODO(nweiz): Remove this and [shelfChange] once Shelf 0.6.0 has been out for
|
| +// six months or so.
|
| +/// Returns `request.url` in a cross-version way.
|
| +///
|
| +/// This follows the semantics of Shelf 0.6.x, even when using Shelf 0.5.x: the
|
| +/// returned URL never starts with "/".
|
| +Uri shelfUrl(shelf.Request request) {
|
| + var url = request.url;
|
| + if (!url.path.startsWith("/")) return url;
|
| + return url.replace(path: url.path.replaceFirst("/", ""));
|
| +}
|
| +
|
| +/// Like [shelf.Request.change], but cross-version.
|
| +///
|
| +/// This follows the semantics of Shelf 0.6.x, even when using Shelf 0.5.x.
|
| +shelf.Request shelfChange(shelf.Request typedRequest, {String path}) {
|
| + // Explicitly make the request dynamic since we're calling methods here that
|
| + // aren't defined in all support Shelf versions, and we don't want the
|
| + // analyzer to complain.
|
| + var request = typedRequest as dynamic;
|
| +
|
| + try {
|
| + return request.change(path: path);
|
| + } on NoSuchMethodError catch (_) {
|
| + var newScriptName = p.url.join(request.scriptName, path);
|
| + if (request.scriptName.isEmpty) newScriptName = "/" + newScriptName;
|
| +
|
| + var newUrlPath = p.url.relative(request.url.path.replaceFirst("/", ""),
|
| + from: path);
|
| + newUrlPath = newUrlPath == "." ? "" : "/" + newUrlPath;
|
| +
|
| + return request.change(
|
| + scriptName: newScriptName, url: request.url.replace(path: newUrlPath));
|
| + }
|
| +}
|
| +
|
| +/// Returns middleware that nests all requests beneath the URL prefix [beneath].
|
| +shelf.Middleware nestingMiddleware(String beneath) {
|
| + return (handler) {
|
| + var pathHandler = new PathHandler()..add(beneath, handler);
|
| + return pathHandler.handler;
|
| + };
|
| +}
|
|
|