using System; using System.Collections.Concurrent; using System.IO; using System.Runtime.CompilerServices; namespace GamecraftModdingAPI.Tests { /// /// API test system assertion utilities. /// public static class Assert { private static StreamWriter logFile = null; private static ConcurrentDictionary callbacks = new ConcurrentDictionary(); private const string PASS = "SUCCESS: "; private const string FAIL = "FAILURE: "; private const string WARN = "WARNING: "; private const string INFO = "DEBUG: "; /// /// Log a message to the test log. /// /// Message. /// Message ending. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Log(string msg, string end = "\n") { if (logFile == null) openTestLog(); logFile.Write(msg + end); logFile.Flush(); } /// /// Asserts that the event receives a callback... eventually. /// Add the eventhandler returned by this method to the relevant event. /// This does not assert that the callback happens under that event's intended circumstances. /// Add another event handler to assert specific circumstance requirements. /// /// The callback event handler. /// Event name. /// Event error message. /// The event handler callback argument object. public static EventHandler CallsBack(string eventName, string eventMsg = null) { if (eventMsg == null) eventMsg = $"expected callback to {eventName} but it never occurred..."; callbacks[eventName] = eventMsg; return (sender, args) => { string value = null; if (!callbacks.TryRemove(eventName, out value)) { Log(WARN + $"callback to {eventName} occurred again or a related error occurred... (Received '{args.ToString()}' from '{(sender == null ? (string)sender : sender.ToString())}')"); } Log(PASS + $"callback to {eventName} occurred... (Received '{args.ToString()}' from '{(sender == null ? (string)sender : sender.ToString())}')"); TestRoot.TestsPassed = true; }; } internal static void CallsComplete() { foreach(string key in callbacks.Keys) { Log(FAIL + callbacks[key]); TestRoot.TestsPassed = false; } } internal static void CloseLog() { if (logFile != null) logFile.Close(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void openTestLog() { logFile = File.CreateText(TestRoot.ReportFile); } } }