#include #include #include #include #include static void destroy_empty_constraint(Constraint *constraint); static int compare_want(Constraint *constraint, intptr_t actual); static void test_want(Constraint *constraint, const char *function, intptr_t actual, const char *test_file, int test_line, TestReporter *reporter); static int compare_non_null(Constraint *constraint, intptr_t actual); static void test_non_null(Constraint *constraint, const char *function, intptr_t actual, const char *test_file, int test_line, TestReporter *reporter); static int compare_want_string(Constraint *constraint, intptr_t actual); static void test_want_string(Constraint *constraint, const char *function, intptr_t actual, const char *test_file, int test_line, TestReporter *reporter); static int compare_want_double(Constraint *constraint, intptr_t actual); static void test_want_double(Constraint *constraint, const char *function, intptr_t actual, const char *test_file, int test_line, TestReporter *reporter); static Constraint *create_constraint(const char *parameter); static void destroy_double_constraint(Constraint *constraint); static double unbox_double(intptr_t box); static double as_double(intptr_t box); static int compare_using_matcher(Constraint *constraint, intptr_t actual); static void test_with_matcher(Constraint *constraint, const char *function, const char* matcher_name, intptr_t actual, const char *test_file, int test_line, TestReporter *reporter); void destroy_constraint(void *abstract) { Constraint *constraint = (Constraint *)abstract; (*constraint->destroy)(constraint); } int is_constraint_parameter(Constraint *constraint, const char *parameter) { return strcmp(constraint->parameter, parameter) == 0; } void test_constraint(Constraint *constraint, const char *function, intptr_t actual, const char *test_file, int test_line, TestReporter *reporter) { (*constraint->test)(constraint, function, actual, test_file, test_line, reporter); } Constraint *want_(const char *parameter, intptr_t expected) { Constraint *constraint = create_constraint(parameter); constraint->parameter = parameter; constraint->compare = &compare_want; constraint->test = &test_want; constraint->expected = expected; return constraint; } Constraint *want_non_null_(const char *parameter) { Constraint *constraint = create_constraint(parameter); constraint->parameter = parameter; constraint->compare = &compare_non_null; constraint->test = &test_non_null; return constraint; } Constraint *want_string_(const char *parameter, char *expected) { Constraint *constraint = create_constraint(parameter); constraint->parameter = parameter; constraint->compare = &compare_want_string; constraint->test = &test_want_string; constraint->expected = (intptr_t)expected; return constraint; } static int compare_non_null(Constraint *constraint, intptr_t actual) { return (NULL != (void*)actual); } static void test_non_null(Constraint *constraint, const char *function, intptr_t actual, const char *test_file, int test_line, TestReporter *reporter) { (*reporter->assert_true)( reporter, test_file, test_line, (*constraint->compare)(constraint, actual), "Wanted non-null, but got null in function [%s] parameter [%s]", function, constraint->parameter); } Constraint *want_double_(const char *parameter, intptr_t expected) { Constraint *constraint = malloc(sizeof(Constraint)); constraint->parameter = parameter; constraint->destroy = &destroy_double_constraint; constraint->compare = &compare_want_double; constraint->test = &test_want_double; constraint->expected = expected; return constraint; } intptr_t box_double(double d) { BoxedDouble *box = malloc(sizeof(BoxedDouble)); box->d = d; return (intptr_t)box; } Constraint *with_(const char *parameter, const char* matcher_name, int (*matcher_function)(const void*)) { Constraint *constraint = create_constraint(parameter); constraint->parameter = parameter; constraint->compare = &compare_using_matcher; constraint->test = &test_with_matcher; constraint->name = matcher_name; constraint->expected = (intptr_t)matcher_function; return constraint; } static void destroy_empty_constraint(Constraint *constraint) { free(constraint); } static int compare_want(Constraint *constraint, intptr_t actual) { return (constraint->expected == actual); } static void test_want(Constraint *constraint, const char *function, intptr_t actual, const char *test_file, int test_line, TestReporter *reporter) { (*reporter->assert_true)( reporter, test_file, test_line, (*constraint->compare)(constraint, actual), "Wanted [%d], but got [%d] in function [%s] parameter [%s]", constraint->expected, actual, function, constraint->parameter); } static int compare_want_string(Constraint *constraint, intptr_t actual) { return strings_are_equal((const char *)constraint->expected, (const char *)actual); } static void test_want_string(Constraint *constraint, const char *function, intptr_t actual, const char *test_file, int test_line, TestReporter *reporter) { (*reporter->assert_true)( reporter, test_file, test_line, (*constraint->compare)(constraint, actual), "Wanted [%s], but got [%s] in function [%s] parameter [%s]", show_null_as_the_string_null((const char *)constraint->expected), show_null_as_the_string_null((const char *)actual), function, constraint->parameter); } static int compare_want_double(Constraint *constraint, intptr_t actual) { return doubles_are_equal(as_double(constraint->expected), as_double(actual)); } static void test_want_double(Constraint *constraint, const char *function, intptr_t actual, const char *test_file, int test_line, TestReporter *reporter) { (*reporter->assert_true)( reporter, test_file, test_line, (*constraint->compare)(constraint, actual), "Wanted [%d], but got [%d] in function [%s] parameter [%s]", as_double(constraint->expected), as_double(actual), function, constraint->parameter); unbox_double(actual); } static int compare_using_matcher(Constraint *constraint, intptr_t actual) { int (*matches)(const void*) = (void *)(intptr_t)constraint->expected; return matches((void *)actual); } static void test_with_matcher(Constraint *constraint, const char *function, const char* matcher_name, intptr_t matcher_function, const char *test_file, int test_line, TestReporter *reporter) { (*reporter->assert_true)( reporter, test_file, test_line, (*constraint->compare)(constraint, matcher_function), "Wanted parameter [%s] to match [%s] in function [%s]", constraint->parameter, matcher_name, function); } static Constraint *create_constraint(const char *parameter) { Constraint *constraint = malloc(sizeof(Constraint)); constraint->parameter = parameter; constraint->destroy = &destroy_empty_constraint; return constraint; } static void destroy_double_constraint(Constraint *constraint) { unbox_double(constraint->expected); destroy_empty_constraint(constraint); } static double unbox_double(intptr_t box) { double d = as_double(box); free((BoxedDouble *)box); return d; } static double as_double(intptr_t box) { return ((BoxedDouble *)box)->d; } /* vim: set ts=4 sw=4 et cindent: */