Skip to content
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
4 changes: 2 additions & 2 deletions samples/Tests/Stride.Samples.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
<IsPackable>true</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="xunit" Version="2.6.5" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.6" />
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\sources\shared\SharedAssemblyInfo.cs">
Expand Down
12 changes: 7 additions & 5 deletions sources/Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,13 @@
</ItemGroup>
<!-- Test dependencies -->
<ItemGroup>
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageVersion Include="TeamCity.VSTest.TestAdapter" Version="1.0.39" />
<PackageVersion Include="xunit" Version="2.6.5" />
<PackageVersion Include="xunit.runner.utility" Version="2.6.5" />
<PackageVersion Include="xunit.runner.visualstudio" Version="2.5.6" />
<PackageVersion Include="coverlet.collector" Version="6.0.4" />
<PackageVersion Include="coverlet.msbuild" Version="6.0.4" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.0.0" />
<PackageVersion Include="TeamCity.VSTest.TestAdapter" Version="1.0.41" />
<PackageVersion Include="xunit" Version="2.9.3" />
<PackageVersion Include="xunit.runner.utility" Version="2.9.3" />
<PackageVersion Include="xunit.runner.visualstudio" Version="2.8.2" />
<PackageVersion Include="Xunit.SkippableFact" Version="1.4.13" />
</ItemGroup>
<!-- Avalonia dependencies -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,31 @@

namespace Stride.Core.CompilerServices.Tests.AnalyzerTests;

/// <summary>
/// Tests for <see cref="STRDIAG000AttributeContradiction"/> analyzer.
/// Validates detection of contradictory DataMember and DataMemberIgnore attributes.
/// </summary>
public class STRDIAG000_Test
{
[Fact]
public async Task Error_On_Attribute_Contradiction_On_Property()
{
string sourceCode = string.Format(ClassTemplates.BasicClassTemplate, "[DataMemberIgnore][DataMember]public int Value { get; set; }");
await TestHelper.ExpectDiagnosticsErrorAsync(sourceCode, STRDIAG000AttributeContradiction.DiagnosticId);
await TestHelper.ExpectDiagnosticAsync(sourceCode, STRDIAG000AttributeContradiction.DiagnosticId);
}

[Fact]
public async Task Error_On_Attribute_Contradiction_On_Field()
{
string sourceCode = string.Format(ClassTemplates.BasicClassTemplate, "[DataMemberIgnore][DataMember]public int Value;");
await TestHelper.ExpectDiagnosticsErrorAsync(sourceCode, STRDIAG000AttributeContradiction.DiagnosticId);
await TestHelper.ExpectDiagnosticAsync(sourceCode, STRDIAG000AttributeContradiction.DiagnosticId);
}

[Fact]
public async Task Error_On_Reversed_Attribute_Order()
{
string sourceCode = string.Format(ClassTemplates.BasicClassTemplate, "[DataMember][DataMemberIgnore]public int Value { get; set; }");
await TestHelper.ExpectDiagnosticAsync(sourceCode, STRDIAG000AttributeContradiction.DiagnosticId);
}

[Fact]
Expand Down Expand Up @@ -46,6 +57,27 @@ public class TripleAnnotation
}
}
";
await TestHelper.ExpectNoDiagnosticsErrorsAsync(sourceCode);
await TestHelper.ExpectNoDiagnosticsAsync(sourceCode);
}

[Fact]
public async Task NoError_On_Only_DataMember()
{
string sourceCode = string.Format(ClassTemplates.BasicClassTemplate, "[DataMember]public int Value { get; set; }");
await TestHelper.ExpectNoDiagnosticsAsync(sourceCode);
}

[Fact]
public async Task NoError_On_Only_DataMemberIgnore()
{
string sourceCode = string.Format(ClassTemplates.BasicClassTemplate, "[DataMemberIgnore]public int Value { get; set; }");
await TestHelper.ExpectNoDiagnosticsAsync(sourceCode);
}

[Fact]
public async Task NoError_On_No_Attributes()
{
string sourceCode = string.Format(ClassTemplates.BasicClassTemplate, "public int Value { get; set; }");
await TestHelper.ExpectNoDiagnosticsAsync(sourceCode);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,73 @@
using Xunit;

namespace Stride.Core.CompilerServices.Tests.AnalyzerTests;

/// <summary>
/// Tests for <see cref="STRDIAG001InvalidDataContract"/> analyzer.
/// Validates that DataContract attribute is only applied to public/internal types.
/// </summary>
public class STRDIAG001_Test
{
[Fact]
public async Task Error_On_Private_Inner_Class_with_DataContract()
{
string sourceCode = string.Format(ClassTemplates.BasicClassTemplate, "[DataContract] private class InnerClass { }");
await TestHelper.ExpectDiagnosticsErrorAsync(sourceCode, STRDIAG001InvalidDataContract.DiagnosticId);
await TestHelper.ExpectDiagnosticAsync(sourceCode, STRDIAG001InvalidDataContract.DiagnosticId);
}

[Fact]
public async Task No_Error_On_Private_Inner_Class_without_DataContract()
{
string sourceCode = string.Format(ClassTemplates.BasicClassTemplate, "private class InnerClass { }");
await TestHelper.ExpectNoDiagnosticsErrorsAsync(sourceCode);
await TestHelper.ExpectNoDiagnosticsAsync(sourceCode);
}

[Fact]
public async Task Error_On_file_scope_Class_with_DataContract()
{
string sourceCode = "using Stride.Core; [DataContract] file class FileScopeClass { }";
await TestHelper.ExpectDiagnosticsErrorAsync(sourceCode, STRDIAG001InvalidDataContract.DiagnosticId);
await TestHelper.ExpectDiagnosticAsync(sourceCode, STRDIAG001InvalidDataContract.DiagnosticId);
}

[Fact]
public async Task No_Error_On_file_scope_Class_without_DataContract()
{
string sourceCode = "using Stride.Core; file class FileScopeClass { }";
await TestHelper.ExpectNoDiagnosticsErrorsAsync(sourceCode);
await TestHelper.ExpectNoDiagnosticsAsync(sourceCode);
}

[Fact]
public async Task No_Error_On_Public_Class_with_DataContract()
{
string sourceCode = "using Stride.Core; [DataContract] public class PublicClass { }";
await TestHelper.ExpectNoDiagnosticsAsync(sourceCode);
}

[Fact]
public async Task No_Error_On_Internal_Class_with_DataContract()
{
string sourceCode = "using Stride.Core; [DataContract] internal class InternalClass { }";
await TestHelper.ExpectNoDiagnosticsAsync(sourceCode);
}

[Fact]
public async Task Error_On_Protected_Inner_Class_with_DataContract()
{
string sourceCode = string.Format(ClassTemplates.BasicClassTemplate, "[DataContract] protected class InnerClass { }");
await TestHelper.ExpectDiagnosticAsync(sourceCode, STRDIAG001InvalidDataContract.DiagnosticId);
}

[Fact]
public async Task No_Error_On_Public_Struct_with_DataContract()
{
string sourceCode = "using Stride.Core; [DataContract] public struct PublicStruct { }";
await TestHelper.ExpectNoDiagnosticsAsync(sourceCode);
}

[Fact]
public async Task No_Error_On_Public_Record_with_DataContract()
{
string sourceCode = "using Stride.Core; [DataContract] public record PublicRecord { }";
await TestHelper.ExpectNoDiagnosticsAsync(sourceCode);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,58 @@

namespace Stride.Core.CompilerServices.Tests.AnalyzerTests;

/// <summary>
/// Tests for <see cref="STRDIAG002InvalidContentMode"/> analyzer.
/// Validates that DataMemberMode.Content is only used with mutable reference types.
/// </summary>
public class STRDIAG002_Test
{
[Fact]
public async Task Error_On_Attribute_Contradiction_On_Property()
public async Task Error_On_ContentMode_With_ValueType_Property()
{
string sourceCode = string.Format(ClassTemplates.BasicClassTemplate, "[DataMember(DataMemberMode.Content)]public int Value { get; set; }");
await TestHelper.ExpectDiagnosticsErrorAsync(sourceCode, STRDIAG002InvalidContentMode.DiagnosticId);
await TestHelper.ExpectDiagnosticAsync(sourceCode, STRDIAG002InvalidContentMode.DiagnosticId);
}

[Fact]
public async Task Error_On_ContentMode_With_ValueType_Field()
{
string sourceCode = string.Format(ClassTemplates.BasicClassTemplate, "[DataMember(DataMemberMode.Content)]public int Value;");
await TestHelper.ExpectDiagnosticAsync(sourceCode, STRDIAG002InvalidContentMode.DiagnosticId);
}

[Fact]
public async Task Error_On_ContentMode_With_String_Property()
{
string sourceCode = string.Format(ClassTemplates.BasicClassTemplate, "[DataMember(DataMemberMode.Content)]public string Value { get; set; }");
await TestHelper.ExpectDiagnosticAsync(sourceCode, STRDIAG002InvalidContentMode.DiagnosticId);
}

[Fact]
public async Task Error_On_ContentMode_With_Struct_Property()
{
string sourceCode = string.Format(ClassTemplates.BasicClassTemplate, "public struct MyStruct { } [DataMember(DataMemberMode.Content)]public MyStruct Value { get; set; }");
await TestHelper.ExpectDiagnosticAsync(sourceCode, STRDIAG002InvalidContentMode.DiagnosticId);
}

[Fact]
public async Task NoError_On_ContentMode_With_ReferenceType_Property()
{
string sourceCode = string.Format(ClassTemplates.BasicClassTemplate, "[DataMember(DataMemberMode.Content)]public object Value { get; set; }");
await TestHelper.ExpectNoDiagnosticsAsync(sourceCode);
}

[Fact]
public async Task NoError_On_AssignMode_With_ValueType()
{
string sourceCode = string.Format(ClassTemplates.BasicClassTemplate, "[DataMember(DataMemberMode.Assign)]public int Value { get; set; }");
await TestHelper.ExpectNoDiagnosticsAsync(sourceCode);
}

[Fact]
public async Task NoError_On_DefaultMode_With_ValueType()
{
string sourceCode = string.Format(ClassTemplates.BasicClassTemplate, "[DataMember]public int Value { get; set; }");
await TestHelper.ExpectNoDiagnosticsAsync(sourceCode);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,47 +3,72 @@

namespace Stride.Core.CompilerServices.Tests.AnalyzerTests;

/// <summary>
/// Tests for <see cref="STRDIAG003InaccessibleMember"/> analyzer.
/// Validates that DataMember attribute is only applied to accessible members.
/// </summary>
public class STRDIAG003_Test
{
[Fact]
public async Task Error_On_Datamember_With_private_InaccessibleMember_On_Property()
{
string sourceCode = string.Format(ClassTemplates.BasicClassTemplate, "[DataMember] private int Value { get; set; }");
await TestHelper.ExpectDiagnosticsErrorAsync(sourceCode, STRDIAG003InaccessibleMember.DiagnosticId);
await TestHelper.ExpectDiagnosticAsync(sourceCode, STRDIAG003InaccessibleMember.DiagnosticId);
}

[Fact]
public async Task Error_On_Datamember_With_private_InaccessibleMember_On_Field()
{
string sourceCode = string.Format(ClassTemplates.BasicClassTemplate, "[DataMember] private int Value = 0;");
await TestHelper.ExpectDiagnosticsErrorAsync(sourceCode, STRDIAG003InaccessibleMember.DiagnosticId);
await TestHelper.ExpectDiagnosticAsync(sourceCode, STRDIAG003InaccessibleMember.DiagnosticId);
}

[Fact]
public async Task Error_On_Datamember_With_protected_InaccessibleMember_On_Property()
{
string sourceCode = string.Format(ClassTemplates.BasicClassTemplate, "[DataMember] protected int Value { get; set; }");
await TestHelper.ExpectDiagnosticsErrorAsync(sourceCode, STRDIAG003InaccessibleMember.DiagnosticId);
await TestHelper.ExpectDiagnosticAsync(sourceCode, STRDIAG003InaccessibleMember.DiagnosticId);
}

[Fact]
public async Task Error_On_Datamember_With_protected_InaccessibleMember_On_Field()
{
string sourceCode = string.Format(ClassTemplates.BasicClassTemplate, "[DataMember] protected int Value = 0;");
await TestHelper.ExpectDiagnosticsErrorAsync(sourceCode, STRDIAG003InaccessibleMember.DiagnosticId);
await TestHelper.ExpectDiagnosticAsync(sourceCode, STRDIAG003InaccessibleMember.DiagnosticId);
}

[Fact]
public async Task Error_On_Datamember_With_private_protected_InaccessibleMember_On_Property()
{
string sourceCode = string.Format(ClassTemplates.BasicClassTemplate, "[DataMember] private protected int Value { get; set; }");
await TestHelper.ExpectDiagnosticsErrorAsync(sourceCode, STRDIAG003InaccessibleMember.DiagnosticId);
await TestHelper.ExpectDiagnosticAsync(sourceCode, STRDIAG003InaccessibleMember.DiagnosticId);
}

[Fact]
public async Task Error_On_Datamember_With_private_protected_InaccessibleMember_On_Field()
{
string sourceCode = string.Format(ClassTemplates.BasicClassTemplate, "[DataMember] private protected int Value = 0;");
await TestHelper.ExpectDiagnosticsErrorAsync(sourceCode, STRDIAG003InaccessibleMember.DiagnosticId);
await TestHelper.ExpectDiagnosticAsync(sourceCode, STRDIAG003InaccessibleMember.DiagnosticId);
}

[Fact]
public async Task NoError_On_Public_Member()
{
string sourceCode = string.Format(ClassTemplates.BasicClassTemplate, "[DataMember] public int Value { get; set; }");
await TestHelper.ExpectNoDiagnosticsAsync(sourceCode);
}

[Fact]
public async Task NoError_On_Internal_Member()
{
string sourceCode = string.Format(ClassTemplates.BasicClassTemplate, "[DataMember] internal int Value { get; set; }");
await TestHelper.ExpectNoDiagnosticsAsync(sourceCode);
}

[Fact]
public async Task NoError_On_ProtectedInternal_Member()
{
string sourceCode = string.Format(ClassTemplates.BasicClassTemplate, "[DataMember] protected internal int Value { get; set; }");
await TestHelper.ExpectNoDiagnosticsAsync(sourceCode);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,65 @@

namespace Stride.Core.CompilerServices.Tests.AnalyzerTests;

/// <summary>
/// Tests for <see cref="STRDIAG004PropertyWithNoGetter"/> analyzer.
/// Validates that DataMember properties have accessible getters.
/// </summary>
public class STRDIAG004_Test
{
[Fact]
public async Task Error_On_No_Get_Property()
{
string sourceCode = string.Format(ClassTemplates.BasicClassTemplate, "[DataMember] public int Value { set; }");
await TestHelper.ExpectDiagnosticsErrorAsync(sourceCode, STRDIAG004PropertyWithNoGetter.DiagnosticId);
await TestHelper.ExpectDiagnosticAsync(sourceCode, STRDIAG004PropertyWithNoGetter.DiagnosticId);
}

[Fact]
public async Task Error_On_private_Get_Property()
{
string sourceCode = string.Format(ClassTemplates.BasicClassTemplate, "[DataMember] public int Value { private get; set; }");
await TestHelper.ExpectDiagnosticsErrorAsync(sourceCode, STRDIAG004PropertyWithNoGetter.DiagnosticId);
await TestHelper.ExpectDiagnosticAsync(sourceCode, STRDIAG004PropertyWithNoGetter.DiagnosticId);
}

[Fact]
public async Task Error_On_protected_Get_Property()
{
string sourceCode = string.Format(ClassTemplates.BasicClassTemplate, "[DataMember] public int Value { protected get; set; }");
await TestHelper.ExpectDiagnosticsErrorAsync(sourceCode, STRDIAG004PropertyWithNoGetter.DiagnosticId);
await TestHelper.ExpectDiagnosticAsync(sourceCode, STRDIAG004PropertyWithNoGetter.DiagnosticId);
}

[Fact]
public async Task Error_On_private_protected_Get_Property()
{
string sourceCode = string.Format(ClassTemplates.BasicClassTemplate, "[DataMember] public int Value { private protected get; set; }");
await TestHelper.ExpectDiagnosticsErrorAsync(sourceCode, STRDIAG004PropertyWithNoGetter.DiagnosticId);
await TestHelper.ExpectDiagnosticAsync(sourceCode, STRDIAG004PropertyWithNoGetter.DiagnosticId);
}

[Fact]
public async Task NoError_On_Public_Get_Property()
{
string sourceCode = string.Format(ClassTemplates.BasicClassTemplate, "[DataMember] public int Value { get; set; }");
await TestHelper.ExpectNoDiagnosticsAsync(sourceCode);
}

[Fact]
public async Task NoError_On_Internal_Get_Property()
{
string sourceCode = string.Format(ClassTemplates.BasicClassTemplate, "[DataMember] public int Value { internal get; set; }");
await TestHelper.ExpectNoDiagnosticsAsync(sourceCode);
}

[Fact]
public async Task NoError_On_ProtectedInternal_Get_Property()
{
string sourceCode = string.Format(ClassTemplates.BasicClassTemplate, "[DataMember] public int Value { protected internal get; set; }");
await TestHelper.ExpectNoDiagnosticsAsync(sourceCode);
}

[Fact]
public async Task NoError_On_Field()
{
string sourceCode = string.Format(ClassTemplates.BasicClassTemplate, "[DataMember] public int Value;");
await TestHelper.ExpectNoDiagnosticsAsync(sourceCode);
}
}
Loading
Loading