public void TestCustomPrinters_InheritanceTest() { // ReversedListSource<T> is sufficiently complicated for this test. Inheritance: // // Many other interfaces Many other interfaces (including IListSource) // ^ ^ // | | // ICollectionImpl<T> IListAndListSource<T> // ^ ^ // | | // ReadOnlyCollectionBase<T> IListImpl<T> // ^ ^ // | | // ListSourceBase<T>------------------/ // ^ // | // ReversedListSource<T> var lht = new LiteralHandlerTable(); Assert.IsTrue(lht.AddPrinter(false, typeof(IListAndListSource <int>), PrintFirstElem)); Assert.IsTrue(lht.AddPrinter(false, typeof(IListSource <int>), PrintFail)); // Won't be used var list = new DList <int> { 123, 456, 789 }; var rlist = new ReversedListSource <int>(list); var sb = new StringBuilder(); Assert.AreEqual("list!", lht.TryPrint(CL(rlist, "list!"), sb).Left.Value.Name); Assert.AreEqual("789", sb.ToString()); // Now add something that will have higher priority... Assert.IsTrue(lht.AddPrinter(false, typeof(IListImpl <int>), PrintFirstChar)); Assert.AreEqual("eels", lht.TryPrint(CL(rlist, "cool!"), sb).Left.Value.Name); Assert.AreEqual(1, sb.Length); // Printer for base class ReadOnlyCollectionBase takes priority over interface IListImpl. // And that one will fail. But the fallback will succeed. Assert.IsTrue(lht.AddPrinter(false, typeof(ReadOnlyCollectionBase <int>), PrintFail)); Assert.AreEqual("eels", lht.TryPrint(CL(rlist, "..."), sb).Left.Value.Name); Assert.AreEqual(1, sb.ToString().Length); // Now install a printer that will succeed Assert.IsTrue(lht.AddPrinter(true, typeof(ReadOnlyCollectionBase <int>), PrintFirstElem)); Assert.AreEqual("cool!", lht.TryPrint(CL(rlist, "cool!"), sb).Left.Value.Name); Assert.AreEqual("789", sb.ToString()); }
public void TestCustomPrinters() { var lht = new LiteralHandlerTable(); // Can't add printer for null Assert.IsFalse(lht.AddPrinter(true, (Type)null, PrintTrim)); Assert.IsFalse(lht.AddPrinter(true, (Symbol)null, PrintTrim)); // Add printer for "trim" marker and string Assert.IsTrue(lht.AddPrinter(false, (Symbol)"trim", PrintTrim)); Assert.IsTrue(lht.AddPrinter(false, typeof(string), PrintTrim)); Assert.IsFalse(lht.AddPrinter(false, typeof(string), PrintTrim)); Assert.IsTrue(lht.AddPrinter(true, typeof(string), PrintTrim)); Assert.IsTrue(lht.AddPrinter(true, typeof(string), PrintTrim)); // Originally there is no printer for int var sb = new StringBuilder(); Assert.IsTrue(lht.TryPrint(LNode.Literal(123), sb).Right.HasValue); Assert.IsTrue(lht.TryPrint(LNode.Literal(123), sb).Right.Value.Format.Contains("no printer for type 'System.Int32'")); Assert.AreEqual("", sb.ToString()); // Add a printer for int and try it Assert.IsTrue(lht.AddPrinter(false, typeof(int), PrintTrim)); Assert.AreEqual("hovercraft", lht.TryPrint(CL(123, "fail"), sb).Left.Value.Name); Assert.AreEqual("123", sb.ToString()); // Add printer for "fail" marker and try it. Assert.IsTrue(lht.AddPrinter(false, (Symbol)"fail", PrintFail)); Assert.AreEqual("Always fails", lht.TryPrint(CL(new int[5], "fail"), sb).Right.Value.Format); Assert.AreEqual("FAIL", sb.ToString()); // TypeMarker printers take priority, so "fail" runs at first. Then the handler for int runs. Assert.AreEqual("hovercraft", lht.TryPrint(CL(999, "fail"), sb).Left.Value.Name); Assert.AreEqual("999", sb.ToString()); // Try our string and trim modes Assert.AreEqual("hovercraft", lht.TryPrint(LNode.Literal(" hi! "), sb).Left.Value.Name); Assert.AreEqual("hi!", sb.ToString()); Assert.AreEqual("hovercraft", lht.TryPrint(CL(new StringBuilder(" bye! "), "trim"), sb).Left.Value.Name); Assert.AreEqual("bye!", sb.ToString()); // TypeMarker printers take priority, so "firstChar" runs in preference to the string handler. Assert.IsTrue(lht.AddPrinter(false, (Symbol)"firstChar", PrintFirstChar)); Assert.AreEqual("eels", lht.TryPrint(CL("hi! ", "firstChar"), sb).Left.Value.Name); Assert.AreEqual("h", sb.ToString()); }