public bool TestWaitOrAndOr(bool a, bool b, bool c, bool d)
        {
            MockQuestionA.Setup(x => x.RequestAs(It.IsAny <IActor>())).Returns(1);
            MockConditionA.Setup(x => x.Evaluate(It.IsAny <int>())).Returns(a);
            MockQuestionB.Setup(x => x.RequestAs(It.IsAny <IActor>())).Returns(false);
            MockConditionB.Setup(x => x.Evaluate(It.IsAny <bool>())).Returns(b);
            MockQuestionC.Setup(x => x.RequestAs(It.IsAny <IActor>())).Returns("title");
            MockConditionC.Setup(x => x.Evaluate(It.IsAny <string>())).Returns(c);
            MockQuestionD.Setup(x => x.RequestAs(It.IsAny <IActor>())).Returns <int?>(null);
            MockConditionD.Setup(x => x.Evaluate(It.IsAny <int?>())).Returns(d);

            bool waitWithoutException = true;

            try
            {
                Actor.AttemptsTo(
                    Wait.Until(MockQuestionA.Object, MockConditionA.Object)
                    .Or(MockQuestionB.Object, MockConditionB.Object)
                    .And(MockQuestionC.Object, MockConditionC.Object)
                    .Or(MockQuestionD.Object, MockConditionD.Object)
                    .ForUpTo(0));
            }
            catch (WaitingException)
            {
                waitWithoutException = false;
            }

            return(waitWithoutException);
        }
        public void TestSuccessfulWaitAndAndAfterChange()
        {
            const int limit       = 5;
            int       incrementer = 0;

            MockQuestionA.Setup(x => x.RequestAs(It.IsAny <IActor>())).Returns(() => ++ incrementer);
            MockConditionA.Setup(x => x.Evaluate(It.Is <int>(v => v < limit))).Returns(false);
            MockConditionA.Setup(x => x.Evaluate(It.Is <int>(v => v >= limit))).Returns(true);
            MockQuestionB.Setup(x => x.RequestAs(It.IsAny <IActor>())).Returns(false);
            MockConditionB.Setup(x => x.Evaluate(It.IsAny <bool>())).Returns(true);
            MockQuestionC.Setup(x => x.RequestAs(It.IsAny <IActor>())).Returns("title");
            MockConditionC.Setup(x => x.Evaluate(It.IsAny <string>())).Returns(true);

            Actor.Invoking(actor => actor.AttemptsTo(
                               Wait.Until(MockQuestionA.Object, MockConditionA.Object)
                               .And(MockQuestionB.Object, MockConditionB.Object)
                               .And(MockQuestionC.Object, MockConditionC.Object)
                               .ForUpTo(1)))
            .Should().NotThrow(because: "the Question should satisfy the condition");

            incrementer.Should().Be(limit, because: $"the Question should be called {limit} times");
        }
        public bool TestWaitAnd(bool a, bool b)
        {
            MockQuestionA.Setup(x => x.RequestAs(It.IsAny <IActor>())).Returns(1);
            MockConditionA.Setup(x => x.Evaluate(It.IsAny <int>())).Returns(a);
            MockQuestionB.Setup(x => x.RequestAs(It.IsAny <IActor>())).Returns(false);
            MockConditionB.Setup(x => x.Evaluate(It.IsAny <bool>())).Returns(b);

            bool waitWithoutException = true;

            try
            {
                Actor.AttemptsTo(
                    Wait.Until(MockQuestionA.Object, MockConditionA.Object)
                    .And(MockQuestionB.Object, MockConditionB.Object)
                    .ForUpTo(0));
            }
            catch (WaitingException)
            {
                waitWithoutException = false;
            }

            return(waitWithoutException);
        }