using Moq;
using NUnit.Framework;
using Robust.Shared.Collections;
using Robust.Shared.Random;
namespace Robust.Shared.Tests.Random;
/// Instantiable tests for .
[TestFixture]
internal sealed class RandomExtensionsGetItemsWithListTests : RandomExtensionsTests>
{
///
protected override IList CreateCollection()
=> new List(CollectionForTests);
///
protected override IReadOnlyCollection Invoke(IList collection, int count, bool allowDuplicates)
=> _underlyingRandom.GetItems(collection, count, allowDuplicates);
}
/// Instantiable tests for .
[TestFixture]
internal sealed class RandomExtensionsGetItemsWithSpanTests : RandomExtensionsTests
{
///
protected override string[] CreateCollection()
=> CollectionForTests;
///
protected override IReadOnlyCollection Invoke(string[] collection, int count, bool allowDuplicates)
{
var span = new Span(collection);
return _underlyingRandom.GetItems(span, count, allowDuplicates)
.ToArray();
}
}
/// Instantiable tests for .
[TestFixture]
internal sealed class RandomExtensionsGetItemsWithValueListTests : RandomExtensionsTests>
{
///
protected override ValueList CreateCollection()
=> new ValueList(CollectionForTests);
///
protected override IReadOnlyCollection Invoke(ValueList collection, int count, bool allowDuplicates)
=> _underlyingRandom.GetItems(collection, count, allowDuplicates)
.ToArray();
}
[TestFixture]
internal abstract class RandomExtensionsTests
{
protected IRobustRandom _underlyingRandom = default!;
protected readonly string[] CollectionForTests = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10" };
private T _collection = default!;
private int Count => CollectionForTests.Length;
[SetUp]
public void Setup()
{
_underlyingRandom = Mock.Of();
_collection = CreateCollection();
}
[Test]
public void GetItems_PickOneFromList_ReturnOfRandomizedIndex()
{
// Arrange
Mock.Get(_underlyingRandom)
.Setup(x => x.Next(Count))
.Returns(8);
// Act
var result = Invoke(_collection, 1, true);
// Assert
Assert.That(result.Count, Is.EqualTo(1));
Assert.That(result.Single(), Is.EqualTo("8"));
}
[Test]
public void GetItems_PickOneFromListWithoutDuplicates_ReturnOfRandomizedIndex()
{
// Arrange
Mock.Get(_underlyingRandom)
.Setup(x => x.Next(Count))
.Returns(8);
// Act
var result = Invoke(_collection, 1, allowDuplicates: false);
// Assert
Assert.That(result.Count, Is.EqualTo(1));
Assert.That(result.Single(), Is.EqualTo("8"));
}
[Test]
public void GetItems_PickSomeFromList_ReturnOfRandomizedIndex()
{
// Arrange
Mock.Get(_underlyingRandom)
.SetupSequence(x => x.Next(Count))
.Returns(8)
.Returns(3)
.Returns(2);
// Act
var result = Invoke(_collection, 3, true);
// Assert
Assert.That(result, Is.EqualTo(new[] { "8", "3", "2" }));
}
[Test]
public void GetItems_PickSomeFromListWhileRollingDuplicates_ReturnWithDuplicates()
{
// Arrange
Mock.Get(_underlyingRandom)
.SetupSequence(x => x.Next(Count))
.Returns(8)
.Returns(2)
.Returns(2)
.Returns(2);
// Act
var result = Invoke(_collection, 4, allowDuplicates: true);
// Assert
Assert.That(result, Is.EqualTo(new[] { "8", "2", "2", "2" }));
}
[Test]
public void GetItems_PickSameAmountAsOriginalCollection_ReturnWithDuplicates()
{
// Arrange
Mock.Get(_underlyingRandom)
.SetupSequence(x => x.Next(Count))
.Returns(0)
.Returns(2)
.Returns(2)
.Returns(4)
.Returns(6)
.Returns(5)
.Returns(4)
.Returns(3)
.Returns(2)
.Returns(1)
.Returns(0);
// Act
var result = Invoke(_collection, 11, allowDuplicates: true);
// Assert
Assert.That(result, Is.EqualTo(new[] { "0", "2", "2", "4", "6", "5", "4", "3", "2", "1", "0" }));
}
[Test]
public void GetItems_PickMoreItemsThenOriginalCollectionHave_ReturnWithDuplicates()
{
// Arrange
Mock.Get(_underlyingRandom)
.SetupSequence(x => x.Next(Count))
.Returns(0)
.Returns(2)
.Returns(2)
.Returns(4)
.Returns(6)
.Returns(5)
.Returns(4)
.Returns(3)
.Returns(2)
.Returns(1)
.Returns(9)
.Returns(9);
// Act
var result = Invoke(_collection, 12, allowDuplicates: true);
// Assert
Assert.That(result, Is.EqualTo(new[] { "0", "2", "2", "4", "6", "5", "4", "3", "2", "1", "9", "9" }));
}
[Test]
public void GetItems_PickSomeItemsWithoutDuplicates_ReturnWithoutDuplicates()
{
// Arrange
var mock = Mock.Get(_underlyingRandom);
mock.Setup(x => x.Next(Count)).Returns(1);
mock.Setup(x => x.Next(Count - 1)).Returns(1);
mock.Setup(x => x.Next(Count - 2)).Returns(6);
// Act
var result = Invoke(_collection, 3, allowDuplicates: false);
// Assert
Assert.That(result, Is.EqualTo(new[] { "1", "10", "6" }));
}
[Test]
public void GetItems_PickOneLessItemsThenOriginalCollectionHaveWithoutDuplicates_ReturnWithoutDuplicates()
{
// Arrange
var mock = Mock.Get(_underlyingRandom);
mock.Setup(x => x.Next(Count)).Returns(1);
mock.Setup(x => x.Next(Count - 1)).Returns(1);
mock.Setup(x => x.Next(Count - 2)).Returns(6);
mock.Setup(x => x.Next(Count - 3)).Returns(6);
mock.Setup(x => x.Next(Count - 4)).Returns(3);
mock.Setup(x => x.Next(Count - 5)).Returns(4);
mock.Setup(x => x.Next(Count - 6)).Returns(4);
mock.Setup(x => x.Next(Count - 7)).Returns(3);
mock.Setup(x => x.Next(Count - 8)).Returns(1);
mock.Setup(x => x.Next(Count - 9)).Returns(1);
// Act
var result = Invoke(_collection, 10, allowDuplicates: false);
// Assert
Assert.That(result, Is.EqualTo(new[] { "1", "10", "6", "8", "3", "4", "5", "7", "9", "2" }));
}
[Test]
public void GetItems_PickAllItemsWithoutDuplicates_ReturnOriginalCollectionShuffledWithoutDuplicates()
{
// Arrange
var shuffled = new[] { "9", "0", "4", "2", "3", "7", "5", "8", "6", "10", "1" };
Mock.Get(_underlyingRandom)
.Setup(x => x.Shuffle(It.IsAny>()))
.Callback>(x =>
{
for (int i = 0; i < shuffled.Length; i++)
{
x[i] = shuffled[i];
}
});
// Act
var result = Invoke(_collection, 11, allowDuplicates: false);
// Assert
Assert.That(result, Is.EqualTo(shuffled));
Mock.Get(_underlyingRandom).Verify(x => x.Next(It.IsAny()), Times.Never);
}
[Test]
public void GetItems_PickMoreItemsThenOriginalHaveWithoutDuplicates_ReturnOriginalShuffledOriginalCollectionWithoutDuplicates()
{
// Arrange
var shuffled = new[] { "9", "0", "4", "2", "3", "7", "5", "8", "6", "10", "1" };
Mock.Get(_underlyingRandom)
.Setup(x => x.Shuffle(It.IsAny>()))
.Callback>(x =>
{
for (int i = 0; i < shuffled.Length; i++)
{
x[i] = shuffled[i];
}
});
// Act
var result = Invoke(_collection, 30, allowDuplicates: false);
// Assert
Assert.That(result, Is.EqualTo(shuffled));
Mock.Get(_underlyingRandom).Verify(x => x.Next(It.IsAny()), Times.Never);
}
/// Create concrete collection for tests.
protected abstract T CreateCollection();
/// Invoke method under test. Separate implementation types will have different overrides to be tested.
protected abstract IReadOnlyCollection Invoke(T collection, int count, bool allowDuplicates);
}