Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 131 additions & 14 deletions tests/GameUtils.Tests/Types/Collections/QuadTreeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,137 @@ public class QuadTreeTests
{
private static AABB DefaultBounds => new AABB(new Vector2(0, 0), new Vector2(100, 100));

// --- Tests from branch test/quadtree-insert-tests ---

[TestMethod]
public void Insert_OutsideBounds_ReturnsFalse()
{
var bounds = new AABB(new Vector2(0, 0), new Vector2(10, 10));
var quadTree = new QuadTree<string>(bounds);

bool result = quadTree.Insert("item1", new Vector2(15, 15));

Assert.IsFalse(result);
Assert.AreEqual(0, quadTree.Query(bounds).Count());
}

[TestMethod]
public void Insert_InsideBounds_ReturnsTrueAndQueryable()
{
var bounds = new AABB(new Vector2(0, 0), new Vector2(10, 10));
var quadTree = new QuadTree<string>(bounds);

bool result = quadTree.Insert("item1", new Vector2(5, 5));

Assert.IsTrue(result);
var items = quadTree.Query(bounds).ToList();
Assert.AreEqual(1, items.Count);
Assert.AreEqual("item1", items[0]);
}

[TestMethod]
public void Insert_AtBoundaries_ReturnsTrue()
{
var bounds = new AABB(new Vector2(0, 0), new Vector2(10, 10));
var quadTree = new QuadTree<string>(bounds);

Assert.IsTrue(quadTree.Insert("min", new Vector2(0, 0)));
Assert.IsTrue(quadTree.Insert("max", new Vector2(10, 10)));
Assert.AreEqual(2, quadTree.Query(bounds).Count());
}

[TestMethod]
public void Insert_ExceedingCapacity_SubdividesAndDistributesItems()
{
var bounds = new AABB(new Vector2(0, 0), new Vector2(100, 100));
var quadTree = new QuadTree<string>(bounds, capacity: 4);

quadTree.Insert("TL", new Vector2(25, 25));
quadTree.Insert("TR", new Vector2(75, 25));
quadTree.Insert("BL", new Vector2(25, 75));
quadTree.Insert("BR", new Vector2(75, 75));

quadTree.Insert("TL2", new Vector2(10, 10));

var allItems = quadTree.Query(bounds).ToList();
Assert.AreEqual(5, allItems.Count);

var tlRegion = new AABB(new Vector2(0, 0), new Vector2(50, 50));
var tlItems = quadTree.Query(tlRegion).ToList();
Assert.IsTrue(tlItems.Contains("TL"));
Assert.IsTrue(tlItems.Contains("TL2"));
Assert.AreEqual(2, tlItems.Count);
}

[TestMethod]
public void Insert_ExceedingMaxDepth_StopsSubdividingAndStoresInLeaf()
{
var bounds = new AABB(new Vector2(0, 0), new Vector2(10, 10));
var quadTree = new QuadTree<string>(bounds, capacity: 1);

for (int i = 0; i < 20; i++)
{
Assert.IsTrue(quadTree.Insert($"item{i}", new Vector2(5, 5)));
}

Assert.AreEqual(20, quadTree.Query(bounds).Count());
}

[TestMethod]
public void Insert_MultipleItemsAtSamePosition_ReturnsTrue()
{
var bounds = new AABB(new Vector2(0, 0), new Vector2(10, 10));
var quadTree = new QuadTree<string>(bounds);

Assert.IsTrue(quadTree.Insert("item1", new Vector2(5, 5)));
Assert.IsTrue(quadTree.Insert("item2", new Vector2(5, 5)));
Assert.AreEqual(2, quadTree.Query(bounds).Count());
}

[TestMethod]
public void Remove_InsertedItem_ReturnsTrueAndRemovesItem()
{
var bounds = new AABB(new Vector2(0, 0), new Vector2(10, 10));
var quadTree = new QuadTree<string>(bounds);

quadTree.Insert("item1", new Vector2(5, 5));
bool removed = quadTree.Remove("item1", new Vector2(5, 5));

Assert.IsTrue(removed);
Assert.AreEqual(0, quadTree.Query(bounds).Count());
}

[TestMethod]
public void Remove_SubdividedTreeItem_ReturnsTrueAndRemovesItem()
{
var bounds = new AABB(new Vector2(0, 0), new Vector2(100, 100));
var quadTree = new QuadTree<string>(bounds, capacity: 2);

quadTree.Insert("A", new Vector2(10, 10));
quadTree.Insert("B", new Vector2(20, 20));
quadTree.Insert("C", new Vector2(80, 80));

Assert.IsTrue(quadTree.Remove("C", new Vector2(80, 80)));
Assert.AreEqual(2, quadTree.Query(bounds).Count());
}

[TestMethod]
public void Clear_RemovesAllItems()
{
var bounds = new AABB(new Vector2(0, 0), new Vector2(100, 100));
var quadTree = new QuadTree<string>(bounds, capacity: 2);

quadTree.Insert("A", new Vector2(10, 10));
quadTree.Insert("B", new Vector2(20, 20));
quadTree.Insert("C", new Vector2(80, 80));

quadTree.Clear();

Assert.AreEqual(0, quadTree.Query(bounds).Count());
}

// --- Tests from origin/master ---

[TestMethod]
public void Query_EmptyTree_ReturnsEmpty()
{
Expand Down Expand Up @@ -131,20 +262,6 @@ public void Query_AfterClear_ReturnsEmpty()
Assert.AreEqual(0, results.Count);
}

[TestMethod]
public void Query_Radius_ReturnsItemsWithinRadius()
{
var tree = new QuadTree<string>(DefaultBounds);
tree.Insert("CenterItem", new Vector2(50, 50));
tree.Insert("NearItem", new Vector2(55, 50));
tree.Insert("FarItem", new Vector2(80, 80));

var results = tree.Query(new Vector2(50, 50), 10f).ToList();

Assert.AreEqual(2, results.Count);
CollectionAssert.AreEquivalent(new[] { "CenterItem", "NearItem" }, results);
}

[TestMethod]
public void Insert_OutsideBounds_ReturnsFalseAndNotQueried()
{
Expand Down
Loading