// 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", () {
    var 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(expectAsync((_) => false, count: 0)),
            throwsCastError);
      });

      test("retainWhere()", () {
        expect(() => wrapper.retainWhere(expectAsync((_) => 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).");
}
