Skip to content

Commit a104b00

Browse files
Improve the fixer PosInfoMoq1000 to add a new line for the first VerifyAll() if need.
1 parent fb6461f commit a104b00

File tree

2 files changed

+147
-11
lines changed

2 files changed

+147
-11
lines changed

src/Moq.Analyzers/CodeFixes/AddVerifyAllCodeFixProvider.cs

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ private static async Task<Document> AddVerifyAllAsync(Document document, MethodD
9292

9393
// Find the location where we can insert the mock.
9494
var index = oldUnitTestMethod.Body.Statements.Count;
95+
bool insertNewLine = true;
9596

9697
foreach (var statement in oldUnitTestMethod.Body.Statements.Reverse())
9798
{
@@ -105,6 +106,8 @@ private static async Task<Document> AddVerifyAllAsync(Document document, MethodD
105106
break;
106107
}
107108

109+
insertNewLine = false;
110+
108111
if (variableName.CompareTo(otherVariableName) >= 0)
109112
{
110113
// The variable name to add is in alphabetic order after the "variable.VerifyAll()",
@@ -123,11 +126,7 @@ private static async Task<Document> AddVerifyAllAsync(Document document, MethodD
123126
SyntaxFactory.IdentifierName(variableName),
124127
SyntaxFactory.IdentifierName("VerifyAll"))));
125128

126-
var oldBodyStatements = oldUnitTestMethod.Body.Statements;
127-
128-
var newStatements = InsertStatement(oldBodyStatements, index, verifyAllCallStatement);
129-
130-
var newUnitTestMethod = oldUnitTestMethod.WithBody(oldUnitTestMethod.Body.WithStatements(newStatements));
129+
var newUnitTestMethodBody = InsertStatement(oldUnitTestMethod.Body, index, verifyAllCallStatement, insertNewLine);
131130

132131
var oldRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
133132

@@ -136,28 +135,39 @@ private static async Task<Document> AddVerifyAllAsync(Document document, MethodD
136135
return document;
137136
}
138137

139-
var newRoot = oldRoot.ReplaceNode(oldUnitTestMethod, newUnitTestMethod);
138+
var newRoot = oldRoot.ReplaceNode(oldUnitTestMethod, oldUnitTestMethod.WithBody(newUnitTestMethodBody));
140139

141140
return document.WithSyntaxRoot(newRoot);
142141
}
143142

144-
private static SyntaxList<StatementSyntax> InsertStatement(SyntaxList<StatementSyntax> list, int index, StatementSyntax statement)
143+
private static BlockSyntax InsertStatement(BlockSyntax unitTestMethodBody, int index, StatementSyntax statement, bool insertNewLine)
145144
{
146-
var newStatements = new List<StatementSyntax>(list);
145+
var newStatements = new List<StatementSyntax>(unitTestMethodBody.Statements);
147146

148147
if (index < newStatements.Count)
149148
{
150149
var leadingTrivia = newStatements[index].GetLeadingTrivia();
151150

152-
// Remove the leading trivia of the current node.
151+
// Remove the leading trivia of the current node and transfert it to the new statement to insert.
153152
newStatements[index] = newStatements[index].ReplaceNode(newStatements[index], newStatements[index].WithoutLeadingTrivia());
154153

155154
statement = statement.WithLeadingTrivia(leadingTrivia);
156155
}
157156

157+
if (insertNewLine)
158+
{
159+
// Special case, we insert a new line at the end of the unit test (we also retrieve the comment at the end if need).
160+
// Because we want that the VerifyAll() blocks are detached with a new line.
161+
// It is useful if developers want to call the fixer for all the solution.
162+
statement = statement.WithLeadingTrivia(
163+
unitTestMethodBody.CloseBraceToken.LeadingTrivia.Add(SyntaxFactory.CarriageReturnLineFeed));
164+
165+
unitTestMethodBody = unitTestMethodBody.WithCloseBraceToken(unitTestMethodBody.CloseBraceToken.WithLeadingTrivia());
166+
}
167+
158168
newStatements.Insert(index, statement);
159169

160-
return SyntaxFactory.List(newStatements);
170+
return unitTestMethodBody.WithStatements(SyntaxFactory.List(newStatements));
161171
}
162172

163173
private static bool IsVerifyAll(SemanticModel semanticModel, MoqSymbols moqSymbols, ExpressionStatementSyntax statement, out string? variableName, CancellationToken cancellationToken)

tests/Moq.Analyzers.Tests/CodeFixes/AddVerifyAllCodeFixProviderTest.cs

Lines changed: 127 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,76 @@ public void TestMethod()
7171
}
7272
}
7373
74+
public interface I
75+
{
76+
void Method();
77+
}
78+
}";
79+
80+
await Verifier.VerifyCodeFixAsync(source, expectedFixedSource);
81+
}
82+
83+
[Fact]
84+
public async Task AddVerifyAllInTheMiddleOfOtherMocks_Fix()
85+
{
86+
var source = @"
87+
namespace ConsoleApplication1
88+
{
89+
using Moq;
90+
using System;
91+
92+
public class TestClass
93+
{
94+
public void TestMethod()
95+
{
96+
var mock1 = new Mock<I>();
97+
mock1.Setup(i => i.Method());
98+
99+
var mock2 = {|PosInfoMoq1000:new Mock<I>()|};
100+
mock2.Setup(i => i.Method());
101+
102+
var mock3 = new Mock<I>();
103+
mock3.Setup(i => i.Method());
104+
105+
// No changes
106+
mock1.VerifyAll();
107+
mock3.VerifyAll();
108+
}
109+
}
110+
111+
public interface I
112+
{
113+
void Method();
114+
}
115+
}";
116+
117+
var expectedFixedSource =
118+
@"
119+
namespace ConsoleApplication1
120+
{
121+
using Moq;
122+
using System;
123+
124+
public class TestClass
125+
{
126+
public void TestMethod()
127+
{
128+
var mock1 = new Mock<I>();
129+
mock1.Setup(i => i.Method());
130+
131+
var mock2 = new Mock<I>();
132+
mock2.Setup(i => i.Method());
133+
134+
var mock3 = new Mock<I>();
135+
mock3.Setup(i => i.Method());
136+
137+
// No changes
138+
mock1.VerifyAll();
139+
mock2.VerifyAll();
140+
mock3.VerifyAll();
141+
}
142+
}
143+
74144
public interface I
75145
{
76146
void Method();
@@ -151,7 +221,58 @@ public interface I
151221
}
152222

153223
[Fact]
154-
public async Task AddVerifyAllSingleMock_WithComment_Fix()
224+
public async Task AddVerifyAllSingleMock()
225+
{
226+
var source = @"
227+
namespace ConsoleApplication1
228+
{
229+
using Moq;
230+
using System;
231+
232+
public class TestClass
233+
{
234+
public void TestMethod()
235+
{
236+
var mock1 = {|PosInfoMoq1000:new Mock<I>()|};
237+
mock1.Setup(i => i.Method());
238+
}
239+
}
240+
241+
public interface I
242+
{
243+
void Method();
244+
}
245+
}";
246+
247+
var expectedFixedSource =
248+
@"
249+
namespace ConsoleApplication1
250+
{
251+
using Moq;
252+
using System;
253+
254+
public class TestClass
255+
{
256+
public void TestMethod()
257+
{
258+
var mock1 = new Mock<I>();
259+
mock1.Setup(i => i.Method());
260+
261+
mock1.VerifyAll();
262+
}
263+
}
264+
265+
public interface I
266+
{
267+
void Method();
268+
}
269+
}";
270+
271+
await Verifier.VerifyCodeFixAsync(source, expectedFixedSource);
272+
}
273+
274+
[Fact]
275+
public async Task AddVerifyAllSingleMock_WithCommentAtTheEnd()
155276
{
156277
var source = @"
157278
namespace ConsoleApplication1
@@ -165,6 +286,8 @@ public void TestMethod()
165286
{
166287
var mock1 = {|PosInfoMoq1000:new Mock<I>()|};
167288
mock1.Setup(i => i.Method());
289+
290+
// End of unit tests
168291
}
169292
}
170293
@@ -187,6 +310,9 @@ public void TestMethod()
187310
{
188311
var mock1 = new Mock<I>();
189312
mock1.Setup(i => i.Method());
313+
314+
// End of unit tests
315+
190316
mock1.VerifyAll();
191317
}
192318
}

0 commit comments

Comments
 (0)