// This file is part of the 64k demo project. // It tests the asset manager's ability to retrieve packed data. // Verifies data integrity and size reporting. #if defined(USE_TEST_ASSETS) #include "test_assets.h" #else #include "generated/assets.h" #endif /* defined(USE_TEST_ASSETS) */ #include #include #include int main() { printf("Running AssetManager test...\n"); size_t size = 0; const uint8_t* data1 = GetAsset(AssetId::ASSET_TEST_ASSET_1, &size); assert(data1 != nullptr); assert(size > 0); const char* expected_prefix = "This is a test asset file."; if (strncmp((const char*)data1, expected_prefix, strlen(expected_prefix)) == 0) { printf("Asset content verification: SUCCESS\n"); } else { printf("Asset content verification: FAILED\n"); printf("Got: %.*s\n", (int)size, (const char*)data1); return 1; } // Test caching: request the same asset again and verify pointer is identical size_t size2 = 0; const uint8_t* data2 = GetAsset(AssetId::ASSET_TEST_ASSET_1, &size2); assert(data2 != nullptr); assert(size2 == size); assert(data1 == data2); // Pointers should be the same for cached static asset printf("Asset caching test: SUCCESS\n"); // Test ASSET_LAST_ID - should not return a valid asset size_t last_id_size = 0; const uint8_t* last_id_data = GetAsset(AssetId::ASSET_LAST_ID, &last_id_size); assert(last_id_data == nullptr); assert(last_id_size == 0); printf("ASSET_LAST_ID test: SUCCESS\n"); printf("Asset size: %zu bytes\n", size); // Test procedural asset printf("\nRunning Procedural Asset test...\n"); size_t proc_size = 0; const uint8_t* proc_data_1 = GetAsset(AssetId::ASSET_PROC_NOISE_256, &proc_size); assert(proc_data_1 != nullptr); assert(proc_size == 256 * 256 * 4); // 256x256 RGBA8 // Verify first few bytes are not all zero (noise should produce non-zero // data) bool non_zero_data = false; for (size_t i = 0; i < 16; ++i) { // Check first 16 bytes if (proc_data_1[i] != 0) { non_zero_data = true; break; } } assert(non_zero_data); printf("Procedural asset content verification: SUCCESS\n"); // Test DropAsset for procedural asset and re-generation DropAsset(AssetId::ASSET_PROC_NOISE_256, proc_data_1); // After dropping, GetAsset should generate new data const uint8_t* proc_data_2 = GetAsset(AssetId::ASSET_PROC_NOISE_256, &proc_size); assert(proc_data_2 != nullptr); // assert(proc_data_1 != proc_data_2); // Removed: Allocator might reuse the // same address // Verify content again to ensure it was re-generated correctly non_zero_data = false; for (size_t i = 0; i < 16; ++i) { if (proc_data_2[i] != 0) { non_zero_data = true; break; } } assert(non_zero_data); printf("Procedural asset DropAsset and re-generation test: SUCCESS\n"); // Test Unknown Procedural Function printf("\nRunning Unknown Procedural Function test...\n"); size_t unknown_size = 0; // This should print an error to stderr: "Error: Unknown procedural function..." const uint8_t* unknown_data = GetAsset(AssetId::ASSET_PROC_UNKNOWN, &unknown_size); assert(unknown_data == nullptr); assert(unknown_size == 0); printf("Unknown Procedural Function test: SUCCESS\n"); // Test Failing Procedural Function printf("\nRunning Failing Procedural Function test...\n"); size_t fail_size = 0; // This should print an error to stderr: "Error: Procedural generation failed..." const uint8_t* fail_data = GetAsset(AssetId::ASSET_PROC_FAIL, &fail_size); assert(fail_data == nullptr); assert(fail_size == 0); printf("Failing Procedural Function test: SUCCESS\n"); // Test Out-of-Bounds ID (beyond ASSET_LAST_ID) // Casting to AssetId to suppress compiler warnings if checking strict enum types printf("\nRunning Out-of-Bounds ID test...\n"); size_t oob_size = 0; const uint8_t* oob_data = GetAsset((AssetId)((int)AssetId::ASSET_LAST_ID + 1), &oob_size); assert(oob_data == nullptr); assert(oob_size == 0); printf("Out-of-Bounds ID test: SUCCESS\n"); // Test DropAsset edge cases printf("\nRunning DropAsset edge cases test...\n"); // Invalid ID DropAsset((AssetId)((int)AssetId::ASSET_LAST_ID + 1), nullptr); // Mismatched pointer (should do nothing) // We use proc_data_2 which is valid, but pass a different ID (e.g. ASSET_TEST_ASSET_1 which is static) DropAsset(AssetId::ASSET_TEST_ASSET_1, proc_data_2); // Verify proc_data_2 is still valid (by checking it's in cache). // Note: GetAsset will just return the cached pointer. If DropAsset worked, it would have been cleared. // But wait, DropAsset clears it from cache. // The correct test for "mismatched pointer" is: pass the correct ID but WRONG pointer. // This ensures we don't clear the cache if the user passes a stale/wrong pointer. // Let's try to drop ASSET_PROC_NOISE_256 with a dummy pointer. uint8_t dummy_ptr; DropAsset(AssetId::ASSET_PROC_NOISE_256, &dummy_ptr); // Check if asset is still in cache (should be, as we didn't drop the real one) // We can't peek into g_asset_cache directly from here (it's static). // But GetAsset should return the SAME pointer as proc_data_2 without re-generation. // If it was dropped, GetAsset would re-generate and likely return a NEW pointer (new allocation). const uint8_t* proc_data_3 = GetAsset(AssetId::ASSET_PROC_NOISE_256, nullptr); assert(proc_data_3 == proc_data_2); printf("DropAsset edge cases test: SUCCESS\n"); printf("Procedural Asset test PASSED\n"); printf("AssetManager test PASSED\n"); return 0; }