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.
1162 lines
34 KiB
1162 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));\
|
|
context.node_freelist = &freelist_nodes[0].rn;\
|
|
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->node_freelist;
|
|
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));
|
|
context.node_freelist = &freelist_nodes[0].rn;
|
|
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));
|
|
context.node_freelist = &freelist_nodes[0].rn;
|
|
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));
|
|
context.node_freelist = &freelist_nodes[0].rn;
|
|
RDIC_Node_Reference root = {0};
|
|
root = rdic_context_start_frame(
|
|
&context,
|
|
root);
|
|
|
|
assert(context.node_freelist == NULL);
|
|
|
|
// 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(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));
|
|
context.node_freelist = &freelist_nodes[0].rn;
|
|
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));
|
|
context.node_freelist = &freelist_nodes[0].rn;
|
|
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));
|
|
context.node_freelist = &freelist_nodes[0].rn;
|
|
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.node_freelist != 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));
|
|
context.node_freelist = &freelist_nodes[0].rn;
|
|
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.node_freelist != 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));
|
|
context.node_freelist = &freelist_nodes[0].rn;
|
|
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));
|
|
context.node_freelist = &freelist_nodes[0].rn;
|
|
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.node_freelist != 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));
|
|
context.node_freelist = &freelist_nodes[0].rn;
|
|
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));\
|
|
context.node_freelist = &freelist_nodes[0].rn;\
|
|
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));
|
|
context.node_freelist = &freelist_nodes[0].rn;
|
|
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));
|
|
context.node_freelist = &freelist_nodes[0].rn;
|
|
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));
|
|
context.node_freelist = &freelist_nodes[0].rn;
|
|
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;
|
|
}
|
|
|
|
|
|
|
|
|
|
|