class TestCase::Module::Immutable::StringList {
  use Immutable::StringList;
  use Fn;
  use Array;
  
  # Fields
  static method fields : int () {
    my $list = Immutable::StringList->new([(string)1, 2, 3]);
    
    # length
    my $length = $list->length;
    unless ($length == 3) {
      return 0;
    }
    
    return 1;
  }
  
  # Class methods
  static method new : int () {
    # new with array
    {
      my $list = Immutable::StringList->new([(string)"abc", "def", "ABC"]);
      
      unless ($list->get(0) eq "abc") {
        return 0;
      }
      
      unless ($list->get(1) eq "def") {
        return 0;
      }
      
      unless ($list->get(2) eq "ABC") {
        return 0;
      }
      
      my $length = $list->length;
      unless ($length == 3) {
        return 0;
      }
    }
    
    # new with undef
    {
      my $list = Immutable::StringList->new((string[])undef);
      
      unless ($list->length == 0) {
        return 0;
      }
    }
    
    # new without arugments
    {
      my $list = Immutable::StringList->new;
      
      unless ($list->length == 0) {
        return 0;
      }
    }
    
    return 1;
  }
  
  static method new_len : int () {
    {
      my $list = Immutable::StringList->new_len(32);
      
      unless ($list->length == 32) {
        return 0;
      }
    }
    {
      my $list = Immutable::StringList->new_len(0);
      
      unless ($list->length == 0) {
        return 0;
      }
    }
    
    {
      eval { Immutable::StringList->new_len(-1); };
      unless (Fn->contains($@, "The length \$length must be greater than or equal to 0")) {
        return 0;
      }
    }
    
    return 1;
  }
  
  # Instance methods
  static method get : int () {
    {
      my $list = Immutable::StringList->new([(string)"abc", "def", "ABC"]);
      
      unless ($list->get(0) eq "abc") {
        return 0;
      }
      
      unless ($list->get(-3) eq "abc") {
        return 0;
      }
      
      unless ($list->get(0) isa string) {
        return 0;
      }
      
      unless ($list->get(1) eq "def") {
        return 0;
      }
      
      unless ($list->get(2) eq "ABC") {
        return 0;
      }
      
      my $length = $list->length;
      unless ($length == 3) {
        return 0;
      }
      
      eval { $list->get(-($list->length + 1)); };
      unless (Fn->contains($@, "The index \$index must be greater than or equal to 0")) {
        return 0;
      }
      
      eval { $list->get(3); };
      unless (Fn->contains($@, "The index \$index must be less than the length of \$list")) {
        return 0;
      }
      
      
    }
    
    return 1;
  }
  
  static method to_array : int () {
    {
      my $list = Immutable::StringList->new([(string)"abc", "def", "ABC"]);
      
      my $array = $list->to_array;
      
      unless ($array isa string[]) {
        return 0;
      }
      
      unless ($array->[0] eq "abc") {
        return 0;
      }
      
      unless ($array->[1] eq "def") {
        return 0;
      }
      
      unless ($array->[2] eq "ABC") {
        return 0;
      }
      
      my $length = @$array;
      unless ($length == 3) {
        return 0;
      }
    }
    
    return 1;
  }
  
}
