From 378c619ba7f87739044caec57fb47ff9fe76bebd Mon Sep 17 00:00:00 2001 From: Mark Rienstra Date: Thu, 5 Dec 2024 09:55:49 +0100 Subject: [PATCH] Added feature and unit test for #577 --- Source/Bogus.Tests/GitHubIssues/Issue577.cs | 40 ++++++++++++++++ Source/Bogus/Faker.cs | 52 +++++++++++++++++++-- 2 files changed, 87 insertions(+), 5 deletions(-) create mode 100644 Source/Bogus.Tests/GitHubIssues/Issue577.cs diff --git a/Source/Bogus.Tests/GitHubIssues/Issue577.cs b/Source/Bogus.Tests/GitHubIssues/Issue577.cs new file mode 100644 index 00000000..bf7dab2f --- /dev/null +++ b/Source/Bogus.Tests/GitHubIssues/Issue577.cs @@ -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(); + + // The maximum number is less than zero. + Action maximum_bounds = () => f.PickRandom(items, 2, -1).ToList(); + maximum_bounds.Should().Throw(); + + // 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); + } +} diff --git a/Source/Bogus/Faker.cs b/Source/Bogus/Faker.cs index 9a821b03..0ba8870c 100644 --- a/Source/Bogus/Faker.cs +++ b/Source/Bogus/Faker.cs @@ -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)); @@ -124,7 +124,7 @@ public DateTime? DateTimeReference set { localDateTimeRef = value; - if( localDateTimeRef.HasValue ) + if (localDateTimeRef.HasValue) { this.Date.LocalSystemClock = () => localDateTimeRef.Value; } @@ -282,22 +282,64 @@ public T PickRandomParam(params T[] items) /// /// Helper to pick random subset of elements out of the list. /// + /// The collection from which to pick random items /// amount of elements to pick of the list. /// if amountToPick is lower than zero. public IEnumerable PickRandom(IEnumerable 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); } + /// + /// Helper to pick random subset of elements out of the list. + /// + /// The collection from which to pick random items + /// The minimum amount of elements to pick of the list. + /// The maximum amount of elements to pick of the list. + /// if maximumAmountToPick is lower than zero. + public IEnumerable PickRandom(IEnumerable items, int minimumAmountToPick, int maximumAmountToPick) + => PickRandom(items, minimumAmountToPick, maximumAmountToPick, false); + + /// + /// Helper to pick random subset of elements out of the list. + /// + /// The collection from which to pick random items + /// The minimum amount of elements to pick of the list. + /// The maximum amount of elements to pick of the list. + /// 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. + /// if maximumAmountToPick is lower than zero. + public IEnumerable? PickRandom(IEnumerable 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(); + } + else + { + return Random.Shuffle(items).Take(pickAmount); + } + } + /// /// Helper method to call faker actions multiple times and return the result as IList of T ///