Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ @inject PropertyType PropertyName
Assert.Equal("PropertyType", node.TypeName);
Assert.Equal("PropertyName", node.MemberName);
}

[Fact]
public void InjectDirectivePass_Execute_DedupesPropertiesByName()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,94 @@ public class MyApp
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
}


[Fact]
public void InjectWithKey_Runtime()
{
// Arrange
AddCSharpSyntaxTree("""

public class MyModel
{

}

public class MyService<TModel>
{
public string Html { get; set; }
}

public class MyApp
{
public string MyProperty { get; set; }
}
""");

var projectItem = CreateProjectItemFromFile();

// Act
var compiled = CompileToAssembly(projectItem, designTime: false);

// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentNode());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertLinePragmas(compiled.CodeDocument);
}




[Fact]
public void MixKeyedInject_Runtime()
{
// Arrange
AddCSharpSyntaxTree("""

public class MyModel
{

}

public class MyService<TModel>
{
public string Html { get; set; }
}

public class MyApp
{
public string MyProperty { get; set; }
}
""");

var projectItem = CreateProjectItemFromFile();

// Act
var compiled = CompileToAssembly(projectItem, designTime: false);

// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentNode());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertLinePragmas(compiled.CodeDocument);
}

[Fact]
public void MalformedKeyedInject_Runtime()
{
// Arrange
var projectItem = CreateProjectItemFromFile();

// Act
var compiled = CompileToCSharp(projectItem, designTime: false);

// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentNode());
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertLinePragmas(compiled.CodeDocument);

var diagnotics = compiled.CodeDocument.GetCSharpDocument().Diagnostics;
Assert.Equal("RZ1016", Assert.Single(diagnotics).Id);
}

[Fact]
public void InjectWithSemicolon_Runtime()
{
Expand Down Expand Up @@ -1255,6 +1343,96 @@ public class MyApp
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
}


[Fact]
public void InjectWithKey_DesignTime()
{
// Arrange
AddCSharpSyntaxTree("""

public class MyModel
{

}

public class MyService<TModel>
{
public string Html { get; set; }
}

public class MyApp
{
public string MyProperty { get; set; }
}
""");

var projectItem = CreateProjectItemFromFile();

// Act
var compiled = CompileToAssembly(projectItem, designTime: true);

// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentNode());
AssertHtmlDocumentMatchesBaseline(RazorHtmlWriter.GetHtmlDocument(compiled.CodeDocument));
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertLinePragmas(compiled.CodeDocument);
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
}

[Fact]
public void MalformedKeyedInject_DesignTime()
{
// Arrange
var projectItem = CreateProjectItemFromFile();

// Act
var compiled = CompileToCSharp(projectItem, designTime: true);

// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentNode());
AssertHtmlDocumentMatchesBaseline(RazorHtmlWriter.GetHtmlDocument(compiled.CodeDocument));
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertLinePragmas(compiled.CodeDocument);
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);

var diagnotics = compiled.CodeDocument.GetCSharpDocument().Diagnostics;
Assert.Equal("RZ1016", Assert.Single(diagnotics).Id);
}

[Fact]
public void MixKeyedInject_DesignTime()
{
// Arrange
AddCSharpSyntaxTree("""

public class MyModel
{

}

public class MyService<TModel>
{
public string Html { get; set; }
}

public class MyApp
{
public string MyProperty { get; set; }
}
""");

var projectItem = CreateProjectItemFromFile();

// Act
var compiled = CompileToAssembly(projectItem, designTime: true);

// Assert
AssertDocumentNodeMatchesBaseline(compiled.CodeDocument.GetDocumentNode());
AssertHtmlDocumentMatchesBaseline(RazorHtmlWriter.GetHtmlDocument(compiled.CodeDocument));
AssertCSharpDocumentMatchesBaseline(compiled.CodeDocument.GetCSharpDocument());
AssertLinePragmas(compiled.CodeDocument);
AssertSourceMappingsMatchBaseline(compiled.CodeDocument);
}
[Fact]
public void InjectWithSemicolon_DesignTime()
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Microsoft.AspNetCore.Razor.Language;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
using Xunit;

namespace Microsoft.AspNetCore.Mvc.Razor.Extensions;

public class KeyedInjectDirectiveTest : RazorProjectEngineTestBase
{
protected override RazorLanguageVersion Version => RazorLanguageVersion.Version_3_0;

protected override void ConfigureProjectEngine(RazorProjectEngineBuilder builder)
{
// Notice we're not registering the InjectDirective.Pass here so we can run it on demand.
builder.AddDirective(InjectDirective.Directive);
builder.AddDirective(KeyedInjectDirective.Directive);
builder.AddDirective(ModelDirective.Directive);

builder.Features.Add(new RazorPageDocumentClassifierPass());
builder.Features.Add(new MvcViewDocumentClassifierPass());
}

protected override void ConfigureCodeDocumentProcessor(RazorCodeDocumentProcessor processor)
{
processor.ExecutePhasesThrough<IRazorDocumentClassifierPhase>();
}

[Fact]
public void KeyedInjectDirectivePass_Execute_DefinesProperty()
{
// Arrange
var codeDocument = ProjectEngine.CreateCodeDocument(@"
@keyedinject PropertyType PropertyName ""PropertyKey""
");
var processor = CreateCodeDocumentProcessor(codeDocument);

// Act
processor.ExecutePass<KeyedInjectDirective.Pass>();

// Assert
var documentNode = processor.GetDocumentNode();
var classNode = documentNode.GetClassNode();

Assert.Equal(2, classNode.Children.Count);

var node = Assert.IsType<KeyedInjectIntermediateNode>(classNode.Children[1]);
Assert.Equal("PropertyType", node.TypeName);
Assert.Equal("PropertyName", node.MemberName);
Assert.Equal("\"PropertyKey\"", node.KeyName);
}

[Fact]
public void KeyedInjectDirectivePass_Execute_DedupesPropertiesByName()
{
// Arrange
var codeDocument = ProjectEngine.CreateCodeDocument(@"
@keyedinject PropertyType PropertyName ""SomeKey""
@keyedinject PropertyType2 PropertyName ""SomeKey2""
");
var processor = CreateCodeDocumentProcessor(codeDocument);

// Act
processor.ExecutePass<KeyedInjectDirective.Pass>();

// Assert
var documentNode = processor.GetDocumentNode();
var classNode = documentNode.GetClassNode();

Assert.Equal(2, classNode.Children.Count);

var node = Assert.IsType<KeyedInjectIntermediateNode>(classNode.Children[1]);
Assert.Equal("PropertyType2", node.TypeName);
Assert.Equal("PropertyName", node.MemberName);
Assert.Equal("\"SomeKey2\"", node.KeyName);
}

[Fact]
public void KeyedInjectDirectivePass_Execute_ExpandsTModel_WithDynamic()
{
// Arrange
var codeDocument = ProjectEngine.CreateCodeDocument(@"
@keyedinject PropertyType<TModel> PropertyName ""SomeKey""
");
var processor = CreateCodeDocumentProcessor(codeDocument);

// Act
processor.ExecutePass<KeyedInjectDirective.Pass>();

// Assert
var documentNode = processor.GetDocumentNode();
var classNode = documentNode.GetClassNode();

Assert.Equal(2, classNode.Children.Count);

var node = Assert.IsType<KeyedInjectIntermediateNode>(classNode.Children[1]);
Assert.Equal("PropertyType<dynamic>", node.TypeName);
Assert.Equal("PropertyName", node.MemberName);
Assert.Equal("\"SomeKey\"", node.KeyName);
}

[Fact]
public void KeyedInjectDirectivePass_Execute_ExpandsTModel_WithModelTypeFirst()
{
// Arrange
var codeDocument = ProjectEngine.CreateCodeDocument(@"
@model ModelType
@keyedinject PropertyType<TModel> PropertyName ""SomeKey""
");
var processor = CreateCodeDocumentProcessor(codeDocument);

// Act
processor.ExecutePass<KeyedInjectDirective.Pass>();

// Assert
var documentNode = processor.GetDocumentNode();
var classNode = documentNode.GetClassNode();

Assert.Equal(2, classNode.Children.Count);

var node = Assert.IsType<KeyedInjectIntermediateNode>(classNode.Children[1]);
Assert.Equal("PropertyType<ModelType>", node.TypeName);
Assert.Equal("PropertyName", node.MemberName);
Assert.Equal("\"SomeKey\"", node.KeyName);
}

[Fact]
public void KeyedInjectDirectivePass_Execute_ExpandsTModel_WithModelType()
{
// Arrange
var codeDocument = ProjectEngine.CreateCodeDocument(@"
@keyedinject PropertyType<TModel> PropertyName ""SomeKey""
@model ModelType
");
var processor = CreateCodeDocumentProcessor(codeDocument);

// Act
processor.ExecutePass<KeyedInjectDirective.Pass>();

// Assert
var documentNode = processor.GetDocumentNode();
var classNode = documentNode.GetClassNode();

Assert.Equal(2, classNode.Children.Count);

var node = Assert.IsType<KeyedInjectIntermediateNode>(classNode.Children[1]);
Assert.Equal("PropertyType<ModelType>", node.TypeName);
Assert.Equal("PropertyName", node.MemberName);
Assert.Equal("\"SomeKey\"", node.KeyName);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#nullable disable

using System;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.AspNetCore.Razor.Language.CodeGeneration;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
using Microsoft.AspNetCore.Razor.Language.Legacy;
using Xunit;

namespace Microsoft.AspNetCore.Mvc.Razor.Extensions;

public class KeyedInjectTargetExtensionTest
{

[Fact]
public void KeyedInjectDirectiveTargetExtension_WritesProperty()
{
// Arrange
using var context = TestCodeRenderingContext.CreateRuntime();
var target = new KeyedInjectTargetExtension(considerNullabilityEnforcement: true);
var node = new KeyedInjectIntermediateNode()
{
TypeName = "PropertyType",
MemberName = "PropertyName",
KeyName = "\"PropertyKey\"",
};

// Act
target.WriteKeyedInjectProperty(context, node);

// Assert
Assert.Equal("""
#nullable restore
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute(Key = "PropertyKey")]
public PropertyType PropertyName { get; private set; } = default!;
#nullable disable

""",
context.CodeWriter.GetText().ToString());
}

}
Loading
Loading