139 lines
		
	
	
	
		
			3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
		
		
			
		
	
	
			139 lines
		
	
	
	
		
			3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| 
								 | 
							
								#include <ecs/sparse_set.hpp>
							 | 
						||
| 
								 | 
							
								#include <ranges>
							 | 
						||
| 
								 | 
							
								#include <test/expects.hpp>
							 | 
						||
| 
								 | 
							
								#include <test/test.hpp>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								using lt::test::Case;
							 | 
						||
| 
								 | 
							
								using lt::test::Suite;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								using lt::test::expect_eq;
							 | 
						||
| 
								 | 
							
								using lt::test::expect_false;
							 | 
						||
| 
								 | 
							
								using lt::test::expect_ne;
							 | 
						||
| 
								 | 
							
								using lt::test::expect_throw;
							 | 
						||
| 
								 | 
							
								using lt::test::expect_true;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								using Set = lt::ecs::SparseSet<int>;
							 | 
						||
| 
								 | 
							
								constexpr auto capacity = 100;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Suite raii = [] {
							 | 
						||
| 
								 | 
							
									Case { "happy path won't throw" } = [] {
							 | 
						||
| 
								 | 
							
										std::ignore = Set {};
							 | 
						||
| 
								 | 
							
										std::ignore = Set { Set::max_capacity };
							 | 
						||
| 
								 | 
							
									};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									Case { "unhappy path throws" } = [] {
							 | 
						||
| 
								 | 
							
										expect_throw([] { std::ignore = Set { Set::max_capacity + 1 }; });
							 | 
						||
| 
								 | 
							
									};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									Case { "post construct has correct state" } = [&] {
							 | 
						||
| 
								 | 
							
										auto set = Set { capacity };
							 | 
						||
| 
								 | 
							
										expect_eq(set.get_size(), 0);
							 | 
						||
| 
								 | 
							
										expect_eq(set.get_capacity(), capacity);
							 | 
						||
| 
								 | 
							
									};
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Suite element_raii = [] {
							 | 
						||
| 
								 | 
							
									Case { "many inserts/removes won't throw" } = [] {
							 | 
						||
| 
								 | 
							
										auto set = Set {};
							 | 
						||
| 
								 | 
							
										for (auto idx : std::views::iota(0, 10'000))
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											set.insert(idx, {});
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										for (auto idx : std::views::iota(0, 10'000))
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											set.remove(idx);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									Case { "insert returns reference to inserted value" } = [] {
							 | 
						||
| 
								 | 
							
										auto set = Set {};
							 | 
						||
| 
								 | 
							
										for (auto idx : std::views::iota(0, 10'000))
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											const auto val = Set::Dense_T { idx, {} };
							 | 
						||
| 
								 | 
							
											expect_eq(set.insert(val.first, val.second), val);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									Case { "post insert/remove has correct state" } = [] {
							 | 
						||
| 
								 | 
							
										auto set = Set {};
							 | 
						||
| 
								 | 
							
										for (auto idx : std::views::iota(0, 10'000))
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											set.insert(idx, idx * 2);
							 | 
						||
| 
								 | 
							
											expect_eq(set.get_size(), idx + 1);
							 | 
						||
| 
								 | 
							
											expect_eq(set.at(idx), Set::Dense_T { idx, idx * 2 });
							 | 
						||
| 
								 | 
							
											expect_true(set.contains(idx));
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										for (auto idx : std::views::iota(0, 10'000))
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											expect_eq(set.at(idx), Set::Dense_T { idx, idx * 2 });
							 | 
						||
| 
								 | 
							
											expect_true(set.contains(idx));
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										for (auto idx : std::views::iota(0, 10'000))
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											set.remove(idx);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											expect_eq(set.get_size(), 10'000 - (idx + 1));
							 | 
						||
| 
								 | 
							
											expect_throw([&] { std::ignore = set.at(idx); });
							 | 
						||
| 
								 | 
							
											expect_false(set.contains(idx));
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									};
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Suite getters = [] {
							 | 
						||
| 
								 | 
							
									Case { "get_size returns correct values" } = [] {
							 | 
						||
| 
								 | 
							
										auto set = Set {};
							 | 
						||
| 
								 | 
							
										for (auto idx : std::views::iota(0, 10'000))
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											expect_eq(set.get_size(), idx);
							 | 
						||
| 
								 | 
							
											set.insert(idx, {});
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										expect_eq(set.get_size(), 10'000);
							 | 
						||
| 
								 | 
							
									};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									Case { "get_capacity returns correct values" } = [] {
							 | 
						||
| 
								 | 
							
										auto set = Set { 10'000 };
							 | 
						||
| 
								 | 
							
										for (auto idx : std::views::iota(0, 10'000))
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											expect_eq(set.get_capacity(), 10'000); // are we testing std::vector's implementation?
							 | 
						||
| 
								 | 
							
											set.insert(idx, {});
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										expect_eq(set.get_capacity(), 10'000);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										set.insert(set.get_size(), {});
							 | 
						||
| 
								 | 
							
										expect_ne(set.get_capacity(), 10'000);
							 | 
						||
| 
								 | 
							
									};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									Case { "at throws with out of bound access" } = [] {
							 | 
						||
| 
								 | 
							
										auto set = Set {};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										for (auto idx : std::views::iota(0, 50))
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											expect_throw([&] {
							 | 
						||
| 
								 | 
							
												set.insert(idx, {});
							 | 
						||
| 
								 | 
							
												std::ignore = set.at(50);
							 | 
						||
| 
								 | 
							
											});
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										set.insert(50, {});
							 | 
						||
| 
								 | 
							
										std::ignore = set.at(50); // should not throw
							 | 
						||
| 
								 | 
							
									};
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Suite clear = [] {
							 | 
						||
| 
								 | 
							
									Case { "post clear has correct state" } = [] {
							 | 
						||
| 
								 | 
							
										auto set = Set { 0 };
							 | 
						||
| 
								 | 
							
										for (auto idx : std::views::iota(0, 10'000))
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											set.insert(idx, {});
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										set.clear();
							 | 
						||
| 
								 | 
							
										expect_eq(set.get_size(), 0);
							 | 
						||
| 
								 | 
							
									};
							 | 
						||
| 
								 | 
							
								};
							 |