/// <summary>
        /// Make instances of <see cref="ITestCommand"/> objects for the given class and method.
        /// </summary>
        /// <param name="classCommand">The class command</param>
        /// <param name="method">The method under test</param>
        /// <returns>The set of <see cref="ITestCommand"/> objects</returns>
        public static IEnumerable <ITestCommand> Make(ITestClassCommand classCommand,
                                                      IMethodInfo method)
        {
            foreach (var testCommand in classCommand.EnumerateTestCommands(method))
            {
                ITestCommand wrappedCommand = testCommand;

                // Timeout (if they have one) -> Capture -> Timed -> Lifetime (if we need an instance) -> BeforeAfter

                wrappedCommand = new BeforeAfterCommand(wrappedCommand, method.MethodInfo);

                if (testCommand.ShouldCreateInstance)
                {
                    wrappedCommand = new LifetimeCommand(wrappedCommand, method);
                }

                wrappedCommand = new ExceptionAndOutputCaptureCommand(wrappedCommand, method);
                wrappedCommand = new TimedCommand(wrappedCommand);

                if (wrappedCommand.Timeout > 0)
                {
                    wrappedCommand = new TimeoutCommand(wrappedCommand, wrappedCommand.Timeout, method);
                }

                yield return(wrappedCommand);
            }
        }
    public void BeforeThrowsAfterThrowsShouldResultInBeforeException()
    {
        MethodInfo methodInfo = typeof(MultipleAttributeSpy).GetMethod("PassedTest");
        StubTestCommand stub = new StubTestCommand();
        BeforeAfterCommand command = new BeforeAfterCommand(stub, methodInfo);
        BeforeAfterSpyAttribute.Reset();
        BeforeAfterSpyAttribute.beforeTestThrowCount = 2;
        BeforeAfterSpyAttribute.afterTestThrowCount = 1;

        Assert.Throws<Exception>(() => command.Execute(new MultipleAttributeSpy()));
    }
    public void MethodUnderTestProvidedToBeforeAfter()
    {
        MethodInfo methodInfo = typeof(InstrumentedTestClass).GetMethod("PassedTest");
        StubTestCommand stub = new StubTestCommand();
        BeforeAfterCommand command = new BeforeAfterCommand(stub, methodInfo);
        InstrumentedTestClass.Reset();

        command.Execute(new InstrumentedTestClass());

        Assert.Same(methodInfo, BeforeAfterSpyAttribute.beforeMethod);
        Assert.Same(methodInfo, BeforeAfterSpyAttribute.afterMethod);
    }
    public void MultipleBeforeAfterTestAttributesAllCalled()
    {
        MethodInfo methodInfo = typeof(BeforeAfterDoubleSpy).GetMethod("PassedTest");
        StubTestCommand stub = new StubTestCommand();
        BeforeAfterCommand command = new BeforeAfterCommand(stub, methodInfo);
        BeforeAfterDoubleSpy.Reset();

        command.Execute(new BeforeAfterDoubleSpy());

        Assert.Equal(2, BeforeAfterSpyAttribute.beforeTestCount);
        Assert.Equal(1, stub.ExecuteCount);
        Assert.Equal(2, BeforeAfterSpyAttribute.afterTestCount);
    }
        public void VerifyBeforeAfterTestAttributeCalledOnce()
        {
            MethodInfo method = typeof(SimpleTestFixtureSpy).GetMethod("PassedTest");
            BeforeAfterCommand command = new BeforeAfterCommand(new FactCommand(Reflector.Wrap(method)), method);
            SimpleTestFixtureSpy.Reset();

            ITestResult result = command.Execute(new SimpleTestFixtureSpy());

            Assert.Equal(1, BeforeAfterSpyAttribute.beforeTestCount);
            Assert.Equal(1, BeforeAfterSpyAttribute.afterTestCount);
            Assert.Equal("ctor beforetest test aftertest ", SimpleTestFixtureSpy.callOrder);
            Assert.IsType<PassedResult>(result);
        }
    public void BeforeTestThrows()
    {
        MethodInfo methodInfo = typeof(InstrumentedTestClass).GetMethod("PassedTest");
        StubTestCommand stub = new StubTestCommand();
        BeforeAfterCommand command = new BeforeAfterCommand(stub, methodInfo);
        InstrumentedTestClass.Reset();
        BeforeAfterSpyAttribute.beforeTestThrowCount = 1;

        Assert.Throws<Exception>(() => command.Execute(new InstrumentedTestClass()));

        Assert.Equal(1, BeforeAfterSpyAttribute.beforeTestCount);
        Assert.Equal(0, stub.ExecuteCount);
        Assert.Equal(0, BeforeAfterSpyAttribute.afterTestCount);
    }
    public void MultipleAfterTestsSecondThrows()
    {
        MethodInfo methodInfo = typeof(MultipleAttributeSpy).GetMethod("PassedTest");
        StubTestCommand stub = new StubTestCommand();
        BeforeAfterCommand command = new BeforeAfterCommand(stub, methodInfo);
        BeforeAfterSpyAttribute.Reset();
        BeforeAfterSpyAttribute.afterTestThrowCount = 2;

        AfterTestException ex = Assert.Throws<AfterTestException>(() => command.Execute(new MultipleAttributeSpy()));

        Assert.Equal(3, BeforeAfterSpyAttribute.beforeTestCount);
        Assert.Equal(1, stub.ExecuteCount);
        Assert.Equal(3, BeforeAfterSpyAttribute.afterTestCount);
        Assert.Equal(2, ex.AfterExceptions.Count);
    }
        /// <summary>
        /// Make instances of <see cref="ITestCommand"/> objects for the given class and method.
        /// </summary>
        /// <param name="classCommand">The class command</param>
        /// <param name="method">The method under test</param>
        /// <returns>The set of <see cref="ITestCommand"/> objects</returns>
        public static IEnumerable<ITestCommand> Make(ITestClassCommand classCommand,
            IMethodInfo method)
        {
            foreach (var testCommand in classCommand.EnumerateTestCommands(method))
            {
                ITestCommand wrappedCommand = testCommand;

                // Timeout (if they have one) -> Capture -> Timed -> Lifetime (if we need an instance) -> BeforeAfter

                wrappedCommand = new BeforeAfterCommand(wrappedCommand, method.MethodInfo);

                if (testCommand.ShouldCreateInstance)
                    wrappedCommand = new LifetimeCommand(wrappedCommand, method);

                wrappedCommand = new TimedCommand(wrappedCommand);
                wrappedCommand = new ExceptionAndOutputCaptureCommand(wrappedCommand, method);

                if (wrappedCommand.Timeout > 0)
                    wrappedCommand = new TimeoutCommand(wrappedCommand, wrappedCommand.Timeout, method);

                yield return wrappedCommand;
            }
        }
    public void TestThrowsAfterThrowsShouldResultInTestException()
    {
        MethodInfo methodInfo = typeof(MultipleAttributeSpy).GetMethod("PassedTest");
        StubTestCommand stub = new StubTestCommand { ThrowsOnExecute = true };
        BeforeAfterCommand command = new BeforeAfterCommand(stub, methodInfo);
        BeforeAfterSpyAttribute.Reset();
        BeforeAfterSpyAttribute.afterTestThrowCount = 1;

        Assert.Throws<Exception>(() => command.Execute(new InstrumentedTestClass()));
    }