#include #include #include #include #include "binary_table.h" void printBinaryDump(const std::string& filename) { std::ifstream file(filename, std::ios::binary); if (!file) { std::cout << "Cannot open file for dump" << std::endl; return; } file.seekg(0, std::ios::end); size_t size = file.tellg(); file.seekg(0, std::ios::beg); std::vector data(size); file.read(reinterpret_cast(data.data()), size); file.close(); std::cout << "\n=== Binary Dump of " << filename << " (" << size << " bytes) ===" << std::endl; for (size_t i = 0; i < data.size(); i += 16) { printf("0x%04X | ", static_cast(i)); // Hex bytes for (int j = 0; j < 16; j++) { if (i + j < data.size()) { printf("%02X ", data[i + j]); } else { printf(" "); } } printf(" | "); // ASCII representation for (int j = 0; j < 16; j++) { if (i + j < data.size()) { uint8_t byte = data[i + j]; printf("%c", (byte >= 32 && byte <= 126) ? byte : '.'); } } printf("\n"); } std::cout << "=========================" << std::endl; } // Test equivalent to Dart's main() function int main() { std::cout << "๐Ÿงช C++ Binary Table Parity Test (matching Dart behavior)" << std::endl; std::cout << "=========================================================" << std::endl; const std::string filename = "cpp_parity_test.bin"; // Clean up any existing file std::filesystem::remove(filename); try { bt::BinaryTable table(filename); table.initialize(); std::cout << "\n1. Testing basic data types..." << std::endl; // Set basic values table.set("myInt", 42); table.set("myFloat", 3.14f); table.set("myString", "Hello, World!"); // Verify basic values assert(table.get("myInt") == 42); assert(table.get("myFloat") == 3.14f); assert(table.get("myString") == "Hello, World!"); std::cout << "โœ… Basic data types work correctly" << std::endl; std::cout << "\n2. Testing array operations..." << std::endl; // Test array creation and access std::vector testArray = {10, 20, 30, 40, 50}; table.set>("myArray", testArray); auto retrievedArray = table.get>("myArray"); assert(retrievedArray.size() == 5); for (size_t i = 0; i < retrievedArray.size(); i++) { assert(retrievedArray[i] == testArray[i]); } std::cout << "โœ… Array storage and retrieval work correctly" << std::endl; // Test uniform array operations auto uniformArray = table.getArray("myArray"); assert(uniformArray.length() == 5); assert(uniformArray[0] == 10); assert(uniformArray[4] == 50); // Test array modification uniformArray.set(2, 999); assert(uniformArray[2] == 999); // Test array extension uniformArray.add(60); assert(uniformArray.length() == 6); assert(uniformArray[5] == 60); std::cout << "โœ… Uniform array operations work correctly" << std::endl; std::cout << "\n3. Testing multi-key operations (previously causing corruption)..." << std::endl; // Add multiple keys to test address table stability table.set("key1", 100); table.set("key2", 200); table.set("key3", 300); table.set("str1", "First"); table.set("str2", "Second"); // Verify all keys are accessible assert(table.get("key1") == 100); assert(table.get("key2") == 200); assert(table.get("key3") == 300); assert(table.get("str1") == "First"); assert(table.get("str2") == "Second"); std::cout << "โœ… Multi-key operations work without corruption" << std::endl; std::cout << "\n4. Testing remove operations..." << std::endl; // Test removal table.remove("key2"); // Verify removed key is gone try { table.get("key2"); assert(false && "Should have thrown exception"); } catch (const std::runtime_error&) { // Expected } // Verify other keys still work assert(table.get("key1") == 100); assert(table.get("key3") == 300); std::cout << "โœ… Remove operations work correctly" << std::endl; std::cout << "\n5. Testing fetchSublist functionality..." << std::endl; auto sublist = uniformArray.fetchSublist(1, 4); assert(sublist.size() == 3); assert(sublist[0] == 20); // myArray[1] assert(sublist[1] == 999); // myArray[2] (modified) assert(sublist[2] == 40); // myArray[3] std::cout << "โœ… fetchSublist works correctly" << std::endl; std::cout << "\n6. Testing free list and truncation operations..." << std::endl; // Create some data, then remove it to test free list table.set("temp1", 1000); table.set("temp2", 2000); table.set("temp3", 3000); table.remove("temp1"); table.remove("temp2"); table.remove("temp3"); // Test truncation table.truncate(); // Verify original data still accessible assert(table.get("myInt") == 42); assert(table.get("myString") == "Hello, World!"); assert(table.get("key1") == 100); std::cout << "โœ… Free list and truncation work correctly" << std::endl; std::cout << "\n๐ŸŽ‰ ALL TESTS PASSED! C++ implementation has Dart parity!" << std::endl; // Print final file dump for verification printBinaryDump(filename); // Clean up std::filesystem::remove(filename); return 0; } catch (const std::exception& e) { std::cout << "โŒ Test failed: " << e.what() << std::endl; // Print file dump for debugging printBinaryDump(filename); std::filesystem::remove(filename); return 1; } }