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

import "package:test/test.dart";

import "package:collection/collection.dart";

void main() {
  group("with an empty outer set", () {
    var set;
    setUp(() {
      set = UnionSet<int>(Set());
    });

    test("length returns 0", () {
      expect(set.length, equals(0));
    });

    test("contains() returns false", () {
      expect(set.contains(0), isFalse);
      expect(set.contains(null), isFalse);
      expect(set.contains("foo"), isFalse);
    });

    test("lookup() returns null", () {
      expect(set.lookup(0), isNull);
      expect(set.lookup(null), isNull);
      expect(set.lookup("foo"), isNull);
    });

    test("toSet() returns an empty set", () {
      expect(set.toSet(), isEmpty);
      expect(set.toSet(), isNot(same(set)));
    });

    test("map() doesn't run on any elements", () {
      expect(set.map(expectAsync1((_) {}, count: 0)), isEmpty);
    });
  });

  group("with multiple disjoint sets", () {
    var set;
    setUp(() {
      set = UnionSet.from([
        Set.of([1, 2]),
        Set.of([3, 4]),
        Set.of([5]),
        Set()
      ], disjoint: true);
    });

    test("length returns the total length", () {
      expect(set.length, equals(5));
    });

    test("contains() returns whether any set contains the element", () {
      expect(set.contains(1), isTrue);
      expect(set.contains(4), isTrue);
      expect(set.contains(5), isTrue);
      expect(set.contains(6), isFalse);
    });

    test("lookup() returns elements that are in any set", () {
      expect(set.lookup(1), equals(1));
      expect(set.lookup(4), equals(4));
      expect(set.lookup(5), equals(5));
      expect(set.lookup(6), isNull);
    });

    test("toSet() returns the union of all the sets", () {
      expect(set.toSet(), unorderedEquals([1, 2, 3, 4, 5]));
      expect(set.toSet(), isNot(same(set)));
    });

    test("map() maps the elements", () {
      expect(set.map((i) => i * 2), unorderedEquals([2, 4, 6, 8, 10]));
    });
  });

  group("with multiple overlapping sets", () {
    var set;
    setUp(() {
      set = UnionSet.from([
        Set.of([1, 2, 3]),
        Set.of([3, 4]),
        Set.of([5, 1]),
        Set()
      ]);
    });

    test("length returns the total length", () {
      expect(set.length, equals(5));
    });

    test("contains() returns whether any set contains the element", () {
      expect(set.contains(1), isTrue);
      expect(set.contains(4), isTrue);
      expect(set.contains(5), isTrue);
      expect(set.contains(6), isFalse);
    });

    test("lookup() returns elements that are in any set", () {
      expect(set.lookup(1), equals(1));
      expect(set.lookup(4), equals(4));
      expect(set.lookup(5), equals(5));
      expect(set.lookup(6), isNull);
    });

    test("lookup() returns the first element in an ordered context", () {
      var duration1 = Duration(seconds: 0);
      var duration2 = Duration(seconds: 0);
      expect(duration1, equals(duration2));
      expect(duration1, isNot(same(duration2)));

      var set = UnionSet.from([
        Set.of([duration1]),
        Set.of([duration2])
      ]);

      expect(set.lookup(Duration(seconds: 0)), same(duration1));
    });

    test("toSet() returns the union of all the sets", () {
      expect(set.toSet(), unorderedEquals([1, 2, 3, 4, 5]));
      expect(set.toSet(), isNot(same(set)));
    });

    test("map() maps the elements", () {
      expect(set.map((i) => i * 2), unorderedEquals([2, 4, 6, 8, 10]));
    });
  });

  group("after an inner set was modified", () {
    var set;
    setUp(() {
      var innerSet = Set.of([3, 7]);
      set = UnionSet.from([
        Set.of([1, 2]),
        Set.of([5]),
        innerSet
      ]);

      innerSet.add(4);
      innerSet.remove(7);
    });

    test("length returns the total length", () {
      expect(set.length, equals(5));
    });

    test("contains() returns true for a new element", () {
      expect(set.contains(4), isTrue);
    });

    test("contains() returns false for a removed element", () {
      expect(set.contains(7), isFalse);
    });

    test("lookup() returns a new element", () {
      expect(set.lookup(4), equals(4));
    });

    test("lookup() doesn't returns a removed element", () {
      expect(set.lookup(7), isNull);
    });

    test("toSet() returns the union of all the sets", () {
      expect(set.toSet(), unorderedEquals([1, 2, 3, 4, 5]));
      expect(set.toSet(), isNot(same(set)));
    });

    test("map() maps the elements", () {
      expect(set.map((i) => i * 2), unorderedEquals([2, 4, 6, 8, 10]));
    });
  });

  group("after the outer set was modified", () {
    var set;
    setUp(() {
      var innerSet = Set.of([6]);
      var outerSet = Set.of([
        Set.of([1, 2]),
        Set.of([5]),
        innerSet
      ]);

      set = UnionSet<int>(outerSet);
      outerSet.remove(innerSet);
      outerSet.add(Set.of([3, 4]));
    });

    test("length returns the total length", () {
      expect(set.length, equals(5));
    });

    test("contains() returns true for a new element", () {
      expect(set.contains(4), isTrue);
    });

    test("contains() returns false for a removed element", () {
      expect(set.contains(6), isFalse);
    });

    test("lookup() returns a new element", () {
      expect(set.lookup(4), equals(4));
    });

    test("lookup() doesn't returns a removed element", () {
      expect(set.lookup(6), isNull);
    });

    test("toSet() returns the union of all the sets", () {
      expect(set.toSet(), unorderedEquals([1, 2, 3, 4, 5]));
      expect(set.toSet(), isNot(same(set)));
    });

    test("map() maps the elements", () {
      expect(set.map((i) => i * 2), unorderedEquals([2, 4, 6, 8, 10]));
    });
  });
}
