Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release 1.1.0: Fully Qualified Type Information #7

Merged
merged 4 commits into from
Aug 5, 2024
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
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [1.1.0] - 2024-08-05

## Changed

- The fully qualified type information for the subject upon which Fluentify has been placed is now captured and utilized when generating extensions, thereby enabling support for nested classes (#3).
- Utilized Microsoft.CodeAnalysis.CSharp.SourceGenerators.Testing to improve the quality of the Generator tests.

## Fixed

- The generated code files no longer include the namespace if the containing namespace is global (#6).
- The generated code files for classes now apply a conditional preprocessor directive to #nullable calls to prevent compilation failure in .NET Standard 2.0 projects.
- The generated extensions no longer call ArgumentNullException.ThrowIfNull to prevent compilation failure in .NET Standard 2.0 projects.
- The generated extensions no longer use pattern matching to prevent compilation failure in .NET Standard 2.0 projects.
- The generated constructor for records now applies a preprocessor directive to the SetRequiredMembers attribute to prevent compilation failure in .NET 6 projects (#5).

## [1.0.0] - 2024-07-22

Initial Release
Expand Down
1 change: 1 addition & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.10.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.Analyzer.Testing" Version="1.1.2" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.SourceGenerators.Testing" Version="1.1.2" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.10.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.Workspaces.Common" Version="4.10.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
Expand Down
2 changes: 1 addition & 1 deletion build/Tests.props
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<ExcludeByFile>**/*.Designer.cs</ExcludeByFile>
<NoWarn>CA1859;CA1861</NoWarn>
<RootNamespace>$(MSBuildProjectName.Replace('.Tests', ''))</RootNamespace>
<TargetFrameworks>net6.0;net8.0</TargetFrameworks>
<TargetFrameworks>net8.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.msbuild">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
namespace Fluentify.Console.Class.GlobalClassTests;

public sealed class WhenWithAgeIsCalled
{
[Fact]
public void GivenNullSubjectThenArgumentNullExceptionIsThrown()
{
// Arrange
GlobalClass? subject = default;

// Act
Func<GlobalClass> act = () => subject!.WithAge(1);

// Assert
_ = act.Should().Throw<ArgumentNullException>()
.WithParameterName(nameof(subject));
}

[Theory]
[InlineData(1)]
[InlineData(-1)]
[InlineData(0)]
[InlineData(int.MinValue)]
[InlineData(int.MaxValue)]
public void GivenAnAgeThenTheValueIsApplied(int age)
{
// Arrange
var original = new GlobalClass
{
Age = Random.Shared.Next(),
Attributes = [new(), new()],
Name = "Avery Brooks",
};

// Act
GlobalClass actual = original.WithAge(age);

// Assert
_ = actual.Should().NotBeSameAs(original);
_ = actual.Age.Should().Be(age);
_ = actual.Attributes.Should().BeEquivalentTo(original.Attributes);
_ = actual.Name.Should().BeEquivalentTo(original.Name);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
namespace Fluentify.Console.Class.GlobalClassTests;

public sealed class WhenWithAttributesIsCalled
{
[Fact]
public void GivenNullSubjectThenArgumentNullExceptionIsThrown()
{
// Arrange
GlobalClass? subject = default;

// Act
Func<GlobalClass> act = () => subject!.WithAttributes(new object());

// Assert
_ = act.Should().Throw<ArgumentNullException>()
.WithParameterName(nameof(subject));
}

[Fact]
public void GivenAttributesThenTheValueIsApplied()
{
// Arrange
object[] attributes = [new()];

var original = new GlobalClass
{
Age = Random.Shared.Next(),
Attributes = [],
Name = "Avery Brooks",
};

// Act
GlobalClass actual = original.WithAttributes(attributes);

// Assert
_ = actual.Should().NotBeSameAs(original);
_ = actual.Age.Should().Be(original.Age);
_ = actual.Attributes.Should().BeEquivalentTo(attributes);
_ = actual.Name.Should().Be(original.Name);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
namespace Fluentify.Console.Class.GlobalClassTests;

public sealed class WhenWithNameIsCalled
{
[Fact]
public void GivenNullSubjectThenArgumentNullExceptionIsThrown()
{
// Arrange
GlobalClass? subject = default;

// Act
Func<GlobalClass> act = () => subject!.WithName("Avery Brooks");

// Assert
_ = act.Should().Throw<ArgumentNullException>()
.WithParameterName(nameof(subject));
}

[Theory]
[InlineData("Avery Brooks")]
[InlineData("")]
[InlineData(" ")]
public void GivenANameThenTheValueIsApplied(string name)
{
// Arrange
var original = new GlobalClass
{
Age = Random.Shared.Next(),
Attributes = [new(), new()],
Name = "Patrick Stewart",
};

// Act
GlobalClass actual = original.WithName(name);

// Assert
_ = actual.Should().NotBeSameAs(original);
_ = actual.Age.Should().Be(original.Age);
_ = actual.Attributes.Should().BeEquivalentTo(original.Attributes);
_ = actual.Name.Should().BeEquivalentTo(name);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
namespace Fluentify.Console.Record.GlobalRecordTests;

public sealed class WhenWithAgeIsCalled
{
[Fact]
public void GivenNullSubjectThenArgumentNullExceptionIsThrown()
{
// Arrange
GlobalRecord? subject = default;

// Act
Func<GlobalRecord> act = () => subject!.WithAge(1);

// Assert
_ = act.Should().Throw<ArgumentNullException>()
.WithParameterName(nameof(subject));
}

[Theory]
[InlineData(1)]
[InlineData(-1)]
[InlineData(0)]
[InlineData(int.MinValue)]
[InlineData(int.MaxValue)]
public void GivenAnAgeThenTheValueIsApplied(int age)
{
// Arrange
var original = new GlobalRecord
{
Age = Random.Shared.Next(),
Attributes = [new(), new()],
Name = "Avery Brooks",
};

// Act
GlobalRecord actual = original.WithAge(age);

// Assert
_ = actual.Should().NotBeSameAs(original);
_ = actual.Age.Should().Be(age);
_ = actual.Attributes.Should().BeEquivalentTo(original.Attributes);
_ = actual.Name.Should().BeEquivalentTo(original.Name);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
namespace Fluentify.Console.Record.GlobalRecordTests;

public sealed class WhenWithAttributesIsCalled
{
[Fact]
public void GivenNullSubjectThenArgumentNullExceptionIsThrown()
{
// Arrange
GlobalRecord? subject = default;

// Act
Func<GlobalRecord> act = () => subject!.WithAttributes(new object());

// Assert
_ = act.Should().Throw<ArgumentNullException>()
.WithParameterName(nameof(subject));
}

[Fact]
public void GivenAttributesThenTheValueIsApplied()
{
// Arrange
object[] attributes = [new()];

var original = new GlobalRecord
{
Age = Random.Shared.Next(),
Attributes = [],
Name = "Avery Brooks",
};

// Act
GlobalRecord actual = original.WithAttributes(attributes);

// Assert
_ = actual.Should().NotBeSameAs(original);
_ = actual.Age.Should().Be(original.Age);
_ = actual.Attributes.Should().BeEquivalentTo(attributes);
_ = actual.Name.Should().Be(original.Name);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
namespace Fluentify.Console.Record.GlobalRecordTests;

public sealed class WhenWithNameIsCalled
{
[Fact]
public void GivenNullSubjectThenArgumentNullExceptionIsThrown()
{
// Arrange
GlobalRecord? subject = default;

// Act
Func<GlobalRecord> act = () => subject!.WithName("Avery Brooks");

// Assert
_ = act.Should().Throw<ArgumentNullException>()
.WithParameterName(nameof(subject));
}

[Theory]
[InlineData("Avery Brooks")]
[InlineData("")]
[InlineData(" ")]
public void GivenANameThenTheValueIsApplied(string name)
{
// Arrange
var original = new GlobalRecord
{
Age = Random.Shared.Next(),
Attributes = [new(), new()],
Name = "Patrick Stewart",
};

// Act
GlobalRecord actual = original.WithName(name);

// Assert
_ = actual.Should().NotBeSameAs(original);
_ = actual.Age.Should().Be(original.Age);
_ = actual.Attributes.Should().BeEquivalentTo(original.Attributes);
_ = actual.Name.Should().BeEquivalentTo(name);
}
}
36 changes: 36 additions & 0 deletions src/Fluentify.Console/Class/GlobalClass.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#pragma warning disable SA1200 // Using directives should be placed correctly
using System.Diagnostics.CodeAnalysis;
using Fluentify;
#pragma warning restore SA1200 // Using directives should be placed correctly

/// <summary>
/// A class that demonstrates the libraries use without generics.
/// </summary>
[Fluentify]
[SuppressMessage("Major Bug", "S3903:Types should be defined in named namespaces", Justification = "The class is intended to demonstrate use in the global namespace.")]
internal sealed class GlobalClass
{
/// <summary>
/// Gets or sets the first property to be subject to the extension generator.
/// </summary>
/// <value>
/// The first property to be subject to the extension generator.
/// </value>
public int Age { get; init; }

/// <summary>
/// Gets or sets the second property to be subject to the extension generator.
/// </summary>
/// <value>
/// The second property to be subject to the extension generator.
/// </value>
public string Name { get; init; } = string.Empty;

/// <summary>
/// Gets or sets the third property to be subject to the extension generator.
/// </summary>
/// <value>
/// The third property to be subject to the extension generator.
/// </value>
public IReadOnlyList<object>? Attributes { get; init; }
}
14 changes: 14 additions & 0 deletions src/Fluentify.Console/Record/GlobalRecord.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#pragma warning disable SA1200 // Using directives should be placed correctly
using System.Diagnostics.CodeAnalysis;
using Fluentify;
#pragma warning restore SA1200 // Using directives should be placed correctly

/// <summary>
/// A class that demonstrates the libraries use without generics.
/// </summary>
/// <param name="Age">The first property to be subject to the extension generator.</param>
/// <param name="Name">The second property to be subject to the extension generator.</param>
/// <param name="Attributes">The third property to be subject to the extension generator.</param>
[Fluentify]
[SuppressMessage("Major Bug", "S3903:Types should be defined in named namespaces", Justification = "The class is intended to demonstrate use in the global namespace.")]
internal sealed partial record GlobalRecord(int Age, string Name, IReadOnlyList<object>? Attributes = default);
Loading