using AcDream.App.UI; using AcDream.App.UI.Layout; using AcDream.Core.Items; using AcDream.Core.Net.Messages; namespace AcDream.App.Tests.UI.Layout; public sealed class CreatureAppraisalRowsTests { [Fact] public void FailedAssessmentShowsOnlyHealthPercentAndUnknownOtherValues() { var profile = Profile( health: 25u, healthMax: 100u, highlights: (ushort)0, colors: (ushort)0); IReadOnlyList rows = CreatureAppraisalRows.Build(profile, success: false); Assert.All( rows, row => Assert.Equal( CreatureAppraisalValueStyle.Incomplete, row.Style)); Assert.Equal("25 %", rows[6].Value); Assert.Equal("???", rows[0].Value); Assert.Equal("???", rows[7].Value); Assert.Equal("???", rows[8].Value); } [Fact] public void EnchantmentBitsSelectRetailPositiveAndNegativeStyles() { var profile = Profile( health: 100u, healthMax: 100u, highlights: (ushort)((1 << 0) | (1 << 6)), colors: (ushort)(1 << 0)); IReadOnlyList rows = CreatureAppraisalRows.Build(profile, success: true); Assert.Equal(CreatureAppraisalValueStyle.Positive, rows[0].Style); Assert.Equal(CreatureAppraisalValueStyle.Negative, rows[6].Style); Assert.Equal(CreatureAppraisalValueStyle.Normal, rows[1].Style); } [Fact] public void ExtraRatingsFollowRetailGroupingFormattingAndSeparators() { var properties = new PropertyBundle(); properties.Ints[0x133u] = 35; properties.Ints[0x139u] = 7; properties.Ints[0x13Au] = 4; properties.Ints[0x134u] = 12; properties.Ints[0x13Bu] = 3; properties.Ints[0x13Cu] = 2; properties.Ints[0x15Eu] = 9; properties.Ints[0x15Fu] = 6; IReadOnlyList rows = CreatureAppraisalRows.BuildExtra(properties); Assert.Equal(5, rows.Count); Assert.Equal(("", ""), (rows[0].Label, rows[0].Value)); Assert.Equal( ("Dmg/CritDmg", "Rating: 35/4"), (rows[1].Label, rows[1].Value)); Assert.Equal( ("Dmg/CritDmg", "Resist: 12/2"), (rows[2].Label, rows[2].Value)); Assert.Equal( ("DoT/Life:", "Resist: 9/6"), (rows[3].Label, rows[3].Value)); Assert.Equal(("", ""), (rows[4].Label, rows[4].Value)); } [Fact] public void CritOnlyTriggersRatingRowWhileHealingBoostAloneDoesNot() { var critOnly = new PropertyBundle(); critOnly.Ints[0x139u] = 8; IReadOnlyList rows = CreatureAppraisalRows.BuildExtra(critOnly); Assert.Equal(3, rows.Count); Assert.Equal("Rating: 0/0", rows[1].Value); var healingOnly = new PropertyBundle(); healingOnly.Ints[0x143u] = 20; Assert.Empty(CreatureAppraisalRows.BuildExtra(healingOnly)); } [Fact] public void AuthoredRowTemplateCarriesRetailOverlappingLabelValueGeometry() { ElementInfo template = FixtureLoader.LoadExaminationRowTemplateInfos(); Assert.Equal(CreatureAppraisalRowTemplateFactory.TemplateId, template.Id); Assert.Equal((292f, 20f), (template.Width, template.Height)); ElementInfo label = Assert.Single( template.Children, child => child.Id == CreatureAppraisalRowTemplateFactory.LabelId); ElementInfo value = Assert.Single( template.Children, child => child.Id == CreatureAppraisalRowTemplateFactory.ValueId); Assert.Equal((0f, 128f), (label.X, label.Width)); Assert.Equal((27f, 256f), (value.X, value.Width)); Assert.Equal(0x40000001u, label.FontDid); Assert.Equal(0x40000001u, value.FontDid); } [Fact] public void CreatureNameResolverUsesLoadedRetailMappingAndSafeFallback() { var resolver = new CreatureDisplayNameResolver( new Dictionary { [77u] = "Ghost" }); Assert.Equal("Ghost", resolver.Resolve(77)); Assert.Equal(string.Empty, resolver.Resolve(0)); Assert.Equal(string.Empty, resolver.Resolve(999)); } [Fact] public void LayeredTemplateSeparatesChromeFromForegroundText() { var templates = new CreatureAppraisalRowTemplateFactory( FixtureLoader.LoadExaminationRowTemplateInfos(), _ => (0u, 0, 0), defaultFont: null); var row = new CreatureAppraisalRow( "Strength", "120", CreatureAppraisalValueStyle.Normal); UiTemplateListSlot background = templates.Create( row, CreatureAppraisalRowLayer.Background); UiTemplateListSlot foreground = templates.Create( row, CreatureAppraisalRowLayer.Foreground); Assert.Empty(((UiText)background.Content.FindElement( CreatureAppraisalRowTemplateFactory.LabelId)!).LinesProvider()); Assert.Empty(((UiText)background.Content.FindElement( CreatureAppraisalRowTemplateFactory.ValueId)!).LinesProvider()); Assert.False( Assert.IsType(foreground.Content.Root).MediaVisible); Assert.Equal( "Strength", Assert.Single(((UiText)foreground.Content.FindElement( CreatureAppraisalRowTemplateFactory.LabelId)!) .LinesProvider()).Text); Assert.Equal( "120", Assert.Single(((UiText)foreground.Content.FindElement( CreatureAppraisalRowTemplateFactory.ValueId)!) .LinesProvider()).Text); } private static AppraiseInfoParser.CreatureProfile Profile( uint health, uint healthMax, ushort highlights, ushort colors) => new( Flags: 0x09u, Health: health, HealthMax: healthMax, Strength: null, Endurance: null, Quickness: null, Coordination: null, Focus: null, Self: null, Stamina: 50u, Mana: 75u, StaminaMax: 100u, ManaMax: 100u, AttributeHighlights: highlights, AttributeColors: colors); }