Fix a broken test for redirects (#317)

This test added a `.catchError` callback with some expects, but the
`Future` was completing normally so the callback and expects never ran.
The reason the response came back successfully was that the IO client
does not consider a `302` to be a redirect when the method is `'POST'`.

https://github.com/dart-lang/sdk/blob/ed9e89ea388e4bc0142bf6e967d4ca11999bdfdc/sdk/lib/_http/http_impl.dart#L355-L365

- Refactor to async/await to clean up the noise of `.then`,
  `.whenComplete`, and `.catchError` and make the logic easier to
  follow.
- Switch the request type to `'GET'` so that the exception occurs.
- Move server starting and stopping to a `setUp` and `tearDown`.
- Fix the expectation to look for the wrapped `ClientException` instead
  of the exception thrown by the IO client. We also lose the underlying
  exception and have only the message so we can't check the length of
  the `redirects` field.
- Remove the now unused test utility to get a matcher on the old
  exception type.
diff --git a/test/io/request_test.dart b/test/io/request_test.dart
index f689dce..a6bb35d 100644
--- a/test/io/request_test.dart
+++ b/test/io/request_test.dart
@@ -10,61 +10,48 @@
 import 'utils.dart';
 
 void main() {
-  test('.send', () {
-    expect(
-        startServer().then((_) {
-          var request = http.Request('POST', serverUrl)
-            ..body = 'hello'
-            ..headers['User-Agent'] = 'Dart';
+  setUp(startServer);
 
-          expect(
-              request.send().then((response) {
-                expect(response.statusCode, equals(200));
-                return response.stream.bytesToString();
-              }).whenComplete(stopServer),
-              completion(parse(equals({
-                'method': 'POST',
-                'path': '/',
-                'headers': {
-                  'content-type': ['text/plain; charset=utf-8'],
-                  'accept-encoding': ['gzip'],
-                  'user-agent': ['Dart'],
-                  'content-length': ['5']
-                },
-                'body': 'hello'
-              }))));
-        }),
-        completes);
+  tearDown(stopServer);
+
+  test('send happy case', () async {
+    final request = http.Request('GET', serverUrl)
+      ..body = 'hello'
+      ..headers['User-Agent'] = 'Dart';
+
+    final response = await request.send();
+
+    expect(response.statusCode, equals(200));
+    final bytesString = await response.stream.bytesToString();
+    expect(
+        bytesString,
+        parse(equals({
+          'method': 'GET',
+          'path': '/',
+          'headers': {
+            'content-type': ['text/plain; charset=utf-8'],
+            'accept-encoding': ['gzip'],
+            'user-agent': ['Dart'],
+            'content-length': ['5']
+          },
+          'body': 'hello',
+        })));
   });
 
-  test('#followRedirects', () {
-    expect(
-        startServer().then((_) {
-          var request = http.Request('POST', serverUrl.resolve('/redirect'))
-            ..followRedirects = false;
-          var future = request.send().then((response) {
-            expect(response.statusCode, equals(302));
-          });
-          expect(
-              future.catchError((_) {}).then((_) => stopServer()), completes);
-          expect(future, completes);
-        }),
-        completes);
+  test('without redirects', () async {
+    final request = http.Request('GET', serverUrl.resolve('/redirect'))
+      ..followRedirects = false;
+    final response = await request.send();
+
+    expect(response.statusCode, equals(302));
   });
 
-  test('#maxRedirects', () {
+  test('exceeding max redirects', () async {
+    final request = http.Request('GET', serverUrl.resolve('/loop?1'))
+      ..maxRedirects = 2;
     expect(
-        startServer().then((_) {
-          var request = http.Request('POST', serverUrl.resolve('/loop?1'))
-            ..maxRedirects = 2;
-          var future = request.send().catchError((error) {
-            expect(error, isRedirectLimitExceededException);
-            expect(error.redirects.length, equals(2));
-          });
-          expect(
-              future.catchError((_) {}).then((_) => stopServer()), completes);
-          expect(future, completes);
-        }),
-        completes);
+        request.send(),
+        throwsA(isA<http.ClientException>()
+            .having((e) => e.message, 'message', 'Redirect limit exceeded')));
   });
 }
diff --git a/test/io/utils.dart b/test/io/utils.dart
index 857b023..7e94396 100644
--- a/test/io/utils.dart
+++ b/test/io/utils.dart
@@ -119,14 +119,6 @@
 /// A matcher for functions that throw HttpException.
 Matcher get throwsClientException => throwsA(TypeMatcher<ClientException>());
 
-/// A matcher for RedirectLimitExceededExceptions.
-final isRedirectLimitExceededException = const TypeMatcher<RedirectException>()
-    .having((e) => e.message, 'message', 'Redirect limit exceeded');
-
-/// A matcher for functions that throw RedirectLimitExceededException.
-final Matcher throwsRedirectLimitExceededException =
-    throwsA(isRedirectLimitExceededException);
-
 /// A matcher for functions that throw SocketException.
 final Matcher throwsSocketException =
     throwsA(const TypeMatcher<SocketException>());