class TestCase::Lib::Fn1 {
  use Fn;
  use Unicode as Un;
  use TestCase::Minimal;

  static method sprintf_d : int () {
    unless (Fn->sprintf("%d", 123) eq "123") {
      return 0;
    }
    
    unless (Fn->sprintf("%d", 123) eq "123") {
      return 0;
    }
    unless (Fn->sprintf("%5d", 123) eq "  123") {
      return 0;
    }
    unless (Fn->sprintf("%05d", 123) eq "00123") {
      return 0;
    }
    unless (Fn->sprintf("%+5d", 123) eq " +123") {
      return 0;
    }
    unless (Fn->sprintf("%-5d", 123) eq "123  ") {
      return 0;
    }
    unless (Fn->sprintf("%-05d", 123) eq "123  ") {
      return 0;
    }
    unless (Fn->sprintf("%d", -123) eq "-123") {
      return 0;
    }
    unless (Fn->sprintf("%+5d", -123) eq " -123") {
      return 0;
    }
    unless (Fn->sprintf("%d", -2147483648) eq "-2147483648") {
      return 0;
    }
    unless (Fn->sprintf("%3d", -2147483648) eq "-2147483648") {
      return 0;
    }
    
    
    # Invalid type
    {
      eval {
        Fn->sprintf("%d", (byte)1);
      };
      unless ($@) {
        return 0;
      }
      $@ = undef;
    }
    
    return 1;
  }

  static method sprintf_u : int () {
    unless (Fn->sprintf("%u", 123) eq "123") { return 0; }
    unless (Fn->sprintf("%05u", 123) eq "00123") { return 0; }
    unless (Fn->sprintf("%+5u", 123) eq "  123") { return 0; }
    unless (Fn->sprintf("%-5u", 123) eq "123  ") { return 0; }
    unless (Fn->sprintf("%u", -1) eq "4294967295") { return 0; }

    {
      eval {
        Fn->sprintf("%d", "str");
      };
      unless ($@) {
        return 0;
      }
      $@ = undef;
    }
    return 1;
  }

  static method sprintf_ld : int () {
    unless (Fn->sprintf("%ld", 10000000000L) eq "10000000000") { return 0; }
    unless (Fn->sprintf("%013ld", 12345678901L) eq "0012345678901") { return 0; }
    unless (Fn->sprintf("%+13ld", 12345678901L) eq " +12345678901") { return 0; }
    unless (Fn->sprintf("%-13ld", 12345678901L) eq "12345678901  ") { return 0; }
    unless (Fn->sprintf("%ld", -9223372036854775808L) eq "-9223372036854775808") {
      return 0;
    }
    unless (Fn->sprintf("%3ld", -9223372036854775808L) eq "-9223372036854775808") {
      return 0;
    }
    {
      eval {
        Fn->sprintf("%ld", "str");
      };
      unless ($@) {
        return 0;
      }
      $@ = undef;
    }
    {
      eval {
        Fn->sprintf("%l", 1L);
      };
      unless ($@) {
        return 0;
      }
      $@ = undef;
    }
    return 1;
  }

  static method sprintf_lu : int () {
    unless (Fn->sprintf("%lu", 10000000000L) eq "10000000000") { return 0; }
    unless (Fn->sprintf("%013lu", 12345678901L) eq "0012345678901") { return 0; }
    unless (Fn->sprintf("%+13lu", 12345678901L) eq "  12345678901") { return 0; }
    unless (Fn->sprintf("%-13lu", 12345678901L) eq "12345678901  ") { return 0; }
    unless (Fn->sprintf("%lu", -1L) eq "18446744073709551615") { return 0; }
    {
      eval {
        Fn->sprintf("%ld", "str");
      };
      unless ($@) {
        return 0;
      }
      $@ = undef;
    }
    {
      eval {
        Fn->sprintf("%l", 1L);
      };
      unless ($@) {
        return 0;
      }
      $@ = undef;
    }
    return 1;
  }

  static method sprintf_f : int () {
    unless (Fn->sprintf("%f", 3.1415) eq "3.141500") { return 0; }
    unless (Fn->sprintf("%.2f", 3.1415) eq "3.14") { return 0; }
    unless (Fn->sprintf("%.10f", 3.14) eq "3.1400000000") { return 0; }
    unless (Fn->sprintf("%012.6f", 3.14) eq "00003.140000") { return 0; }
    unless (Fn->sprintf("%+12.6f", 3.14) eq "   +3.140000") { return 0; }
    unless (Fn->sprintf("%-12.6f", 3.14) eq "3.140000    ") { return 0; }
    unless (Fn->sprintf("%+-12.6f", 3.14) eq "+3.140000   ") { return 0; }
    unless (Fn->sprintf("%.300f", 1.0) eq ("1." . Fn->repeat("0", 300))) { return 0; }
    unless (Fn->sprintf("%10.300f", 1.0) eq ("1." . Fn->repeat("0", 300))) { return 0; }
    
    # Float
    {
      unless (Fn->sprintf("%.2f", 3.1415f) eq "3.14") { return 0; }
    }
    
    {
      eval {
        Fn->sprintf("%f", "str");
      };
      unless ($@) {
        return 0;
      }
      $@ = undef;
    }
    return 1;
  }

  static method sprintf_g : int () {
    unless (Fn->sprintf("%g", 3.14) eq "3.14") { return 0; }
    unless (Fn->sprintf("%.2g", 3.14) eq "3.1") { return 0; }
    unless (Fn->sprintf("%-+10.2g", 3.14) eq "+3.1      ") { return 0; }

    unless (Fn->sprintf("%g", 3.14f) eq "3.14") { return 0; }
    
    {
      eval {
        Fn->sprintf("%g", "str");
      };
      unless ($@) {
        return 0;
      }
      $@ = undef;
    }
    return 1;
  }

  static method sprintf_c : int () {
    unless (Fn->sprintf("%c", 'x') eq "x") { return 0; }
    unless (Fn->sprintf("%05c", 'x') eq "0000x") { return 0; }
    unless (Fn->sprintf("%-5c", 'x') eq "x    ") { return 0; }
    unless (Fn->sprintf("%+c", 'x') eq "x") { return 0; }
    
    # UTF-8
    {
      unless (Fn->sprintf("%c", Fn->ord("あ")) eq "あ") { return 0; }
      
      unless (Fn->sprintf("%05c", Fn->ord("あ")) eq "00あ") { return 0; }
      unless (Fn->sprintf("%-5c", Fn->ord("あ")) eq "あ  ") { return 0; }
      unless (Fn->sprintf("%+c", Fn->ord("あ")) eq "あ") { return 0; }
    }

    {
      eval {
        Fn->sprintf("%c", "str");
      };
      unless ($@) {
        return 0;
      }
      $@ = undef;
    }
    return 1;
  }

  static method sprintf_s : int () {
    unless (Fn->sprintf("%s", "ABC") eq "ABC") { return 0; }
    unless (Fn->sprintf("%05s", "str") eq "00str") { return 0; }
    unless (Fn->sprintf("%-5s", "str") eq "str  ") { return 0; }
    unless (Fn->sprintf("%+s", "str") eq "str") { return 0; }
    {
      eval {
        Fn->sprintf("%s", 1);
      };
      unless ($@) {
        return 0;
      }
      $@ = undef;
    }
    return 1;
  }

  static method sprintf_percent : int () {
    unless (Fn->sprintf("%d%%",    1) eq "1%") { return 0; }
    unless (Fn->sprintf("%%%d",    1) eq "%1") { return 0; }
    unless (Fn->sprintf("%d%%str", 1) eq "1%str") { return 0; }
    return 1;
  }

  static method sprintf_x : int () {
    
    unless (Fn->sprintf("%x", 0) eq "0") {
      return 0;
    }
    unless (Fn->sprintf("%x", 255) eq "ff") {
      return 0;
    }
    unless (Fn->sprintf("%x", -1) eq "ffffffff") {
      return 0;
    }
    unless (Fn->sprintf("%08x", 255) eq "000000ff") {
      return 0;
    }
    
    # Ignore "+"
    unless (Fn->sprintf("%+08x", 255) eq "000000ff") {
      return 0;
    }
    
    # "-" ignores "0" padding
    unless (Fn->sprintf("%-08x", 255) eq "ff      ") {
      return 0;
    }
    
    # Invalid type
    {
      eval {
        Fn->sprintf("%x", (byte)1);
      };
      unless ($@) {
        return 0;
      }
      $@ = undef;
    }
    
    return 1;
  }

  static method sprintf_X : int () {
    
    unless (Fn->sprintf("%X", 0) eq "0") {
      return 0;
    }
    
    unless (Fn->sprintf("%X", 255) eq "FF") {
      return 0;
    }
    unless (Fn->sprintf("%X", -1) eq "FFFFFFFF") {
      return 0;
    }
    unless (Fn->sprintf("%X", 10) eq "A") {
      return 0;
    }
    unless (Fn->sprintf("%X", 11) eq "B") {
      return 0;
    }
    unless (Fn->sprintf("%X", 12) eq "C") {
      return 0;
    }
    unless (Fn->sprintf("%X", 13) eq "D") {
      return 0;
    }
    unless (Fn->sprintf("%X", 14) eq "E") {
      return 0;
    }
    unless (Fn->sprintf("%X", 15) eq "F") {
      return 0;
    }
    unless (Fn->sprintf("%08X", 255) eq "000000FF") {
      return 0;
    }
    
    # Ignore "+"
    unless (Fn->sprintf("%+08X", 255) eq "000000FF") {
      return 0;
    }
    
    # "-" ignores "0" padding
    unless (Fn->sprintf("%-08X", 255) eq "FF      ") {
      return 0;
    }
    
    # Invalid type
    {
      eval {
        Fn->sprintf("%X", (byte)1);
      };
      unless ($@) {
        return 0;
      }
      $@ = undef;
    }
    
    return 1;
  }

  static method sprintf_lx : int () {
    
    unless (Fn->sprintf("%lx", 0L) eq "0") {
      return 0;
    }
    unless (Fn->sprintf("%lx", 255L) eq "ff") {
      return 0;
    }
    unless (Fn->sprintf("%lx", -1L) eq "ffffffffffffffff") {
      return 0;
    }
    unless (Fn->sprintf("%08lx", 255L) eq "000000ff") {
      return 0;
    }
    
    # Ignore "+"
    unless (Fn->sprintf("%+08lx", 255L) eq "000000ff") {
      return 0;
    }
    
    # "-" ignores "0" padding
    unless (Fn->sprintf("%-08lx", 255L) eq "ff      ") {
      return 0;
    }
    
    # Invalid type
    {
      eval {
        Fn->sprintf("%lx", 1);
      };
      unless ($@) {
        return 0;
      }
      $@ = undef;
    }
    
    return 1;
  }

  static method sprintf_lX : int () {
    
    unless (Fn->sprintf("%lX", 0L) eq "0") {
      return 0;
    }
    unless (Fn->sprintf("%lX", 255L) eq "FF") {
      return 0;
    }
    unless (Fn->sprintf("%lX", -1L) eq "FFFFFFFFFFFFFFFF") {
      return 0;
    }
    unless (Fn->sprintf("%08lX", 255L) eq "000000FF") {
      return 0;
    }
    
    # Ignore "+"
    unless (Fn->sprintf("%+08lX", 255L) eq "000000FF") {
      return 0;
    }
    
    # "-" ignores "0" padding
    unless (Fn->sprintf("%-08lX", 255L) eq "FF      ") {
      return 0;
    }
    
    # Invalid type
    {
      eval {
        Fn->sprintf("%lX", 1);
      };
      unless ($@) {
        return 0;
      }
      $@ = undef;
    }
    
    return 1;
  }

  static method sprintf_all : int () {
    {
      # Invalid conversion (end of string)
      eval {
        Fn->sprintf("%d%", 1);
      };
      unless ($@ && Fn->index($@, "Invalid conversion in sprintf: end of string", 0) > -1) {
        warn("got error: $@");
        return 0;
      }
      $@ = undef;
    }
    {
      # Invalid conversion (unknown specifier)
      eval {
        Fn->sprintf("%d%k", 1, 2);
      };
      unless ($@) {
        return 0;
      }
      $@ = undef;
    }
    {
      # Invalid conversion (no type)
      eval {
        Fn->sprintf("%012.3", 3.14);
      };
      unless ($@) {
        return 0;
      }
      $@ = undef;
    }
    {
      # Missing argument
      eval {
        Fn->sprintf("%d%d", 1);
      };
      unless ($@) {
        return 0;
      }
      $@ = undef;
    }
    {
      my $string = "abc\n";
      my $ret = Fn->chompr($string);
      unless ($ret eq "abc") {
        return 0;
      }
    }
    {
      my $string = "abc";
      my $ret = Fn->chompr($string);
      unless ($ret eq "abc") {
        return 0;
      }
    }
    {
      my $string = "";
      my $ret = Fn->chompr($string);
      unless ($ret eq "") {
        return 0;
      }
    }

    return 1;
  }

  static method sort_byte : int () {
    # Sort array by asc order
    {
      my $nums = [(byte)2, 3, 1];
      
      Fn->sort_byte($nums, 0, scalar @$nums, method : int ($a : byte, $b : byte) {
        return $a <=> $b;
      });
      
      unless (Fn->equals_array_byte($nums, [(byte)1, 2, 3])) {
        return 0;
      }
    }

    # Sort array by asc order more long
    {
      my $nums = [(byte)5, 7, 9, 2, 4, 8, 1, 3, 6, 0];
      
      Fn->sort_byte($nums, 0, scalar @$nums, method : int ($a : byte, $b : byte) {
        return $a <=> $b;
      });
      
      unless (Fn->equals_array_byte($nums, [(byte)0, 1, 2, 3, 4, 5, 6, 7, 8, 9])) {
        return 0;
      }
    }

    # Sort array by asc order more long with same values
    {
      my $nums = [(byte)5, 7, 9, 2, 5, 4, 8, 1, 3, 6, 3, 0];
      
      Fn->sort_byte($nums, 0, scalar @$nums, method : int ($a : byte, $b : byte) {
        return $a <=> $b;
      });
      
      unless (Fn->equals_array_byte($nums, [(byte)0, 1, 2, 3, 3, 4, 5, 5, 6, 7, 8, 9])) {
        return 0;
      }
    }

    # Sort byte array by desc order
    {
      my $nums = [(byte)2, 3, 1];
      
      Fn->sort_byte($nums, 0, scalar @$nums, method : int ($a : byte, $b : byte) {
        return $b <=> $a;
      });
      
      unless (Fn->equals_array_byte($nums, [(byte)3, 2, 1])) {
        return 0;
      }
    }

    # If length is 0, There is nothing to do
    {
      my $nums = [(byte)2, 3, 1];
      
      Fn->sort_byte($nums, 0, 0, method : int ($a : byte, $b : byte) {
        return $a <=> $b;
      });
      
      unless (Fn->equals_array_byte($nums, [(byte)2, 3, 1])) {
        return 0;
      }
    }
    
    # Sort partially
    {
      my $nums = [(byte)5, 2, 3, 1, -10];
      
      Fn->sort_byte($nums, 1, 3, method : int ($a : byte, $b : byte) {
        return $a <=> $b;
      });
      
      unless (Fn->equals_array_byte($nums, [(byte)5, 1, 2, 3, -10])) {
        return 0;
      }
    }

    # Exception - Array must be not undef
    {
      my $nums = [(byte)2, 3, 1];
      
      eval {
        Fn->sort_byte(undef, 0, scalar @$nums, method : int ($a : byte, $b : byte) {
          return $a <=> $b;
        });
      };
      unless ($@) {
        return 0;
      }
    }
    
    # Exception - Offset must be more than or equals to 0
    {
      my $nums = [(byte)5, 2, 3, 1, -10];
      
      eval {
        Fn->sort_byte($nums, -1, 3, method : int ($a : byte, $b : byte) {
          return $a <=> $b;
        });
      };
      unless ($@) {
        return 0;
      }
    }

    # Exception - Length must be more than or equals to 0
    {
      my $nums = [(byte)5, 2, 3, 1, -10];
      
      eval {
        Fn->sort_byte($nums, 1, -1, method : int ($a : byte, $b : byte) {
          return $a <=> $b;
        });
      };
      unless ($@) {
        return 0;
      }
    }

    # Exception - Offset + Length must be in the array range
    {
      my $nums = [(byte)5, 2, 3, 1, -10];
      
      eval {
        Fn->sort_byte($nums, 3, 3, method : int ($a : byte, $b : byte) {
          return $a <=> $b;
        });
      };
      unless ($@) {
        return 0;
      }
    }
    
    $@ = undef;
    
    return 1;
  }

  static method sort_short : int () {
    # Sort array by asc order
    {
      my $nums = [(short)2, 3, 1];
      
      Fn->sort_short($nums, 0, scalar @$nums, method : int ($a : short, $b : short) {
        return $a <=> $b;
      });
      
      unless (Fn->equals_array_short($nums, [(short)1, 2, 3])) {
        return 0;
      }
    }

    # Sort array by asc order more long
    {
      my $nums = [(short)5, 7, 9, 2, 4, 8, 1, 3, 6, 0];
      
      Fn->sort_short($nums, 0, scalar @$nums, method : int ($a : short, $b : short) {
        return $a <=> $b;
      });
      
      unless (Fn->equals_array_short($nums, [(short)0, 1, 2, 3, 4, 5, 6, 7, 8, 9])) {
        return 0;
      }
    }

    # Sort array by asc order more long with same values
    {
      my $nums = [(short)5, 7, 9, 2, 5, 4, 8, 1, 3, 6, 3, 0];
      
      Fn->sort_short($nums, 0, scalar @$nums, method : int ($a : short, $b : short) {
        return $a <=> $b;
      });
      
      unless (Fn->equals_array_short($nums, [(short)0, 1, 2, 3, 3, 4, 5, 5, 6, 7, 8, 9])) {
        return 0;
      }
    }

    # Sort short array by desc order
    {
      my $nums = [(short)2, 3, 1];
      
      Fn->sort_short($nums, 0, scalar @$nums, method : int ($a : short, $b : short) {
        return $b <=> $a;
      });
      
      unless (Fn->equals_array_short($nums, [(short)3, 2, 1])) {
        return 0;
      }
    }

    # If length is 0, There is nothing to do
    {
      my $nums = [(short)2, 3, 1];
      
      Fn->sort_short($nums, 0, 0, method : int ($a : short, $b : short) {
        return $a <=> $b;
      });
      
      unless (Fn->equals_array_short($nums, [(short)2, 3, 1])) {
        return 0;
      }
    }
    
    # Sort partially
    {
      my $nums = [(short)5, 2, 3, 1, -10];
      
      Fn->sort_short($nums, 1, 3, method : int ($a : short, $b : short) {
        return $a <=> $b;
      });
      
      unless (Fn->equals_array_short($nums, [(short)5, 1, 2, 3, -10])) {
        return 0;
      }
    }

    # Exception - Array must be not undef
    {
      my $nums = [(short)2, 3, 1];
      
      eval {
        Fn->sort_short(undef, 0, scalar @$nums, method : int ($a : short, $b : short) {
          return $a <=> $b;
        });
      };
      unless ($@) {
        return 0;
      }
    }
    
    # Exception - Offset must be more than or equals to 0
    {
      my $nums = [(short)5, 2, 3, 1, -10];
      
      eval {
        Fn->sort_short($nums, -1, 3, method : int ($a : short, $b : short) {
          return $a <=> $b;
        });
      };
      unless ($@) {
        return 0;
      }
    }

    # Exception - Length must be more than or equals to 0
    {
      my $nums = [(short)5, 2, 3, 1, -10];
      
      eval {
        Fn->sort_short($nums, 1, -1, method : int ($a : short, $b : short) {
          return $a <=> $b;
        });
      };
      unless ($@) {
        return 0;
      }
    }

    # Exception - Offset + Length must be in the array range
    {
      my $nums = [(short)5, 2, 3, 1, -10];
      
      eval {
        Fn->sort_short($nums, 3, 3, method : int ($a : short, $b : short) {
          return $a <=> $b;
        });
      };
      unless ($@) {
        return 0;
      }
    }
    
    $@ = undef;
    
    return 1;
  }

  static method sort_int : int () {
    # Sort array by asc order
    {
      my $nums = [(int)2, 3, 1];
      
      Fn->sort_int($nums, 0, scalar @$nums, method : int ($a : int, $b : int) {
        return $a <=> $b;
      });
      
      unless (Fn->equals_array_int($nums, [(int)1, 2, 3])) {
        return 0;
      }
    }

    # Sort array by asc order more long
    {
      my $nums = [(int)5, 7, 9, 2, 4, 8, 1, 3, 6, 0];
      
      Fn->sort_int($nums, 0, scalar @$nums, method : int ($a : int, $b : int) {
        return $a <=> $b;
      });
      
      unless (Fn->equals_array_int($nums, [(int)0, 1, 2, 3, 4, 5, 6, 7, 8, 9])) {
        return 0;
      }
    }

    # Sort array by asc order more long with same values
    {
      my $nums = [(int)5, 7, 9, 2, 5, 4, 8, 1, 3, 6, 3, 0];
      
      Fn->sort_int($nums, 0, scalar @$nums, method : int ($a : int, $b : int) {
        return $a <=> $b;
      });
      
      unless (Fn->equals_array_int($nums, [(int)0, 1, 2, 3, 3, 4, 5, 5, 6, 7, 8, 9])) {
        return 0;
      }
    }

    # Sort int array by desc order
    {
      my $nums = [(int)2, 3, 1];
      
      Fn->sort_int($nums, 0, scalar @$nums, method : int ($a : int, $b : int) {
        return $b <=> $a;
      });
      
      unless (Fn->equals_array_int($nums, [(int)3, 2, 1])) {
        return 0;
      }
    }

    # If length is 0, There is nothing to do
    {
      my $nums = [(int)2, 3, 1];
      
      Fn->sort_int($nums, 0, 0, method : int ($a : int, $b : int) {
        return $a <=> $b;
      });
      
      unless (Fn->equals_array_int($nums, [(int)2, 3, 1])) {
        return 0;
      }
    }
    
    # Sort partially
    {
      my $nums = [(int)5, 2, 3, 1, -10];
      
      Fn->sort_int($nums, 1, 3, method : int ($a : int, $b : int) {
        return $a <=> $b;
      });
      
      unless (Fn->equals_array_int($nums, [(int)5, 1, 2, 3, -10])) {
        return 0;
      }
    }

    # Exception - Array must be not undef
    {
      my $nums = [(int)2, 3, 1];
      
      eval {
        Fn->sort_int(undef, 0, scalar @$nums, method : int ($a : int, $b : int) {
          return $a <=> $b;
        });
      };
      unless ($@) {
        return 0;
      }
    }
    
    # Exception - Offset must be more than or equals to 0
    {
      my $nums = [(int)5, 2, 3, 1, -10];
      
      eval {
        Fn->sort_int($nums, -1, 3, method : int ($a : int, $b : int) {
          return $a <=> $b;
        });
      };
      unless ($@) {
        return 0;
      }
    }

    # Exception - Length must be more than or equals to 0
    {
      my $nums = [(int)5, 2, 3, 1, -10];
      
      eval {
        Fn->sort_int($nums, 1, -1, method : int ($a : int, $b : int) {
          return $a <=> $b;
        });
      };
      unless ($@) {
        return 0;
      }
    }

    # Exception - Offset + Length must be in the array range
    {
      my $nums = [(int)5, 2, 3, 1, -10];
      
      eval {
        Fn->sort_int($nums, 3, 3, method : int ($a : int, $b : int) {
          return $a <=> $b;
        });
      };
      unless ($@) {
        return 0;
      }
    }
    
    $@ = undef;
    
    return 1;
  }

  static method sort_long : int () {
    # Sort array by asc order
    {
      my $nums = [(long)2, 3, 1];
      
      Fn->sort_long($nums, 0, scalar @$nums, method : int ($a : long, $b : long) {
        return $a <=> $b;
      });
      
      unless (Fn->equals_array_long($nums, [(long)1, 2, 3])) {
        return 0;
      }
    }

    # Sort array by asc order more long
    {
      my $nums = [(long)5, 7, 9, 2, 4, 8, 1, 3, 6, 0];
      
      Fn->sort_long($nums, 0, scalar @$nums, method : int ($a : long, $b : long) {
        return $a <=> $b;
      });
      
      unless (Fn->equals_array_long($nums, [(long)0, 1, 2, 3, 4, 5, 6, 7, 8, 9])) {
        return 0;
      }
    }

    # Sort array by asc order more long with same values
    {
      my $nums = [(long)5, 7, 9, 2, 5, 4, 8, 1, 3, 6, 3, 0];
      
      Fn->sort_long($nums, 0, scalar @$nums, method : int ($a : long, $b : long) {
        return $a <=> $b;
      });
      
      unless (Fn->equals_array_long($nums, [(long)0, 1, 2, 3, 3, 4, 5, 5, 6, 7, 8, 9])) {
        return 0;
      }
    }

    # Sort long array by desc order
    {
      my $nums = [(long)2, 3, 1];
      
      Fn->sort_long($nums, 0, scalar @$nums, method : int ($a : long, $b : long) {
        return $b <=> $a;
      });
      
      unless (Fn->equals_array_long($nums, [(long)3, 2, 1])) {
        return 0;
      }
    }

    # If length is 0, There is nothing to do
    {
      my $nums = [(long)2, 3, 1];
      
      Fn->sort_long($nums, 0, 0, method : int ($a : long, $b : long) {
        return $a <=> $b;
      });
      
      unless (Fn->equals_array_long($nums, [(long)2, 3, 1])) {
        return 0;
      }
    }
    
    # Sort partially
    {
      my $nums = [(long)5, 2, 3, 1, -10];
      
      Fn->sort_long($nums, 1, 3, method : int ($a : long, $b : long) {
        return $a <=> $b;
      });
      
      unless (Fn->equals_array_long($nums, [(long)5, 1, 2, 3, -10])) {
        return 0;
      }
    }

    # Exception - Array must be not undef
    {
      my $nums = [(long)2, 3, 1];
      
      eval {
        Fn->sort_long(undef, 0, scalar @$nums, method : int ($a : long, $b : long) {
          return $a <=> $b;
        });
      };
      unless ($@) {
        return 0;
      }
    }
    
    # Exception - Offset must be more than or equals to 0
    {
      my $nums = [(long)5, 2, 3, 1, -10];
      
      eval {
        Fn->sort_long($nums, -1, 3, method : int ($a : long, $b : long) {
          return $a <=> $b;
        });
      };
      unless ($@) {
        return 0;
      }
    }

    # Exception - Length must be more than or equals to 0
    {
      my $nums = [(long)5, 2, 3, 1, -10];
      
      eval {
        Fn->sort_long($nums, 1, -1, method : int ($a : long, $b : long) {
          return $a <=> $b;
        });
      };
      unless ($@) {
        return 0;
      }
    }

    # Exception - Offset + Length must be in the array range
    {
      my $nums = [(long)5, 2, 3, 1, -10];
      
      eval {
        Fn->sort_long($nums, 3, 3, method : int ($a : long, $b : long) {
          return $a <=> $b;
        });
      };
      unless ($@) {
        return 0;
      }
    }
    
    $@ = undef;
    
    return 1;
  }

  static method sort_float : int () {
    # Sort array by asc order
    {
      my $nums = [(float)2, 3, 1];
      
      Fn->sort_float($nums, 0, scalar @$nums, method : int ($a : float, $b : float) {
        return $a <=> $b;
      });
      
      unless (Fn->equals_array_float($nums, [(float)1, 2, 3])) {
        return 0;
      }
    }

    # Sort array by asc order more long
    {
      my $nums = [(float)5, 7, 9, 2, 4, 8, 1, 3, 6, 0];
      
      Fn->sort_float($nums, 0, scalar @$nums, method : int ($a : float, $b : float) {
        return $a <=> $b;
      });
      
      unless (Fn->equals_array_float($nums, [(float)0, 1, 2, 3, 4, 5, 6, 7, 8, 9])) {
        return 0;
      }
    }

    # Sort array by asc order more long with same values
    {
      my $nums = [(float)5, 7, 9, 2, 5, 4, 8, 1, 3, 6, 3, 0];
      
      Fn->sort_float($nums, 0, scalar @$nums, method : int ($a : float, $b : float) {
        return $a <=> $b;
      });
      
      unless (Fn->equals_array_float($nums, [(float)0, 1, 2, 3, 3, 4, 5, 5, 6, 7, 8, 9])) {
        return 0;
      }
    }

    # Sort float array by desc order
    {
      my $nums = [(float)2, 3, 1];
      
      Fn->sort_float($nums, 0, scalar @$nums, method : int ($a : float, $b : float) {
        return $b <=> $a;
      });
      
      unless (Fn->equals_array_float($nums, [(float)3, 2, 1])) {
        return 0;
      }
    }

    # If length is 0, There is nothing to do
    {
      my $nums = [(float)2, 3, 1];
      
      Fn->sort_float($nums, 0, 0, method : int ($a : float, $b : float) {
        return $a <=> $b;
      });
      
      unless (Fn->equals_array_float($nums, [(float)2, 3, 1])) {
        return 0;
      }
    }
    
    # Sort partially
    {
      my $nums = [(float)5, 2, 3, 1, -10];
      
      Fn->sort_float($nums, 1, 3, method : int ($a : float, $b : float) {
        return $a <=> $b;
      });
      
      unless (Fn->equals_array_float($nums, [(float)5, 1, 2, 3, -10])) {
        return 0;
      }
    }

    # Exception - Array must be not undef
    {
      my $nums = [(float)2, 3, 1];
      
      eval {
        Fn->sort_float(undef, 0, scalar @$nums, method : int ($a : float, $b : float) {
          return $a <=> $b;
        });
      };
      unless ($@) {
        return 0;
      }
    }
    
    # Exception - Offset must be more than or equals to 0
    {
      my $nums = [(float)5, 2, 3, 1, -10];
      
      eval {
        Fn->sort_float($nums, -1, 3, method : int ($a : float, $b : float) {
          return $a <=> $b;
        });
      };
      unless ($@) {
        return 0;
      }
    }

    # Exception - Length must be more than or equals to 0
    {
      my $nums = [(float)5, 2, 3, 1, -10];
      
      eval {
        Fn->sort_float($nums, 1, -1, method : int ($a : float, $b : float) {
          return $a <=> $b;
        });
      };
      unless ($@) {
        return 0;
      }
    }

    # Exception - Offset + Length must be in the array range
    {
      my $nums = [(float)5, 2, 3, 1, -10];
      
      eval {
        Fn->sort_float($nums, 3, 3, method : int ($a : float, $b : float) {
          return $a <=> $b;
        });
      };
      unless ($@) {
        return 0;
      }
    }
    
    $@ = undef;
    
    return 1;
  }

  static method sort_double : int () {
    # Sort array by asc order
    {
      my $nums = [(double)2, 3, 1];
      
      Fn->sort_double($nums, 0, scalar @$nums, method : int ($a : double, $b : double) {
        return $a <=> $b;
      });
      
      unless (Fn->equals_array_double($nums, [(double)1, 2, 3])) {
        return 0;
      }
    }

    # Sort array by asc order more long
    {
      my $nums = [(double)5, 7, 9, 2, 4, 8, 1, 3, 6, 0];
      
      Fn->sort_double($nums, 0, scalar @$nums, method : int ($a : double, $b : double) {
        return $a <=> $b;
      });
      
      unless (Fn->equals_array_double($nums, [(double)0, 1, 2, 3, 4, 5, 6, 7, 8, 9])) {
        return 0;
      }
    }

    # Sort array by asc order more long with same values
    {
      my $nums = [(double)5, 7, 9, 2, 5, 4, 8, 1, 3, 6, 3, 0];
      
      Fn->sort_double($nums, 0, scalar @$nums, method : int ($a : double, $b : double) {
        return $a <=> $b;
      });
      
      unless (Fn->equals_array_double($nums, [(double)0, 1, 2, 3, 3, 4, 5, 5, 6, 7, 8, 9])) {
        return 0;
      }
    }

    # Sort double array by desc order
    {
      my $nums = [(double)2, 3, 1];
      
      Fn->sort_double($nums, 0, scalar @$nums, method : int ($a : double, $b : double) {
        return $b <=> $a;
      });
      
      unless (Fn->equals_array_double($nums, [(double)3, 2, 1])) {
        return 0;
      }
    }

    # If length is 0, There is nothing to do
    {
      my $nums = [(double)2, 3, 1];
      
      Fn->sort_double($nums, 0, 0, method : int ($a : double, $b : double) {
        return $a <=> $b;
      });
      
      unless (Fn->equals_array_double($nums, [(double)2, 3, 1])) {
        return 0;
      }
    }
    
    # Sort partially
    {
      my $nums = [(double)5, 2, 3, 1, -10];
      
      Fn->sort_double($nums, 1, 3, method : int ($a : double, $b : double) {
        return $a <=> $b;
      });
      
      unless (Fn->equals_array_double($nums, [(double)5, 1, 2, 3, -10])) {
        return 0;
      }
    }

    # Exception - Array must be not undef
    {
      my $nums = [(double)2, 3, 1];
      
      eval {
        Fn->sort_double(undef, 0, scalar @$nums, method : int ($a : double, $b : double) {
          return $a <=> $b;
        });
      };
      unless ($@) {
        return 0;
      }
    }
    
    # Exception - Offset must be more than or equals to 0
    {
      my $nums = [(double)5, 2, 3, 1, -10];
      
      eval {
        Fn->sort_double($nums, -1, 3, method : int ($a : double, $b : double) {
          return $a <=> $b;
        });
      };
      unless ($@) {
        return 0;
      }
    }

    # Exception - Length must be more than or equals to 0
    {
      my $nums = [(double)5, 2, 3, 1, -10];
      
      eval {
        Fn->sort_double($nums, 1, -1, method : int ($a : double, $b : double) {
          return $a <=> $b;
        });
      };
      unless ($@) {
        return 0;
      }
    }

    # Exception - Offset + Length must be in the array range
    {
      my $nums = [(double)5, 2, 3, 1, -10];
      
      eval {
        Fn->sort_double($nums, 3, 3, method : int ($a : double, $b : double) {
          return $a <=> $b;
        });
      };
      unless ($@) {
        return 0;
      }
    }
    
    $@ = undef;
    
    return 1;
  }

  static method sort_string : int () {
    # Sort array by asc order
    {
      my $strings = [(string)2, 3, 1];
      
      Fn->sort_string($strings, 0, scalar @$strings, method : int ($a : string, $b : string) {
        return $a cmp $b;
      });
      
      unless (Fn->equals_array_string($strings, [(string)1, 2, 3])) {
        return 0;
      }
    }

    # Sort array by asc order more long
    {
      my $strings = [(string)5, 7, 9, 2, 4, 8, 1, 3, 6, 0];
      
      Fn->sort_string($strings, 0, scalar @$strings, method : int ($a : string, $b : string) {
        return $a cmp $b;
      });
      
      unless (Fn->equals_array_string($strings, [(string)0, 1, 2, 3, 4, 5, 6, 7, 8, 9])) {
        return 0;
      }
    }

    # Sort array by asc order more long with same values
    {
      my $strings = [(string)5, 7, 9, 2, 5, 4, 8, 1, 3, 6, 3, 0];
      
      Fn->sort_string($strings, 0, scalar @$strings, method : int ($a : string, $b : string) {
        return $a cmp $b;
      });
      
      unless (Fn->equals_array_string($strings, [(string)0, 1, 2, 3, 3, 4, 5, 5, 6, 7, 8, 9])) {
        return 0;
      }
    }

    # Sort string array by desc order
    {
      my $strings = [(string)2, 3, 1];
      
      Fn->sort_string($strings, 0, scalar @$strings, method : int ($a : string, $b : string) {
        return $b cmp $a;
      });
      
      unless (Fn->equals_array_string($strings, [(string)3, 2, 1])) {
        return 0;
      }
    }

    # If length is 0, There is nothing to do
    {
      my $strings = [(string)2, 3, 1];
      
      Fn->sort_string($strings, 0, 0, method : int ($a : string, $b : string) {
        return $a cmp $b;
      });
      
      unless (Fn->equals_array_string($strings, [(string)2, 3, 1])) {
        return 0;
      }
    }
    
    # Sort partially
    {
      my $strings = [(string)5, 2, 3, 1, -10];
      
      Fn->sort_string($strings, 1, 3, method : int ($a : string, $b : string) {
        return $a cmp $b;
      });
      
      unless (Fn->equals_array_string($strings, [(string)5, 1, 2, 3, -10])) {
        return 0;
      }
    }

    # Sort length is differnt and contain empty string and undef
    {
      my $strings = ["11", "1", "2", undef, ""];
      
      Fn->sort_string($strings, 0, scalar @$strings, method : int ($a : string, $b : string) {
        return $a cmp $b;
      });
      
      unless (Fn->equals_array_string($strings, [(string)undef, "", "1", "11", "2"])) {
        return 0;
      }
    }

    # Exception - Array must be not undef
    {
      my $strings = [(string)2, 3, 1];
      
      eval {
        Fn->sort_string(undef, 0, scalar @$strings, method : int ($a : string, $b : string) {
          return $a cmp $b;
        });
      };
      unless ($@) {
        return 0;
      }
    }
    
    # Exception - Offset must be more than or equals to 0
    {
      my $strings = [(string)5, 2, 3, 1, -10];
      
      eval {
        Fn->sort_string($strings, -1, 3, method : int ($a : string, $b : string) {
          return $a cmp $b;
        });
      };
      unless ($@) {
        return 0;
      }
    }

    # Exception - Length must be more than or equals to 0
    {
      my $strings = [(string)5, 2, 3, 1, -10];
      
      eval {
        Fn->sort_string($strings, 1, -1, method : int ($a : string, $b : string) {
          return $a cmp $b;
        });
      };
      unless ($@) {
        return 0;
      }
    }

    # Exception - Offset + Length must be in the array range
    {
      my $strings = [(string)5, 2, 3, 1, -10];
      
      eval {
        Fn->sort_string($strings, 3, 3, method : int ($a : string, $b : string) {
          return $a cmp $b;
        });
      };
      unless ($@) {
        return 0;
      }
    }
    
    $@ = undef;
    
    return 1;
  }

  static method new_minimal : TestCase::Minimal ($x : int, $y : int) {
    my $minimal = TestCase::Minimal->new;
    $minimal->set_x($x);
    $minimal->set_y($y);
    
    return $minimal;
  }
  
  static method sort_object : int () {
    
    # Sort array by asc order
    {
      my $objs = [&new_minimal(2, 0), &new_minimal(3, 0), &new_minimal(1, 0)];
      
      Fn->sort_object($objs, 0, scalar @$objs, method : int ($a : object, $b : object) {
        return ((TestCase::Minimal)$a)->x <=> ((TestCase::Minimal)$b)->x;
      });
      
      my $is_equals = Fn->equals_array_object($objs, [&new_minimal(1, 0), &new_minimal(2, 0), &new_minimal(3, 0)], method : int ($a : object, $b : object) {
        return ((TestCase::Minimal)$a)->x == ((TestCase::Minimal)$b)->x;
      });
      
      unless ($is_equals) {
        return 0;
      }
    }

    # Sort array by multiple conditions
    {
      my $objs = [&new_minimal(2, 1), &new_minimal(2, 2), &new_minimal(1, 3)];

      Fn->sort_object($objs, 0, scalar @$objs, method : int ($a : object, $b : object) {
        my $a_x = ((TestCase::Minimal)$a)->x;
        my $a_y = ((TestCase::Minimal)$a)->y;
        my $b_x = ((TestCase::Minimal)$b)->x;
        my $b_y = ((TestCase::Minimal)$b)->y;
        
        my $cmp = ((TestCase::Minimal)$a)->x <=> ((TestCase::Minimal)$b)->x;
        if ($cmp != 0) {
          return $cmp;
        }
        else {
          $cmp = ((TestCase::Minimal)$a)->y <=> ((TestCase::Minimal)$b)->y;
        }
        
        return $cmp;
      });

      my $is_equals = Fn->equals_array_object($objs, [&new_minimal(1, 3), &new_minimal(2, 1), &new_minimal(2, 2)], method : int ($a : object, $b : object) {
        if (((TestCase::Minimal)$a)->x == ((TestCase::Minimal)$b)->x && ((TestCase::Minimal)$a)->y == ((TestCase::Minimal)$b)->y) {
          return 1;
        }
        else {
          return 0;
        }
      });
      
      unless ($is_equals) {
        return 0;
      }
    }

    # Sort array by desc order
    {
      my $objs = [&new_minimal(2, 0), &new_minimal(3, 0), &new_minimal(1, 0)];
      
      Fn->sort_object($objs, 0, scalar @$objs, method : int ($a : object, $b : object) {
        return ((TestCase::Minimal)$b)->x <=> ((TestCase::Minimal)$a)->x;
      });
      
      my $is_equals = Fn->equals_array_object($objs, [&new_minimal(3, 0), &new_minimal(2, 0), &new_minimal(1, 0)], method : int ($a : object, $b : object) {
        return ((TestCase::Minimal)$a)->x == ((TestCase::Minimal)$b)->x;
      });
      
      unless ($is_equals) {
        return 0;
      }
    }

    # If length is 0, There is nothing to do
    {
      my $objs = [&new_minimal(2, 0), &new_minimal(3, 0), &new_minimal(1, 0)];
      
      Fn->sort_object($objs, 0, 0, method : int ($a : object, $b : object) {
        return ((TestCase::Minimal)$a)->x <=> ((TestCase::Minimal)$b)->x;
      });
      
      my $is_equals = Fn->equals_array_object($objs, [&new_minimal(2, 0), &new_minimal(3, 0), &new_minimal(1, 0)], method : int ($a : object, $b : object) {
        return ((TestCase::Minimal)$a)->x == ((TestCase::Minimal)$b)->x;
      });
      unless ($is_equals) {
        return 0;
      }
    }
    
    # Sort partially
    {
      my $objs = [&new_minimal(5, 0), &new_minimal(2, 0), &new_minimal(3, 0), &new_minimal(1, 0), &new_minimal(-10, 0)];
      
      Fn->sort_object($objs, 1, 3, method : int ($a : object, $b : object) {
        return ((TestCase::Minimal)$a)->x <=> ((TestCase::Minimal)$b)->x;
      });
      
      my $is_equals = Fn->equals_array_object(
        $objs,
        [&new_minimal(5, 0), &new_minimal(1, 0), &new_minimal(2, 0), &new_minimal(3, 0), &new_minimal(-10, 0)],
        method : int ($a : object, $b : object) {
          return ((TestCase::Minimal)$a)->x == ((TestCase::Minimal)$b)->x;
        }
      );
      unless ($is_equals) {
        return 0;
      }
    }

    # Exception - Array must be not undef
    {
      my $objs = [&new_minimal(2, 0), &new_minimal(3, 0), &new_minimal(1, 0)];
      
      eval {
        Fn->sort_object(undef, 0, scalar @$objs, method : int ($a : object, $b : object) {
          return ((TestCase::Minimal)$a)->x <=> ((TestCase::Minimal)$b)->x;
        });
      };
      unless ($@) {
        return 0;
      }
    }
    
    # Exception - Offset must be more than or equals to 0
    {
      my $objs = [&new_minimal(2, 0), &new_minimal(3, 0), &new_minimal(1, 0)];
      
      eval {
        Fn->sort_object($objs, -1, 3, method : int ($a : object, $b : object) {
          return ((TestCase::Minimal)$a)->x <=> ((TestCase::Minimal)$b)->x;
        });
      };
      unless ($@) {
        return 0;
      }
    }

    # Exception - Length must be more than or equals to 0
    {
      my $objs = [&new_minimal(5, 0), &new_minimal(2, 0), &new_minimal(3, 0), &new_minimal(1, 0), &new_minimal(-10, 0)];
      
      eval {
        Fn->sort_object($objs, 1, -1, method : int ($a : object, $b : object) {
          return ((TestCase::Minimal)$a)->x <=> ((TestCase::Minimal)$b)->x;
        });
      };
      unless ($@) {
        return 0;
      }
    }

    # Exception - Offset + Length must be in the array range
    {
      my $objs = [&new_minimal(5, 0), &new_minimal(2, 0), &new_minimal(3, 0), &new_minimal(1, 0), &new_minimal(-10, 0)];
      
      eval {
        Fn->sort_object($objs, 3, 3, method : int ($a : object, $b : object) {
          return ((TestCase::Minimal)$a)->x <=> ((TestCase::Minimal)$b)->x;
        });
      };
      unless ($@) {
        return 0;
      }
    }
    
    $@ = undef;

    return 1;
  }

  static method chr : int () {
    
    {
      unless (Fn->chr(0) eq "\0") {
        return 0;
      }

      unless (Fn->chr('0') eq "0") {
        return 0;
      }

      unless (Fn->chr('a') eq "a") {
        return 0;
      }

      unless (Fn->chr(0x3042) eq "あ") {
        return 0;
      }
      
      if (Fn->chr(-1)) {
        return 0;
      }

      unless (Fn->chr(0xD800 - 1)) {
        return 0;
      }

      if (Fn->chr(0xD800)) {
        return 0;
      }

      if (Fn->chr(0xDFFF)) {
        return 0;
      }

      unless (Fn->chr(0xDFFF + 1)) {
        return 0;
      }

      unless (Fn->chr(0x10FFFF)) {
        return 0;
      }

      if (Fn->chr(0x10FFFF + 1)) {
        return 0;
      }
    }
    
    return 1;
  }

  static method ord : int () {
    
    unless (Fn->ord("a") == 97) {
      return 0;
    }
    unless (Fn->ord("ab") == 97) {
      return 0;
    }
    unless (Fn->ord("\x00") == 0) {
      return 0;
    }
    
    unless (Fn->ord("\x01") == 1) {
      return 0;
    }

    unless (Fn->ord("\x7F") == 127) {
      return 0;
    }

    unless (Fn->ord("あ") == 12354) {
      return 0;
    }
    
    # Unicode max scalar value
    unless (Fn->ord(Fn->chr(0x10FFFF)) == 0x10FFFF) {
      return 0;
    }
    
    # Error
    {
      unless (Fn->ord("") < 0) {
        return 0;
      }
      unless (Fn->ord(undef) < 0) {
        return 0;
      }
    }
    
    return 1;
  }

  static method repeat : int () {
    
    unless (Fn->repeat("abc", 3) eq "abcabcabc") {
      return 0;
    }

    # Exception
    {
      eval { Fn->repeat(undef, 1); };
      unless ($@) {
        return 0;
      }
      
      eval { Fn->repeat("abc", 0); };
      unless ($@) {
        return 0;
      }
    }
    
    $@ = undef;
    
    return 1;
  }

  static method match : int () {
    
    # match
    {
      my $match = Fn->match("ppzabcz", "abc");
      unless ($match) {
        return 0;
      }
      
      unless ($match isa Regex) {
        return 0;
      }
    }
    
    # not match
    {
      my $match = Fn->match("ppzabcz", "abd");
      unless ($match == undef) {
        return 0;
      }
    }
    
    # . - single line mode
    {
      my $m = Fn->match("abc\ndef", "(.+)", "s");
      
      unless ($m) {
        return 0;
      }
      
      unless ($m->cap1 eq "abc\ndef") {
        return 0;
      }
    }
    
    return 1;
  }

  static method replace : int () {
    
    {
      my $result = Fn->replace("xyzAAAxyzAAA", "A+", "BBB");
      unless ($result eq "xyzBBBxyzAAA") {
        return 0;
      }
    }
    
    {
      # "xyzBBBxyzBBB"
      my $result = Fn->replace("xyzAAAxyzAAA", "A+", "BBB", "g");
      unless ($result eq "xyzBBBxyzBBB") {
        return 0;
      }
    }
    
    {
      # "xyzaaaxyzAAA"
      my $result = Fn->replace("xyzAAAxyzAAA", "(A+)", method : string ($re : Regex) { return Fn->lc($re->captures->[0]); });
      unless ($result eq "xyzaaaxyzAAA") {
        return 0;
      }
    }
    
    {
      # "xyzaaaxyzaaa"
      my $result = Fn->replace("xyzAAAxyzAAA", "(A+)", method : string ($re : Regex) { return Fn->lc($re->captures->[0]); }, "g");
      unless ($result eq "xyzaaaxyzaaa") {
        return 0;
      }
    }
    
    return 1;
  }
}