// 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:collection/collection.dart";
import "package:test/test.dart";

import '../utils.dart';

void main() {
  group("with valid types, forwards", () {
    var wrapper;
    setUp(() {
      wrapper = DelegatingSet.typed<int>(new Set<Object>.from([1, 2, 3, 4, 5]));
    });

    test("add()", () {
      wrapper.add(1);
      wrapper.add(6);
      expect(wrapper, unorderedEquals([1, 2, 3, 4, 5, 6]));
    });

    test("addAll()", () {
      wrapper.addAll([1, 6, 7]);
      expect(wrapper, unorderedEquals([1, 2, 3, 4, 5, 6, 7]));
    });

    test("clear()", () {
      wrapper.clear();
      expect(wrapper, isEmpty);
    });

    test("containsAll()", () {
      expect(wrapper.containsAll([1, 3, 5]), isTrue);
      expect(wrapper.containsAll([1, 3, 6]), isFalse);
      expect(wrapper.containsAll([1, 3, "foo"]), isFalse);
    });

    test("difference()", () {
      expect(wrapper.difference(new Set.from([1, 3, 6])),
          unorderedEquals([2, 4, 5]));
    });

    test("intersection()", () {
      expect(wrapper.intersection(new Set.from([1, 3, 6, "foo"])),
          unorderedEquals([1, 3]));
    });

    test("lookup()", () {
      expect(wrapper.lookup(1), equals(1));
      expect(wrapper.lookup(7), isNull);
      expect(wrapper.lookup("foo"), isNull);
    });

    test("remove()", () {
      expect(wrapper.remove(3), isTrue);
      expect(wrapper, unorderedEquals([1, 2, 4, 5]));

      expect(wrapper.remove(3), isFalse);
      expect(wrapper.remove("foo"), isFalse);
    });

    test("removeAll()", () {
      wrapper.removeAll([1, 3, 6, "foo"]);
      expect(wrapper, unorderedEquals([2, 4, 5]));
    });

    test("removeWhere()", () {
      wrapper.removeWhere((i) => i.isOdd);
      expect(wrapper, unorderedEquals([2, 4]));
    });

    test("retainAll()", () {
      wrapper.retainAll([1, 3, 6, "foo"]);
      expect(wrapper, unorderedEquals([1, 3]));
    });

    test("retainWhere()", () {
      wrapper.retainWhere((i) => i.isOdd);
      expect(wrapper, unorderedEquals([1, 3, 5]));
    });

    test("union()", () {
      expect(wrapper.union(new Set.from([5, 6, 7])),
          unorderedEquals([1, 2, 3, 4, 5, 6, 7]));
    });
  });

  group("with invalid types", () {
    Set inner;
    var wrapper;
    setUp(() {
      inner = new Set<Object>.from(["foo", "bar", "baz"]);
      wrapper = DelegatingSet.typed<int>(inner);
    });

    group("throws a CastError for", () {
      test("difference()", () {
        var result = wrapper.difference(new Set.from([1, 3, 6]));
        expect(() => result.first, throwsCastError);
      });

      test("intersection()", () {
        var result = wrapper.intersection(new Set.from([1, 3, 6, "foo"]));
        expect(() => result.first, throwsCastError);
      });

      test("lookup()", () {
        expect(() => wrapper.lookup("foo"), throwsCastError);
      });

      test("removeWhere()", () {
        expect(() => wrapper.removeWhere(expectAsync1((_) => false, count: 0)),
            throwsCastError);
      });

      test("retainWhere()", () {
        expect(() => wrapper.retainWhere(expectAsync1((_) => false, count: 0)),
            throwsCastError);
      });

      test("union()", () {
        var result = wrapper.union(new Set.from([5, 6, 7]));
        expect(() => result.first, throwsCastError);
      });
    });

    group("doesn't throw a CastError for", () {
      test("add()", () {
        wrapper.add(6);
        expect(inner, unorderedEquals(["foo", "bar", "baz", 6]));
      });

      test("addAll()", () {
        wrapper.addAll([6, 7]);
        expect(inner, unorderedEquals(["foo", "bar", "baz", 6, 7]));
      });

      test("clear()", () {
        wrapper.clear();
        expect(wrapper, isEmpty);
      });

      test("containsAll()", () {
        expect(wrapper.containsAll(["foo", "bar"]), isTrue);
        expect(wrapper.containsAll(["foo", "bar", 1]), isFalse);
      });

      test("lookup()", () {
        expect(wrapper.lookup(1), isNull);
        expect(wrapper.lookup("zap"), isNull);
      });

      test("remove()", () {
        expect(wrapper.remove("foo"), isTrue);
        expect(inner, unorderedEquals(["bar", "baz"]));

        expect(wrapper.remove(3), isFalse);
        expect(wrapper.remove("foo"), isFalse);
      });

      test("removeAll()", () {
        wrapper.removeAll([1, "foo", "baz"]);
        expect(inner, unorderedEquals(["bar"]));
      });

      test("retainAll()", () {
        wrapper.retainAll([1, "foo", "baz"]);
        expect(inner, unorderedEquals(["foo", "baz"]));
      });
    });
  }, skip: "Re-enable this when test can run DDC (test#414).");
}
