#include "net/disk_cache/sql/indexed_pair_set.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
using testing::UnorderedElementsAre;
namespace disk_cache {
class IndexedPairSetTest : public testing::Test {
protected:
IndexedPairSet<int64_t, int64_t> set_;
};
TEST_F(IndexedPairSetTest, EmptyInitially) {
EXPECT_TRUE(set_.empty());
EXPECT_EQ(0u, set_.size());
}
TEST_F(IndexedPairSetTest, InsertAndFindSingleValue) {
EXPECT_TRUE(set_.Insert(10, 100));
EXPECT_FALSE(set_.empty());
EXPECT_EQ(1u, set_.size());
EXPECT_TRUE(set_.Contains(10));
std::vector<int64_t> values = set_.Find(10);
ASSERT_EQ(1u, values.size());
EXPECT_EQ(100, values[0]);
}
TEST_F(IndexedPairSetTest, InsertDuplicatePair) {
EXPECT_TRUE(set_.Insert(10, 100));
EXPECT_EQ(1u, set_.size());
EXPECT_FALSE(set_.Insert(10, 100));
EXPECT_EQ(1u, set_.size());
EXPECT_TRUE(set_.Insert(10, 200));
EXPECT_EQ(2u, set_.size());
EXPECT_FALSE(set_.Insert(10, 200));
EXPECT_EQ(2u, set_.size());
}
TEST_F(IndexedPairSetTest, InsertDuplicateKey) {
EXPECT_TRUE(set_.Insert(10, 100));
EXPECT_TRUE(set_.Insert(10, 200));
EXPECT_EQ(2u, set_.size());
EXPECT_THAT(set_.Find(10), UnorderedElementsAre(100, 200));
EXPECT_TRUE(set_.Insert(10, 300));
EXPECT_EQ(3u, set_.size());
EXPECT_THAT(set_.Find(10), UnorderedElementsAre(100, 200, 300));
}
TEST_F(IndexedPairSetTest, Contains) {
EXPECT_TRUE(set_.Insert(10, 100));
EXPECT_TRUE(set_.Insert(20, 200));
EXPECT_TRUE(set_.Insert(10, 300));
EXPECT_TRUE(set_.Contains(10));
EXPECT_TRUE(set_.Contains(20));
EXPECT_FALSE(set_.Contains(99));
}
TEST_F(IndexedPairSetTest, Clear) {
EXPECT_TRUE(set_.Insert(10, 100));
EXPECT_TRUE(set_.Insert(20, 200));
EXPECT_FALSE(set_.empty());
set_.Clear();
EXPECT_TRUE(set_.empty());
EXPECT_EQ(0u, set_.size());
EXPECT_FALSE(set_.Contains(10));
EXPECT_TRUE(set_.Find(20).empty());
}
TEST_F(IndexedPairSetTest, RemoveNonExistent) {
EXPECT_TRUE(set_.Insert(10, 100));
EXPECT_FALSE(set_.Remove(99, 999));
EXPECT_FALSE(set_.Remove(10, 999));
EXPECT_EQ(1u, set_.size());
}
TEST_F(IndexedPairSetTest, RemoveSingleValue) {
EXPECT_TRUE(set_.Insert(10, 100));
EXPECT_TRUE(set_.Remove(10, 100));
EXPECT_EQ(0u, set_.size());
EXPECT_TRUE(set_.empty());
EXPECT_FALSE(set_.Contains(10));
EXPECT_TRUE(set_.Find(10).empty());
}
TEST_F(IndexedPairSetTest, RemoveMultipleValuesForKey) {
EXPECT_TRUE(set_.Insert(10, 100));
EXPECT_TRUE(set_.Insert(10, 200));
EXPECT_TRUE(set_.Insert(10, 300));
EXPECT_EQ(3u, set_.size());
EXPECT_TRUE(set_.Remove(10, 200));
EXPECT_EQ(2u, set_.size());
EXPECT_TRUE(set_.Contains(10));
EXPECT_THAT(set_.Find(10), UnorderedElementsAre(100, 300));
EXPECT_TRUE(set_.Remove(10, 100));
EXPECT_EQ(1u, set_.size());
EXPECT_THAT(set_.Find(10), UnorderedElementsAre(300));
EXPECT_TRUE(set_.Remove(10, 300));
EXPECT_EQ(0u, set_.size());
EXPECT_FALSE(set_.Contains(10));
}
TEST_F(IndexedPairSetTest, RemovePromotesFromAdditionalMap) {
set_.Insert(10, 100);
set_.Insert(10, 200);
set_.Insert(10, 300);
EXPECT_TRUE(set_.Remove(10, 100));
EXPECT_EQ(2u, set_.size());
EXPECT_THAT(set_.Find(10), UnorderedElementsAre(200, 300));
}
TEST_F(IndexedPairSetTest, RemoveLastFromAdditionalMapEmptiesSet) {
set_.Insert(10, 100);
set_.Insert(10, 200);
EXPECT_TRUE(set_.Remove(10, 200));
EXPECT_EQ(1u, set_.size());
EXPECT_THAT(set_.Find(10), UnorderedElementsAre(100));
EXPECT_TRUE(set_.Insert(10, 300));
EXPECT_EQ(2u, set_.size());
EXPECT_THAT(set_.Find(10), UnorderedElementsAre(100, 300));
}
TEST_F(IndexedPairSetTest, RemoveFromAdditionalMapThenInsertNewValue) {
EXPECT_TRUE(set_.Insert(10, 100));
EXPECT_TRUE(set_.Insert(10, 200));
EXPECT_TRUE(set_.Insert(20, 300));
EXPECT_EQ(3u, set_.size());
EXPECT_TRUE(set_.Remove(10, 200));
EXPECT_EQ(2u, set_.size());
EXPECT_TRUE(set_.Insert(10, 400));
EXPECT_EQ(3u, set_.size());
EXPECT_THAT(set_.Find(10), UnorderedElementsAre(100, 400));
}
TEST_F(IndexedPairSetTest, MoveConstructor) {
set_.Insert(10, 100);
set_.Insert(20, 200);
EXPECT_EQ(2u, set_.size());
IndexedPairSet<int64_t, int64_t> new_set(std::move(set_));
EXPECT_EQ(0u, set_.size());
EXPECT_TRUE(set_.empty());
EXPECT_EQ(2u, new_set.size());
EXPECT_TRUE(new_set.Contains(10));
EXPECT_TRUE(new_set.Contains(20));
EXPECT_THAT(new_set.Find(10), UnorderedElementsAre(100));
EXPECT_THAT(new_set.Find(20), UnorderedElementsAre(200));
}
TEST_F(IndexedPairSetTest, MoveAssignment) {
set_.Insert(10, 100);
set_.Insert(20, 200);
IndexedPairSet<int64_t, int64_t> new_set;
new_set.Insert(30, 300);
new_set = std::move(set_);
EXPECT_EQ(0u, set_.size());
EXPECT_TRUE(set_.empty());
EXPECT_EQ(2u, new_set.size());
EXPECT_TRUE(new_set.Contains(10));
EXPECT_TRUE(new_set.Contains(20));
EXPECT_THAT(new_set.Find(10), UnorderedElementsAre(100));
EXPECT_THAT(new_set.Find(20), UnorderedElementsAre(200));
EXPECT_FALSE(new_set.Contains(30));
}
TEST_F(IndexedPairSetTest, MoveAssignmentSelf) {
set_.Insert(10, 100);
set_.Insert(20, 200);
EXPECT_EQ(2u, set_.size());
set_ = std::move(set_);
EXPECT_EQ(2u, set_.size());
EXPECT_TRUE(set_.Contains(10));
EXPECT_TRUE(set_.Contains(20));
EXPECT_THAT(set_.Find(10), UnorderedElementsAre(100));
EXPECT_THAT(set_.Find(20), UnorderedElementsAre(200));
}
TEST_F(IndexedPairSetTest, RemoveLastValueFromSecondaryMapRemovesKey) {
set_.Insert(10, 100);
set_.Insert(10, 200);
EXPECT_TRUE(set_.HasMultipleValues(10));
EXPECT_TRUE(set_.Remove(10, 200));
EXPECT_EQ(1u, set_.size());
EXPECT_THAT(set_.Find(10), UnorderedElementsAre(100));
EXPECT_FALSE(set_.HasMultipleValues(10));
}
TEST_F(IndexedPairSetTest, RemoveAndPromoteWithEmptyingSecondaryMapRemovesKey) {
set_.Insert(10, 100);
set_.Insert(10, 200);
EXPECT_TRUE(set_.HasMultipleValues(10));
EXPECT_TRUE(set_.Remove(10, 100));
EXPECT_EQ(1u, set_.size());
EXPECT_THAT(set_.Find(10), UnorderedElementsAre(200));
EXPECT_FALSE(set_.HasMultipleValues(10));
}
TEST_F(IndexedPairSetTest, TryGetSingleValue) {
EXPECT_EQ(set_.TryGetSingleValue(10), std::nullopt);
EXPECT_TRUE(set_.Insert(10, 100));
EXPECT_THAT(set_.TryGetSingleValue(10), 100);
EXPECT_TRUE(set_.Insert(10, 200));
EXPECT_EQ(set_.TryGetSingleValue(10), std::nullopt);
EXPECT_TRUE(set_.Remove(10, 200));
EXPECT_THAT(set_.TryGetSingleValue(10), 100);
EXPECT_TRUE(set_.Remove(10, 100));
EXPECT_EQ(set_.TryGetSingleValue(10), std::nullopt);
}
}