class TestCase::Operator::DynamicLength {
  
  use Array;
  
  static method set_length : int () {
    
    # string
    {
      {
        my $string = (mutable string)copy "abc";
        
        unless (capacity $string == 3 + 1) {
          return 0;
        }
        
        set_length($string, 2);
        
        unless (length $string == 2) {
          return 0;
        }
        
        unless ($string eq "ab") {
          return 0;
        }
        
        set_length($string, 3);
        
        unless (length $string == 3) {
          return 0;
        }
        
        unless ($string eq "ab\0") {
          return 0;
        }
      }
      
      {
        my $string = (mutable string)copy "abc";
        
        set_length($string, 0);
        
        unless (length $string == 0) {
          return 0;
        }
        
        unless ($string eq "") {
          return 0;
        }
      }
      
      {
        my $string = (mutable string)copy "abc";
        
        set_length($string, 4);
        
        unless (length $string == 4) {
          return 0;
        }
        
        unless ($string eq "abc\0") {
          return 0;
        }
        
        unless (capacity $string == 4 + 1) {
          return 0;
        }
        
      }
      
      {
        my $string = (mutable string)copy "abc";
        
        set_length($string, 3);
        
        unless (length $string == 3) {
          return 0;
        }
        
        unless ($string eq "abc") {
          return 0;
        }
      }
    }
    
    # array
    {
      # numeric array
      {
        {
          my $array = [1, 2, 3];
          
          set_length($array, 2);
          
          unless (@$array == 2) {
            return 0;
          }
          
          unless (Array->equals($array, [1, 2])) {
            return 0;
          }
          
          set_length($array, 3);
          
          unless (@$array == 3) {
            return 0;
          }
          
          unless (Array->equals($array, [1, 2, 0])) {
            return 0;
          }
        }
        
        {
          my $array = [1, 2, 3];
          
          set_length($array, 0);
          
          unless (@$array == 0) {
            return 0;
          }
          
          unless (Array->equals($array, new int[0])) {
            return 0;
          }
        }
        
        {
          my $array = [1, 2, 3];
          
          set_length($array, 4);
          
          unless (@$array == 4) {
            return 0;
          }
          
          unless (Array->equals($array, [1, 2, 3, 0])) {
            return 0;
          }
          
          unless (capacity $array == 4 + 1) {
            return 0;
          }
          
        }
      }
      
      # object array
      {
        {
          my $array = ["1", "2", "3"];
          
          set_length($array, 2);
          
          unless (@$array == 2) {
            return 0;
          }
          
          unless (Array->equals($array, ["1", "2"])) {
            return 0;
          }
          
          set_length($array, 3);
          
          unless (@$array == 3) {
            return 0;
          }
          
          unless (Array->equals($array, ["1", "2", undef])) {
            return 0;
          }
        }
        
        {
          my $array = ["1", "2", "3"];
          
          set_length($array, 0);
          
          unless (@$array == 0) {
            return 0;
          }
          
          unless (Array->equals($array, new string[0])) {
            return 0;
          }
        }
        
        {
          my $array = ["1", "2", "3"];
          
          set_length($array, 4);
          
          unless (@$array == 4) {
            return 0;
          }
          
          unless (Array->equals($array, ["1", "2", "3", undef])) {
            return 0;
          }
          
          unless (capacity $array == 4 + 1) {
            return 0;
          }
          
        }
      }
    }
    
    # Exceptions
    {
      {
        my $string = (mutable string)undef;
        
        eval { set_length($string, 3); }
        
        unless ($@) {
          return 0;
        }
      }
      
      {
        my $string = (mutable string)copy "abc";
        
        make_fixed_length $string;
        
        eval { set_length($string, 3); }
        
        unless ($@) {
          return 0;
        }
      }
      
      {
        my $string = (mutable string)copy "abc";
        
        make_read_only $string;
        
        eval { set_length($string, 3); }
        
        unless ($@) {
          return 0;
        }
      }
      
      {
        my $string = (mutable string)copy "abc";
        
        eval { set_length($string, -1); }
        
        unless ($@) {
          return 0;
        }
      }
      
    }
    
    return 1;
  }
  
  static method set_capacity : int () {
    
    # string
    {
      {
        my $string = (mutable string)copy "abc";
        
        unless (capacity $string == 4) {
          return 0;
        }
        
        set_capacity($string, 5);
        
        unless (capacity $string == 5) {
          return 0;
        }
        
        unless (length $string == 3) {
          return 0;
        }
        
        unless ($string eq "abc") {
          return 0;
        }
      }
      
      {
        my $string = (mutable string)copy "abc";
        
        set_capacity($string, 4);
        
        unless (capacity $string == 4) {
          return 0;
        }
        
        unless ($string eq "abc") {
          return 0;
        }
      }
    }
    
    # array
    {
      # numeric array
      {
        {
          my $array = [1, 2, 3];
          
          set_capacity($array, 4);
          
          unless (@$array == 3) {
            return 0;
          }
          
          unless (Array->equals($array, [1, 2, 3])) {
            return 0;
          }
          
          unless (capacity $array == 4) {
            return 0;
          }
          
        }
      }
      
      # object array
      {
        {
          my $array = ["1", "2", "3"];
          
          set_capacity($array, 4);
          
          unless (@$array == 3) {
            return 0;
          }
          
          unless (Array->equals($array, ["1", "2", "3"])) {
            return 0;
          }
          
          unless (capacity $array == 4) {
            return 0;
          }
          
        }
      }
    }
    
    # Exceptions
    {
      {
        my $string = (mutable string)undef;
        
        eval { set_capacity($string, 3); }
        
        unless ($@) {
          return 0;
        }
      }
      
      {
        my $string = (mutable string)copy "abc";
        
        make_fixed_length $string;
        
        eval { set_capacity($string, 3); }
        
        unless ($@) {
          return 0;
        }
      }
      
      {
        my $string = (mutable string)copy "abc";
        
        make_read_only $string;
        
        eval { set_capacity($string, 3); }
        
        unless ($@) {
          return 0;
        }
      }
      
      {
        my $string = (mutable string)copy "abc";
        
        eval { set_capacity($string, -1); }
        
        unless ($@) {
          return 0;
        }
      }
      
      {
        my $string = (mutable string)copy "abc";
        
        eval { set_capacity($string, 3); }
        
        unless ($@) {
          return 0;
        }
      }
      
    }
    
    return 1;
  }
  
}
