Loading files
3d097a032This file is pinned to the selected release. Download the original to open it in your design tool.
// Copyright (c) 2024 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <NCollection_FlatMap.hxx>
#include <TCollection_AsciiString.hxx>
#include <gtest/gtest.h>
#include <algorithm>
#include <set>
//=================================================================================================
// NCollection_FlatMap Tests
//=================================================================================================
class NCollection_FlatMapTest : public testing::Test
{
protected:
void SetUp() override {}
void TearDown() override {}
};
TEST_F(NCollection_FlatMapTest, DefaultConstructor)
{
NCollection_FlatMap<int> aMap;
EXPECT_TRUE(aMap.IsEmpty());
EXPECT_EQ(0, aMap.Size());
}
TEST_F(NCollection_FlatMapTest, AddAndContains)
{
NCollection_FlatMap<int> aMap;
EXPECT_TRUE(aMap.Add(1)); // New key
EXPECT_TRUE(aMap.Add(2)); // New key
EXPECT_TRUE(aMap.Add(3)); // New key
EXPECT_FALSE(aMap.Add(1)); // Duplicate
EXPECT_EQ(3, aMap.Size());
EXPECT_TRUE(aMap.Contains(1));
EXPECT_TRUE(aMap.Contains(2));
EXPECT_TRUE(aMap.Contains(3));
EXPECT_FALSE(aMap.Contains(4));
}
TEST_F(NCollection_FlatMapTest, Remove)
{
NCollection_FlatMap<int> aMap;
aMap.Add(1);
aMap.Add(2);
aMap.Add(3);
EXPECT_TRUE(aMap.Remove(2));
EXPECT_EQ(2, aMap.Size());
EXPECT_FALSE(aMap.Contains(2));
EXPECT_FALSE(aMap.Remove(4)); // Non-existent
EXPECT_EQ(2, aMap.Size());
}
TEST_F(NCollection_FlatMapTest, Clear)
{
NCollection_FlatMap<int> aMap;
aMap.Add(1);
aMap.Add(2);
aMap.Clear();
EXPECT_TRUE(aMap.IsEmpty());
}
TEST_F(NCollection_FlatMapTest, CopyConstructor)
{
NCollection_FlatMap<int> aMap1;
aMap1.Add(1);
aMap1.Add(2);
aMap1.Add(3);
NCollection_FlatMap<int> aMap2(aMap1);
EXPECT_EQ(aMap1.Size(), aMap2.Size());
EXPECT_TRUE(aMap2.Contains(1));
EXPECT_TRUE(aMap2.Contains(2));
EXPECT_TRUE(aMap2.Contains(3));
}
TEST_F(NCollection_FlatMapTest, MoveConstructor)
{
NCollection_FlatMap<int> aMap1;
aMap1.Add(1);
aMap1.Add(2);
NCollection_FlatMap<int> aMap2(std::move(aMap1));
EXPECT_EQ(2, aMap2.Size());
EXPECT_TRUE(aMap1.IsEmpty());
}
TEST_F(NCollection_FlatMapTest, Iterator)
{
NCollection_FlatMap<int> aMap;
aMap.Add(10);
aMap.Add(20);
aMap.Add(30);
std::set<int> foundKeys;
NCollection_FlatMap<int>::Iterator it(aMap);
for (; it.More(); it.Next())
{
foundKeys.insert(it.Key());
}
EXPECT_EQ(3u, foundKeys.size());
EXPECT_TRUE(foundKeys.find(10) != foundKeys.end());
EXPECT_TRUE(foundKeys.find(20) != foundKeys.end());
EXPECT_TRUE(foundKeys.find(30) != foundKeys.end());
}
TEST_F(NCollection_FlatMapTest, STLIterators)
{
NCollection_FlatMap<int> aMap;
aMap.Add(10);
aMap.Add(20);
aMap.Add(30);
int aSum = 0;
for (const int aKey : aMap)
{
aSum += aKey;
}
EXPECT_EQ(60, aSum);
const NCollection_FlatMap<int>& aConstMap = aMap;
const auto anIt = std::find(aConstMap.cbegin(), aConstMap.cend(), 20);
ASSERT_NE(aConstMap.cend(), anIt);
EXPECT_EQ(20, *anIt);
}
TEST_F(NCollection_FlatMapTest, LargeDataSet)
{
const int NUM_ELEMENTS = 10000;
NCollection_FlatMap<int> aMap;
for (int i = 0; i < NUM_ELEMENTS; ++i)
{
aMap.Add(i);
}
EXPECT_EQ(NUM_ELEMENTS, aMap.Size());
for (int i = 0; i < NUM_ELEMENTS; ++i)
{
EXPECT_TRUE(aMap.Contains(i)) << "Key " << i << " not found";
}
}
TEST_F(NCollection_FlatMapTest, LongProbeSequence)
{
struct ConstantHasher
{
size_t operator()(int) const { return 0; }
bool operator()(int theKey1, int theKey2) const { return theKey1 == theKey2; }
};
constexpr int THE_NUM_ELEMENTS = 400;
NCollection_FlatMap<int, ConstantHasher> aMap;
for (int i = 0; i < THE_NUM_ELEMENTS; ++i)
{
EXPECT_TRUE(aMap.Add(i));
}
EXPECT_EQ(THE_NUM_ELEMENTS, aMap.Size());
for (int i = 0; i < THE_NUM_ELEMENTS; ++i)
{
EXPECT_TRUE(aMap.Contains(i)) << "Key " << i << " not found";
}
}
TEST_F(NCollection_FlatMapTest, StringKeys)
{
NCollection_FlatMap<TCollection_AsciiString> aMap;
aMap.Add("Hello");
aMap.Add("World");
aMap.Add("Test");
EXPECT_EQ(3, aMap.Size());
EXPECT_TRUE(aMap.Contains("Hello"));
EXPECT_TRUE(aMap.Contains("World"));
EXPECT_TRUE(aMap.Contains("Test"));
EXPECT_FALSE(aMap.Contains("NotFound"));
}
// Tests for Added method
TEST_F(NCollection_FlatMapTest, AddedNewKey)
{
NCollection_FlatMap<TCollection_AsciiString> aMap;
const TCollection_AsciiString& aRef = aMap.Added("Hello");
EXPECT_TRUE(aRef.IsEqual("Hello"));
EXPECT_EQ(1, aMap.Size());
}
TEST_F(NCollection_FlatMapTest, AddedExistingKey)
{
NCollection_FlatMap<TCollection_AsciiString> aMap;
aMap.Add("Hello");
const TCollection_AsciiString& aRef = aMap.Added("Hello");
EXPECT_TRUE(aRef.IsEqual("Hello"));
EXPECT_EQ(1, aMap.Size()); // Size unchanged
}
// Tests for Emplace method
TEST_F(NCollection_FlatMapTest, EmplaceNewKey)
{
NCollection_FlatMap<TCollection_AsciiString> aMap;
// Emplace with new key
EXPECT_TRUE(aMap.Emplace("Hello"));
EXPECT_EQ(1, aMap.Size());
EXPECT_TRUE(aMap.Contains("Hello"));
}
TEST_F(NCollection_FlatMapTest, EmplaceExistingKey)
{
NCollection_FlatMap<TCollection_AsciiString> aMap;
aMap.Add("Hello");
// Emplace on existing key - destroys and reconstructs
EXPECT_FALSE(aMap.Emplace("Hello"));
EXPECT_EQ(1, aMap.Size());
EXPECT_TRUE(aMap.Contains("Hello"));
}
// Tests for Emplaced method
TEST_F(NCollection_FlatMapTest, EmplacedNewKey)
{
NCollection_FlatMap<TCollection_AsciiString> aMap;
const TCollection_AsciiString& aRef = aMap.Emplaced("World");
EXPECT_TRUE(aRef.IsEqual("World"));
EXPECT_EQ(1, aMap.Size());
}
TEST_F(NCollection_FlatMapTest, EmplacedExistingKey)
{
NCollection_FlatMap<TCollection_AsciiString> aMap;
aMap.Add("World");
// Emplaced on existing - destroys and reconstructs
const TCollection_AsciiString& aRef = aMap.Emplaced("World");
EXPECT_TRUE(aRef.IsEqual("World"));
EXPECT_EQ(1, aMap.Size());
}
// Tests for Seek method
TEST_F(NCollection_FlatMapTest, SeekFound)
{
NCollection_FlatMap<int> aMap;
aMap.Add(10);
aMap.Add(20);
aMap.Add(30);
const int* pKey = aMap.Seek(10);
ASSERT_NE(nullptr, pKey);
EXPECT_EQ(10, *pKey);
pKey = aMap.Seek(30);
ASSERT_NE(nullptr, pKey);
EXPECT_EQ(30, *pKey);
}
TEST_F(NCollection_FlatMapTest, SeekNotFound)
{
NCollection_FlatMap<int> aMap;
aMap.Add(10);
const int* pKey = aMap.Seek(99);
EXPECT_EQ(nullptr, pKey);
// Seek on empty map
NCollection_FlatMap<int> anEmptyMap;
EXPECT_EQ(nullptr, anEmptyMap.Seek(10));
}
TEST_F(NCollection_FlatMapTest, ChangeSeekModify)
{
NCollection_FlatMap<TCollection_AsciiString> aMap;
aMap.Add("Hello");
aMap.Add("World");
TCollection_AsciiString* pKey = aMap.ChangeSeek("Hello");
ASSERT_NE(nullptr, pKey);
EXPECT_TRUE(pKey->IsEqual("Hello"));
}
TEST_F(NCollection_FlatMapTest, ChangeSeekNotFound)
{
NCollection_FlatMap<int> aMap;
aMap.Add(10);
int* pKey = aMap.ChangeSeek(99);
EXPECT_EQ(nullptr, pKey);
}
// Tests for hasher constructor
TEST_F(NCollection_FlatMapTest, HasherConstructorCopy)
{
// Custom hasher with state
struct StatefulHasher
{
int mySalt;
StatefulHasher(int theSalt = 0)
: mySalt(theSalt)
{
}
size_t operator()(int theKey) const { return std::hash<int>{}(theKey + mySalt); }
bool operator()(int theKey1, int theKey2) const { return theKey1 == theKey2; }
};
StatefulHasher aHasher(42);
NCollection_FlatMap<int, StatefulHasher> aMap(aHasher, 10);
aMap.Add(1);
aMap.Add(2);
aMap.Add(3);
EXPECT_EQ(3, aMap.Size());
EXPECT_TRUE(aMap.Contains(1));
EXPECT_TRUE(aMap.Contains(2));
EXPECT_TRUE(aMap.Contains(3));
// Verify hasher was copied
const StatefulHasher& aMapHasher = aMap.GetHasher();
EXPECT_EQ(42, aMapHasher.mySalt);
}
TEST_F(NCollection_FlatMapTest, HasherConstructorMove)
{
struct StatefulHasher
{
int mySalt;
StatefulHasher(int theSalt = 0)
: mySalt(theSalt)
{
}
size_t operator()(int theKey) const { return std::hash<int>{}(theKey + mySalt); }
bool operator()(int theKey1, int theKey2) const { return theKey1 == theKey2; }
};
NCollection_FlatMap<int, StatefulHasher> aMap(StatefulHasher(99), 10);
aMap.Add(10);
aMap.Add(20);
EXPECT_EQ(2, aMap.Size());
EXPECT_EQ(99, aMap.GetHasher().mySalt);
}
TEST_F(NCollection_FlatMapTest, CopyConstructorPreservesHasher)
{
struct StatefulHasher
{
int mySalt;
StatefulHasher(int theSalt = 0)
: mySalt(theSalt)
{
}
size_t operator()(int theKey) const { return std::hash<int>{}(theKey + mySalt); }
bool operator()(int theKey1, int theKey2) const { return theKey1 == theKey2; }
};
NCollection_FlatMap<int, StatefulHasher> aMap1(StatefulHasher(123), 10);
aMap1.Add(1);
aMap1.Add(2);
// Copy construct
NCollection_FlatMap<int, StatefulHasher> aMap2(aMap1);
EXPECT_EQ(123, aMap2.GetHasher().mySalt);
EXPECT_EQ(2, aMap2.Size());
EXPECT_TRUE(aMap2.Contains(1));
EXPECT_TRUE(aMap2.Contains(2));
}
// Test iterator equality
TEST_F(NCollection_FlatMapTest, IteratorEquality)
{
NCollection_FlatMap<int> aMap;
aMap.Add(1);
aMap.Add(2);
aMap.Add(3);
// Test Iterator::IsEqual method directly
NCollection_FlatMap<int>::Iterator anIt1(aMap);
NCollection_FlatMap<int>::Iterator anIt2(aMap);
NCollection_FlatMap<int>::Iterator anEndIt;
// Two iterators at beginning should be equal
EXPECT_TRUE(anIt1.IsEqual(anIt2));
// Iterator at beginning should not equal end iterator
EXPECT_FALSE(anIt1.IsEqual(anEndIt));
// Two iterators at different positions must NOT be equal
anIt2.Next();
EXPECT_FALSE(anIt1.IsEqual(anIt2));
// Iterators at same position should be equal
NCollection_FlatMap<int>::Iterator anIt3(aMap);
anIt3.Next();
EXPECT_TRUE(anIt2.IsEqual(anIt3));
// End iterators should be equal
NCollection_FlatMap<int>::Iterator anEndIt2;
EXPECT_TRUE(anEndIt.IsEqual(anEndIt2));
}