Skip to content

Commit 9fd07fb

Browse files
authored
feat: nunit numeric assertions (#294)
* feat: add nunit numeric assertions
1 parent 5481668 commit 9fd07fb

File tree

3 files changed

+261
-25
lines changed

3 files changed

+261
-25
lines changed

src/FluentAssertions.Analyzers.Tests/Tips/NunitTests.cs

Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System;
12
using FluentAssertions.Analyzers.TestUtils;
23
using Microsoft.CodeAnalysis;
34
using Microsoft.VisualStudio.TestTools.UnitTesting;
@@ -192,6 +193,200 @@ public class NunitTests
192193
[Implemented]
193194
public void Nunit4_AssertNotNull_TestCodeFix(string oldAssertion, string newAssertion) => Nunit4VerifyFix("object actual", oldAssertion, newAssertion);
194195

196+
[DataTestMethod]
197+
[AssertionDiagnostic("Assert.Greater(arg1, arg2{0});")]
198+
[Implemented]
199+
public void Nunit3_AssertGreater_TestAnalyzer(string assertion)
200+
{
201+
foreach (var comparableArgument in ComparableArguments)
202+
{
203+
Nunit3VerifyDiagnostic(comparableArgument, assertion);
204+
}
205+
}
206+
207+
[DataTestMethod]
208+
[AssertionDiagnostic("ClassicAssert.Greater(arg1, arg2{0});")]
209+
[Implemented]
210+
public void Nunit4_AssertGreater_TestAnalyzer(string assertion)
211+
{
212+
foreach (var comparableArgument in ComparableArguments)
213+
{
214+
Nunit4VerifyDiagnostic(comparableArgument, assertion);
215+
}
216+
}
217+
218+
[DataTestMethod]
219+
[AssertionCodeFix(
220+
oldAssertion: "Assert.Greater(arg1, arg2{0});",
221+
newAssertion: "arg1.Should().BeGreaterThan(arg2{0});")]
222+
[Implemented]
223+
public void Nunit3_AssertGreater_TestCodeFix(string oldAssertion, string newAssertion)
224+
{
225+
foreach (var comparableArgument in ComparableArguments)
226+
{
227+
Nunit3VerifyFix(comparableArgument, oldAssertion, newAssertion);
228+
}
229+
}
230+
231+
[DataTestMethod]
232+
[AssertionCodeFix(
233+
oldAssertion: "ClassicAssert.Greater(arg1, arg2{0});",
234+
newAssertion: "arg1.Should().BeGreaterThan(arg2{0});")]
235+
[Implemented]
236+
public void Nunit4_AssertGreater_TestCodeFix(string oldAssertion, string newAssertion)
237+
{
238+
foreach (var comparableArgument in ComparableArguments)
239+
{
240+
Nunit4VerifyFix(comparableArgument, oldAssertion, newAssertion);
241+
}
242+
}
243+
244+
[DataTestMethod]
245+
[AssertionDiagnostic("Assert.GreaterOrEqual(arg1, arg2{0});")]
246+
[Implemented]
247+
public void Nunit3_AssertGreaterOrEqual_TestAnalyzer(string assertion)
248+
{
249+
foreach (var comparableArgument in ComparableArguments)
250+
{
251+
Nunit3VerifyDiagnostic(comparableArgument, assertion);
252+
}
253+
}
254+
255+
[DataTestMethod]
256+
[AssertionDiagnostic("ClassicAssert.GreaterOrEqual(arg1, arg2{0});")]
257+
[Implemented]
258+
public void Nunit4_AssertGreaterOrEqual_TestAnalyzer(string assertion)
259+
{
260+
foreach (var comparableArgument in ComparableArguments)
261+
{
262+
Nunit4VerifyDiagnostic(comparableArgument, assertion);
263+
}
264+
}
265+
266+
[DataTestMethod]
267+
[AssertionCodeFix(
268+
oldAssertion: "Assert.GreaterOrEqual(arg1, arg2{0});",
269+
newAssertion: "arg1.Should().BeGreaterOrEqualTo(arg2{0});")]
270+
[Implemented]
271+
public void Nunit3_AssertGreaterOrEqual_TestCodeFix(string oldAssertion, string newAssertion)
272+
{
273+
foreach (var comparableArgument in ComparableArguments)
274+
{
275+
Nunit3VerifyFix(comparableArgument, oldAssertion, newAssertion);
276+
}
277+
}
278+
279+
[DataTestMethod]
280+
[AssertionCodeFix(
281+
oldAssertion: "ClassicAssert.GreaterOrEqual(arg1, arg2{0});",
282+
newAssertion: "arg1.Should().BeGreaterOrEqualTo(arg2{0});")]
283+
[Implemented]
284+
public void Nunit4_AssertGreaterOrEqual_TestCodeFix(string oldAssertion, string newAssertion)
285+
{
286+
foreach (var comparableArgument in ComparableArguments)
287+
{
288+
Nunit4VerifyFix(comparableArgument, oldAssertion, newAssertion);
289+
}
290+
}
291+
292+
[DataTestMethod]
293+
[AssertionDiagnostic("Assert.Less(arg1, arg2{0});")]
294+
[Implemented]
295+
public void Nunit3_AssertLess_TestAnalyzer(string assertion)
296+
{
297+
foreach (var comparableArgument in ComparableArguments)
298+
{
299+
Nunit3VerifyDiagnostic(comparableArgument, assertion);
300+
}
301+
}
302+
303+
[DataTestMethod]
304+
[AssertionDiagnostic("ClassicAssert.Less(arg1, arg2{0});")]
305+
[Implemented]
306+
public void Nunit4_AssertLess_TestAnalyzer(string assertion)
307+
{
308+
foreach (var comparableArgument in ComparableArguments)
309+
{
310+
Nunit4VerifyDiagnostic(comparableArgument, assertion);
311+
}
312+
}
313+
314+
[DataTestMethod]
315+
[AssertionCodeFix(
316+
oldAssertion: "Assert.Less(arg1, arg2{0});",
317+
newAssertion: "arg1.Should().BeLessThan(arg2{0});")]
318+
[Implemented]
319+
public void Nunit3_AssertLess_TestCodeFix(string oldAssertion, string newAssertion)
320+
{
321+
foreach (var comparableArgument in ComparableArguments)
322+
{
323+
Nunit3VerifyFix(comparableArgument, oldAssertion, newAssertion);
324+
}
325+
}
326+
327+
[DataTestMethod]
328+
[AssertionCodeFix(
329+
oldAssertion: "ClassicAssert.Less(arg1, arg2{0});",
330+
newAssertion: "arg1.Should().BeLessThan(arg2{0});")]
331+
[Implemented]
332+
public void Nunit4_AssertLess_TestCodeFix(string oldAssertion, string newAssertion)
333+
{
334+
foreach (var comparableArgument in ComparableArguments)
335+
{
336+
Nunit4VerifyFix(comparableArgument, oldAssertion, newAssertion);
337+
}
338+
}
339+
340+
[DataTestMethod]
341+
[AssertionDiagnostic("Assert.LessOrEqual(arg1, arg2{0});")]
342+
[Implemented]
343+
public void Nunit3_AssertLessOrEqual_TestAnalyzer(string assertion)
344+
{
345+
foreach (var comparableArgument in ComparableArguments)
346+
{
347+
Nunit3VerifyDiagnostic(comparableArgument, assertion);
348+
}
349+
}
350+
351+
[DataTestMethod]
352+
[AssertionDiagnostic("ClassicAssert.LessOrEqual(arg1, arg2{0});")]
353+
[Implemented]
354+
public void Nunit4_AssertLessOrEqual_TestAnalyzer(string assertion)
355+
{
356+
foreach (var comparableArgument in ComparableArguments)
357+
{
358+
Nunit4VerifyDiagnostic(comparableArgument, assertion);
359+
}
360+
}
361+
362+
[DataTestMethod]
363+
[AssertionCodeFix(
364+
oldAssertion: "Assert.LessOrEqual(arg1, arg2{0});",
365+
newAssertion: "arg1.Should().BeLessOrEqualTo(arg2{0});")]
366+
[Implemented]
367+
public void Nunit3_AssertLessOrEqual_TestCodeFix(string oldAssertion, string newAssertion)
368+
{
369+
foreach (var comparableArgument in ComparableArguments)
370+
{
371+
Nunit3VerifyFix(comparableArgument, oldAssertion, newAssertion);
372+
}
373+
}
374+
375+
[DataTestMethod]
376+
[AssertionCodeFix(
377+
oldAssertion: "ClassicAssert.LessOrEqual(arg1, arg2{0});",
378+
newAssertion: "arg1.Should().BeLessOrEqualTo(arg2{0});")]
379+
[Implemented]
380+
public void Nunit4_AssertLessOrEqual_TestCodeFix(string oldAssertion, string newAssertion)
381+
{
382+
foreach (var comparableArgument in ComparableArguments)
383+
{
384+
Nunit4VerifyFix(comparableArgument, oldAssertion, newAssertion);
385+
}
386+
}
387+
388+
private static readonly string[] ComparableArguments = Array.ConvertAll(new string[] { "int", "uint", "long", "ulong", "float", "double", "decimal" }, x => $"{x} arg1, {x} arg2");
389+
195390
private void Nunit3VerifyDiagnostic(string methodArguments, string assertion)
196391
=> VerifyDiagnostic(GenerateCode.Nunit3Assertion(methodArguments, assertion), PackageReference.Nunit_3_14_0);
197392
private void Nunit3VerifyFix(string methodArguments, string oldAssertion, string newAssertion)

src/FluentAssertions.Analyzers/Tips/NunitCodeFixProvider.cs

Lines changed: 63 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,15 @@ protected override CreateChangedDocument TryComputeFixCore(IInvocationOperation
2222

2323
return assertType.Name switch
2424
{
25-
"Assert" when isNunit3 => TryComputeFixForNunit3Assert(invocation, context, t),
26-
"ClassicAssert" when isNunit4 => TryComputeFixForNunit4ClassicAssert(invocation, context, t),
25+
"Assert" when isNunit3 => TryComputeFixForNunitClassicAssert(invocation, context, t),
26+
"ClassicAssert" when isNunit4 => TryComputeFixForNunitClassicAssert(invocation, context, t),
2727
//"StringAssert" => TryComputeFixForStringAssert(invocation, context, testContext),
2828
//"CollectionAssert" => TryComputeFixForCollectionAssert(invocation, context, testContext),
2929
_ => null
3030
};
3131
}
3232

33-
private CreateChangedDocument TryComputeFixForNunit3Assert(IInvocationOperation invocation, CodeFixContext context, TestingFrameworkCodeFixContext t)
33+
private CreateChangedDocument TryComputeFixForNunitClassicAssert(IInvocationOperation invocation, CodeFixContext context, TestingFrameworkCodeFixContext t)
3434
{
3535
switch (invocation.TargetMethod.Name)
3636
{
@@ -46,29 +46,67 @@ private CreateChangedDocument TryComputeFixForNunit3Assert(IInvocationOperation
4646
case "NotNull": // Assert.NotNull(object anObject)
4747
case "IsNotNull": // Assert.IsNotNull(object anObject)
4848
return DocumentEditorUtils.RenameMethodToSubjectShouldAssertion(invocation, context, "NotBeNull", subjectIndex: 0, argumentsToRemove: []);
49+
case "Greater" when ArgumentsAreTypeOf(invocation, t.Int32, t.Int32): // Assert.Greater(int arg1, int arg2)
50+
case "Greater" when ArgumentsAreTypeOf(invocation, t.UInt32, t.UInt32): // Assert.Greater(uint arg1, uint arg2)
51+
case "Greater" when ArgumentsAreTypeOf(invocation, t.Long, t.Long): // Assert.Greater(long arg1, long arg2)
52+
case "Greater" when ArgumentsAreTypeOf(invocation, t.ULong, t.ULong): // Assert.Greater(ulong arg1, ulong arg2)
53+
case "Greater" when ArgumentsAreTypeOf(invocation, t.Float, t.Float): // Assert.Greater(float arg1, float arg2)
54+
case "Greater" when ArgumentsAreTypeOf(invocation, t.Double, t.Double): // Assert.Greater(double arg1, double arg2)
55+
case "Greater" when ArgumentsAreTypeOf(invocation, t.Decimal, t.Decimal): // Assert.Greater(decimal arg1, decimal arg2)
56+
case "Greater" when ArgumentsAreTypeOf(invocation, t.Int32, t.Int32, t.String, t.ObjectArray): // Assert.Greater(int arg1, int arg2, string message, params object[] parms)
57+
case "Greater" when ArgumentsAreTypeOf(invocation, t.UInt32, t.UInt32, t.String, t.ObjectArray): // Assert.Greater(uint arg1, uint arg2, string message, params object[] parms)
58+
case "Greater" when ArgumentsAreTypeOf(invocation, t.Long, t.Long, t.String, t.ObjectArray): // Assert.Greater(long arg1, long arg2, string message, params object[] parms)
59+
case "Greater" when ArgumentsAreTypeOf(invocation, t.ULong, t.ULong, t.String, t.ObjectArray): // Assert.Greater(ulong arg1, ulong arg2, string message, params object[] parms)
60+
case "Greater" when ArgumentsAreTypeOf(invocation, t.Float, t.Float, t.String, t.ObjectArray): // Assert.Greater(float arg1, float arg2, string message, params object[] parms)
61+
case "Greater" when ArgumentsAreTypeOf(invocation, t.Double, t.Double, t.String, t.ObjectArray): // Assert.Greater(double arg1, double arg2, string message, params object[] parms)
62+
case "Greater" when ArgumentsAreTypeOf(invocation, t.Decimal, t.Decimal, t.String, t.ObjectArray): // Assert.Greater(decimal arg1, decimal arg2, string message, params object[] parms)
63+
return DocumentEditorUtils.RenameMethodToSubjectShouldAssertion(invocation, context, "BeGreaterThan", subjectIndex: 0, argumentsToRemove: []);
64+
case "GreaterOrEqual" when ArgumentsAreTypeOf(invocation, t.Int32, t.Int32): // Assert.GreaterOrEqual(int arg1, int arg2)
65+
case "GreaterOrEqual" when ArgumentsAreTypeOf(invocation, t.UInt32, t.UInt32): // Assert.GreaterOrEqual(uint arg1, uint arg2)
66+
case "GreaterOrEqual" when ArgumentsAreTypeOf(invocation, t.Long, t.Long): // Assert.GreaterOrEqual(long arg1, long arg2)
67+
case "GreaterOrEqual" when ArgumentsAreTypeOf(invocation, t.ULong, t.ULong): // Assert.GreaterOrEqual(ulong arg1, ulong arg2)
68+
case "GreaterOrEqual" when ArgumentsAreTypeOf(invocation, t.Float, t.Float): // Assert.GreaterOrEqual(float arg1, float arg2)
69+
case "GreaterOrEqual" when ArgumentsAreTypeOf(invocation, t.Double, t.Double): // Assert.GreaterOrEqual(double arg1, double arg2)
70+
case "GreaterOrEqual" when ArgumentsAreTypeOf(invocation, t.Decimal, t.Decimal): // Assert.GreaterOrEqual(decimal arg1, decimal arg2)
71+
case "GreaterOrEqual" when ArgumentsAreTypeOf(invocation, t.Int32, t.Int32, t.String, t.ObjectArray): // Assert.GreaterOrEqual(int arg1, int arg2, string message, params object[] parms)
72+
case "GreaterOrEqual" when ArgumentsAreTypeOf(invocation, t.UInt32, t.UInt32, t.String, t.ObjectArray): // Assert.GreaterOrEqual(uint arg1, uint arg2, string message, params object[] parms)
73+
case "GreaterOrEqual" when ArgumentsAreTypeOf(invocation, t.Long, t.Long, t.String, t.ObjectArray): // Assert.GreaterOrEqual(long arg1, long arg2, string message, params object[] parms)
74+
case "GreaterOrEqual" when ArgumentsAreTypeOf(invocation, t.ULong, t.ULong, t.String, t.ObjectArray): // Assert.GreaterOrEqual(ulong arg1, ulong arg2, string message, params object[] parms)
75+
case "GreaterOrEqual" when ArgumentsAreTypeOf(invocation, t.Float, t.Float, t.String, t.ObjectArray): // Assert.GreaterOrEqual(float arg1, float arg2, string message, params object[] parms)
76+
case "GreaterOrEqual" when ArgumentsAreTypeOf(invocation, t.Double, t.Double, t.String, t.ObjectArray): // Assert.GreaterOrEqual(double arg1, double arg2, string message, params object[] parms)
77+
case "GreaterOrEqual" when ArgumentsAreTypeOf(invocation, t.Decimal, t.Decimal, t.String, t.ObjectArray): // Assert.GreaterOrEqual(decimal arg1, decimal arg2, string message, params object[] parms)
78+
return DocumentEditorUtils.RenameMethodToSubjectShouldAssertion(invocation, context, "BeGreaterOrEqualTo", subjectIndex: 0, argumentsToRemove: []);
79+
case "Less" when ArgumentsAreTypeOf(invocation, t.Int32, t.Int32): // Assert.Less(int arg1, int arg2)
80+
case "Less" when ArgumentsAreTypeOf(invocation, t.UInt32, t.UInt32): // Assert.Less(uint arg1, uint arg2)
81+
case "Less" when ArgumentsAreTypeOf(invocation, t.Long, t.Long): // Assert.Less(long arg1, long arg2)
82+
case "Less" when ArgumentsAreTypeOf(invocation, t.ULong, t.ULong): // Assert.Less(ulong arg1, ulong arg2)
83+
case "Less" when ArgumentsAreTypeOf(invocation, t.Float, t.Float): // Assert.Less(float arg1, float arg2)
84+
case "Less" when ArgumentsAreTypeOf(invocation, t.Double, t.Double): // Assert.Less(double arg1, double arg2)
85+
case "Less" when ArgumentsAreTypeOf(invocation, t.Decimal, t.Decimal): // Assert.Less(decimal arg1, decimal arg2)
86+
case "Less" when ArgumentsAreTypeOf(invocation, t.Int32, t.Int32, t.String, t.ObjectArray): // Assert.Less(int arg1, int arg2, string message, params object[] parms)
87+
case "Less" when ArgumentsAreTypeOf(invocation, t.UInt32, t.UInt32, t.String, t.ObjectArray): // Assert.Less(uint arg1, uint arg2, string message, params object[] parms)
88+
case "Less" when ArgumentsAreTypeOf(invocation, t.Long, t.Long, t.String, t.ObjectArray): // Assert.Less(long arg1, long arg2, string message, params object[] parms)
89+
case "Less" when ArgumentsAreTypeOf(invocation, t.ULong, t.ULong, t.String, t.ObjectArray): // Assert.Less(ulong arg1, ulong arg2, string message, params object[] parms)
90+
case "Less" when ArgumentsAreTypeOf(invocation, t.Float, t.Float, t.String, t.ObjectArray): // Assert.Less(float arg1, float arg2, string message, params object[] parms)
91+
case "Less" when ArgumentsAreTypeOf(invocation, t.Double, t.Double, t.String, t.ObjectArray): // Assert.Less(double arg1, double arg2, string message, params object[] parms)
92+
case "Less" when ArgumentsAreTypeOf(invocation, t.Decimal, t.Decimal, t.String, t.ObjectArray): // Assert.Less(decimal arg1, decimal arg2, string message, params object[] parms)
93+
return DocumentEditorUtils.RenameMethodToSubjectShouldAssertion(invocation, context, "BeLessThan", subjectIndex: 0, argumentsToRemove: []);
94+
case "LessOrEqual" when ArgumentsAreTypeOf(invocation, t.Int32, t.Int32): // Assert.LessOrEqual(int arg1, int arg2)
95+
case "LessOrEqual" when ArgumentsAreTypeOf(invocation, t.UInt32, t.UInt32): // Assert.LessOrEqual(uint arg1, uint arg2)
96+
case "LessOrEqual" when ArgumentsAreTypeOf(invocation, t.Long, t.Long): // Assert.LessOrEqual(long arg1, long arg2)
97+
case "LessOrEqual" when ArgumentsAreTypeOf(invocation, t.ULong, t.ULong): // Assert.LessOrEqual(ulong arg1, ulong arg2)
98+
case "LessOrEqual" when ArgumentsAreTypeOf(invocation, t.Float, t.Float): // Assert.LessOrEqual(float arg1, float arg2)
99+
case "LessOrEqual" when ArgumentsAreTypeOf(invocation, t.Double, t.Double): // Assert.LessOrEqual(double arg1, double arg2)
100+
case "LessOrEqual" when ArgumentsAreTypeOf(invocation, t.Decimal, t.Decimal): // Assert.LessOrEqual(decimal arg1, decimal arg2)
101+
case "LessOrEqual" when ArgumentsAreTypeOf(invocation, t.Int32, t.Int32, t.String, t.ObjectArray): // Assert.LessOrEqual(int arg1, int arg2, string message, params object[] parms)
102+
case "LessOrEqual" when ArgumentsAreTypeOf(invocation, t.UInt32, t.UInt32, t.String, t.ObjectArray): // Assert.LessOrEqual(uint arg1, uint arg2, string message, params object[] parms)
103+
case "LessOrEqual" when ArgumentsAreTypeOf(invocation, t.Long, t.Long, t.String, t.ObjectArray): // Assert.LessOrEqual(long arg1, long arg2, string message, params object[] parms)
104+
case "LessOrEqual" when ArgumentsAreTypeOf(invocation, t.ULong, t.ULong, t.String, t.ObjectArray): // Assert.LessOrEqual(ulong arg1, ulong arg2, string message, params object[] parms)
105+
case "LessOrEqual" when ArgumentsAreTypeOf(invocation, t.Float, t.Float, t.String, t.ObjectArray): // Assert.LessOrEqual(float arg1, float arg2, string message, params object[] parms)
106+
case "LessOrEqual" when ArgumentsAreTypeOf(invocation, t.Double, t.Double, t.String, t.ObjectArray): // Assert.LessOrEqual(double arg1, double arg2, string message, params object[] parms)
107+
case "LessOrEqual" when ArgumentsAreTypeOf(invocation, t.Decimal, t.Decimal, t.String, t.ObjectArray): // Assert.LessOrEqual(decimal arg1, decimal arg2, string message, params object[] parms)
108+
return DocumentEditorUtils.RenameMethodToSubjectShouldAssertion(invocation, context, "BeLessOrEqualTo", subjectIndex: 0, argumentsToRemove: []);
49109
}
50-
51-
return null;
52-
}
53-
54-
private CreateChangedDocument TryComputeFixForNunit4ClassicAssert(IInvocationOperation invocation, CodeFixContext context, TestingFrameworkCodeFixContext t)
55-
{
56-
switch (invocation.TargetMethod.Name)
57-
{
58-
case "True": // Assert.True(bool condition)
59-
case "IsTrue": // Assert.IsTrue(bool condition)
60-
return DocumentEditorUtils.RenameMethodToSubjectShouldAssertion(invocation, context, "BeTrue", subjectIndex: 0, argumentsToRemove: []);
61-
case "False": // Assert.False(bool condition)
62-
case "IsFalse": // Assert.IsFalse(bool condition)
63-
return DocumentEditorUtils.RenameMethodToSubjectShouldAssertion(invocation, context, "BeFalse", subjectIndex: 0, argumentsToRemove: []);
64-
case "Null": // Assert.Null(object anObject)
65-
case "IsNull": // Assert.IsNull(object anObject)
66-
return DocumentEditorUtils.RenameMethodToSubjectShouldAssertion(invocation, context, "BeNull", subjectIndex: 0, argumentsToRemove: []);
67-
case "NotNull": // Assert.NotNull(object anObject)
68-
case "IsNotNull": // Assert.IsNotNull(object anObject)
69-
return DocumentEditorUtils.RenameMethodToSubjectShouldAssertion(invocation, context, "NotBeNull", subjectIndex: 0, argumentsToRemove: []);
70-
}
71-
72110
return null;
73111
}
74112
}

0 commit comments

Comments
 (0)