1#include <userver/multi-index-lru/container.hpp>
5#include <gtest/gtest.h>
6#include <boost/multi_index/member.hpp>
12class LRUUsersTest :
public ::testing::Test {
14 void SetUp()
override {}
25 bool operator==(
const User& other)
const {
26 return id == other.id && email == other.email && name == other.name;
30 using UserCache = multi_index_lru::
Container<
32 boost::multi_index::indexed_by<
33 boost::multi_index::ordered_unique<
34 boost::multi_index::tag<IdTag>,
35 boost::multi_index::member<User,
int, &User::id>>,
36 boost::multi_index::ordered_unique<
37 boost::multi_index::tag<EmailTag>,
38 boost::multi_index::member<User, std::string, &User::email>>,
39 boost::multi_index::ordered_non_unique<
40 boost::multi_index::tag<NameTag>,
41 boost::multi_index::member<User, std::string, &User::name>>>>;
44TEST_F(LRUUsersTest, BasicOperations) {
48 cache.emplace(User{1,
"alice@test.com",
"Alice"});
49 cache.emplace(User{2,
"bob@test.com",
"Bob"});
50 cache.emplace(User{3,
"charlie@test.com",
"Charlie"});
52 EXPECT_EQ(cache.size(), 3);
55 auto by_id = cache.find<IdTag,
int>(1);
56 ASSERT_NE(by_id, cache.end<IdTag>());
57 EXPECT_EQ(by_id->name,
"Alice");
60 auto by_email = cache.find<EmailTag, std::string>(
"bob@test.com");
61 ASSERT_NE(by_email, cache.end<EmailTag>());
62 EXPECT_EQ(by_email->id, 2);
65 auto by_name = cache.find<NameTag, std::string>(
"Charlie");
66 ASSERT_NE(by_name, cache.end<NameTag>());
67 EXPECT_EQ(by_name->email,
"charlie@test.com");
70 auto it = cache.find<EmailTag, std::string>(
"alice@test.com");
71 EXPECT_NE(it, cache.end<EmailTag>());
74TEST_F(LRUUsersTest, LRUEviction) {
77 cache.emplace(User{1,
"alice@test.com",
"Alice"});
78 cache.emplace(User{2,
"bob@test.com",
"Bob"});
79 cache.emplace(User{3,
"charlie@test.com",
"Charlie"});
86 cache.emplace(User{4,
"david@test.com",
"David"});
88 EXPECT_FALSE((cache.contains<IdTag>(2)));
89 EXPECT_TRUE((cache.contains<IdTag>(1)));
90 EXPECT_TRUE((cache.contains<IdTag>(3)));
91 EXPECT_TRUE((cache.contains<IdTag>(4)));
94class ProductsTest :
public ::testing::Test {
104 bool operator==(
const Product& other)
const {
105 return sku == other.sku && name == other.name && price == other.price;
109 using ProductCache = multi_index_lru::
Container<
111 boost::multi_index::indexed_by<
112 boost::multi_index::ordered_unique<
113 boost::multi_index::tag<SkuTag>,
114 boost::multi_index::member<Product, std::string, &Product::sku>>,
115 boost::multi_index::ordered_unique<
116 boost::multi_index::tag<NameTag>,
117 boost::multi_index::member<Product, std::string, &Product::name>>>>;
120TEST_F(ProductsTest, BasicProductOperations) {
121 ProductCache cache(2);
123 cache.emplace(Product{
"A1",
"Laptop", 999.99});
124 cache.emplace(Product{
"A2",
"Mouse", 29.99});
126 auto laptop = cache.find<SkuTag, std::string>(
"A1");
127 ASSERT_NE(laptop, cache.end<SkuTag>());
128 EXPECT_EQ(laptop->name,
"Laptop");
131TEST_F(ProductsTest, ProductEviction) {
132 ProductCache cache(2);
134 cache.emplace(Product{
"A1",
"Laptop", 999.99});
135 cache.emplace(Product{
"A2",
"Mouse", 29.99});
138 cache.find<SkuTag>(
"A1");
139 cache.emplace(Product{
"A3",
"Keyboard", 79.99});
141 EXPECT_TRUE((cache.contains<SkuTag, std::string>(
"A1")));
142 EXPECT_TRUE((cache.contains<SkuTag, std::string>(
"A3")));
143 EXPECT_FALSE((cache.contains<SkuTag, std::string>(
"A2")));
145 EXPECT_NE(cache.find<NameTag>(
"Keyboard"), cache.end<NameTag>());
146 EXPECT_EQ(cache.find<NameTag>(
"Mouse"), cache.end<NameTag>());