using game.PlayerDataStorage; using Newtonsoft.Json.Linq; static partial class Tests { static async Task RunPotionSchemaTests() { await Run("M25-potion-complete-nested-and-enums",() => { var item=new { name="synthetic",index=3,isOver=true,DataType=2,ColorTypeList=new[] { 7,9 },ShelfTypeList=new[] { 0,1 },GridStateList=new[] { 0,5 },FromDisplayAreaIndexList=new[] { 1,2 } }; var obj=JObject.FromObject(new { EventID=11,PotionID=11,StageID=11,Stage1TotalLevel=11,Stage2TotalLevel=11,LevelID=11,LevelIndex=11,CorrectNum=11,SubmitNum=11,Token=11,ConsumedToken=11,Rule=11,PreEventID=11,PrePotionID=11,PreStageID=11,PreLevelID=11,Round=11,FirstPlayedEventId=11,IsOver=true,Name="synthetic",InflationRate=1.5f,LevelTargetData=item,LevelDisplayData=item,LevelProcessedList=new[] { item } }); Dictionary Raw(JObject value)=>new() { ["epdk"]=value.ToString() }; var state=PlayerKVSaveSchema.DecodePotion(Raw(obj),new()); Check(state!=null && state.IsPresent,"present valid"); Check(state.EventID==11,"EventID"); Check(state.PotionID==11,"PotionID"); Check(state.StageID==11,"StageID"); Check(state.Stage1TotalLevel==11,"Stage1TotalLevel"); Check(state.Stage2TotalLevel==11,"Stage2TotalLevel"); Check(state.LevelID==11,"LevelID"); Check(state.LevelIndex==11,"LevelIndex"); Check(state.CorrectNum==11,"CorrectNum"); Check(state.SubmitNum==11,"SubmitNum"); Check(state.Token==11,"Token"); Check(state.ConsumedToken==11,"ConsumedToken"); Check(state.Rule==11,"Rule"); Check(state.PreEventID==11,"PreEventID"); Check(state.PrePotionID==11,"PrePotionID"); Check(state.PreStageID==11,"PreStageID"); Check(state.PreLevelID==11,"PreLevelID"); Check(state.Round==11,"Round"); Check(state.FirstPlayedEventId==11,"FirstPlayedEventId"); Check(state.IsOver==true,"IsOver"); Check(state.Name=="synthetic","Name"); Check(state.InflationRate==1.5f,"InflationRate"); foreach(var entry in new[] { state.LevelTargetData,state.LevelDisplayData,state.LevelProcessedList[0] }) Check(entry.Name=="synthetic" && entry.Index==3 && entry.IsOver && entry.DataType==2 && entry.Colors.SequenceEqual(new[] { 7,9 }) && entry.Shelves.SequenceEqual(new[] { 0,1 }) && entry.Grids.SequenceEqual(new[] { 0,5 }) && entry.FromDisplay.SequenceEqual(new[] { 1,2 }),"all nested fields"); foreach(var path in obj.Properties().Select(p=>p.Name).Concat(new[] { "LevelTargetData.name","LevelTargetData.index","LevelTargetData.isOver","LevelTargetData.DataType", "LevelTargetData.ColorTypeList","LevelTargetData.ShelfTypeList","LevelTargetData.GridStateList","LevelTargetData.FromDisplayAreaIndexList","LevelProcessedList[0]" })) { var bad=(JObject)obj.DeepClone(); bad.SelectToken(path).Replace(JValue.CreateNull()); Check(PlayerKVSaveSchema.DecodePotion(Raw(bad),new())==null,"all nested nulls rejected"); } foreach(var path in new[] { "LevelTargetData.DataType","LevelTargetData.ShelfTypeList[0]","LevelTargetData.GridStateList[0]" }) { var bad=(JObject)obj.DeepClone(); bad.SelectToken(path).Replace(new JValue(99)); Check(PlayerKVSaveSchema.DecodePotion(Raw(bad),new())==null,"undefined enum rejected"); } Check(!PlayerKVSaveSchema.DecodePotion(new Dictionary(),new()).IsPresent,"missing distinct"); return Task.CompletedTask; }); } }