public void CreateDescriptor_DoesntResolveInheritedTagNames() { // Arrange var errorSink = new ParserErrorSink(); var validProp = typeof(InheritedMultiTagTagHelper).GetProperty(nameof(InheritedMultiTagTagHelper.ValidAttribute)); var expectedDescriptor = new TagHelperDescriptor( "inherited-multi-tag", typeof(InheritedMultiTagTagHelper).FullName, AssemblyName, new[] { new TagHelperAttributeDescriptor("valid-attribute", validProp) }); // Act var descriptors = TagHelperDescriptorFactory.CreateDescriptors( AssemblyName, typeof(InheritedMultiTagTagHelper), errorSink); // Assert Assert.Empty(errorSink.Errors); var descriptor = Assert.Single(descriptors); Assert.Equal(expectedDescriptor, descriptor, CaseSensitiveTagHelperDescriptorComparer.Default); }
private void ParserTest(string content, Block document, TagProvidersCollection providers = null) { providers = providers ?? TagProvidersCollection.Default; var output = new StringBuilder(); using (var reader = new StringReader(content)) { using (var source = new SeekableTextReader(reader)) { var errors = new ParserErrorSink(); var parser = new HandlebarsParser(); var context = new ParserContext(source, parser, errors, providers); parser.Context = context; parser.ParseDocument(); var results = context.CompleteParse(); var comparer = new EquivalanceComparer(output, 0); Assert.True(comparer.Equals(document, results.Document), output.ToString()); } } }
public void CreateDescriptor_OnlyAcceptsPropertiesWithPublicGetAndSet() { // Arrange var errorSink = new ParserErrorSink(); var validProperty = typeof(PrivateAccessorTagHelper).GetProperty( nameof(PrivateAccessorTagHelper.ValidAttribute)); var expectedDescriptor = new TagHelperDescriptor( "private-accessor", typeof(PrivateAccessorTagHelper).FullName, AssemblyName, new[] { new TagHelperAttributeDescriptor( "valid-attribute", validProperty) }); // Act var descriptors = TagHelperDescriptorFactory.CreateDescriptors( AssemblyName, typeof(PrivateAccessorTagHelper), errorSink); // Assert Assert.Empty(errorSink.Errors); var descriptor = Assert.Single(descriptors); Assert.Equal(expectedDescriptor, descriptor, CaseSensitiveTagHelperDescriptorComparer.Default); }
public void RenderAttributeValue_RendersModelExpressionsCorrectly(string modelExpressionType, string propertyType, string expectedValue) { // Arrange var renderer = new MvcTagHelperAttributeValueCodeRenderer( new GeneratedTagHelperAttributeContext { ModelExpressionTypeName = modelExpressionType, CreateModelExpressionMethodName = "SomeMethod" }); var attributeDescriptor = new TagHelperAttributeDescriptor("MyAttribute", "SomeProperty", propertyType); var writer = new CSharpCodeWriter(); var generatorContext = new CodeGeneratorContext(host: null, className: string.Empty, rootNamespace: string.Empty, sourceFile: string.Empty, shouldGenerateLinePragmas: true); var errorSink = new ParserErrorSink(); var context = new CodeBuilderContext(generatorContext, errorSink); // Act renderer.RenderAttributeValue(attributeDescriptor, writer, context, (codeWriter) => { codeWriter.Write("MyValue"); }, complexValue: false); // Assert Assert.Equal(expectedValue, writer.GenerateCode()); }
public void CreateDescriptor_ResolvesMultipleTagHelperDescriptorsFromSingleType() { // Arrange var errorSink = new ParserErrorSink(); var validProp = typeof(MultiTagTagHelper).GetProperty(nameof(MultiTagTagHelper.ValidAttribute)); var expectedDescriptors = new[] { new TagHelperDescriptor( "p", typeof(MultiTagTagHelper).FullName, AssemblyName, new[] { new TagHelperAttributeDescriptor("valid-attribute", validProp) }), new TagHelperDescriptor( "div", typeof(MultiTagTagHelper).FullName, AssemblyName, new[] { new TagHelperAttributeDescriptor("valid-attribute", validProp) }) }; // Act var descriptors = TagHelperDescriptorFactory.CreateDescriptors( AssemblyName, typeof(MultiTagTagHelper), errorSink); // Assert Assert.Empty(errorSink.Errors); Assert.Equal(expectedDescriptors, descriptors, CaseSensitiveTagHelperDescriptorComparer.Default); }
public void CreateDescriptor_AllowsOverridenAttributeNameOnUnimplementedVirtual() { // Arrange var errorSink = new ParserErrorSink(); var validProperty1 = typeof(InheritedNotOverriddenAttributeTagHelper).GetProperty( nameof(InheritedNotOverriddenAttributeTagHelper.ValidAttribute1)); var validProperty2 = typeof(InheritedNotOverriddenAttributeTagHelper).GetProperty( nameof(InheritedNotOverriddenAttributeTagHelper.ValidAttribute2)); var expectedDescriptors = new[] { new TagHelperDescriptor( "inherited-not-overridden-attribute", typeof(InheritedNotOverriddenAttributeTagHelper).FullName, AssemblyName, new[] { new TagHelperAttributeDescriptor("SomethingElse", validProperty1), new TagHelperAttributeDescriptor("Something-Else", validProperty2) }) }; // Act var descriptors = TagHelperDescriptorFactory.CreateDescriptors( AssemblyName, typeof(InheritedNotOverriddenAttributeTagHelper), errorSink); // Assert Assert.Empty(errorSink.Errors); Assert.Equal(expectedDescriptors, descriptors, CaseSensitiveTagHelperDescriptorComparer.Default); }
public void CreateDescriptor_BuildsDescriptorsWithConventionNames() { // Arrange var errorSink = new ParserErrorSink(); var intProperty = typeof(SingleAttributeTagHelper).GetProperty(nameof(SingleAttributeTagHelper.IntAttribute)); var expectedDescriptor = new TagHelperDescriptor( "single-attribute", typeof(SingleAttributeTagHelper).FullName, AssemblyName, new[] { new TagHelperAttributeDescriptor("int-attribute", intProperty) }); // Act var descriptors = TagHelperDescriptorFactory.CreateDescriptors( AssemblyName, typeof(SingleAttributeTagHelper), new ParserErrorSink()); // Assert Assert.Empty(errorSink.Errors); var descriptor = Assert.Single(descriptors); Assert.Equal(expectedDescriptor, descriptor, CaseSensitiveTagHelperDescriptorComparer.Default); }
protected override IEnumerable <TagHelperDescriptor> ResolveDescriptorsInAssembly( string assemblyName, SourceLocation documentLocation, ParserErrorSink errorSink) { throw _error; }
public void DescriptorResolver_UnderstandsUnexpectedExceptions_DoesNotThrow() { // Arrange var expectedErrorMessage = "Encountered an unexpected error when attempting to resolve tag helper " + "directive '@addtaghelper' with value 'A custom lookup text'. Error: A " + "custom exception"; var documentLocation = new SourceLocation(1, 2, 3); var directiveType = TagHelperDirectiveType.AddTagHelper; var errorSink = new ParserErrorSink(); var expectedError = new Exception("A custom exception"); var tagHelperDescriptorResolver = new ThrowingTagHelperDescriptorResolver(expectedError); var resolutionContext = new TagHelperDescriptorResolutionContext( new[] { new TagHelperDirectiveDescriptor("A custom lookup text", documentLocation, directiveType) }, errorSink); // Act tagHelperDescriptorResolver.Resolve(resolutionContext); // Assert var error = Assert.Single(errorSink.Errors); Assert.Equal(1, error.Length); Assert.Equal(documentLocation, error.Location); Assert.Equal(expectedErrorMessage, error.Message); }
/// <summary> /// Creates a document <see cref="Block"/> from the given template. /// </summary> /// <param name="template">The template.</param> /// <returns>The document <see cref="Block"/></returns> private Block CreateDocument(string template) { using (var reader = new StringReader(template)) { using (var source = new SeekableTextReader(reader)) { var errors = new ParserErrorSink(); var parser = new HandlebarsParser(); var context = new ParserContext(source, parser, errors, TagProviders); parser.Context = context; parser.ParseDocument(); var results = context.CompleteParse(); if (results.Success) { return(results.Document); } throw new InvalidOperationException( string.Join("\n", results.Errors.Select(e => string.Format("{0}: {1}", e.Location, e.Message)))); } } }
public void DescriptorResolver_CreatesErrorIfNullOrEmptyLookupText_DoesNotThrow(string lookupText) { // Arrange var errorSink = new ParserErrorSink(); var tagHelperDescriptorResolver = new TestTagHelperDescriptorResolver( new TestTagHelperTypeResolver(InvalidTestableTagHelpers)); var documentLocation = new SourceLocation(1, 2, 3); var directiveType = TagHelperDirectiveType.AddTagHelper; var expectedErrorMessage = Resources.FormatTagHelperDescriptorResolver_InvalidTagHelperLookupText(lookupText); var resolutionContext = new TagHelperDescriptorResolutionContext( new [] { new TagHelperDirectiveDescriptor(lookupText, documentLocation, directiveType) }, errorSink); // Act tagHelperDescriptorResolver.Resolve(resolutionContext); // Assert var error = Assert.Single(errorSink.Errors); Assert.Equal(1, error.Length); Assert.Equal(documentLocation, error.Location); Assert.Equal(expectedErrorMessage, error.Message); }
private static LookupInfo GetLookupInfo(TagHelperDirectiveDescriptor directiveDescriptor, ParserErrorSink errorSink) { var lookupText = directiveDescriptor.DirectiveText; var lookupStrings = lookupText?.Split(new[] { ',' }); // Ensure that we have valid lookupStrings to work with. Valid formats are: // "assemblyName" // "typeName, assemblyName" if (lookupStrings == null || lookupStrings.Any(string.IsNullOrWhiteSpace) || lookupStrings.Length != 2) { errorSink.OnError( directiveDescriptor.Location, Resources.FormatTagHelperDescriptorResolver_InvalidTagHelperLookupText(lookupText)); return(null); } return(new LookupInfo { TypePattern = lookupStrings[0].Trim(), AssemblyName = lookupStrings[1].Trim() }); }
/// <summary> /// Instantiates a new instance of <see cref="TagHelperDescriptorResolutionContext"/>. /// </summary> /// <param name="directiveDescriptors"><see cref="TagHelperDirectiveDescriptor"/>s used to resolve /// <see cref="TagHelperDescriptor"/>s.</param> /// <param name="errorSink">Used to aggregate <see cref="Parser.SyntaxTree.RazorError"/>s.</param> public TagHelperDescriptorResolutionContext( [NotNull] IEnumerable <TagHelperDirectiveDescriptor> directiveDescriptors, [NotNull] ParserErrorSink errorSink) { DirectiveDescriptors = new List <TagHelperDirectiveDescriptor>(directiveDescriptors); ErrorSink = errorSink; }
public void VisitSendsErrorsToVisitor() { // Arrange Mock <ParserVisitor> targetMock = new Mock <ParserVisitor>(); var root = new BlockBuilder() { Type = BlockType.Comment }.Build(); var errorSink = new ParserErrorSink(); List <RazorError> errors = new List <RazorError> { new RazorError("Foo", 1, 0, 1), new RazorError("Bar", 2, 0, 2), }; foreach (var error in errors) { errorSink.OnError(error); } var results = new ParserResults(root, Enumerable.Empty <TagHelperDescriptor>(), errorSink); // Act targetMock.Object.Visit(results); // Assert targetMock.Verify(v => v.VisitError(errors[0])); targetMock.Verify(v => v.VisitError(errors[1])); }
public void CreateDescriptor_IgnoresDuplicateTagNamesFromAttribute() { // Arrange var errorSink = new ParserErrorSink(); var expectedDescriptors = new[] { new TagHelperDescriptor( "p", typeof(DuplicateTagNameTagHelper).FullName, AssemblyName), new TagHelperDescriptor( "div", typeof(DuplicateTagNameTagHelper).FullName, AssemblyName) }; // Act var descriptors = TagHelperDescriptorFactory.CreateDescriptors( AssemblyName, typeof(DuplicateTagNameTagHelper), errorSink); // Assert Assert.Empty(errorSink.Errors); Assert.Equal(expectedDescriptors, descriptors, CaseSensitiveTagHelperDescriptorComparer.Default); }
protected override TagHelperDescriptorResolutionContext GetTagHelperDescriptorResolutionContext( IEnumerable <TagHelperDirectiveDescriptor> descriptors, ParserErrorSink errorSink) { var directivesToImport = MergeDirectiveDescriptors(descriptors, _globalImportDirectiveDescriptors); return(base.GetTagHelperDescriptorResolutionContext(directivesToImport, errorSink)); }
private static IEnumerable <TargetElementAttribute> GetValidTargetElementAttributes( TypeInfo typeInfo, ParserErrorSink errorSink) { var targetElementAttributes = typeInfo.GetCustomAttributes <TargetElementAttribute>(inherit: false); return(targetElementAttributes.Where(attribute => ValidTargetElementAttributeNames(attribute, errorSink))); }
public GlobalImportTagHelperDirectiveSpanVisitor( ITagHelperDescriptorResolver descriptorResolver, IEnumerable <TagHelperDirectiveDescriptor> globalImportDirectiveDescriptors, ParserErrorSink errorSink) : base(descriptorResolver, errorSink) { _globalImportDirectiveDescriptors = globalImportDirectiveDescriptors; }
public ViewStartAddRemoveTagHelperVisitor( ITagHelperDescriptorResolver descriptorResolver, IEnumerable <TagHelperDirectiveDescriptor> viewStartDirectiveDescriptors, ParserErrorSink errorSink) : base(descriptorResolver, errorSink) { _viewStartDirectiveDescriptors = viewStartDirectiveDescriptors; }
protected override TagHelperDescriptorResolutionContext GetTagHelperDescriptorResolutionContext( IEnumerable <TagHelperDirectiveDescriptor> descriptors, ParserErrorSink errorSink) { return(base.GetTagHelperDescriptorResolutionContext( _viewStartDirectiveDescriptors.Concat(descriptors), errorSink)); }
protected override IEnumerable <TagHelperDescriptor> ResolveDescriptorsInAssembly( string assemblyName, SourceLocation documentLocation, ParserErrorSink errorSink) { CalledWithAssemblyName = assemblyName; return(Enumerable.Empty <TagHelperDescriptor>()); }
protected virtual ParserResults ParseDocument(string document, bool designTimeParser, ParserErrorSink errorSink) { return(RunParse(document, parser => parser.ParseDocument, designTimeParser, parserSelector: c => c.MarkupParser, errorSink: errorSink)); }
/// <inheritdoc /> protected override IEnumerable <TagHelperDescriptor> GetTagHelperDescriptors( [NotNull] Block documentRoot, [NotNull] ParserErrorSink errorSink) { var visitor = new ViewStartAddRemoveTagHelperVisitor(TagHelperDescriptorResolver, _viewStartDirectiveDescriptors, errorSink); return(visitor.GetDescriptors(documentRoot)); }
/// <inheritdoc /> protected override IEnumerable <TagHelperDescriptor> GetTagHelperDescriptors( [NotNull] Block documentRoot, [NotNull] ParserErrorSink errorSink) { var visitor = new GlobalImportTagHelperDirectiveSpanVisitor( TagHelperDescriptorResolver, _globalImportDirectiveDescriptors, errorSink); return(visitor.GetDescriptors(documentRoot)); }
/// <summary> /// Instantiates a new <see cref="ParserResults"/> instance. /// </summary> /// <param name="success"><c>true</c> if parsing was successful, <c>false</c> otherwise.</param> /// <param name="document">The <see cref="Block"/> for the syntax tree.</param> /// <param name="tagHelperDescriptors"> /// The <see cref="TagHelperDescriptor"/>s that apply to the current Razor document. /// </param> /// <param name="errorSink"> /// The <see cref="ParserErrorSink"/> used to collect <see cref="RazorError"/>s encountered when parsing the /// current Razor document. /// </param> protected ParserResults(bool success, [NotNull] Block document, [NotNull] IEnumerable <TagHelperDescriptor> tagHelperDescriptors, [NotNull] ParserErrorSink errorSink) { Success = success; Document = document; TagHelperDescriptors = tagHelperDescriptors; ErrorSink = errorSink; ParserErrors = errorSink.Errors; }
public virtual ParserContext CreateParserContext(ITextDocument input, ParserBase codeParser, ParserBase markupParser, ParserErrorSink errorSink) { return(new ParserContext(input, codeParser, markupParser, SelectActiveParser(codeParser, markupParser), errorSink)); }
// Internal for testing. internal CodeBuilderContext(RazorEngineHost host, string className, string rootNamespace, string sourceFile, bool shouldGenerateLinePragmas, ParserErrorSink errorSink) : base(host, className, rootNamespace, sourceFile, shouldGenerateLinePragmas) { ErrorSink = errorSink; ExpressionRenderingMode = ExpressionRenderingMode.WriteToOutput; }
public void ConstructorAcceptsActiveParserIfIsSameAsEitherCodeOrMarkupParser() { var codeParser = new CSharpCodeParser(); var markupParser = new HtmlMarkupParser(); var errorSink = new ParserErrorSink(); new ParserContext( new SeekableTextReader(TextReader.Null), codeParser, markupParser, codeParser, errorSink); new ParserContext( new SeekableTextReader(TextReader.Null), codeParser, markupParser, markupParser, errorSink); }
/// <summary> /// Instantiates a new <see cref="GeneratorResults"/> instance. /// </summary> /// <param name="document">The <see cref="Block"/> for the syntax tree.</param> /// <param name="tagHelperDescriptors"> /// The <see cref="TagHelperDescriptor"/>s that apply to the current Razor document. /// </param> /// <param name="errorSink"> /// The <see cref="ParserErrorSink"/> used to collect <see cref="RazorError"/>s encountered when parsing the /// current Razor document. /// </param> /// <param name="codeBuilderResult">The results of generating code for the document.</param> /// <param name="codeTree">A <see cref="CodeTree"/> for the document.</param> public GeneratorResults([NotNull] Block document, [NotNull] IEnumerable <TagHelperDescriptor> tagHelperDescriptors, [NotNull] ParserErrorSink errorSink, [NotNull] CodeBuilderResult codeBuilderResult, [NotNull] CodeTree codeTree) : base(document, tagHelperDescriptors, errorSink) { GeneratedCode = codeBuilderResult.Code; DesignTimeLineMappings = codeBuilderResult.DesignTimeLineMappings; CodeTree = codeTree; }
public static TagHelperBlockBuilder Rewrite(string tagName, bool validStructure, Block tag, IEnumerable <TagHelperDescriptor> descriptors, ParserErrorSink errorSink) { // There will always be at least one child for the '<'. var start = tag.Children.First().Start; var attributes = GetTagAttributes(tagName, validStructure, tag, descriptors, errorSink); return(new TagHelperBlockBuilder(tagName, start, attributes, descriptors)); }
public TagHelperDirectiveSpanVisitor([NotNull] ITagHelperDescriptorResolver descriptorResolver, [NotNull] ParserErrorSink errorSink) { _descriptorResolver = descriptorResolver; _errorSink = errorSink; }