// 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 test program for constructors and initializers.

// @dart = 2.9

// Check function subtyping for bound closures on generic type against generic
// typedefs.

import 'package:expect/expect.dart';

typedef int Foo<T>(T a, [String b]);
typedef int Bar<T>(T a, [String b]);
typedef int Baz<T>(T a, {String b});
typedef int Boz<T>(T a);
typedef int Biz<T>(T a, int b);

class C<T> {
  int foo(bool a, [String b]) => null;
  int baz(bool a, {String b}) => null;

  void test(String nameOfT, bool expectedResult) {
    void localMethod() {
      Expect.equals(expectedResult, foo is Foo<T>, 'foo is Foo<$nameOfT>');
      Expect.equals(expectedResult, foo is Bar<T>, 'foo is Bar<$nameOfT>');
      Expect.isFalse(foo is Baz<T>, 'foo is Baz<$nameOfT>');
      Expect.equals(expectedResult, foo is Boz<T>, 'foo is Boz<$nameOfT>');
      Expect.isFalse(foo is Biz<T>, 'foo is Biz<$nameOfT>');

      Expect.isFalse(baz is Foo<T>, 'baz is Foo<$nameOfT>');
      Expect.isFalse(baz is Bar<T>, 'baz is Bar<$nameOfT>');
      Expect.equals(expectedResult, baz is Baz<T>, 'baz is Baz<$nameOfT>');
      Expect.equals(expectedResult, baz is Boz<T>, 'baz is Boz<$nameOfT>');
      Expect.isFalse(baz is Biz<T>, 'bar is Biz<$nameOfT>');
    }

    localMethod();
  }
}

main() {
  new C<bool>().test('bool', true);
  new C<int>().test('int', false);
  new C<Object>().test('Object', false);
  new C<dynamic>().test('dynamic', false);
  new C<Null>().test('Null', true);
}
