class TestCase::Module::StringBuffer {
  use StringBuffer;
  use Fn;
  use Array;
  
  # Fields
  static method fields : int () {
    # length
    {
      my $buffer = StringBuffer->new;
      
      $buffer->push("a");
      $buffer->push("bc");
      
      # length
      my $length = $buffer->length;
      unless ($length == 3) {
        return 0;
      }
    }
    
    return 1;
  }
  
  static method new : int () {
    
    {
      my $buffer = StringBuffer->new;
      
      unless ($buffer isa StringBuffer) {
        return 0;
      }
      
      unless ($buffer->length == 0) {
        return 0;
      }
    }
    
    {
      my $buffer = StringBuffer->new("abc");
      
      unless ($buffer isa StringBuffer) {
        return 0;
      }
      
      unless ($buffer->length == 3) {
        return 0;
      }
      
      unless ($buffer->capacity == 4) {
        return 0;
      }
      
      unless ($buffer->to_string eq "abc") {
        return 0;
      }
    }
    
    return 1;
  }

  static method new_len : int () {
    
    {
      my $buffer = StringBuffer->new_len(0);
      
      unless ($buffer isa StringBuffer) {
        return 0;
      }
      
      unless ($buffer->length == 0) {
        return 0;
      }
      unless ($buffer->capacity == 4) {
        return 0;
      }
    }
    {
      my $buffer= StringBuffer->new_len(3);
      
      unless ($buffer->to_string eq "\0\0\0") {
        return 0;
      }
    }
    
    {
      my $buffer = StringBuffer->new_len(5);
      
      unless ($buffer isa StringBuffer) {
        return 0;
      }
      
      unless ($buffer->length == 5) {
        return 0;
      }
      unless ($buffer->capacity == 5) {
        return 0;
      }
    }
    {
      eval { StringBuffer->new_len(-1); };
      unless (Fn->contains($@, "The length \$length must be greater than or equal to 0")) {
        return 0;
      }
    }
    
    
    
    return 1;
  }
  
  static method push  : int () {
    {
      my $buffer = StringBuffer->new;
      $buffer->push ("abc");
      unless ($buffer->to_string eq "abc") {
        return 0;
      }
      $buffer->push ("de");
      unless ($buffer->to_string eq "abcde") {
        return 0;
      }
      $buffer->push ("f");
      unless ($buffer->to_string eq "abcdef") {
        return 0;
      }
    }

    {
      my $buffer = StringBuffer->new;
      my $offset = 1;
      my $length = 2;
      $buffer->push ("abcd", $offset, $length);
      unless ($buffer->to_string eq "bc") {
        return 0;
      }
    }
    
    # Exceptions
    {
      {
        my $buffer = StringBuffer->new;
        my $string = (string)undef;
        my $offset = 1;
        my $length = 2;
        eval { $buffer->push ($string, $offset, $length); };
        
        unless (Fn->contains($@, "The string \$string must be defined")) {
          return 0;
        }
      }
      {
        my $buffer = StringBuffer->new;
        my $string = "abcd";
        my $offset = -1;
        my $length = 2;
        eval { $buffer->push ($string, $offset, $length); };
        
        unless (Fn->contains($@, "The offset \$offset must be greater than or equal to 0")) {
          return 0;
        }
      }
      {
        my $buffer = StringBuffer->new;
        my $string = "abcd";
        my $offset = 1;
        my $length = 4;
        eval { $buffer->push ($string, $offset, $length); };
        
        unless (Fn->contains($@, "The offset \$offset + the length \$length must be less than or equal to the length of the string $string")) {
          return 0;
        }
      }
    }
    
    
    
    return 1;
  }
  
  static method push_char  : int () {
    my $buffer = StringBuffer->new;
    $buffer->push_char('a');
    unless ($buffer->to_string eq "a") {
      return 0;
    }
    $buffer->push_char('b');
    unless ($buffer->to_string eq "ab") {
      return 0;
    }
    $buffer->push_char('c');
    unless ($buffer->to_string eq "abc") {
      return 0;
    }
    return 1;
  }
  
  static method append_copy_on_write : int () {
    return 0;
  }
  
  static method to_string : int () {
    {
      my $minimal_buf = StringBuffer->new;
      $minimal_buf->push ("a");
      unless ($minimal_buf->to_string eq "a") {
        return 0;
      }
    }
    {
      my $large_buf = StringBuffer->new;
      $large_buf->push ("b");
      unless ($large_buf->to_string eq "b") {
        return 0;
      }
    }
    return 1;
  }
  
  static method get_string_unsafe : int () {
    
    {
      my $buffer = StringBuffer->new;
      $buffer->push("abc");
      
      my $value = (mutable string)$buffer->get_string_unsafe;
      $value->[0] = 'd';
      
      unless ($buffer->to_string eq "dbc") {
        return 0;
      }
    }
    
    return 1;
  }
  
  static method replace : int () {
    {
      my $target = StringBuffer->new;
      $target->push("abcd");
      $target->replace(1, 2, undef);
      unless ($target->to_string eq "ad") {
        return 0;
      }
    }
    {
      my $target = StringBuffer->new;
      $target->push("abcd");
      $target->replace(1, 2, "xyz");
      unless ($target->to_string eq "axyzd") {
        return 0;
      }
    }
    {
      my $target = StringBuffer->new;
      $target->push("abcd");
      $target->replace(0, 2, "xyz");
      unless ($target->to_string eq "xyzcd") {
        return 0;
      }
    }
    {
      my $target = StringBuffer->new;
      $target->push("abcd");
      $target->replace(2, 2, "xyz");
      unless ($target->to_string eq "abxyz") {
        return 0;
      }
    }
    
    {
      my $target = StringBuffer->new;
      $target->push("abcd");
      eval { $target->replace(-1, 3, "xyz"); };
      unless (Fn->contains($@, "The offset \$offset must be greater than or equal to 0")) {
        return 0;
      }
    }
    
    {
      my $target = StringBuffer->new;
      $target->push("abcd");
      eval { $target->replace(2, 3, "xyz"); };
      unless (Fn->contains($@, "\$offset + \$removing length must be less than or equal to the length of \$string buffer")) {
        return 0;
      }
    }
    {
      my $target = StringBuffer->new;
      $target->push("a");
      $target->replace(1, 0, "xy");
      unless ($target->to_string eq "axy") {
        return 0;
      }
    }
    
    {
      my $target = StringBuffer->new;
      $target->push("a");
      eval { $target->replace(2, 0, "xy"); };
      unless (Fn->contains($@, "\$offset + \$removing length must be less than or equal to the length of \$string buffer")) {
        return 0;
      }
    }
    
    {
      my $target = StringBuffer->new;
      $target->push("a");
      eval { $target->replace(1, 2, "xy"); };
      unless (Fn->contains($@, "\$offset + \$removing length must be less than or equal to the length of \$string buffer")) {
        return 0;
      }
    }
    
    {
      my $target = StringBuffer->new;
      $target->push("a");
      eval { $target->replace(2, 2, "xy"); };
      unless (Fn->contains($@, "\$offset + \$removing length must be less than or equal to the length of \$string buffer")) {
        return 0;
      }
    }
    
    
    
    return 1;
  }
  
  static method reserve : int () {
    {
      my $buffer = StringBuffer->new("a");
      $buffer->reserve(4);
      unless ($buffer->capacity == 4) {
        return 0;
      }
      $buffer->reserve(0);
      unless ($buffer->capacity == 4) {
        return 0;
      }
    }
    {
      my $buffer = StringBuffer->new("abc");
      my $value = (mutable string)$buffer->get_string_unsafe;
      my $string = $buffer->to_string;
      $buffer->reserve(5);
      unless ($buffer->capacity == 5) {
        return 0;
      }
      
      if ((mutable string)$buffer->get_string_unsafe == $value) {
        return 0;
      }
      
      unless ($buffer->to_string eq $string) {
        return 0;
      }
    }
    
    return 1;
  }
  
  static method set_length : int () {
    
    {
      my $buffer = StringBuffer->new("abc");
      
      $buffer->set_length(2);
      
      unless ($buffer->to_string eq "ab") {
        return 0;
      }
      
      unless ($buffer->get_string_unsafe->[2] == '\0') {
        return 0;
      }
    }
    
    {
      my $buffer = StringBuffer->new("abc");
      
      $buffer->set_length(0);
      
      unless ($buffer->to_string eq "") {
        return 0;
      }
      
      unless ($buffer->get_string_unsafe->[0] == '\0') {
        return 0;
      }
      
      unless ($buffer->get_string_unsafe->[1] == '\0') {
        return 0;
      }
      
      unless ($buffer->get_string_unsafe->[2] == '\0') {
        return 0;
      }
    }
    
    {
      my $buffer = StringBuffer->new("abc");
      
      $buffer->set_length(4);
      
      unless ($buffer->to_string eq "abc\0") {
        return 0;
      }
    }
    
    # Exceptions
    {
      {
        my $buffer = StringBuffer->new("abc");
        
        eval { $buffer->set_length(-1); }
        
        unless (Fn->contains($@, "The length \$length must be greater than or equal to 0.")) {
          return 0;
        }
      }
    }
    
    
    
    return 1;
  }
  
  static method set : int () {
    
    {
      my $buffer = StringBuffer->new("abc");
      
      $buffer->set("ab");
      
      unless ($buffer->to_string eq "ab") {
        return 0;
      }
      
      unless ($buffer->get_string_unsafe->[2] == '\0') {
        return 0;
      }
    }
    
    {
      my $buffer = StringBuffer->new("abc");
      
      $buffer->set("");
      
      unless ($buffer->to_string eq "") {
        return 0;
      }
      
      unless ($buffer->get_string_unsafe->[0] == '\0') {
        return 0;
      }
      
      unless ($buffer->get_string_unsafe->[1] == '\0') {
        return 0;
      }
      
      unless ($buffer->get_string_unsafe->[2] == '\0') {
        return 0;
      }
    }
    
    {
      my $buffer = StringBuffer->new("abc");
      
      $buffer->set("abcd");
      
      unless ($buffer->to_string eq "abcd") {
        return 0;
      }
    }
    
    
    
    return 1;
  }
  
  static method extra : int () {
    
    {
      my $buffer = StringBuffer->new;
      $buffer->push("abc");
      
      my $value = (mutable string)$buffer->get_string_unsafe;
      
      my $length = $buffer->length;
      
      $value->[0] = 'f';
      
      my $substr = Fn->substr($value, 0, $length);
      
      unless ($substr eq "fbc") {
        return 0;
      }
    }
    
    return 1;
  }
  
  static method clone : int () {
    
    {
      my $buffer = StringBuffer->new("abc");
      
      my $ret = $buffer->clone;
      
      unless ($ret is_type StringBuffer) {
        return 0;
      }
      
      unless ($ret->to_string eq "abc") {
        return 0;
      }
      
    }
    
    return 1;
  }
  
  static method cmp : int () {
    
    {
      my $buffer = StringBuffer->new;
      
      unless ($buffer isa Comparable) {
        return 0;
      }
      
      {
        my $ret = $buffer->cmp(StringBuffer->new("abd"), StringBuffer->new("abc"));
        unless ($ret == 1) {
          return 0;
        }
      }
      
      {
        my $ret = $buffer->cmp(StringBuffer->new("abcd"), StringBuffer->new("abc"));
        unless ($ret == 1) {
          return 0;
        }
      }
      
      {
        my $ret = $buffer->cmp(StringBuffer->new("abb"), StringBuffer->new("abc"));
        unless ($ret == -1) {
          return 0;
        }
      }
      
      {
        my $ret = $buffer->cmp(StringBuffer->new("abc"), StringBuffer->new("abcd"));
        unless ($ret == -1) {
          return 0;
        }
      }
      
      {
        my $ret = $buffer->cmp(StringBuffer->new("abc"), StringBuffer->new("abc"));
        unless ($ret == 0) {
          return 0;
        }
      }
      
      {
        my $ret = $buffer->cmp(undef, undef);
        unless ($ret == 0) {
          return 0;
        }
      }
      
      {
        my $ret = $buffer->cmp(undef, StringBuffer->new(""));
        unless ($ret == -1) {
          return 0;
        }
      }
      
      {
        my $ret = $buffer->cmp(StringBuffer->new(""), undef);
        unless ($ret == 1) {
          return 0;
        }
      }
    }
    
    return 1;
  }
  
  static method eq : int () {
    
    {
      my $buffer = StringBuffer->new;
      
      unless ($buffer isa EqualityCheckable) {
        return 0;
      }
      
      {
        my $ret = $buffer->eq(StringBuffer->new("abd"), StringBuffer->new("abc"));
        unless ($ret == 0) {
          return 0;
        }
      }
      
      {
        my $ret = $buffer->eq(StringBuffer->new("abc"), StringBuffer->new("abc"));
        unless ($ret == 1) {
          return 0;
        }
      }
      
      {
        my $ret = $buffer->eq(undef, undef);
        unless ($ret == 1) {
          return 0;
        }
      }
      
      {
        my $ret = $buffer->eq(undef, StringBuffer->new(""));
        unless ($ret == 0) {
          return 0;
        }
      }
      
      {
        my $ret = $buffer->eq(StringBuffer->new(""), undef);
        unless ($ret == 0) {
          return 0;
        }
      }
    }
    
    return 1;
  }
  
  static method compare_string : int () {
    
    {
      {
        my $ret = StringBuffer->new("abd")->compare_string("abc");
        unless ($ret == 1) {
          return 0;
        }
      }
      
      {
        my $ret = StringBuffer->new("abcd")->compare_string("abc");
        unless ($ret == 1) {
          return 0;
        }
      }
      
      {
        my $ret = StringBuffer->new("abb")->compare_string("abc");
        unless ($ret == -1) {
          return 0;
        }
      }
      
      {
        my $ret = StringBuffer->new("abc")->compare_string("abcd");
        unless ($ret == -1) {
          return 0;
        }
      }
      
      {
        my $ret = StringBuffer->new("abc")->compare_string("abc");
        unless ($ret == 0) {
          return 0;
        }
      }
      
      {
        my $ret = StringBuffer->new("")->compare_string(undef);
        unless ($ret == 1) {
          return 0;
        }
      }
    }
    
    return 1;
  }
  
  static method equals_string : int () {
    
    {
      {
        my $ret = StringBuffer->new("abd")->equals_string("abc");
        unless ($ret == 0) {
          return 0;
        }
      }
      
      {
        my $ret = StringBuffer->new("abc")->equals_string("abc");
        unless ($ret == 1) {
          return 0;
        }
      }
      
      {
        my $ret = StringBuffer->new("")->equals_string(undef);
        unless ($ret == 0) {
          return 0;
        }
      }
    }
    
    return 1;
  }
  
  static method substr : int () {
    
    {
      my $buffer = StringBuffer->new("abc");
      
      my $ret = $buffer->substr(0, 2);
      
      unless ($ret eq "ab") {
        return 0;
      }
    }
    
    {
      my $buffer = StringBuffer->new("abc");
      
      my $ret = $buffer->substr(0, 3);
      
      unless ($ret eq "abc") {
        return 0;
      }
    }
    
    {
      my $buffer = StringBuffer->new("abc");
      
      my $ret = $buffer->substr(1, 2);
      
      unless ($ret eq "bc") {
        return 0;
      }
    }
    
    # Exceptions
    {
      {
        my $buffer = StringBuffer->new("abc");
        
        eval { $buffer->substr(1, 3); }
        
        unless ($@) {
          return 0;
        }
      }
    }
    
    return 1;
  }
  
  static method index : int () {
    
    {
      my $buffer = StringBuffer->new("abcde");
      my $substring = "";
      my $found_offset = $buffer->index($substring, 0);
      unless ($found_offset == 0) {
        return 0;
      }
    }
    {
      my $buffer = StringBuffer->new("abcde");
      my $substring = "";
      my $found_offset = $buffer->index($substring);
      unless ($found_offset == 0) {
        return 0;
      }
    }
    {
      my $buffer = StringBuffer->new("");
      my $substring = "";
      my $found_offset = $buffer->index($substring, 0);
      unless ($found_offset == 0) {
        return 0;
      }
    }
    
    {
      my $buffer = StringBuffer->new("abc");
      my $substring = "";
      my $found_offset = $buffer->index($substring);
      unless ($found_offset == 0) {
        return 0;
      }
    }
    
    {
      my $buffer = StringBuffer->new("abc");
      my $substring = "";
      my $begin = 1;
      my $found_offset = $buffer->index($substring, $begin);
      unless ($found_offset == 1) {
        return 0;
      }
    }
    {
      my $buffer = StringBuffer->new("abc");
      my $substring = "";
      my $begin = 3;
      my $found_offset = $buffer->index($substring, $begin);
      unless ($found_offset == 3) {
        return 0;
      }
    }
    
    {
      my $buffer = StringBuffer->new("abcde");
      my $substring = "bcd";
      my $found_offset = $buffer->index($substring, 0);
      unless ($found_offset == 1) {
        return 0;
      }
    }
    {
      my $buffer = StringBuffer->new("abcde");
      my $substring = "bcd";
      my $found_offset = $buffer->index($substring, 1);
      unless ($found_offset == 1) {
        return 0;
      }
    }
    
    {
      my $buffer = StringBuffer->new("abcde");
      my $substring = "bcd";
      my $found_offset = $buffer->index($substring, 2);
      unless ($found_offset == -1) {
        return 0;
      }
    }
    
    {
      my $buffer = StringBuffer->new("abcde");
      my $substring = "pq";
      my $found_offset = $buffer->index($substring, 2);
      unless ($found_offset == -1) {
        return 0;
      }
    }

    {
      my $buffer = StringBuffer->new("abcde");
      my $substring = "bcd";
      my $found_offset = $buffer->index($substring, 0, $buffer->length - 1);
      unless ($found_offset == 1) {
        return 0;
      }
    }
    {
      my $buffer = StringBuffer->new("abcde");
      my $substring = "bcd";
      my $found_offset = $buffer->index($substring, 0);
      unless ($found_offset == 1) {
        return 0;
      }
    }
    
    {
      my $buffer = StringBuffer->new("abcde");
      my $substring = "";
      my $found_offset = $buffer->index($substring, 0);
      unless ($found_offset == 0) {
        return 0;
      }
    }
    
    {
      my $buffer = StringBuffer->new("abcde");
      my $substring = "";
      my $found_offset = $buffer->index($substring, 1);
      unless ($found_offset == 1) {
        return 0;
      }
    }
    {
      my $buffer = StringBuffer->new("abcde");
      my $substring = "bcd";
      my $found_offset = $buffer->index($substring, 0, 3);
      unless ($found_offset == 1) {
        return 0;
      }
    }
    {
      my $buffer = StringBuffer->new("abcde");
      my $substring = "bcd";
      my $found_offset = $buffer->index($substring, 0, 2);
      unless ($found_offset == -1) {
        return 0;
      }
    }
    {
      my $buffer = StringBuffer->new("foo,bar,baz,,");
      my $substring = ",";
      my $offset = 8;
      my $found_offset = $buffer->index($substring, $offset);
      unless ($found_offset == 11) {
        return 0;
      }
    }
    
    # Exception
    {
      {
        my $buffer = (string)undef;
        my $substring = "bcd";
        eval { Fn->index(undef, $substring); };
        unless ($@) {
          return 0;
        }
      }
      
      {
        my $buffer = StringBuffer->new("abcde");
        my $substring = (string)undef;
        eval { $buffer->index($substring); };
        unless ($@) {
          return 0;
        }
      }
      
      {
        my $buffer = StringBuffer->new("abcde");
        my $substring = "bcd";
        eval { $buffer->index($substring, -1); };
        unless ($@) {
          return 0;
        }
      }
      
      {
        my $buffer = StringBuffer->new("abcde");
        my $substring = "bcd";
        eval { $buffer->index($substring, $buffer->length + 1); };
        unless ($@) {
          return 0;
        }
      }
      
      {
        my $buffer = StringBuffer->new("abcde");
        my $substring = "bcd";
        eval { $buffer->index($substring, 0, $buffer->length + 1); };
        unless ($@) {
          return 0;
        }
      }
      
      {
        my $buffer = StringBuffer->new("abcde");
        my $substring = "bcd";
        my $begin = 2;
        my $end = 1;
        eval { $buffer->index($substring, $begin, $end); };
        unless ($@) {
          return 0;
        }
      }
    }
    
    return 1;
  }
  
  static method contains : int () {
    {
      my $buffer = StringBuffer->new("abcde");
      my $substring = "";
      my $found = $buffer->contains($substring);
      unless ($found == 1) {
        return 0;
      }
    }
    {
      my $buffer = StringBuffer->new("");
      my $substring = "";
      my $found = $buffer->contains($substring);
      unless ($found == 1) {
        return 0;
      }
    }
    {
      my $buffer = StringBuffer->new("abcde");
      my $substring = "bcd";
      my $found = $buffer->contains($substring);
      unless ($found == 1) {
        return 0;
      }
    }
    {
      my $buffer = StringBuffer->new("abcde");
      my $substring = "abcde";
      my $found = $buffer->contains($substring);
      unless ($found == 1) {
        return 0;
      }
    }
    {
      my $buffer = StringBuffer->new("abcde");
      my $substring = "p";
      my $found = $buffer->contains($substring);
      unless ($found == 0) {
        return 0;
      }
    }
    
    # Exceptions
    {
      {
        {
          my $buffer = (StringBuffer)undef;
          my $substring = "p";
          eval { $buffer->contains($substring); };
          
          unless ($@) {
            return 0;
          }
        }
      }
      
      {
        {
        my $buffer = StringBuffer->new("abcde");
        my $substring = (string)undef;
          eval {$buffer->contains($substring); };
          unless ($@) {
            return 0;
          }
        }
      }
    }
    
    return 1;
  }
  
}