using System.Net; using System.Text; using XFEEDToolBox.Core.Galaxy; using XFEExtension.NetCore.XUnit.Attributes; namespace XFEEDToolBox.Test; [TestFixture] public class GalaxyFilterTests { private static GalacticSystem Star(string type="G")=>new("Fixture",new(0,0,0),StarClass:type); [Test] public void UnknownPoliticalDataNeverMasqueradesAsNoneOrUninhabited() { var f=new GalaxyMapFilter{Mode=GalaxyMapMode.Map,Category=GalaxyFilterCategory.Allegiance,Values=new HashSet{"none"},IncludeUnknown=false}; Check.That(!f.Matches(Star()));Check.That(f.Matches(Star() with{Data=new(){Allegiance="None"}})); Check.That((f with{IncludeUnknown=true}).Matches(Star())); var population=f with{Category=GalaxyFilterCategory.Population,Values=new HashSet{"uninhabited"}}; Check.That(!population.Matches(Star()));Check.That(population.Matches(Star() with{Data=new(){Population=0}})); Check.That(!population.Matches(Star() with{Data=new(){Population=500}})); } [Test] public void MainSequenceAndSpecialStarClassesRemainIndependentlySelectable() { var tests=new[]{("K (Yellow-Orange) Star","k"),("M_RedGiant","m_redgiant"),("M (Red super giant) Star","m_redsupergiant"),("White Dwarf (DA) Star","da"),("DAB","dab"),("Neutron Star","n"),("Black Hole","h"),("Supermassive Black Hole","supermassiveblackhole"),("Herbig Ae/Be Star","aebe"),("T Tauri Star","tts"),("WN","wn")}; foreach(var (input,key) in tests) { Check.Equal(key,GalaxyMapFilter.StarKey(input)); var f=new GalaxyMapFilter{Mode=GalaxyMapMode.Map,Values=new HashSet{key},IncludeUnknown=false}; Check.That(f.Matches(Star(input)),input);Check.That(!f.Matches(Star("Unknown exotic"))); Check.That(GalaxyFilterDefinitions.All.Single(x=>x.Category==GalaxyFilterCategory.StarClass).Choices.Any(c=>c.Key==key),input); } var scoop=new GalaxyMapFilter{Mode=GalaxyMapMode.Map,Values="obafgkm".Select(x=>x.ToString()).ToHashSet(),IncludeUnknown=false}; Check.That(scoop.Matches(Star("G")));Check.That(!scoop.Matches(Star("L")));Check.That(!scoop.Matches(Star("N"))); } [Test] public void EmptySelectionHidesKnownDataAndUnknownIsAnIndependentChoice() { var f=new GalaxyMapFilter{Mode=GalaxyMapMode.Map,Values=new HashSet(),IncludeUnknown=false}; Check.That(!f.Matches(Star()));Check.That(!f.Matches(Star(""))); Check.That((f with{IncludeUnknown=true}).Matches(Star("")));Check.That(!(f with{IncludeUnknown=true}).Matches(Star())); Check.That((f with{Values=null}).Matches(Star()));Check.That((f with{Mode=GalaxyMapMode.Realistic}).Matches(Star())); } [Test] public void MultipleServicesAndEconomiesUseAnInclusiveChoiceWithinTheSelectedCategory() { var s=Star() with{Data=new(){Services=["repair","refuel"],Economy="Agriculture",SecondaryEconomy="High Tech"}}; var f=new GalaxyMapFilter{Mode=GalaxyMapMode.Map,Category=GalaxyFilterCategory.Services,Values=new HashSet{"refuel"},IncludeUnknown=false}; Check.That(f.Matches(s));Check.That(!(f with{Values=new HashSet{"blackmarket"}}).Matches(s)); Check.That((f with{Category=GalaxyFilterCategory.Economy,Values=new HashSet{"hightech"}}).Matches(s)); Check.That(!f.Matches(Star() with{Data=new(){Services=[]}})); } [Test] public void PartialStationObservationsNeverProveTheWholeSystemLacksAService() { var observed=Star() with{Data=new(){Services=["refuel","materialtrader"]}}; var f=new GalaxyMapFilter{Mode=GalaxyMapMode.Map,Category=GalaxyFilterCategory.Services,Values=new HashSet{"shipyard"},IncludeUnknown=true}; Check.That(f.IsUnknown(observed));Check.That(f.Matches(observed));Check.That(!(f with{IncludeUnknown=false}).Matches(observed)); var subtype=f with{Values=new HashSet{"materialtraderraw"}}; Check.That(subtype.IsUnknown(observed));Check.That(!(subtype with{IncludeUnknown=false}).Matches(observed)); Check.That(!(f with{Values=new HashSet{"refuel"}}).IsUnknown(observed)); } [Test] public void OriginalNativeGiantAndBlackHoleNamesAgreeWithPublicSpectralDescriptions() { foreach(var (name,key,palette) in new[]{("Wolf-Rayet Star","w",0),("A_BlueWhiteSuperGiant","a_bluewhitesupergiant",2),("F_WhiteSuperGiant","f_whitesupergiant",3),("M_RedGiant","m_redgiant",6),("SupermassiveBlackHole","supermassiveblackhole",12)}) { Check.Equal(key,GalaxyMapFilter.StarKey(name));Check.Equal(palette,StellarAppearance.ColourIndex(name)); var f=new GalaxyMapFilter{Mode=GalaxyMapMode.Map,Values=new HashSet{key},IncludeUnknown=false};Check.That(f.Matches(Star(name))); } } [Test] public void NativeCompactLuminositySeparatesGiantsFromDwarfsWithoutReusingXOrNebulaTypeIds() { GalacticSystem Native(int type,int luminosity,string stale="M_RedGiant")=>Star(stale) with {OriginalAppearance=new(0,null,null,0,(ushort)(type|luminosity<<10),.7f,.7f,null)}; var giants=new GalaxyMapFilter{Mode=GalaxyMapMode.Map,Values=new HashSet{"m_redgiant","a_bluewhitesupergiant","k_orangegiant"}}; Check.That(giants.Matches(Native(6,10)));Check.That(giants.Matches(Native(5,6)));Check.That(giants.Matches(Native(2,3))); Check.That(!giants.Matches(Native(6,18)));Check.That(!giants.Matches(Native(6,14)));Check.That(!giants.Matches(Native(43,3)));Check.That(!giants.Matches(Native(44,3))); Check.Equal("x",GalaxyMapFilter.StarKey(Native(43,3)));Check.Equal((string?)null,GalaxyMapFilter.StarKey(Native(44,3))); Check.Equal("III",Native(6,10).OriginalAppearance!.LuminosityClass);Check.Equal("IV",Native(6,14).OriginalAppearance!.LuminosityClass); Check.That((giants with{Values=new HashSet{"m"}}).Matches(Native(6,18))); } [Test] public void JournalTokensAndVisitsAreObservedWithoutGuessingMissingFacts() { var d=GalaxySystemData.FromJournal(Check.Json("""{"SystemAllegiance":"Federation","SystemGovernment":"$government_Democracy;","SystemEconomy":"$economy_HighTech;","SystemSecurity":"$SYSTEM_SECURITY_high;","Population":0,"SystemFaction":{"Name":"Fixture","FactionState":"Boom"},"StationServices":["refuel","repair"]}""")); Check.Equal("Democracy",d.Government);Check.Equal("HighTech",d.Economy);Check.Equal("high",d.Security);Check.Equal("Boom",d.State);Check.That(d.Visited==true); Check.That(d.FleetCarrier is null&&d.Exploration is null&&d.TradeData is null); var older=new GalaxySystemData{Population=4000,Government="Corporate",Services=["shipyard"]}; var merged=older.Merge(new(){Population=0,Visited=true});Check.Equal(0L,merged.Population);Check.Equal("Corporate",merged.Government);Check.That(merged.Services!.Contains("shipyard")); } [Test] public async Task PublicCatalogRequestsRealInformationAndKeepsMissingInformationUnknown() { var handler=new CatalogHandler();using var http=new HttpClient(handler);var catalog=new GalaxyCatalog(http); var rows=await catalog.RegionAsync(new(0,0,0));Check.That(handler.Url.Contains("showInformation=1")); Check.Equal(2,rows.Count);Check.Equal("Federation",rows[0].Data.Allegiance);Check.Equal(0L,rows[0].Data.Population);Check.That(rows[1].Data.Population is null); Check.That(rows[1].Data.Visited is null);Check.That(rows[0].Data.Services is null); } [Test] public void EveryOriginalFilterCategoryHasAUniqueInventoryAndMapColoursAreStable() { Check.Equal(Enum.GetValues().Length,GalaxyFilterDefinitions.All.Count); Check.Equal(GalaxyFilterDefinitions.All.Count,GalaxyFilterDefinitions.All.Select(x=>x.Category).Distinct().Count()); foreach(var definition in GalaxyFilterDefinitions.All)Check.Equal(definition.Choices.Count,definition.Choices.Select(x=>x.Key).Distinct().Count()); var f=new GalaxyMapFilter{Mode=GalaxyMapMode.Map,Category=GalaxyFilterCategory.Allegiance};var a=Star() with{Data=new(){Allegiance="Alliance"}};var b=Star() with{Data=new(){Allegiance="Empire"}}; Check.That(f.GetColour(a)!=f.GetColour(b));Check.Equal(f.GetColour(a),f.GetColour(a with{Name="Other"})); } private sealed class CatalogHandler:HttpMessageHandler { public string Url=""; protected override Task SendAsync(HttpRequestMessage request,CancellationToken token) {Url=request.RequestUri!.OriginalString;return Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK){Content=new StringContent("""[{"name":"Known","coords":{"x":0,"y":0,"z":0},"primaryStar":{"type":"G"},"information":{"allegiance":"Federation","government":"Democracy","population":0,"economy":"High Tech","security":"High"}},{"name":"Unknown","coords":{"x":1,"y":0,"z":0}}]""",Encoding.UTF8,"application/json")});} } }