fwt_software/tests/test_hash.cpp

48 lines
1.7 KiB
C++

#include <doctest/doctest.h>
#include "fgc/Hash.h"
#include <filesystem>
#include <fstream>
#include <string>
#include <unistd.h>
using namespace fgc;
namespace fs = std::filesystem;
TEST_CASE("fnv1a64 matches the reference vectors") {
// The published FNV-1a 64 test vectors: if these drift, a stored digest from
// an older build would silently stop matching.
CHECK(fnv1a64("") == 0xcbf29ce484222325ULL);
CHECK(fnv1a64("a") == 0xaf63dc4c8601ec8cULL);
CHECK(fnv1a64("foobar") == 0x85944171f73967e8ULL);
}
TEST_CASE("fnv1a64 separates inputs that differ by one bit") {
CHECK(fnv1a64("standard") != fnv1a64("standarD"));
CHECK(fnv1a64("AcquisitionFrameRate = 10") != fnv1a64("AcquisitionFrameRate = 11"));
// Order matters: two files with the same bytes rearranged are different files.
CHECK(fnv1a64("ab") != fnv1a64("ba"));
}
TEST_CASE("hashLabel is prefixed and fixed width") {
// The prefix exists so a digest can never be misread if the algorithm changes.
CHECK(hashLabel(0) == "fnv1a64:0000000000000000");
CHECK(hashLabel(0xcbf29ce484222325ULL) == "fnv1a64:cbf29ce484222325");
CHECK(hashLabel(fnv1a64("")).size() == 8 + 16);
}
TEST_CASE("fnv1a64File hashes contents and throws on a missing file") {
const fs::path p = fs::temp_directory_path() /
("fgc_hash_" + std::to_string(::getpid()) + ".bin");
{ std::ofstream f(p, std::ios::binary); f << "foobar"; }
CHECK(fnv1a64File(p.string()) == fnv1a64("foobar"));
// A missing file must NOT read as an unchanged one - the caller uses this to
// decide whether to regenerate.
fs::remove(p);
CHECK_THROWS(fnv1a64File(p.string()));
}