diff --git a/code/logic/common.c b/code/logic/common.c index a477ec9..c23b801 100644 --- a/code/logic/common.c +++ b/code/logic/common.c @@ -161,13 +161,13 @@ void fossil_pizza_hash(const char *input, const char *output, uint8_t *hash_out) // Lookup tables for valid tags and criteria static const char* VALID_TAGS[] = { "fossil", // default tag - "jellyfish", // Jellyfish AI tag + "ai", // Jellyfish AI tag "network", // Network-related tests "database", // Database-related tests "ui", // User Interface tests "api", // API-related tests "critical", // Critical tests - "non_critical", // Non-critical tests + "media", // Media tests null // Sentinel to mark the end }; @@ -175,6 +175,8 @@ static const char* VALID_CRITERIA[] = { "name", "time", "result", + "priority", + "hash", null // Sentinel to mark the end }; diff --git a/code/logic/fossil/pizza/test.h b/code/logic/fossil/pizza/test.h index 3223466..ecf0287 100644 --- a/code/logic/fossil/pizza/test.h +++ b/code/logic/fossil/pizza/test.h @@ -80,6 +80,7 @@ typedef struct { void (*run)(void); // Test execution function uint64_t elapsed_ns; // Timing in nanoseconds + int64_t priority; // Priority level (lower = higher priority) fossil_pizza_case_result_t result; // Outcome // TI Extensions: @@ -272,6 +273,7 @@ FOSSIL_PIZZA_API void _on_skip(const char *description); nullptr, \ test_name##_run, \ 0, \ + 0, \ FOSSIL_PIZZA_CASE_EMPTY, \ { \ nullptr, \ @@ -297,6 +299,7 @@ FOSSIL_PIZZA_API void _on_skip(const char *description); .teardown = NULL, \ .run = test_name##_run, \ .elapsed_ns = 0, \ + .priority = 0, \ .result = FOSSIL_PIZZA_CASE_EMPTY, \ .meta = { \ .hash = NULL, \ diff --git a/code/logic/test.c b/code/logic/test.c index 1bd47f6..168a874 100644 --- a/code/logic/test.c +++ b/code/logic/test.c @@ -740,10 +740,26 @@ static int compare_time_desc(const void* a, const void* b) { return ((fossil_pizza_case_t*)b)->elapsed_ns - ((fossil_pizza_case_t*)a)->elapsed_ns; } +static int compare_priority_asc(const void* a, const void* b) { + return ((fossil_pizza_case_t*)a)->priority - ((fossil_pizza_case_t*)b)->priority; +} + +static int compare_priority_desc(const void* a, const void* b) { + return ((fossil_pizza_case_t*)b)->priority - ((fossil_pizza_case_t*)a)->priority; +} + +static int compare_hash_asc(const void* a, const void* b) { + return memcmp(((fossil_pizza_case_t*)a)->meta.hash, ((fossil_pizza_case_t*)b)->meta.hash, FOSSIL_PIZZA_HASH_SIZE); +} + +static int compare_hash_desc(const void* a, const void* b) { + return memcmp(((fossil_pizza_case_t*)b)->meta.hash, ((fossil_pizza_case_t*)a)->meta.hash, FOSSIL_PIZZA_HASH_SIZE); +} + void fossil_pizza_sort_cases(fossil_pizza_suite_t* suite, const fossil_pizza_engine_t* engine) { if (!suite || !suite->cases || suite->count <= 1 || !engine) return; - int (*compare)(const void*, const void*) = null; + int (*compare)(const void*, const void*) = NULL; if (engine->pallet.sort.by) { if (pizza_io_cstr_compare(engine->pallet.sort.by, "name") == 0) { @@ -752,20 +768,16 @@ void fossil_pizza_sort_cases(fossil_pizza_suite_t* suite, const fossil_pizza_eng compare = (pizza_io_cstr_compare(engine->pallet.sort.order, "desc") == 0) ? compare_result_desc : compare_result_asc; } else if (pizza_io_cstr_compare(engine->pallet.sort.by, "time") == 0) { compare = (pizza_io_cstr_compare(engine->pallet.sort.order, "desc") == 0) ? compare_time_desc : compare_time_asc; + } else if (pizza_io_cstr_compare(engine->pallet.sort.by, "priority") == 0) { + compare = (pizza_io_cstr_compare(engine->pallet.sort.order, "desc") == 0) ? compare_priority_desc : compare_priority_asc; + } else if (pizza_io_cstr_compare(engine->pallet.sort.by, "hash") == 0) { + compare = (pizza_io_cstr_compare(engine->pallet.sort.order, "desc") == 0) ? compare_hash_desc : compare_hash_asc; } else { // Invalid sort criteria return; } } - if (engine->pallet.sort.order) { - if (pizza_io_cstr_compare(engine->pallet.sort.order, "desc") == 0) { - compare = (compare == compare_name_asc) ? compare_name_desc : compare; - } else if (pizza_io_cstr_compare(engine->pallet.sort.order, "asc") == 0) { - compare = (compare == compare_name_desc) ? compare_name_asc : compare; - } - } - if (compare) { qsort(suite->cases, suite->count, sizeof(fossil_pizza_case_t), compare); } @@ -801,9 +813,10 @@ void fossil_pizza_shuffle_cases(fossil_pizza_suite_t* suite, const fossil_pizza_ unsigned int seed = (engine && engine->pallet.shuffle.seed) ? (unsigned int)atoi(engine->pallet.shuffle.seed) - : (unsigned int)time(null); + : (unsigned int)time(NULL); srand(seed); + // Fisher-Yates shuffle for (size_t i = suite->count - 1; i > 0; --i) { size_t j = rand() % (i + 1); fossil_pizza_case_t temp = suite->cases[i]; @@ -811,14 +824,18 @@ void fossil_pizza_shuffle_cases(fossil_pizza_suite_t* suite, const fossil_pizza_ suite->cases[j] = temp; } + // Optional secondary shuffle/sort by field if (engine && engine->pallet.shuffle.by) { if (pizza_io_cstr_compare(engine->pallet.shuffle.by, "name") == 0) { - qsort(suite->cases, suite->count, sizeof(fossil_pizza_case_t), - (int (*)(const void*, const void*))pizza_io_cstr_compare); + qsort(suite->cases, suite->count, sizeof(fossil_pizza_case_t), compare_name_asc); } else if (pizza_io_cstr_compare(engine->pallet.shuffle.by, "result") == 0) { qsort(suite->cases, suite->count, sizeof(fossil_pizza_case_t), compare_result_asc); } else if (pizza_io_cstr_compare(engine->pallet.shuffle.by, "time") == 0) { qsort(suite->cases, suite->count, sizeof(fossil_pizza_case_t), compare_time_asc); + } else if (pizza_io_cstr_compare(engine->pallet.shuffle.by, "priority") == 0) { + qsort(suite->cases, suite->count, sizeof(fossil_pizza_case_t), compare_priority_asc); + } else if (pizza_io_cstr_compare(engine->pallet.shuffle.by, "hash") == 0) { + qsort(suite->cases, suite->count, sizeof(fossil_pizza_case_t), compare_hash_asc); } } }