// Copyright (c) 2011, 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.
// Test that instanceof works correctly with type variables.

part of GenericInstanceofTest.dart;

class Foo<T> {
  Foo() {}

  bool isT(x) {
    // Untyped parameter to ensure that the static type
    // does not affect the result.
    return x is T;
  }

  bool isListT(x) {
    return x is List<T>;
  }
}

class GenericInstanceof {
  static void testMain() {
    // Using Object instead of String to ensure that the static type
    // does not affect the result.
    Foo<Object> fooObject = new Foo<String>();
    Expect.equals(true, fooObject.isT("string"));
    Expect.equals(false, fooObject.isT(1));

    Foo<String> fooString = new Foo<String>();
    Expect.equals(true, fooString.isT("string"));
    Expect.equals(false, fooString.isT(1));

    // Not providing a type argument to ensure that the static type
    // does not affect the result.
    {
      Foo foo = new Foo<String>();
      Expect.equals(true, foo.isT("string"));
      Expect.equals(false, foo.isT(1));
    }
    {
      Foo foo = new Foo();
      Expect.equals(true, foo.isT(new List(5)));
      Expect.equals(true, foo.isT(new List<Object>(5)));
      Expect.equals(true, foo.isT(new List<int>(5)));
      Expect.equals(true, foo.isT(new List<num>(5)));
      Expect.equals(true, foo.isT(new List<String>(5)));
    }
    {
      Foo foo = new Foo<List>();
      Expect.equals(true, foo.isT(new List(5)));
      Expect.equals(true, foo.isT(new List<Object>(5)));
      Expect.equals(true, foo.isT(new List<int>(5)));
      Expect.equals(true, foo.isT(new List<num>(5)));
      Expect.equals(true, foo.isT(new List<String>(5)));
    }
    {
      Foo foo = new Foo<List<Object>>();
      Expect.equals(true, foo.isT(new List(5)));
      Expect.equals(true, foo.isT(new List<Object>(5)));
      Expect.equals(true, foo.isT(new List<int>(5)));
      Expect.equals(true, foo.isT(new List<num>(5)));
      Expect.equals(true, foo.isT(new List<String>(5)));
    }
    {
      Foo foo = new Foo<List<int>>();
      Expect.equals(false, foo.isT(new List(5)));
      Expect.equals(false, foo.isT(new List<Object>(5)));
      Expect.equals(true, foo.isT(new List<int>(5)));
      Expect.equals(false, foo.isT(new List<num>(5)));
      Expect.equals(false, foo.isT(new List<String>(5)));
    }
    {
      Foo foo = new Foo<List<num>>();
      Expect.equals(false, foo.isT(new List(5)));
      Expect.equals(false, foo.isT(new List<Object>(5)));
      Expect.equals(true, foo.isT(new List<int>(5)));
      Expect.equals(true, foo.isT(new List<num>(5)));
      Expect.equals(false, foo.isT(new List<String>(5)));
    }
    {
      Foo foo = new Foo<List<String>>();
      Expect.equals(false, foo.isT(new List(5)));
      Expect.equals(false, foo.isT(new List<Object>(5)));
      Expect.equals(false, foo.isT(new List<int>(5)));
      Expect.equals(false, foo.isT(new List<num>(5)));
      Expect.equals(true, foo.isT(new List<String>(5)));
    }
    {
      Foo foo = new Foo();
      Expect.equals(true, foo.isListT(new List(5)));
      Expect.equals(true, foo.isListT(new List<Object>(5)));
      Expect.equals(true, foo.isListT(new List<int>(5)));
      Expect.equals(true, foo.isListT(new List<num>(5)));
      Expect.equals(true, foo.isListT(new List<String>(5)));
    }
    {
      Foo foo = new Foo<Object>();
      Expect.equals(true, foo.isListT(new List(5)));
      Expect.equals(true, foo.isListT(new List<Object>(5)));
      Expect.equals(true, foo.isListT(new List<int>(5)));
      Expect.equals(true, foo.isListT(new List<num>(5)));
      Expect.equals(true, foo.isListT(new List<String>(5)));
    }
    {
      Foo foo = new Foo<int>();
      Expect.equals(false, foo.isListT(new List(5)));
      Expect.equals(false, foo.isListT(new List<Object>(5)));
      Expect.equals(true, foo.isListT(new List<int>(5)));
      Expect.equals(false, foo.isListT(new List<num>(5)));
      Expect.equals(false, foo.isListT(new List<String>(5)));
    }
    {
      Foo foo = new Foo<num>();
      Expect.equals(false, foo.isListT(new List(5)));
      Expect.equals(false, foo.isListT(new List<Object>(5)));
      Expect.equals(true, foo.isListT(new List<int>(5)));
      Expect.equals(true, foo.isListT(new List<num>(5)));
      Expect.equals(false, foo.isListT(new List<String>(5)));
    }
    {
      Foo foo = new Foo<String>();
      Expect.equals(false, foo.isListT(new List(5)));
      Expect.equals(false, foo.isListT(new List<Object>(5)));
      Expect.equals(false, foo.isListT(new List<int>(5)));
      Expect.equals(false, foo.isListT(new List<num>(5)));
      Expect.equals(true, foo.isListT(new List<String>(5)));
    }
  }
}
