From 5e7f687e2200e7c12bce713fb5269d88d9462ca1 Mon Sep 17 00:00:00 2001 From: Eideren Date: Wed, 11 Dec 2024 18:48:19 +0100 Subject: [PATCH 1/2] feat: Process required keyword like MemberRequiredAttribute --- .../ComponentChecks/RequiredMembersCheck.cs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/sources/engine/Stride.Assets/Entities/ComponentChecks/RequiredMembersCheck.cs b/sources/engine/Stride.Assets/Entities/ComponentChecks/RequiredMembersCheck.cs index 000b67d8b5..a7ed663f46 100644 --- a/sources/engine/Stride.Assets/Entities/ComponentChecks/RequiredMembersCheck.cs +++ b/sources/engine/Stride.Assets/Entities/ComponentChecks/RequiredMembersCheck.cs @@ -33,12 +33,16 @@ public void Check(EntityComponent component, Entity entity, AssetItem assetItem, if (member.Type.IsValueType) continue; // value types cannot be null, and must always have a proper default value - MemberRequiredAttribute memberRequired; - if ((memberRequired = member.GetCustomAttributes(true).FirstOrDefault()) != null) - { - if (member.Get(component) == null) - WriteResult(result, componentName, targetUrlInStorage, entity.Name, member.Name, memberRequired.ReportAs); - } + MemberRequiredReportType reportType; + if (member.GetCustomAttributes(true).FirstOrDefault() is {} strideAttribute) + reportType = strideAttribute.ReportAs; + else if (member.GetCustomAttributes(true).Any()) + reportType = MemberRequiredReportType.Warning; + else + continue; + + if (member.Get(component) == null) + WriteResult(result, componentName, targetUrlInStorage, entity.Name, member.Name, reportType); } } From 42d221072feecb3372109d77d5f9a8526e73c8d6 Mon Sep 17 00:00:00 2001 From: Eideren Date: Thu, 12 Dec 2024 21:33:22 +0100 Subject: [PATCH 2/2] Add tests --- .../TestMemberRequiredComponentChecks.cs | 73 +++++++++++++++++-- 1 file changed, 65 insertions(+), 8 deletions(-) diff --git a/sources/engine/Stride.Assets.Tests/TestMemberRequiredComponentChecks.cs b/sources/engine/Stride.Assets.Tests/TestMemberRequiredComponentChecks.cs index e92986078f..0176809942 100644 --- a/sources/engine/Stride.Assets.Tests/TestMemberRequiredComponentChecks.cs +++ b/sources/engine/Stride.Assets.Tests/TestMemberRequiredComponentChecks.cs @@ -35,6 +35,9 @@ public class MemberRequiredComponent : VirtualBaseComponent [MemberRequired] [DataMember] internal object InternalProp { get; set; } public override object VirtualProp { get; set; } = new object(); + public required object KeywordRequired { get; set; } + [MemberRequired(ReportAs = MemberRequiredReportType.Error)] public required object KeywordAndAttributeRequired { get; set; } + public MemberRequiredComponent(object initData, object internalData) { InitProp = initData; @@ -50,6 +53,8 @@ void EntityIsNotMissingRequiredMembers() InternalField = new object(), PublicProp = new object(), PublicField = new object(), + KeywordRequired = new object(), + KeywordAndAttributeRequired = new object() }; var entity = new Entity("test"); entity.Add(memberRequiredComponent); @@ -70,9 +75,11 @@ void EntityIsMissingRequiredMember_PublicField() InternalField = new object(), PublicProp = new object(), PublicField = null, + KeywordRequired = new object(), + KeywordAndAttributeRequired = new object() }; var memberName = nameof(memberRequiredComponent.PublicField); - TestSingle(memberRequiredComponent, memberName); + TestSingleWarning(memberRequiredComponent, memberName); } [Fact] @@ -83,9 +90,11 @@ void EntityIsMissingRequiredMember_PublicProp() InternalField = new object(), PublicProp = null, PublicField = new object(), + KeywordRequired = new object(), + KeywordAndAttributeRequired = new object() }; var memberName = nameof(memberRequiredComponent.PublicProp); - TestSingle(memberRequiredComponent, memberName); + TestSingleWarning(memberRequiredComponent, memberName); } [Fact] @@ -96,9 +105,11 @@ void EntityIsMissingRequiredMember_InitProp() InternalField = new object(), PublicProp = new object(), PublicField = new object(), + KeywordRequired = new object(), + KeywordAndAttributeRequired = new object() }; var memberName = nameof(MemberRequiredComponent.InitProp); - TestSingle(memberRequiredComponent, memberName); + TestSingleWarning(memberRequiredComponent, memberName); } [Fact] @@ -109,9 +120,41 @@ void EntityIsMissingRequiredMember_InternalProp() InternalField = new object(), PublicProp = new object(), PublicField = new object(), + KeywordRequired = new object(), + KeywordAndAttributeRequired = new object() }; var memberName = nameof(MemberRequiredComponent.InternalProp); - TestSingle(memberRequiredComponent, memberName); + TestSingleWarning(memberRequiredComponent, memberName); + } + + [Fact] + void EntityIsMissingRequiredMember_Keyword() + { + var memberRequiredComponent = new MemberRequiredComponent(new object(), new object()) + { + InternalField = new object(), + PublicProp = new object(), + PublicField = new object(), + KeywordRequired = null, + KeywordAndAttributeRequired = new object() + }; + var memberName = nameof(MemberRequiredComponent.KeywordRequired); + TestSingleWarning(memberRequiredComponent, memberName); + } + + [Fact] + void EntityIsMissingRequiredMember_KeywordWithAttribute() + { + var memberRequiredComponent = new MemberRequiredComponent(new object(), new object()) + { + InternalField = new object(), + PublicProp = new object(), + PublicField = new object(), + KeywordRequired = new object(), + KeywordAndAttributeRequired = null + }; + var memberName = nameof(MemberRequiredComponent.KeywordAndAttributeRequired); + TestSingleError(memberRequiredComponent, memberName); } [Fact] @@ -121,6 +164,8 @@ void EntityIsMissingAllRequiredMembers() { PublicProp = null, PublicField = null, + KeywordRequired = null, + KeywordAndAttributeRequired = null }; var entity = new Entity("test"); entity.Add(memberRequiredComponent); @@ -130,7 +175,7 @@ void EntityIsMissingAllRequiredMembers() Assert.True(check.AppliesTo(memberRequiredComponent.GetType())); check.Check(memberRequiredComponent, entity, null, "", result); - Assert.Equal(5, result.Messages.Count); + Assert.Equal(7, result.Messages.Count); } [Fact] @@ -142,12 +187,24 @@ void EntityIsMissingRequiredMember_VirtualProp() PublicProp = new object(), PublicField = new object(), VirtualProp = null, + KeywordRequired = new object(), + KeywordAndAttributeRequired = new object() }; var memberName = nameof(memberRequiredComponent.VirtualProp); - TestSingle(memberRequiredComponent, memberName); + TestSingleWarning(memberRequiredComponent, memberName); + } + + private static void TestSingleError(MemberRequiredComponent memberRequiredComponent, string memberName) + { + TestSingle(memberRequiredComponent, memberName, Core.Diagnostics.LogMessageType.Error); + } + + private static void TestSingleWarning(MemberRequiredComponent memberRequiredComponent, string memberName) + { + TestSingle(memberRequiredComponent, memberName, Core.Diagnostics.LogMessageType.Warning); } - private static void TestSingle(MemberRequiredComponent memberRequiredComponent, string memberName) + private static void TestSingle(MemberRequiredComponent memberRequiredComponent, string memberName, Core.Diagnostics.LogMessageType messageType) { var entity = new Entity("Test"); entity.Add(memberRequiredComponent); @@ -159,7 +216,7 @@ private static void TestSingle(MemberRequiredComponent memberRequiredComponent, check.Check(memberRequiredComponent, entity, null, "", result); Assert.Collection(result.Messages, (msg) => { - Assert.Equal(Core.Diagnostics.LogMessageType.Warning, msg.Type); + Assert.Equal(messageType, msg.Type); Assert.Contains(memberName, msg.Text); }); }