/* SPDX-License-Identifier: GPL-3.0-or-later * Copyright © 2023-2024 The TokTok team. */ #include "sort.h" #include #include #include #include "sort_test_util.hh" namespace { TEST(MergeSort, BehavesLikeStdSort) { std::mt19937 rng; // INT_MAX-1 so later we have room to add 1 larger element if needed. std::uniform_int_distribution dist{ std::numeric_limits::min(), std::numeric_limits::max() - 1}; constexpr auto int_funcs = sort_funcs(); // Test with int arrays. for (uint32_t i = 1; i < 500; ++i) { std::vector vec(i); std::generate(std::begin(vec), std::end(vec), [&]() { return dist(rng); }); auto sorted = vec; std::sort(sorted.begin(), sorted.end(), std::less()); // If vec was accidentally sorted, add another larger element that almost definitely makes // it not sorted. if (vec == sorted) { int const largest = *std::prev(sorted.end()) + 1; sorted.push_back(largest); vec.insert(vec.begin(), largest); } ASSERT_NE(vec, sorted); // Just pass some arbitrary "self" to make sure the callbacks pass it through. ASSERT_TRUE(merge_sort(vec.data(), vec.size(), &i, &int_funcs)); ASSERT_EQ(vec, sorted); } } TEST(MergeSort, WorksWithNonTrivialTypes) { std::mt19937 rng; std::uniform_int_distribution dist{ std::numeric_limits::min(), std::numeric_limits::max()}; constexpr auto string_funcs = sort_funcs(); // Test with std::string arrays. for (uint32_t i = 1; i < 500; ++i) { std::vector vec(i); std::generate(std::begin(vec), std::end(vec), [&]() { return std::to_string(dist(rng)); }); auto sorted = vec; std::sort(sorted.begin(), sorted.end(), std::less()); // If vec was accidentally sorted, add another larger element that almost definitely makes // it not sorted. if (vec == sorted) { std::string const largest = "larger than largest int"; sorted.push_back(largest); vec.insert(vec.begin(), largest); } ASSERT_NE(vec, sorted); // Just pass some arbitrary "self" to make sure the callbacks pass it through. ASSERT_TRUE(merge_sort(vec.data(), vec.size(), &i, &string_funcs)); ASSERT_EQ(vec, sorted); } } } // namespace