class TestCase::Operator::CompileTypeName {
  use TestCase::Minimal;
  use TestCase::Simple;
  
  static method compile_type_name : int () {
    
    {
      my $minimal = TestCase::Minimal->new;
      
      unless (compile_type_name $minimal eq "TestCase::Minimal") {
        return 0;
      }
    }
    
    {
      my $minimal = TestCase::Minimal->new;
      my $compile_type_name = compile_type_name $minimal;
      
      unless ($compile_type_name eq "TestCase::Minimal") {
        return 0;
      }
    }
    
    {
      my $obj = new TestCase::Minimal[3];
      my $compile_type_name = compile_type_name $obj;
      
      unless ($compile_type_name eq "TestCase::Minimal[]") {
        return 0;
      }
    }
    
    {
      my $obj = new TestCase::Minimal[][3];
      my $compile_type_name = compile_type_name $obj;
      
      unless ($compile_type_name eq "TestCase::Minimal[][]") {
        return 0;
      }
    }
    
    {
      my $obj : object = undef;
      my $compile_type_name = compile_type_name $obj;
      
      unless ($compile_type_name eq "object") {
        return 0;
      }
    }
    
    {
      my $obj : object[] = undef;
      my $compile_type_name = compile_type_name $obj;
      
      unless ($compile_type_name eq "object[]") {
        return 0;
      }
    }
    
    {
      my $obj : int = 1;
      my $compile_type_name = compile_type_name $obj;
      
      unless ($compile_type_name eq "int") {
        return 0;
      }
    }
    
    {
      my $obj = new byte[1];
      my $compile_type_name = compile_type_name $obj;
      unless ($compile_type_name eq "byte[]") {
        return 0;
      }
    }
    
    {
      my $obj = (mutable string)copy "abc";
      my $compile_type_name = compile_type_name $obj;
      unless ($compile_type_name eq "mutable string") {
        return 0;
      }
    }
    
    {
      my $obj = (Hash of List of string)undef;
      my $compile_type_name = compile_type_name $obj;
      unless ($compile_type_name eq "Hash of List of string") {
        warn $compile_type_name;
        return 0;
      }
    }
    
    {
      my $obj = (string|Int)undef;
      my $compile_type_name = compile_type_name $obj;
      
      unless ($compile_type_name eq "object") {
        return 0;
      }
    }
    
    # Extra
    {
      {
        use TestCase::List;
        
        my $array = [TestCase::List->new(["a", "b"]), TestCase::List->new(["c", "d"])];
        
        my $list = (TestCase::List of TestCase::List of string)TestCase::List->new($array);
        
        my $ret_array = $list->get_array;
        
        unless ($ret_array is_compile_type TestCase::List[]) {
          return 0;
        }
        
        unless ($ret_array == $array) {
          return 0;
        }
        
        my $elem = $ret_array->[0];
        
        unless ($elem is_compile_type TestCase::List) {
          return 0;
        }
        
        my $elem_elem = $elem->[0];
        
        compile_type_name $elem_elem;
      }
    }
    return 1;
  }
}
