/* * Tests for basic type system * (C) 2006, Pascal Schmidt * see file ../doc/LICENSE for license */ #include #include #include "test.h" #include "../libruntime/runtime.h" static value *dummy(arena_state *s, unsigned int argc, value **argv) { return (value *) (argc + (int) argv); } void value_test(void) { value *val, *val2, *elem, *elem2; int i, j, res, buf; signature *sig; sig = call_sig_builtin("dummy", 0, "", dummy); test_banner("libruntime"); /* * Section: allocation of values */ test_section("value allocators"); /* * Basics */ test_start("value_alloc"); val = value_alloc(VALUE_TYPE_VOID); test_assert(val != NULL && val->type == VALUE_TYPE_VOID); test_start("value_free"); value_free(val); test_assert(1); test_start("value_free (null)"); value_free(NULL); test_assert(1); /* * Construction of fixed values */ test_start("value_make_void"); val = value_make_void(); test_assert(val != NULL && val->type == VALUE_TYPE_VOID); value_free(val); test_start("value_make_bool (false)"); val = value_make_bool(0); test_assert(val != NULL && val->type == VALUE_TYPE_BOOL && val->value_u.bool_val == 0); value_free(val); test_start("value_make_bool (true)"); val = value_make_bool(42); test_assert(val != NULL && val->type == VALUE_TYPE_BOOL && val->value_u.bool_val == 1); value_free(val); test_start("value_make_int (-42)"); val = value_make_int(-42); test_assert(val != NULL && val->type == VALUE_TYPE_INT && val->value_u.int_val == -42); value_free(val); test_start("value_make_float (4.2)"); val = value_make_float(4.2); test_assert(val != NULL && val->type == VALUE_TYPE_FLOAT && val->value_u.float_val == 4.2); value_free(val); test_start("value_make_string (\"42\")"); val = value_make_string("42"); test_assert(val != NULL && val->type == VALUE_TYPE_STRING && val->value_u.string_val.len == 2 && strcmp(val->value_u.string_val.value, "42") == 0); value_free(val); test_start("value_make_array"); val = value_make_array(); test_assert(val != NULL && val->type == VALUE_TYPE_ARRAY && val->value_u.array_val.len == 0 && val->value_u.array_val.value == NULL); value_free(val); test_start("value_make_struct"); val = value_make_struct(); test_assert(val != NULL && val->type == VALUE_TYPE_STRUCT && val->value_u.struct_val != NULL); value_free(val); test_start("value_make_fn"); val = value_make_fn(sig); test_assert(val != NULL && val->type == VALUE_TYPE_FN); value_free(val); /* * Section: array functions */ test_section("value arrays"); test_start("value_add_to_array (42000 elements)"); val = value_make_array(); for (i = 0; i < 42000; i++) { elem = value_make_int(i); value_add_to_array(val, elem); value_free(elem); } test_assert(val != NULL && val->type == VALUE_TYPE_ARRAY && val->value_u.array_val.len == 42000); test_start("value_get_array (42000 elements)"); res = 0; for (i = 0; i < 42000; i++) { elem = value_get_array(val, i); if (!elem || elem->type != VALUE_TYPE_INT || elem->value_u.int_val != i) { res++; } value_free(elem); } test_assert(res == 0); test_start("value_set_array (84000 elements)"); for (i = 0; i < 84000; i++) { elem = value_make_int(i * (-42)); value_set_array(val, i, elem); value_free(elem); } test_assert(val != NULL && val->type == VALUE_TYPE_ARRAY && val->value_u.array_val.len == 84000); test_start("value_get_array (84000 elements)"); res = 0; for (i = 0; i < 84000; i++) { elem = value_get_array(val, i); if (!elem || elem->type != VALUE_TYPE_INT || elem->value_u.int_val != i * (-42)) { res++; } value_free(elem); } test_assert(res == 0); test_start("value_set_array (autofill)"); elem = value_make_int(100000); value_set_array(val, 100000, elem); value_free(elem); elem = value_get_array(val, 100000); buf = 0; for (i = 84000; i < 100000; i++) { elem2 = value_get_array(val, i); if (!elem2 || !elem2->type == VALUE_TYPE_VOID) buf++; value_free(elem2); } test_assert(buf == 0 && elem->type == VALUE_TYPE_INT && elem->value_u.int_val == 100000 && val->value_u.array_val.len == 100001); value_free(elem); test_start("value_get_array (out of bounds)"); elem = value_get_array(val, 200000); test_assert(elem && elem->type == VALUE_TYPE_VOID); value_free(elem); test_start("value_delete_array (42000 elements)"); for (i = 0; i < 42000; i++) { value_delete_array(val, i); } buf = 0; for (i = 0; i < 84000; i++) { elem = value_get_array(val, i); if (i < 42000) { if (!elem || elem->type != VALUE_TYPE_VOID) buf++; } else { if (!elem || elem->type != VALUE_TYPE_INT || elem->value_u.int_val != i * (-42)) buf++; } value_free(elem); } test_assert(buf == 0); /* * Section: copying of values */ test_section("value copy"); test_start("value_copy (int)"); elem = value_make_int(4200); elem2 = value_copy(elem); test_assert(elem && elem2 && elem2->type == VALUE_TYPE_INT && elem2->value_u.int_val == 4200); value_free(elem); value_free(elem2); test_start("value_copy (string)"); elem = value_make_string("foo"); elem2 = value_copy(elem); test_assert(elem && elem2 && elem2->type == VALUE_TYPE_STRING && elem2->value_u.string_val.len == 3 && elem2->value_u.string_val.value && strcmp(elem2->value_u.string_val.value, "foo") == 0); value_free(elem); value_free(elem2); test_start("value_copy (large array)"); elem2 = value_copy(val); /* large array from above */ res = 0; for (i = 0; i < 84000; i++) { elem = value_get_array(elem2, i); if (i < 42000) { if (!elem || elem->type != VALUE_TYPE_VOID) res++; } else { if (!elem || elem->type != VALUE_TYPE_INT || elem->value_u.int_val != i * (-42)) { res++; } } value_free(elem); } test_assert(elem2 && elem2->type == VALUE_TYPE_ARRAY && elem2->value_u.array_val.len == val->value_u.array_val.len && res == 0); /* * Freeing */ test_start("value_free (large arrays)"); value_free(val); value_free(elem2); test_assert(1); /* * Section: nested arrays */ test_section("nested value arrays"); test_start("value_add_to_array (nested arrays)"); val = value_make_array(); for (i = 0; i < 100; i++) { elem = value_make_array(); for (j = 0; j < i; j++) { elem2 = value_make_int(j); value_add_to_array(elem, elem2); value_free(elem2); } value_add_to_array(val, elem); value_free(elem); } test_assert(1); test_start("value_get_array (nested arrays)"); res = 0; for (i = 0; i < 100; i++) { elem = value_get_array(val, i); if (!elem || elem->type != VALUE_TYPE_ARRAY || elem->value_u.array_val.len != i) { res++; } else { for (j = 0; j < i; j++) { elem2 = value_get_array(elem, j); if (!elem2 || elem2->type != VALUE_TYPE_INT || elem2->value_u.int_val != j) res++; value_free(elem2); } } value_free(elem); } test_assert(res == 0); test_start("value_copy (nested arrays)"); val2 = value_copy(val); res = 0; for (i = 0; i < 100; i++) { elem = value_get_array(val2, i); if (!elem || elem->type != VALUE_TYPE_ARRAY || elem->value_u.array_val.len != i) { res++; } else { for (j = 0; j < i; j++) { elem2 = value_get_array(elem, j); if (!elem2 || elem2->type != VALUE_TYPE_INT || elem2->value_u.int_val != j) res++; value_free(elem2); } } value_free(elem); } test_assert(res == 0 && val2); test_start("value_free (nested arrays)"); value_free(val); value_free(val2); test_assert(1); }