public void Visit_GeneratesProperties_ForInjectChunks() { // Arrange var expected = @"[ActivateAttribute] public MyType1 MyPropertyName1 { get; private set; } [ActivateAttribute] public MyType2 @MyPropertyName2 { get; private set; } "; var writer = new CSharpCodeWriter(); var context = CreateContext(); var visitor = new InjectChunkVisitor(writer, context, "ActivateAttribute"); var factory = SpanFactory.CreateCsHtml(); var node = (Span)factory.Code("Some code") .As(new InjectParameterGenerator("MyType", "MyPropertyName")); // Act visitor.Accept(new Chunk[] { new LiteralChunk(), new InjectChunk("MyType1", "MyPropertyName1") { Association = node }, new InjectChunk("MyType2", "@MyPropertyName2") { Association = node } }); var code = writer.GenerateCode(); // Assert Assert.Equal(expected, code); }
public void ParseModelKeyword_InfersBaseType_FromModelName( string modelName, string expectedModel) { // Arrange var documentContent = "@model " + modelName + Environment.NewLine + "Bar"; var factory = SpanFactory.CreateCsHtml(); var errors = new List <RazorError>(); var expectedSpans = new Span[] { factory.EmptyHtml(), factory.CodeTransition(SyntaxConstants.TransitionString) .Accepts(AcceptedCharacters.None), factory.MetaCode("model ") .Accepts(AcceptedCharacters.None), factory.Code(modelName + Environment.NewLine) .As(new ModelChunkGenerator(expectedModel)) .Accepts(AcceptedCharacters.AnyExceptNewline), factory.Markup("Bar") .With(new MarkupChunkGenerator()) }; // Act var spans = ParseDocument(documentContent, errors); // Assert Assert.Equal(expectedSpans, spans); Assert.Empty(errors); }
public void ParseModelKeyword_ErrorOnMissingModelType() { // Arrange + Act var errors = new List <RazorError>(); var document = "@model "; var spans = ParseDocument(document, errors); // Assert var factory = SpanFactory.CreateCsHtml(); var expectedSpans = new Span[] { factory.EmptyHtml(), factory.CodeTransition(SyntaxConstants.TransitionString) .Accepts(AcceptedCharacters.None), factory.MetaCode("model ") .Accepts(AcceptedCharacters.None), factory.Code(" ") .As(new ModelChunkGenerator(string.Empty)) .Accepts(AcceptedCharacters.AnyExceptNewline), factory.EmptyHtml(), }; var expectedErrors = new[] { new RazorError("The 'model' keyword must be followed by a type name on the same line.", new SourceLocation(1, 0, 1), 5) }; Assert.Equal(expectedSpans, spans); Assert.Equal(expectedErrors, errors); }
public void ParseInjectKeyword_ErrorOnMissingPropertyName_WhenTypeNameEndsWithEOF() { // Arrange var errors = new List <RazorError>(); var documentContent = "@inject IMyServi"; var factory = SpanFactory.CreateCsHtml(); var expectedSpans = new Span[] { factory.EmptyHtml(), factory.CodeTransition(SyntaxConstants.TransitionString) .Accepts(AcceptedCharacters.None), factory.MetaCode("inject ") .Accepts(AcceptedCharacters.None), factory.Code(" IMyServi") .As(new InjectParameterGenerator("IMyServi", string.Empty)) .Accepts(AcceptedCharacters.AnyExceptNewline), factory.EmptyHtml() }; var expectedErrors = new[] { new RazorError("A property name must be specified when using the 'inject' statement. " + "Format for a 'inject' statement is '@inject <Type Name> <Property Name>'.", new SourceLocation(1, 0, 1), 21) }; // Act var spans = ParseDocument(documentContent, errors); // Assert Assert.Equal(expectedSpans, spans); Assert.Equal(expectedErrors, errors); }
public void ParseInjectKeyword_ErrorOnMissingTypeName_WhenTypeNameEndsWithEOF() { // Arrange var errors = new List <RazorError>(); var documentContent = "@inject "; var factory = SpanFactory.CreateCsHtml(); var expectedSpans = new Span[] { factory.EmptyHtml(), factory.CodeTransition(SyntaxConstants.TransitionString) .Accepts(AcceptedCharacters.None), factory.MetaCode("inject ") .Accepts(AcceptedCharacters.None), factory.Code(" ") .As(new InjectParameterGenerator(string.Empty, string.Empty)) .Accepts(AcceptedCharacters.AnyExceptNewline), factory.EmptyHtml() }; var expectedErrors = new[] { new RazorError("The 'inject' keyword must be followed by a type name on the same line.", new SourceLocation(1, 0, 1), 6) }; // Act var spans = ParseDocument(documentContent, errors); // Assert Assert.Equal(expectedSpans, spans); Assert.Equal(expectedErrors, errors); }
public void ParseInjectKeyword_ParsesUpToNewLine( string injectStatement, string expectedService, string expectedPropertyName) { // Arrange var documentContent = "@inject " + injectStatement + Environment.NewLine + "Bar"; var factory = SpanFactory.CreateCsHtml(); var errors = new List <RazorError>(); var expectedSpans = new Span[] { factory.EmptyHtml(), factory.CodeTransition(SyntaxConstants.TransitionString) .Accepts(AcceptedCharacters.None), factory.MetaCode("inject ") .Accepts(AcceptedCharacters.None), factory.Code(injectStatement + Environment.NewLine) .As(new InjectParameterGenerator(expectedService, expectedPropertyName)) .Accepts(AcceptedCharacters.AnyExceptNewline), factory.Markup("Bar") .With(new MarkupChunkGenerator()) }; // Act var spans = ParseDocument(documentContent, errors); // Assert Assert.Equal(expectedSpans, spans); Assert.Empty(errors); }
public void ParseModelKeyword_HandlesSingleInstance() { // Arrange var document = "@model Foo"; var factory = SpanFactory.CreateCsHtml(); var errors = new List <RazorError>(); var expectedSpans = new Span[] { factory.EmptyHtml(), factory.CodeTransition(SyntaxConstants.TransitionString) .Accepts(AcceptedCharacters.None), factory.MetaCode("model ") .Accepts(AcceptedCharacters.None), factory.Code(" Foo") .As(new ModelChunkGenerator("Foo")) .Accepts(AcceptedCharacters.AnyExceptNewline), factory.EmptyHtml() }; // Act var spans = ParseDocument(document, errors); // Assert Assert.Equal(expectedSpans, spans); Assert.Empty(errors); }
public void ParseInjectKeyword_AllowsOptionalTrailingSemicolon( string injectStatement, string expectedService, string expectedPropertyName) { // Arrange var documentContent = "@inject " + injectStatement; var factory = SpanFactory.CreateCsHtml(); var errors = new List <RazorError>(); var expectedSpans = new Span[] { factory.EmptyHtml(), factory.CodeTransition(SyntaxConstants.TransitionString) .Accepts(AcceptedCharacters.None), factory.MetaCode("inject ") .Accepts(AcceptedCharacters.None), factory.Code(injectStatement) .As(new InjectParameterGenerator(expectedService, expectedPropertyName)) .Accepts(AcceptedCharacters.AnyExceptNewline), factory.EmptyHtml() }; // Act var spans = ParseDocument(documentContent, errors); // Assert Assert.Equal(expectedSpans, spans); Assert.Empty(errors); }
public void Visit_WithDesignTimeHost_GeneratesPropertiesAndLinePragmas_ForInjectChunks() { // Arrange var expected = string.Join(Environment.NewLine, @"[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]", @"public", @"#line 1 """"", @"MyType1 MyPropertyName1", "", @"#line default", @"#line hidden", @"{ get; private set; }", @"[Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]", @"public", @"#line 1 """"", @"MyType2 @MyPropertyName2", "", @"#line default", @"#line hidden", @"{ get; private set; }", ""); var writer = new CSharpCodeWriter(); var context = CreateContext(); context.Host.DesignTimeMode = true; var visitor = new InjectChunkVisitor(writer, context, "Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute"); var factory = SpanFactory.CreateCsHtml(); var node = (Span)factory.Code("Some code") .As(new InjectParameterGenerator("MyType", "MyPropertyName")); // Act visitor.Accept(new Chunk[] { new LiteralChunk(), new InjectChunk("MyType1", "MyPropertyName1") { Association = node }, new InjectChunk("MyType2", "@MyPropertyName2") { Association = node } }); var code = writer.GenerateCode(); // Assert Assert.Equal(expected, code); }
public void ParseModelKeyword_ErrorOnInheritsFollowedByModel() { // Arrange var errors = new List <RazorError>(); var document = "@inherits Bar" + Environment.NewLine + "@model Foo"; var factory = SpanFactory.CreateCsHtml(); var expectedSpans = new Span[] { factory.EmptyHtml(), factory.CodeTransition(SyntaxConstants.TransitionString) .Accepts(AcceptedCharacters.None), factory.MetaCode("inherits ") .Accepts(AcceptedCharacters.None), factory.Code("Bar" + Environment.NewLine) .As(new SetBaseTypeChunkGenerator("Bar")) .Accepts(AcceptedCharacters.AnyExceptNewline), factory.EmptyHtml(), factory.CodeTransition(SyntaxConstants.TransitionString) .Accepts(AcceptedCharacters.None), factory.MetaCode("model ") .Accepts(AcceptedCharacters.None), factory.Code("Foo") .As(new ModelChunkGenerator("Foo")) .Accepts(AcceptedCharacters.AnyExceptNewline), factory.EmptyHtml() }; var expectedErrors = new[] { new RazorError( "The 'inherits' keyword is not allowed when a 'model' keyword is used.", new SourceLocation(9, 0, 9), length: 8) }; // Act var spans = ParseDocument(document, errors); // Assert Assert.Equal(expectedSpans, spans.ToArray()); Assert.Equal(expectedErrors, errors.ToArray()); }
public void ParseModelKeyword_ErrorOnMultipleModelStatements() { // Arrange + Act var errors = new List <RazorError>(); var document = "@model Foo" + Environment.NewLine + "@model Bar"; var factory = SpanFactory.CreateCsHtml(); var expectedSpans = new Span[] { factory.EmptyHtml(), factory.CodeTransition(SyntaxConstants.TransitionString) .Accepts(AcceptedCharacters.None), factory.MetaCode("model ") .Accepts(AcceptedCharacters.None), factory.Code("Foo" + Environment.NewLine) .As(new ModelChunkGenerator("Foo")) .Accepts(AcceptedCharacters.AnyExceptNewline), factory.EmptyHtml(), factory.CodeTransition(SyntaxConstants.TransitionString) .Accepts(AcceptedCharacters.None), factory.MetaCode("model ") .Accepts(AcceptedCharacters.None), factory.Code("Bar") .As(new ModelChunkGenerator("Bar")) .Accepts(AcceptedCharacters.AnyExceptNewline), factory.EmptyHtml() }; var expectedErrors = new[] { new RazorError( "Only one 'model' statement is allowed in a file.", PlatformNormalizer.NormalizedSourceLocation(13, 1, 1), 5) }; // Act var spans = ParseDocument(document, errors); // Assert Assert.Equal(expectedSpans, spans); Assert.Equal(expectedErrors, errors); }