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

/**
 * Tests for the toString methods on collections and maps.
 */

library collection_to_string;

import "package:expect/expect.dart";
import 'dart:collection' show Queue, LinkedHashMap;
import 'dart:math' as Math;

// TODO(jjb): seed random number generator when API allows it

const int NUM_TESTS = 300;
const int MAX_COLLECTION_SIZE = 7;

Math.Random rand;

main() {
  rand = new Math.Random();
  smokeTest();
  exactTest();
  inexactTest();
}

/**
 * Test a few simple examples.
 */
void smokeTest() {
  // Non-const lists
  Expect.equals([].toString(), '[]');
  Expect.equals([1].toString(), '[1]');
  Expect.equals(['Elvis'].toString(), '[Elvis]');
  Expect.equals([null].toString(), '[null]');
  Expect.equals([1, 2].toString(), '[1, 2]');
  Expect.equals(['I', 'II'].toString(), '[I, II]');
  Expect.equals(
      [
        [1, 2],
        [3, 4],
        [5, 6]
      ].toString(),
      '[[1, 2], [3, 4], [5, 6]]');

  // Const lists
  Expect.equals((const []).toString(), '[]');
  Expect.equals((const [1]).toString(), '[1]');
  Expect.equals((const ['Elvis']).toString(), '[Elvis]');
  Expect.equals((const [null]).toString(), '[null]');
  Expect.equals((const [1, 2]).toString(), '[1, 2]');
  Expect.equals((const ['I', 'II']).toString(), '[I, II]');
  Expect.equals(
      (const [
        const [1, 2],
        const [3, 4],
        const [5, 6]
      ])
          .toString(),
      '[[1, 2], [3, 4], [5, 6]]');

  // Non-const maps - Note that all keys are strings; the spec currently demands this
  Expect.equals({}.toString(), '{}');
  Expect.equals({'Elvis': 'King'}.toString(), '{Elvis: King}');
  Expect.equals({'Elvis': null}.toString(), '{Elvis: null}');
  Expect.equals({'I': 1, 'II': 2}.toString(), '{I: 1, II: 2}');
  Expect.equals(
      {
        'X': {'I': 1, 'II': 2},
        'Y': {'III': 3, 'IV': 4},
        'Z': {'V': 5, 'VI': 6}
      }.toString(),
      '{X: {I: 1, II: 2}, Y: {III: 3, IV: 4}, Z: {V: 5, VI: 6}}');

  // Const maps
  Expect.equals(const {}.toString(), '{}');
  Expect.equals(const {'Elvis': 'King'}.toString(), '{Elvis: King}');
  Expect.equals({'Elvis': null}.toString(), '{Elvis: null}');
  Expect.equals(const {'I': 1, 'II': 2}.toString(), '{I: 1, II: 2}');
  Expect.equals(
      const {
        'X': const {'I': 1, 'II': 2},
        'Y': const {'III': 3, 'IV': 4},
        'Z': const {'V': 5, 'VI': 6}
      }.toString(),
      '{X: {I: 1, II: 2}, Y: {III: 3, IV: 4}, Z: {V: 5, VI: 6}}');
}

// SERIOUS "BASHER" TESTS

/**
 * Generate a bunch of random collections (including Maps), and test that
 * there string form is as expected. The collections include collections
 * as elements, keys, and values, and include recursive references.
 *
 * This test restricts itself to collections with well-defined iteration
 * orders (i.e., no HashSet, HashMap).
 */
void exactTest() {
  for (int i = 0; i < NUM_TESTS; i++) {
    // Choose a size from 0 to MAX_COLLECTION_SIZE, favoring larger sizes
    int size =
        Math.sqrt(random(MAX_COLLECTION_SIZE * MAX_COLLECTION_SIZE)).toInt();

    StringBuffer stringRep = new StringBuffer();
    Object o = randomCollection(size, stringRep, exact: true);
    print(stringRep);
    print(o);
    Expect.equals(o.toString(), stringRep.toString());
  }
}

/**
 * Generate a bunch of random collections (including Maps), and test that
 * there string form is as expected. The collections include collections
 * as elements, keys, and values, and include recursive references.
 *
 * This test includes collections with ill-defined iteration orders (i.e.,
 * HashSet, HashMap). As a consequence, it can't use equality tests on the
 * string form. Instead, it performs equality tests on their "alphagrams."
 * This might allow false positives, but it does give a fair amount of
 * confidence.
 */
void inexactTest() {
  for (int i = 0; i < NUM_TESTS; i++) {
    // Choose a size from 0 to MAX_COLLECTION_SIZE, favoring larger sizes
    int size =
        Math.sqrt(random(MAX_COLLECTION_SIZE * MAX_COLLECTION_SIZE)).toInt();

    StringBuffer stringRep = new StringBuffer();
    Object o = randomCollection(size, stringRep, exact: false);
    print(stringRep);
    print(o);
    Expect.equals(alphagram(o.toString()), alphagram(stringRep.toString()));
  }
}

/**
 * Return a random collection (or Map) of the specified size, placing its
 * string representation into the given string buffer.
 *
 * If exact is true, the returned collections will not be, and will not contain
 * a collection with ill-defined iteration order (i.e., a HashSet or HashMap).
 */
Object randomCollection(int size, StringBuffer stringRep, {bool exact}) {
  return randomCollectionHelper(size, exact, stringRep, []);
}

/**
 * Return a random collection (or map) of the specified size, placing its
 * string representation into the given string buffer. The beingMade
 * parameter is a list of collections currently under construction, i.e.,
 * candidates for recursive references.
 *
 * If exact is true, the returned collections will not be, and will not contain
 * a collection with ill-defined iteration order (i.e., a HashSet or HashMap).
 */
Object randomCollectionHelper(
    int size, bool exact, StringBuffer stringRep, List beingMade) {
  double interfaceFrac = rand.nextDouble();

  if (exact) {
    if (interfaceFrac < 1 / 3) {
      return randomList(size, exact, stringRep, beingMade);
    } else if (interfaceFrac < 2 / 3) {
      return randomQueue(size, exact, stringRep, beingMade);
    } else {
      return randomMap(size, exact, stringRep, beingMade);
    }
  } else {
    if (interfaceFrac < 1 / 4) {
      return randomList(size, exact, stringRep, beingMade);
    } else if (interfaceFrac < 2 / 4) {
      return randomQueue(size, exact, stringRep, beingMade);
    } else if (interfaceFrac < 3 / 4) {
      return randomSet(size, exact, stringRep, beingMade);
    } else {
      return randomMap(size, exact, stringRep, beingMade);
    }
  }
}

/**
 * Return a random List of the specified size, placing its string
 * representation into the given string buffer. The beingMade
 * parameter is a list of collections currently under construction, i.e.,
 * candidates for recursive references.
 *
 * If exact is true, the returned collections will not be, and will not contain
 * a collection with ill-defined iteration order (i.e., a HashSet or HashMap).
 */
List randomList(int size, bool exact, StringBuffer stringRep, List beingMade) {
  return populateRandomCollection(size, exact, stringRep, beingMade, [], "[]");
}

/**
 * Like randomList, but returns a queue.
 */
Queue randomQueue(
    int size, bool exact, StringBuffer stringRep, List beingMade) {
  return populateRandomCollection(
      size, exact, stringRep, beingMade, new Queue(), "{}");
}

/**
 * Like randomList, but returns a Set.
 */
Set randomSet(int size, bool exact, StringBuffer stringRep, List beingMade) {
  // Until we have LinkedHashSet, method will only be called with exact==true
  return populateRandomSet(size, exact, stringRep, beingMade, new Set());
}

/**
 * Like randomList, but returns a map.
 */
Map randomMap(int size, bool exact, StringBuffer stringRep, List beingMade) {
  if (exact) {
    return populateRandomMap(
        size, exact, stringRep, beingMade, new LinkedHashMap());
  } else {
    return populateRandomMap(size, exact, stringRep, beingMade,
        randomBool() ? new Map() : new LinkedHashMap());
  }
}

/**
 * Populates the given empty collection with elements, emitting the string
 * representation of the collection to stringRep.  The beingMade parameter is
 * a list of collections currently under construction, i.e., candidates for
 * recursive references.
 *
 * If exact is true, the elements of the returned collections will not be,
 * and will not contain a collection with ill-defined iteration order
 * (i.e., a HashSet or HashMap).
 */
populateRandomCollection(int size, bool exact, StringBuffer stringRep,
    List beingMade, var coll, String delimiters) {
  beingMade.add(coll);
  int start = stringRep.length;

  stringRep.write(delimiters[0]);

  List indices = [];
  for (int i = 0; i < size; i++) {
    indices.add(stringRep.length);
    if (i != 0) stringRep.write(', ');
    coll.add(randomElement(random(size), exact, stringRep, beingMade));
  }
  if (size > 5 && delimiters == "()") {
    const int MAX_LENGTH = 80;
    const int MIN_COUNT = 3;
    const int MAX_COUNT = 100;
    // It's an iterable, it may omit some elements.
    int end = stringRep.length;
    if (size > MAX_COUNT) {
      // Last two elements are also omitted, just find the first three or
      // first 60 characters.
      for (int i = MIN_COUNT; i < size; i++) {
        int startIndex = indices[i];
        if (startIndex - start > MAX_LENGTH - 6) {
          // Limit - ", ...)".length.
          String prefix = stringRep.toString().substring(0, startIndex);
          stringRep.clear();
          stringRep.write(prefix);
          stringRep.write(", ...");
        }
      }
    } else if (stringRep.length - start > MAX_LENGTH - 1) {
      // 80 - ")".length.
      // Last two elements are always included. Middle ones may be omitted.
      int lastTwoLength = end - indices[indices.length - 2];
      // Try to find first element to omit.
      for (int i = 3; i <= size - 3; i++) {
        int elementEnd = indices[i + 1];
        int lengthAfter = elementEnd - start;
        int ellipsisSize = 5; // ", ...".length
        if (i == size - 3) ellipsisSize = 0; // No ellipsis if we hit the end.
        if (lengthAfter + ellipsisSize + lastTwoLength > MAX_LENGTH - 1) {
          // Omit this element and everything up to the last two.
          int elementStart = indices[i];
          // Rewrite string buffer by copying it out, clearing, and putting
          // the parts back in.
          String buffer = stringRep.toString();
          String prefix = buffer.substring(0, elementStart);
          String suffix = buffer.substring(end - lastTwoLength, end);
          stringRep.clear();
          stringRep.write(prefix);
          stringRep.write(", ...");
          stringRep.write(suffix);
          break;
        }
      }
    }
  }

  stringRep.write(delimiters[1]);
  beingMade.removeLast();
  return coll;
}

/** Like populateRandomCollection, but for sets (elements must be hashable) */
Set populateRandomSet(
    int size, bool exact, StringBuffer stringRep, List beingMade, Set set) {
  stringRep.write('{');

  for (int i = 0; i < size; i++) {
    if (i != 0) stringRep.write(', ');
    set.add(i);
    stringRep.write(i);
  }

  stringRep.write('}');
  return set;
}

/** Like populateRandomCollection, but for maps. */
Map populateRandomMap(
    int size, bool exact, StringBuffer stringRep, List beingMade, Map map) {
  beingMade.add(map);
  stringRep.write('{');

  for (int i = 0; i < size; i++) {
    if (i != 0) stringRep.write(', ');

    int key = i; // Ensures no duplicates
    stringRep.write(key);
    stringRep.write(': ');
    Object val = randomElement(random(size), exact, stringRep, beingMade);
    map[key] = val;
  }

  stringRep.write('}');
  beingMade.removeLast();
  return map;
}

/**
 * Generates a random element which can be an int, a collection, or a map,
 * and emits it to StringRep. The beingMade parameter is a list of collections
 * currently under construction, i.e., candidates for recursive references.
 *
 * If exact is true, the returned element will not be, and will not contain
 * a collection with ill-defined iteration order (i.e., a HashSet or HashMap).
 */
Object randomElement(
    int size, bool exact, StringBuffer stringRep, List beingMade) {
  Object result;
  double elementTypeFrac = rand.nextDouble();
  if (elementTypeFrac < 1 / 3) {
    result = random(1000);
    stringRep.write(result);
  } else if (elementTypeFrac < 2 / 3) {
    // Element is a random (new) collection
    result = randomCollectionHelper(size, exact, stringRep, beingMade);
  } else {
    // Element is a random recursive ref
    result = beingMade[random(beingMade.length)];
    if (result is List) {
      stringRep.write('[...]');
    } else if (result is Set || result is Map || result is Queue) {
      stringRep.write('{...}');
    } else {
      stringRep.write('(...)');
    }
  }
  return result;
}

/** Returns a random int on [0, max) */
int random(int max) {
  return rand.nextInt(max);
}

/** Returns a random boolean value. */
bool randomBool() {
  return rand.nextBool();
}

/** Returns the alphabetized characters in a string. */
String alphagram(String s) {
  // Calling [toList] to convert unmodifiable list to normal list.
  List<int> chars = s.codeUnits.toList();
  chars.sort((int a, int b) => a - b);
  return new String.fromCharCodes(chars);
}
