class TestCase::Module::Point {
  use Point;
  
  static method interfaces : int () {

    # Interface
    {
      my $point = Point->new;
      unless ($point isa Stringable) {
        return 0;
      }
      unless ($point isa Cloneable) {
        return 0;
      }
    }
    
    # Stringable
    {
      my $point = Point->new(1, 2);
      my $stringable = (Stringable)$point;
      my $point_string = $stringable->to_string;
      unless ($point_string eq "(1,2)") {
        return 0;
      }
    }

    # Cloneable
    {
      my $point = Point->new(1, 2);
      my $cloneable = (Cloneable)$point;
      my $point_clone = (Point)$cloneable->clone;
      unless ($point_clone->x == $point->x && $point_clone->y == $point->y) {
        return 0;
      }
      
      if ($point_clone == $point) {
        return 0;
      }
    }
    
    return 1;
  }
  
  static method fields : int () {
    
    {
      my $point = Point->new(1, 2);
      unless ($point isa Point) {
        return 0;
      }
      
      unless ($point->x == 1) {
        return 0;
      }
      
      unless ($point->y == 2) {
        return 0;
      }
    }
    
    return 1;
  }
  
  static method new : int () {
    {
      my $point = Point->new;
      unless ($point isa Point) {
        return 0;
      }
      
      unless ($point->x == 0) {
        return 0;
      }
      
      unless ($point->y == 0) {
        return 0;
      }
    }
    
    {
      my $point = Point->new(1);
      unless ($point isa Point) {
        return 0;
      }
      
      unless ($point->x == 1) {
        return 0;
      }
      
      unless ($point->y == 0) {
        return 0;
      }
    }
    
    {
      my $point = Point->new(1, 2);
      unless ($point isa Point) {
        return 0;
      }
      
      unless ($point->x == 1) {
        return 0;
      }
      
      unless ($point->y == 2) {
        return 0;
      }
    }
    
    return 1;
  }
  
  static method clear : int () {
    
    {
      my $point = Point->new(1, 2);
      $point->clear;
      
      unless ($point->x == 0) {
        return 0;
      }
      unless ($point->y == 0) {
        return 0;
      }
    }
    
    return 1;
  }
  
  static method to_string: int () {
    
    {
      my $point = Point->new(1, 2);
      
      unless ($point->to_string eq "(1,2)") {
        return 0;
      }
    }
    
    return 1;
  }
  
  static method extra : int () {
    {
      my $point = Point->new(1, 2);
      
      my $x = $point->x;
      my $y = $point->y;
      
      unless ($x == 1) {
        return 0;
      }
      
      unless ($y == 2) {
        return 0;
      }
    }
    
    
    {
      my $point = Point->new(1, 2);
      
      my $x = $point->x;
      my $y = $point->y;
      
      unless ($x == 1) {
        return 0;
      }
      
      unless ($y == 2) {
        return 0;
      }
    }
    
    # Stringable
    {
      my $point = Point->new(1, 2);
      my $stringable = (Stringable)$point;
      my $point_string = $stringable->to_string;
      unless ($point_string eq "(1,2)") {
        return 0;
      }
    }

    # Cloneable
    {
      my $point = Point->new(1, 2);
      my $cloneable = (Cloneable)$point;
      my $point_clone = (Point)$cloneable->clone;
      unless ($point_clone->x == $point->x && $point_clone->y == $point->y) {
        return 0;
      }
      
      if ($point_clone == $point) {
        return 0;
      }
    }
    
    # Basic
    {
      my $point = Point->new(1, 2);
      unless ($point isa Point) {
        return 0;
      }
      
      unless ($point->x == 1) {
        return 0;
      }
      
      unless ($point->y == 2) {
        return 0;
      }

      my $string = $point->to_string;
      unless ($string eq "(1,2)") {
        return 0;
      }
      
      $point->clear;
      unless ($point->x == 0 && $point->y == 0) {
        return 0;
      }
    }
    
    return 1;
  }
  
  static method eq : int () {
    
    {
      my $point = Point->new;
      
      unless ($point isa EqualityCheckable) {
        return 0;
      }
      
      {
        my $ret = $point->eq(Point->new(1, 2), Point->new(1, 3));
        unless ($ret == 0) {
          return 0;
        }
      }
      
      {
        my $ret = $point->eq(Point->new(1, 2), Point->new(1, 2));
        unless ($ret == 1) {
          return 0;
        }
      }
      
      {
        my $ret = $point->eq(undef, undef);
        unless ($ret == 1) {
          return 0;
        }
      }
      
      {
        my $ret = $point->eq(undef, Point->new);
        unless ($ret == 0) {
          return 0;
        }
      }
      
      {
        my $ret = $point->eq(Point->new, undef);
        unless ($ret == 0) {
          return 0;
        }
      }
    }
    
    return 1;
  }
  
}
