From 45e287a987c2490633badef2f02151aa5293c689 Mon Sep 17 00:00:00 2001 From: bchavez Date: Mon, 10 Feb 2020 11:29:05 -0800 Subject: [PATCH] Use `in` parameter modifier to resolve compiler ambiguity when using struct Guid?, primitive type int?, and reference types like object. #124 --- HISTORY.md | 5 +-- Source/Bogus.Tests/GitHubIssues/Issue124.cs | 32 +++++++++++++++++++ .../Bogus/Extensions/ExtensionsForFakerT.cs | 4 ++- 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index f1321e09..1b507ec5 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,9 +1,10 @@ -## v28.5.1 -Release Date: 2020-TBA +## v29.0.1 +Release Date: 2020-02-10 * Data parity with faker.js. Deterministic sequences using `Internet.Avatar()` may have changed. * Add support for .snupkg NuGet Symbol Server Packages via SourceLink. * Added Randomizer.Enums() that makes selecting a subset of enum values easier. +* Modified `.OrNull(f)` extension method signatures for type-safe with nullable primitive types, structs, and reference types via `in` parameter to avoid ambiguous calls. ## v28.4.4 Release Date: 2019-12-10 diff --git a/Source/Bogus.Tests/GitHubIssues/Issue124.cs b/Source/Bogus.Tests/GitHubIssues/Issue124.cs index ef1d57d1..fa8232af 100644 --- a/Source/Bogus.Tests/GitHubIssues/Issue124.cs +++ b/Source/Bogus.Tests/GitHubIssues/Issue124.cs @@ -119,6 +119,31 @@ public void test_deterministic_or_null() ); } + [Fact] + public void nullable_int_and_nullable_reference_type() + { + var faker = new Faker() + .RuleFor(x => x.Id, f => f.Random.Int().OrNull(f)) + .RuleFor(x => x.Obj, f => new object().OrNull(f)) + .RuleFor(x => x.Str, f => f.Random.Word().OrNull(f)); + + var q = faker.Generate(3); + + console.Dump(q); + + q[0].Id.Should().NotBeNull(); + q[0].Obj.Should().NotBeNull(); + q[0].Str.Should().BeNull(); + + q[1].Id.Should().BeNull(); + q[1].Obj.Should().NotBeNull(); + q[1].Str.Should().BeNull(); + + q[2].Id.Should().BeNull(); + q[2].Obj.Should().NotBeNull(); + q[2].Str.Should().NotBeNull(); + } + public class Foo { public Guid Id { get; set; } @@ -130,6 +155,13 @@ public class Bar public Guid Id { get; set; } public Person Person { get; set; } } + + public class Qux + { + public int? Id { get; set; } + public object Obj { get; set; } + public string Str { get; set; } + } } public class Person diff --git a/Source/Bogus/Extensions/ExtensionsForFakerT.cs b/Source/Bogus/Extensions/ExtensionsForFakerT.cs index 262d0b12..c21becd1 100644 --- a/Source/Bogus/Extensions/ExtensionsForFakerT.cs +++ b/Source/Bogus/Extensions/ExtensionsForFakerT.cs @@ -27,9 +27,10 @@ public static List GenerateBetween(this Faker faker, int min, int max, /// Helpful extension for creating randomly null values for .RuleFor() rules. /// Example: .RuleFor(x=>x.Prop, f=>f.Random.Word().OrNull(f)) /// + /// Any reference type. /// The Faker facade. This is usually the f from RuleFor(.., f => lambda). /// The probability of null occurring. Range [1.0f - 0.0f] (100% and 0%) respectively. For example, if 15% null is desired pass nullWeight = 0.15f. - public static object OrNull(this object value, Faker f, float nullWeight = 0.5f) + public static T OrNull(this T value, in Faker f, float nullWeight = 0.5f) where T : class { if (nullWeight > 1 || nullWeight < 0) throw new ArgumentOutOfRangeException(nameof(nullWeight), $".{nameof(OrNull)}() {nameof(nullWeight)} of '{nullWeight}' must be between 1.0f and 0.0f."); return f.Random.Float() > nullWeight ? value : null; @@ -39,6 +40,7 @@ public static object OrNull(this object value, Faker f, float nullWeight = 0.5f) /// Helpful extension for creating randomly null values for .RuleFor() rules. /// Example: .RuleFor(x=>x.Prop, f=>f.Random.Int().OrNull(f)) /// + /// Any nullable type. ie: int?, Guid?, etc. /// The Faker facade. This is usually the f from RuleFor(.., f => lambda). /// The probability of null occurring. Range [1.0f - 0.0f] (100% and 0%) respectively. For example, if 15% null is desired pass nullWeight = 0.15f. public static T? OrNull(this T value, Faker f, float nullWeight = 0.5f) where T : struct