using System.Collections.Generic; using System.Linq; using UnitTestSharp; namespace Vellum.UnitTests { public class UnreadKeyTests : TestFixture { public static SaveSession Session(bool reports = true) { SaveSession session = SaveableTests.Session(); session.ReportsUnreadKeys = reports; return session; } public static class Reader { public class Breaks { } public class Skips { } public class Forgets { } } public class ReaderConverter : SaveConverter { public override SaveNode Write(Reader.Breaks value, SaveSession session) { return SaveNode.NewTable(); } public override Reader.Breaks Read(SaveNode node, SaveSession session) { new SaveReader(node, session); throw new System.InvalidOperationException("broke"); } } public class SkipsConverter : SaveConverter { public override SaveNode Write(Reader.Skips value, SaveSession session) { return SaveNode.NewTable(); } public override Reader.Skips Read(SaveNode node, SaveSession session) { new SaveReader(node, session).Skip("Mine"); return new Reader.Skips(); } } public class ForgetsConverter : SaveConverter { public override SaveNode Write(Reader.Forgets value, SaveSession session) { return SaveNode.NewTable(); } public override Reader.Forgets Read(SaveNode node, SaveSession session) { new SaveReader(node, session); return new Reader.Forgets(); } } public static SaveSession ConverterSession() { SaveSession session = new SaveConverters(new SaveConverter[] { new ReaderConverter(), new SkipsConverter(), new ForgetsConverter() }).CreateSession(); session.ReportsUnreadKeys = true; return session; } public static SaveNode CrateNode(SaveSession session) { var crate = new Crate { Inside = new Crate() }; return session.ToNode(crate, typeof(Crate)); } public class ReportingTests : TestFixture { public void ReportsNothingByDefault() { SaveSession session = Session(reports: false); SaveNode node = CrateNode(session); node.Entries["Gone"] = SaveNode.OfText("1"); session.FromNode(node, typeof(Crate)); CheckEqual(0, session.Sandbox.Issues.Count); } public void EveryKeyRead_ReportsNothing() { SaveSession session = Session(); session.FromNode(CrateNode(session), typeof(Crate)); CheckEqual(0, session.Sandbox.Issues.Count); } public void ExtraKey_IsReportedUnderItsName() { SaveSession session = Session(); SaveNode node = CrateNode(session); node.Entries["Gone"] = SaveNode.OfText("1"); session.FromNode(node, typeof(Crate)); CheckEqual(new[] { "Gone" }, SaveConvertersTests.IssuePaths(session)); CheckEqual(LoadIssueKind.UnreadKey, session.Sandbox.Issues.Single().Kind); } public void ExtraKeyInANestedObject_IsReportedBeneathTheKeysToIt() { SaveSession session = Session(); SaveNode node = CrateNode(session); node.Entries["Inside"].Entries["Gone"] = SaveNode.OfText("1"); session.FromNode(node, typeof(Crate)); CheckEqual(new[] { "Inside: Gone" }, SaveConvertersTests.IssuePaths(session)); } public void SeveralExtraKeys_AreReportedInOrder() { SaveSession session = Session(); SaveNode node = CrateNode(session); node.Entries["Zed"] = SaveNode.OfText("1"); node.Entries["Ant"] = SaveNode.OfText("1"); session.FromNode(node, typeof(Crate)); CheckEqual(new[] { "Ant", "Zed" }, SaveConvertersTests.IssuePaths(session)); } public void SubtypesTypeEntry_IsNotReported() { SaveSession session = Session(); SaveNode wrapped = session.ToNode(new Truck()); session.FromNode(wrapped, typeof(Pallet)); CheckEqual(0, session.Sandbox.Issues.Count); } public void ObjectInALoop_IsReportedOnce() { SaveSession session = Session(); var clan = new Clan(); clan.Scouts.Add(new Scout { Clan = clan }); SaveNode node = session.ToNode(clan, typeof(Clan)); node.Entries["Scouts"].Items[0].Entries["Gone"] = SaveNode.OfText("1"); session.FromNode(node, typeof(Clan)); CheckEqual(new[] { "Scouts: [0]: Gone" }, SaveConvertersTests.IssuePaths(session)); } public void ItemThatFailedMidRead_ReportsOnlyTheFailure() { SaveSession session = ConverterSession(); SaveNode item = SaveNode.NewTable(); item.Entries["Gone"] = SaveNode.OfText("1"); SaveNode list = SaveNode.NewList(); list.Items.Add(item); session.FromNode>(list); CheckEqual(new[] { "[0]" }, SaveConvertersTests.IssuePaths(session)); CheckEqual(LoadIssueKind.ConverterBug, session.Sandbox.Issues.Single().Kind); } public void FailedLoad_ReportsNothing() { SaveSession session = ConverterSession(); SaveNode node = SaveNode.NewTable(); node.Entries["Gone"] = SaveNode.OfText("1"); try { session.FromNode(node, typeof(Reader.Breaks)); } catch (System.InvalidOperationException) { } CheckEqual(0, session.Sandbox.Issues.Count); } } public class SkipTests : TestFixture { public static SaveNode OneKey() { SaveNode node = SaveNode.NewTable(); node.Entries["Mine"] = SaveNode.OfText("1"); return node; } public void SkippedKey_IsNotReported() { SaveSession session = ConverterSession(); session.FromNode(OneKey(), typeof(Reader.Skips)); CheckEqual(0, session.Sandbox.Issues.Count); } public void KeyNobodyReadOrSkipped_IsReported() { SaveSession session = ConverterSession(); session.FromNode(OneKey(), typeof(Reader.Forgets)); CheckEqual(new[] { "Mine" }, SaveConvertersTests.IssuePaths(session)); } public void DefaultReader_Throws() { CheckThrow(typeof(System.InvalidOperationException)); default(SaveReader).Skip("Mine"); } } } }