/*
 * Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
 * for details. All rights reserved. Use of this source code is governed by a
 * BSD-style license that can be found in the LICENSE file.
 */
/**
 * @assertion void writeAll(
 *  Iterable objects, [
 *  String separator = ""
 *  ])
 * Iterates over the given objects and writes them in sequence.
 *
 * If separator is provided, a write with the separator is performed between any
 * two elements of objects`.
 *
 * This operation is non-blocking. See flush or done for how to get any errors
 * generated by this call.
 * @description Checks that any errors generated by this call can be caught
 * @author sgrekhov@unipro.ru
 */
import "dart:io";
import "../../../Utils/expect.dart";

class C {
  String toString() {
    if (1 + 1 == 2) {
      throw new Exception("An exception");
    }
    return "This is C";
  }
}

var localhost = InternetAddress.loopbackIPv4.address;

test(String method) async {
  asyncStart();
  Iterable objects = [1, "2", 3.14, new C(), null];
  HttpServer server = await HttpServer.bind(localhost, 0);
  server.listen((HttpRequest request) {
  });

  HttpClient client = new HttpClient();
  client.open(method, localhost, server.port, "")
      .then((HttpClientRequest request) {
    request.contentLength = 6;
    request.writeAll(objects);
    return request.close();
  }).then((HttpClientResponse response) {
    Expect.fail("Error expected");
  }, onError: (_) {
    client.close(force: true);
    server.close();
    asyncEnd();
  });
}

main() {
  test("get");
  test("head");
  test("delete");
  test("put");
  test("post");
  test("patch");
}
