public void Execute_RewritesHtml_WithCode()
        {
            // Arrange
            var document = CreateDocument(@"
<html>
  @if (some_bool)
  {
  <head cool=""beans"">
    @hello
  </head>
  }
</html>");

            var documentNode = Lower(document);

            // Act
            Pass.Execute(document, documentNode);

            // Assert
            var method = documentNode.FindPrimaryMethod();

            Assert.Collection(
                method.Children,
                c => Assert.IsType <CSharpCodeIntermediateNode>(c),
                c => NodeAssert.Whitespace(c),
                c => NodeAssert.Element(c, "html"));

            var html = NodeAssert.Element(method.Children[2], "html");

            Assert.Equal(2, html.Source.Value.AbsoluteIndex);
            Assert.Equal(1, html.Source.Value.LineIndex);
            Assert.Equal(0, html.Source.Value.CharacterIndex);
            Assert.Equal(90, html.Source.Value.Length);
            Assert.Collection(
                html.Children,
                c => NodeAssert.Whitespace(c),
                c => Assert.IsType <CSharpCodeIntermediateNode>(c),
                c => Assert.IsType <CSharpCodeIntermediateNode>(c),
                c => NodeAssert.Whitespace(c),
                c => NodeAssert.Element(c, "head"),
                c => NodeAssert.Whitespace(c),
                c => Assert.IsType <CSharpCodeIntermediateNode>(c));

            var head = NodeAssert.Element(html.Children[4], "head");

            Assert.Equal(36, head.Source.Value.AbsoluteIndex);
            Assert.Equal(4, head.Source.Value.LineIndex);
            Assert.Equal(2, head.Source.Value.CharacterIndex);
            Assert.Equal(42, head.Source.Value.Length);
            Assert.Collection(
                head.Children,
                c => NodeAssert.Attribute(c, "cool", "beans"),
                c => NodeAssert.Whitespace(c),
                c => Assert.IsType <CSharpExpressionIntermediateNode>(c),
                c => NodeAssert.Whitespace(c));
        }
        public void Execute_RewritesHtml_Mixed()
        {
            // Arrange
            var document = CreateDocument(@"
<html>
  <head cool=""beans"" csharp=""@yes"" mixed=""hi @there"">
  </head>
</html>");

            var documentNode = Lower(document);

            // Act
            Pass.Execute(document, documentNode);

            // Assert
            var method = documentNode.FindPrimaryMethod();

            Assert.Collection(
                method.Children,
                c => Assert.IsType <CSharpCodeIntermediateNode>(c),
                c => NodeAssert.Whitespace(c),
                c => NodeAssert.Element(c, "html"));

            var html = NodeAssert.Element(method.Children[2], "html");

            Assert.Equal(2, html.Source.Value.AbsoluteIndex);
            Assert.Equal(1, html.Source.Value.LineIndex);
            Assert.Equal(0, html.Source.Value.CharacterIndex);
            Assert.Equal(81, html.Source.Value.Length);
            Assert.Collection(
                html.Children,
                c => NodeAssert.Whitespace(c),
                c => NodeAssert.Element(c, "head"),
                c => NodeAssert.Whitespace(c));

            var head = NodeAssert.Element(html.Children[1], "head");

            Assert.Equal(12, head.Source.Value.AbsoluteIndex);
            Assert.Equal(2, head.Source.Value.LineIndex);
            Assert.Equal(2, head.Source.Value.CharacterIndex);
            Assert.Equal(62, head.Source.Value.Length);
            Assert.Collection(
                head.Children,
                c => NodeAssert.Attribute(c, "cool", "beans"),
                c => NodeAssert.CSharpAttribute(c, "csharp", "yes"),
                c => Assert.IsType <HtmlAttributeIntermediateNode>(c),
                c => NodeAssert.Whitespace(c));

            var mixed = Assert.IsType <HtmlAttributeIntermediateNode>(head.Children[2]);

            Assert.Collection(
                mixed.Children,
                c => Assert.IsType <HtmlAttributeValueIntermediateNode>(c),
                c => Assert.IsType <CSharpExpressionAttributeValueIntermediateNode>(c));
        }
        public void Execute_RewritesHtml_Basic()
        {
            // Arrange
            var document = CreateDocument(@"
<html>
  <head cool=""beans"">
    Hello, World!
  </head>
</html>");

            var documentNode = Lower(document);

            // Act
            Pass.Execute(document, documentNode);

            // Assert
            var method = documentNode.FindPrimaryMethod();

            Assert.Collection(
                method.Children,
                c => Assert.IsType <CSharpCodeIntermediateNode>(c),
                c => NodeAssert.Whitespace(c),
                c => NodeAssert.Element(c, "html"));

            var html = NodeAssert.Element(method.Children[2], "html");

            Assert.Equal(2, html.Source.Value.AbsoluteIndex);
            Assert.Equal(1, html.Source.Value.LineIndex);
            Assert.Equal(0, html.Source.Value.CharacterIndex);
            Assert.Equal(68, html.Source.Value.Length);
            Assert.Collection(
                html.Children,
                c => NodeAssert.Whitespace(c),
                c => NodeAssert.Element(c, "head"),
                c => NodeAssert.Whitespace(c));

            var head = NodeAssert.Element(html.Children[1], "head");

            Assert.Equal(12, head.Source.Value.AbsoluteIndex);
            Assert.Equal(2, head.Source.Value.LineIndex);
            Assert.Equal(2, head.Source.Value.CharacterIndex);
            Assert.Equal(49, head.Source.Value.Length);
            Assert.Collection(
                head.Children,
                c => NodeAssert.Attribute(c, "cool", "beans"),
                c => NodeAssert.Content(c, "Hello, World!"));
        }
        public void Execute_RewritesHtml_TagHelper()
        {
            // Arrange
            var document = CreateDocument(@"
@addTagHelper ""*, test""
<html>
  <test>
    <head cool=""beans"">
      Hello, World!
    </head>
  </test>
</html>");

            var documentNode = Lower(document);

            // Act
            Pass.Execute(document, documentNode);

            // Assert
            var method = documentNode.FindPrimaryMethod();

            Assert.Collection(
                method.Children,
                c => Assert.IsType <CSharpCodeIntermediateNode>(c),
                c => NodeAssert.Whitespace(c),
                c => Assert.IsType <DirectiveIntermediateNode>(c),
                c => NodeAssert.Element(c, "html"));

            var html = NodeAssert.Element(method.Children[3], "html");

            Assert.Equal(27, html.Source.Value.AbsoluteIndex);
            Assert.Equal(2, html.Source.Value.LineIndex);
            Assert.Equal(0, html.Source.Value.CharacterIndex);
            Assert.Equal(95, html.Source.Value.Length);
            Assert.Collection(
                html.Children,
                c => NodeAssert.Whitespace(c),
                c => Assert.IsType <TagHelperIntermediateNode>(c),
                c => NodeAssert.Whitespace(c));

            var body = html.Children
                       .OfType <TagHelperIntermediateNode>().Single().Children
                       .OfType <TagHelperBodyIntermediateNode>().Single();

            Assert.Collection(
                body.Children,
                c => NodeAssert.Whitespace(c),
                c => NodeAssert.Element(c, "head"),
                c => NodeAssert.Whitespace(c));

            var head = body.Children[1];

            Assert.Equal(49, head.Source.Value.AbsoluteIndex);
            Assert.Equal(4, head.Source.Value.LineIndex);
            Assert.Equal(4, head.Source.Value.CharacterIndex);
            Assert.Equal(53, head.Source.Value.Length);
            Assert.Collection(
                head.Children,
                c => NodeAssert.Attribute(c, "cool", "beans"),
                c => NodeAssert.Content(c, "Hello, World!"));
        }