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

feat: add nunit types assertions #296

Merged
merged 1 commit into from
Jan 18, 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
161 changes: 159 additions & 2 deletions src/FluentAssertions.Analyzers.Tests/Tips/NunitTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,7 @@ public void Nunit4_AssertEqualDouble_TestCodeFix(string oldAssertion, string new
[Implemented]
public void Nunit3_AssertEqualObject_TestAnalyzer(string assertion)
=> Nunit3VerifyDiagnostic("object expected, object actual", assertion);

[DataTestMethod]
[AssertionDiagnostic("ClassicAssert.AreEqual(expected, actual{0});")]
[Implemented]
Expand Down Expand Up @@ -479,7 +479,7 @@ public void Nunit3_AssertNotEqualObject_TestCodeFix(string oldAssertion, string
[Implemented]
public void Nunit4_AssertNotEqualObject_TestCodeFix(string oldAssertion, string newAssertion)
=> Nunit4VerifyFix("object expected, object actual", oldAssertion, newAssertion);

[DataTestMethod]
[AssertionDiagnostic("Assert.AreSame(expected, actual{0});")]
[Implemented]
Expand Down Expand Up @@ -510,6 +510,163 @@ public void Nunit4_AssertSame_TestCodeFix(string oldAssertion, string newAsserti

#endregion

#region Assert.Types.cs

[DataTestMethod]
[AssertionDiagnostic("Assert.IsAssignableFrom(typeof(string), actual{0});")]
[AssertionDiagnostic("Assert.IsAssignableFrom(expected, actual{0});")]
[AssertionDiagnostic("Assert.IsAssignableFrom<string>(actual{0});")]
[Implemented]
public void Nunit3_AssertIsAssignableFrom_TestAnalyzer(string assertion)
=> Nunit3VerifyDiagnostic("object actual, Type expected", assertion);

[DataTestMethod]
[AssertionDiagnostic("ClassicAssert.IsAssignableFrom(typeof(string), actual{0});")]
[AssertionDiagnostic("ClassicAssert.IsAssignableFrom(expected, actual{0});")]
[AssertionDiagnostic("ClassicAssert.IsAssignableFrom<string>(actual{0});")]
[Implemented]
public void Nunit4_AssertIsAssignableFrom_TestAnalyzer(string assertion)
=> Nunit4VerifyDiagnostic("object actual, Type expected", assertion);

[DataTestMethod]
[AssertionCodeFix(
oldAssertion: "Assert.IsAssignableFrom(typeof(string), actual{0});",
newAssertion: "actual.Should().BeAssignableTo<string>({0});")]
[AssertionCodeFix(
oldAssertion: "Assert.IsAssignableFrom(expected, actual{0});",
newAssertion: "actual.Should().BeAssignableTo(expected{0});")]
[Implemented]
public void Nunit3_AssertIsAssignableFrom_TestCodeFix(string oldAssertion, string newAssertion)
=> Nunit3VerifyFix("object actual, Type expected", oldAssertion, newAssertion);

[DataTestMethod]
[AssertionCodeFix(
oldAssertion: "ClassicAssert.IsAssignableFrom(typeof(string), actual{0});",
newAssertion: "actual.Should().BeAssignableTo<string>({0});")]
[AssertionCodeFix(
oldAssertion: "ClassicAssert.IsAssignableFrom(expected, actual{0});",
newAssertion: "actual.Should().BeAssignableTo(expected{0});")]
[Implemented]
public void Nunit4_AssertIsAssignableFrom_TestCodeFix(string oldAssertion, string newAssertion)
=> Nunit4VerifyFix("object actual, Type expected", oldAssertion, newAssertion);

[DataTestMethod]
[AssertionDiagnostic("Assert.IsNotAssignableFrom(typeof(string), actual{0});")]
[AssertionDiagnostic("Assert.IsNotAssignableFrom(expected, actual{0});")]
[AssertionDiagnostic("Assert.IsNotAssignableFrom<string>(actual{0});")]
[Implemented]
public void Nunit3_AssertIsNotAssignableFrom_TestAnalyzer(string assertion)
=> Nunit3VerifyDiagnostic("object actual, Type expected", assertion);

[DataTestMethod]
[AssertionDiagnostic("ClassicAssert.IsNotAssignableFrom(typeof(string), actual{0});")]
[AssertionDiagnostic("ClassicAssert.IsNotAssignableFrom(expected, actual{0});")]
[AssertionDiagnostic("ClassicAssert.IsNotAssignableFrom<string>(actual{0});")]
[Implemented]
public void Nunit4_AssertIsNotAssignableFrom_TestAnalyzer(string assertion)
=> Nunit4VerifyDiagnostic("object actual, Type expected", assertion);

[DataTestMethod]
[AssertionCodeFix(
oldAssertion: "Assert.IsNotAssignableFrom(typeof(string), actual{0});",
newAssertion: "actual.Should().NotBeAssignableTo<string>({0});")]
[AssertionCodeFix(
oldAssertion: "Assert.IsNotAssignableFrom(expected, actual{0});",
newAssertion: "actual.Should().NotBeAssignableTo(expected{0});")]
[Implemented]
public void Nunit3_AssertIsNotAssignableFrom_TestCodeFix(string oldAssertion, string newAssertion)
=> Nunit3VerifyFix("object actual, Type expected", oldAssertion, newAssertion);

[DataTestMethod]
[AssertionCodeFix(
oldAssertion: "ClassicAssert.IsNotAssignableFrom(typeof(string), actual{0});",
newAssertion: "actual.Should().NotBeAssignableTo<string>({0});")]
[AssertionCodeFix(
oldAssertion: "ClassicAssert.IsNotAssignableFrom(expected, actual{0});",
newAssertion: "actual.Should().NotBeAssignableTo(expected{0});")]
[Implemented]
public void Nunit4_AssertIsNotAssignableFrom_TestCodeFix(string oldAssertion, string newAssertion)
=> Nunit4VerifyFix("object actual, Type expected", oldAssertion, newAssertion);

// void IsInstanceOf(Type expected, object? actual, string message, params object?[]? args)
[DataTestMethod]
[AssertionDiagnostic("Assert.IsInstanceOf(typeof(string), actual{0});")]
[AssertionDiagnostic("Assert.IsInstanceOf(expected, actual{0});")]
[AssertionDiagnostic("Assert.IsInstanceOf<string>(actual{0});")]
[Implemented]
public void Nunit3_AssertIsInstanceOf_TestAnalyzer(string assertion)
=> Nunit3VerifyDiagnostic("object actual, Type expected", assertion);

[DataTestMethod]
[AssertionDiagnostic("ClassicAssert.IsInstanceOf(typeof(string), actual{0});")]
[AssertionDiagnostic("ClassicAssert.IsInstanceOf(expected, actual{0});")]
[AssertionDiagnostic("ClassicAssert.IsInstanceOf<string>(actual{0});")]
[Implemented]
public void Nunit4_AssertIsInstanceOf_TestAnalyzer(string assertion)
=> Nunit4VerifyDiagnostic("object actual, Type expected", assertion);

[DataTestMethod]
[AssertionCodeFix(
oldAssertion: "Assert.IsInstanceOf(typeof(string), actual{0});",
newAssertion: "actual.Should().BeOfType<string>({0});")]
[AssertionCodeFix(
oldAssertion: "Assert.IsInstanceOf(expected, actual{0});",
newAssertion: "actual.Should().BeOfType(expected{0});")]
[Implemented]
public void Nunit3_AssertIsInstanceOf_TestCodeFix(string oldAssertion, string newAssertion)
=> Nunit3VerifyFix("object actual, Type expected", oldAssertion, newAssertion);

[DataTestMethod]
[AssertionCodeFix(
oldAssertion: "ClassicAssert.IsInstanceOf(typeof(string), actual{0});",
newAssertion: "actual.Should().BeOfType<string>({0});")]
[AssertionCodeFix(
oldAssertion: "ClassicAssert.IsInstanceOf(expected, actual{0});",
newAssertion: "actual.Should().BeOfType(expected{0});")]
[Implemented]
public void Nunit4_AssertIsInstanceOf_TestCodeFix(string oldAssertion, string newAssertion)
=> Nunit4VerifyFix("object actual, Type expected", oldAssertion, newAssertion);

[DataTestMethod]
[AssertionDiagnostic("Assert.IsNotInstanceOf(typeof(string), actual{0});")]
[AssertionDiagnostic("Assert.IsNotInstanceOf(expected, actual{0});")]
[AssertionDiagnostic("Assert.IsNotInstanceOf<string>(actual{0});")]
[Implemented]
public void Nunit3_AssertIsNotInstanceOf_TestAnalyzer(string assertion)
=> Nunit3VerifyDiagnostic("object actual, Type expected", assertion);

[DataTestMethod]
[AssertionDiagnostic("ClassicAssert.IsNotInstanceOf(typeof(string), actual{0});")]
[AssertionDiagnostic("ClassicAssert.IsNotInstanceOf(expected, actual{0});")]
[AssertionDiagnostic("ClassicAssert.IsNotInstanceOf<string>(actual{0});")]
[Implemented]
public void Nunit4_AssertIsNotInstanceOf_TestAnalyzer(string assertion)
=> Nunit4VerifyDiagnostic("object actual, Type expected", assertion);

[DataTestMethod]
[AssertionCodeFix(
oldAssertion: "Assert.IsNotInstanceOf(typeof(string), actual{0});",
newAssertion: "actual.Should().NotBeOfType<string>({0});")]
[AssertionCodeFix(
oldAssertion: "Assert.IsNotInstanceOf(expected, actual{0});",
newAssertion: "actual.Should().NotBeOfType(expected{0});")]
[Implemented]
public void Nunit3_AssertIsNotInstanceOf_TestCodeFix(string oldAssertion, string newAssertion)
=> Nunit3VerifyFix("object actual, Type expected", oldAssertion, newAssertion);

[DataTestMethod]
[AssertionCodeFix(
oldAssertion: "ClassicAssert.IsNotInstanceOf(typeof(string), actual{0});",
newAssertion: "actual.Should().NotBeOfType<string>({0});")]
[AssertionCodeFix(
oldAssertion: "ClassicAssert.IsNotInstanceOf(expected, actual{0});",
newAssertion: "actual.Should().NotBeOfType(expected{0});")]
[Implemented]
public void Nunit4_AssertIsNotInstanceOf_TestCodeFix(string oldAssertion, string newAssertion)
=> Nunit4VerifyFix("object actual, Type expected", oldAssertion, newAssertion);

#endregion

private void Nunit3VerifyDiagnostic(string methodArguments, string assertion)
=> VerifyDiagnostic(GenerateCode.Nunit3Assertion(methodArguments, assertion), PackageReference.Nunit_3_14_0);
private void Nunit3VerifyFix(string methodArguments, string oldAssertion, string newAssertion)
Expand Down
54 changes: 53 additions & 1 deletion src/FluentAssertions.Analyzers/Tips/NunitCodeFixProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ protected override CreateChangedDocument TryComputeFixCore(IInvocationOperation
{
var assertType = invocation.TargetMethod.ContainingType;
var nunitVersion = assertType.ContainingAssembly.Identity.Version;

var isNunit3 = nunitVersion >= new Version(3, 0, 0, 0) && nunitVersion < new Version(4, 0, 0, 0);
var isNunit4 = nunitVersion >= new Version(4, 0, 0, 0) && nunitVersion < new Version(5, 0, 0, 0);

Expand Down Expand Up @@ -119,6 +119,58 @@ private CreateChangedDocument TryComputeFixForNunitClassicAssert(IInvocationOper
return DocumentEditorUtils.RenameMethodToSubjectShouldAssertion(invocation, context, "BeSameAs", subjectIndex: 1, argumentsToRemove: []);
case "AreNotSame": // Assert.AreNotSame(object expected, object actual)
return DocumentEditorUtils.RenameMethodToSubjectShouldAssertion(invocation, context, "NotBeSameAs", subjectIndex: 1, argumentsToRemove: []);
case "IsAssignableFrom" when ArgumentsAreTypeOf(invocation, t.Type, t.Object): // Assert.IsAssignableFrom(Type expectedType, object obj)
case "IsAssignableFrom" when ArgumentsAreTypeOf(invocation, t.Type, t.Object, t.String, t.ObjectArray): // Assert.IsAssignableFrom(Type expectedType, object obj, string message, params object[] parms)
{
if (invocation.Arguments[0].Value is not ITypeOfOperation typeOf)
{
return DocumentEditorUtils.RenameMethodToSubjectShouldAssertion(invocation, context, "BeAssignableTo", subjectIndex: 1, argumentsToRemove: []);
}

return DocumentEditorUtils.RenameMethodToSubjectShouldGenericAssertion(invocation, ImmutableArray.Create(typeOf.TypeOperand), context, "BeAssignableTo", subjectIndex: 1, argumentsToRemove: [0]);
}
case "IsAssignableFrom" when ArgumentsAreTypeOf(invocation, t.Object): // Assert.IsAssignableFrom<T>(object actual)
case "IsAssignableFrom" when ArgumentsAreTypeOf(invocation, t.Object, t.String, t.ObjectArray): // Assert.IsAssignableFrom<T>(object actual, string message, params object[] parms)
return DocumentEditorUtils.RenameGenericMethodToSubjectShouldGenericAssertion(invocation, context, "BeAssignableTo", subjectIndex: 0, argumentsToRemove: []);
case "IsNotAssignableFrom" when ArgumentsAreTypeOf(invocation, t.Type, t.Object): // Assert.IsNotAssignableFrom(Type expectedType, object obj)
case "IsNotAssignableFrom" when ArgumentsAreTypeOf(invocation, t.Type, t.Object, t.String, t.ObjectArray): // Assert.IsNotAssignableFrom(Type expectedType, object obj, string message, params object[] parms)
{
if (invocation.Arguments[0].Value is not ITypeOfOperation typeOf)
{
return DocumentEditorUtils.RenameMethodToSubjectShouldAssertion(invocation, context, "NotBeAssignableTo", subjectIndex: 1, argumentsToRemove: []);
}

return DocumentEditorUtils.RenameMethodToSubjectShouldGenericAssertion(invocation, ImmutableArray.Create(typeOf.TypeOperand), context, "NotBeAssignableTo", subjectIndex: 1, argumentsToRemove: [0]);
}
case "IsNotAssignableFrom" when ArgumentsAreTypeOf(invocation, t.Object): // Assert.IsNotAssignableFrom<T>(object actual)
case "IsNotAssignableFrom" when ArgumentsAreTypeOf(invocation, t.Object, t.String, t.ObjectArray): // Assert.IsNotAssignableFrom<T>(object actual, string message, params object[] parms)
return DocumentEditorUtils.RenameGenericMethodToSubjectShouldGenericAssertion(invocation, context, "NotBeAssignableTo", subjectIndex: 0, argumentsToRemove: []);
case "IsInstanceOf" when ArgumentsAreTypeOf(invocation, t.Type, t.Object): // Assert.IsInstanceOf(Type expectedType, object actual)
case "IsInstanceOf" when ArgumentsAreTypeOf(invocation, t.Type, t.Object, t.String, t.ObjectArray): // Assert.IsInstanceOf(Type expectedType, object actual, string message, params object[] parms)
{
if (invocation.Arguments[0].Value is not ITypeOfOperation typeOf)
{
return DocumentEditorUtils.RenameMethodToSubjectShouldAssertion(invocation, context, "BeOfType", subjectIndex: 1, argumentsToRemove: []);
}

return DocumentEditorUtils.RenameMethodToSubjectShouldGenericAssertion(invocation, ImmutableArray.Create(typeOf.TypeOperand), context, "BeOfType", subjectIndex: 1, argumentsToRemove: [0]);
}
case "IsInstanceOf" when ArgumentsAreTypeOf(invocation, t.Object): // Assert.IsInstanceOf<T>(object actual)
case "IsInstanceOf" when ArgumentsAreTypeOf(invocation, t.Object, t.String, t.ObjectArray): // Assert.IsInstanceOf<T>(object actual, string message, params object[] parms)
return DocumentEditorUtils.RenameGenericMethodToSubjectShouldGenericAssertion(invocation, context, "BeOfType", subjectIndex: 0, argumentsToRemove: []);
case "IsNotInstanceOf" when ArgumentsAreTypeOf(invocation, t.Type, t.Object): // Assert.IsNotInstanceOf(Type expectedType, object actual)
case "IsNotInstanceOf" when ArgumentsAreTypeOf(invocation, t.Type, t.Object, t.String, t.ObjectArray): // Assert.IsNotInstanceOf(Type expectedType, object actual, string message, params object[] parms)
{
if (invocation.Arguments[0].Value is not ITypeOfOperation typeOf)
{
return DocumentEditorUtils.RenameMethodToSubjectShouldAssertion(invocation, context, "NotBeOfType", subjectIndex: 1, argumentsToRemove: []);
}

return DocumentEditorUtils.RenameMethodToSubjectShouldGenericAssertion(invocation, ImmutableArray.Create(typeOf.TypeOperand), context, "NotBeOfType", subjectIndex: 1, argumentsToRemove: [0]);
}
case "IsNotInstanceOf" when ArgumentsAreTypeOf(invocation, t.Object): // Assert.IsNotInstanceOf<T>(object actual)
case "IsNotInstanceOf" when ArgumentsAreTypeOf(invocation, t.Object, t.String, t.ObjectArray): // Assert.IsNotInstanceOf<T>(object actual, string message, params object[] parms)
return DocumentEditorUtils.RenameGenericMethodToSubjectShouldGenericAssertion(invocation, context, "NotBeOfType", subjectIndex: 0, argumentsToRemove: []);
}
return null;
}
Expand Down
Loading