Skip to content

Commit e888619

Browse files
Adds DateTime conversion analyzer tests
Adds tests for implicit DateTime to DateTimeOffset conversion analyzer. These tests cover scenarios such as implicit conversions in property comparisons inside lambdas, expression tree lambdas, nullable DateTime to nullable DateTimeOffset assignments, and method return statements. Also adds missing references to DiagnosticVerifier to enable the tests.
1 parent 4cfeb01 commit e888619

2 files changed

Lines changed: 138 additions & 1 deletion

File tree

IntelliTect.Analyzer/IntelliTect.Analyzer.Test/DateTimeConversionTests.cs

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,140 @@ static void Main(string[] args)
205205

206206
}
207207

208+
[TestMethod]
209+
public void ImplicitConversionInPropertyComparisonInsideLambda_ProducesWarningMessage()
210+
{
211+
string source = @"
212+
using System;
213+
214+
namespace ConsoleApp53
215+
{
216+
class TimeEntry
217+
{
218+
public DateTimeOffset EndDate { get; set; }
219+
}
220+
221+
class Program
222+
{
223+
static DateTimeOffset EndDate { get; set; }
224+
225+
static void Main(string[] args)
226+
{
227+
TimeEntry entry = new TimeEntry();
228+
Func<bool> check = () => entry.EndDate <= EndDate.Date.AddDays(1).AddTicks(-1);
229+
}
230+
}
231+
}";
232+
233+
VerifyCSharpDiagnostic(source,
234+
new DiagnosticResult
235+
{
236+
Id = "INTL0202",
237+
Severity = DiagnosticSeverity.Warning,
238+
Message = "Using 'DateTimeOffset.implicit operator DateTimeOffset(DateTime)' or 'new DateTimeOffset(DateTime)' can result in unpredictable behavior",
239+
Locations =
240+
[
241+
new DiagnosticResultLocation("Test0.cs", 18, 55)
242+
]
243+
});
244+
}
245+
246+
[TestMethod]
247+
public void ImplicitConversionInExpressionTreeLambda_ProducesWarningMessage()
248+
{
249+
string source = @"
250+
using System;
251+
using System.Linq.Expressions;
252+
253+
namespace ConsoleApp54
254+
{
255+
class Program
256+
{
257+
static void Main(string[] args)
258+
{
259+
Expression<Func<DateTimeOffset, bool>> expr = dto => dto > DateTime.Now;
260+
}
261+
}
262+
}";
263+
264+
VerifyCSharpDiagnostic(source,
265+
new DiagnosticResult
266+
{
267+
Id = "INTL0202",
268+
Severity = DiagnosticSeverity.Warning,
269+
Message = "Using 'DateTimeOffset.implicit operator DateTimeOffset(DateTime)' or 'new DateTimeOffset(DateTime)' can result in unpredictable behavior",
270+
Locations =
271+
[
272+
new DiagnosticResultLocation("Test0.cs", 11, 72)
273+
]
274+
});
275+
}
276+
277+
[TestMethod]
278+
public void NullableDateTimeToNullableDateTimeOffsetAssignment_ProducesWarningMessage()
279+
{
280+
string source = @"
281+
using System;
282+
283+
namespace ConsoleApp55
284+
{
285+
class Program
286+
{
287+
static void Main(string[] args)
288+
{
289+
DateTime? dt = DateTime.Now;
290+
DateTimeOffset? dto = dt;
291+
}
292+
}
293+
}";
294+
295+
VerifyCSharpDiagnostic(source,
296+
new DiagnosticResult
297+
{
298+
Id = "INTL0202",
299+
Severity = DiagnosticSeverity.Warning,
300+
Message = "Using 'DateTimeOffset.implicit operator DateTimeOffset(DateTime)' or 'new DateTimeOffset(DateTime)' can result in unpredictable behavior",
301+
Locations =
302+
[
303+
new DiagnosticResultLocation("Test0.cs", 11, 35)
304+
]
305+
});
306+
}
307+
308+
[TestMethod]
309+
public void ImplicitConversionInMethodReturnStatement_ProducesWarningMessage()
310+
{
311+
string source = @"
312+
using System;
313+
314+
namespace ConsoleApp57
315+
{
316+
class Program
317+
{
318+
static DateTimeOffset GetDateTimeOffset()
319+
{
320+
return DateTime.Now;
321+
}
322+
323+
static void Main(string[] args)
324+
{
325+
}
326+
}
327+
}";
328+
329+
VerifyCSharpDiagnostic(source,
330+
new DiagnosticResult
331+
{
332+
Id = "INTL0202",
333+
Severity = DiagnosticSeverity.Warning,
334+
Message = "Using 'DateTimeOffset.implicit operator DateTimeOffset(DateTime)' or 'new DateTimeOffset(DateTime)' can result in unpredictable behavior",
335+
Locations =
336+
[
337+
new DiagnosticResultLocation("Test0.cs", 10, 20)
338+
]
339+
});
340+
}
341+
208342
protected override DiagnosticAnalyzer GetCSharpDiagnosticAnalyzer()
209343
{
210344
return new Analyzers.BanImplicitDateTimeToDateTimeOffsetConversion();

IntelliTect.Analyzer/IntelliTect.Analyzer.Test/Helpers/DiagnosticVerifier.Helper.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Generic;
33
using System.Collections.Immutable;
44
using System.Linq;
5+
using System.Linq.Expressions;
56
using Microsoft.CodeAnalysis;
67
using Microsoft.CodeAnalysis.CSharp;
78
using Microsoft.CodeAnalysis.Diagnostics;
@@ -19,6 +20,7 @@ public abstract partial class DiagnosticVerifier
1920
private static readonly MetadataReference _SystemCoreReference = MetadataReference.CreateFromFile(typeof(Enumerable).Assembly.Location);
2021
private static readonly MetadataReference _CSharpSymbolsReference = MetadataReference.CreateFromFile(typeof(CSharpCompilation).Assembly.Location);
2122
private static readonly MetadataReference _CodeAnalysisReference = MetadataReference.CreateFromFile(typeof(Compilation).Assembly.Location);
23+
private static readonly MetadataReference _LinqExpressionsReference = MetadataReference.CreateFromFile(typeof(Expression<>).Assembly.Location);
2224

2325
internal static string DefaultFilePathPrefix = "Test";
2426
internal static string CSharpDefaultFileExt = "cs";
@@ -158,7 +160,8 @@ private static Project CreateProject(string[] sources, string language = Languag
158160
.AddMetadataReference(projectId, _CorlibReference)
159161
.AddMetadataReference(projectId, _SystemCoreReference)
160162
.AddMetadataReference(projectId, _CSharpSymbolsReference)
161-
.AddMetadataReference(projectId, _CodeAnalysisReference);
163+
.AddMetadataReference(projectId, _CodeAnalysisReference)
164+
.AddMetadataReference(projectId, _LinqExpressionsReference);
162165
}
163166

164167
int count = 0;

0 commit comments

Comments
 (0)