/******************************************************************************** * ReactPhysics3D physics library, http://www.reactphysics3d.com * * Copyright (c) 2010-2016 Daniel Chappuis * ********************************************************************************* * * * This software is provided 'as-is', without any express or implied warranty. * * In no event will the authors be held liable for any damages arising from the * * use of this software. * * * * Permission is granted to anyone to use this software for any purpose, * * including commercial applications, and to alter it and redistribute it * * freely, subject to the following restrictions: * * * * 1. The origin of this software must not be misrepresented; you must not claim * * that you wrote the original software. If you use this software in a * * product, an acknowledgment in the product documentation would be * * appreciated but is not required. * * * * 2. Altered source versions must be plainly marked as such, and must not be * * misrepresented as being the original software. * * * * 3. This notice may not be removed or altered from any source distribution. * * * ********************************************************************************/ #ifndef TEST_MAP_H #define TEST_MAP_H // Libraries #include "Test.h" #include "containers/Map.h" #include "memory/DefaultAllocator.h" // Key to test map with always same hash values namespace reactphysics3d { struct TestKey { int key; TestKey(int k) :key(k) {} bool operator==(const TestKey& testKey) const { return key == testKey.key; } }; } // Hash function for struct VerticesPair namespace std { template <> struct hash { size_t operator()(const reactphysics3d::TestKey& key) const { return 1; } }; } /// Reactphysics3D namespace namespace reactphysics3d { // Class TestMap /** * Unit test for the Map class */ class TestMap : public Test { private : // ---------- Atributes ---------- // DefaultAllocator mAllocator; public : // ---------- Methods ---------- // /// Constructor TestMap(const std::string& name) : Test(name) { } /// Run the tests void run() { testConstructors(); testReserve(); testAddRemoveClear(); testContainsKey(); testFind(); testIndexing(); testEquality(); testAssignment(); testIterators(); } void testConstructors() { // ----- Constructors ----- // Map map1(mAllocator); rp3d_test(map1.capacity() == 0); rp3d_test(map1.size() == 0); Map map2(mAllocator, 100); rp3d_test(map2.capacity() >= 100); rp3d_test(map2.size() == 0); // ----- Copy Constructors ----- // Map map3(map1); rp3d_test(map3.capacity() == map1.capacity()); rp3d_test(map3.size() == map1.size()); Map map4(mAllocator); map4.add(Pair(1, 10)); map4.add(Pair(2, 20)); map4.add(Pair(3, 30)); rp3d_test(map4.capacity() >= 3); rp3d_test(map4.size() == 3); Map map5(map4); rp3d_test(map5.capacity() == map4.capacity()); rp3d_test(map5.size() == map4.size()); rp3d_test(map5[1] == 10); rp3d_test(map5[2] == 20); rp3d_test(map5[3] == 30); } void testReserve() { Map map1(mAllocator); map1.reserve(15); rp3d_test(map1.capacity() >= 15); map1.add(Pair(1, "test1")); map1.add(Pair(2, "test2")); rp3d_test(map1.capacity() >= 15); map1.reserve(10); rp3d_test(map1.capacity() >= 15); map1.reserve(100); rp3d_test(map1.capacity() >= 100); rp3d_test(map1[1] == "test1"); rp3d_test(map1[2] == "test2"); } void testAddRemoveClear() { // ----- Test add() ----- // Map map1(mAllocator); map1.add(Pair(1, 10)); map1.add(Pair(8, 80)); map1.add(Pair(13, 130)); rp3d_test(map1[1] == 10); rp3d_test(map1[8] == 80); rp3d_test(map1[13] == 130); rp3d_test(map1.size() == 3); Map map2(mAllocator, 15); for (int i = 0; i < 1000000; i++) { map2.add(Pair(i, i * 100)); } bool isValid = true; for (int i = 0; i < 1000000; i++) { if (map2[i] != i * 100) isValid = false; } rp3d_test(isValid); map1.remove(1); map1.add(Pair(1, 10)); rp3d_test(map1.size() == 3); rp3d_test(map1[1] == 10); map1.add(Pair(56, 34)); rp3d_test(map1[56] == 34); rp3d_test(map1.size() == 4); map1.add(Pair(56, 13), true); rp3d_test(map1[56] == 13); rp3d_test(map1.size() == 4); // ----- Test remove() ----- // map1.remove(1); rp3d_test(!map1.containsKey(1)); rp3d_test(map1.containsKey(8)); rp3d_test(map1.containsKey(13)); rp3d_test(map1.size() == 3); map1.remove(13); rp3d_test(map1.containsKey(8)); rp3d_test(!map1.containsKey(13)); rp3d_test(map1.size() == 2); map1.remove(8); rp3d_test(!map1.containsKey(8)); rp3d_test(map1.size() == 1); auto it = map1.remove(56); rp3d_test(!map1.containsKey(56)); rp3d_test(map1.size() == 0); rp3d_test(it == map1.end()); isValid = true; for (int i = 0; i < 1000000; i++) { map2.remove(i); } for (int i = 0; i < 1000000; i++) { if (map2.containsKey(i)) isValid = false; } rp3d_test(isValid); rp3d_test(map2.size() == 0); Map map3(mAllocator); for (int i=0; i < 1000000; i++) { map3.add(Pair(i, i * 10)); map3.remove(i); } map3.add(Pair(1, 10)); map3.add(Pair(2, 20)); map3.add(Pair(3, 30)); rp3d_test(map3.size() == 3); it = map3.begin(); map3.remove(it++); rp3d_test(!map3.containsKey(1)); rp3d_test(map3.size() == 2); rp3d_test(it->second == 20); map3.add(Pair(56, 32)); map3.add(Pair(23, 89)); for (it = map3.begin(); it != map3.end();) { it = map3.remove(it); } rp3d_test(map3.size() == 0); // ----- Test clear() ----- // Map map4(mAllocator); map4.add(Pair(2, 20)); map4.add(Pair(4, 40)); map4.add(Pair(6, 60)); map4.clear(); rp3d_test(map4.size() == 0); map4.add(Pair(2, 20)); rp3d_test(map4.size() == 1); rp3d_test(map4[2] == 20); map4.clear(); rp3d_test(map4.size() == 0); Map map5(mAllocator); map5.clear(); rp3d_test(map5.size() == 0); // ----- Test map with always same hash value for keys ----- // Map map6(mAllocator); for (int i=0; i < 1000; i++) { map6.add(Pair(TestKey(i), i)); } bool isTestValid = true; for (int i=0; i < 1000; i++) { if (map6[TestKey(i)] != i) { isTestValid = false; } } rp3d_test(isTestValid); for (int i=0; i < 1000; i++) { map6.remove(TestKey(i)); } rp3d_test(map6.size() == 0); } void testContainsKey() { Map map1(mAllocator); rp3d_test(!map1.containsKey(2)); rp3d_test(!map1.containsKey(4)); rp3d_test(!map1.containsKey(6)); map1.add(Pair(2, 20)); map1.add(Pair(4, 40)); map1.add(Pair(6, 60)); rp3d_test(map1.containsKey(2)); rp3d_test(map1.containsKey(4)); rp3d_test(map1.containsKey(6)); map1.remove(4); rp3d_test(!map1.containsKey(4)); rp3d_test(map1.containsKey(2)); rp3d_test(map1.containsKey(6)); map1.clear(); rp3d_test(!map1.containsKey(2)); rp3d_test(!map1.containsKey(6)); } void testIndexing() { Map map1(mAllocator); map1.add(Pair(2, 20)); map1.add(Pair(4, 40)); map1.add(Pair(6, 60)); rp3d_test(map1[2] == 20); rp3d_test(map1[4] == 40); rp3d_test(map1[6] == 60); map1[2] = 10; map1[4] = 20; map1[6] = 30; rp3d_test(map1[2] == 10); rp3d_test(map1[4] == 20); rp3d_test(map1[6] == 30); } void testFind() { Map map1(mAllocator); map1.add(Pair(2, 20)); map1.add(Pair(4, 40)); map1.add(Pair(6, 60)); rp3d_test(map1.find(2)->second == 20); rp3d_test(map1.find(4)->second == 40); rp3d_test(map1.find(6)->second == 60); rp3d_test(map1.find(45) == map1.end()); map1[2] = 10; map1[4] = 20; map1[6] = 30; rp3d_test(map1.find(2)->second == 10); rp3d_test(map1.find(4)->second == 20); rp3d_test(map1.find(6)->second == 30); } void testEquality() { Map map1(mAllocator, 10); Map map2(mAllocator, 2); rp3d_test(map1 == map2); map1.add(Pair("a", 1)); map1.add(Pair("b", 2)); map1.add(Pair("c", 3)); map2.add(Pair("a", 1)); map2.add(Pair("b", 2)); map2.add(Pair("c", 4)); rp3d_test(map1 == map1); rp3d_test(map2 == map2); rp3d_test(map1 != map2); map2["c"] = 3; rp3d_test(map1 == map2); Map map3(mAllocator); map3.add(Pair("a", 1)); rp3d_test(map1 != map3); rp3d_test(map2 != map3); } void testAssignment() { Map map1(mAllocator); map1.add(Pair(1, 3)); map1.add(Pair(2, 6)); map1.add(Pair(10, 30)); Map map2(mAllocator); map2 = map1; rp3d_test(map2.size() == map1.size()); rp3d_test(map1 == map2); rp3d_test(map2[1] == 3); rp3d_test(map2[2] == 6); rp3d_test(map2[10] == 30); Map map3(mAllocator, 100); map3 = map1; rp3d_test(map3.size() == map1.size()); rp3d_test(map3 == map1); rp3d_test(map3[1] == 3); rp3d_test(map3[2] == 6); rp3d_test(map3[10] == 30); Map map4(mAllocator); map3 = map4; rp3d_test(map3.size() == 0); rp3d_test(map3 == map4); Map map5(mAllocator); map5.add(Pair(7, 8)); map5.add(Pair(19, 70)); map1 = map5; rp3d_test(map5.size() == map1.size()); rp3d_test(map5 == map1); rp3d_test(map1[7] == 8); rp3d_test(map1[19] == 70); } void testIterators() { Map map1(mAllocator); rp3d_test(map1.begin() == map1.end()); map1.add(Pair(1, 5)); map1.add(Pair(2, 6)); map1.add(Pair(3, 8)); map1.add(Pair(4, -1)); Map::Iterator itBegin = map1.begin(); Map::Iterator it = map1.begin(); rp3d_test(itBegin == it); int size = 0; for (auto it = map1.begin(); it != map1.end(); ++it) { rp3d_test(map1.containsKey(it->first)); size++; } rp3d_test(map1.size() == size); } }; } #endif