using System.Collections.Generic;
using UnitTestSharp;
namespace Glass.UnitTests
{
public class FocusScopeTests : TestFixture
{
public static Control Focusable(string debugName = null)
{
return KeyboardManagerTests.Focusable(debugName);
}
public static Control Scope(string debugName = null)
{
return new Control(debugName) { FocusScope = new FocusScope() };
}
public class DeactivationVersionTests : TestFixture
{
public void ByDefault_IsZero()
{
CheckEqual(0, new FocusScope().DeactivationVersion);
}
}
///
/// Records every OnActiveChanged a scope raises.
///
public class ActiveChanges
{
public readonly List Raised = new List();
public ActiveChanges(FocusScope scope)
{
scope.OnActiveChanged += Raised.Add;
}
}
public class ActiveTests : TestFixture
{
public void ByDefault_IsFalse()
{
CheckFalse(new FocusScope().Active);
}
}
public class ActivateTests : TestFixture
{
public void WhenInactive_MakesItActiveAndRaisesTrue()
{
var scope = new FocusScope();
var changes = new ActiveChanges(scope);
scope.Activate();
CheckTrue(scope.Active);
CheckEqual(new[] { true }, changes.Raised);
}
public void WhenAlreadyActive_RaisesNothing()
{
var scope = new FocusScope();
scope.Activate();
var changes = new ActiveChanges(scope);
scope.Activate();
CheckEqual(0, changes.Raised.Count);
}
}
public class DeactivateTests : TestFixture
{
public void WhenActive_MakesItInactiveAndRaisesFalse()
{
var scope = new FocusScope();
scope.Activate();
var changes = new ActiveChanges(scope);
scope.Deactivate();
CheckFalse(scope.Active);
CheckEqual(new[] { false }, changes.Raised);
}
public void WhenInactive_RaisesNothing()
{
var scope = new FocusScope();
var changes = new ActiveChanges(scope);
scope.Deactivate();
CheckEqual(0, changes.Raised.Count);
}
public void Always_BumpsTheVersion()
{
var scope = new FocusScope();
scope.Deactivate();
scope.Deactivate();
CheckEqual(2, scope.DeactivationVersion);
}
}
public class ResumeTargetTests : TestFixture
{
public void ByDefault_IsNull()
{
CheckNull(new FocusScope().ResumeTarget);
}
public void AfterTheRememberedControlsFocusIsCancelled_IsNull()
{
var scope = new FocusScope();
var control = Focusable();
scope.SetResumeTarget(control);
control.CancelFocus();
CheckNull(scope.ResumeTarget);
}
}
public class SetResumeTargetTests : TestFixture
{
public void Always_MakesResumeTargetThatControl()
{
var scope = new FocusScope();
var control = Focusable();
scope.SetResumeTarget(control);
CheckEqual(control, scope.ResumeTarget);
}
public void Again_ReplacesTheEarlierControl()
{
var scope = new FocusScope();
var later = Focusable("later");
scope.SetResumeTarget(Focusable("earlier"));
scope.SetResumeTarget(later);
CheckEqual(later, scope.ResumeTarget);
}
}
public class ClearResumeTargetTests : TestFixture
{
public void Always_MakesResumeTargetNull()
{
var scope = new FocusScope();
scope.SetResumeTarget(Focusable());
scope.ClearResumeTarget();
CheckNull(scope.ResumeTarget);
}
}
public class FindScopeOfTests : TestFixture
{
public void ControlInAScope_ReturnsTheScope()
{
var contents = new ControlContainer();
var scope = contents.Add(Scope("scope"));
var control = Focusable("control");
scope.CanvasChildren.Add(control);
CheckEqual(scope, FocusScope.FindScopeOf(contents, control));
}
public void TheScopeItself_ReturnsItself()
{
var contents = new ControlContainer();
var scope = contents.Add(Scope());
CheckEqual(scope, FocusScope.FindScopeOf(contents, scope));
}
public void ControlOutsideEveryScope_ReturnsNull()
{
var contents = new ControlContainer();
contents.Add(Scope("scope"));
var outside = contents.Add(Focusable("outside"));
CheckNull(FocusScope.FindScopeOf(contents, outside));
}
public void ControlNotAmongTheContents_ReturnsNull()
{
var contents = new ControlContainer();
var scope = contents.Add(Scope("scope"));
scope.CanvasChildren.Add(Focusable("inside"));
CheckNull(FocusScope.FindScopeOf(contents, Focusable("elsewhere")));
}
public void ControlAfterAnUnscopedSiblingThatHasChildren_ReturnsItsScope()
{
var contents = new ControlContainer();
var unscoped = contents.Add(new Control("unscoped"));
unscoped.CanvasChildren.Add(Focusable("inside unscoped"));
var scope = contents.Add(Scope("scope"));
var control = Focusable("control");
scope.CanvasChildren.Add(control);
CheckEqual(scope, FocusScope.FindScopeOf(contents, control));
}
public void ControlInNestedScopes_ReturnsTheInnermost()
{
var contents = new ControlContainer();
var outer = contents.Add(Scope("outer"));
var inner = Scope("inner");
var control = Focusable("control");
outer.CanvasChildren.Add(inner);
inner.CanvasChildren.Add(control);
CheckEqual(inner, FocusScope.FindScopeOf(contents, control));
}
public void ControlInAnUnscopedChildOfAScope_ReturnsTheScope()
{
var contents = new ControlContainer();
var scope = contents.Add(Scope("scope"));
var panel = new Control("panel");
var control = Focusable("control");
scope.CanvasChildren.Add(panel);
panel.CanvasChildren.Add(control);
CheckEqual(scope, FocusScope.FindScopeOf(contents, control));
}
public void ControlInAWindowsChrome_ReturnsTheWindow()
{
var contents = new ControlContainer();
var window = contents.Add(new Window());
CheckEqual(window, FocusScope.FindScopeOf(contents, window.CloseButton));
}
public void WithAnEnclosingScope_ControlNothingNearerHolds_ReturnsTheEnclosingScope()
{
var contents = new ControlContainer();
var control = contents.Add(Focusable("control"));
var enclosing = Scope("enclosing");
CheckEqual(enclosing, FocusScope.FindScopeOf(contents, control, enclosing));
}
public void WithAnEnclosingScope_ControlNotAmongTheContents_ReturnsNull()
{
var contents = new ControlContainer();
contents.Add(Focusable("control"));
CheckNull(FocusScope.FindScopeOf(contents, Focusable("elsewhere"), Scope("enclosing")));
}
}
public class NextFocusableTests : TestFixture
{
public void NoFocusableControls_ReturnsNull()
{
var contents = new ControlContainer();
contents.Add(new Control());
CheckNull(FocusScope.NextFocusable(contents, current: null, forward: true));
}
public void NoCurrent_Forward_ReturnsTheFirstOne()
{
var contents = new ControlContainer();
var first = contents.Add(Focusable("first"));
contents.Add(Focusable("second"));
CheckEqual(first, FocusScope.NextFocusable(contents, current: null, forward: true));
}
public void NoCurrent_Backward_ReturnsTheLastOne()
{
var contents = new ControlContainer();
contents.Add(Focusable("first"));
var second = contents.Add(Focusable("second"));
CheckEqual(second, FocusScope.NextFocusable(contents, current: null, forward: false));
}
public void CurrentNotAmongThem_ReturnsTheFirstOne()
{
var contents = new ControlContainer();
var first = contents.Add(Focusable("first"));
contents.Add(Focusable("second"));
CheckEqual(first, FocusScope.NextFocusable(contents, Focusable("elsewhere"), forward: true));
}
public void MiddleCurrent_Forward_ReturnsTheNextOne()
{
var contents = new ControlContainer();
contents.Add(Focusable("first"));
var second = contents.Add(Focusable("second"));
var third = contents.Add(Focusable("third"));
CheckEqual(third, FocusScope.NextFocusable(contents, second, forward: true));
}
public void MiddleCurrent_Backward_ReturnsThePreviousOne()
{
var contents = new ControlContainer();
var first = contents.Add(Focusable("first"));
var second = contents.Add(Focusable("second"));
contents.Add(Focusable("third"));
CheckEqual(first, FocusScope.NextFocusable(contents, second, forward: false));
}
public void LastCurrent_Forward_WrapsToTheFirstOne()
{
var contents = new ControlContainer();
var first = contents.Add(Focusable("first"));
var second = contents.Add(Focusable("second"));
CheckEqual(first, FocusScope.NextFocusable(contents, second, forward: true));
}
public void FirstCurrent_Backward_WrapsToTheLastOne()
{
var contents = new ControlContainer();
var first = contents.Add(Focusable("first"));
var second = contents.Add(Focusable("second"));
CheckEqual(second, FocusScope.NextFocusable(contents, first, forward: false));
}
public void SingleFocusableControl_WrapsToItself()
{
var contents = new ControlContainer();
var only = contents.Add(Focusable());
CheckEqual(only, FocusScope.NextFocusable(contents, only, forward: true));
}
public void SkipsNonFocusableControls()
{
var contents = new ControlContainer();
var first = contents.Add(Focusable("first"));
contents.Add(new Control("second"));
var third = contents.Add(Focusable("third"));
CheckEqual(third, FocusScope.NextFocusable(contents, first, forward: true));
}
public void SkipsDisabledControls()
{
var contents = new ControlContainer();
var first = contents.Add(Focusable("first"));
contents.Add(Focusable("second")).Enabled = false;
var third = contents.Add(Focusable("third"));
CheckEqual(third, FocusScope.NextFocusable(contents, first, forward: true));
}
public void SkipsHiddenControls()
{
var contents = new ControlContainer();
var first = contents.Add(Focusable("first"));
contents.Add(Focusable("second")).Visible = false;
var third = contents.Add(Focusable("third"));
CheckEqual(third, FocusScope.NextFocusable(contents, first, forward: true));
}
public void SkipsEverythingInsideAHiddenControl()
{
var contents = new ControlContainer();
var first = contents.Add(Focusable("first"));
var hidden = contents.Add(new Control("hidden"));
hidden.CanvasChildren.Add(Focusable("inside hidden"));
hidden.Visible = false;
CheckEqual(first, FocusScope.NextFocusable(contents, first, forward: true));
}
public void VisitsAFocusableParentBeforeItsFocusableChildren()
{
var contents = new ControlContainer();
var parent = contents.Add(Focusable("parent"));
var child = Focusable("child");
parent.CanvasChildren.Add(child);
CheckEqual(parent, FocusScope.NextFocusable(contents, current: null, forward: true));
CheckEqual(child, FocusScope.NextFocusable(contents, parent, forward: true));
}
public void SkipsNestedScopesAndEverythingInThem()
{
var contents = new ControlContainer();
var first = contents.Add(Focusable("first"));
var nested = contents.Add(Scope("nested"));
nested.Focusable = true;
nested.CanvasChildren.Add(Focusable("inside nested"));
CheckEqual(first, FocusScope.NextFocusable(contents, first, forward: true));
}
}
public class NextFocusableCurrentFoundTests : TestFixture
{
[IgnoreTest]
public static ControlContainer Row(out Control a, out Control b, out Control c)
{
var contents = new ControlContainer();
a = contents.Add(Focusable("a"));
b = contents.Add(Focusable("b"));
c = contents.Add(Focusable("c"));
return contents;
}
public void ACurrentInTheOrder_IsFound()
{
ControlContainer contents = Row(out _, out Control b, out _);
FocusScope.NextFocusable(contents, b, forward: true, out bool found);
CheckTrue(found);
}
public void AnAbsentCurrent_IsNotFound()
{
ControlContainer contents = Row(out _, out _, out _);
FocusScope.NextFocusable(contents, Focusable("elsewhere"), forward: true, out bool found);
CheckFalse(found);
}
public void ANullCurrent_IsNotFound()
{
ControlContainer contents = Row(out _, out _, out _);
FocusScope.NextFocusable(contents, current: null, forward: true, out bool found);
CheckFalse(found);
}
public void ADisabledCurrent_IsFoundAndSteppedPast()
{
ControlContainer contents = Row(out Control a, out Control b, out Control c);
b.Enabled = false;
Control next = FocusScope.NextFocusable(contents, b, forward: true, out bool found);
CheckTrue(found);
CheckEqual(c, next);
}
public void AHiddenCurrent_IsFoundAndSteppedPast()
{
ControlContainer contents = Row(out Control a, out Control b, out Control c);
b.Visible = false;
Control next = FocusScope.NextFocusable(contents, b, forward: true, out bool found);
CheckTrue(found);
CheckEqual(c, next);
}
public void AHiddenCurrent_GoingBackward_StepsToTheOneBefore()
{
ControlContainer contents = Row(out Control a, out Control b, out Control c);
b.Visible = false;
CheckEqual(a, FocusScope.NextFocusable(contents, b, forward: false, out _));
}
public void AHiddenLastCurrent_WrapsToTheFirst()
{
ControlContainer contents = Row(out Control a, out Control b, out Control c);
c.Visible = false;
CheckEqual(a, FocusScope.NextFocusable(contents, c, forward: true, out _));
}
public void ACurrentInsideAHiddenPanel_IsFoundAndSteppedPast()
{
var contents = new ControlContainer();
var panel = contents.Add(new Control());
Control inside = panel.CanvasChildren.Add(Focusable("inside"));
panel.CanvasChildren.Add(Focusable("also inside"));
Control after = contents.Add(Focusable("after"));
panel.Visible = false;
Control next = FocusScope.NextFocusable(contents, inside, forward: true, out bool found);
CheckTrue(found);
CheckEqual(after, next);
}
public void ControlsInsideAHiddenPanel_AreNeverTheAnswer()
{
var contents = new ControlContainer();
var panel = contents.Add(new Control());
panel.CanvasChildren.Add(Focusable("inside"));
Control only = contents.Add(Focusable("only"));
panel.Visible = false;
CheckEqual(only, FocusScope.NextFocusable(contents, only, forward: true, out _));
}
public void ACurrentInsideANestedScope_IsNotFound()
{
var contents = new ControlContainer();
Control nested = contents.Add(Scope("nested"));
Control inside = nested.CanvasChildren.Add(Focusable("inside"));
contents.Add(Focusable("other"));
FocusScope.NextFocusable(contents, inside, forward: true, out bool found);
CheckFalse(found);
}
}
}
}