Skip to content

Enable nullable in project but disable in files#115

Merged
twogood merged 1 commit intomainfrom
nullable-enable-start-Activout.RestClient.Newtonsoft.Json.Test
Oct 24, 2025
Merged

Enable nullable in project but disable in files#115
twogood merged 1 commit intomainfrom
nullable-enable-start-Activout.RestClient.Newtonsoft.Json.Test

Conversation

@twogood
Copy link
Owner

@twogood twogood commented Oct 24, 2025

Summary by CodeRabbit

  • Chores
    • Updated test project configuration to enforce stricter type-safety standards across the testing framework, enhancing code robustness and reducing potential runtime errors. Selective exemptions were strategically applied to specific test modules to maintain backward compatibility during a phased rollout of enhanced null-safety checks and validation practices.

@twogood twogood self-assigned this Oct 24, 2025
@coderabbitai
Copy link

coderabbitai bot commented Oct 24, 2025

Walkthrough

The test project's project file enables nullable reference types globally by adding <Nullable>enable</Nullable> to its PropertyGroup configuration. Subsequently, individual test files throughout the project are annotated with #nullable disable directives to opt out of nullable reference type checking.

Changes

Cohort / File(s) Summary
Project Configuration
Activout.RestClient.Newtonsoft.Json.Test/Activout.RestClient.Newtonsoft.Json.Test.csproj
Added <Nullable>enable</Nullable> to enable nullable reference types project-wide.
DomainExceptions Test Files
Activout.RestClient.Newtonsoft.Json.Test/DomainExceptions/DefaultDomainExceptionErrorObjectTests.cs, DomainExceptionErrorEnumTests.cs, DomainExceptionErrorObjectTests.cs, MyApiError.cs, MyApiErrorResponse.cs, MyDomainErrorAttribute.cs, MyDomainErrorEnum.cs, MyDomainHttpErrorAttribute.cs
Added #nullable disable directive at file top.
MovieReviews Test Files
Activout.RestClient.Newtonsoft.Json.Test/MovieReviews/ErrorResponse.cs, IMovieReviewService.cs, Movie.cs, Review.cs
Added #nullable disable directive at file top.
Root Test Files
Activout.RestClient.Newtonsoft.Json.Test/LoggerFactoryHelpers.cs, NewtonsoftJsonDeserializerTest.cs, RestClientTests.cs, SerializationOrderTest.cs, SimpleValueObjectTest.cs
Added #nullable disable directive at file top.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

The changes are homogeneous and repetitive—enabling nullable types at the project level and selectively disabling them in individual test files through straightforward preprocessor directives. No logic modifications, control flow changes, or public API alterations are present.

Poem

🐰 Nullable types enabled, yet files opt out,
A pragmatic dance of what nulls are about,
Project-wide strictness with selective peace,
Test files find refuge, their warnings cease! 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "Enable nullable in project but disable in files" accurately and concisely summarizes the main change across all modified files. The pull request enables nullable reference types at the project level by adding <Nullable>enable</Nullable> to the .csproj file, while simultaneously adding #nullable disable directives to 17 individual test files to opt out at the file level. The title is specific and clear enough that a reviewer scanning the history would immediately understand the dual-configuration strategy being implemented, without using vague terminology or unnecessary noise.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch nullable-enable-start-Activout.RestClient.Newtonsoft.Json.Test

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (9)
Activout.RestClient.Newtonsoft.Json.Test/DomainExceptions/MyDomainHttpErrorAttribute.cs (1)

5-13: Consider refactoring to use file-scoped namespace and primary constructor.

Per coding guidelines, this code could be modernized:

  • Use file-scoped namespace (reduces nesting)
  • Use primary constructor (more concise)

Apply this refactor:

-namespace Activout.RestClient.Newtonsoft.Json.Test.DomainExceptions
-{
-    internal class MyDomainHttpErrorAttribute : DomainHttpErrorAttribute
-    {
-        public MyDomainHttpErrorAttribute(HttpStatusCode httpStatusCode, MyDomainErrorEnum domainErrorValue) : base(
-            httpStatusCode, domainErrorValue)
-        {
-        }
-    }
-}
+namespace Activout.RestClient.Newtonsoft.Json.Test.DomainExceptions;
+
+internal class MyDomainHttpErrorAttribute(HttpStatusCode httpStatusCode, MyDomainErrorEnum domainErrorValue)
+    : DomainHttpErrorAttribute(httpStatusCode, domainErrorValue);
Activout.RestClient.Newtonsoft.Json.Test/DomainExceptions/MyDomainErrorAttribute.cs (1)

4-11: Consider refactoring to use file-scoped namespace and primary constructor.

Per coding guidelines, this code could be modernized with file-scoped namespace and primary constructor.

Apply this refactor:

-namespace Activout.RestClient.Newtonsoft.Json.Test.DomainExceptions
-{
-    internal class MyDomainErrorAttribute : DomainErrorAttribute
-    {
-        public MyDomainErrorAttribute(MyApiError apiValue, MyDomainErrorEnum domainValue) : base(apiValue, domainValue)
-        {
-        }
-    }
-}
+namespace Activout.RestClient.Newtonsoft.Json.Test.DomainExceptions;
+
+internal class MyDomainErrorAttribute(MyApiError apiValue, MyDomainErrorEnum domainValue)
+    : DomainErrorAttribute(apiValue, domainValue);
Activout.RestClient.Newtonsoft.Json.Test/DomainExceptions/MyApiError.cs (1)

2-9: Consider using file-scoped namespace.

Per coding guidelines, this enum definition could use file-scoped namespace to reduce nesting.

Apply this refactor:

-namespace Activout.RestClient.Newtonsoft.Json.Test.DomainExceptions
-{
-    public enum MyApiError
-    {
-        Foo = 4,
-        Bar = 5
-    }
-}
+namespace Activout.RestClient.Newtonsoft.Json.Test.DomainExceptions;
+
+public enum MyApiError
+{
+    Foo = 4,
+    Bar = 5
+}
Activout.RestClient.Newtonsoft.Json.Test/NewtonsoftJsonDeserializerTest.cs (1)

14-20: Consider using file-scoped namespace and record for DTO.

Per coding guidelines:

  • Use file-scoped namespace to reduce nesting
  • Use records for DTOs and immutable data structures

The Data class could be a record:

-namespace Activout.RestClient.Newtonsoft.Json.Test
-{
-    [SuppressMessage("ReSharper", "ClassNeverInstantiated.Global")]
-    public class Data
-    {
-        public string Value { get; set; }
-    }
+namespace Activout.RestClient.Newtonsoft.Json.Test;
+
+[SuppressMessage("ReSharper", "ClassNeverInstantiated.Global")]
+public record Data(string Value);
Activout.RestClient.Newtonsoft.Json.Test/DomainExceptions/DomainExceptionErrorObjectTests.cs (1)

13-23: Consider using file-scoped namespace and primary constructor.

Per coding guidelines, MyDomainErrorObject could be modernized with file-scoped namespace and primary constructor.

Apply this refactor:

-namespace Activout.RestClient.Newtonsoft.Json.Test.DomainExceptions
-{
-    internal class MyDomainErrorObject
-    {
-        public MyDomainErrorEnum ErrorEnum { get; }
-
-        public MyDomainErrorObject(MyDomainErrorEnum errorEnum)
-        {
-            ErrorEnum = errorEnum;
-        }
-    }
+namespace Activout.RestClient.Newtonsoft.Json.Test.DomainExceptions;
+
+internal class MyDomainErrorObject(MyDomainErrorEnum errorEnum)
+{
+    public MyDomainErrorEnum ErrorEnum { get; } = errorEnum;
+}
Activout.RestClient.Newtonsoft.Json.Test/RestClientTests.cs (1)

17-17: Consider using file-scoped namespace.

Per coding guidelines, the namespace declaration could be file-scoped to reduce nesting.

Change:

-namespace Activout.RestClient.Newtonsoft.Json.Test
-{
+namespace Activout.RestClient.Newtonsoft.Json.Test;

(and remove the closing brace at the end of the file)

Activout.RestClient.Newtonsoft.Json.Test/SimpleValueObjectTest.cs (1)

11-28: Consider using file-scoped namespace, primary constructor, and record for DTO.

Per coding guidelines, this code could be modernized:

  • Use file-scoped namespace
  • Use primary constructor for MySimpleValueObject
  • Use record for Stuff (it's a DTO)

Apply this refactor:

-namespace Activout.RestClient.Newtonsoft.Json.Test
-{
-    public class MySimpleValueObject
-    {
-        public string Value { get; }
-
-        public MySimpleValueObject(string value)
-        {
-            Value = value;
-        }
-    }
-
-    public class Stuff
-    {
-        public MySimpleValueObject FooBar { get; set; }
-
-        public int? NullableInteger { get; set; }
-    }
+namespace Activout.RestClient.Newtonsoft.Json.Test;
+
+public class MySimpleValueObject(string value)
+{
+    public string Value { get; } = value;
+}
+
+public record Stuff
+{
+    public MySimpleValueObject? FooBar { get; set; }
+    public int? NullableInteger { get; set; }
+}
Activout.RestClient.Newtonsoft.Json.Test/DomainExceptions/MyApiErrorResponse.cs (1)

2-9: Consider using file-scoped namespace and record for DTO.

Per coding guidelines, this DTO class could be modernized with file-scoped namespace and record syntax.

Apply this refactor:

-namespace Activout.RestClient.Newtonsoft.Json.Test.DomainExceptions
-{
-    public class MyApiErrorResponse
-    {
-        [MyDomainError(MyApiError.Foo, MyDomainErrorEnum.DomainFoo)]
-        public MyApiError Code { get; set; }
-    }
-}
+namespace Activout.RestClient.Newtonsoft.Json.Test.DomainExceptions;
+
+public record MyApiErrorResponse
+{
+    [MyDomainError(MyApiError.Foo, MyDomainErrorEnum.DomainFoo)]
+    public MyApiError Code { get; set; }
+}
Activout.RestClient.Newtonsoft.Json.Test/MovieReviews/IMovieReviewService.cs (1)

1-1: Intentional nullable disable for incremental adoption.

The approach of enabling nullable project-wide while disabling it per-file is a valid incremental migration strategy. This prevents breaking existing test code while setting up the infrastructure for future nullable adoption.

Consider tracking this as technical debt. Future work could gradually enable nullable in test files and annotate reference type parameters (e.g., movieId, reviewId) to catch potential null references at compile time.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c27bf7b and d6664b7.

📒 Files selected for processing (18)
  • Activout.RestClient.Newtonsoft.Json.Test/Activout.RestClient.Newtonsoft.Json.Test.csproj (1 hunks)
  • Activout.RestClient.Newtonsoft.Json.Test/DomainExceptions/DefaultDomainExceptionErrorObjectTests.cs (1 hunks)
  • Activout.RestClient.Newtonsoft.Json.Test/DomainExceptions/DomainExceptionErrorEnumTests.cs (1 hunks)
  • Activout.RestClient.Newtonsoft.Json.Test/DomainExceptions/DomainExceptionErrorObjectTests.cs (1 hunks)
  • Activout.RestClient.Newtonsoft.Json.Test/DomainExceptions/MyApiError.cs (1 hunks)
  • Activout.RestClient.Newtonsoft.Json.Test/DomainExceptions/MyApiErrorResponse.cs (1 hunks)
  • Activout.RestClient.Newtonsoft.Json.Test/DomainExceptions/MyDomainErrorAttribute.cs (1 hunks)
  • Activout.RestClient.Newtonsoft.Json.Test/DomainExceptions/MyDomainErrorEnum.cs (1 hunks)
  • Activout.RestClient.Newtonsoft.Json.Test/DomainExceptions/MyDomainHttpErrorAttribute.cs (1 hunks)
  • Activout.RestClient.Newtonsoft.Json.Test/LoggerFactoryHelpers.cs (1 hunks)
  • Activout.RestClient.Newtonsoft.Json.Test/MovieReviews/ErrorResponse.cs (1 hunks)
  • Activout.RestClient.Newtonsoft.Json.Test/MovieReviews/IMovieReviewService.cs (1 hunks)
  • Activout.RestClient.Newtonsoft.Json.Test/MovieReviews/Movie.cs (1 hunks)
  • Activout.RestClient.Newtonsoft.Json.Test/MovieReviews/Review.cs (1 hunks)
  • Activout.RestClient.Newtonsoft.Json.Test/NewtonsoftJsonDeserializerTest.cs (1 hunks)
  • Activout.RestClient.Newtonsoft.Json.Test/RestClientTests.cs (1 hunks)
  • Activout.RestClient.Newtonsoft.Json.Test/SerializationOrderTest.cs (1 hunks)
  • Activout.RestClient.Newtonsoft.Json.Test/SimpleValueObjectTest.cs (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.cs

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.cs: Use [] list syntax for collections
Use file-scoped namespaces
Use primary constructors wherever possible
Use records for data transfer objects (DTOs) and immutable data structures
Use var for local variable declarations when possible
Use expression-bodied members for simple methods and properties
Use pattern matching for type checks and deconstruction
Use using statements for resource management
Use async and await for asynchronous programming
Never include "Async" in method names
Only include comments that explain why something is done, not what is done

Files:

  • Activout.RestClient.Newtonsoft.Json.Test/RestClientTests.cs
  • Activout.RestClient.Newtonsoft.Json.Test/LoggerFactoryHelpers.cs
  • Activout.RestClient.Newtonsoft.Json.Test/SimpleValueObjectTest.cs
  • Activout.RestClient.Newtonsoft.Json.Test/DomainExceptions/MyDomainErrorAttribute.cs
  • Activout.RestClient.Newtonsoft.Json.Test/DomainExceptions/MyDomainHttpErrorAttribute.cs
  • Activout.RestClient.Newtonsoft.Json.Test/DomainExceptions/MyApiErrorResponse.cs
  • Activout.RestClient.Newtonsoft.Json.Test/NewtonsoftJsonDeserializerTest.cs
  • Activout.RestClient.Newtonsoft.Json.Test/DomainExceptions/MyApiError.cs
  • Activout.RestClient.Newtonsoft.Json.Test/SerializationOrderTest.cs
  • Activout.RestClient.Newtonsoft.Json.Test/MovieReviews/IMovieReviewService.cs
  • Activout.RestClient.Newtonsoft.Json.Test/DomainExceptions/DomainExceptionErrorEnumTests.cs
  • Activout.RestClient.Newtonsoft.Json.Test/DomainExceptions/DomainExceptionErrorObjectTests.cs
  • Activout.RestClient.Newtonsoft.Json.Test/DomainExceptions/DefaultDomainExceptionErrorObjectTests.cs
  • Activout.RestClient.Newtonsoft.Json.Test/MovieReviews/ErrorResponse.cs
  • Activout.RestClient.Newtonsoft.Json.Test/MovieReviews/Movie.cs
  • Activout.RestClient.Newtonsoft.Json.Test/DomainExceptions/MyDomainErrorEnum.cs
  • Activout.RestClient.Newtonsoft.Json.Test/MovieReviews/Review.cs
**/{global.json,Directory.Build.props,Directory.Build.targets,*.csproj}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use features from the latest stable .NET (9.x) and C# (13)

Files:

  • Activout.RestClient.Newtonsoft.Json.Test/Activout.RestClient.Newtonsoft.Json.Test.csproj
🔇 Additional comments (18)
Activout.RestClient.Newtonsoft.Json.Test/DomainExceptions/MyDomainHttpErrorAttribute.cs (1)

1-1: Nullable disable directive is appropriate for gradual migration.

The #nullable disable directive is a valid approach for gradually migrating to nullable reference types. This allows the project to enable nullable warnings globally while addressing each file incrementally.

Activout.RestClient.Newtonsoft.Json.Test/DomainExceptions/MyDomainErrorAttribute.cs (1)

1-1: Nullable disable directive is appropriate for gradual migration.

The #nullable disable directive follows the same valid migration pattern as other files in this PR.

Activout.RestClient.Newtonsoft.Json.Test/DomainExceptions/MyApiError.cs (1)

1-1: Nullable disable directive is appropriate for gradual migration.

Consistent with the PR's migration strategy.

Activout.RestClient.Newtonsoft.Json.Test/NewtonsoftJsonDeserializerTest.cs (1)

1-1: Nullable disable directive is appropriate for gradual migration.

This follows the PR's strategy of enabling nullable project-wide while incrementally migrating files.

Activout.RestClient.Newtonsoft.Json.Test/DomainExceptions/DomainExceptionErrorObjectTests.cs (1)

1-1: Nullable disable directive is appropriate for gradual migration.

Consistent with the PR's nullable reference type migration strategy.

Activout.RestClient.Newtonsoft.Json.Test/RestClientTests.cs (1)

1-1: Nullable disable directive is appropriate for gradual migration.

The directive follows the PR's migration pattern consistently.

Activout.RestClient.Newtonsoft.Json.Test/SimpleValueObjectTest.cs (1)

1-1: Nullable disable directive is appropriate for gradual migration.

Consistent with the PR's nullable migration approach.

Activout.RestClient.Newtonsoft.Json.Test/DomainExceptions/MyApiErrorResponse.cs (1)

1-1: Nullable disable directive is appropriate for gradual migration.

The directive aligns with the PR's migration strategy.

Activout.RestClient.Newtonsoft.Json.Test/Activout.RestClient.Newtonsoft.Json.Test.csproj (2)

6-6: Verify target framework against coding guidelines.

The coding guidelines specify using features from the latest stable .NET (9.x), but this project targets net8.0. Consider whether the project should be upgraded to net9.0 to align with the guidelines.

As per coding guidelines.


8-8: Good incremental nullable migration strategy.

Enabling nullable reference types at the project level while individual files opt out with #nullable disable is a solid approach for gradual migration. This allows new code to benefit from nullable analysis while existing code can be migrated file-by-file.

Note that the per-file #nullable disable directives should be considered temporary and removed as files are updated to properly handle nullability.

Activout.RestClient.Newtonsoft.Json.Test/DomainExceptions/DefaultDomainExceptionErrorObjectTests.cs (1)

1-1: Consistent nullable opt-out for gradual migration.

The #nullable disable directive appropriately opts this file out of nullable reference type checking as part of the project-wide nullable migration strategy. This should be removed once the file is updated to handle nullable reference types properly.

Activout.RestClient.Newtonsoft.Json.Test/MovieReviews/Review.cs (1)

1-1: Consistent nullable opt-out for gradual migration.

The #nullable disable directive appropriately opts this file out of nullable reference type checking as part of the project-wide nullable migration strategy. This should be removed once the file is updated to handle nullable reference types properly.

Activout.RestClient.Newtonsoft.Json.Test/DomainExceptions/MyDomainErrorEnum.cs (1)

1-1: Consistent nullable opt-out for gradual migration.

The #nullable disable directive appropriately opts this file out of nullable reference type checking as part of the project-wide nullable migration strategy. This should be removed once the file is updated to handle nullable reference types properly.

Activout.RestClient.Newtonsoft.Json.Test/DomainExceptions/DomainExceptionErrorEnumTests.cs (1)

1-1: Consistent nullable opt-out for gradual migration.

The #nullable disable directive appropriately opts this file out of nullable reference type checking as part of the project-wide nullable migration strategy. This should be removed once the file is updated to handle nullable reference types properly.

Activout.RestClient.Newtonsoft.Json.Test/SerializationOrderTest.cs (1)

1-1: Consistent nullable opt-out for gradual migration.

The #nullable disable directive appropriately opts this file out of nullable reference type checking as part of the project-wide nullable migration strategy. This should be removed once the file is updated to handle nullable reference types properly.

Activout.RestClient.Newtonsoft.Json.Test/MovieReviews/Movie.cs (1)

1-1: Consistent nullable opt-out for gradual migration.

The #nullable disable directive appropriately opts this file out of nullable reference type checking as part of the project-wide nullable migration strategy. This should be removed once the file is updated to handle nullable reference types properly.

Activout.RestClient.Newtonsoft.Json.Test/MovieReviews/ErrorResponse.cs (1)

1-1: Consistent nullable opt-out for gradual migration.

The #nullable disable directive appropriately opts this file out of nullable reference type checking as part of the project-wide nullable migration strategy. This should be removed once the file is updated to handle nullable reference types properly.

Activout.RestClient.Newtonsoft.Json.Test/LoggerFactoryHelpers.cs (1)

1-1: Consistent with the nullable migration strategy.

This follows the same incremental adoption pattern as other test files in this PR.

@twogood twogood merged commit 7141730 into main Oct 24, 2025
9 checks passed
@twogood twogood deleted the nullable-enable-start-Activout.RestClient.Newtonsoft.Json.Test branch October 24, 2025 20:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant