/** * @file value_compare.c * @brief Tests the comparison operators across integer, float and string. */ #include #include #include #include "testutil.h" static akbasic_Value A; static akbasic_Value B; static akbasic_Value SCRATCH; static void set_int(akbasic_Value *v, int64_t n) { test_discard_error(akbasic_value_zero(v)); v->valuetype = AKBASIC_TYPE_INTEGER; v->intval = n; } static void set_float(akbasic_Value *v, double n) { test_discard_error(akbasic_value_zero(v)); v->valuetype = AKBASIC_TYPE_FLOAT; v->floatval = n; } static void set_string(akbasic_Value *v, const char *s) { test_discard_error(akbasic_value_zero(v)); v->valuetype = AKBASIC_TYPE_STRING; strncpy(v->stringval, s, AKBASIC_MAX_STRING_LENGTH - 1); } #define EXPECT_BOOL(__call, __want) \ do { \ akbasic_Value *__out = NULL; \ TEST_REQUIRE_OK(__call(&A, &B, &SCRATCH, &__out)); \ TEST_REQUIRE(__out->valuetype == AKBASIC_TYPE_BOOLEAN, \ #__call " did not produce a boolean"); \ TEST_REQUIRE(akbasic_value_is_true(__out) == (__want), \ #__call " expected %s", ((__want) ? "true" : "false")); \ TEST_REQUIRE_INT(__out->boolvalue, ((__want) ? AKBASIC_TRUE : AKBASIC_FALSE)); \ } while ( 0 ) int main(void) { akbasic_Value *out = NULL; TEST_REQUIRE_OK(akbasic_error_register()); /* Integers. */ set_int(&A, 3); set_int(&B, 5); EXPECT_BOOL(akbasic_value_less_than, true); EXPECT_BOOL(akbasic_value_less_than_equal, true); EXPECT_BOOL(akbasic_value_greater_than, false); EXPECT_BOOL(akbasic_value_greater_than_equal, false); EXPECT_BOOL(akbasic_value_is_equal, false); EXPECT_BOOL(akbasic_value_is_not_equal, true); set_int(&B, 3); EXPECT_BOOL(akbasic_value_less_than, false); EXPECT_BOOL(akbasic_value_less_than_equal, true); EXPECT_BOOL(akbasic_value_greater_than_equal, true); EXPECT_BOOL(akbasic_value_is_equal, true); /* Floats. */ set_float(&A, 1.5); set_float(&B, 2.5); EXPECT_BOOL(akbasic_value_less_than, true); EXPECT_BOOL(akbasic_value_greater_than, false); /* Strings compare lexically. */ set_string(&A, "APPLE"); set_string(&B, "BANANA"); EXPECT_BOOL(akbasic_value_less_than, true); EXPECT_BOOL(akbasic_value_greater_than, false); EXPECT_BOOL(akbasic_value_is_equal, false); set_string(&B, "APPLE"); EXPECT_BOOL(akbasic_value_is_equal, true); EXPECT_BOOL(akbasic_value_less_than_equal, true); EXPECT_BOOL(akbasic_value_greater_than_equal, true); /* BASIC true is -1, not 1: the Commodore convention the README calls out. */ set_int(&A, 1); set_int(&B, 1); TEST_REQUIRE_OK(akbasic_value_is_equal(&A, &B, &SCRATCH, &out)); TEST_REQUIRE_INT(out->boolvalue, -1); /* is_true is false for anything that is not a boolean. */ set_int(&A, -1); TEST_REQUIRE(!akbasic_value_is_true(&A), "an integer -1 is not a BASIC true"); TEST_REQUIRE(!akbasic_value_is_true(NULL), "NULL is not true"); TEST_REQUIRE_STATUS(akbasic_value_is_equal(&A, NULL, &SCRATCH, &out), AKERR_NULLPOINTER); return akbasic_test_failures; }