// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
using Moq;
using Xunit;
namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
{
public class DefaultDocumentWriterTest
{
[Fact] // This test covers the whole process including actual hashing.
public void WriteDocument_EndToEnd_WritesChecksumAndMarksAutoGenerated()
{
// Arrange
var document = new DocumentIntermediateNode();
var codeDocument = TestRazorCodeDocument.CreateEmpty();
var options = RazorCodeGenerationOptions.CreateDefault();
var target = CodeTarget.CreateDefault(codeDocument, options);
var writer = new DefaultDocumentWriter(target, options);
// Act
var result = writer.WriteDocument(codeDocument, document);
// Assert
var csharp = result.GeneratedCode;
Assert.Equal(
@"#pragma checksum ""test.cshtml"" ""{ff1816ec-aa5e-4d10-87f7-6f4963833460}"" ""da39a3ee5e6b4b0d3255bfef95601890afd80709""
//
#pragma warning disable 1591
#pragma warning restore 1591
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteDocument_SHA1_WritesChecksumAndMarksAutoGenerated()
{
// Arrange
var checksumBytes = new byte[] { (byte)'t', (byte)'e', (byte)'s', (byte)'t', };
var sourceDocument = Mock.Of(d =>
d.FilePath == "test.cshtml" &&
d.GetChecksum() == checksumBytes &&
d.GetChecksumAlgorithm() == "SHA1");
var document = new DocumentIntermediateNode();
var codeDocument = RazorCodeDocument.Create(sourceDocument);
var options = RazorCodeGenerationOptions.CreateDefault();
var target = CodeTarget.CreateDefault(codeDocument, options);
var writer = new DefaultDocumentWriter(target, options);
// Act
var result = writer.WriteDocument(codeDocument, document);
// Assert
var csharp = result.GeneratedCode;
Assert.Equal(
@"#pragma checksum ""test.cshtml"" ""{ff1816ec-aa5e-4d10-87f7-6f4963833460}"" ""74657374""
//
#pragma warning disable 1591
#pragma warning restore 1591
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteDocument_SHA256_WritesChecksumAndMarksAutoGenerated()
{
// Arrange
var checksumBytes = new byte[] { (byte)'t', (byte)'e', (byte)'s', (byte)'t', };
var sourceDocument = Mock.Of(d =>
d.FilePath == "test.cshtml" &&
d.GetChecksum() == checksumBytes &&
d.GetChecksumAlgorithm() == "SHA256");
var document = new DocumentIntermediateNode();
var codeDocument = RazorCodeDocument.Create(sourceDocument);
var options = RazorCodeGenerationOptions.CreateDefault();
var target = CodeTarget.CreateDefault(codeDocument, options);
var writer = new DefaultDocumentWriter(target, options);
// Act
var result = writer.WriteDocument(codeDocument, document);
// Assert
var csharp = result.GeneratedCode;
Assert.Equal(
@"#pragma checksum ""test.cshtml"" ""{8829d00f-11b8-4213-878b-770e8597ac16}"" ""74657374""
//
#pragma warning disable 1591
#pragma warning restore 1591
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteDocument_UnsupportedChecksumAlgorithm_Throws()
{
// Arrange
var checksumBytes = new byte[] { (byte)'t', (byte)'e', (byte)'s', (byte)'t', };
var sourceDocument = Mock.Of(d =>
d.FilePath == "test.cshtml" &&
d.GetChecksum() == checksumBytes &&
d.GetChecksumAlgorithm() == "SHA3");
var document = new DocumentIntermediateNode();
var codeDocument = RazorCodeDocument.Create(sourceDocument);
var options = RazorCodeGenerationOptions.CreateDefault();
var target = CodeTarget.CreateDefault(codeDocument, options);
var writer = new DefaultDocumentWriter(target, options);
// Act & Assert
var exception = Assert.Throws(() =>
{
var result = writer.WriteDocument(codeDocument, document);
});
Assert.Equal(
"The hash algorithm 'SHA3' is not supported for checksum generation. Supported algorithms are: 'SHA1 SHA256'. " +
"Set 'RazorCodeGenerationOptions.SuppressChecksum' to 'True' to suppress automatic checksum generation.",
exception.Message);
}
[Fact]
public void WriteDocument_Empty_SuppressChecksumTrue_DoesnotWriteChecksum()
{
// Arrange
var document = new DocumentIntermediateNode();
var codeDocument = TestRazorCodeDocument.CreateEmpty();
var optionsBuilder = new DefaultRazorCodeGenerationOptionsBuilder(designTime: false)
{
SuppressChecksum = true
};
var options = optionsBuilder.Build();
var target = CodeTarget.CreateDefault(codeDocument, options);
var writer = new DefaultDocumentWriter(target, options);
// Act
var result = writer.WriteDocument(codeDocument, document);
// Assert
var csharp = result.GeneratedCode;
Assert.Equal(
@"//
#pragma warning disable 1591
#pragma warning restore 1591
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteDocument_WritesNamespace()
{
// Arrange
var document = new DocumentIntermediateNode();
var builder = IntermediateNodeBuilder.Create(document);
builder.Add(new NamespaceDeclarationIntermediateNode()
{
Content = "TestNamespace",
});
var codeDocument = TestRazorCodeDocument.CreateEmpty();
var options = RazorCodeGenerationOptions.CreateDefault();
var target = CodeTarget.CreateDefault(codeDocument, options);
var writer = new DefaultDocumentWriter(target, options);
// Act
var result = writer.WriteDocument(codeDocument, document);
// Assert
var csharp = result.GeneratedCode;
Assert.Equal(
@"#pragma checksum ""test.cshtml"" ""{ff1816ec-aa5e-4d10-87f7-6f4963833460}"" ""da39a3ee5e6b4b0d3255bfef95601890afd80709""
//
#pragma warning disable 1591
namespace TestNamespace
{
#line hidden
}
#pragma warning restore 1591
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteDocument_WritesClass()
{
// Arrange
var document = new DocumentIntermediateNode();
var builder = IntermediateNodeBuilder.Create(document);
builder.Add(new ClassDeclarationIntermediateNode()
{
Modifiers =
{
"internal"
},
BaseType = "TestBase",
Interfaces = new List { "IFoo", "IBar", },
ClassName = "TestClass",
});
var codeDocument = TestRazorCodeDocument.CreateEmpty();
var options = RazorCodeGenerationOptions.CreateDefault();
var target = CodeTarget.CreateDefault(codeDocument, options);
var writer = new DefaultDocumentWriter(target, options);
// Act
var result = writer.WriteDocument(codeDocument, document);
// Assert
var csharp = result.GeneratedCode;
Assert.Equal(
@"#pragma checksum ""test.cshtml"" ""{ff1816ec-aa5e-4d10-87f7-6f4963833460}"" ""da39a3ee5e6b4b0d3255bfef95601890afd80709""
//
#pragma warning disable 1591
internal class TestClass : TestBase, IFoo, IBar
{
}
#pragma warning restore 1591
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteDocument_WritesMethod()
{
// Arrange
var document = new DocumentIntermediateNode();
var builder = IntermediateNodeBuilder.Create(document);
builder.Add(new MethodDeclarationIntermediateNode()
{
Modifiers =
{
"internal",
"virtual",
"async",
},
MethodName = "TestMethod",
ReturnType = "string",
});
var codeDocument = TestRazorCodeDocument.CreateEmpty();
var options = RazorCodeGenerationOptions.CreateDefault();
var target = CodeTarget.CreateDefault(codeDocument, options);
var writer = new DefaultDocumentWriter(target, options);
// Act
var result = writer.WriteDocument(codeDocument, document);
// Assert
var csharp = result.GeneratedCode;
Assert.Equal(
@"#pragma checksum ""test.cshtml"" ""{ff1816ec-aa5e-4d10-87f7-6f4963833460}"" ""da39a3ee5e6b4b0d3255bfef95601890afd80709""
//
#pragma warning disable 1591
#pragma warning disable 1998
internal virtual async string TestMethod()
{
}
#pragma warning restore 1998
#pragma warning restore 1591
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteDocument_WritesField()
{
// Arrange
var document = new DocumentIntermediateNode();
var builder = IntermediateNodeBuilder.Create(document);
builder.Add(new FieldDeclarationIntermediateNode()
{
Modifiers =
{
"internal",
"readonly",
},
FieldName = "_foo",
FieldType = "string",
});
var codeDocument = TestRazorCodeDocument.CreateEmpty();
var options = RazorCodeGenerationOptions.CreateDefault();
var target = CodeTarget.CreateDefault(codeDocument, options);
var writer = new DefaultDocumentWriter(target, options);
// Act
var result = writer.WriteDocument(codeDocument, document);
// Assert
var csharp = result.GeneratedCode;
Assert.Equal(
@"#pragma checksum ""test.cshtml"" ""{ff1816ec-aa5e-4d10-87f7-6f4963833460}"" ""da39a3ee5e6b4b0d3255bfef95601890afd80709""
//
#pragma warning disable 1591
internal readonly string _foo;
#pragma warning restore 1591
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteDocument_WritesProperty()
{
// Arrange
var document = new DocumentIntermediateNode();
var builder = IntermediateNodeBuilder.Create(document);
builder.Add(new PropertyDeclarationIntermediateNode()
{
Modifiers =
{
"internal",
"virtual",
},
PropertyName = "Foo",
PropertyType = "string",
});
var codeDocument = TestRazorCodeDocument.CreateEmpty();
var options = RazorCodeGenerationOptions.CreateDefault();
var target = CodeTarget.CreateDefault(codeDocument, options);
var writer = new DefaultDocumentWriter(target, options);
// Act
var result = writer.WriteDocument(codeDocument, document);
// Assert
var csharp = result.GeneratedCode;
Assert.Equal(
@"#pragma checksum ""test.cshtml"" ""{ff1816ec-aa5e-4d10-87f7-6f4963833460}"" ""da39a3ee5e6b4b0d3255bfef95601890afd80709""
//
#pragma warning disable 1591
internal virtual string Foo { get; set; }
#pragma warning restore 1591
",
csharp,
ignoreLineEndingDifferences: true);
}
}
}