summaryrefslogtreecommitdiff
path: root/src/tests/test_assets.cc
blob: 86b4ba447c3a5fa39289a652ec59f61de6698d18 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
// 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 <assert.h>
#include <stdio.h>
#include <string.h>

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);
  // Expect 256x256 RGBA8 + 8 byte header
  assert(proc_size == 256 * 256 * 4 + 8);

  // Verify first few bytes of DATA (skip header)
  // Header is 8 bytes
  const uint8_t* pixel_data_1 = proc_data_1 + 8;
  bool non_zero_data = false;
  for (size_t i = 0; i < 16; ++i) { // Check first 16 bytes of pixels
    if (pixel_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;
  const uint8_t* pixel_data_2 = proc_data_2 + 8;
  for (size_t i = 0; i < 16; ++i) {
    if (pixel_data_2[i] != 0) {
      non_zero_data = true;
      break;
    }
  }
  assert(non_zero_data);
  printf("Procedural asset DropAsset and re-generation test: SUCCESS\n");

  // Test Texture Asset (TGA loading)
  printf("\nRunning Texture Asset test...\n");
  TextureAsset tex = GetTextureAsset(AssetId::ASSET_TEST_IMAGE);
  assert(tex.pixels != nullptr);
  assert(tex.width == 2);
  assert(tex.height == 2);

  // Verify pixels (Expected RGBA)
  // Pixel 0: Red (255, 0, 0, 255)
  assert(tex.pixels[0] == 255 && tex.pixels[1] == 0 && tex.pixels[2] == 0 &&
         tex.pixels[3] == 255);
  // Pixel 1: Green (0, 255, 0, 255)
  assert(tex.pixels[4] == 0 && tex.pixels[5] == 255 && tex.pixels[6] == 0 &&
         tex.pixels[7] == 255);
  // Pixel 2: Blue (0, 0, 255, 255)
  assert(tex.pixels[8] == 0 && tex.pixels[9] == 0 && tex.pixels[10] == 255 &&
         tex.pixels[11] == 255);
  // Pixel 3: White (255, 255, 255, 255)
  assert(tex.pixels[12] == 255 && tex.pixels[13] == 255 &&
         tex.pixels[14] == 255 && tex.pixels[15] == 255);

  printf("Texture Asset content verification: 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;
}