// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information. using System.Web.Razor.Editor; using System.Web.Razor.Generator; using System.Web.Razor.Parser; using System.Web.Razor.Parser.SyntaxTree; using System.Web.Razor.Test.Framework; using System.Web.Razor.Text; using Xunit; namespace System.Web.Razor.Test.Parser.Html { public class HtmlUrlAttributeTest : CsHtmlMarkupParserTestBase { [Fact] public void SimpleUrlInAttributeInMarkupBlock() { ParseBlockTest("", new MarkupBlock( Factory.Markup("(" href='", 2, 0, 2), new LocationTagged("'", 22, 0, 22)), Factory.Markup(" href='").With(SpanCodeGenerator.Null), Factory.Markup("~/Foo/Bar/Baz") .WithEditorHints(EditorHints.VirtualPath) .With(new LiteralAttributeCodeGenerator( new LocationTagged(String.Empty, 9, 0, 9), new LocationTagged(new ResolveUrlCodeGenerator(), 9, 0, 9))), Factory.Markup("'").With(SpanCodeGenerator.Null)), Factory.Markup(" />").Accepts(AcceptedCharacters.None))); } [Fact] public void SimpleUrlInAttributeInMarkupDocument() { ParseDocumentTest("", new MarkupBlock( Factory.Markup("(" href='", 2, 0, 2), new LocationTagged("'", 22, 0, 22)), Factory.Markup(" href='").With(SpanCodeGenerator.Null), Factory.Markup("~/Foo/Bar/Baz") .WithEditorHints(EditorHints.VirtualPath) .With(new LiteralAttributeCodeGenerator( new LocationTagged(String.Empty, 9, 0, 9), new LocationTagged(new ResolveUrlCodeGenerator(), 9, 0, 9))), Factory.Markup("'").With(SpanCodeGenerator.Null)), Factory.Markup(" />"))); } [Fact] public void SimpleUrlInAttributeInMarkupSection() { ParseDocumentTest("@section Foo { }", new MarkupBlock( Factory.EmptyHtml(), new SectionBlock(new SectionCodeGenerator("Foo"), Factory.CodeTransition(), Factory.MetaCode("section Foo {") .AutoCompleteWith(null, atEndOfSpan: true) .Accepts(AcceptedCharacters.Any), new MarkupBlock( Factory.Markup(" (" href='", 17, 0, 17), new LocationTagged("'", 37, 0, 37)), Factory.Markup(" href='").With(SpanCodeGenerator.Null), Factory.Markup("~/Foo/Bar/Baz") .WithEditorHints(EditorHints.VirtualPath) .With(new LiteralAttributeCodeGenerator( new LocationTagged(String.Empty, 24, 0, 24), new LocationTagged(new ResolveUrlCodeGenerator(), 24, 0, 24))), Factory.Markup("'").With(SpanCodeGenerator.Null)), Factory.Markup(" /> ")), Factory.MetaCode("}").Accepts(AcceptedCharacters.None)), Factory.EmptyHtml())); } [Fact] public void UrlWithExpressionsInAttributeInMarkupBlock() { ParseBlockTest("", new MarkupBlock( Factory.Markup("(" href='", 2, 0, 2), new LocationTagged("'", 22, 0, 22)), Factory.Markup(" href='").With(SpanCodeGenerator.Null), Factory.Markup("~/Foo/") .WithEditorHints(EditorHints.VirtualPath) .With(new LiteralAttributeCodeGenerator( new LocationTagged(String.Empty, 9, 0, 9), new LocationTagged(new ResolveUrlCodeGenerator(), 9, 0, 9))), new MarkupBlock(new DynamicAttributeBlockCodeGenerator(new LocationTagged(String.Empty, 15, 0, 15), 15, 0, 15), new ExpressionBlock( Factory.CodeTransition().Accepts(AcceptedCharacters.None), Factory.Code("id") .AsImplicitExpression(CSharpCodeParser.DefaultKeywords) .Accepts(AcceptedCharacters.NonWhiteSpace))), Factory.Markup("/Baz") .With(new LiteralAttributeCodeGenerator(new LocationTagged(String.Empty, 18, 0, 18), new LocationTagged("/Baz", 18, 0, 18))), Factory.Markup("'").With(SpanCodeGenerator.Null)), Factory.Markup(" />").Accepts(AcceptedCharacters.None))); } [Fact] public void UrlWithExpressionsInAttributeInMarkupDocument() { ParseDocumentTest("", new MarkupBlock( Factory.Markup("(" href='", 2, 0, 2), new LocationTagged("'", 22, 0, 22)), Factory.Markup(" href='").With(SpanCodeGenerator.Null), Factory.Markup("~/Foo/") .WithEditorHints(EditorHints.VirtualPath) .With(new LiteralAttributeCodeGenerator( new LocationTagged(String.Empty, 9, 0, 9), new LocationTagged(new ResolveUrlCodeGenerator(), 9, 0, 9))), new MarkupBlock(new DynamicAttributeBlockCodeGenerator(new LocationTagged(String.Empty, 15, 0, 15), 15, 0, 15), new ExpressionBlock( Factory.CodeTransition().Accepts(AcceptedCharacters.None), Factory.Code("id") .AsImplicitExpression(CSharpCodeParser.DefaultKeywords) .Accepts(AcceptedCharacters.NonWhiteSpace))), Factory.Markup("/Baz") .With(new LiteralAttributeCodeGenerator(new LocationTagged(String.Empty, 18, 0, 18), new LocationTagged("/Baz", 18, 0, 18))), Factory.Markup("'").With(SpanCodeGenerator.Null)), Factory.Markup(" />"))); } [Fact] public void UrlWithExpressionsInAttributeInMarkupSection() { ParseDocumentTest("@section Foo { }", new MarkupBlock( Factory.EmptyHtml(), new SectionBlock(new SectionCodeGenerator("Foo"), Factory.CodeTransition(), Factory.MetaCode("section Foo {") .AutoCompleteWith(null, atEndOfSpan: true), new MarkupBlock( Factory.Markup(" (" href='", 17, 0, 17), new LocationTagged("'", 37, 0, 37)), Factory.Markup(" href='").With(SpanCodeGenerator.Null), Factory.Markup("~/Foo/") .WithEditorHints(EditorHints.VirtualPath) .With(new LiteralAttributeCodeGenerator( new LocationTagged(String.Empty, 24, 0, 24), new LocationTagged(new ResolveUrlCodeGenerator(), 24, 0, 24))), new MarkupBlock(new DynamicAttributeBlockCodeGenerator(new LocationTagged(String.Empty, 30, 0, 30), 30, 0, 30), new ExpressionBlock( Factory.CodeTransition().Accepts(AcceptedCharacters.None), Factory.Code("id") .AsImplicitExpression(CSharpCodeParser.DefaultKeywords) .Accepts(AcceptedCharacters.NonWhiteSpace))), Factory.Markup("/Baz") .With(new LiteralAttributeCodeGenerator(new LocationTagged(String.Empty, 33, 0, 33), new LocationTagged("/Baz", 33, 0, 33))), Factory.Markup("'").With(SpanCodeGenerator.Null)), Factory.Markup(" /> ")), Factory.MetaCode("}").Accepts(AcceptedCharacters.None)), Factory.EmptyHtml())); } [Fact] public void UrlWithComplexCharactersInAttributeInMarkupBlock() { ParseBlockTest("", new MarkupBlock( Factory.Markup("(" href='", 2, 0, 2), new LocationTagged("'", 31, 0, 31)), Factory.Markup(" href='").With(SpanCodeGenerator.Null), Factory.Markup("~/Foo+Bar:Baz(Biz),Boz") .WithEditorHints(EditorHints.VirtualPath) .With(new LiteralAttributeCodeGenerator( new LocationTagged(String.Empty, 9, 0, 9), new LocationTagged(new ResolveUrlCodeGenerator(), 9, 0, 9))), Factory.Markup("'").With(SpanCodeGenerator.Null)), Factory.Markup(" />").Accepts(AcceptedCharacters.None))); } [Fact] public void UrlWithComplexCharactersInAttributeInMarkupDocument() { ParseDocumentTest("", new MarkupBlock( Factory.Markup("(" href='", 2, 0, 2), new LocationTagged("'", 31, 0, 31)), Factory.Markup(" href='").With(SpanCodeGenerator.Null), Factory.Markup("~/Foo+Bar:Baz(Biz),Boz") .WithEditorHints(EditorHints.VirtualPath) .With(new LiteralAttributeCodeGenerator( new LocationTagged(String.Empty, 9, 0, 9), new LocationTagged(new ResolveUrlCodeGenerator(), 9, 0, 9))), Factory.Markup("'").With(SpanCodeGenerator.Null)), Factory.Markup(" />"))); } [Fact] public void UrlInUnquotedAttributeValueInMarkupBlock() { ParseBlockTest("", new MarkupBlock( Factory.Markup("(" href=", 2, 0, 2), new LocationTagged(String.Empty, 38, 0, 38)), Factory.Markup(" href=").With(SpanCodeGenerator.Null), Factory.Markup("~/Foo+Bar:Baz(Biz),Boz/") .WithEditorHints(EditorHints.VirtualPath) .With(new LiteralAttributeCodeGenerator( new LocationTagged(String.Empty, 8, 0, 8), new LocationTagged(new ResolveUrlCodeGenerator(), 8, 0, 8))), new MarkupBlock(new DynamicAttributeBlockCodeGenerator(new LocationTagged(String.Empty, 31, 0, 31), 31, 0, 31), new ExpressionBlock( Factory.CodeTransition() .Accepts(AcceptedCharacters.None), Factory.Code("id") .AsImplicitExpression(CSharpCodeParser.DefaultKeywords) .Accepts(AcceptedCharacters.NonWhiteSpace))), Factory.Markup("/Boz").With(new LiteralAttributeCodeGenerator(new LocationTagged(String.Empty, 34, 0, 34), new LocationTagged("/Boz", 34, 0, 34)))), Factory.Markup(" />").Accepts(AcceptedCharacters.None))); } [Fact] public void UrlInUnquotedAttributeValueInMarkupDocument() { ParseDocumentTest("", new MarkupBlock( Factory.Markup("(" href=", 2, 0, 2), new LocationTagged(String.Empty, 38, 0, 38)), Factory.Markup(" href=").With(SpanCodeGenerator.Null), Factory.Markup("~/Foo+Bar:Baz(Biz),Boz/") .WithEditorHints(EditorHints.VirtualPath) .With(new LiteralAttributeCodeGenerator( new LocationTagged(String.Empty, 8, 0, 8), new LocationTagged(new ResolveUrlCodeGenerator(), 8, 0, 8))), new MarkupBlock(new DynamicAttributeBlockCodeGenerator(new LocationTagged(String.Empty, 31, 0, 31), 31, 0, 31), new ExpressionBlock( Factory.CodeTransition() .Accepts(AcceptedCharacters.None), Factory.Code("id") .AsImplicitExpression(CSharpCodeParser.DefaultKeywords) .Accepts(AcceptedCharacters.NonWhiteSpace))), Factory.Markup("/Boz").With(new LiteralAttributeCodeGenerator(new LocationTagged(String.Empty, 34, 0, 34), new LocationTagged("/Boz", 34, 0, 34)))), Factory.Markup(" />"))); } [Fact] public void UrlInUnquotedAttributeValueInMarkupSection() { ParseDocumentTest("@section Foo { }", new MarkupBlock( Factory.EmptyHtml(), new SectionBlock(new SectionCodeGenerator("Foo"), Factory.CodeTransition(), Factory.MetaCode("section Foo {") .AutoCompleteWith(null, atEndOfSpan: true), new MarkupBlock( Factory.Markup(" (" href=", 17, 0, 17), new LocationTagged(String.Empty, 53, 0, 53)), Factory.Markup(" href=").With(SpanCodeGenerator.Null), Factory.Markup("~/Foo+Bar:Baz(Biz),Boz/") .WithEditorHints(EditorHints.VirtualPath) .With(new LiteralAttributeCodeGenerator( new LocationTagged(String.Empty, 23, 0, 23), new LocationTagged(new ResolveUrlCodeGenerator(), 23, 0, 23))), new MarkupBlock(new DynamicAttributeBlockCodeGenerator(new LocationTagged(String.Empty, 46, 0, 46), 46, 0, 46), new ExpressionBlock( Factory.CodeTransition() .Accepts(AcceptedCharacters.None), Factory.Code("id") .AsImplicitExpression(CSharpCodeParser.DefaultKeywords) .Accepts(AcceptedCharacters.NonWhiteSpace))), Factory.Markup("/Boz").With(new LiteralAttributeCodeGenerator(new LocationTagged(String.Empty, 49, 0, 49), new LocationTagged("/Boz", 49, 0, 49)))), Factory.Markup(" /> ")), Factory.MetaCode("}").Accepts(AcceptedCharacters.None)), Factory.EmptyHtml())); } } }