using System; using System.Threading; using UnitTestSharp; namespace Glass.UnitTests { public class TreeWalkGuardTests : TestFixture { public class BeginTests : TestFixture { public void EmptyContainer_Succeeds() { new TreeWalkGuard().Begin(new ControlContainer()).Dispose(); } public void WellFormedNestedTree_Succeeds() { var root = new Control("root"); root.CanvasChildren.Add(new Control("child")); root.CanvasChildren.Add(new Control("sibling")).CanvasChildren.Add(new Control("grandchild")); var controls = new ControlContainer(); controls.Add(root); new TreeWalkGuard().Begin(controls).Dispose(); } public void Cycle_Throws() { var parent = new Control("parent"); var child = new Control("child"); parent.CanvasChildren.Add(child); child.CanvasChildren.Add(parent); var controls = new ControlContainer(); controls.Add(parent); CheckThrow(typeof(InvalidOperationException)); new TreeWalkGuard().Begin(controls); } public void ControlAddedTwiceToTheSameParent_Throws() { var parent = new Control("parent"); var child = new Control("child"); parent.CanvasChildren.Add(child); parent.CanvasChildren.Add(child); var controls = new ControlContainer(); controls.Add(parent); CheckThrow(typeof(InvalidOperationException)); new TreeWalkGuard().Begin(controls); } public void ControlSharedBetweenTwoBranches_Throws() { var shared = new Control("shared"); var first = new Control("first"); var second = new Control("second"); first.CanvasChildren.Add(shared); second.CanvasChildren.Add(shared); var controls = new ControlContainer(); controls.Add(first); controls.Add(second); CheckThrow(typeof(InvalidOperationException)); new TreeWalkGuard().Begin(controls); } public void MalformedTree_DoesNotClaimTheGuard() { var guard = new TreeWalkGuard(); var malformed = new ControlContainer(); var control = new Control("control"); malformed.Add(control); malformed.Add(control); try { guard.Begin(malformed); } catch (InvalidOperationException) { } guard.Begin(new ControlContainer()).Dispose(); } public void MalformedTree_LeavesNoVisitedControlsBehind() { var guard = new TreeWalkGuard(); var control = new Control("control"); var malformed = new ControlContainer(); malformed.Add(control); malformed.Add(control); var wellFormed = new ControlContainer(); wellFormed.Add(control); try { guard.Begin(malformed); } catch (InvalidOperationException) { } guard.Begin(wellFormed).Dispose(); } public void WhileAWalkIsUnderway_Throws() { var guard = new TreeWalkGuard(); var scope = guard.Begin(new ControlContainer()); CheckThrow(typeof(InvalidOperationException)); guard.Begin(new ControlContainer()); } public void AfterTheScopeIsDisposed_Succeeds() { var guard = new TreeWalkGuard(); guard.Begin(new ControlContainer()).Dispose(); guard.Begin(new ControlContainer()).Dispose(); } public void WhileAWalkIsUnderwayOnAnotherGuard_Succeeds() { var first = new TreeWalkGuard(); var second = new TreeWalkGuard(); using (first.Begin(new ControlContainer())) { second.Begin(new ControlContainer()).Dispose(); } } public void WhileAWalkIsUnderwayOnAnotherThread_Succeeds() { var guard = new TreeWalkGuard(); Exception thrown = null; using (guard.Begin(new ControlContainer())) { var thread = new Thread(() => { try { guard.Begin(new ControlContainer()).Dispose(); } catch (Exception exception) { thrown = exception; } }); thread.Start(); thread.Join(); } CheckNull(thrown); } } } }