package TestCase::Lib::SPVM::CORE {
  use TestCase::Minimal;
  use SPVM::Errno;
  use SPVM::Time (time);

  sub test_rand : int () {
    my $seed = (int)time();
    my $founds = new int[10];
    for (my $i = 0; $i < 100000; $i++) {
      my $rand = rand(\$seed);
      if ($rand < 0) {
        return 0;
      }
      my $dig0 = $rand % 10;
      $founds->[$dig0] = 1;
    }
    
    unless (equals_iarray($founds, [1, 1, 1, 1, 1, 1, 1, 1, 1, 1])) {
      return 0;
    }
    
    return 1;
  }
  
  sub test_ucfirst : int () {
    {
      my $str = "@abc";
      my $result_str = ucfirst($str);
      unless ($result_str eq "@abc") {
        return 0;
      }
    }
    {
      my $str = "[abc";
      my $result_str = ucfirst($str);
      unless ($result_str eq "[abc") {
        return 0;
      }
    }

    {
      my $str = "aabc";
      my $result_str = ucfirst($str);
      unless ($result_str eq "Aabc") {
        return 0;
      }
    }

    {
      my $str = "pabc";
      my $result_str = ucfirst($str);
      unless ($result_str eq "Pabc") {
        return 0;
      }
    }

    {
      my $str = "zabc";
      my $result_str = ucfirst($str);
      unless ($result_str eq "Zabc") {
        return 0;
      }
    }
    return 1;
  }

  sub test_uc : int () {
    {
      my $str = "@[apz[";
      my $result_str = uc($str);
      unless ($result_str eq "@[APZ[") {
        return 0;
      }
    }
    return 1;
  }

  sub test_lc : int () {
    {
      my $str = "@[APZ[";
      my $result_str = lc($str);
      unless ($result_str eq "@[apz[") {
        return 0;
      }
    }
    return 1;
  }

  sub test_lcfirst : int () {
    {
      my $str = "@ABC";
      my $result_str = lcfirst($str);
      unless ($result_str eq "@ABC") {
        return 0;
      }
    }
    {
      my $str = "[ABC";
      my $result_str = lcfirst($str);
      unless ($result_str eq "[ABC") {
        return 0;
      }
    }

    {
      my $str = "AABC";
      my $result_str = lcfirst($str);
      unless ($result_str eq "aABC") {
        return 0;
      }
    }

    {
      my $str = "PABC";
      my $result_str = lcfirst($str);
      unless ($result_str eq "pABC") {
        return 0;
      }
    }

    {
      my $str = "ZABC";
      my $result_str = lcfirst($str);
      unless ($result_str eq "zABC") {
        return 0;
      }
    }
    return 1;
  }
  sub test_replace_all : int () {
    
    {
      my $str = "foo bar foo bar foo";
      my $substr = "bar";
      my $replace = "AB";
      my $result_str = replace_all($str, $substr, $replace);
      unless ($result_str eq "foo AB foo AB foo") {
        return 0;
      }
    }

    {
      my $str = "foobarfoobarfoo";
      my $substr = "bar";
      my $replace = "";
      my $result_str = replace_all($str, $substr, $replace);
      unless ($result_str eq "foofoofoo") {
        return 0;
      }
    }

    return 1;
  }

  sub test_replace : int () {
    
    {
      my $str = "abcde";
      my $substr = "bcd";
      my $replace = "AB";
      my $found_pos : int;
      my $result_str = replace($str, $substr, $replace, 0, \$found_pos);
      unless ($found_pos == 1) {
        return 0;
      }
      unless ($result_str eq "aABe") {
        return 0;
      }
    }

    {
      my $str = "abcde";
      my $substr = "bcd";
      my $replace = "AB";
      my $found_pos : int;
      my $result_str = replace($str, $substr, $replace, 2, \$found_pos);
      unless ($found_pos == -1) {
        return 0;
      }
      unless ($result_str eq $str) {
        return 0;
      }
    }

    {
      my $str = "abcde";
      my $substr = "abc";
      my $replace = "ABCD";
      my $found_pos : int;
      my $result_str = replace($str, $substr, $replace, 0, \$found_pos);
      unless ($found_pos == 0) {
        return 0;
      }
      unless ($result_str eq "ABCDde") {
        return 0;
      }
    }

    {
      my $str = "abcde";
      my $substr = "cde";
      my $replace = "ABCD";
      my $found_pos : int;
      my $result_str = replace($str, $substr, $replace, 0, \$found_pos);
      unless ($found_pos == 2) {
        return 0;
      }
      unless ($result_str eq "abABCD") {
        return 0;
      }
    }

    {
      my $str = "abcdcd";
      my $substr = "cd";
      my $replace = "A";
      my $found_pos : int;
      my $result_str = replace($str, $substr, $replace, 4, \$found_pos);
      unless ($found_pos == 4) {
        return 0;
      }
      unless ($result_str eq "abcdA") {
        return 0;
      }
    }

    {
      my $str = "abcd";
      my $substr = "bc";
      my $replace = "";
      my $found_pos : int;
      my $result_str = replace($str, $substr, $replace, 0, \$found_pos);
      
      unless ($found_pos == 1) {
        return 0;
      }
      unless ($result_str eq "ad") {
        return 0;
      }
    }
    
    return 1;
  }

  sub test_memcpy : int () {
    
    {
      my $target = "abcde";
      my $search = "ABC";
      memcpy((byte[])$target, 0, (byte[])$search, 0, 3);
      unless ($target eq "ABCde") {
        return 0;
      }
    }

    {
      my $target = "abcde";
      my $search = "ABC";
      memcpy((byte[])$target, 2, (byte[])$search, 0, 3);
      unless ($target eq "abABC") {
        return 0;
      }
    }

    {
      my $target = "abcde";
      my $search = "ABC";
      memcpy((byte[])$target, 2, (byte[])$search, 0, 3);
      unless ($target eq "abABC") {
        return 0;
      }
    }
    
    return 1;
  }

  sub test_memmove : int () {
    
    {
      my $target = "abcde";
      my $search = "ABC";
      memmove((byte[])$target, 0, (byte[])$search, 0, 3);
      unless ($target eq "ABCde") {
        return 0;
      }
    }

    {
      my $target = "abcde";
      my $search = "ABC";
      memmove((byte[])$target, 2, (byte[])$search, 0, 3);
      unless ($target eq "abABC") {
        return 0;
      }
    }

    {
      my $target = "abcde";
      my $search = "ABC";
      memmove((byte[])$target, 2, (byte[])$search, 0, 3);
      unless ($target eq "abABC") {
        return 0;
      }
    }

    {
      my $target = "abcde";
      memmove((byte[])$target, 0, (byte[])$target, 2, 2);
      unless ($target eq "cdcde") {
        return 0;
      }
    }
    
    return 1;
  }

  sub test_index : int () {
    
    {
      my $target = "abcde";
      my $search = "bcd";
      my $pos = index($target, $search, 0);
      unless ($pos == 1) {
        return 0;
      }
    }

    {
      my $target = "abcde";
      my $search = "bcd";
      my $pos = index($target, $search, 1);
      unless ($pos == 1) {
        return 0;
      }
    }

    {
      my $target = "abcde";
      my $search = "bcd";
      my $pos = index($target, $search, 2);
      unless ($pos == -1) {
        return 0;
      }
    }

    {
      my $target = "abcde";
      my $search = "pq";
      my $pos = index($target, $search, 2);
      unless ($pos == -1) {
        return 0;
      }
    }
    
    return 1;
  }

  sub test_contains : int () {
    
    {
      my $target = "abcde";
      my $search = "bcd";
      my $ret = contains($target, $search);
      unless ($ret) {
        return 0;
      }
    }
    
    {
      my $target = "abcde";
      my $search = "ppp";
      my $ret = contains($target, $search);
      if ($ret) {
        return 0;
      }
    }
    
    return 1;
  }

  sub test_strerror : int () {
    
    my $error = strerror(SPVM::Errno->ENOENT);
    
    unless (length $error > 0) {
      return 0;
    }
    
    return 1;
  }

  sub test_getenv : int () {
    
    my $value = getenv("SPVM_ENV_NAME");
    
    unless ($value eq "SPVM_ENV_VALUE") {
      return 0;
    }
    
    return 1;
  }

  sub test_split : int () {
    {
      my $str = "foo,bar,baz";
      my $split_strs = split(",", $str, -1);
      unless (equals_strarray($split_strs, ["foo", "bar", "baz"])) {
        return 0;
      }
    }
    
    {
      my $str = "foo,bar,";
      my $split_strs = split(",", $str, -1);
      unless (equals_strarray($split_strs, ["foo", "bar", ""])) {
        return 0;
      }
    }

    {
      my $str = ",foo,,bar,,";
      my $split_strs = split(",", $str, -1);
      unless (equals_strarray($split_strs, ["", "foo", "", "bar", "", ""])) {
        return 0;
      }
    }

    {
      my $str = "foo : bar : baz";
      my $split_strs = split(" : ", $str, -1);
      unless (equals_strarray($split_strs, ["foo", "bar", "baz"])) {
        return 0;
      }
    }
    {
      my $str = "foo : bar : ";
      my $split_strs = split(" : ", $str, -1);
      unless (equals_strarray($split_strs, ["foo", "bar", ""])) {
        return 0;
      }
    }
    {
      my $str = " : foo :  : bar :  : ";
      my $split_strs = split(" : ", $str, -1);
      unless (equals_strarray($split_strs, ["", "foo", "", "bar", "", ""])) {
        return 0;
      }
    }

    {
      my $str = "foo---bar---baz";
      my $split_strs = split("---", $str, -1);
      unless (equals_strarray($split_strs, ["foo", "bar", "baz"])) {
        return 0;
      }
    }
    {
      my $str = "foo---bar---";
      my $split_strs = split("---", $str, -1);
      unless (equals_strarray($split_strs, ["foo", "bar", ""])) {
        return 0;
      }
    }
    {
      my $str = "---foo------bar------";
      my $split_strs = split("---", $str, -1);
      unless (equals_strarray($split_strs, ["", "foo", "", "bar", "", ""])) {
        return 0;
      }
    }

    {
      my $str = "foo--!bar---baz";
      my $split_strs = split("---", $str, -1);
      unless (equals_strarray($split_strs, ["foo--!bar", "baz"])) {
        return 0;
      }
    }
    return 1;
  }

  sub test_init_native_constants : int () {
    {
      my $int_constants = [
        O_RDONLY(),
        O_WRONLY(),
        O_RDWR(),
        O_APPEND(),
        O_CREAT(),
        O_TRUNC(),
        SEEK_SET(),
        SEEK_CUR(),
        SEEK_END(),
        EOF(),
      ];
      
      my $ret = test_init_native_constants_native($int_constants);
      
      unless ($ret) {
        return 0;
      }
    }
    
    return 1;
  }

  native sub test_init_native_constants_native : int ($int_constants : int[]);

  sub test_join : int () {
    my $strings = ["abc", "def", "hij"];
    
    my $join = join(",", $strings);
    
    if ($join eq "abc,def,hij") {
      return 1;
    }
    
    return 0;
  }

  sub test_byte_constant : int () {
    if ((int)INT8_MIN() == (int)(byte)-128) {
      if ((int)INT8_MAX() == (int)(byte)127) {
        return 1;
      }
    }
    
    return 0;
  }

  sub test_short_constant : int () {
    if ((int)INT16_MIN() == (int)(short)-32768) {
      if ((int)INT16_MAX() == (int)(short)32767) {
        return 1;
      }
    }
    
    return 0;
  }

  sub test_int_constant : int () {
    if (INT32_MIN() == -2147483648) {
      if (INT32_MAX() == 2147483647) {
        return 1;
      }
    }
    
    return 0;
  }

  sub test_long_constant : int () {
    if (INT64_MIN() == -9223372036854775808L) {
      if (INT64_MAX() == 9223372036854775807L) {
        return 1;
      }
    }
    
    return 0;
  }

  sub test_new_oarray_proto : int () {
    my $minimals = new TestCase::Minimal[1];
    
    my $new_oarray = new_oarray_proto($minimals, 2);
    unless ($new_oarray isa TestCase::Minimal[]) {
      return 0;
    }
    my $new_minimals = (TestCase::Minimal[])$new_oarray;
    unless (@$new_minimals == 2) {
      return 0;
    }
    
    return 1;
  }
  sub test_sliceb : int () {
    {
      my $nums = [(byte)5, -7, 9, INT8_MIN(), 127, 15, 19];
      my $slice = sliceb($nums, 0, 7);
      unless (equals_barray($slice, [(byte)5, -7, 9, INT8_MIN(), 127, 15, 19])) {
        return 0;
      }
    }
    
    {
      my $nums = [(byte)5, -7, 9, INT8_MIN(), 127, 15, 19];
      my $slice = sliceb($nums, 1, 3);
      unless (equals_barray($slice, [(byte)-7, 9, INT8_MIN()])) {
        return 0;
      }
    }

    return 1;
  }
  sub test_slices : int () {
    {
      my $nums = [(short)5, -7, 9, INT16_MIN(), 127, 15, 19];
      my $slice = slices($nums, 0, 7);
      unless (equals_sarray($slice, [(short)5, -7, 9, INT16_MIN(), 127, 15, 19])) {
        return 0;
      }
    }
    {
      my $nums = [(short)5, -7, 9, INT16_MIN(), 127, 15, 19];
      my $slice = slices($nums, 1, 3);
      unless (equals_sarray($slice, [(short)-7, 9, INT16_MIN()])) {
        return 0;
      }
    }

    return 1;
  }
  sub test_slicei : int () {
    {
      my $nums = [(int)5, -7, 9, INT32_MIN(), 127, 15, 19];
      my $slice = slicei($nums, 0, 7);
      unless (equals_iarray($slice, [(int)5, -7, 9, INT32_MIN(), 127, 15, 19])) {
        return 0;
      }
    }
    {
      my $nums = [(int)5, -7, 9, INT32_MIN(), 127, 15, 19];
      my $slice = slicei($nums, 1, 3);
      unless (equals_iarray($slice, [(int)-7, 9, INT32_MIN()])) {
        return 0;
      }
    }
    return 1;
  }
  sub test_slicel : int () {
    {
      my $nums = [(long)5, -7, 9, INT64_MIN(), 127, 15, 19];
      my $slice = slicel($nums, 0, 7);
      unless (equals_larray($slice, [(long)5, -7, 9, INT64_MIN(), 127, 15, 19])) {
        return 0;
      }
    }
    {
      my $nums = [(long)5, -7, 9, INT64_MIN(), 127, 15, 19];
      my $slice = slicel($nums, 1, 3);
      unless (equals_larray($slice, [(long)-7, 9, INT64_MIN()])) {
        return 0;
      }
    }
    
    return 1;
  }
  sub test_slicef : int () {
    {
      my $nums = [(float)5, -7, 9, FLT_MIN(), 127, 15, 19];
      my $slice = slicef($nums, 0, 7);
      unless (equals_farray($slice, [(float)5, -7, 9, FLT_MIN(), 127, 15, 19])) {
        return 0;
      }
    }
    {
      my $nums = [(float)5, -7, 9, FLT_MIN(), 127, 15, 19];
      my $slice = slicef($nums, 1, 3);
      unless (equals_farray($slice, [(float)-7, 9, FLT_MIN()])) {
        return 0;
      }
    }
    
    
    return 1;
  }
  sub test_sliced : int () {
    {
      my $nums = [(double)5, -7, 9, DBL_MIN(), 127, 15, 19];
      my $slice = sliced($nums, 0, 7);
      unless (equals_darray($slice, [(double)5, -7, 9, DBL_MIN(), 127, 15, 19])) {
        return 0;
      }
    }
    {
      my $nums = [(double)5, -7, 9, DBL_MIN(), 127, 15, 19];
      my $slice = sliced($nums, 1, 3);
      unless (equals_darray($slice, [(double)-7, 9, DBL_MIN()])) {
        return 0;
      }
    }
    return 1;
  }
  sub test_sliceo : int () {
    {
      my $minimal1 = TestCase::Minimal->new;
      my $minimal2 = TestCase::Minimal->new;
      my $minimal3 = TestCase::Minimal->new;
      my $minimal4 = TestCase::Minimal->new;
      
      my $elems = [$minimal1, $minimal2, $minimal3, $minimal4];
      my $slice = (TestCase::Minimal[])sliceo($elems, 0, 4);
      unless (equals_oarray($slice, [$minimal1, $minimal2, $minimal3, $minimal4])) {
        return 0;
      }
    }
    {
      my $minimal1 = TestCase::Minimal->new;
      my $minimal2 = TestCase::Minimal->new;
      my $minimal3 = TestCase::Minimal->new;
      my $minimal4 = TestCase::Minimal->new;
      
      my $elems = [$minimal1, $minimal2, $minimal3, $minimal4];
      my $slice = (TestCase::Minimal[])sliceo($elems, 1, 2);
      unless (equals_oarray($slice, [$minimal2, $minimal3])) {
        return 0;
      }
    }
    return 1;
  }

  sub test_reverseb : int () {
    {
      my $nums = [(byte)1, 3, INT8_MAX()];
      reverseb($nums);
      unless (equals_barray($nums, [(byte)INT8_MAX(), 3, 1])) {
        return 0;
      }
    }
    {
      my $nums = [(byte)1, 3, 5, INT8_MAX()];
      reverseb($nums);
      unless (equals_barray($nums, [(byte)INT8_MAX(), 5, 3, 1])) {
        return 0;
      }
    }

    return 1;
  }
  sub test_reverses : int () {
    {
      my $nums = [(short)1, 3, INT16_MAX()];
      reverses($nums);
      unless (equals_sarray($nums, [(short)INT16_MAX(), 3, 1])) {
        return 0;
      }
    }
    {
      my $nums = [(short)1, 3, 5, INT16_MAX()];
      reverses($nums);
      unless (equals_sarray($nums, [(short)INT16_MAX(), 5, 3, 1])) {
        return 0;
      }
    }

    return 1;
  }
  sub test_reversei : int () {
    {
      my $nums = [(int)1, 3, INT32_MAX()];
      reversei($nums);
      unless (equals_iarray($nums, [(int)INT32_MAX(), 3, 1])) {
        return 0;
      }
    }
    {
      my $nums = [(int)1, 3, 5, INT32_MAX()];
      reversei($nums);
      unless (equals_iarray($nums, [(int)INT32_MAX(), 5, 3, 1])) {
        return 0;
      }
    }
    return 1;
  }
  sub test_reversel : int () {
    {
      my $nums = [(long)1, 3, INT64_MAX()];
      reversel($nums);
      unless (equals_larray($nums, [(long)INT64_MAX(), 3, 1])) {
        return 0;
      }
    }
    {
      my $nums = [(long)1, 3, 5, INT64_MAX()];
      reversel($nums);
      unless (equals_larray($nums, [(long)INT64_MAX(), 5, 3, 1])) {
        return 0;
      }
    }
    
    
    return 1;
  }
  sub test_reversef : int () {
    {
      my $nums = [(float)1, 3, FLT_MAX()];
      reversef($nums);
      unless (equals_farray($nums, [(float)FLT_MAX(), 3, 1])) {
        return 0;
      }
    }
    {
      my $nums = [(float)1, 3, 5, FLT_MAX()];
      reversef($nums);
      unless (equals_farray($nums, [(float)FLT_MAX(), 5, 3, 1])) {
        return 0;
      }
    }
    
    return 1;
  }
  sub test_reversed : int () {
    {
      my $nums = [(double)1, 3, DBL_MAX()];
      reversed($nums);
      unless (equals_darray($nums, [(double)DBL_MAX(), 3, 1])) {
        return 0;
      }
    }
    {
      my $nums = [(double)1, 3, 5, DBL_MAX()];
      reversed($nums);
      unless (equals_darray($nums, [(double)DBL_MAX(), 5, 3, 1])) {
        return 0;
      }
    }
    return 1;
  }

  sub test_reverseo : int () {
    {
      my $minimal1 = TestCase::Minimal->new;
      my $minimal2 = TestCase::Minimal->new;
      my $minimal3 = TestCase::Minimal->new;
      
      my $nums = [$minimal1, $minimal2, $minimal3];
      reverseo($nums);
      unless (equals_oarray($nums, [$minimal3, $minimal2, $minimal1])) {
        return 0;
      }
    }
    return 1;
  }

  sub test_sortb : int () {
    {
      my $nums = [(byte)5, -7, 9, INT8_MIN(), 127, 15, 19];
      sortb($nums);
      unless (equals_barray($nums, [(byte)INT8_MIN(), -7, 5, 9, 15, 19, 127])) {
        return 0;
      }
    }

    return 1;
  }
  sub test_sorts : int () {
    {
      my $nums = [(short)5, -7, 9, INT16_MIN(), 127, 15, 19];
      sorts($nums);
      unless (equals_sarray($nums, [(short)INT16_MIN(), -7, 5, 9, 15, 19, 127])) {
        return 0;
      }
    }

    return 1;
  }
  sub test_sorti : int () {
    {
      my $nums = [(int)5, -7, 9, INT32_MIN(), 127, 15, 19];
      sorti($nums);
      unless (equals_iarray($nums, [(int)INT32_MIN(), -7, 5, 9, 15, 19, 127])) {
        return 0;
      }
    }
    return 1;
  }
  sub test_sortl : int () {
    {
      my $nums = [(long)5, -7, 9, INT64_MIN(), 127, 15, 19];
      sortl($nums);
      unless (equals_larray($nums, [(long)INT64_MIN(), -7, 5, 9, 15, 19, 127])) {
        return 0;
      }
    }
    
    return 1;
  }
  sub test_sortf : int () {
    {
      my $nums = [(float)5, -7, 9, FLT_MIN(), 127, 15, 19];
      sortf($nums);
      unless (equals_farray($nums, [(float)-7, FLT_MIN(), 5, 9, 15, 19, 127])) {
        return 0;
      }
    }
    
    return 1;
  }
  sub test_sortd : int () {
    {
      my $nums = [(double)5, -7, 9, DBL_MIN(), 127, 15, 19];
      sortd($nums);
      unless (equals_darray($nums, [(double)-7, DBL_MIN(), 5, 9, 15, 19, 127])) {
        return 0;
      }
    }
    return 1;
  }

  sub test_sorto : int () {
    {
      my $m10 = TestCase::Minimal->newp(10, 419);
      my $m11 = TestCase::Minimal->newp(11, 366);
      my $m12 = TestCase::Minimal->newp(12, 402);
      my $m13 = TestCase::Minimal->newp(13, 453);
      my $m14 = TestCase::Minimal->newp(14, 419);
      my $m15 = TestCase::Minimal->newp(15, 402);
      
      my $ms = [$m10, $m11, $m12, $m13, $m14, $m15];
      sorto($ms, sub : int ($self : self, $x1 : object, $x2 : object) {
        my $m1 = (TestCase::Minimal)$x1;
        my $m2 = (TestCase::Minimal)$x2;
        if ($m1->y > $m2->y) {
          return 1;
        }
        elsif ($m1->y < $m2->y) {
          return -1;
        }
        else {
          return 0;
        }
      });
      unless (equals_oarray($ms, [$m11, $m12, $m15, $m10, $m14, $m13])) {
        return 0;
      }
    }
    return 1;
  }

  sub test_equals_barray : int () {
    my $nums1 = [(byte)0, 1, INT8_MIN()];
    my $nums2 = [(byte)0, 1, INT8_MIN()];
    my $nums3 = [(byte)0, 1];
    my $nums4 = [(byte)0, 1, 2];
    {
      my $is_equals = equals_barray($nums1, $nums2);
      unless ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = equals_barray($nums1, $nums3);
      if ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = equals_barray($nums1, $nums4);
      if ($is_equals) {
        return 0;
      }
    }
    
    return 1;
  }

  sub test_equals_sarray : int () {
    my $nums1 = [(short)0, 1, INT16_MIN()];
    my $nums2 = [(short)0, 1, INT16_MIN()];
    my $nums3 = [(short)0, 1];
    my $nums4 = [(short)0, 1, 2];
    
    {
      my $is_equals = equals_sarray($nums1, $nums2);
      
      unless ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = equals_sarray($nums1, $nums3);
      
      if ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = equals_sarray($nums1, $nums4);
      if ($is_equals) {
        return 0;
      }
    }
    
    return 1;
  }

  sub test_equals_iarray : int () {
    my $nums1 = [(int)0, 1, INT32_MIN()];
    my $nums2 = [(int)0, 1, INT32_MIN()];
    my $nums3 = [(int)0, 1];
    my $nums4 = [(int)0, 1, 2];
    
    {
      my $is_equals = equals_iarray($nums1, $nums2);
      unless ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = equals_iarray($nums1, $nums3);
      if ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = equals_iarray($nums1, $nums4);
      if ($is_equals) {
        return 0;
      }
    }
    
    return 1;
  }

  sub test_equals_larray : int () {
    my $nums1 = [(long)0, 1, INT64_MIN()];
    my $nums2 = [(long)0, 1, INT64_MIN()];
    my $nums3 = [(long)0, 1];
    my $nums4 = [(long)0, 1, 2];
    
    {
      my $is_equals = equals_larray($nums1, $nums2);
      unless ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = equals_larray($nums1, $nums3);
      if ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = equals_larray($nums1, $nums4);
      if ($is_equals) {
        return 0;
      }
    }
    
    return 1;
  }

  sub test_equals_farray : int () {
    my $nums1 = [0.0f, 1.5f, FLT_MIN()];
    my $nums2 = [0.0f, 1.5f, FLT_MIN()];
    my $nums3 = [0.0f, 1.5f];
    my $nums4 = [(float)0.0f, 1.5f, 0.5f];
    
    {
      my $is_equals = equals_farray($nums1, $nums2);
      unless ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = equals_farray($nums1, $nums3);
      if ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = equals_farray($nums1, $nums4);
      if ($is_equals) {
        return 0;
      }
    }
    
    return 1;
  }

  sub test_equals_darray : int () {
    my $nums1 = [0.0, 1.5, DBL_MIN()];
    my $nums2 = [0.0, 1.5, DBL_MIN()];
    my $nums3 = [0.0, 1.5];
    my $nums4 = [(double)0.0, 1.5, 0.5];
    
    {
      my $is_equals = equals_darray($nums1, $nums2);
      unless ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = equals_darray($nums1, $nums3);
      if ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = equals_darray($nums1, $nums4);
      if ($is_equals) {
        return 0;
      }
    }
    
    return 1;
  }

  sub test_equals_oarray : int () {
    my $minimal1 = TestCase::Minimal->new;
    my $minimal2 = TestCase::Minimal->new;
    my $minimal3 = TestCase::Minimal->new;
    my $minimal4 = TestCase::Minimal->new;
    my $nums1 = [$minimal1, $minimal2, $minimal3];
    my $nums2 = [$minimal1, $minimal2, $minimal3];
    my $nums3 = [$minimal1, $minimal2];
    my $nums4 = [$minimal1, $minimal2, $minimal4];
    my $nums5 = [(object)$minimal1, $minimal2, $minimal3];
    
    {
      my $is_equals = equals_oarray($nums1, $nums2);
      unless ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = equals_oarray($nums1, $nums3);
      if ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = equals_oarray($nums1, $nums4);
      if ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = equals_oarray($nums1, $nums5);
      unless ($is_equals) {
        return 0;
      }
    }
    
    return 1;
  }


  sub test_equals_strarray : int () {
    my $strings1 = ["abc", "def", "ghi"];
    my $strings2 = ["abc", "def", "ghi"];
    my $strings3 = ["abc", "def"];
    my $strings4 = ["abc", "def", "xxx"];
    
    {
      my $is_equals = equals_strarray($strings1, $strings2);
      unless ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = equals_strarray($strings1, $strings3);
      if ($is_equals) {
        return 0;
      }
    }
    {
      my $is_equals = equals_strarray($strings1, $strings4);
      if ($is_equals) {
        return 0;
      }
    }
    
    return 1;
  }
  

  sub test_type_name : int () {
    my $minimal = TestCase::Minimal->new;
    my $type_name = type_name($minimal);
    
    unless ($type_name eq "TestCase::Minimal") {
      return 0;
    }
    
    return 1;
  }
  
  sub test_copy_str : int () {
    my $string = "abc";
    my $string_out = copy_str($string);
    
    unless ($string_out eq "abc") {
      return 0;
    }
    
    return 1;
  }

  sub test_copy_barray : int () {
    my $nums = [(byte)1, 2, INT8_MIN()];
    my $nums_out = copy_barray($nums);
    
    unless ($nums->[0] == 1) {
      return 0;
    }
    
    unless ($nums->[1] == 2) {
      return 0;
    }
    
    unless ($nums->[2] == INT8_MIN()) {
      return 0;
    }
    
    unless (@$nums_out == 3) {
      return 0;
    }
    
    return 1;
  }

  sub test_copy_sarray : int () {
    my $nums = [(short)1, 2, INT16_MIN()];
    my $nums_out = copy_sarray($nums);
    
    unless ($nums->[0] == 1) {
      return 0;
    }
    
    unless ($nums->[1] == 2) {
      return 0;
    }
    
    unless ($nums->[2] == INT16_MIN()) {
      return 0;
    }
    
    unless (@$nums_out == 3) {
      return 0;
    }
    
    return 1;
  }

  sub test_copy_iarray : int () {
    my $nums = [(int)1, 2, INT32_MIN()];
    my $nums_out = copy_iarray($nums);
    
    unless ($nums->[0] == 1) {
      return 0;
    }
    
    unless ($nums->[1] == 2) {
      return 0;
    }
    
    unless ($nums->[2] == INT32_MIN()) {
      return 0;
    }
    
    unless (@$nums_out == 3) {
      return 0;
    }
    
    return 1;
  }

  sub test_copy_larray : int () {
    my $nums = [(long)1, 2, INT64_MIN()];
    my $nums_out = copy_larray($nums);
    
    unless ($nums->[0] == 1) {
      return 0;
    }
    
    unless ($nums->[1] == 2) {
      return 0;
    }
    
    unless ($nums->[2] == INT64_MIN()) {
      return 0;
    }
    
    unless (@$nums_out == 3) {
      return 0;
    }
    
    return 1;
  }

  sub test_copy_farray : int () {
    my $nums = [(float)0.5f, 0.25f, FLT_MIN()];
    my $nums_out = copy_farray($nums);
    
    unless ($nums->[0] == 0.5) {
      return 0;
    }
    
    unless ($nums->[1] == 0.25) {
      return 0;
    }
    
    unless ($nums->[2] == FLT_MIN()) {
      return 0;
    }
    
    unless (@$nums_out == 3) {
      return 0;
    }
    
    return 1;
  }

  sub test_copy_darray : int () {
    my $nums = [(double)0.5, 0.25, DBL_MIN()];
    my $nums_out = copy_darray($nums);
    
    unless ($nums->[0] == 0.5) {
      return 0;
    }
    
    unless ($nums->[1] == 0.25) {
      return 0;
    }
    
    unless ($nums->[2] == DBL_MIN()) {
      return 0;
    }
    
    unless (@$nums_out == 3) {
      return 0;
    }
    
    return 1;
  }

  sub test_copy_oarray : int () {
    my $objects = [(object)SPVM::Int->new(1), SPVM::Int->new(2), SPVM::Int->new(INT32_MIN())];
    my $objects_out = copy_oarray($objects);

    unless ($objects->[0] == $objects_out->[0]) {
      return 0;
    }
    
    unless ($objects->[1] == $objects_out->[1]) {
      return 0;
    }
    
    unless ($objects->[2] == $objects_out->[2]) {
      return 0;
    }
    
    unless ((int)$objects->[0] == 1) {
      return 0;
    }
    
    unless ((int)$objects->[1] == 2) {
      return 0;
    }
    
    unless ((int)$objects->[2] == INT32_MIN()) {
      return 0;
    }
    
    unless (@$objects_out == 3) {
      return 0;
    }
    
    unless ($objects != $objects_out) {
      return 0;
    }
    
    return 1;
  }

  sub test_copy_strarray : int () {
    my $strings = ["abc", "def", "hij"];
    my $strings_out = copy_strarray($strings);
    
    unless ($strings->[0] eq $strings_out->[0]) {
      return 0;
    }
    
    unless ($strings->[1] == $strings_out->[1]) {
      return 0;
    }
    
    unless ($strings->[2] == $strings_out->[2]) {
      return 0;
    }
    
    unless (@$strings_out == 3) {
      return 0;
    }
    
    return 1;
  }
}
