using System.Collections.Generic; using System.IO; using UnitTestSharp; using Vellum; namespace Clave.Vellum.UnitTests { public class ChordArbiterConverterTests : TestFixture { public static List MountsOf(ChordArbiter arbiter) { var returnMe = new List(); foreach (ChordMount mount in arbiter.Mounts()) { returnMe.Add(mount); } return returnMe; } public static List ChordsOn(ChordArbiter arbiter, ChordMount mount) { var returnMe = new List(); foreach (Chord chord in arbiter.ChordsOn(mount)) { returnMe.Add(chord); } return returnMe; } public static KeyboardSnapshot Pressing(KeyCode key) { return new KeyTracker().KeyDown(key, key, isRepeat: false); } public class WriteTests : TestFixture { public void EmptyArbiter_IsNoMounts() { SaveNode node = SavedThrough.Session().ToNode(new ChordArbiter(), typeof(ChordArbiter)); CheckEqual(0, node.RequireEntry(ChordArbiterConverter.MountsKey).Items.Count); } public void EachMount_IsSavedInTheOrderItWasMountedWithItsEnabledFlag() { var arbiter = new ChordArbiter(); ChordMount removed = arbiter.Mount(); ChordMount first = arbiter.Mount(Chord.Press(KeyCode.Z)); ChordMount second = arbiter.Mount(Chord.Press(KeyCode.X)); arbiter.Unmount(removed); arbiter.Mount(Chord.Press(KeyCode.C)); arbiter.SetEnabled(second, false); IReadOnlyList mounts = SavedThrough.Session().ToNode(arbiter, typeof(ChordArbiter)) .RequireEntry(ChordArbiterConverter.MountsKey).Items; CheckEqual(3, mounts.Count); CheckEqual("true", mounts[0].RequireEntry(ChordSetConverter.EnabledKey).Text); CheckEqual("false", mounts[1].RequireEntry(ChordSetConverter.EnabledKey).Text); CheckEqual("true", mounts[2].RequireEntry(ChordSetConverter.EnabledKey).Text); } public void TheChordsOfAMount_AreSavedHighestPriorityFirst() { var arbiter = new ChordArbiter(); ChordMount mount = arbiter.Mount(); arbiter.Add(Chord.Press(KeyCode.Z), mount, priority: 1); arbiter.Add(Chord.Press(KeyCode.X), mount, priority: 5); IReadOnlyList chords = SavedThrough.Session().ToNode(arbiter, typeof(ChordArbiter)) .RequireEntry(ChordArbiterConverter.MountsKey).Items[0] .RequireEntry(ChordSetConverter.ChordsKey).Items; CheckEqual("5", chords[0].RequireEntry(ChordSetConverter.PriorityKey).Text); CheckEqual("1", chords[1].RequireEntry(ChordSetConverter.PriorityKey).Text); } public void EachChordOfAMount_IsSavedWithItsPriorityAndEnabledFlag() { var arbiter = new ChordArbiter(); ChordMount mount = arbiter.Mount(); Chord chord = arbiter.Add(Chord.Press(KeyCode.Z), mount, priority: 7); arbiter.SetEnabled(chord, mount, false); SaveNode entry = SavedThrough.Session().ToNode(arbiter, typeof(ChordArbiter)) .RequireEntry(ChordArbiterConverter.MountsKey).Items[0] .RequireEntry(ChordSetConverter.ChordsKey).Items[0]; CheckEqual("7", entry.RequireEntry(ChordSetConverter.PriorityKey).Text); CheckEqual("false", entry.RequireEntry(ChordSetConverter.EnabledKey).Text); } } public class ReadTests : TestFixture { public void MissingMounts_Throws() { CheckThrow(typeof(InvalidDataException)); SavedThrough.Session().FromNode(SaveNode.NewTable(), typeof(ChordArbiter)); } public void AMountWithoutChords_Throws() { SaveNode mounts = SaveNode.NewList(); mounts.Items.Add(SaveNode.NewTable()); SaveNode node = SaveNode.NewTable(); node.Entries[ChordArbiterConverter.MountsKey] = mounts; CheckThrow(typeof(InvalidDataException)); SavedThrough.Session().FromNode(node, typeof(ChordArbiter)); } public void AMountWithoutAnEnabledFlag_IsEnabled() { SaveNode mount = ChordSetConverterTests.Saved(ChordSetConverterTests.Entry("Pressed(Z)")); SaveNode mounts = SaveNode.NewList(); mounts.Items.Add(mount); SaveNode node = SaveNode.NewTable(); node.Entries[ChordArbiterConverter.MountsKey] = mounts; var loaded = (ChordArbiter)SavedThrough.Session().FromNode(node, typeof(ChordArbiter)); CheckTrue(loaded.IsEnabled(MountsOf(loaded)[0])); } } public class TryListChildrenTests : TestFixture { public static SaveNode Mounts(params SaveNode[] mounts) { SaveNode list = SaveNode.NewList(); list.Items.AddRange(mounts); SaveNode returnMe = SaveNode.NewTable(); returnMe.Entries[ChordArbiterConverter.MountsKey] = list; return returnMe; } public void TheChordsOfEveryMount_AreListedAsChords() { SaveNode node = Mounts( ChordSetConverterTests.Saved(ChordSetConverterTests.Entry("Pressed(Z)")), ChordSetConverterTests.Saved(ChordSetConverterTests.Entry("Pressed(X)"), ChordSetConverterTests.Entry("Pressed(C)"))); var children = new ChildList(); CheckTrue(new ChordArbiterConverter().TryListChildren(node, children)); CheckEqual(3, children.Count); CheckEqual(typeof(Chord), children.TypeAt(2)); } public void NoMountsEntry_ListsNothing() { var children = new ChildList(); CheckFalse(new ChordArbiterConverter().TryListChildren(SaveNode.NewTable(), children)); } public void AMountWithoutChords_ListsNothing() { var children = new ChildList(); CheckFalse(new ChordArbiterConverter().TryListChildren(Mounts(SaveNode.NewTable()), children)); } } public class RoundTripTests : TestFixture { public void Mounts_KeepTheirOrderAndEnabledFlags() { var arbiter = new ChordArbiter(); ChordMount removed = arbiter.Mount(); arbiter.Mount(Chord.Press(KeyCode.Z)); ChordMount disabled = arbiter.Mount(Chord.Press(KeyCode.X), priority: 4); arbiter.Unmount(removed); arbiter.Mount(); arbiter.SetEnabled(disabled, false); ChordArbiter loaded = SavedThrough.RoundTrip(arbiter); List mounts = MountsOf(loaded); CheckEqual(3, mounts.Count); CheckEqual(1, loaded.CountOn(mounts[0])); CheckEqual(1, loaded.CountOn(mounts[1])); CheckEqual(0, loaded.CountOn(mounts[2])); CheckTrue(loaded.IsEnabled(mounts[0])); CheckFalse(loaded.IsEnabled(mounts[1])); CheckTrue(loaded.IsEnabled(mounts[2])); } public void Chords_KeepPriorityAndEnabledFlag() { var arbiter = new ChordArbiter(); ChordMount mount = arbiter.Mount(); Chord kept = arbiter.Add(Chord.Press(KeyCode.Z), mount, priority: 2); Chord off = arbiter.Add(Chord.Press(KeyCode.X), mount, priority: -1); arbiter.SetEnabled(off, mount, false); ChordArbiter loaded = SavedThrough.RoundTrip(arbiter); ChordMount loadedMount = MountsOf(loaded)[0]; List chords = ChordsOn(loaded, loadedMount); Chord loadedKept = chords.Find(chord => chord.Formula.Equals(kept.Formula)); Chord loadedOff = chords.Find(chord => chord.Formula.Equals(off.Formula)); CheckEqual(2, loaded.PriorityOf(loadedKept, loadedMount)); CheckEqual(-1, loaded.PriorityOf(loadedOff, loadedMount)); CheckTrue(loaded.IsEnabled(loadedKept, loadedMount)); CheckFalse(loaded.IsEnabled(loadedOff, loadedMount)); } public void EquivalentChordsOnTwoMounts_StillCompeteByPriority() { var arbiter = new ChordArbiter(); arbiter.Mount(Chord.Press(KeyCode.Z), priority: 0); arbiter.Mount(Chord.Press(KeyCode.Z), priority: 1); ChordArbiter loaded = SavedThrough.RoundTrip(arbiter); List mounts = MountsOf(loaded); KeyboardSnapshot pressingZ = Pressing(KeyCode.Z); CheckFalse(loaded.ShouldFire(ChordsOn(loaded, mounts[0])[0], mounts[0], pressingZ)); CheckTrue(loaded.ShouldFire(ChordsOn(loaded, mounts[1])[0], mounts[1], pressingZ)); } public void ASpecificChordOnAnotherMount_StillHidesTheGeneralOne() { var arbiter = new ChordArbiter(); arbiter.Mount(Chord.Press(KeyCode.Z)); arbiter.Mount(Chord.Press(KeyCode.Z).WithAnyHeld(KeyState.Shift)); ChordArbiter loaded = SavedThrough.RoundTrip(arbiter); var tracker = new KeyTracker(); tracker.KeyDown(KeyCode.ShiftLeft, KeyCode.ShiftLeft, isRepeat: false); KeyboardSnapshot shiftZ = tracker.KeyDown(KeyCode.Z, KeyCode.Z, isRepeat: false); List mounts = MountsOf(loaded); CheckFalse(loaded.ShouldFire(ChordsOn(loaded, mounts[0])[0], mounts[0], shiftZ)); CheckTrue(loaded.ShouldFire(ChordsOn(loaded, mounts[1])[0], mounts[1], shiftZ)); } public void AMountDisabledAsAWhole_KeepsEachChordsOwnEnabledFlag() { var arbiter = new ChordArbiter(); ChordMount mount = arbiter.Mount(); arbiter.Add(Chord.Press(KeyCode.Z), mount); Chord off = arbiter.Add(Chord.Press(KeyCode.X), mount); arbiter.SetEnabled(off, mount, false); arbiter.SetEnabled(mount, false); ChordArbiter loaded = SavedThrough.RoundTrip(arbiter); ChordMount loadedMount = MountsOf(loaded)[0]; loaded.SetEnabled(loadedMount, true); int enabled = 0; foreach (Chord chord in loaded.ChordsOn(loadedMount)) { if (loaded.IsEnabled(chord, loadedMount)) { ++enabled; } } CheckEqual(1, enabled); } } } }