Skip to content

Commit

Permalink
Added feature and unit test for bchavez#577
Browse files Browse the repository at this point in the history
  • Loading branch information
TRoZZNL committed Dec 5, 2024
1 parent 91dc658 commit 378c619
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 5 deletions.
40 changes: 40 additions & 0 deletions Source/Bogus.Tests/GitHubIssues/Issue577.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using FluentAssertions;
using System;
using System.Linq;
using Xunit;

namespace Bogus.Tests.GitHubIssues;

public class Issue577 : SeededTest
{
[Fact]
public void issue_577()
{
var items = Enumerable.Range(1, 10).ToArray();

var f = new Faker();

// The minimum number is more than the number of items in the list.
Action minimum_bounds = () => f.PickRandom(items, 15, 25).ToList();
minimum_bounds.Should().Throw<ArgumentOutOfRangeException>();

// The maximum number is less than zero.
Action maximum_bounds = () => f.PickRandom(items, 2, -1).ToList();
maximum_bounds.Should().Throw<ArgumentOutOfRangeException>();

// Should return an empty list.
var pickedEmpty = f.PickRandom(items, 0, 0);
pickedEmpty.Dump();
pickedEmpty.Should().BeEmpty();

// Should return NULL.
var pickedNull = f.PickRandom(items, 0, 0, true);
pickedNull.Dump();
pickedNull.Should().BeNull();

// Should return a list with some items.
var picked = f.PickRandom(items, 2, 5);
picked.Dump();
picked.Should().Equal(7, 2, 1, 4, 9);
}
}
52 changes: 47 additions & 5 deletions Source/Bogus/Faker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ public Faker(string locale = "en")

this.Address = this.Notifier.Flow(new Address(locale));
this.Company = this.Notifier.Flow(new Company(locale));
this.Date = this.Notifier.Flow(new Date (locale));
this.Finance = this.Notifier.Flow(new Finance {Locale = locale});
this.Date = this.Notifier.Flow(new Date(locale));
this.Finance = this.Notifier.Flow(new Finance { Locale = locale });
this.Hacker = this.Notifier.Flow(new Hacker(locale));
this.Image = this.Notifier.Flow(new Images(locale));
this.Internet = this.Notifier.Flow(new Internet(locale));
Expand Down Expand Up @@ -124,7 +124,7 @@ public DateTime? DateTimeReference
set
{
localDateTimeRef = value;
if( localDateTimeRef.HasValue )
if (localDateTimeRef.HasValue)
{
this.Date.LocalSystemClock = () => localDateTimeRef.Value;
}
Expand Down Expand Up @@ -282,22 +282,64 @@ public T PickRandomParam<T>(params T[] items)
/// <summary>
/// Helper to pick random subset of elements out of the list.
/// </summary>
/// <param name="items">The collection from which to pick random items</param>
/// <param name="amountToPick">amount of elements to pick of the list.</param>
/// <exception cref="ArgumentException">if amountToPick is lower than zero.</exception>
public IEnumerable<T> PickRandom<T>(IEnumerable<T> items, int amountToPick)
{
if( amountToPick < 0 )
if (amountToPick < 0)
{
throw new ArgumentOutOfRangeException($"{nameof(amountToPick)} needs to be a positive integer.");
}
var size = items.Count();
if( amountToPick > size )
if (amountToPick > size)
{
throw new ArgumentOutOfRangeException($"{nameof(amountToPick)} is greater than the number of items.");
}
return this.Random.Shuffle(items).Take(amountToPick);
}

/// <summary>
/// Helper to pick random subset of elements out of the list.
/// </summary>
/// <param name="items">The collection from which to pick random items</param>
/// <param name="minimumAmountToPick">The minimum amount of elements to pick of the list.</param>
/// <param name="maximumAmountToPick">The maximum amount of elements to pick of the list.</param>
/// <exception cref="ArgumentOutOfRangeException" >if maximumAmountToPick is lower than zero.</exception>
public IEnumerable<T> PickRandom<T>(IEnumerable<T> items, int minimumAmountToPick, int maximumAmountToPick)
=> PickRandom(items, minimumAmountToPick, maximumAmountToPick, false);

/// <summary>
/// Helper to pick random subset of elements out of the list.
/// </summary>
/// <param name="items">The collection from which to pick random items</param>
/// <param name="minimumAmountToPick">The minimum amount of elements to pick of the list.</param>
/// <param name="maximumAmountToPick">The maximum amount of elements to pick of the list.</param>
/// <param name="returnNullOnZeroItems">When true, NULL will be returned when the amount of items that will be picked is Zero. When false, an empty collection will be returned when the amount of items that will be picked is Zero. </param>
/// <exception cref="ArgumentOutOfRangeException" >if maximumAmountToPick is lower than zero.</exception>
public IEnumerable<T>? PickRandom<T>(IEnumerable<T> items, int minimumAmountToPick, int maximumAmountToPick, bool returnNullOnZeroItems)
{
if (maximumAmountToPick < 0)
{
throw new ArgumentOutOfRangeException(nameof(maximumAmountToPick), $"{nameof(maximumAmountToPick)} needs to be a positive integer.");
}
var size = items.Count();
if (minimumAmountToPick > size)
{
throw new ArgumentOutOfRangeException(nameof(minimumAmountToPick), $"{nameof(minimumAmountToPick)} is greater than the number of items.");
}

var pickAmount = Random.Number(minimumAmountToPick, Math.Min(size, maximumAmountToPick));
if (pickAmount == 0)
{
return returnNullOnZeroItems ? null : Enumerable.Empty<T>();
}
else
{
return Random.Shuffle(items).Take(pickAmount);
}
}

/// <summary>
/// Helper method to call faker actions multiple times and return the result as IList of T
/// </summary>
Expand Down

0 comments on commit 378c619

Please sign in to comment.