{"action":"created","comment":{"url":"https://api.github.com/repos/aspnet/Razor/pulls/comments/30434503","id":30434503,"diff_hunk":"@@ -0,0 +1,909 @@\n+﻿// Copyright (c) .NET Foundation. All rights reserved.\n+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.\n+\n+using System;\n+using System.Collections.Generic;\n+using System.Linq;\n+using Microsoft.AspNet.Razor.Parser;\n+using Microsoft.AspNet.Razor.Parser.SyntaxTree;\n+using Microsoft.AspNet.Razor.Test.Framework;\n+using Microsoft.AspNet.Razor.Test.TagHelpers;\n+using Xunit;\n+\n+namespace Microsoft.AspNet.Razor.TagHelpers\n+{\n+    public class TagHelperBlockRewriterTest : TagHelperRewritingTestBase\n+    {\n+        public static TheoryData MinimizedAttributeData_Document\n+        {\n+            get\n+            {\n+                var factory = CreateDefaultSpanFactory();\n+                var noErrors = new RazorError[0];\n+                var errorFormat = \"Attribute '{0}' on tag helper element '{1}' requires a value. Tag helper bound \" +\n+                    \"attributes of type '{2}' cannot be empty or contain only whitespace.\";\n+                var stringType = typeof(string).FullName;\n+                var intType = typeof(int).FullName;\n+                var expressionString = \"@DateTime.Now + 1\";\n+                var expression = new MarkupBlock(\n+                    new MarkupBlock(\n+                        new ExpressionBlock(\n+                            factory.CodeTransition(),\n+                                factory.Code(\"DateTime.Now\")\n+                                    .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)\n+                                    .Accepts(AcceptedCharacters.NonWhiteSpace))),\n+                    factory.Markup(\" +\"),\n+                    factory.Markup(\" 1\"));\n+\n+                // documentContent, expectedOutput, expectedErrors\n+                return new TheoryData<string, MarkupBlock, RazorError[]>\n+                {\n+                    {\n+                        \"<input unbound-required />\",\n+                        new MarkupBlock(\n+                            new MarkupTagHelperBlock(\n+                                \"input\",\n+                                selfClosing: true,\n+                                attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()\n+                                {\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"unbound-required\", null),\n+                                })),\n+                        noErrors\n+                    },\n+                    {\n+                        \"<p bound-string></p>\",\n+                        new MarkupBlock(\n+                            new MarkupTagHelperBlock(\n+                                \"p\",\n+                                selfClosing: false,\n+                                attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()\n+                                {\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"bound-string\", null),\n+                                })),\n+                        new[]\n+                        {\n+                            new RazorError(\n+                                string.Format(errorFormat, \"bound-string\", \"p\", stringType), 3, 0, 3, 12)\n+                        }\n+                    },\n+                    {\n+                        \"<input bound-required-string />\",\n+                        new MarkupBlock(\n+                            new MarkupTagHelperBlock(\n+                                \"input\",\n+                                selfClosing: true,\n+                                attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()\n+                                {\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"bound-required-string\", null),\n+                                })),\n+                        new[]\n+                        {\n+                            new RazorError(\n+                                string.Format(errorFormat, \"bound-required-string\", \"input\", stringType), 7, 0, 7, 21)\n+                        }\n+                    },\n+                    {\n+                        \"<input bound-required-int />\",\n+                        new MarkupBlock(\n+                            new MarkupTagHelperBlock(\n+                                \"input\",\n+                                selfClosing: true,\n+                                attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()\n+                                {\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"bound-required-int\", null),\n+                                })),\n+                        new[]\n+                        {\n+                            new RazorError(\n+                                string.Format(errorFormat, \"bound-required-int\", \"input\", intType), 7, 0, 7, 18)\n+                        }\n+                    },\n+                    {\n+                        \"<p bound-int></p>\",\n+                        new MarkupBlock(\n+                            new MarkupTagHelperBlock(\n+                                \"p\",\n+                                selfClosing: false,\n+                                attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()\n+                                {\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"bound-int\", null),\n+                                })),\n+                        new[] { new RazorError(string.Format(errorFormat, \"bound-int\", \"p\", intType), 3, 0, 3, 9) }\n+                    },\n+                    {\n+                        \"<input unbound-required bound-required-string />\",\n+                        new MarkupBlock(\n+                            new MarkupTagHelperBlock(\n+                                \"input\",\n+                                selfClosing: true,\n+                                attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()\n+                                {\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"unbound-required\", null),\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"bound-required-string\", null),\n+                                })),\n+                        new[]\n+                        {\n+                            new RazorError(\n+                                string.Format(errorFormat, \"bound-required-string\", \"input\", stringType),\n+                                absoluteIndex: 24,\n+                                lineIndex: 0,\n+                                columnIndex: 24,\n+                                length: 21)\n+                        }\n+                    },\n+                    {\n+                        \"<p bound-int bound-string></p>\",\n+                        new MarkupBlock(\n+                            new MarkupTagHelperBlock(\n+                                \"p\",\n+                                selfClosing: false,\n+                                attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()\n+                                {\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"bound-int\", null),\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"bound-string\", null),\n+                                })),\n+                        new[]\n+                        {\n+                            new RazorError(string.Format(errorFormat, \"bound-int\", \"p\", intType), 3, 0, 3, 9),\n+                            new RazorError(string.Format(errorFormat, \"bound-string\", \"p\", stringType), 13, 0, 13, 12),\n+                        }\n+                    },\n+                    {\n+                        \"<input bound-required-int unbound-required bound-required-string />\",\n+                        new MarkupBlock(\n+                            new MarkupTagHelperBlock(\n+                                \"input\",\n+                                selfClosing: true,\n+                                attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()\n+                                {\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"bound-required-int\", null),\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"unbound-required\", null),\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"bound-required-string\", null),\n+                                })),\n+                        new[]\n+                        {\n+                            new RazorError(\n+                                string.Format(errorFormat, \"bound-required-int\", \"input\", intType), 7, 0, 7, 18),\n+                            new RazorError(\n+                                string.Format(errorFormat, \"bound-required-string\", \"input\", stringType),\n+                                absoluteIndex: 43,\n+                                lineIndex: 0,\n+                                columnIndex: 43,\n+                                length: 21)\n+                        }\n+                    },\n+                    {\n+                        \"<p bound-int bound-string bound-string></p>\",\n+                        new MarkupBlock(\n+                            new MarkupTagHelperBlock(\n+                                \"p\",\n+                                selfClosing: false,\n+                                attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()\n+                                {\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"bound-int\", null),\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"bound-string\", null),\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"bound-string\", null),\n+                                })),\n+                        new[]\n+                        {\n+                            new RazorError(string.Format(errorFormat, \"bound-int\", \"p\", intType), 3, 0, 3, 9),\n+                            new RazorError(string.Format(errorFormat, \"bound-string\", \"p\", stringType), 13, 0, 13, 12),\n+                            new RazorError(string.Format(errorFormat, \"bound-string\", \"p\", stringType), 26, 0, 26, 12),\n+                        }\n+                    },\n+                    {\n+                        \"<input unbound-required class='btn' />\",\n+                        new MarkupBlock(\n+                            new MarkupTagHelperBlock(\n+                                \"input\",\n+                                selfClosing: true,\n+                                attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()\n+                                {\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"unbound-required\", null),\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"class\", factory.Markup(\"btn\")),\n+                                })),\n+                        noErrors\n+                    },\n+                    {\n+                        \"<p bound-string class='btn'></p>\",\n+                        new MarkupBlock(\n+                            new MarkupTagHelperBlock(\n+                                \"p\",\n+                                selfClosing: false,\n+                                attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()\n+                                {\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"bound-string\", null),\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"class\", factory.Markup(\"btn\")),\n+                                })),\n+                        new[]\n+                        {\n+                            new RazorError(\n+                                string.Format(errorFormat, \"bound-string\", \"p\", stringType),\n+                                absoluteIndex: 3,\n+                                lineIndex: 0,\n+                                columnIndex: 3,\n+                                length: 12)\n+                        }\n+                    },\n+                    {\n+                        $\"<input unbound-required class='{expressionString}' />\",\n+                        new MarkupBlock(\n+                            new MarkupTagHelperBlock(\n+                                \"input\",\n+                                selfClosing: true,\n+                                attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()\n+                                {\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"unbound-required\", null),\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"class\", expression),\n+                                })),\n+                        noErrors\n+                    },\n+                    {\n+                        $\"<p bound-string class='{expressionString}'></p>\",\n+                        new MarkupBlock(\n+                            new MarkupTagHelperBlock(\n+                                \"p\",\n+                                selfClosing: false,\n+                                attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()\n+                                {\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"bound-string\", null),\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"class\", expression),\n+                                })),\n+                        new[]\n+                        {\n+                            new RazorError(\n+                                string.Format(errorFormat, \"bound-string\", \"p\", stringType),\n+                                absoluteIndex: 3,\n+                                lineIndex: 0,\n+                                columnIndex: 3,\n+                                length: 12)\n+                        }\n+                    },\n+                    {\n+                        \"<input class='btn' unbound-required />\",\n+                        new MarkupBlock(\n+                            new MarkupTagHelperBlock(\n+                                \"input\",\n+                                selfClosing: true,\n+                                attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()\n+                                {\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"class\", factory.Markup(\"btn\")),\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"unbound-required\", null),\n+                                })),\n+                        noErrors\n+                    },\n+                    {\n+                        \"<p class='btn' bound-string></p>\",\n+                        new MarkupBlock(\n+                            new MarkupTagHelperBlock(\n+                                \"p\",\n+                                selfClosing: false,\n+                                attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()\n+                                {\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"class\", factory.Markup(\"btn\")),\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"bound-string\", null),\n+                                })),\n+                        new[]\n+                        {\n+                            new RazorError(\n+                                string.Format(errorFormat, \"bound-string\", \"p\", stringType),\n+                                absoluteIndex: 15,\n+                                lineIndex: 0,\n+                                columnIndex: 15,\n+                                length: 12)\n+                        }\n+                    },\n+                    {\n+                        $\"<input class='{expressionString}' unbound-required />\",\n+                        new MarkupBlock(\n+                            new MarkupTagHelperBlock(\n+                                \"input\",\n+                                selfClosing: true,\n+                                attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()\n+                                {\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"class\", expression),\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"unbound-required\", null),\n+                                })),\n+                        noErrors\n+                    },\n+                    {\n+                        $\"<p class='{expressionString}' bound-string></p>\",\n+                        new MarkupBlock(\n+                            new MarkupTagHelperBlock(\n+                                \"p\",\n+                                selfClosing: false,\n+                                attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()\n+                                {\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"class\", expression),\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"bound-string\", null),\n+                                })),\n+                        new[]\n+                        {\n+                            new RazorError(\n+                                string.Format(errorFormat, \"bound-string\", \"p\", stringType),\n+                                absoluteIndex: 29,\n+                                lineIndex: 0,\n+                                columnIndex: 29,\n+                                length: 12)\n+                        }\n+                    },\n+                    {\n+                        \"<input bound-required-string class='btn' />\",\n+                        new MarkupBlock(\n+                            new MarkupTagHelperBlock(\n+                                \"input\",\n+                                selfClosing: true,\n+                                attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()\n+                                {\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"bound-required-string\", null),\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"class\", factory.Markup(\"btn\")),\n+                                })),\n+                        new[]\n+                        {\n+                            new RazorError(\n+                                string.Format(errorFormat, \"bound-required-string\", \"input\", stringType),\n+                                absoluteIndex: 7,\n+                                lineIndex: 0,\n+                                columnIndex: 7,\n+                                length: 21)\n+                        }\n+                    },\n+                    {\n+                        $\"<input bound-required-string class='{expressionString}' />\",\n+                        new MarkupBlock(\n+                            new MarkupTagHelperBlock(\n+                                \"input\",\n+                                selfClosing: true,\n+                                attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()\n+                                {\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"bound-required-string\", null),\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"class\", expression),\n+                                })),\n+                        new[]\n+                        {\n+                            new RazorError(\n+                                string.Format(errorFormat, \"bound-required-string\", \"input\", stringType),\n+                                absoluteIndex: 7,\n+                                lineIndex: 0,\n+                                columnIndex: 7,\n+                                length: 21)\n+                        }\n+                    },\n+                    {\n+                        \"<input class='btn' bound-required-string />\",\n+                        new MarkupBlock(\n+                            new MarkupTagHelperBlock(\n+                                \"input\",\n+                                selfClosing: true,\n+                                attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()\n+                                {\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"class\", factory.Markup(\"btn\")),\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"bound-required-string\", null),\n+                                })),\n+                        new[]\n+                        {\n+                            new RazorError(\n+                                string.Format(errorFormat, \"bound-required-string\", \"input\", stringType),\n+                                absoluteIndex: 19,\n+                                lineIndex: 0,\n+                                columnIndex: 19,\n+                                length: 21)\n+                        }\n+                    },\n+                    {\n+                        $\"<input class='{expressionString}' bound-required-string />\",\n+                        new MarkupBlock(\n+                            new MarkupTagHelperBlock(\n+                                \"input\",\n+                                selfClosing: true,\n+                                attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()\n+                                {\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"class\", expression),\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"bound-required-string\", null),\n+                                })),\n+                        new[]\n+                        {\n+                            new RazorError(\n+                                string.Format(errorFormat, \"bound-required-string\", \"input\", stringType),\n+                                absoluteIndex: 33,\n+                                lineIndex: 0,\n+                                columnIndex: 33,\n+                                length: 21)\n+                        }\n+                    },\n+                    {\n+                        \"<input bound-required-int class='btn' />\",\n+                        new MarkupBlock(\n+                            new MarkupTagHelperBlock(\n+                                \"input\",\n+                                selfClosing: true,\n+                                attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()\n+                                {\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"bound-required-int\", null),\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"class\", factory.Markup(\"btn\")),\n+                                })),\n+                        new[]\n+                        {\n+                            new RazorError(\n+                                string.Format(errorFormat, \"bound-required-int\", \"input\", intType), 7, 0, 7, 18)\n+                        }\n+                    },\n+                    {\n+                        \"<p bound-int class='btn'></p>\",\n+                        new MarkupBlock(\n+                            new MarkupTagHelperBlock(\n+                                \"p\",\n+                                selfClosing: false,\n+                                attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()\n+                                {\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"bound-int\", null),\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"class\", factory.Markup(\"btn\")),\n+                                })),\n+                        new[]\n+                        {\n+                            new RazorError(string.Format(errorFormat, \"bound-int\", \"p\", intType), 3, 0, 3, 9)\n+                        }\n+                    },\n+                    {\n+                        $\"<input bound-required-int class='{expressionString}' />\",\n+                        new MarkupBlock(\n+                            new MarkupTagHelperBlock(\n+                                \"input\",\n+                                selfClosing: true,\n+                                attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()\n+                                {\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"bound-required-int\", null),\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"class\", expression),\n+                                })),\n+                        new[]\n+                        {\n+                            new RazorError(\n+                                string.Format(errorFormat, \"bound-required-int\", \"input\", intType), 7, 0, 7, 18)\n+                        }\n+                    },\n+                    {\n+                        $\"<p bound-int class='{expressionString}'></p>\",\n+                        new MarkupBlock(\n+                            new MarkupTagHelperBlock(\n+                                \"p\",\n+                                selfClosing: false,\n+                                attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()\n+                                {\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"bound-int\", null),\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"class\", expression),\n+                                })),\n+                        new[]\n+                        {\n+                            new RazorError(string.Format(errorFormat, \"bound-int\", \"p\", intType), 3, 0, 3, 9)\n+                        }\n+                    },\n+                    {\n+                        \"<input class='btn' bound-required-int />\",\n+                        new MarkupBlock(\n+                            new MarkupTagHelperBlock(\n+                                \"input\",\n+                                selfClosing: true,\n+                                attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()\n+                                {\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"class\", factory.Markup(\"btn\")),\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"bound-required-int\", null),\n+                                })),\n+                        new[]\n+                        {\n+                            new RazorError(string.Format(errorFormat, \"bound-required-int\", \"input\", intType), 19, 0, 19, 18)\n+                        }\n+                    },\n+                    {\n+                        \"<p class='btn' bound-int></p>\",\n+                        new MarkupBlock(\n+                            new MarkupTagHelperBlock(\n+                                \"p\",\n+                                selfClosing: false,\n+                                attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()\n+                                {\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"class\", factory.Markup(\"btn\")),\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"bound-int\", null),\n+                                })),\n+                        new[]\n+                        {\n+                            new RazorError(string.Format(errorFormat, \"bound-int\", \"p\", intType), 15, 0, 15, 9)\n+                        }\n+                    },\n+                    {\n+                        $\"<input class='{expressionString}' bound-required-int />\",\n+                        new MarkupBlock(\n+                            new MarkupTagHelperBlock(\n+                                \"input\",\n+                                selfClosing: true,\n+                                attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()\n+                                {\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"class\", expression),\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"bound-required-int\", null),\n+                                })),\n+                        new[]\n+                        {\n+                            new RazorError(\n+                                string.Format(errorFormat, \"bound-required-int\", \"input\", intType), 33, 0, 33, 18)\n+                        }\n+                    },\n+                    {\n+                        $\"<p class='{expressionString}' bound-int></p>\",\n+                        new MarkupBlock(\n+                            new MarkupTagHelperBlock(\n+                                \"p\",\n+                                selfClosing: false,\n+                                attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()\n+                                {\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"class\", expression),\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"bound-int\", null),\n+                                })),\n+                        new[]\n+                        {\n+                            new RazorError(string.Format(errorFormat, \"bound-int\", \"p\", intType), 29, 0, 29, 9)\n+                        }\n+                    },\n+                    {\n+                        $\"<input    bound-required-int class='{expressionString}'   bound-required-string \" +\n+                        $\"class='{expressionString}'  unbound-required  />\",\n+                        new MarkupBlock(\n+                            new MarkupTagHelperBlock(\n+                                \"input\",\n+                                selfClosing: true,\n+                                attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()\n+                                {\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"bound-required-int\", null),\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"class\", expression),\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"bound-required-string\", null),\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"class\", expression),\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"unbound-required\", null),\n+                                })),\n+                        new[]\n+                        {\n+                            new RazorError(\n+                                string.Format(errorFormat, \"bound-required-int\", \"input\", intType), 10, 0, 10, 18),\n+                            new RazorError(\n+                                string.Format(errorFormat, \"bound-required-string\", \"input\", stringType),\n+                                absoluteIndex: 57,\n+                                lineIndex: 0,\n+                                columnIndex: 57,\n+                                length: 21),\n+                        }\n+                    },\n+                    {\n+                        $\"<p    bound-int class='{expressionString}'   bound-string \" +\n+                        $\"class='{expressionString}'  bound-string></p>\",\n+                        new MarkupBlock(\n+                            new MarkupTagHelperBlock(\n+                                \"p\",\n+                                selfClosing: false,\n+                                attributes: new List<KeyValuePair<string, SyntaxTreeNode>>()\n+                                {\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"bound-int\", null),\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"class\", expression),\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"bound-string\", null),\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"class\", expression),\n+                                    new KeyValuePair<string, SyntaxTreeNode>(\"bound-string\", null),\n+                                })),\n+                        new[]\n+                        {\n+                            new RazorError(string.Format(errorFormat, \"bound-int\", \"p\", intType), 6, 0, 6, 9),\n+                            new RazorError(string.Format(errorFormat, \"bound-string\", \"p\", stringType), 44, 0, 44, 12),\n+                            new RazorError(string.Format(errorFormat, \"bound-string\", \"p\", stringType), 84, 0, 84, 12),\n+                        }\n+                    },\n+                };\n+            }\n+        }\n+\n+        public static TheoryData MinimizedAttributeData_CSharpBlock\n+        {\n+            get\n+            {\n+                var factory = CreateDefaultSpanFactory();\n+                var documentData = MinimizedAttributeData_Document;\n+                Func<Func<MarkupBlock>, MarkupBlock> buildStatementBlock = (insideBuilder) =>\n+                {\n+                    return new MarkupBlock(\n+                        factory.EmptyHtml(),\n+                        new StatementBlock(\n+                            factory.CodeTransition(),\n+                            factory.MetaCode(\"{\").Accepts(AcceptedCharacters.None),\n+                            insideBuilder(),\n+                            factory.EmptyCSharp().AsStatement(),\n+                            factory.MetaCode(\"}\").Accepts(AcceptedCharacters.None)),\n+                        factory.EmptyHtml());\n+                };\n+\n+                foreach (var data in documentData)\n+                {\n+                    data[0] = $\"@{{{data[0]}}}\";\n+                    data[1] = buildStatementBlock(() => data[1] as MarkupBlock);\n+\n+                    var errors = data[2] as RazorError[];\n+\n+                    for (var i = 0; i < errors.Length; i++)\n+                    {\n+                        var error = errors[i];\n+                        error.Location = SourceLocation.Advance(error.Location, \"@{\");\n+                    }\n+                }\n+\n+                return documentData;","path":"test/Microsoft.AspNet.Razor.Test/TagHelpers/TagHelperBlockRewriterTest.cs","position":631,"original_position":631,"commit_id":"2097006620d8f37f0de7e1c5de3f28aeb0de4167","original_commit_id":"2097006620d8f37f0de7e1c5de3f28aeb0de4167","user":{"login":"dougbu","id":6431421,"avatar_url":"https://avatars.githubusercontent.com/u/6431421?v=3","gravatar_id":"","url":"https://api.github.com/users/dougbu","html_url":"https://github.com/dougbu","followers_url":"https://api.github.com/users/dougbu/followers","following_url":"https://api.github.com/users/dougbu/following{/other_user}","gists_url":"https://api.github.com/users/dougbu/gists{/gist_id}","starred_url":"https://api.github.com/users/dougbu/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dougbu/subscriptions","organizations_url":"https://api.github.com/users/dougbu/orgs","repos_url":"https://api.github.com/users/dougbu/repos","events_url":"https://api.github.com/users/dougbu/events{/privacy}","received_events_url":"https://api.github.com/users/dougbu/received_events","type":"User","site_admin":false},"body":"Cheating to hide the large amount of repetition but :ok:","created_at":"2015-05-15T18:42:34Z","updated_at":"2015-05-15T18:42:34Z","html_url":"https://github.com/aspnet/Razor/pull/372#discussion_r30434503","pull_request_url":"https://api.github.com/repos/aspnet/Razor/pulls/372","_links":{"self":{"href":"https://api.github.com/repos/aspnet/Razor/pulls/comments/30434503"},"html":{"href":"https://github.com/aspnet/Razor/pull/372#discussion_r30434503"},"pull_request":{"href":"https://api.github.com/repos/aspnet/Razor/pulls/372"}}},"pull_request":{"url":"https://api.github.com/repos/aspnet/Razor/pulls/372","id":34576441,"html_url":"https://github.com/aspnet/Razor/pull/372","diff_url":"https://github.com/aspnet/Razor/pull/372.diff","patch_url":"https://github.com/aspnet/Razor/pull/372.patch","issue_url":"https://api.github.com/repos/aspnet/Razor/issues/372","number":372,"state":"open","locked":false,"title":"Add support for minimized attributes in TagHelpers.","user":{"login":"NTaylorMullen","id":2008729,"avatar_url":"https://avatars.githubusercontent.com/u/2008729?v=3","gravatar_id":"","url":"https://api.github.com/users/NTaylorMullen","html_url":"https://github.com/NTaylorMullen","followers_url":"https://api.github.com/users/NTaylorMullen/followers","following_url":"https://api.github.com/users/NTaylorMullen/following{/other_user}","gists_url":"https://api.github.com/users/NTaylorMullen/gists{/gist_id}","starred_url":"https://api.github.com/users/NTaylorMullen/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/NTaylorMullen/subscriptions","organizations_url":"https://api.github.com/users/NTaylorMullen/orgs","repos_url":"https://api.github.com/users/NTaylorMullen/repos","events_url":"https://api.github.com/users/NTaylorMullen/events{/privacy}","received_events_url":"https://api.github.com/users/NTaylorMullen/received_events","type":"User","site_admin":false},"body":"- Updated the Razor parser to understand minimized attributes instead of just treating them like plain text. This just involved encompassing minimized attributes in their own blocks just like the other attributes found on the HTML tag.\r\n- Updated TagHelperParseTreeRewriter to only accept minimized attributes for unbound attributes.\r\n- Updated IReadOnlyTagHelperAttribute/TagHelperAttribute to have a Minimized property to indicate that an attribute was minimized.\r\n- Updated parser level block structures to represent minimized attributes as null syntax tree nodes.\r\n- Updated chunk level structures to represent minimized attributes as null chunks.\r\n- Added parse level rewriting tests to validate new TagHelper rewritten structures for minimized attributes.\r\n- Updated existing parser tests to understand minimized attributes.\r\n- Added codegen test to validate understanding of minimized attributes.\r\n- Added TagHelperExecutionContext tests to validate maintaining of runtime TagHelperOutput tests.\r\n- Refactored part of the TagHelperParseTreeRewriterTest file into a base class file so we can make better rewriting tests.\r\n\r\n#220","created_at":"2015-05-01T23:56:45Z","updated_at":"2015-05-15T18:42:34Z","closed_at":null,"merged_at":null,"merge_commit_sha":"cda7c39ee3168b1f52f9dea6c126493d64d6154e","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/aspnet/Razor/pulls/372/commits","review_comments_url":"https://api.github.com/repos/aspnet/Razor/pulls/372/comments","review_comment_url":"https://api.github.com/repos/aspnet/Razor/pulls/comments{/number}","comments_url":"https://api.github.com/repos/aspnet/Razor/issues/372/comments","statuses_url":"https://api.github.com/repos/aspnet/Razor/statuses/2097006620d8f37f0de7e1c5de3f28aeb0de4167","head":{"label":"aspnet:nimullen/novalueattrs.220","ref":"nimullen/novalueattrs.220","sha":"2097006620d8f37f0de7e1c5de3f28aeb0de4167","user":{"login":"aspnet","id":6476660,"avatar_url":"https://avatars.githubusercontent.com/u/6476660?v=3","gravatar_id":"","url":"https://api.github.com/users/aspnet","html_url":"https://github.com/aspnet","followers_url":"https://api.github.com/users/aspnet/followers","following_url":"https://api.github.com/users/aspnet/following{/other_user}","gists_url":"https://api.github.com/users/aspnet/gists{/gist_id}","starred_url":"https://api.github.com/users/aspnet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aspnet/subscriptions","organizations_url":"https://api.github.com/users/aspnet/orgs","repos_url":"https://api.github.com/users/aspnet/repos","events_url":"https://api.github.com/users/aspnet/events{/privacy}","received_events_url":"https://api.github.com/users/aspnet/received_events","type":"Organization","site_admin":false},"repo":{"id":15835991,"name":"Razor","full_name":"aspnet/Razor","owner":{"login":"aspnet","id":6476660,"avatar_url":"https://avatars.githubusercontent.com/u/6476660?v=3","gravatar_id":"","url":"https://api.github.com/users/aspnet","html_url":"https://github.com/aspnet","followers_url":"https://api.github.com/users/aspnet/followers","following_url":"https://api.github.com/users/aspnet/following{/other_user}","gists_url":"https://api.github.com/users/aspnet/gists{/gist_id}","starred_url":"https://api.github.com/users/aspnet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aspnet/subscriptions","organizations_url":"https://api.github.com/users/aspnet/orgs","repos_url":"https://api.github.com/users/aspnet/repos","events_url":"https://api.github.com/users/aspnet/events{/privacy}","received_events_url":"https://api.github.com/users/aspnet/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/aspnet/Razor","description":"Parser and code generator for CSHTML files used in view pages for MVC web apps.","fork":false,"url":"https://api.github.com/repos/aspnet/Razor","forks_url":"https://api.github.com/repos/aspnet/Razor/forks","keys_url":"https://api.github.com/repos/aspnet/Razor/keys{/key_id}","collaborators_url":"https://api.github.com/repos/aspnet/Razor/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/aspnet/Razor/teams","hooks_url":"https://api.github.com/repos/aspnet/Razor/hooks","issue_events_url":"https://api.github.com/repos/aspnet/Razor/issues/events{/number}","events_url":"https://api.github.com/repos/aspnet/Razor/events","assignees_url":"https://api.github.com/repos/aspnet/Razor/assignees{/user}","branches_url":"https://api.github.com/repos/aspnet/Razor/branches{/branch}","tags_url":"https://api.github.com/repos/aspnet/Razor/tags","blobs_url":"https://api.github.com/repos/aspnet/Razor/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/aspnet/Razor/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/aspnet/Razor/git/refs{/sha}","trees_url":"https://api.github.com/repos/aspnet/Razor/git/trees{/sha}","statuses_url":"https://api.github.com/repos/aspnet/Razor/statuses/{sha}","languages_url":"https://api.github.com/repos/aspnet/Razor/languages","stargazers_url":"https://api.github.com/repos/aspnet/Razor/stargazers","contributors_url":"https://api.github.com/repos/aspnet/Razor/contributors","subscribers_url":"https://api.github.com/repos/aspnet/Razor/subscribers","subscription_url":"https://api.github.com/repos/aspnet/Razor/subscription","commits_url":"https://api.github.com/repos/aspnet/Razor/commits{/sha}","git_commits_url":"https://api.github.com/repos/aspnet/Razor/git/commits{/sha}","comments_url":"https://api.github.com/repos/aspnet/Razor/comments{/number}","issue_comment_url":"https://api.github.com/repos/aspnet/Razor/issues/comments{/number}","contents_url":"https://api.github.com/repos/aspnet/Razor/contents/{+path}","compare_url":"https://api.github.com/repos/aspnet/Razor/compare/{base}...{head}","merges_url":"https://api.github.com/repos/aspnet/Razor/merges","archive_url":"https://api.github.com/repos/aspnet/Razor/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/aspnet/Razor/downloads","issues_url":"https://api.github.com/repos/aspnet/Razor/issues{/number}","pulls_url":"https://api.github.com/repos/aspnet/Razor/pulls{/number}","milestones_url":"https://api.github.com/repos/aspnet/Razor/milestones{/number}","notifications_url":"https://api.github.com/repos/aspnet/Razor/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/aspnet/Razor/labels{/name}","releases_url":"https://api.github.com/repos/aspnet/Razor/releases{/id}","created_at":"2014-01-12T03:52:46Z","updated_at":"2015-05-14T06:41:48Z","pushed_at":"2015-05-15T18:09:25Z","git_url":"git://github.com/aspnet/Razor.git","ssh_url":"git@github.com:aspnet/Razor.git","clone_url":"https://github.com/aspnet/Razor.git","svn_url":"https://github.com/aspnet/Razor","homepage":"","size":9752,"stargazers_count":341,"watchers_count":341,"language":"C#","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":88,"mirror_url":null,"open_issues_count":77,"forks":88,"open_issues":77,"watchers":341,"default_branch":"dev"}},"base":{"label":"aspnet:dev","ref":"dev","sha":"2c9856d4daba03d2c893cd89ba996aec19a93b4b","user":{"login":"aspnet","id":6476660,"avatar_url":"https://avatars.githubusercontent.com/u/6476660?v=3","gravatar_id":"","url":"https://api.github.com/users/aspnet","html_url":"https://github.com/aspnet","followers_url":"https://api.github.com/users/aspnet/followers","following_url":"https://api.github.com/users/aspnet/following{/other_user}","gists_url":"https://api.github.com/users/aspnet/gists{/gist_id}","starred_url":"https://api.github.com/users/aspnet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aspnet/subscriptions","organizations_url":"https://api.github.com/users/aspnet/orgs","repos_url":"https://api.github.com/users/aspnet/repos","events_url":"https://api.github.com/users/aspnet/events{/privacy}","received_events_url":"https://api.github.com/users/aspnet/received_events","type":"Organization","site_admin":false},"repo":{"id":15835991,"name":"Razor","full_name":"aspnet/Razor","owner":{"login":"aspnet","id":6476660,"avatar_url":"https://avatars.githubusercontent.com/u/6476660?v=3","gravatar_id":"","url":"https://api.github.com/users/aspnet","html_url":"https://github.com/aspnet","followers_url":"https://api.github.com/users/aspnet/followers","following_url":"https://api.github.com/users/aspnet/following{/other_user}","gists_url":"https://api.github.com/users/aspnet/gists{/gist_id}","starred_url":"https://api.github.com/users/aspnet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aspnet/subscriptions","organizations_url":"https://api.github.com/users/aspnet/orgs","repos_url":"https://api.github.com/users/aspnet/repos","events_url":"https://api.github.com/users/aspnet/events{/privacy}","received_events_url":"https://api.github.com/users/aspnet/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/aspnet/Razor","description":"Parser and code generator for CSHTML files used in view pages for MVC web apps.","fork":false,"url":"https://api.github.com/repos/aspnet/Razor","forks_url":"https://api.github.com/repos/aspnet/Razor/forks","keys_url":"https://api.github.com/repos/aspnet/Razor/keys{/key_id}","collaborators_url":"https://api.github.com/repos/aspnet/Razor/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/aspnet/Razor/teams","hooks_url":"https://api.github.com/repos/aspnet/Razor/hooks","issue_events_url":"https://api.github.com/repos/aspnet/Razor/issues/events{/number}","events_url":"https://api.github.com/repos/aspnet/Razor/events","assignees_url":"https://api.github.com/repos/aspnet/Razor/assignees{/user}","branches_url":"https://api.github.com/repos/aspnet/Razor/branches{/branch}","tags_url":"https://api.github.com/repos/aspnet/Razor/tags","blobs_url":"https://api.github.com/repos/aspnet/Razor/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/aspnet/Razor/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/aspnet/Razor/git/refs{/sha}","trees_url":"https://api.github.com/repos/aspnet/Razor/git/trees{/sha}","statuses_url":"https://api.github.com/repos/aspnet/Razor/statuses/{sha}","languages_url":"https://api.github.com/repos/aspnet/Razor/languages","stargazers_url":"https://api.github.com/repos/aspnet/Razor/stargazers","contributors_url":"https://api.github.com/repos/aspnet/Razor/contributors","subscribers_url":"https://api.github.com/repos/aspnet/Razor/subscribers","subscription_url":"https://api.github.com/repos/aspnet/Razor/subscription","commits_url":"https://api.github.com/repos/aspnet/Razor/commits{/sha}","git_commits_url":"https://api.github.com/repos/aspnet/Razor/git/commits{/sha}","comments_url":"https://api.github.com/repos/aspnet/Razor/comments{/number}","issue_comment_url":"https://api.github.com/repos/aspnet/Razor/issues/comments{/number}","contents_url":"https://api.github.com/repos/aspnet/Razor/contents/{+path}","compare_url":"https://api.github.com/repos/aspnet/Razor/compare/{base}...{head}","merges_url":"https://api.github.com/repos/aspnet/Razor/merges","archive_url":"https://api.github.com/repos/aspnet/Razor/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/aspnet/Razor/downloads","issues_url":"https://api.github.com/repos/aspnet/Razor/issues{/number}","pulls_url":"https://api.github.com/repos/aspnet/Razor/pulls{/number}","milestones_url":"https://api.github.com/repos/aspnet/Razor/milestones{/number}","notifications_url":"https://api.github.com/repos/aspnet/Razor/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/aspnet/Razor/labels{/name}","releases_url":"https://api.github.com/repos/aspnet/Razor/releases{/id}","created_at":"2014-01-12T03:52:46Z","updated_at":"2015-05-14T06:41:48Z","pushed_at":"2015-05-15T18:09:25Z","git_url":"git://github.com/aspnet/Razor.git","ssh_url":"git@github.com:aspnet/Razor.git","clone_url":"https://github.com/aspnet/Razor.git","svn_url":"https://github.com/aspnet/Razor","homepage":"","size":9752,"stargazers_count":341,"watchers_count":341,"language":"C#","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":88,"mirror_url":null,"open_issues_count":77,"forks":88,"open_issues":77,"watchers":341,"default_branch":"dev"}},"_links":{"self":{"href":"https://api.github.com/repos/aspnet/Razor/pulls/372"},"html":{"href":"https://github.com/aspnet/Razor/pull/372"},"issue":{"href":"https://api.github.com/repos/aspnet/Razor/issues/372"},"comments":{"href":"https://api.github.com/repos/aspnet/Razor/issues/372/comments"},"review_comments":{"href":"https://api.github.com/repos/aspnet/Razor/pulls/372/comments"},"review_comment":{"href":"https://api.github.com/repos/aspnet/Razor/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/aspnet/Razor/pulls/372/commits"},"statuses":{"href":"https://api.github.com/repos/aspnet/Razor/statuses/2097006620d8f37f0de7e1c5de3f28aeb0de4167"}}}}