package TestCase::MyExe {
  use UseAllTestCase;
  our $TEST_NUM : int;
  
  sub main : int ($argv : string[]) {
    # Exception
    {
      {
        ok(TestCase::Exception->exception_eval_call_sub());
      }
    }
    # sort
    {
      # sortb
      ok(TestCase::Lib::SPVM::Sort->test_sortb);

      # sorts
      ok(TestCase::Lib::SPVM::Sort->test_sorts);

      # sorti
      ok(TestCase::Lib::SPVM::Sort->test_sorti);

      # sortl
      ok(TestCase::Lib::SPVM::Sort->test_sortl);

      # sortf
      ok(TestCase::Lib::SPVM::Sort->test_sortf);

      # sortd
      ok(TestCase::Lib::SPVM::Sort->test_sortd);

      # sortd
      ok(TestCase::Lib::SPVM::Sort->test_sorto);
    }
    
    # join
    {
      ok(TestCase::Lib::SPVM::Util->test_join);
    }
    
    # Import sub
    {
      ok(TestCase::Sub->test_import_sub);
    }

    # Retrun value automatical numeric convertion
    {
      ok(TestCase::Sub->return_value_automatical_numeric_convertion);
    }
    # variable length arguments
    {
      ok(TestCase::Sub->vaarg_objects_pass_each_values);
      ok(TestCase::Sub->vaarg_objects_pass_array);
      ok(TestCase::Sub->vaarg_pass_each_values);
      ok(TestCase::Sub->vaarg_pass_array);
    }

    # Anon sub
    {
      ok(TestCase::Sub->cb_obj_capture);
      ok(TestCase::Sub->cb_obj_call_cb_obj);
      ok(TestCase::Sub->cb_obj_call_cb_obj_from_callback);
    }

    # Return value
    {
      ok(TestCase::Sub->return_value_byte);
      ok(TestCase::Sub->return_value_short);
      ok(TestCase::Sub->return_value_int);
      ok(TestCase::Sub->return_value_long);
      ok(TestCase::Sub->return_value_float);
      ok(TestCase::Sub->return_value_double);
    }

    {
      ok(TestCase::Sub->push_arg_undef());
    }

    # Call subroutine
    {
      ok(TestCase::Sub->call_sub_last_camma());
      ok(TestCase::Sub->call_sub_undef(undef));
    }

    # Call void subroutine
    {
      ok(TestCase::Sub->call_void());
    }

    # Default return value
    {
      ok(TestCase::Sub->default_return_value_byte());
      ok(TestCase::Sub->default_return_value_short());
      ok(TestCase::Sub->default_return_value_int());
      ok(TestCase::Sub->default_return_value_long());
      ok(TestCase::Sub->default_return_value_float());
      ok(TestCase::Sub->default_return_value_double());
      ok(TestCase::Sub->default_return_value_object());
    }

    {
      ok(TestCase::Sub->call_sub_nest());
    }

    # Argument convetion
    {
      ok(TestCase::Sub->call_sub_args_convertion());
    }

    # Fat camma
    {
      ok(TestCase::Array->array_init_fatcamma);
    }

    # Array
    {
      ok(TestCase::Array->array());
      ok(TestCase::Array->array_store_undef());
    }

    # Array length
    {
      ok(TestCase::Array->array_length_atmark());
      ok(TestCase::Array->array_length_atmark_brace());
      ok(TestCase::Array->array_length_scalar_atmark());
      ok(TestCase::Array->array_length_scalar_atmark_brace());
      ok(TestCase::Array->array_length_undef());
    }

    # Array initialization
    {
      ok(TestCase::Array->array_init_empty());
      ok(TestCase::Array->array_init_byte());
      ok(TestCase::Array->array_init_short());
      ok(TestCase::Array->array_init_int());
      ok(TestCase::Array->array_init_long());
      ok(TestCase::Array->array_init_float());
      ok(TestCase::Array->array_init_double());
      ok(TestCase::Array->array_init_object());
    }

    # Array default
    {
      ok(TestCase::Array->array_default_zero_memory_pool());
      ok(TestCase::Array->array_default_zero_not_memory_pool());
    }

    # package variable access
    {
      ok(TestCase::NativeAPI->set_package_var_byte);
      ok(TestCase::NativeAPI->set_package_var_short);
      ok(TestCase::NativeAPI->set_package_var_int);
      ok(TestCase::NativeAPI->set_package_var_long);
      ok(TestCase::NativeAPI->set_package_var_float);
      ok(TestCase::NativeAPI->set_package_var_double);
      ok(TestCase::NativeAPI->set_package_var_object);
      ok(TestCase::NativeAPI->get_package_var_byte);
      ok(TestCase::NativeAPI->get_package_var_short);
      ok(TestCase::NativeAPI->get_package_var_int);
      ok(TestCase::NativeAPI->get_package_var_long);
      ok(TestCase::NativeAPI->get_package_var_float);
      ok(TestCase::NativeAPI->get_package_var_double);
      ok(TestCase::NativeAPI->get_package_var_object);
    }

    # has_callback
    {
      ok(TestCase::NativeAPI->has_callback);
    }

    # is_type
    {
      ok(TestCase::NativeAPI->is_type);
    }

    # Native Exception
    {
      ok(TestCase::NativeAPI->native_use_strlen_test);
      ok(TestCase::NativeAPI->call_void_sub_exception);
    }

    # Check mortal API
    {
      ok(TestCase::NativeAPI->mortal_api);
      ok(TestCase::NativeAPI->enter_scope_leave_scope);
    }

    # env->call_sub
    {
      ok(TestCase::NativeAPI->native_call_sub);
    }

    # Field
    {
      ok(TestCase::NativeAPI->get_field_byte());
      ok(TestCase::NativeAPI->get_field_short());
      ok(TestCase::NativeAPI->get_field_int());
      ok(TestCase::NativeAPI->get_field_long());
      ok(TestCase::NativeAPI->get_field_float());
      ok(TestCase::NativeAPI->get_field_double());
      ok(TestCase::NativeAPI->get_field_object());

      ok(TestCase::NativeAPI->set_field_byte());
      ok(TestCase::NativeAPI->set_field_short());
      ok(TestCase::NativeAPI->set_field_int());
      ok(TestCase::NativeAPI->set_field_long());
      ok(TestCase::NativeAPI->set_field_float());
      ok(TestCase::NativeAPI->set_field_double());
      ok(TestCase::NativeAPI->set_field_object());

    }

    # Ref
    {
      ok(TestCase::NativeAPI->ref_byte());
      ok(TestCase::NativeAPI->ref_short());
      ok(TestCase::NativeAPI->ref_int());
      ok(TestCase::NativeAPI->ref_long());
      ok(TestCase::NativeAPI->ref_float());
      ok(TestCase::NativeAPI->ref_double());
    }

    # Native Exception
    {
      ok(TestCase::NativeAPI2->spvm_extension2());
    }

    # Pointer
    {
      ok(TestCase::Pointer->struct_test());
    }

    # Various Tests
    {
      ok(TestCase::Callback->basic());
      ok(TestCase::Callback->comparator());
      ok(TestCase::Object->object_field_set_and_get);
    }
    
    # use TestCase::Minimal
    {
      my $minimal = TestCase::Minimal->new;
      $minimal->{x} = 10;

      my $ok = 0;
      if ($minimal->{x} == 10) {
        $ok = 1;
      }
      ok($ok);
    }
    
    # use TestCase
    {
      my $ret = TestCase->my_exe_test(10);
      my $ok = 0;
      if ($ret == 20) {
        $ok = 1;
      }
      ok($ok);
    }
    
    # precompile sub
    {
      my $ret = precompile_sub(3);
      my $ok = 0;
      if ($ret == 9) {
        $ok = 1;
      }
      ok($ok);
    }
    
    # Finish test
    print "1.." . (string)$TEST_NUM . "\n";
    
    return 0;
  }
  
  sub ok : void ($ok : int) {
    $TEST_NUM++;

    if ($ok) {
      print "ok ";
    }
    else {
      print "not ok ";
    }
    print((string)$TEST_NUM . "\n");
  }
  
  precompile sub precompile_sub : int ($num : int) {
    
    return $num * 3;
  }
}
