// Copyright (c) 2013, 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

import "package:expect/expect.dart";
import 'dart:async';
import 'dart:convert';
import 'unicode_tests.dart';
import "package:async_helper/async_helper.dart";

Stream<List<int>> encode(String string, int chunkSize) {
  var controller;
  controller = new StreamController<String>(onListen: () {
    int i = 0;
    while (i < string.length) {
      if (i + chunkSize <= string.length) {
        controller.add(string.substring(i, i + chunkSize));
      } else {
        controller.add(string.substring(i));
      }
      i += chunkSize;
    }
    controller.close();
  });
  return controller.stream.transform(utf8.encoder);
}

void testUnpaused(List<int> expected, Stream<List<int>> stream) {
  asyncStart();
  stream.toList().then((list) {
    var combined = [];
    // Flatten the list.
    list.forEach(combined.addAll);
    Expect.listEquals(expected, combined);
    asyncEnd();
  });
}

void testWithPauses(List<int> expected, Stream<List<int>> stream) {
  asyncStart();
  var combined = <int>[];
  var sub;
  sub = stream.listen((x) {
    combined.addAll(x);
    sub.pause(new Future.delayed(Duration.zero));
  }, onDone: () {
    Expect.listEquals(expected, combined);
    asyncEnd();
  });
}

main() {
  for (var test in UNICODE_TESTS) {
    var expected = test[0];
    var string = test[1];
    testUnpaused(expected, encode(string, 1));
    testWithPauses(expected, encode(string, 1));
    testUnpaused(expected, encode(string, 2));
    testWithPauses(expected, encode(string, 2));
  }
}
