// 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.

// @dart = 2.9

/// @assertion void writeCharCode(int charCode)
/// Writes the character of charCode.
///
/// This method is equivalent to write(new String.fromCharCode(charCode)).
///
/// This operation is non-blocking. See flush or done for how to get any errors
/// generated by this call.
/// @description Checks that this operation is non-blocking
/// @author sgrekhov@unipro.ru

import "dart:io";
import "../../../Utils/expect.dart";

var localhost = InternetAddress.loopbackIPv4.address;

test(String method) async {
  List<int> codes = new List<int>(256);
  for (int i = 0; i < codes.length; i++) {
    codes[i] = i;
  }
  asyncStart();
  HttpServer server = await HttpServer.bind(localhost, 0);
  server.listen((HttpRequest request) {
    request.toList().then((List<List<int>> l) {
      for (int i = 0; i < codes.length; i++) {
        Expect.listEquals([i], l[i]);
      }
      request.response.close();
      server.close();
      asyncEnd();
    });
  });

  HttpClient client = new HttpClient();
  client.open(method, localhost, server.port, "")
      .then((HttpClientRequest request) {
    request.contentLength = -1;
    for (int i = 0; i < codes.length; i++) {
      request.writeCharCode(codes[i]);
    }
    return request.close();
  });
}

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