Skip to content
Merged
Show file tree
Hide file tree
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
2 changes: 1 addition & 1 deletion Buildenator/Buildenator.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<IncludeBuildOutput>false</IncludeBuildOutput>
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
<!-- Do not include the generator as a lib dependency -->
<Version>10.8.1.0</Version>
<Version>10.8.2.0</Version>
</PropertyGroup>

<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion Buildenator/CodeAnalysis/TypedSymbol.cs
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ public string GenerateLazyFieldValueReturn()
+ (_nullableStrategy == NullableStrategy.Enabled ? "!" : "")
: GetDefaultValueName() is { } defaultValueName
? defaultValueName
: $"default({TypeFullName})")})).Object";
: $"default({TypeFullName})" + (_nullableStrategy == NullableStrategy.Enabled ? "!" : ""))})).Object";

public string GenerateFieldValueReturn()
=> IsMockable()
Expand Down
26 changes: 7 additions & 19 deletions Buildenator/Configuration/EntityToBuild.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,19 +68,12 @@ public string GenerateBuildsCode(bool shouldGenerateMethodsForUnreachablePropert
if (ConstructorToBuild is null)
return "";

var disableWarning = NullableStrategy == NullableStrategy.Enabled
? "#pragma warning disable CS8604\n"
: string.Empty;
var restoreWarning = NullableStrategy == NullableStrategy.Enabled
? "#pragma warning restore CS8604\n"
: string.Empty;

return $@"{disableWarning} public {FullName} {DefaultConstants.BuildMethodName}()
return $@" public {FullName} {DefaultConstants.BuildMethodName}()
{{
{DefaultConstants.PreBuildMethodName}();
{GenerateLazyBuildEntityString(shouldGenerateMethodsForUnreachableProperties, ConstructorToBuild.Parameters)}
}}
{restoreWarning}

";
}

Expand Down Expand Up @@ -151,26 +144,21 @@ public string GenerateDefaultBuildsCode()
.Aggregate(new StringBuilder(), (builder, s) => builder.AppendLine(s))
.ToString();

var nullForgiving = NullableStrategy == NullableStrategy.Enabled ? "!" : string.Empty;
var methodParameters = ConstructorToBuild.Parameters
.Concat(_properties)
.Select(s =>
{
var fieldType = s.GenerateFieldType();
return $"{fieldType} {s.UnderScoreName} = default({fieldType})";
return $"{fieldType} {s.UnderScoreName} = default({fieldType}){nullForgiving}";
}).ComaJoin();
var disableWarning = NullableStrategy == NullableStrategy.Enabled
? "#pragma warning disable CS8625\n"
: string.Empty;
var restoreWarning = NullableStrategy == NullableStrategy.Enabled
? "#pragma warning restore CS8625\n"
: string.Empty;

return $@"{disableWarning} public static {FullName} BuildDefault({methodParameters})

return $@" public static {FullName} BuildDefault({methodParameters})
{{
{moqInit}
{GenerateDefaultBuildEntityString(ConstructorToBuild.Parameters)}
}}
{restoreWarning}";
";
}

private string GenerateDefaultBuildEntityString(IEnumerable<TypedSymbol> parameters)
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## 10.8.2.0 - 2026-8-31

### Fixed
- **CS8625/CS8604 nullable warnings in generated `Build()`/`BuildDefault()`**: Non-nullable reference properties without a fixture, mock, or `Default{PropertyName}` value fell back to `default(T)` in the generated code, which the compiler flags as a null-to-non-nullable-type conversion. `Build()` suppressed the resulting CS8604 with a pragma but never suppressed the underlying CS8625, so consumers with `WarningsAsErrors=nullable` (or similarly strict nullable settings) could hit a hard build error instead of a warning. The `default(T)` fallback now uses the null-forgiving operator (`!`) directly, the same pattern already used for the AutoFixture branch, instead of pragma-suppressing the whole method body. Both `Build()` and `BuildDefault()` are now generated warning-free with no pragmas needed.

## 10.8.1.0 - 2026-4-12

### Fixed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<IsPackable>false</IsPackable>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,14 @@ public void BuildersGenerator_MandatoryParameters_NoStaticFactoryPropertyGenerat

staticProperty.Should().BeNull("static factory property is incompatible with mandatory constructor parameters");
}

[Fact]
public void BuildersGenerator_MandatoryParameters_BuildDefaultUsesDefaultValues()
{
var result = EntityWithMandatoryConstructorParametersBuilder.BuildDefault();

result.LineNumber.Should().Be(0);
result.Activity.Should().BeNull();
result.Tags.Should().BeNull();
}
}
Loading