Files
SweepStore/cpp/parity_test.cpp

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;
}
}