You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1177 lines
34 KiB
1177 lines
34 KiB
|
|
|
|
// *** TODO *** |
|
// Consider "Arrange, Act, Assert" structure. |
|
// - So far this looks pretty nice. Encourages a structure I like. |
|
// - I will probably define some macros to generate the boilerplate code that |
|
// will be repeated over and over. |
|
// |
|
// Handle segfaults as ordinary test failures. |
|
// - See https://stackoverflow.com/questions/10202941/segmentation-fault-handling |
|
// - Would be a great way to allow more tests to run after a test has crashed. |
|
|
|
|
|
|
|
|
|
#include <stddef.h> |
|
#include <assert.h> |
|
|
|
#define RDIC_IMPLEMENTATION |
|
#include "../rdic.h" |
|
|
|
typedef struct GUI_Node { |
|
// NOTE(Zelaven): This codebase assumes rn is the first member for subtyping. |
|
RDIC_Node rn; |
|
char *debug_name; |
|
} GUI_Node; |
|
|
|
|
|
|
|
// --- ARRANGE HELPERS --- |
|
|
|
#define ARRAYLENGTH(X) (sizeof(X)/sizeof((X)[0])) |
|
|
|
void init_node_freelist(GUI_Node *nodes, int node_count) |
|
{ |
|
// NOTE(Zelaven): We special-case the last node. |
|
for(int i = 0; i < node_count -1; i++) |
|
{ |
|
nodes[i].rn = (RDIC_Node){ |
|
.sibling = &((nodes+i+1)->rn), |
|
}; |
|
nodes[i].debug_name = NULL; |
|
} |
|
nodes[node_count-1].rn = (RDIC_Node){0}; |
|
} |
|
|
|
#define ARRANGE_DEFAULT_CONFIGURATION(FREELIST_LENGTH)\ |
|
RDIC_Context context = {0};\ |
|
GUI_Node freelist_nodes[FREELIST_LENGTH] = {0};\ |
|
init_node_freelist(freelist_nodes, ARRAYLENGTH(freelist_nodes));\ |
|
RDIC_Freelist freelist = {&freelist_nodes[0].rn};\ |
|
context.freelist = &freelist;\ |
|
RDIC_Node_Reference root = {0}; |
|
|
|
|
|
RDIC_Node_Reference test_get_node( |
|
RDIC_Context *context, |
|
RDIC_Node_Reference reference, |
|
char *name) |
|
{ |
|
RDIC_Node_Reference new_ref = rdic_get_node(context, reference, NULL); |
|
if(new_ref.node != NULL) |
|
{ |
|
((GUI_Node*)new_ref.node)->debug_name = name; |
|
} |
|
return new_ref; |
|
} |
|
#define GET_NODE(context, ref) test_get_node(context, ref, #ref); |
|
|
|
#define SET_DEBUG_NAME(REF, NAME) ((GUI_Node*)(REF).node)->debug_name = (NAME) |
|
|
|
|
|
|
|
// --- ASSERT HELPERS --- |
|
// NOTE(Zelaven): Helpers can be buggy too and could in principle have tests. |
|
int freelist_contains(RDIC_Context *context, RDIC_Node *node) |
|
{ |
|
RDIC_Node *current = context->freelist->head; |
|
int result = 0; |
|
while(!result && current != NULL) |
|
{ |
|
if(current == node) {result = 1;} |
|
current = current->sibling; |
|
} |
|
return result; |
|
} |
|
|
|
#define ASSERT_REFERENCE_VALID(REF)\ |
|
if((REF).node == NULL)\ |
|
{TEST_ERROR("`" #REF "` is invalid: node is NULL.");}\ |
|
else if((REF).generation != (REF).node->generation)\ |
|
{TEST_ERROR("`" #REF "` is invalid: generation differs.");} |
|
// TODO(Zelaven): create TEST_ERROR_FMT and use it here. |
|
//{TEST_ERROR("`" #REF "` is invalid: generation differs (" #REF ": %d, node: %d).");} |
|
#define ASSERT_REFERENCE_INVALID(REF, TEXT...)\ |
|
if(((REF).node != NULL) && ((REF).generation == (REF).node->generation))\ |
|
{TEST_ERROR("`" #REF "` is valid when it should be invalid. "TEXT);} |
|
|
|
#define ASSERT_PARENT_OF(PARENT, CHILD)\ |
|
if((CHILD).node->parent != (PARENT).node)\ |
|
{TEST_ERROR("parent of `" #CHILD "` is not `" #PARENT "`.");} |
|
#define ASSERT_SIBLING_OF(SIBLING, NODE)\ |
|
if((NODE).node->sibling != (SIBLING).node)\ |
|
{TEST_ERROR("sibling of `" #NODE "` is not `" #SIBLING "`.");} |
|
#define ASSERT_NO_SIBLING(NODE)\ |
|
if((NODE).node->sibling != NULL)\ |
|
{TEST_ERROR("`" #NODE "` has a sibling when it should not.");} |
|
#define ASSERT_FRISTCHILD_OF(FIRSTCHILD, PARENT)\ |
|
if((PARENT).node->first_child != (FIRSTCHILD).node)\ |
|
{TEST_ERROR("first_child of `" #PARENT "` is not `" #FIRSTCHILD "`.");} |
|
|
|
#define ASSERT_IN_FREELIST(CONTEXT, NODE)\ |
|
if(!freelist_contains(CONTEXT, NODE.node))\ |
|
{TEST_ERROR("`"#NODE"` not in freelist.");} |
|
|
|
|
|
|
|
// --- TEST INFRASTRUCTURE --- |
|
|
|
// TODO(Zelaven): Should probably make a separate arena for strings generated by running the tests. |
|
#include "memory_arena.c" |
|
#include "memory_arena_linux.c" |
|
|
|
typedef struct Report_Test_Result |
|
{ |
|
enum { |
|
TESTRESULT_UNDEFINED = 0, |
|
TESTRESULT_SUCCESS, |
|
TESTRESULT_ERROR, |
|
TESTRESULT_NUM_LEVELS, |
|
} level; |
|
const char *test_name; |
|
char *string; |
|
} Report_Test_Result; |
|
typedef struct Report_Group Report_Group; |
|
struct Report_Group { |
|
char *name; |
|
Report_Group *next; |
|
unsigned int num_test_results; |
|
Report_Test_Result results[]; |
|
}; |
|
|
|
Memory_Arena g_test_report_arena; |
|
unsigned int _g_test_report_num_test_results = 0; |
|
Report_Group *g_first_report_group = NULL; |
|
Report_Group *g_current_report_group = NULL; |
|
int g_error_occurred = 0; |
|
|
|
#define arena_allocate_TYPE(arena, TYPE) ((TYPE*)memory_arena_allocate(arena, sizeof(TYPE), _Alignof(TYPE))) |
|
#define arena_allocate_report_group(arena) arena_allocate_TYPE(arena, Report_Group) |
|
#define arena_allocate_report_test_result(arena) arena_allocate_TYPE(arena, Report_Test_Result) |
|
|
|
static inline void log_new_report_group(char *name) |
|
{ |
|
Report_Group *new_group = arena_allocate_report_group(&g_test_report_arena); |
|
if(g_current_report_group == NULL) |
|
{ |
|
g_first_report_group = new_group; |
|
} |
|
else |
|
{ |
|
g_current_report_group->next = new_group; |
|
} |
|
g_current_report_group = new_group; |
|
|
|
*new_group = (Report_Group){ |
|
.name = name, |
|
}; |
|
} |
|
|
|
static inline void log_result_to_report( |
|
Report_Test_Result result) |
|
{ |
|
// This is allocated in extension of the results[] member of a Report_Group. |
|
*arena_allocate_report_test_result(&g_test_report_arena) = result; |
|
//g_test_report_num_test_results += 1; |
|
g_current_report_group->num_test_results += 1; |
|
} |
|
|
|
char *g_test_name; |
|
|
|
#define TEST_ERROR(STRING) \ |
|
g_error_occurred = 1;\ |
|
log_result_to_report((Report_Test_Result){\ |
|
.level = TESTRESULT_ERROR,\ |
|
.test_name = g_test_name,\ |
|
.string = STRING,\ |
|
}) |
|
|
|
|
|
// --- TESTS --- |
|
|
|
|
|
void test__start_frame__empty_freelist(void) |
|
{ |
|
// Arrange. |
|
RDIC_Context context = {0}; |
|
RDIC_Node_Reference root = {0}; |
|
|
|
// Act. |
|
root = rdic_context_start_frame( |
|
&context, |
|
root); |
|
|
|
// Assert. |
|
ASSERT_REFERENCE_INVALID(root, "(Empty freelist)"); |
|
} |
|
|
|
void test__start_frame__succeed(void) |
|
{ |
|
// Arrange. |
|
RDIC_Context context = {0}; |
|
GUI_Node freelist_nodes[1] = {0}; |
|
init_node_freelist(freelist_nodes, ARRAYLENGTH(freelist_nodes)); |
|
RDIC_Freelist freelist = {&freelist_nodes[0].rn}; |
|
context.freelist = &freelist; |
|
RDIC_Node_Reference root = {0}; |
|
|
|
// Act. |
|
root = rdic_context_start_frame( |
|
&context, |
|
root); |
|
|
|
// Assert. |
|
ASSERT_REFERENCE_VALID(root); |
|
} |
|
|
|
void test__finish_frame__succeed(void) |
|
{ |
|
// Arrange. |
|
RDIC_Context context = {0}; |
|
GUI_Node freelist_nodes[1] = {0}; |
|
init_node_freelist(freelist_nodes, ARRAYLENGTH(freelist_nodes)); |
|
RDIC_Freelist freelist = {&freelist_nodes[0].rn}; |
|
context.freelist = &freelist; |
|
RDIC_Node_Reference root = {0}; |
|
root = rdic_context_start_frame( |
|
&context, |
|
root); |
|
|
|
// Act. |
|
rdic_context_finish_frame(&context); |
|
|
|
// Assert. |
|
// No asserts. If it doesn't crash then we're good for now. |
|
// In the future we will want to assert on the structure of the node tree. |
|
} |
|
|
|
|
|
// --- |
|
|
|
|
|
void test__get_node_with_empty_freelist__return_null_reference(void) |
|
{ |
|
// Arrange. |
|
RDIC_Context context = {0}; |
|
GUI_Node freelist_nodes[1] = {0}; |
|
init_node_freelist(freelist_nodes, ARRAYLENGTH(freelist_nodes)); |
|
RDIC_Freelist freelist = {&freelist_nodes[0].rn}; |
|
context.freelist = &freelist; |
|
RDIC_Node_Reference root = {0}; |
|
root = rdic_context_start_frame( |
|
&context, |
|
root); |
|
|
|
// Act. |
|
RDIC_Node_Reference node = {0}; // Invalid reference -> new node. |
|
node = GET_NODE(&context, node); |
|
|
|
// Assert. |
|
// NOTE(Zelaven): We specifically assert that the reference is all 0. |
|
if(context.freelist->head != NULL) |
|
{TEST_ERROR("Freelist not empty.");} |
|
if(node.node != NULL) |
|
{TEST_ERROR("Non-NULL node despite empty freelist.");} |
|
if(node.generation != 0) |
|
{TEST_ERROR("Non-0 generation despite empty freelist.");} |
|
} |
|
|
|
void test__get_node_with_empty_freelist_with_nonzero_generation__return_null_reference(void) |
|
{ |
|
// Arrange. |
|
RDIC_Context context = {0}; |
|
GUI_Node freelist_nodes[1] = {0}; |
|
init_node_freelist(freelist_nodes, ARRAYLENGTH(freelist_nodes)); |
|
RDIC_Freelist freelist = {&freelist_nodes[0].rn}; |
|
context.freelist = &freelist; |
|
RDIC_Node_Reference root = {0}; |
|
root = rdic_context_start_frame( |
|
&context, |
|
root); |
|
|
|
// Act. |
|
RDIC_Node_Reference node = {0}; // Invalid reference -> new node. |
|
node.generation = 42; // Should become 0. |
|
node = GET_NODE(&context, node); |
|
|
|
// Assert. |
|
// NOTE(Zelaven): We specifically assert that the reference is all 0. |
|
if(node.node != NULL) |
|
{TEST_ERROR("Non-NULL node despite empty freelist.");} |
|
if(node.generation != 0) |
|
{TEST_ERROR("Non-0 generation despite empty freelist.");} |
|
} |
|
|
|
void test__get_node__succeed(void) |
|
{ |
|
// Arrange. |
|
RDIC_Context context = {0}; |
|
GUI_Node freelist_nodes[2] = {0}; |
|
init_node_freelist(freelist_nodes, ARRAYLENGTH(freelist_nodes)); |
|
RDIC_Freelist freelist = {&freelist_nodes[0].rn}; |
|
context.freelist = &freelist; |
|
RDIC_Node_Reference root = {0}; |
|
root = rdic_context_start_frame( |
|
&context, |
|
root); |
|
|
|
// Act. |
|
RDIC_Node_Reference node = {0}; // Invalid reference -> new node. |
|
node = GET_NODE(&context, node); |
|
|
|
// Assert. |
|
ASSERT_REFERENCE_VALID(node); |
|
// NOTE(Zelaven): We want to assert this to make sure we are counting from 0. |
|
// If not then we may be incrementing on the allocation of the node, which is |
|
// incorrect. We increment (invalidate) the generation on de-allocation. |
|
if(node.generation != 0) |
|
{TEST_ERROR("Non-0 generation for first allocation of node from freelist.");} |
|
} |
|
|
|
void test__get_node_finish_frame__succeed(void) |
|
{ |
|
// Arrange. |
|
RDIC_Context context = {0}; |
|
GUI_Node freelist_nodes[2] = {0}; |
|
init_node_freelist(freelist_nodes, ARRAYLENGTH(freelist_nodes)); |
|
RDIC_Freelist freelist = {&freelist_nodes[0].rn}; |
|
context.freelist = &freelist; |
|
RDIC_Node_Reference root = {0}; |
|
root = rdic_context_start_frame( |
|
&context, |
|
root); |
|
|
|
// Act. |
|
RDIC_Node_Reference node = {0}; // Invalid reference -> new node. |
|
node = GET_NODE(&context, node); |
|
|
|
rdic_context_finish_frame(&context); |
|
|
|
// Assert. |
|
} |
|
|
|
void test__single_node__returned_to_freelist(void) |
|
{ |
|
// Arrange. |
|
ARRANGE_DEFAULT_CONFIGURATION(2); |
|
RDIC_Node_Reference node = {0}; |
|
|
|
// Act. |
|
// First frame. |
|
root = rdic_context_start_frame( |
|
&context, |
|
root); |
|
// Invalid reference -> new node. |
|
node = GET_NODE(&context, node); |
|
rdic_context_finish_frame(&context); |
|
// Second frame. |
|
// node should return to freelist. |
|
root = rdic_context_start_frame( |
|
&context, |
|
root); |
|
// No call to get_node for node. |
|
rdic_context_finish_frame(&context); |
|
|
|
// Assert. |
|
// Firstly, we know that the release of the node should increment its |
|
// generation. |
|
// We also know that the pointer points to a node that has just been submitted |
|
// to the freelist. |
|
// In fact, we know that it has been released precisely 1 time, so its |
|
// generation should be 1 and the reference should still have a generation of |
|
// 0 as we seek to invalidate it, so they should mismatch. |
|
if(node.generation != 0) |
|
{TEST_ERROR("Node _reference_ generation changed?");} |
|
if(node.node->generation == 0) |
|
{TEST_ERROR("Node submitted to freelist stayed generation 0.");} |
|
if(node.node->generation != 1) |
|
{TEST_ERROR("Node submitted to freelist increased generation more than once?");} |
|
ASSERT_REFERENCE_INVALID(node, "(Skipped in second frame)"); |
|
if(context.freelist->head != node.node) |
|
{TEST_ERROR("Node not prepended to freelist.");} |
|
|
|
|
|
if(root.node->first_child != NULL) |
|
{TEST_ERROR("Last frame is empty, yet root has a first_child.");} |
|
} |
|
|
|
#define ASSERT_REFERENCES_EQUAL(REF1, REF2)\ |
|
if(!rdic_node_references_equal((REF1), (REF2)))\ |
|
{TEST_ERROR("`"#REF1"` != `"#REF2"`.\n");} |
|
void test__single_node__nodes_are_stable(void) |
|
{ |
|
// Arrange. |
|
RDIC_Context context = {0}; |
|
GUI_Node freelist_nodes[2] = {0}; |
|
init_node_freelist(freelist_nodes, ARRAYLENGTH(freelist_nodes)); |
|
RDIC_Freelist freelist = {&freelist_nodes[0].rn}; |
|
context.freelist = &freelist; |
|
RDIC_Node_Reference root = {0}; |
|
RDIC_Node_Reference node = {0}; |
|
|
|
RDIC_Node_Reference new_root = {0}; |
|
RDIC_Node_Reference new_node = {0}; |
|
|
|
// Act. |
|
// First frame. |
|
root = rdic_context_start_frame(&context, root); |
|
node = GET_NODE(&context, node); |
|
rdic_context_finish_frame(&context); |
|
// Second frame. |
|
new_root = rdic_context_start_frame(&context, root); |
|
new_node = GET_NODE(&context, node); |
|
rdic_context_finish_frame(&context); |
|
|
|
// Assert. |
|
ASSERT_REFERENCES_EQUAL(root, new_root); |
|
ASSERT_REFERENCES_EQUAL(node, new_node); |
|
} |
|
|
|
void test__single_node_freelist_reuse__succeed(void) |
|
{ |
|
// Arrange. |
|
ARRANGE_DEFAULT_CONFIGURATION(2); |
|
RDIC_Node_Reference node = {0}; |
|
|
|
// Act. |
|
// --- FRAME --- |
|
root = rdic_context_start_frame( |
|
&context, |
|
root); |
|
// Invalid reference -> new node. |
|
node = GET_NODE(&context, node); |
|
rdic_context_finish_frame(&context); |
|
// --- FRAME --- |
|
// node should return to freelist. |
|
root = rdic_context_start_frame( |
|
&context, |
|
root); |
|
// No call to get_node for node. |
|
rdic_context_finish_frame(&context); |
|
// --- FRAME --- |
|
root = rdic_context_start_frame( |
|
&context, |
|
root); |
|
// Invalid reference -> new node. |
|
node = GET_NODE(&context, node); |
|
rdic_context_finish_frame(&context); |
|
|
|
// Assert. |
|
// Firstly, we know that the release of the node should increment its |
|
// generation. Therefore, when we get the node again, its generation should |
|
// be exactly 1. |
|
if(node.generation != 1) |
|
{TEST_ERROR("`node` generation is not 1.");} |
|
ASSERT_REFERENCE_VALID(node); |
|
if(context.freelist->head != NULL) |
|
{TEST_ERROR("Freelist should be empty.");} |
|
} |
|
|
|
|
|
// --- |
|
|
|
|
|
void test__parent_child_frame__succeed(void) |
|
{ |
|
// Arrange. |
|
RDIC_Context context = {0}; |
|
GUI_Node freelist_nodes[3] = {0}; |
|
init_node_freelist(freelist_nodes, ARRAYLENGTH(freelist_nodes)); |
|
RDIC_Freelist freelist = {&freelist_nodes[0].rn}; |
|
context.freelist = &freelist; |
|
RDIC_Node_Reference root = {0}; |
|
RDIC_Node_Reference parent_node = {0}; |
|
RDIC_Node_Reference child_node = {0}; |
|
|
|
// Act. |
|
// First frame. |
|
root = rdic_context_start_frame( |
|
&context, |
|
root); |
|
// Invalid reference -> new node. |
|
parent_node = GET_NODE(&context, parent_node); |
|
rdic_push_parent(&context, parent_node); |
|
child_node = GET_NODE(&context, child_node); |
|
rdic_pop_parent(&context); |
|
rdic_context_finish_frame(&context); |
|
|
|
// Assert. |
|
ASSERT_PARENT_OF(root, parent_node); |
|
ASSERT_PARENT_OF(parent_node, child_node); |
|
ASSERT_FRISTCHILD_OF(child_node, parent_node); |
|
} |
|
|
|
void test__parent_child_free_child__child_to_freelist(void) |
|
{ |
|
// Arrange. |
|
RDIC_Context context = {0}; |
|
GUI_Node freelist_nodes[3] = {0}; |
|
init_node_freelist(freelist_nodes, ARRAYLENGTH(freelist_nodes)); |
|
RDIC_Freelist freelist = {&freelist_nodes[0].rn}; |
|
context.freelist = &freelist; |
|
RDIC_Node_Reference root = {0}; |
|
RDIC_Node_Reference parent_node = {0}; |
|
RDIC_Node_Reference child_node = {0}; |
|
|
|
// Act. |
|
// First frame. |
|
root = rdic_context_start_frame( |
|
&context, |
|
root); |
|
// Invalid reference -> new node. |
|
parent_node = GET_NODE(&context, parent_node); |
|
rdic_push_parent(&context, parent_node); |
|
child_node = GET_NODE(&context, child_node); |
|
rdic_pop_parent(&context); |
|
rdic_context_finish_frame(&context); |
|
// Second frame. |
|
root = rdic_context_start_frame( |
|
&context, |
|
root); |
|
parent_node = GET_NODE(&context, parent_node); |
|
rdic_push_parent(&context, parent_node); |
|
rdic_pop_parent(&context); |
|
rdic_context_finish_frame(&context); |
|
|
|
// Assert. |
|
if(child_node.generation != 0) |
|
{TEST_ERROR("Node _reference_ generation changed?");} |
|
if(child_node.node->generation != 1) |
|
{TEST_ERROR("Node submitted to freelist retained same generation?");} |
|
ASSERT_REFERENCE_INVALID(child_node, "(Skipped in second frame)"); |
|
if(context.freelist->head != child_node.node) |
|
{TEST_ERROR("Node not prepended to freelist.");} |
|
} |
|
|
|
void test__parent_child_free_child__parent_to_freelist(void) |
|
{ |
|
// Arrange. |
|
RDIC_Context context = {0}; |
|
GUI_Node freelist_nodes[3] = {0}; |
|
init_node_freelist(freelist_nodes, ARRAYLENGTH(freelist_nodes)); |
|
RDIC_Freelist freelist = {&freelist_nodes[0].rn}; |
|
context.freelist = &freelist; |
|
RDIC_Node_Reference root = {0}; |
|
RDIC_Node_Reference parent = {0}; |
|
RDIC_Node_Reference child = {0}; |
|
|
|
// Act. |
|
// First frame. |
|
root = rdic_context_start_frame( |
|
&context, |
|
root); |
|
// Invalid reference -> new node. |
|
parent = GET_NODE(&context, parent); |
|
rdic_push_parent(&context, parent); |
|
child = GET_NODE(&context, child); |
|
rdic_pop_parent(&context); |
|
rdic_context_finish_frame(&context); |
|
// Second frame. |
|
root = rdic_context_start_frame( |
|
&context, |
|
root); |
|
rdic_context_finish_frame(&context); |
|
|
|
// Assert. |
|
if(child.generation != 0) |
|
{TEST_ERROR("`child` _reference_ generation changed?");} |
|
if(child.node->generation != 1) |
|
{TEST_ERROR("`child` submitted to freelist retained same generation?");} |
|
ASSERT_REFERENCE_INVALID(child, "(Skipped in second frame)"); |
|
ASSERT_IN_FREELIST(&context, child); |
|
|
|
if(parent.generation != 0) |
|
{TEST_ERROR("`parent` _reference_ generation changed?");} |
|
if(parent.node->generation != 1) |
|
{TEST_ERROR("`parent` submitted to freelist retained same generation?");} |
|
ASSERT_REFERENCE_INVALID(parent, "(Skipped in second frame)"); |
|
ASSERT_IN_FREELIST(&context, parent); |
|
} |
|
|
|
void test__parent_child_both_reused__succeed(void) |
|
{ |
|
// Arrange. |
|
ARRANGE_DEFAULT_CONFIGURATION(3); |
|
RDIC_Node_Reference parent = {0}; |
|
RDIC_Node_Reference child = {0}; |
|
|
|
// NOTE(Zelaven): Multiple re-uses because it uncovers new bugs. |
|
// Act. |
|
// --- FRAME --- |
|
root = rdic_context_start_frame(&context, root); |
|
SET_DEBUG_NAME(root, "root"); |
|
parent = GET_NODE(&context, parent); |
|
rdic_push_parent(&context, parent); |
|
child = GET_NODE(&context, child); |
|
rdic_pop_parent(&context); |
|
rdic_context_finish_frame(&context); |
|
// --- FRAME --- |
|
root = rdic_context_start_frame(&context, root); |
|
rdic_context_finish_frame(&context); |
|
// --- FRAME --- |
|
root = rdic_context_start_frame(&context, root); |
|
SET_DEBUG_NAME(root, "root"); |
|
parent = GET_NODE(&context, parent); |
|
rdic_push_parent(&context, parent); |
|
child = GET_NODE(&context, child); |
|
rdic_pop_parent(&context); |
|
rdic_context_finish_frame(&context); |
|
// --- FRAME --- |
|
root = rdic_context_start_frame(&context, root); |
|
rdic_context_finish_frame(&context); |
|
// --- FRAME --- |
|
root = rdic_context_start_frame(&context, root); |
|
SET_DEBUG_NAME(root, "root"); |
|
parent = GET_NODE(&context, parent); |
|
rdic_push_parent(&context, parent); |
|
child = GET_NODE(&context, child); |
|
rdic_pop_parent(&context); |
|
rdic_context_finish_frame(&context); |
|
// --- FRAME --- |
|
root = rdic_context_start_frame(&context, root); |
|
rdic_context_finish_frame(&context); |
|
// --- FRAME --- |
|
root = rdic_context_start_frame(&context, root); |
|
SET_DEBUG_NAME(root, "root"); |
|
parent = GET_NODE(&context, parent); |
|
rdic_push_parent(&context, parent); |
|
child = GET_NODE(&context, child); |
|
rdic_pop_parent(&context); |
|
rdic_context_finish_frame(&context); |
|
|
|
// Assert. |
|
ASSERT_REFERENCE_VALID(parent); |
|
ASSERT_REFERENCE_VALID(child); |
|
} |
|
|
|
|
|
|
|
// --- |
|
|
|
#define PREAMBLE__parent_3children\ |
|
RDIC_Context context = {0};\ |
|
GUI_Node freelist_nodes[5] = {0};\ |
|
init_node_freelist(freelist_nodes, ARRAYLENGTH(freelist_nodes));\ |
|
RDIC_Freelist freelist = {&freelist_nodes[0].rn};\ |
|
context.freelist = &freelist;\ |
|
RDIC_Node_Reference root = {0};\ |
|
RDIC_Node_Reference parent = {0};\ |
|
RDIC_Node_Reference child1 = {0};\ |
|
RDIC_Node_Reference child2 = {0};\ |
|
RDIC_Node_Reference child3 = {0}; |
|
|
|
#define ACT__parent_3children_full_frame\ |
|
root = rdic_context_start_frame(&context, root);\ |
|
SET_DEBUG_NAME(root, "root");\ |
|
parent = GET_NODE(&context, parent);\ |
|
rdic_push_parent(&context, parent);\ |
|
child1 = GET_NODE(&context, child1);\ |
|
child2 = GET_NODE(&context, child2);\ |
|
child3 = GET_NODE(&context, child3);\ |
|
rdic_pop_parent(&context);\ |
|
rdic_context_finish_frame(&context); |
|
|
|
#define ASSERT__parent_3children__123_frame_structure\ |
|
ASSERT_PARENT_OF(root, parent);\ |
|
ASSERT_FRISTCHILD_OF(child1, parent);\ |
|
ASSERT_PARENT_OF(parent, child1);\ |
|
ASSERT_PARENT_OF(parent, child2);\ |
|
ASSERT_PARENT_OF(parent, child3);\ |
|
ASSERT_SIBLING_OF(child2, child1);\ |
|
ASSERT_SIBLING_OF(child3, child2);\ |
|
ASSERT_NO_SIBLING(child3); |
|
|
|
void test__parent_3children_123frame__succeed(void) { |
|
// Arrange. |
|
PREAMBLE__parent_3children |
|
|
|
// Act. |
|
// --- FRAME --- |
|
ACT__parent_3children_full_frame |
|
|
|
// Assert. |
|
ASSERT__parent_3children__123_frame_structure |
|
} |
|
|
|
void test__parent_3children_partial_frame_then_complete__succeed( |
|
int enable_child1, int enable_child2, int enable_child3) |
|
{ |
|
PREAMBLE__parent_3children; |
|
|
|
// --- FRAME --- |
|
root = rdic_context_start_frame(&context, root); |
|
SET_DEBUG_NAME(root, "root"); |
|
parent = GET_NODE(&context, parent); |
|
rdic_push_parent(&context, parent); |
|
if(enable_child1) child1 = GET_NODE(&context, child1); |
|
if(enable_child2) child2 = GET_NODE(&context, child2); |
|
if(enable_child3) child3 = GET_NODE(&context, child3); |
|
rdic_pop_parent(&context); |
|
rdic_context_finish_frame(&context); |
|
//ASSERT_REFERENCE_VALID(child1); |
|
//ASSERT_REFERENCE_VALID(child2); |
|
//ASSERT_REFERENCE_VALID(child3); |
|
// --- FRAME --- |
|
ACT__parent_3children_full_frame |
|
|
|
// Assert. |
|
ASSERT__parent_3children__123_frame_structure |
|
} |
|
|
|
|
|
void test__parent_3children_culling__succeed( |
|
int enable_child1, int enable_child2, int enable_child3) |
|
{ |
|
PREAMBLE__parent_3children; |
|
|
|
// --- FRAME --- |
|
ACT__parent_3children_full_frame |
|
// --- FRAME --- |
|
root = rdic_context_start_frame(&context, root); |
|
SET_DEBUG_NAME(root, "root"); |
|
parent = GET_NODE(&context, parent); |
|
rdic_push_parent(&context, parent); |
|
if(enable_child1) { |
|
child1 = GET_NODE(&context, child1);} |
|
if(enable_child2) { |
|
child2 = GET_NODE(&context, child2);} |
|
if(enable_child3) { |
|
child3 = GET_NODE(&context, child3);} |
|
rdic_pop_parent(&context); |
|
rdic_context_finish_frame(&context); |
|
|
|
// Assert. |
|
// NOTE(Zelaven): Yes, the assertions look messy, but it's just as easy to |
|
// make 9 cases of copy-paste messy. |
|
// Deciphering the exact conditions may take a few seconds, but this was the |
|
// simplest solution I could come up with that met my quality standards for |
|
// this test code. |
|
if(enable_child1) {ASSERT_REFERENCE_VALID(child1);} |
|
else {ASSERT_REFERENCE_INVALID(child1);} |
|
if(enable_child2) {ASSERT_REFERENCE_VALID(child2);} |
|
else {ASSERT_REFERENCE_INVALID(child2);} |
|
if(enable_child3) {ASSERT_REFERENCE_VALID(child3);} |
|
else {ASSERT_REFERENCE_INVALID(child3);} |
|
|
|
ASSERT_PARENT_OF(root, parent); |
|
if(enable_child1) {ASSERT_FRISTCHILD_OF(child1, parent);} |
|
else if(enable_child2) {ASSERT_FRISTCHILD_OF(child2, parent);} |
|
else if (enable_child3) {ASSERT_FRISTCHILD_OF(child3, parent);} |
|
|
|
if(enable_child1) {ASSERT_PARENT_OF(parent, child1);} |
|
if(enable_child2) {ASSERT_PARENT_OF(parent, child2);} |
|
if(enable_child3) {ASSERT_PARENT_OF(parent, child3);} |
|
if(enable_child1 && enable_child2) {ASSERT_SIBLING_OF(child2, child1);} |
|
else if(enable_child1 && enable_child3) {ASSERT_SIBLING_OF(child3, child1);} |
|
if(enable_child2 && enable_child3) {ASSERT_SIBLING_OF(child3, child2);} |
|
|
|
if(enable_child3) {ASSERT_NO_SIBLING(child3);} |
|
else if(enable_child2) {ASSERT_NO_SIBLING(child2);} |
|
else if(enable_child1) {ASSERT_NO_SIBLING(child2);} |
|
|
|
if(!enable_child1) {ASSERT_IN_FREELIST(&context, child1);} |
|
if(!enable_child2) {ASSERT_IN_FREELIST(&context, child2);} |
|
if(!enable_child3) {ASSERT_IN_FREELIST(&context, child3);} |
|
} |
|
|
|
|
|
void test__parent_3children_full_frame_reuse__succeed(void) { |
|
// Arrange. |
|
PREAMBLE__parent_3children |
|
|
|
// Act. |
|
// --- FRAME --- |
|
ACT__parent_3children_full_frame |
|
// --- FRAME --- |
|
root = rdic_context_start_frame(&context, root); |
|
rdic_context_finish_frame(&context); |
|
// --- FRAME --- |
|
ACT__parent_3children_full_frame |
|
// --- FRAME --- |
|
root = rdic_context_start_frame(&context, root); |
|
rdic_context_finish_frame(&context); |
|
// --- FRAME --- |
|
ACT__parent_3children_full_frame |
|
// --- FRAME --- |
|
root = rdic_context_start_frame(&context, root); |
|
rdic_context_finish_frame(&context); |
|
// --- FRAME --- |
|
ACT__parent_3children_full_frame |
|
// --- FRAME --- |
|
root = rdic_context_start_frame(&context, root); |
|
rdic_context_finish_frame(&context); |
|
// --- FRAME --- |
|
ACT__parent_3children_full_frame |
|
// --- FRAME --- |
|
root = rdic_context_start_frame(&context, root); |
|
rdic_context_finish_frame(&context); |
|
// --- FRAME --- |
|
ACT__parent_3children_full_frame |
|
// --- FRAME --- |
|
root = rdic_context_start_frame(&context, root); |
|
rdic_context_finish_frame(&context); |
|
// --- FRAME --- |
|
ACT__parent_3children_full_frame |
|
|
|
|
|
// Assert. |
|
ASSERT__parent_3children__123_frame_structure |
|
} |
|
|
|
|
|
// --- |
|
|
|
void test__exhaust_freelist_larger_tree__no_crash(void) |
|
{ |
|
// Arrange. |
|
RDIC_Context context = {0}; |
|
GUI_Node freelist_nodes[3] = {0}; |
|
init_node_freelist(freelist_nodes, ARRAYLENGTH(freelist_nodes)); |
|
RDIC_Freelist freelist = {&freelist_nodes[0].rn}; |
|
context.freelist = &freelist; |
|
RDIC_Node_Reference root = {0}; |
|
RDIC_Node_Reference n1 = {0}; |
|
RDIC_Node_Reference n1_1 = {0}; |
|
RDIC_Node_Reference n1_1_1 = {0}; |
|
RDIC_Node_Reference n1_1_2 = {0}; |
|
RDIC_Node_Reference n1_2 = {0}; |
|
RDIC_Node_Reference n1_2_1 = {0}; |
|
RDIC_Node_Reference n1_2_2 = {0}; |
|
RDIC_Node_Reference n2 = {0}; |
|
RDIC_Node_Reference n2_1 = {0}; |
|
RDIC_Node_Reference n2_2 = {0}; |
|
RDIC_Node_Reference n3 = {0}; |
|
RDIC_Node_Reference n3_1 = {0}; |
|
RDIC_Node_Reference n3_2 = {0}; |
|
|
|
// Act. |
|
/* |
|
* r |
|
* n n n |
|
* n n nn nn |
|
* nn nn |
|
*/ |
|
// First frame. |
|
root = rdic_context_start_frame(&context, root); |
|
SET_DEBUG_NAME(root, "root"); |
|
n1 = GET_NODE(&context, n1); |
|
rdic_push_parent(&context, n1); |
|
n1_1 = GET_NODE(&context, n1_1); |
|
rdic_push_parent(&context, n1_1); |
|
n1_1_1 = GET_NODE(&context, n1_1_1); |
|
n1_1_2 = GET_NODE(&context, n1_1_2); |
|
rdic_pop_parent(&context); |
|
n1_2 = GET_NODE(&context, n1_2); |
|
rdic_push_parent(&context, n1_2); |
|
n1_2_1 = GET_NODE(&context, n1_2_1); |
|
n1_2_2 = GET_NODE(&context, n1_2_2); |
|
rdic_pop_parent(&context); |
|
rdic_pop_parent(&context); |
|
n2 = GET_NODE(&context, n2); |
|
rdic_push_parent(&context, n2); |
|
n2_1 = GET_NODE(&context, n2_1); |
|
n2_2 = GET_NODE(&context, n2_2); |
|
rdic_pop_parent(&context); |
|
n3 = GET_NODE(&context, n3); |
|
rdic_push_parent(&context, n3); |
|
n3_1 = GET_NODE(&context, n3_1); |
|
n3_2 = GET_NODE(&context, n3_2); |
|
rdic_pop_parent(&context); |
|
rdic_context_finish_frame(&context); |
|
|
|
root = rdic_context_start_frame(&context, root); |
|
rdic_context_finish_frame(&context); |
|
|
|
// Assert. |
|
} |
|
|
|
void test__large_tree_constructed__succeed(void) |
|
{ |
|
// Arrange. |
|
RDIC_Context context = {0}; |
|
GUI_Node freelist_nodes[14] = {0}; |
|
init_node_freelist(freelist_nodes, ARRAYLENGTH(freelist_nodes)); |
|
RDIC_Freelist freelist = {&freelist_nodes[0].rn}; |
|
context.freelist = &freelist; |
|
RDIC_Node_Reference root = {0}; |
|
RDIC_Node_Reference n1 = {0}; |
|
RDIC_Node_Reference n1_1 = {0}; |
|
RDIC_Node_Reference n1_1_1 = {0}; |
|
RDIC_Node_Reference n1_1_2 = {0}; |
|
RDIC_Node_Reference n1_2 = {0}; |
|
RDIC_Node_Reference n1_2_1 = {0}; |
|
RDIC_Node_Reference n1_2_2 = {0}; |
|
RDIC_Node_Reference n2 = {0}; |
|
RDIC_Node_Reference n2_1 = {0}; |
|
RDIC_Node_Reference n2_2 = {0}; |
|
RDIC_Node_Reference n3 = {0}; |
|
RDIC_Node_Reference n3_1 = {0}; |
|
RDIC_Node_Reference n3_2 = {0}; |
|
|
|
// Act. |
|
/* |
|
* r |
|
* n n n |
|
* n n nn nn |
|
* nn nn |
|
*/ |
|
// First frame. |
|
root = rdic_context_start_frame(&context, root); |
|
SET_DEBUG_NAME(root, "root"); |
|
n1 = GET_NODE(&context, n1); |
|
rdic_push_parent(&context, n1); |
|
n1_1 = GET_NODE(&context, n1_1); |
|
rdic_push_parent(&context, n1_1); |
|
n1_1_1 = GET_NODE(&context, n1_1_1); |
|
n1_1_2 = GET_NODE(&context, n1_1_2); |
|
rdic_pop_parent(&context); |
|
n1_2 = GET_NODE(&context, n1_2); |
|
rdic_push_parent(&context, n1_2); |
|
n1_2_1 = GET_NODE(&context, n1_2_1); |
|
n1_2_2 = GET_NODE(&context, n1_2_2); |
|
rdic_pop_parent(&context); |
|
rdic_pop_parent(&context); |
|
n2 = GET_NODE(&context, n2); |
|
rdic_push_parent(&context, n2); |
|
n2_1 = GET_NODE(&context, n2_1); |
|
n2_2 = GET_NODE(&context, n2_2); |
|
rdic_pop_parent(&context); |
|
n3 = GET_NODE(&context, n3); |
|
rdic_push_parent(&context, n3); |
|
n3_1 = GET_NODE(&context, n3_1); |
|
n3_2 = GET_NODE(&context, n3_2); |
|
rdic_pop_parent(&context); |
|
rdic_context_finish_frame(&context); |
|
|
|
// Assert. |
|
ASSERT_REFERENCE_VALID(root); |
|
ASSERT_REFERENCE_VALID(n1); |
|
ASSERT_REFERENCE_VALID(n1_1); |
|
ASSERT_REFERENCE_VALID(n1_1_1); |
|
ASSERT_REFERENCE_VALID(n1_1_2); |
|
ASSERT_REFERENCE_VALID(n1_2); |
|
ASSERT_REFERENCE_VALID(n1_2_1); |
|
ASSERT_REFERENCE_VALID(n1_2_2); |
|
ASSERT_REFERENCE_VALID(n2); |
|
ASSERT_REFERENCE_VALID(n2_1); |
|
ASSERT_REFERENCE_VALID(n2_2); |
|
ASSERT_REFERENCE_VALID(n3); |
|
ASSERT_REFERENCE_VALID(n3_1); |
|
ASSERT_REFERENCE_VALID(n3_2); |
|
// NOTE(Zelaven): More asserts could be added to assert correct structure. |
|
} |
|
|
|
void test__culling_that_needs_to_use_stash__succeed(void) |
|
{ |
|
// Arrange. |
|
RDIC_Context context = {0}; |
|
GUI_Node freelist_nodes[14] = {0}; |
|
init_node_freelist(freelist_nodes, ARRAYLENGTH(freelist_nodes)); |
|
RDIC_Freelist freelist = {&freelist_nodes[0].rn}; |
|
context.freelist = &freelist; |
|
RDIC_Node_Reference root = {0}; |
|
RDIC_Node_Reference n1 = {0}; |
|
RDIC_Node_Reference n1_1 = {0}; |
|
RDIC_Node_Reference n1_1_1 = {0}; |
|
RDIC_Node_Reference n1_1_2 = {0}; |
|
RDIC_Node_Reference n1_2 = {0}; |
|
RDIC_Node_Reference n1_2_1 = {0}; |
|
RDIC_Node_Reference n1_2_2 = {0}; |
|
RDIC_Node_Reference n2 = {0}; |
|
RDIC_Node_Reference n2_1 = {0}; |
|
RDIC_Node_Reference n2_2 = {0}; |
|
RDIC_Node_Reference n3 = {0}; |
|
RDIC_Node_Reference n3_1 = {0}; |
|
RDIC_Node_Reference n3_2 = {0}; |
|
|
|
// Act. |
|
/* |
|
* r |
|
* n n n |
|
* n n nn nn |
|
* nn nn |
|
*/ |
|
// First frame. |
|
root = rdic_context_start_frame(&context, root); |
|
SET_DEBUG_NAME(root, "root"); |
|
n1 = GET_NODE(&context, n1); |
|
rdic_push_parent(&context, n1); |
|
n1_1 = GET_NODE(&context, n1_1); |
|
rdic_push_parent(&context, n1_1); |
|
n1_1_1 = GET_NODE(&context, n1_1_1); |
|
n1_1_2 = GET_NODE(&context, n1_1_2); |
|
rdic_pop_parent(&context); |
|
n1_2 = GET_NODE(&context, n1_2); |
|
rdic_push_parent(&context, n1_2); |
|
n1_2_1 = GET_NODE(&context, n1_2_1); |
|
n1_2_2 = GET_NODE(&context, n1_2_2); |
|
rdic_pop_parent(&context); |
|
rdic_pop_parent(&context); |
|
n2 = GET_NODE(&context, n2); |
|
rdic_push_parent(&context, n2); |
|
n2_1 = GET_NODE(&context, n2_1); |
|
n2_2 = GET_NODE(&context, n2_2); |
|
rdic_pop_parent(&context); |
|
n3 = GET_NODE(&context, n3); |
|
rdic_push_parent(&context, n3); |
|
n3_1 = GET_NODE(&context, n3_1); |
|
n3_2 = GET_NODE(&context, n3_2); |
|
rdic_pop_parent(&context); |
|
rdic_context_finish_frame(&context); |
|
|
|
root = rdic_context_start_frame(&context, root); |
|
rdic_context_finish_frame(&context); |
|
|
|
// Assert. |
|
// NOTE(Zelaven): The root node is never collected (always re-used). |
|
//ASSERT_REFERENCE_INVALID(root); |
|
//ASSERT_IN_FREELIST(&context, root); |
|
ASSERT_REFERENCE_INVALID(n1); |
|
ASSERT_IN_FREELIST(&context, n1); |
|
ASSERT_REFERENCE_INVALID(n1_1); |
|
ASSERT_IN_FREELIST(&context, n1_1); |
|
ASSERT_REFERENCE_INVALID(n1_1_1); |
|
ASSERT_IN_FREELIST(&context, n1_1_1); |
|
ASSERT_REFERENCE_INVALID(n1_1_2); |
|
ASSERT_IN_FREELIST(&context, n1_1_2); |
|
ASSERT_REFERENCE_INVALID(n1_2); |
|
ASSERT_IN_FREELIST(&context, n1_2); |
|
ASSERT_REFERENCE_INVALID(n1_2_1); |
|
ASSERT_IN_FREELIST(&context, n1_2_1); |
|
ASSERT_REFERENCE_INVALID(n1_2_2); |
|
ASSERT_IN_FREELIST(&context, n1_2_2); |
|
ASSERT_REFERENCE_INVALID(n2); |
|
ASSERT_IN_FREELIST(&context, n2); |
|
ASSERT_REFERENCE_INVALID(n2_1); |
|
ASSERT_IN_FREELIST(&context, n2_1); |
|
ASSERT_REFERENCE_INVALID(n2_2); |
|
ASSERT_IN_FREELIST(&context, n2_2); |
|
ASSERT_REFERENCE_INVALID(n3); |
|
ASSERT_IN_FREELIST(&context, n3); |
|
ASSERT_REFERENCE_INVALID(n3_1); |
|
ASSERT_IN_FREELIST(&context, n3_1); |
|
ASSERT_REFERENCE_INVALID(n3_2); |
|
ASSERT_IN_FREELIST(&context, n3_2); |
|
} |
|
|
|
|
|
|
|
|
|
#include <stdio.h> |
|
#if 0 |
|
// You can remove the %d in this format specifier by using stringification. |
|
// I just lazied and didn't bother. |
|
#define MY_ASSERT(X) if(!(X)) printf(__FILE__":%d: %s: `"#X"` failed.\n", __LINE__, __func__); |
|
MY_ASSERT(node.generation != 0); |
|
assert(node.generation != 0); |
|
#endif |
|
|
|
|
|
// --- TEST RUNNER --- |
|
|
|
|
|
#include <stdio.h> |
|
|
|
void print_test_result(Report_Test_Result result) |
|
{ |
|
char *color_codes[TESTRESULT_NUM_LEVELS] = { |
|
"\033[30m", |
|
"\033[32m", |
|
"\033[31m", |
|
}; |
|
printf("%s: %s%s\033[0m\n", result.test_name, color_codes[result.level], result.string); |
|
} |
|
|
|
//#define TEST(func_to_test, args...) print_test_result(#func_to_test, func_to_test(args)); |
|
|
|
#define TEST(func_to_test, args...) \ |
|
g_error_occurred = 0;\ |
|
g_test_name = #func_to_test"("#args")";\ |
|
func_to_test(args);\ |
|
if(!g_error_occurred) log_result_to_report((Report_Test_Result){\ |
|
.level = TESTRESULT_SUCCESS,\ |
|
.test_name = g_test_name,\ |
|
.string = "Test Successful.",\ |
|
}); |
|
|
|
int main() |
|
{ |
|
assert(linux_allocate_arena_memory( |
|
&g_test_report_arena, |
|
1024*4) == 0); |
|
|
|
log_new_report_group("Starting and Finishing Frames."); |
|
// Starting and finishing frames. |
|
TEST(test__start_frame__empty_freelist); |
|
TEST(test__start_frame__succeed); |
|
TEST(test__finish_frame__succeed); |
|
|
|
log_new_report_group("Next node - getting a single node."); |
|
// Next node. |
|
TEST(test__get_node_with_empty_freelist__return_null_reference); |
|
TEST(test__get_node_with_empty_freelist_with_nonzero_generation__return_null_reference); |
|
TEST(test__get_node__succeed); |
|
TEST(test__get_node_finish_frame__succeed); |
|
TEST(test__single_node__returned_to_freelist); |
|
TEST(test__single_node__nodes_are_stable); |
|
TEST(test__single_node_freelist_reuse__succeed); |
|
|
|
log_new_report_group("Root - parent - child."); |
|
TEST(test__parent_child_frame__succeed); |
|
TEST(test__parent_child_free_child__child_to_freelist); |
|
TEST(test__parent_child_free_child__parent_to_freelist); |
|
TEST(test__parent_child_both_reused__succeed); |
|
|
|
log_new_report_group("Root - parent - 3 children."); |
|
TEST(test__parent_3children_123frame__succeed); |
|
|
|
TEST(test__parent_3children_partial_frame_then_complete__succeed, 1,1,1); |
|
TEST(test__parent_3children_partial_frame_then_complete__succeed, 1,1,0); |
|
TEST(test__parent_3children_partial_frame_then_complete__succeed, 1,0,1); |
|
TEST(test__parent_3children_partial_frame_then_complete__succeed, 0,1,1); |
|
TEST(test__parent_3children_partial_frame_then_complete__succeed, 1,0,0); |
|
TEST(test__parent_3children_partial_frame_then_complete__succeed, 0,1,0); |
|
TEST(test__parent_3children_partial_frame_then_complete__succeed, 0,0,1); |
|
TEST(test__parent_3children_partial_frame_then_complete__succeed, 0,0,0); |
|
|
|
TEST(test__parent_3children_culling__succeed, 1,1,0); |
|
TEST(test__parent_3children_culling__succeed, 1,0,1); |
|
TEST(test__parent_3children_culling__succeed, 0,1,1); |
|
TEST(test__parent_3children_culling__succeed, 1,0,0); |
|
TEST(test__parent_3children_culling__succeed, 0,1,0); |
|
TEST(test__parent_3children_culling__succeed, 0,0,1); |
|
TEST(test__parent_3children_culling__succeed, 0,0,0); |
|
|
|
TEST(test__parent_3children_full_frame_reuse__succeed); |
|
|
|
log_new_report_group("Larger tree."); |
|
TEST(test__exhaust_freelist_larger_tree__no_crash); |
|
TEST(test__large_tree_constructed__succeed); |
|
TEST(test__culling_that_needs_to_use_stash__succeed); |
|
|
|
|
|
// TODO(Zelaven): A test that causes the deallocation of a subtree that |
|
// requires the collector to use the stashing mechanism. |
|
|
|
|
|
//printf("\n\n\n"); |
|
//Test_Result *results = g_test_report_arena.memory; |
|
Report_Group *current_group = g_first_report_group; |
|
while(current_group != NULL) |
|
{ |
|
printf("\n*** %s ***\n", current_group->name); |
|
Report_Test_Result *results = current_group->results; |
|
for(unsigned int i = 0; i < current_group->num_test_results; i++) |
|
{ |
|
print_test_result(results[i]); |
|
} |
|
current_group = current_group->next; |
|
} |
|
|
|
return 0; |
|
} |
|
|
|
|
|
|
|
|
|
|