public void Render_AttributeChildContent_IgnoresEmptyBody()
        {
            // Arrange
            AdditionalSyntaxTrees.Add(RenderChildContentComponent);

            var component = CompileToComponent(@"
@addTagHelper *, TestAssembly
@{ RenderFragment<string> template = (context) => @<div>@context.ToLowerInvariant()</div>; }
<RenderChildContent ChildContent=""@template(""HI"")""></RenderChildContent>");

            // Act
            var frames = GetRenderTree(component);

            // Assert
            Assert.Collection(
                frames,
                frame => AssertFrame.Component(frame, "Test.RenderChildContent", 2, 2),
                frame => AssertFrame.Attribute(frame, RenderTreeBuilder.ChildContent, 3),
                frame => AssertFrame.Element(frame, "div", 2, 0),
                frame => AssertFrame.Text(frame, "hi", 1));
        }
        public void Render_BodyChildContent()
        {
            // Arrange
            AdditionalSyntaxTrees.Add(RenderChildContentComponent);

            var component = CompileToComponent(@"
@addTagHelper *, TestAssembly
<RenderChildContent>
  <div></div>
</RenderChildContent>");

            // Act
            var frames = GetRenderTree(component);

            // Assert
            Assert.Collection(
                frames,
                frame => AssertFrame.Component(frame, "Test.RenderChildContent", 2, 0),
                frame => AssertFrame.Attribute(frame, RenderTreeBuilder.ChildContent, 1),
                frame => AssertFrame.Markup(frame, "\n  <div></div>\n", 2));
        }
Ejemplo n.º 3
0
        public void Template_ExplicitExpressionInComponentAttribute_CreatesDiagnostic()
        {
            // Arrange
            AdditionalSyntaxTrees.Add(Parse(@"
using Microsoft.AspNetCore.Components;

namespace Test
{
    public class MyComponent : ComponentBase
    {
    }
}
"));
            // Act
            var generated = CompileToCSharp(@"<MyComponent attr=""@(@<div></div>)"" />");

            // Assert
            var diagnostic = Assert.Single(generated.Diagnostics);

            Assert.Equal("BL9994", diagnostic.Id);
        }
        public void Render_AttributeChildContent_NoArgTemplate()
        {
            // Arrange
            AdditionalSyntaxTrees.Add(RenderChildContentComponent);

            var component = CompileToComponent(@"
@addTagHelper *, TestAssembly
@{ RenderFragment template = @<div>@(""HI"".ToLowerInvariant())</div>; }
<RenderChildContent ChildContent=""@template"" />");

            // Act
            var frames = GetRenderTree(component);

            // Assert
            Assert.Collection(
                frames,
                frame => AssertFrame.Component(frame, "Test.RenderChildContent", 2, 2),
                frame => AssertFrame.Attribute(frame, RenderTreeBuilder.ChildContent, 3),
                frame => AssertFrame.Element(frame, "div", 2, 0),
                frame => AssertFrame.Text(frame, "hi", 1));
        }
Ejemplo n.º 5
0
        public void Render_AttributeChildContent_RenderFragmentOfString()
        {
            // Arrange
            AdditionalSyntaxTrees.Add(RenderChildContentStringComponent);

            var component = CompileToComponent(@"
@{ RenderFragment<string> template = (context) => @<div>@context.ToLowerInvariant()</div>; }
<RenderChildContentString ChildContent=""@template"" Value=""HI"" />");

            // Act
            var frames = GetRenderTree(component);

            // Assert
            Assert.Collection(
                frames,
                frame => AssertFrame.Component(frame, "Test.RenderChildContentString", 3, 2),
                frame => AssertFrame.Attribute(frame, RenderTreeBuilder.ChildContent, 3),
                frame => AssertFrame.Attribute(frame, "Value", "HI", 4),
                frame => AssertFrame.Element(frame, "div", 2, 0),
                frame => AssertFrame.Text(frame, "hi", 1));
        }
        public void Render_ChildComponent_WithChildContent()
        {
            // Arrange
            AdditionalSyntaxTrees.Add(Parse(@"
using Microsoft.AspNetCore.Blazor;
using Microsoft.AspNetCore.Blazor.Components;
namespace Test
{
    public class MyComponent : BlazorComponent
    {
        public string MyAttr { get; set; }
        public RenderFragment ChildContent { get; set; }
    }
}
"));

            var component = CompileToComponent(@"
@addTagHelper *, TestAssembly
<MyComponent MyAttr=""abc"">Some text<some-child a='1'>Nested text</some-child></MyComponent>");

            // Act
            var frames = GetRenderTree(component);

            // Assert: component frames are correct
            Assert.Collection(
                frames,
                frame => AssertFrame.Component(frame, "Test.MyComponent", 3, 0),
                frame => AssertFrame.Attribute(frame, "MyAttr", "abc", 1),
                frame => AssertFrame.Attribute(frame, RenderTreeBuilder.ChildContent, 2));

            // Assert: Captured ChildContent frames are correct
            var childFrames = GetFrames((RenderFragment)frames[2].AttributeValue);

            Assert.Collection(
                childFrames,
                frame => AssertFrame.Text(frame, "Some text", 3),
                frame => AssertFrame.Element(frame, "some-child", 3, 4),
                frame => AssertFrame.Attribute(frame, "a", "1", 5),
                frame => AssertFrame.Text(frame, "Nested text", 6));
        }
        public void RejectsTagHelperDirectives()
        {
            // Arrange/Act
            AdditionalSyntaxTrees.Add(Parse(@"
using Microsoft.AspNetCore.Components;

namespace Test
{
    public class MyComponent : ComponentBase
    {
    }
}
"));

            var result = CompileToCSharp(@"
@addTagHelper *, TestAssembly
@tagHelperPrefix th

<MyComponent />
");

            // Assert
            Assert.Collection(result.Diagnostics,
                              item =>
            {
                Assert.Equal("RZ9978", item.Id);
                Assert.Equal("The directives @addTagHelper, @removeTagHelper and @tagHelperPrefix are not valid in a component document. " +
                             "Use '@using <namespace>' directive instead.", item.GetMessage(CultureInfo.CurrentCulture));
                Assert.Equal(0, item.Span.LineIndex);
                Assert.Equal(0, item.Span.CharacterIndex);
            },
                              item =>
            {
                Assert.Equal("RZ9978", item.Id);
                Assert.Equal("The directives @addTagHelper, @removeTagHelper and @tagHelperPrefix are not valid in a component document. " +
                             "Use '@using <namespace>' directive instead.", item.GetMessage(CultureInfo.CurrentCulture));
                Assert.Equal(1, item.Span.LineIndex);
                Assert.Equal(0, item.Span.CharacterIndex);
            });
        }
Ejemplo n.º 8
0
        public void ComponentDiscovery_CanFindComponent_WithNamespace_DefinedinCSharp()
        {
            // Arrange
            AdditionalSyntaxTrees.Add(Parse(@"
using Microsoft.AspNetCore.Blazor.Components;

namespace Test.AnotherNamespace
{
    public class MyComponent : BlazorComponent
    {
    }
}
"));

            // Act
            var result = CompileToCSharp("@addTagHelper *, TestAssembly");

            // Assert
            var bindings = result.CodeDocument.GetTagHelperContext();

            Assert.Single(bindings.TagHelpers, t => t.Name == "Test.AnotherNamespace.MyComponent");
        }
        public void ChildContent_ExplicitChildContent_UnrecogizedContent_ProducesDiagnostic()
        {
            // Arrange
            AdditionalSyntaxTrees.Add(RenderChildContentComponent);

            // Act
            var generated = CompileToCSharp(@"
<RenderChildContent>
<ChildContent>
</ChildContent>
@somethingElse
</RenderChildContent>");

            // Assert
            var diagnostic = Assert.Single(generated.Diagnostics);

            Assert.Same(ComponentDiagnosticFactory.ChildContentMixedWithExplicitChildContent.Id, diagnostic.Id);
            Assert.Equal(
                "Unrecognized child content inside component 'RenderChildContent'. The component 'RenderChildContent' accepts " +
                "child content through the following top-level items: 'ChildContent'.",
                diagnostic.GetMessage());
        }
Ejemplo n.º 10
0
        public void Render_ExplicitChildContent()
        {
            // Arrange
            AdditionalSyntaxTrees.Add(RenderChildContentComponent);

            var component = CompileToComponent(@"
<RenderChildContent>
  <ChildContent>
    <div></div>
  </ChildContent>
</RenderChildContent>");

            // Act
            var frames = GetRenderTree(component);

            // Assert
            Assert.Collection(
                frames,
                frame => AssertFrame.Component(frame, "Test.RenderChildContent", 2, 0),
                frame => AssertFrame.Attribute(frame, "ChildContent", 1),
                frame => AssertFrame.Markup(frame, "\n    <div></div>\n  ", 2));
        }
Ejemplo n.º 11
0
        public void BindToComponent_TypeChecked_WithMatchingProperties()
        {
            // Arrange
            AdditionalSyntaxTrees.Add(Parse(@"
using System;
using Microsoft.AspNetCore.Blazor.Components;

namespace Test
{
    public class MyComponent : BlazorComponent
    {
        [Parameter]
        int Value { get; set; }

        [Parameter]
        Action<int> ValueChanged { get; set; }
    }
}"));

            // Act
            var generated = CompileToCSharp(@"
@addTagHelper *, TestAssembly
<MyComponent bind-Value=""ParentValue"" />
@functions {
    public string ParentValue { get; set; } = ""42"";
}");

            // Assert
            AssertDocumentNodeMatchesBaseline(generated.CodeDocument);
            AssertCSharpDocumentMatchesBaseline(generated.CodeDocument);

            var assembly = CompileToAssembly(generated, throwOnFailure: false);

            // This has some errors
            Assert.Collection(
                assembly.Diagnostics.OrderBy(d => d.Id),
                d => Assert.Equal("CS0029", d.Id),
                d => Assert.Equal("CS1503", d.Id));
        }
        public void ComponentDiscovery_CanFindComponent_DefinedinCSharp()
        {
            // Arrange
            AdditionalSyntaxTrees.Add(Parse(@"
using Microsoft.AspNetCore.Components;

namespace Test
{
    public class MyComponent : ComponentBase
    {
    }
}
"));

            // Act
            var result = CompileToCSharp(string.Empty);

            // Assert
            var bindings = result.CodeDocument.GetTagHelperContext();

            Assert.Contains(bindings.TagHelpers, t => t.Name == "Test.MyComponent");
        }
Ejemplo n.º 13
0
    public void Template_ImplicitExpressionInComponentAttribute_CreatesDiagnostic()
    {
        // Arrange
        AdditionalSyntaxTrees.Add(Parse(@"
using Microsoft.AspNetCore.Components;

namespace Test
{
    public class MyComponent : ComponentBase
    {
    }
}
"));

        // Act
        var generated = CompileToCSharp(@"<MyComponent attr=""@<div></div>"" />", throwOnFailure: false);

        // Assert
        Assert.Collection(
            generated.Diagnostics,
            d => Assert.Equal("RZ9986", d.Id),
            d => Assert.Equal("RZ1005", d.Id));
    }
Ejemplo n.º 14
0
        public void BodyAndExplicitChildContent()
        {
            // Arrange
            AdditionalSyntaxTrees.Add(Parse(@"
using Microsoft.AspNetCore.Blazor;
using Microsoft.AspNetCore.Blazor.Components;

namespace Test
{
    public class MyComponent : BlazorComponent
    {
        [Parameter]
        RenderFragment<string> Header { get; set; }

        [Parameter]
        RenderFragment ChildContent { get; set; }

        [Parameter]
        RenderFragment Footer { get; set; }
    }
}
"));

            // Act
            var generated = CompileToCSharp(@"
@addTagHelper *, TestAssembly
@{ RenderFragment<string> header = (context) => @<div>@context.ToLowerInvariant()</div>; }
<MyComponent Header=@header>
  <ChildContent>Some Content</ChildContent>
  <Footer>Bye!</Footer>
</MyComponent>");

            // Assert
            AssertDocumentNodeMatchesBaseline(generated.CodeDocument);
            AssertCSharpDocumentMatchesBaseline(generated.CodeDocument);
            CompileToAssembly(generated);
        }
Ejemplo n.º 15
0
        public void RazorTemplate_FollowedByComponent()
        {
            // Arrange
            AdditionalSyntaxTrees.Add(Parse(@"
using Microsoft.AspNetCore.Blazor.Components;

namespace Test
{
    public class MyComponent : BlazorComponent
    {
        [Parameter] string Name { get; set; }
    }
}
"));

            // Act
            var generated = CompileToCSharp(@"
@addTagHelper ""*, TestAssembly""
@{
    RenderFragment<Person> p = (person) => @<div><MyComponent Name=""@person.Name""/></div>;
}
<MyComponent>
@(""hello, world!"")
</MyComponent>

@functions {
    class Person
    {
        public string Name { get; set; }
    }
}");

            // Assert
            AssertDocumentNodeMatchesBaseline(generated.CodeDocument);
            AssertCSharpDocumentMatchesBaseline(generated.CodeDocument);
            CompileToAssembly(generated);
        }
Ejemplo n.º 16
0
        [Fact] // https://github.com/aspnet/Blazor/issues/772
        public void Regression_772()
        {
            // Arrange
            AdditionalSyntaxTrees.Add(Parse(@"
using Microsoft.AspNetCore.Blazor.Components;

namespace Test
{
    public class SurveyPrompt : BlazorComponent
    {
        [Parameter] private string Title { get; set; }
    }
}
"));

            // Act
            var generated = CompileToCSharp(@"
@addTagHelper *, TestAssembly
@page ""/""

<h1>Hello, world!</h1>

Welcome to your new app.

<SurveyPrompt Title=""
");

            // Assert
            AssertDocumentNodeMatchesBaseline(generated.CodeDocument);
            AssertCSharpDocumentMatchesBaseline(generated.CodeDocument);

            // This has some errors
            Assert.Collection(
                generated.Diagnostics.OrderBy(d => d.Id),
                d => Assert.Equal("RZ1034", d.Id),
                d => Assert.Equal("RZ1035", d.Id));
        }
        private IReadOnlyList <TagHelperDescriptor> GetComponents()
        {
            AdditionalSyntaxTrees.Add(Parse(@"
using Microsoft.AspNetCore.Components;
namespace Test
{
    public class Counter : ComponentBase
    {
        [Parameter]
        public int IncrementAmount { get; set; }
    }

    public class GridTable : ComponentBase
    {
        [Parameter]
        public RenderFragment ChildContent { get; set; }
    }

    public class GridRow : ComponentBase
    {
        [Parameter]
        public RenderFragment ChildContent { get; set; }
    }

    public class GridCell : ComponentBase
    {
        [Parameter]
        public RenderFragment ChildContent { get; set; }
    }
}
"));

            var generated  = CompileToCSharp("Test.razor", string.Empty, throwOnFailure: false, fileKind: FileKinds.Component);
            var tagHelpers = generated.CodeDocument.GetTagHelperContext().TagHelpers;

            return(tagHelpers);
        }
        public void Render_GenericComponent_TypeInference_WithRef_Recursive()
        {
            // Arrange
            AdditionalSyntaxTrees.Add(GenericContextComponent);

            var assembly = CompileToAssembly("Test.cshtml", @"
@addTagHelper *, TestAssembly
@typeparam TItem
<GenericContext Items=""@MyItems"" ref=""_my"" />

@functions {
    [Parameter] List<TItem> MyItems { get; set; }
    GenericContext<TItem> _my;
    void Foo() { GC.KeepAlive(_my); }
}");

            var componentType = assembly.Assembly.DefinedTypes
                                .Where(t => t.Name == "Test`1")
                                .Single()
                                .MakeGenericType(typeof(int));
            var component = (IComponent)Activator.CreateInstance(componentType);

            // Act
            var frames = GetRenderTree(component);

            // Assert
            var genericComponentType = assembly.Assembly.DefinedTypes
                                       .Where(t => t.Name == "GenericContext`1")
                                       .Single()
                                       .MakeGenericType(typeof(int));

            Assert.Collection(
                frames,
                frame => AssertFrame.Component(frame, genericComponentType.FullName, 3, 0),
                frame => AssertFrame.Attribute(frame, "Items", 1),
                frame => AssertFrame.ComponentReferenceCapture(frame, 2));
        }
Ejemplo n.º 19
0
        public void Render_BindToComponent_SpecifiesValueAndChangeEvent_WithMatchingProperties()
        {
            // Arrange
            AdditionalSyntaxTrees.Add(Parse(@"
using System;
using Microsoft.AspNetCore.Blazor.Components;

namespace Test
{
    public class MyComponent : BlazorComponent
    {
        [Parameter]
        int Value { get; set; }

        [Parameter]
        Action<int> OnChanged { get; set; }
    }
}"));

            var component = CompileToComponent(@"
@addTagHelper *, TestAssembly
<MyComponent bind-Value-OnChanged=""ParentValue"" />
@functions {
    public int ParentValue { get; set; } = 42;
}");

            // Act
            var frames = GetRenderTree(component);

            // Assert
            Assert.Collection(
                frames,
                frame => AssertFrame.Component(frame, "Test.MyComponent", 3, 0),
                frame => AssertFrame.Attribute(frame, "Value", 42, 1),
                frame => AssertFrame.Attribute(frame, "OnChanged", typeof(Action <int>), 2));
        }
Ejemplo n.º 20
0
        public void ChildComponent_WithParameters()
        {
            // Arrange
            AdditionalSyntaxTrees.Add(Parse(@"
using Microsoft.AspNetCore.Blazor.Components;

namespace Test
{
    public class SomeType
    {
    }

    public class MyComponent : BlazorComponent
    {
        [Parameter] int IntProperty { get; set; }
        [Parameter] bool BoolProperty { get; set; }
        [Parameter] string StringProperty { get; set; }
        [Parameter] SomeType ObjectProperty { get; set; }
    }
}
"));

            // Act
            var generated = CompileToCSharp(@"
@addTagHelper *, TestAssembly
<MyComponent 
    IntProperty=""123""
    BoolProperty=""true""
    StringProperty=""My string""
    ObjectProperty=""new SomeType()""/>");

            // Assert
            AssertDocumentNodeMatchesBaseline(generated.CodeDocument);
            AssertCSharpDocumentMatchesBaseline(generated.CodeDocument);
            CompileToAssembly(generated);
        }
Ejemplo n.º 21
0
        public void ChildComponent_WithNonPropertyAttributes()
        {
            // Arrange
            AdditionalSyntaxTrees.Add(Parse(@"
using Microsoft.AspNetCore.Blazor.Components;

namespace Test
{
    public class MyComponent : BlazorComponent
    {
    }
}
"));

            // Act
            var generated = CompileToCSharp(@"
@addTagHelper *, TestAssembly
<MyComponent some-attribute=""foo"" another-attribute=""@(43.ToString())""/>");

            // Assert
            AssertDocumentNodeMatchesBaseline(generated.CodeDocument);
            AssertCSharpDocumentMatchesBaseline(generated.CodeDocument);
            CompileToAssembly(generated);
        }
        public void Render_GenericComponent_WithoutChildContent()
        {
            // Arrange
            AdditionalSyntaxTrees.Add(GenericContextComponent);

            var component = CompileToComponent(@"
<GenericContext TItem=int Items=""@(new List<int>() { 1, 2, })"" />");

            // Act
            var frames = GetRenderTree(component);

            // Assert
            var genericComponentType = component.GetType().Assembly.DefinedTypes
                                       .Where(t => t.Name == "GenericContext`1")
                                       .Single()
                                       .MakeGenericType(typeof(int));

            Assert.Collection(
                frames,
                frame => AssertFrame.Component(frame, genericComponentType.FullName, 2, 0),
                frame => AssertFrame.Attribute(frame, "Items", typeof(List <int>), 1),
                frame => AssertFrame.Text(frame, "1", 0),
                frame => AssertFrame.Text(frame, "2", 1));
        }
Ejemplo n.º 23
0
        public void ChildComponent_WithExplicitEventHandler()
        {
            // Arrange
            AdditionalSyntaxTrees.Add(Parse(@"
using System;
using Microsoft.AspNetCore.Blazor;
using Microsoft.AspNetCore.Blazor.Components;

namespace Test
{
    public class MyComponent : BlazorComponent
    {
        [Parameter]
        Action<UIEventArgs> OnClick { get; set; }
    }
}
"));

            // Act
            var generated = CompileToCSharp(@"
@addTagHelper *, TestAssembly
@using Microsoft.AspNetCore.Blazor
<MyComponent OnClick=""@Increment""/>

@functions {
    private int counter;
    private void Increment(UIEventArgs e) {
        counter++;
    }
}");

            // Assert
            AssertDocumentNodeMatchesBaseline(generated.CodeDocument);
            AssertCSharpDocumentMatchesBaseline(generated.CodeDocument);
            CompileToAssembly(generated);
        }
        public void Component_StartAndEndTagCaseMismatch_ReportsError()
        {
            // Arrange & Act
            AdditionalSyntaxTrees.Add(Parse(@"
using Microsoft.AspNetCore.Components;

namespace Test
{
    public class MyComponent : ComponentBase
    {
    }
}
"));
            var generated = CompileToCSharp(@"
<MyComponent></mycomponent>");

            // Assert
            var diagnostic = Assert.Single(generated.Diagnostics);

            Assert.Equal("RZ10013", diagnostic.Id);
            Assert.Equal(
                "The start tag name 'MyComponent' does not match the end tag name 'mycomponent'. Components must have matching start and end tag names (case-sensitive).",
                diagnostic.GetMessage(CultureInfo.CurrentCulture));
        }
Ejemplo n.º 25
0
        public void ChildComponent_Simple()
        {
            // Arrange
            AdditionalSyntaxTrees.Add(Parse(@"
using Microsoft.AspNetCore.Blazor.Components;

namespace Test
{
    public class MyComponent : BlazorComponent
    {
    }
}
"));

            // Act
            var generated = CompileToCSharp(@"
@addTagHelper *, TestAssembly
<MyComponent />");

            // Assert
            AssertDocumentNodeMatchesBaseline(generated.CodeDocument);
            AssertCSharpDocumentMatchesBaseline(generated.CodeDocument);
            CompileToAssembly(generated);
        }
Ejemplo n.º 26
0
        public void Render_BindToComponent_SpecifiesValue_WithoutMatchingProperties()
        {
            // Arrange
            AdditionalSyntaxTrees.Add(Parse(@"
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;

namespace Test
{
    public class MyComponent : ComponentBase, IComponent
    {
        Task IComponent.SetParametersAsync(ParameterCollection parameters)
        {
            return Task.CompletedTask;
        }
    }
}"));

            var component = CompileToComponent(@"
@addTagHelper *, TestAssembly
<MyComponent bind-Value=""ParentValue"" />
@functions {
    public int ParentValue { get; set; } = 42;
}");

            // Act
            var frames = GetRenderTree(component);

            // Assert
            Assert.Collection(
                frames,
                frame => AssertFrame.Component(frame, "Test.MyComponent", 3, 0),
                frame => AssertFrame.Attribute(frame, "Value", 42, 1),
                frame => AssertFrame.Attribute(frame, "ValueChanged", typeof(EventCallback <UIChangeEventArgs>), 2));
        }
Ejemplo n.º 27
0
        public void Render_BodyChildContent_Generic()
        {
            // Arrange
            AdditionalSyntaxTrees.Add(RenderChildContentStringComponent);

            var component = CompileToComponent(@"
<RenderChildContentString Value=""HI"">
  <div>@context.ToLowerInvariant()</div>
</RenderChildContentString>");

            // Act
            var frames = GetRenderTree(component);

            // Assert
            Assert.Collection(
                frames,
                frame => AssertFrame.Component(frame, "Test.RenderChildContentString", 3, 0),
                frame => AssertFrame.Attribute(frame, "Value", "HI", 1),
                frame => AssertFrame.Attribute(frame, "ChildContent", 2),
                frame => AssertFrame.MarkupWhitespace(frame, 3),
                frame => AssertFrame.Element(frame, "div", 2, 4),
                frame => AssertFrame.Text(frame, "hi", 5),
                frame => AssertFrame.MarkupWhitespace(frame, 6));
        }
        protected CompileToCSharpResult CompileToCSharp(string cshtmlRelativePath, string cshtmlContent, bool throwOnFailure = true, string fileKind = null)
        {
            if (DeclarationOnly && DesignTime)
            {
                throw new InvalidOperationException($"{nameof(DeclarationOnly)} cannot be used with {nameof(DesignTime)}.");
            }

            if (DeclarationOnly && UseTwoPhaseCompilation)
            {
                throw new InvalidOperationException($"{nameof(DeclarationOnly)} cannot be used with {nameof(UseTwoPhaseCompilation)}.");
            }

            if (UseTwoPhaseCompilation)
            {
                // The first phase won't include any metadata references for component discovery. This mirrors
                // what the build does.
                var projectEngine = CreateProjectEngine(RazorConfiguration.Default, Array.Empty <MetadataReference>());

                RazorCodeDocument codeDocument;
                foreach (var item in AdditionalRazorItems)
                {
                    // Result of generating declarations
                    codeDocument = projectEngine.ProcessDeclarationOnly(item);
                    Assert.Empty(codeDocument.GetCSharpDocument().Diagnostics);

                    var syntaxTree = Parse(codeDocument.GetCSharpDocument().GeneratedCode, path: item.FilePath);
                    AdditionalSyntaxTrees.Add(syntaxTree);
                }

                // Result of generating declarations
                var projectItem = CreateProjectItem(cshtmlRelativePath, cshtmlContent, fileKind);
                codeDocument = projectEngine.ProcessDeclarationOnly(projectItem);
                var declaration = new CompileToCSharpResult
                {
                    BaseCompilation = BaseCompilation.AddSyntaxTrees(AdditionalSyntaxTrees),
                    CodeDocument    = codeDocument,
                    Code            = codeDocument.GetCSharpDocument().GeneratedCode,
                    Diagnostics     = codeDocument.GetCSharpDocument().Diagnostics,
                };

                // Result of doing 'temp' compilation
                var tempAssembly = CompileToAssembly(declaration, throwOnFailure);

                // Add the 'temp' compilation as a metadata reference
                var references = BaseCompilation.References.Concat(new[] { tempAssembly.Compilation.ToMetadataReference() }).ToArray();
                projectEngine = CreateProjectEngine(RazorConfiguration.Default, references);

                // Now update the any additional files
                foreach (var item in AdditionalRazorItems)
                {
                    // Result of generating definition
                    codeDocument = DesignTime ? projectEngine.ProcessDesignTime(item) : projectEngine.Process(item);
                    Assert.Empty(codeDocument.GetCSharpDocument().Diagnostics);

                    // Replace the 'declaration' syntax tree
                    var syntaxTree = Parse(codeDocument.GetCSharpDocument().GeneratedCode, path: item.FilePath);
                    AdditionalSyntaxTrees.RemoveAll(st => st.FilePath == item.FilePath);
                    AdditionalSyntaxTrees.Add(syntaxTree);
                }

                // Result of real code generation for the document under test
                codeDocument = DesignTime ? projectEngine.ProcessDesignTime(projectItem) : projectEngine.Process(projectItem);
                return(new CompileToCSharpResult
                {
                    BaseCompilation = BaseCompilation.AddSyntaxTrees(AdditionalSyntaxTrees),
                    CodeDocument = codeDocument,
                    Code = codeDocument.GetCSharpDocument().GeneratedCode,
                    Diagnostics = codeDocument.GetCSharpDocument().Diagnostics,
                });
            }
            else
            {
                // For single phase compilation tests just use the base compilation's references.
                // This will include the built-in components.
                var projectEngine = CreateProjectEngine(Configuration, BaseCompilation.References.ToArray());

                var projectItem = CreateProjectItem(cshtmlRelativePath, cshtmlContent, fileKind);

                RazorCodeDocument codeDocument;
                if (DeclarationOnly)
                {
                    codeDocument = projectEngine.ProcessDeclarationOnly(projectItem);
                }
                else
                {
                    codeDocument = DesignTime ? projectEngine.ProcessDesignTime(projectItem) : projectEngine.Process(projectItem);
                }

                return(new CompileToCSharpResult
                {
                    BaseCompilation = BaseCompilation.AddSyntaxTrees(AdditionalSyntaxTrees),
                    CodeDocument = codeDocument,
                    Code = codeDocument.GetCSharpDocument().GeneratedCode,
                    Diagnostics = codeDocument.GetCSharpDocument().Diagnostics,
                });
            }
        }
Ejemplo n.º 29
0
        public void Render_HtmlBlock_Integration()
        {
            // Arrange
            AdditionalSyntaxTrees.Add(Parse(@"
using Microsoft.AspNetCore.Components;
namespace Test
{
    public class MyComponent : ComponentBase
    {
        [Parameter]
        public RenderFragment ChildContent { get; set; }
    }
}
"));

            var component = CompileToComponent(@"
<html>
  <head><meta><meta></head>
  <body>
    <MyComponent>
      <div><span></span><span></span></div>
      <div>@(""hi"")</div>
      <div><span></span><span></span></div>
      <div></div>
      <div>@(""hi"")</div>
      <div></div>
  </MyComponent>
  </body>
</html>");

            // Act
            var frames = GetRenderTree(component);

            // Assert: component frames are correct
            Assert.Collection(
                frames,
                frame => AssertFrame.Element(frame, "html", 9, 0),
                frame => AssertFrame.MarkupWhitespace(frame, 1),
                frame => AssertFrame.Markup(frame, "<head><meta><meta></head>\n  ", 2),
                frame => AssertFrame.Element(frame, "body", 5, 3),
                frame => AssertFrame.MarkupWhitespace(frame, 4),
                frame => AssertFrame.Component(frame, "Test.MyComponent", 2, 5),
                frame => AssertFrame.Attribute(frame, "ChildContent", 6),
                frame => AssertFrame.MarkupWhitespace(frame, 16),
                frame => AssertFrame.MarkupWhitespace(frame, 17));

            // Assert: Captured ChildContent frames are correct
            var childFrames = GetFrames((RenderFragment)frames[6].AttributeValue);

            Assert.Collection(
                childFrames.AsEnumerable(),
                frame => AssertFrame.MarkupWhitespace(frame, 7),
                frame => AssertFrame.Markup(frame, "<div><span></span><span></span></div>\n      ", 8),
                frame => AssertFrame.Element(frame, "div", 2, 9),
                frame => AssertFrame.Text(frame, "hi", 10),
                frame => AssertFrame.MarkupWhitespace(frame, 11),
                frame => AssertFrame.Markup(frame, "<div><span></span><span></span></div>\n      <div></div>\n      ", 12),
                frame => AssertFrame.Element(frame, "div", 2, 13),
                frame => AssertFrame.Text(frame, "hi", 14),
                frame => AssertFrame.Markup(frame, "\n      <div></div>\n  ", 15));
        }
Ejemplo n.º 30
0
        protected CompileToCSharpResult CompileToCSharp(string cshtmlRelativePath, string cshtmlContent)
        {
            if (UseTwoPhaseCompilation)
            {
                // The first phase won't include any metadata references for component discovery. This mirrors
                // what the build does.
                var projectEngine = CreateProjectEngine(Array.Empty <MetadataReference>());

                RazorCodeDocument codeDocument;
                foreach (var item in AdditionalRazorItems)
                {
                    // Result of generating declarations
                    codeDocument = projectEngine.ProcessDeclarationOnly(item);
                    Assert.Empty(codeDocument.GetCSharpDocument().Diagnostics);

                    var syntaxTree = Parse(codeDocument.GetCSharpDocument().GeneratedCode, path: item.FilePath);
                    AdditionalSyntaxTrees.Add(syntaxTree);
                }

                // Result of generating declarations
                var projectItem = CreateProjectItem(cshtmlRelativePath, cshtmlContent);
                codeDocument = projectEngine.ProcessDeclarationOnly(projectItem);
                var declaration = new CompileToCSharpResult
                {
                    BaseCompilation = BaseCompilation.AddSyntaxTrees(AdditionalSyntaxTrees),
                    CodeDocument    = codeDocument,
                    Code            = codeDocument.GetCSharpDocument().GeneratedCode,
                    Diagnostics     = codeDocument.GetCSharpDocument().Diagnostics,
                };

                // Result of doing 'temp' compilation
                var tempAssembly = CompileToAssembly(declaration);

                // Add the 'temp' compilation as a metadata reference
                var references = BaseCompilation.References.Concat(new[] { tempAssembly.Compilation.ToMetadataReference() }).ToArray();
                projectEngine = CreateProjectEngine(references);

                // Now update the any additional files
                foreach (var item in AdditionalRazorItems)
                {
                    // Result of generating declarations
                    codeDocument = DesignTime ? projectEngine.ProcessDesignTime(item) : projectEngine.Process(item);
                    Assert.Empty(codeDocument.GetCSharpDocument().Diagnostics);

                    // Replace the 'declaration' syntax tree
                    var syntaxTree = Parse(codeDocument.GetCSharpDocument().GeneratedCode, path: item.FilePath);
                    AdditionalSyntaxTrees.RemoveAll(st => st.FilePath == item.FilePath);
                    AdditionalSyntaxTrees.Add(syntaxTree);
                }

                // Result of real code generation for the document under test
                codeDocument = DesignTime ? projectEngine.ProcessDesignTime(projectItem) : projectEngine.Process(projectItem);

                _output.Value.WriteLine("Use this output when opening an issue");
                _output.Value.WriteLine(string.Empty);

                _output.Value.WriteLine($"## Main source file ({projectItem.FileKind}):");
                _output.Value.WriteLine("```");
                _output.Value.WriteLine(ReadProjectItem(projectItem));
                _output.Value.WriteLine("```");
                _output.Value.WriteLine(string.Empty);

                foreach (var item in AdditionalRazorItems)
                {
                    _output.Value.WriteLine($"### Additional source file ({item.FileKind}):");
                    _output.Value.WriteLine("```");
                    _output.Value.WriteLine(ReadProjectItem(item));
                    _output.Value.WriteLine("```");
                    _output.Value.WriteLine(string.Empty);
                }

                _output.Value.WriteLine("## Generated C#:");
                _output.Value.WriteLine("```C#");
                _output.Value.WriteLine(codeDocument.GetCSharpDocument().GeneratedCode);
                _output.Value.WriteLine("```");

                return(new CompileToCSharpResult
                {
                    BaseCompilation = BaseCompilation.AddSyntaxTrees(AdditionalSyntaxTrees),
                    CodeDocument = codeDocument,
                    Code = codeDocument.GetCSharpDocument().GeneratedCode,
                    Diagnostics = codeDocument.GetCSharpDocument().Diagnostics,
                });
            }
            else
            {
                // For single phase compilation tests just use the base compilation's references.
                // This will include the built-in Blazor components.
                var projectEngine = CreateProjectEngine(BaseCompilation.References.ToArray());

                var projectItem  = CreateProjectItem(cshtmlRelativePath, cshtmlContent);
                var codeDocument = DesignTime ? projectEngine.ProcessDesignTime(projectItem) : projectEngine.Process(projectItem);

                // Log the generated code for test results.
                _output.Value.WriteLine("Use this output when opening an issue");
                _output.Value.WriteLine(string.Empty);

                _output.Value.WriteLine($"## Main source file ({projectItem.FileKind}):");
                _output.Value.WriteLine("```");
                _output.Value.WriteLine(ReadProjectItem(projectItem));
                _output.Value.WriteLine("```");
                _output.Value.WriteLine(string.Empty);

                _output.Value.WriteLine("## Generated C#:");
                _output.Value.WriteLine("```C#");
                _output.Value.WriteLine(codeDocument.GetCSharpDocument().GeneratedCode);
                _output.Value.WriteLine("```");

                return(new CompileToCSharpResult
                {
                    BaseCompilation = BaseCompilation.AddSyntaxTrees(AdditionalSyntaxTrees),
                    CodeDocument = codeDocument,
                    Code = codeDocument.GetCSharpDocument().GeneratedCode,
                    Diagnostics = codeDocument.GetCSharpDocument().Diagnostics,
                });
            }
        }