public void WriteTagHelperExecute_Runtime_RendersCorrectly()
    {
        // Arrange
        var extension = new DefaultTagHelperTargetExtension();
        var context   = TestCodeRenderingContext.CreateRuntime();

        var tagHelperNode = new TagHelperIntermediateNode();
        var node          = new DefaultTagHelperExecuteIntermediateNode();

        tagHelperNode.Children.Add(node);
        Push(context, tagHelperNode);

        // Act
        extension.WriteTagHelperExecute(context, node);

        // Assert
        var csharp = context.CodeWriter.GenerateCode();

        Assert.Equal(
            @"await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
if (!__tagHelperExecutionContext.Output.IsContentModified)
{
    await __tagHelperExecutionContext.SetOutputContentAsync();
}
Write(__tagHelperExecutionContext.Output);
__tagHelperExecutionContext = __tagHelperScopeManager.End();
",
            csharp,
            ignoreLineEndingDifferences: true);
    }
    public void WriteTagHelperExecute(CodeRenderingContext context, DefaultTagHelperExecuteIntermediateNode node)
    {
        if (context.Parent as TagHelperIntermediateNode == null)
        {
            var message = Resources.FormatIntermediateNodes_InvalidParentNode(node.GetType(), typeof(TagHelperIntermediateNode));
            throw new InvalidOperationException(message);
        }

        // We always render `await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);` to notify users of the requirement for a method
        // to be asynchronous.

        context.CodeWriter
        .Write("await ")
        .WriteStartInstanceMethodInvocation(
            RunnerVariableName,
            RunnerRunAsyncMethodName)
        .Write(ExecutionContextVariableName)
        .WriteEndMethodInvocation();

        if (!context.Options.DesignTime)
        {
            var tagHelperOutputAccessor = $"{ExecutionContextVariableName}.{ExecutionContextOutputPropertyName}";

            context.CodeWriter
            .Write("if (!")
            .Write(tagHelperOutputAccessor)
            .Write(".")
            .Write(TagHelperOutputIsContentModifiedPropertyName)
            .WriteLine(")");

            using (context.CodeWriter.BuildScope())
            {
                context.CodeWriter
                .Write("await ")
                .WriteInstanceMethodInvocation(
                    ExecutionContextVariableName,
                    ExecutionContextSetOutputContentAsyncMethodName);
            }

            context.CodeWriter
            .WriteStartMethodInvocation(WriteTagHelperOutputMethod)
            .Write(tagHelperOutputAccessor)
            .WriteEndMethodInvocation()
            .WriteStartAssignment(ExecutionContextVariableName)
            .WriteInstanceMethodInvocation(
                ScopeManagerVariableName,
                ScopeManagerEndMethodName);
        }
    }
    public void WriteTagHelperExecute_DesignTime_RendersAsyncCode()
    {
        // Arrange
        var extension = new DefaultTagHelperTargetExtension();
        var context   = TestCodeRenderingContext.CreateDesignTime();

        var tagHelperNode = new TagHelperIntermediateNode();
        var node          = new DefaultTagHelperExecuteIntermediateNode();

        tagHelperNode.Children.Add(node);
        Push(context, tagHelperNode);

        // Act
        extension.WriteTagHelperExecute(context, node);

        // Assert
        var csharp = context.CodeWriter.GenerateCode();

        Assert.Equal(
            @"await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
",
            csharp,
            ignoreLineEndingDifferences: true);
    }