Skip to content

Commit 5c709b1

Browse files
Add C#11 specific test cases for non-sonarway rules M-O (#6426)
1 parent eb45094 commit 5c709b1

10 files changed

Lines changed: 266 additions & 31 deletions

analyzers/tests/SonarAnalyzer.UnitTest/Rules/MemberInitializedToDefaultTest.cs

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,14 @@ public class MemberInitializedToDefaultTest
3131
public void MemberInitializedToDefault() =>
3232
builder.AddPaths("MemberInitializedToDefault.cs").Verify();
3333

34+
[TestMethod]
35+
public void MemberInitializedToDefault_CodeFix() =>
36+
builder
37+
.WithCodeFix<MemberInitializedToDefaultCodeFix>()
38+
.AddPaths("MemberInitializedToDefault.cs")
39+
.WithCodeFixedPaths("MemberInitializedToDefault.Fixed.cs")
40+
.VerifyCodeFix();
41+
3442
#if NET
3543

3644
[TestMethod]
@@ -41,18 +49,24 @@ public void MemberInitializedToDefault_CSharp8() =>
4149
public void MemberInitializedToDefault_CSharp9() =>
4250
builder.AddPaths("MemberInitializedToDefault.CSharp9.cs").WithOptions(ParseOptionsHelper.FromCSharp9).Verify();
4351

52+
[TestMethod]
53+
public void MemberInitializedToDefault_CSharp10() =>
54+
builder.AddPaths("MemberInitializedToDefault.CSharp10.cs").WithOptions(ParseOptionsHelper.FromCSharp10).Verify();
55+
4456
[TestMethod]
4557
public void MemberInitializedToDefault_CSharp11() =>
4658
builder.AddPaths("MemberInitializedToDefault.CSharp11.cs").WithOptions(ParseOptionsHelper.FromCSharp11).Verify();
4759

48-
#endif
49-
5060
[TestMethod]
51-
public void MemberInitializedToDefault_CodeFix() =>
61+
public void MemberInitializedToDefault_CSharp11_CodeFix() =>
5262
builder
53-
.WithCodeFix<MemberInitializedToDefaultCodeFix>()
54-
.AddPaths("MemberInitializedToDefault.cs")
55-
.WithCodeFixedPaths("MemberInitializedToDefault.Fixed.cs")
56-
.VerifyCodeFix();
63+
.WithCodeFix<MemberInitializedToDefaultCodeFix>()
64+
.AddPaths("MemberInitializedToDefault.CSharp11.cs")
65+
.WithCodeFixedPaths("MemberInitializedToDefault.CSharp11.Fixed.cs")
66+
.WithOptions(ParseOptionsHelper.FromCSharp11)
67+
.VerifyCodeFix();
68+
69+
#endif
70+
5771
}
5872
}

analyzers/tests/SonarAnalyzer.UnitTest/Rules/NameOfShouldBeUsedTest.cs

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,23 +28,37 @@ namespace SonarAnalyzer.UnitTest.Rules
2828
[TestClass]
2929
public class NameOfShouldBeUsedTest
3030
{
31-
private readonly VerifierBuilder builderCS = new VerifierBuilder<CS.NameOfShouldBeUsed>().AddPaths("NameOfShouldBeUsed.cs");
32-
private readonly VerifierBuilder builderVB = new VerifierBuilder<VB.NameOfShouldBeUsed>().AddPaths("NameOfShouldBeUsed.vb");
31+
private readonly VerifierBuilder builderCS = new VerifierBuilder<CS.NameOfShouldBeUsed>();
32+
private readonly VerifierBuilder builderVB = new VerifierBuilder<VB.NameOfShouldBeUsed>();
3333

3434
[TestMethod]
35-
public void NameOfShouldBeUsed_FromCSharp6() =>
36-
builderCS.WithOptions(ParseOptionsHelper.FromCSharp6).Verify();
35+
public void NameOfShouldBeUsed_CSharp6() =>
36+
builderCS.AddPaths("NameOfShouldBeUsed.cs").WithOptions(ParseOptionsHelper.FromCSharp6).Verify();
3737

3838
[TestMethod]
3939
public void NameOfShouldBeUsed_CSharp5() =>
40-
builderCS.WithLanguageVersion(RoslynCS.LanguageVersion.CSharp5).WithErrorBehavior(CompilationErrorBehavior.Ignore).VerifyNoIssueReported();
40+
builderCS.AddPaths("NameOfShouldBeUsed.cs")
41+
.WithLanguageVersion(RoslynCS.LanguageVersion.CSharp5)
42+
.WithErrorBehavior(CompilationErrorBehavior.Ignore)
43+
.VerifyNoIssueReported();
44+
45+
#if NET
46+
47+
[TestMethod]
48+
public void NameOfShouldBeUsed_CSharp11() =>
49+
builderCS.AddPaths("NameOfShouldBeUsed.CSharp11.cs").WithOptions(ParseOptionsHelper.FromCSharp11).Verify();
50+
51+
#endif
4152

4253
[TestMethod]
4354
public void NameOfShouldBeUsed_FromVB14() =>
44-
builderVB.WithOptions(ParseOptionsHelper.FromVisualBasic14).Verify();
55+
builderVB.AddPaths("NameOfShouldBeUsed.vb").WithOptions(ParseOptionsHelper.FromVisualBasic14).Verify();
4556

4657
[TestMethod]
4758
public void NameOfShouldBeUsed_VB12() =>
48-
builderVB.WithLanguageVersion(RoslynVB.LanguageVersion.VisualBasic12).WithErrorBehavior(CompilationErrorBehavior.Ignore).VerifyNoIssueReported();
59+
builderVB.AddPaths("NameOfShouldBeUsed.vb")
60+
.WithLanguageVersion(RoslynVB.LanguageVersion.VisualBasic12)
61+
.WithErrorBehavior(CompilationErrorBehavior.Ignore)
62+
.VerifyNoIssueReported();
4963
}
5064
}

analyzers/tests/SonarAnalyzer.UnitTest/Rules/OperatorOverloadsShouldHaveNamedAlternativesTest.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ public void OperatorOverloadsShouldHaveNamedAlternatives() =>
3737
public void OperatorOverloadsShouldHaveNamedAlternatives_CSharp9() =>
3838
builder.AddPaths("OperatorOverloadsShouldHaveNamedAlternatives.CSharp9.cs").WithOptions(ParseOptionsHelper.FromCSharp9).Verify();
3939

40+
[TestMethod]
41+
public void OperatorOverloadsShouldHaveNamedAlternatives_CSharp11() =>
42+
builder.AddPaths("OperatorOverloadsShouldHaveNamedAlternatives.CSharp11.cs").WithOptions(ParseOptionsHelper.FromCSharp11).Verify();
43+
4044
#endif
4145

4246
}

analyzers/tests/SonarAnalyzer.UnitTest/Rules/OperatorsShouldBeOverloadedConsistentlyTest.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ public void OperatorsShouldBeOverloadedConsistently() =>
3737
public void OperatorsShouldBeOverloadedConsistently_CSharp9() =>
3838
builder.AddPaths("OperatorsShouldBeOverloadedConsistently.CSharp9.cs").WithOptions(ParseOptionsHelper.FromCSharp9).Verify();
3939

40+
[TestMethod]
41+
public void OperatorsShouldBeOverloadedConsistently_CSharp11() =>
42+
builder.AddPaths("OperatorsShouldBeOverloadedConsistently.CSharp11.cs").WithOptions(ParseOptionsHelper.FromCSharp11).Verify();
43+
4044
#endif
4145

4246
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using System;
2+
3+
namespace Tests.Diagnostics
4+
{
5+
public struct BarStruct
6+
{
7+
// Repro for issue: https://github.com/SonarSource/sonar-dotnet/issues/6461
8+
public int someField = 0; // Noncompliant FP for versions < C# 11 Fields that are not initialized in all constructors must be set explicitly.
9+
public BarStruct(bool someDummy) // Ctor with a parameter that does not initialize all fields
10+
{ }
11+
}
12+
}
13+
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
using System;
2+
using System.Diagnostics.CodeAnalysis;
3+
4+
record IntPointers
5+
{
6+
public const IntPtr myConst = 0; // Compliant
7+
public static IntPtr staticField; // Fixed
8+
9+
public IntPtr field1; // Fixed
10+
public IntPtr field2 = 42; // Compliant
11+
12+
public UIntPtr field3; // Fixed
13+
public UIntPtr field4 = 42;// Compliant
14+
15+
public IntPtr field5; // Fixed
16+
public IntPtr field6; // Fixed
17+
public UIntPtr field7; // Fixed
18+
public IntPtr field8; // Fixed
19+
public IntPtr field9 = new IntPtr(staticField); // Compliant
20+
21+
public UIntPtr field10; // Fixed
22+
public UIntPtr field11; // Fixed
23+
public UIntPtr field12; // Fixed
24+
25+
public IntPtr Property1 { get; set; } // Fixed
26+
public IntPtr Property2 { get; set; } = 42; // Compliant
27+
28+
public UIntPtr Property3 { get; init; } // Fixed
29+
public UIntPtr Property4 { get; init; } = 42; // Compliant
30+
31+
public IntPtr Property5 { get; set; } = 0 * 20 - 0; // FN - Expression is not evaluated
32+
public UIntPtr Property6 { get; set; } = 0 * 20 - 0; // FN - Expression is not evaluated
33+
}
34+
35+
public readonly struct FooStruct
36+
{
37+
public FooStruct() { }
38+
39+
public int Value { get; init; } // Compliant
40+
public bool BoolValue { get; init; } // Compliant
41+
42+
public int ValueDefault { get; init; } // Fixed
43+
public bool BoolValueDefault { get; init; } // Fixed
44+
}
45+
46+
public struct BarStruct
47+
{
48+
public int someField; // Fixed
49+
public required int someRequiredField; // Fixed
50+
public BarStruct(int dummy) { }
51+
52+
[SetsRequiredMembers]
53+
public BarStruct() { } // this constructor will init all required members to their default values.
54+
}
55+
56+
public struct FooBarStruct
57+
{
58+
public int someField; // Compliant - does not raise a CS0171 issue anymore due to the auto-default-struct C# 11 feature https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-11#auto-default-struct
59+
public required int someRequiredField; // Compliant - does not raise a CS0171 and the compiler will default this to 0.
60+
61+
public FooBarStruct(int dummy) { }
62+
}
63+
64+
public class TestRequiredProperties
65+
{
66+
void Method()
67+
{
68+
var classWithRequiredProperties = new ClassWithRequiredProperties() { RequiredProperty = 0 };
69+
var classWithRequiredProperties_initWithConstructor = new ClassWithRequiredProperties();
70+
}
71+
72+
public class ClassWithRequiredProperties
73+
{
74+
public required int RequiredProperty { get; init; } // Fixed
75+
public int AnotherProperty { get; set; }
76+
77+
[SetsRequiredMembers]
78+
public ClassWithRequiredProperties() { }
79+
}
80+
}
Lines changed: 65 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,80 @@
11
using System;
2+
using System.Diagnostics.CodeAnalysis;
23

3-
record IntPointers
4+
record IntPointers
45
{
5-
public const IntPtr myConst = 0; // Compliant
6+
public const IntPtr myConst = 0; // Compliant
67
public static IntPtr staticField = 0; // Noncompliant
78

8-
public IntPtr field1 = 0; // Noncompliant
9-
public IntPtr field2 = 42; // Compliant
9+
public IntPtr field1 = 0; // Noncompliant
10+
public IntPtr field2 = 42; // Compliant
1011

11-
public UIntPtr field3 = 0; // Noncompliant
12-
public UIntPtr field4 = 42; // Compliant
12+
public UIntPtr field3 = 0; // Noncompliant
13+
public UIntPtr field4 = 42;// Compliant
1314

14-
public IntPtr field5 = IntPtr.Zero; // Noncompliant
15-
public IntPtr field6 = 0x0000000000000000; // Noncompliant
16-
public UIntPtr field7 = UIntPtr.Zero; // Noncompliant
17-
public IntPtr field8 = new IntPtr(0); // Noncompliant
15+
public IntPtr field5 = IntPtr.Zero; // Noncompliant
16+
public IntPtr field6 = 0x0000000000000000; // Noncompliant
17+
public UIntPtr field7 = UIntPtr.Zero; // Noncompliant
18+
public IntPtr field8 = new IntPtr(0); // Noncompliant
1819
public IntPtr field9 = new IntPtr(staticField); // Compliant
1920

20-
public UIntPtr field10 = new UIntPtr(0); // Noncompliant
21-
public UIntPtr field11 = new(); // Noncompliant
22-
public UIntPtr field12 = new UIntPtr { }; // Noncompliant
21+
public UIntPtr field10 = new UIntPtr(0); // Noncompliant
22+
public UIntPtr field11 = new(); // Noncompliant
23+
public UIntPtr field12 = new UIntPtr { }; // Noncompliant
2324

24-
public IntPtr Property1 { get; set; } = 0; // Noncompliant
25-
public IntPtr Property2 { get; set; } = 42; // Compliant
25+
public IntPtr Property1 { get; set; } = 0; // Noncompliant
26+
public IntPtr Property2 { get; set; } = 42; // Compliant
2627

27-
public UIntPtr Property3 { get; init; } = 0; // Noncompliant
28-
public UIntPtr Property4 { get; init; } = 42; // Compliant
28+
public UIntPtr Property3 { get; init; } = 0; // Noncompliant
29+
public UIntPtr Property4 { get; init; } = 42; // Compliant
2930

3031
public IntPtr Property5 { get; set; } = 0 * 20 - 0; // FN - Expression is not evaluated
3132
public UIntPtr Property6 { get; set; } = 0 * 20 - 0; // FN - Expression is not evaluated
3233
}
34+
35+
public readonly struct FooStruct
36+
{
37+
public FooStruct() { }
38+
39+
public int Value { get; init; } // Compliant
40+
public bool BoolValue { get; init; } // Compliant
41+
42+
public int ValueDefault { get; init; } = 0; // Noncompliant
43+
public bool BoolValueDefault { get; init; } = false; // Noncompliant
44+
}
45+
46+
public struct BarStruct
47+
{
48+
public int someField = 0; // Noncompliant Initializing this field is optional for C# 11 due to the auto-default-struct C# feature https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-11#auto-default-struct
49+
public required int someRequiredField = 0; // Noncompliant "required" indicates C# 11 and the compiler takes care of the initialization to the default value for structs in C#11 and above
50+
public BarStruct(int dummy) { }
51+
52+
[SetsRequiredMembers]
53+
public BarStruct() { } // this constructor will init all required members to their default values.
54+
}
55+
56+
public struct FooBarStruct
57+
{
58+
public int someField; // Compliant - does not raise a CS0171 issue anymore due to the auto-default-struct C# 11 feature https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-11#auto-default-struct
59+
public required int someRequiredField; // Compliant - does not raise a CS0171 and the compiler will default this to 0.
60+
61+
public FooBarStruct(int dummy) { }
62+
}
63+
64+
public class TestRequiredProperties
65+
{
66+
void Method()
67+
{
68+
var classWithRequiredProperties = new ClassWithRequiredProperties() { RequiredProperty = 0 };
69+
var classWithRequiredProperties_initWithConstructor = new ClassWithRequiredProperties();
70+
}
71+
72+
public class ClassWithRequiredProperties
73+
{
74+
public required int RequiredProperty { get; init; } = 0; // Noncompliant - the required property is to be set on the caller's side anyways or by the constructor.
75+
public int AnotherProperty { get; set; }
76+
77+
[SetsRequiredMembers]
78+
public ClassWithRequiredProperties() { }
79+
}
80+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
using System;
2+
3+
namespace Tests.Diagnostics
4+
{
5+
class Program
6+
{
7+
public void Method_With_RawStringLiterals(int arg1)
8+
{
9+
// Repro for https://github.com/SonarSource/sonar-dotnet/issues/6441
10+
if (arg1 < 0)
11+
throw new Exception("""arg1"""); // FN
12+
else if (arg1 > 100)
13+
throw new ArgumentException("""Bad parameter name""", """arg1"""); // FN
14+
}
15+
16+
17+
public void Method_With_NewLinesInStringInterpolation(int arg1)
18+
{
19+
string argName = "arg1";
20+
if (arg1 < 0)
21+
{
22+
throw new Exception($"{
23+
arg1 switch
24+
{
25+
< 0 => "arg1", // Noncompliant
26+
_ => "Can't touch this",
27+
}}");
28+
}
29+
else
30+
{
31+
throw new Exception($$"""arg1"""); // Noncompliant
32+
}
33+
}
34+
}
35+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
using System.Threading.Tasks;
2+
using System;
3+
4+
internal interface IOperator<T> where T : IOperator<T>
5+
{
6+
static virtual T operator ++(T input) => input; // Noncompliant {{Implement alternative method 'Increment' for the operator '++'.}}
7+
static abstract T operator --(T input); // Noncompliant
8+
static IOperator<T> operator ~(IOperator<T> input) => input; // Noncompliant
9+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Issues are not raised in Interface implementations.
2+
// Interfaces are used to describe the operators supported by a type in a fine grained way
3+
public interface IPlus<TSelf> where TSelf : IPlus<TSelf>
4+
{
5+
static virtual TSelf operator +(TSelf a, TSelf b) => a;
6+
}
7+
public interface IMinus<TSelf> where TSelf : IMinus<TSelf>
8+
{
9+
static abstract TSelf operator -(TSelf a, TSelf b);
10+
}
11+
public interface IMulti
12+
{
13+
static IMulti operator *(IMulti a, IMulti b) => a;
14+
}

0 commit comments

Comments
 (0)