public void Execute_ThrowsForMissingDependency()
        {
            // Arrange
            var phase = new DefaultRazorOptimizationPhase();

            var engine = RazorEngine.CreateEmpty(b => b.Phases.Add(phase));

            var codeDocument = TestRazorCodeDocument.CreateEmpty();

            // Act & Assert
            ExceptionAssert.Throws <InvalidOperationException>(
                () => phase.Execute(codeDocument),
                $"The '{nameof(DefaultRazorOptimizationPhase)}' phase requires a '{nameof(DocumentIntermediateNode)}' " +
                $"provided by the '{nameof(RazorCodeDocument)}'.");
        }
        public void Execute_ExecutesPhasesInOrder()
        {
            // Arrange
            var codeDocument = TestRazorCodeDocument.CreateEmpty();

            // We're going to set up mocks to simulate a sequence of passes. We don't care about
            // what's in the nodes, we're just going to look at the identity via strict mocks.
            var originalNode   = new DocumentIntermediateNode();
            var firstPassNode  = new DocumentIntermediateNode();
            var secondPassNode = new DocumentIntermediateNode();

            codeDocument.SetDocumentIntermediateNode(originalNode);

            var firstPass = new Mock <IRazorOptimizationPass>(MockBehavior.Strict);

            firstPass.SetupGet(m => m.Order).Returns(0);
            firstPass.SetupProperty(m => m.Engine);
            firstPass.Setup(m => m.Execute(codeDocument, originalNode)).Callback(() =>
            {
                originalNode.Children.Add(firstPassNode);
            });

            var secondPass = new Mock <IRazorOptimizationPass>(MockBehavior.Strict);

            secondPass.SetupGet(m => m.Order).Returns(1);
            secondPass.SetupProperty(m => m.Engine);
            secondPass.Setup(m => m.Execute(codeDocument, originalNode)).Callback(() =>
            {
                // Works only when the first pass has run before this.
                originalNode.Children[0].Children.Add(secondPassNode);
            });

            var phase = new DefaultRazorOptimizationPhase();

            var engine = RazorEngine.CreateEmpty(b =>
            {
                b.Phases.Add(phase);

                b.Features.Add(firstPass.Object);
                b.Features.Add(secondPass.Object);
            });

            // Act
            phase.Execute(codeDocument);

            // Assert
            Assert.Same(secondPassNode, codeDocument.GetDocumentIntermediateNode().Children[0].Children[0]);
        }