using System; using System.Collections.Generic; using System.Runtime.Versioning; using Amphora; using Ariadne; using Vellum; [assembly: SupportedOSPlatform("browser")] namespace Vellum.WasmProbe { public static class Program { private static int failures; private static TickContext Fresh() { return new TickContext(new ExceptionSandbox(typeof(AriadneSites).Assembly), TimeSpan.Zero, TimeSpan.Zero); } private static SaveConverters converters; private static SaveConverters Converters { get { return converters ?? (converters = SaveConverters.For(typeof(Program).Assembly)); } } private static void Describe(Exception exception) { for (Exception each = exception; each != null; each = each.InnerException) { Console.WriteLine(" " + each.GetType().FullName + ": " + each.Message.Split('\n')[0]); string[] frames = (each.StackTrace ?? "").Split('\n'); for (int i = 0; i < frames.Length && i < 4; ++i) { Console.WriteLine(" " + frames[i].Trim()); } } } private static string Save(object value, Type type) { return LuaSaveFormat.Format(Converters.CreateSession().ToNode(value, type)); } private static object Load(string text, Type type) { return Converters.CreateSession().FromNode(LuaSaveFormat.Parse(text), type); } private static void Check(string name, Func test) { try { bool ok = test(); Console.WriteLine((ok ? "PASS " : "FAIL ") + name); if (!ok) { failures++; } } catch (Exception exception) { Console.WriteLine("FAIL " + name); Describe(exception); failures++; } } #if SAVER private static void PrintSaves() { var zoo = new Zoo { Star = new Dog { Name = "Rex", Tricks = 3 }, Other = new Cat { Name = "Tom", Mood = Mood.Angry }, Pairs = new List { new Pair { A = 1, B = "one" }, new Pair { A = 2, B = "two" } }, Index = new Dictionary { { "k", new Pair { A = 9, B = "nine" } } }, Mood = Mood.Calm, }; var hidden = new Hidden(); hidden.Tick(new Gates(), Fresh()); Console.WriteLine("---ZOO---"); Console.WriteLine(Save(zoo, typeof(Zoo))); Console.WriteLine("---ARCS---"); SaveNode document = SaveNode.NewTable(); document.Entries["arcs"] = Converters.CreateSession().ToNode(new List> { hidden }, typeof(List>)); Console.WriteLine(LuaSaveFormat.Format(document)); Console.WriteLine("---END---"); } #endif private static int Main() { Console.WriteLine("probe: " + System.Runtime.InteropServices.RuntimeInformation.RuntimeIdentifier); try { Console.WriteLine("converters: " + (Converters != null)); } catch (Exception exception) { Console.WriteLine("FAIL creating the converters"); Describe(exception); return 98; } #if SAVER PrintSaves(); #endif Check("subclass built in code, struct list and map, enum", () => { var zoo = new Zoo { Star = new Dog { Name = "Rex", Tricks = 3 }, Pairs = new List { new Pair { A = 1, B = "one" }, new Pair { A = 2, B = "two" } }, Index = new Dictionary { { "k", new Pair { A = 9, B = "nine" } } }, Mood = Mood.Angry, }; var loaded = (Zoo)Load(Save(zoo, typeof(Zoo)), typeof(Zoo)); return loaded.Star is Dog dog && dog.Tricks == 3 && dog.Name == "Rex" && loaded.Pairs.Count == 2 && loaded.Pairs[1].B == "two" && loaded.Index["k"].A == 9 && loaded.Mood == Mood.Angry; }); Check("subclass no code constructs (Cat), enum, from a saved file", () => { var loaded = (Zoo)Load(ProbeSaves.Zoo, typeof(Zoo)); return loaded.Other is Cat cat && cat.Name == "Tom" && cat.Mood == Mood.Angry && loaded.Star is Dog && loaded.Pairs.Count == 2 && loaded.Index["k"].B == "nine"; }); Check("arc no code constructs (Hidden), from a saved file", () => { SaveNode document = LuaSaveFormat.Parse(ProbeSaves.Arcs); var loaded = (List>)Converters.CreateSession().FromNode(document.RequireEntry("arcs"), typeof(List>)); var gates = new Gates(); gates.Open.Add("go"); loaded[0].Tick(gates, Fresh()); return loaded[0].GetType().Name == "Hidden" && ((Hidden)loaded[0]).Count == 1 && loaded[0].Finished; }); Check("arc with generic polymorphic recursion, reloaded at each pause", () => { var gates = new Gates(); var script = new Widening(); script.Tick(gates, Fresh()); foreach (string gate in new[] { "wrap2", "wrap1", "wrap0" }) { script = (Widening)Load(Save(script, typeof(Widening)), typeof(Widening)); gates.Open.Add(gate); script.Tick(gates, Fresh()); } return script.Log == "0@2;1@1;2@0;up2;up1;up0;" && script.Finished; }); Console.WriteLine(failures == 0 ? "ALL PASSED" : failures + " FAILED"); return failures; } } }