197 lines
6.7 KiB
C++
197 lines
6.7 KiB
C++
#include <iostream>
|
|
#include <cassert>
|
|
#include <vector>
|
|
#include <filesystem>
|
|
#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<uint8_t> data(size);
|
|
file.read(reinterpret_cast<char*>(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<unsigned int>(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<int32_t>("myInt", 42);
|
|
table.set<float>("myFloat", 3.14f);
|
|
table.set<std::string>("myString", "Hello, World!");
|
|
|
|
// Verify basic values
|
|
assert(table.get<int32_t>("myInt") == 42);
|
|
assert(table.get<float>("myFloat") == 3.14f);
|
|
assert(table.get<std::string>("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<int32_t> testArray = {10, 20, 30, 40, 50};
|
|
table.set<std::vector<int32_t>>("myArray", testArray);
|
|
|
|
auto retrievedArray = table.get<std::vector<int32_t>>("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<int32_t>("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<int32_t>("key1", 100);
|
|
table.set<int32_t>("key2", 200);
|
|
table.set<int32_t>("key3", 300);
|
|
table.set<std::string>("str1", "First");
|
|
table.set<std::string>("str2", "Second");
|
|
|
|
// Verify all keys are accessible
|
|
assert(table.get<int32_t>("key1") == 100);
|
|
assert(table.get<int32_t>("key2") == 200);
|
|
assert(table.get<int32_t>("key3") == 300);
|
|
assert(table.get<std::string>("str1") == "First");
|
|
assert(table.get<std::string>("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<int32_t>("key2");
|
|
assert(false && "Should have thrown exception");
|
|
} catch (const std::runtime_error&) {
|
|
// Expected
|
|
}
|
|
|
|
// Verify other keys still work
|
|
assert(table.get<int32_t>("key1") == 100);
|
|
assert(table.get<int32_t>("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<int32_t>("temp1", 1000);
|
|
table.set<int32_t>("temp2", 2000);
|
|
table.set<int32_t>("temp3", 3000);
|
|
|
|
table.remove("temp1");
|
|
table.remove("temp2");
|
|
table.remove("temp3");
|
|
|
|
// Test truncation
|
|
table.truncate();
|
|
|
|
// Verify original data still accessible
|
|
assert(table.get<int32_t>("myInt") == 42);
|
|
assert(table.get<std::string>("myString") == "Hello, World!");
|
|
assert(table.get<int32_t>("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;
|
|
}
|
|
} |