Avoid errors when generating baselines
- ignore missing expected output resources in this mode - update `BaselineWriter` to avoid `IOException`s (file access issues) - serialize file operations - one file handle per file - repeatedly `rm TestFiles/CodeGenerator/Output/*; `dnx . test`; no errors also - add generation of design-time line mappings - fix ChunkGenerator -> CodeGenerator typo in path names - update files only if they have changed - new `TestFiles.Exists()` method to support this check - do not check results in `CSharpCodeBuilderTests` if `GENERATE_BASELINES` set nits: - update BOM in CodeBlockWithTextElement.cs to avoid future `git diff`s - use more `var` and improve variable names in `TestFile` - wrap long lines
This commit is contained in:
parent
1e5ad1154d
commit
d545f47fe4
|
|
@ -2,6 +2,9 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
#if !DNXCORE50
|
||||
#if GENERATE_BASELINES
|
||||
using System;
|
||||
#endif
|
||||
using Microsoft.AspNet.Razor.Parser.SyntaxTree;
|
||||
using Microsoft.AspNet.Razor.Test;
|
||||
using Microsoft.AspNet.Razor.Test.Generator;
|
||||
|
|
@ -29,18 +32,37 @@ namespace Microsoft.AspNet.Razor.CodeGenerators
|
|||
codeGeneratorContext.ChunkTreeBuilder.AddUsingChunk("FakeNamespace1", syntaxTreeNode.Object);
|
||||
codeGeneratorContext.ChunkTreeBuilder.AddUsingChunk("FakeNamespace2.SubNamespace", syntaxTreeNode.Object);
|
||||
var codeGenerator = new CodeGenTestCodeGenerator(codeGeneratorContext);
|
||||
var testFile = TestFile.Create("TestFiles/CodeGenerator/Output/CSharpCodeGenerator.cs");
|
||||
|
||||
string expectedOutput;
|
||||
#if GENERATE_BASELINES
|
||||
if (testFile.Exists())
|
||||
{
|
||||
expectedOutput = testFile.ReadAllText();
|
||||
}
|
||||
else
|
||||
{
|
||||
expectedOutput = null;
|
||||
}
|
||||
#else
|
||||
expectedOutput = testFile.ReadAllText();
|
||||
#endif
|
||||
|
||||
// Act
|
||||
var result = codeGenerator.Generate();
|
||||
|
||||
BaselineWriter.WriteBaseline(
|
||||
@"test\Microsoft.AspNet.Razor.Test\TestFiles\CodeGenerator\Output\CSharpCodeGenerator.cs",
|
||||
result.Code);
|
||||
|
||||
var expectedOutput = TestFile.Create("TestFiles/CodeGenerator/Output/CSharpCodeGenerator.cs").ReadAllText();
|
||||
|
||||
// Assert
|
||||
#if GENERATE_BASELINES
|
||||
// Update baseline files if files do not already match.
|
||||
if (!string.Equals(expectedOutput, result.Code, StringComparison.Ordinal))
|
||||
{
|
||||
BaselineWriter.WriteBaseline(
|
||||
@"test\Microsoft.AspNet.Razor.Test\TestFiles\CodeGenerator\Output\CSharpCodeGenerator.cs",
|
||||
result.Code);
|
||||
}
|
||||
#else
|
||||
Assert.Equal(expectedOutput, result.Code);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -127,9 +127,22 @@ namespace Microsoft.AspNet.Razor.Test.Generator
|
|||
}
|
||||
|
||||
var sourceLocation = string.Format("TestFiles/CodeGenerator/Source/{0}.{1}", name, FileExtension);
|
||||
var expectedOutput = TestFile
|
||||
.Create(string.Format("TestFiles/CodeGenerator/Output/{0}.{1}", baselineName, BaselineExtension))
|
||||
.ReadAllText();
|
||||
var testFile = TestFile
|
||||
.Create(string.Format("TestFiles/CodeGenerator/Output/{0}.{1}", baselineName, BaselineExtension));
|
||||
|
||||
string expectedOutput;
|
||||
#if GENERATE_BASELINES
|
||||
if (testFile.Exists())
|
||||
{
|
||||
expectedOutput = testFile.ReadAllText();
|
||||
}
|
||||
else
|
||||
{
|
||||
expectedOutput = null;
|
||||
}
|
||||
#else
|
||||
expectedOutput = testFile.ReadAllText();
|
||||
#endif
|
||||
|
||||
// Set up the host and engine
|
||||
var host = CreateHost();
|
||||
|
|
@ -179,17 +192,20 @@ namespace Microsoft.AspNet.Razor.Test.Generator
|
|||
rootNamespace: TestRootNamespaceName,
|
||||
sourceFileName: sourceFileName);
|
||||
}
|
||||
// Only called if GENERATE_BASELINES is set, otherwise compiled out.
|
||||
BaselineWriter.WriteBaseline(
|
||||
string.Format(
|
||||
@"test\Microsoft.AspNet.Razor.Test\TestFiles\ChunkGenerator\Output\{0}.{1}",
|
||||
baselineName,
|
||||
BaselineExtension),
|
||||
results.GeneratedCode);
|
||||
|
||||
#if !GENERATE_BASELINES
|
||||
var textOutput = results.GeneratedCode;
|
||||
#if GENERATE_BASELINES
|
||||
var outputFile = string.Format(
|
||||
@"test\Microsoft.AspNet.Razor.Test\TestFiles\CodeGenerator\Output\{0}.{1}",
|
||||
baselineName,
|
||||
BaselineExtension);
|
||||
|
||||
// Update baseline files if files do not already match.
|
||||
if (!string.Equals(expectedOutput, textOutput, StringComparison.Ordinal))
|
||||
{
|
||||
BaselineWriter.WriteBaseline(outputFile, textOutput);
|
||||
}
|
||||
#else
|
||||
if (onResults != null)
|
||||
{
|
||||
onResults(results);
|
||||
|
|
@ -216,17 +232,70 @@ namespace Microsoft.AspNet.Razor.Test.Generator
|
|||
|
||||
if (expectedDesignTimePragmas != null)
|
||||
{
|
||||
Assert.True(results.DesignTimeLineMappings != null); // Guard
|
||||
Assert.NotNull(results.DesignTimeLineMappings); // Guard
|
||||
#if GENERATE_BASELINES
|
||||
if (expectedDesignTimePragmas == null ||
|
||||
!Enumerable.SequenceEqual(expectedDesignTimePragmas, results.DesignTimeLineMappings))
|
||||
{
|
||||
var lineMappingFile = Path.ChangeExtension(outputFile, "lineMappings.cs");
|
||||
var lineMappingCode = GetDesignTimeLineMappingsCode(results.DesignTimeLineMappings);
|
||||
BaselineWriter.WriteBaseline(lineMappingFile, lineMappingCode);
|
||||
}
|
||||
#else
|
||||
for (var i = 0; i < expectedDesignTimePragmas.Count && i < results.DesignTimeLineMappings.Count; i++)
|
||||
{
|
||||
Assert.Equal(expectedDesignTimePragmas[i], results.DesignTimeLineMappings[i]);
|
||||
}
|
||||
|
||||
Assert.Equal(expectedDesignTimePragmas.Count, results.DesignTimeLineMappings.Count);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetDesignTimeLineMappingsCode(IList<LineMapping> designTimeLineMappings)
|
||||
{
|
||||
var lineMappings = new StringBuilder();
|
||||
lineMappings.AppendLine($"// !!! Do not check in. Instead paste content into test method. !!!");
|
||||
lineMappings.AppendLine();
|
||||
|
||||
var indent = " ";
|
||||
lineMappings.AppendLine($"{ indent }var expectedLineMappings = new[]");
|
||||
lineMappings.AppendLine($"{ indent }{{");
|
||||
foreach (var lineMapping in designTimeLineMappings)
|
||||
{
|
||||
var innerIndent = indent + " ";
|
||||
var documentLocation = lineMapping.DocumentLocation;
|
||||
var generatedLocation = lineMapping.GeneratedLocation;
|
||||
lineMappings.AppendLine($"{ innerIndent }BuildLineMapping(");
|
||||
|
||||
innerIndent += " ";
|
||||
lineMappings.AppendLine($"{ innerIndent }documentAbsoluteIndex: { documentLocation.AbsoluteIndex },");
|
||||
lineMappings.AppendLine($"{ innerIndent }documentLineIndex: { documentLocation.LineIndex },");
|
||||
if (documentLocation.CharacterIndex != generatedLocation.CharacterIndex)
|
||||
{
|
||||
lineMappings.AppendLine($"{ innerIndent }documentCharacterOffsetIndex: { documentLocation.CharacterIndex },");
|
||||
}
|
||||
|
||||
lineMappings.AppendLine($"{ innerIndent }generatedAbsoluteIndex: { generatedLocation.AbsoluteIndex },");
|
||||
lineMappings.AppendLine($"{ innerIndent }generatedLineIndex: { generatedLocation.LineIndex },");
|
||||
if (documentLocation.CharacterIndex != generatedLocation.CharacterIndex)
|
||||
{
|
||||
lineMappings.AppendLine($"{ innerIndent }generatedCharacterOffsetIndex: { generatedLocation.CharacterIndex },");
|
||||
}
|
||||
else
|
||||
{
|
||||
lineMappings.AppendLine($"{ innerIndent }characterOffsetIndex: { generatedLocation.CharacterIndex },");
|
||||
}
|
||||
|
||||
lineMappings.AppendLine($"{ innerIndent }contentLength: { generatedLocation.ContentLength }),");
|
||||
}
|
||||
|
||||
lineMappings.AppendLine($"{ indent }}};");
|
||||
|
||||
return lineMappings.ToString();
|
||||
}
|
||||
|
||||
private void VerifyNoBrokenEndOfLines(string text)
|
||||
{
|
||||
for (int i = 0; i < text.Length; i++)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#pragma checksum "CodeBlockWithTextElement.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "13e48ff59aab8106ceb68dd4a10b0bdf10c322fc"
|
||||
#pragma checksum "CodeBlockWithTextElement.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "13e48ff59aab8106ceb68dd4a10b0bdf10c322fc"
|
||||
namespace TestOutput
|
||||
{
|
||||
using System;
|
||||
|
|
|
|||
|
|
@ -8,19 +8,26 @@ namespace Microsoft.AspNet.Razor.Test.Utils
|
|||
{
|
||||
public static class BaselineWriter
|
||||
{
|
||||
private static object baselineLock = new object();
|
||||
|
||||
[Conditional("GENERATE_BASELINES")]
|
||||
public static void WriteBaseline(string baselineFile, string output)
|
||||
{
|
||||
var root = RecursiveFind("Razor.sln", Path.GetFullPath("."));
|
||||
var baselinePath = Path.Combine(root, baselineFile);
|
||||
|
||||
// Update baseline
|
||||
// IMPORTANT! Replace this path with the local path on your machine to the baseline files!
|
||||
if (File.Exists(baselinePath))
|
||||
// Serialize writes to minimize contention for file handles and directory access.
|
||||
lock (baselineLock)
|
||||
{
|
||||
File.Delete(baselinePath);
|
||||
// Update baseline
|
||||
using (var stream = File.Open(baselinePath, FileMode.Create, FileAccess.Write))
|
||||
{
|
||||
using (var writer = new StreamWriter(stream))
|
||||
{
|
||||
writer.Write(output);
|
||||
}
|
||||
}
|
||||
}
|
||||
File.WriteAllText(baselinePath, output.ToString());
|
||||
}
|
||||
|
||||
private static string RecursiveFind(string path, string start)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// 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.IO;
|
||||
using System.Reflection;
|
||||
using Xunit;
|
||||
|
|
@ -9,16 +10,15 @@ namespace Microsoft.AspNet.Razor.Test
|
|||
{
|
||||
public class TestFile
|
||||
{
|
||||
public const string ResourceNameFormat = "{0}.TestFiles.{1}";
|
||||
public TestFile(string resourceName, Assembly assembly)
|
||||
{
|
||||
Assembly = assembly;
|
||||
ResourceName = Assembly.GetName().Name + "." + resourceName.Replace('/', '.');
|
||||
}
|
||||
|
||||
public Assembly Assembly { get; }
|
||||
|
||||
public string ResourceName { get; }
|
||||
public Assembly Assembly { get; set; }
|
||||
|
||||
public TestFile(string resName, Assembly asm)
|
||||
{
|
||||
Assembly = asm;
|
||||
ResourceName = Assembly.GetName().Name + "." + resName.Replace('/', '.');
|
||||
}
|
||||
|
||||
public static TestFile Create(string localResourceName)
|
||||
{
|
||||
|
|
@ -27,27 +27,44 @@ namespace Microsoft.AspNet.Razor.Test
|
|||
|
||||
public Stream OpenRead()
|
||||
{
|
||||
var strm = Assembly.GetManifestResourceStream(ResourceName);
|
||||
if (strm == null)
|
||||
var stream = Assembly.GetManifestResourceStream(ResourceName);
|
||||
if (stream == null)
|
||||
{
|
||||
Assert.True(false, string.Format("Manifest resource: {0} not found", ResourceName));
|
||||
}
|
||||
return strm;
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
public bool Exists()
|
||||
{
|
||||
var resourceNames = Assembly.GetManifestResourceNames();
|
||||
foreach (var resourceName in resourceNames)
|
||||
{
|
||||
// Resource names are case-sensitive.
|
||||
if (string.Equals(ResourceName, resourceName, StringComparison.Ordinal))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public byte[] ReadAllBytes()
|
||||
{
|
||||
using (Stream stream = OpenRead())
|
||||
using (var stream = OpenRead())
|
||||
{
|
||||
byte[] buffer = new byte[stream.Length];
|
||||
var buffer = new byte[stream.Length];
|
||||
stream.Read(buffer, 0, buffer.Length);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
|
||||
public string ReadAllText()
|
||||
{
|
||||
using (StreamReader reader = new StreamReader(OpenRead()))
|
||||
using (var reader = new StreamReader(OpenRead()))
|
||||
{
|
||||
// The .Replace() calls normalize line endings, in case you get \n instead of \r\n
|
||||
// since all the unit tests rely on the assumption that the files will have \r\n endings.
|
||||
|
|
@ -66,9 +83,9 @@ namespace Microsoft.AspNet.Razor.Test
|
|||
Directory.CreateDirectory(directory);
|
||||
}
|
||||
|
||||
using (Stream outStream = File.Create(filePath))
|
||||
using (var outStream = File.Create(filePath))
|
||||
{
|
||||
using (Stream inStream = OpenRead())
|
||||
using (var inStream = OpenRead())
|
||||
{
|
||||
inStream.CopyTo(outStream);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue