| 1618 | } |
| 1619 | |
| 1620 | static void test_hasher(testing & t) { |
| 1621 | static const std::vector<std::pair<size_t, size_t>> chunk_sizes = { |
| 1622 | {1, 2}, |
| 1623 | {1, 16}, |
| 1624 | {8, 1}, |
| 1625 | {1, 1024}, |
| 1626 | {5, 512}, |
| 1627 | {16, 256}, |
| 1628 | {45, 122}, |
| 1629 | {70, 634}, |
| 1630 | }; |
| 1631 | |
| 1632 | static auto random_bytes = [](size_t length) -> std::string { |
| 1633 | std::string data; |
| 1634 | data.resize(length); |
| 1635 | for (size_t i = 0; i < length; ++i) { |
| 1636 | data[i] = static_cast<char>(rand() % 256); |
| 1637 | } |
| 1638 | return data; |
| 1639 | }; |
| 1640 | |
| 1641 | t.test("state unchanged with empty input", [](testing & t) { |
| 1642 | jinja::hasher hasher; |
| 1643 | hasher.update("some data"); |
| 1644 | size_t initial_state = hasher.digest(); |
| 1645 | hasher.update("", 0); |
| 1646 | size_t final_state = hasher.digest(); |
| 1647 | t.assert_true("Hasher state should remain unchanged", initial_state == final_state); |
| 1648 | }); |
| 1649 | |
| 1650 | t.test("different inputs produce different hashes", [](testing & t) { |
| 1651 | jinja::hasher hasher1; |
| 1652 | hasher1.update("data one"); |
| 1653 | size_t hash1 = hasher1.digest(); |
| 1654 | |
| 1655 | jinja::hasher hasher2; |
| 1656 | hasher2.update("data two"); |
| 1657 | size_t hash2 = hasher2.digest(); |
| 1658 | |
| 1659 | t.assert_true("Different inputs should produce different hashes", hash1 != hash2); |
| 1660 | }); |
| 1661 | |
| 1662 | t.test("same inputs produce same hashes", [](testing & t) { |
| 1663 | jinja::hasher hasher1; |
| 1664 | hasher1.update("consistent data"); |
| 1665 | size_t hash1 = hasher1.digest(); |
| 1666 | |
| 1667 | jinja::hasher hasher2; |
| 1668 | hasher2.update("consistent data"); |
| 1669 | size_t hash2 = hasher2.digest(); |
| 1670 | |
| 1671 | t.assert_true("Same inputs should produce same hashes", hash1 == hash2); |
| 1672 | }); |
| 1673 | |
| 1674 | t.test("property: update(a ~ b) == update(a).update(b)", [](testing & t) { |
| 1675 | for (const auto & [size1, size2] : chunk_sizes) { |
| 1676 | std::string data1 = random_bytes(size1); |
| 1677 | std::string data2 = random_bytes(size2); |