using System.Numerics; using System.Text.Json; using XFEEDToolBox.Core.Galaxy; using XFEExtension.NetCore.XUnit.Attributes; namespace XFEEDToolBox.Test; [TestFixture] public sealed class GalaxyOriginalCommodityFilterTests { private static GalaxyMapFilter Filter(int mode=0,uint uid=0xF0000001)=>new(){Mode=GalaxyMapMode.Map,Category=GalaxyFilterCategory.Commodity, Values=new HashSet{"gold"},OriginalCommodityOptions=[new(uid,"gold","Metals",1,true)],OriginalCommodityPriceMode=mode,CommodityDirection=GalaxyCommodityDirection.Both}; private static GalacticSystem Star(GalaxyMapFilter f,GalaxyNativeCommodityStyle? style,GalaxyNativeCommodityRequest? binding=null)=>new("Actual",new(0,0,0),42,"G") {Data=new(){AccountFid="F1",Commodities=["gold"],CommodityDemands=["gold"],ConfirmedQueries=new HashSet{f.QueryKey}, NativeFilterFacts=new("F1",100,42){Commodity=new(binding??f.CommodityRequest!,style)}}}; private static GalaxyNativeCommodityStyle Style(int category=0,float opacity=.5f,float size=1,int sprite=12)=>new(7,category,opacity,size,sprite,[2,.2f,.3f,.8f]); [Test] public void ExactOriginalUidAndBothPriceModesRemainDistinctFromObservedMarketIds() { var f=Filter();Check.Equal(new GalaxyNativeCommodityRequest(0xF0000001,0),f.CommodityRequest); Check.Equal(new GalaxyNativeCommodityRequest(0,3),(Filter(3,0)).CommodityRequest); Check.That(f.QueryKey!=Filter(3).QueryKey);Check.Equal(GalaxyCommodityDirection.Both,GalaxyOriginalCommodities.DirectionFromSavedPriceMode(3)); Check.That((f with{OriginalCommodityOptions=[]}).CommodityRequest is null); Check.That((f with{Values=new HashSet{"gold","silver"}}).CommodityRequest is null); Check.That((f with{OriginalCommodityOptions=[new(1,"gold","Metals",1,true),new(2,"gold","Metals",1,true)]}).CommodityRequest is null); Check.That((f with{OriginalCommodityOptions=[new(1,"gold","Metals",2,false)]}).CommodityRequest is null); } [Test] public void PublicPresenceAndSavedProofCannotReplaceUnknownOrKnownNoneInOriginalQueries() { var f=Filter();var unknown=Star(f,null); Check.That(!f.Matches(unknown)&&f.Evaluate(unknown).Unknown&&!f.Evaluate(unknown).Matches); Check.That(f.GetOriginalRgba(unknown) is null);Check.Equal(new StarColour(125,140,150),f.GetColour(unknown)); Check.That((f with{IncludeUnknown=true}).Matches(unknown)); var stale=Star(f,Style(),new(123,0));Check.That(!f.Matches(stale)&&f.IsUnknown(stale)); for(var category=0;category<4;category++)Check.That(f.Matches(Star(f,Style(category)))); var none=Star(f,Style(4));Check.That(!f.Matches(none)&&!f.IsUnknown(none));Check.That(!(f with{IncludeUnknown=true}).Matches(none)); Check.That(!f.Matches(Star(f,Style(opacity:0)))); } [Test] public void ImportedPendingUidCannotFallBackToPreviousPublicSelectionOrAnotherActualUid() { var previous=Filter() with{OriginalCommodityOptions=[],CommodityDirection=GalaxyCommodityDirection.Exports,OriginalCommodityPriceMode=null}; var pending=GalaxyOriginalSettings.Parse("",previous).Filter; var old=Star(previous,null) with{Data=new(){Commodities=["gold"],ConfirmedQueries=new HashSet{pending.QueryKey}}}; Check.That(pending.RequiresOriginalCommodity&&pending.CommodityRequest is null&&!pending.Matches(old)&&pending.IsUnknown(old)); Check.That(pending.Evaluate(old) is{Unknown:true,Matches:false});Check.That(pending.GetOriginalRgba(old) is null); Check.That((pending with{IncludeUnknown=true}).Matches(old)); var mismatched=pending with{OriginalCommodityOptions=Filter().OriginalCommodityOptions};Check.That(mismatched.CommodityRequest is null&&!mismatched.Matches(old)); Check.That((pending with{OriginalCommodityUid=124}).QueryKey!=pending.QueryKey); var manual=pending with{OriginalCommodityUid=null};Check.That(!manual.RequiresOriginalCommodity&&manual.Matches(old)); var restored=GalaxyOriginalCommodities.WithOptions(pending,[new(123,"gold","Metals",1,true)]);Check.Equal(new GalaxyNativeCommodityRequest(123,2),restored.CommodityRequest); } [Test] public void ActualRawRgbaOpacitySpritesAndIndependentSizeUseTheSameBoundSnapshot() { var f=Filter();var star=Star(f,Style(size:.5f,sprite:11)); Check.Equal(new Vector4(2,.2f,.3f,.4f),f.GetOriginalRgba(star)!.Value); Check.Equal(11,f.SpriteLayerFor(star));Check.Equal(.7f,f.RelativeSize(star)); Check.Equal(.5f,(f with{SizeCategory=GalaxyFilterCategory.Commodity}).RelativeSize(star)); var other=f with{Category=GalaxyFilterCategory.None,Values=null,SizeCategory=GalaxyFilterCategory.Commodity, SavedValues=new Dictionary?>{[GalaxyFilterCategory.Commodity]=new HashSet{"gold"}}}; Check.Equal(f.CommodityRequest,other.CommodityRequest);Check.That(other.Matches(star));Check.Equal(.5f,other.RelativeSize(star)); Check.That(!other.Matches(Star(f,Style(size:0)))); Check.That(!(other with{SavedValues=new Dictionary?>()}).Matches(star)); } [Test] public void RuntimeCommodityFactsClearWithSessionAndExplicitUnknownWithoutDiskOrIdentityChurn() { var f=Filter();var data=Star(f,Style()).Data; var equal=data with{NativeFilterFacts=data.NativeFilterFacts! with{Commodity=new(f.CommodityRequest!,Style())}}; Check.That(ReferenceEquals(data,data.Merge(equal))); var changed=data.Merge(data with{NativeFilterFacts=data.NativeFilterFacts! with{Commodity=new(f.CommodityRequest!,null)}}); Check.That(changed.NativeFilterFacts!.Commodity is{Style:null});Check.That(!ReferenceEquals(changed,data)); Check.That(data.ForAccount("F2").NativeFilterFacts is null&&data.ForNativeContext("F1",101,42).NativeFilterFacts is null&&data.ForNativeContext("F1",100,43).NativeFilterFacts is null); var stored=JsonSerializer.Serialize(data);Check.That(!stored.Contains("NativeFilterFacts")&&!stored.Contains("commodityUid",StringComparison.OrdinalIgnoreCase)); } }