Added an output validator to make a best-effort attempt at validating old and new codeDOM/codeTree output.

This commit is contained in:
N. Taylor Mullen 2014-01-28 17:05:48 -08:00
parent 03164325b6
commit 73dae5fcaa
6 changed files with 151 additions and 3 deletions

View File

@ -8,7 +8,7 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp
{
public class CSharpDesignTimeHelpersVisitor : CodeVisitor
{
private const string InheritsHelper = "__inheritsHelper";
internal const string InheritsHelper = "__inheritsHelper";
private CSharpCodeWriter _writer;
// TODO: No need for the entire host

View File

@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNet.Razor.Generator;
using Microsoft.AspNet.Razor.Generator.Compiler;
using Microsoft.AspNet.Razor.Parser.SyntaxTree;
@ -39,6 +40,7 @@ namespace Microsoft.AspNet.Razor
#if NET45
public CodeCompileUnit CCU { get; set; }
public IDictionary<int, GeneratedCodeMapping> OLDDesignTimeLineMappings { get; set; }
#endif
internal CodeTree CT { get; set; }
}

View File

@ -188,7 +188,8 @@ namespace Microsoft.AspNet.Razor
{
#if NET45
CCU = generator.Context.CompileUnit,
#endif
OLDDesignTimeLineMappings = designTimeLineMappings,
#endif
CT = generator.Context.CodeTreeBuilder.CodeTree
};
}

View File

@ -19,9 +19,10 @@ namespace Microsoft.AspNet.Razor.Test.Generator
{
RunTest("CodeTree", onResults: (results, codDOMOutput) =>
{
CodeTreeOutputValidator.ValidateResults(results.GeneratedCode, codDOMOutput, results.DesignTimeLineMappings, results.OLDDesignTimeLineMappings);
File.WriteAllText("./testfile_ct.cs", results.GeneratedCode);
File.WriteAllText("./testfile_cd.cs", codDOMOutput);
}, designTimeMode: false);
}, designTimeMode: true);
}
}
}

View File

@ -0,0 +1,143 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.AspNet.Razor.Generator;
using Microsoft.AspNet.Razor.Generator.Compiler;
using Microsoft.AspNet.Razor.Generator.Compiler.CSharp;
using Microsoft.TestCommon;
namespace Microsoft.AspNet.Razor.Test.Generator
{
public class CodeTreeOutputValidator
{
public static void ValidateResults(string codeTreeCode, string codeDOMCode, IList<LineMapping> codeTreeMappings, IDictionary<int, GeneratedCodeMapping> codeDOMMappings)
{
Assert.Equal(codeTreeMappings.Count, codeDOMMappings.Values.Count);
ValidateNamespace(codeTreeCode, codeDOMCode);
ValidateClass(codeTreeCode, codeDOMCode);
ValidateUsings(codeTreeCode, codeDOMCode);
ValidateNewObjects(codeTreeCode, codeDOMCode);
ValidateBraces(codeTreeCode, codeDOMCode);
ValidateLambdas(codeTreeCode, codeDOMCode);
ValidateMembers(codeTreeCode, codeDOMCode);
ValidateReturns(codeTreeCode, codeDOMCode);
ValidateBaseTypes(codeTreeCode, codeDOMCode);
}
private static void ValidateNamespace(string codeTreeCode, string codeDOMCode)
{
ValidateCodeTreeContains(codeTreeCode, codeDOMCode, @"namespace [^\s{]+");
}
private static void ValidateClass(string codeTreeCode, string codeDOMCode)
{
ValidateCodeTreeContains(codeTreeCode, codeDOMCode, @"class [^\s{]+");
}
private static void ValidateUsings(string codeTreeCode, string codeDOMCode)
{
ValidateCodeTreeContainsAll(codeTreeCode, codeDOMCode, @"using [^\s{;]+");
}
private static void ValidateNewObjects(string codeTreeCode, string codeDOMCode)
{
ValidateCodeTreeContainsAll(codeTreeCode, codeDOMCode, @"new [^\(<\s]+");
}
private static void ValidateBraces(string codeTreeCode, string codeDOMCode)
{
var codeDOMMatches = Regex.Matches(codeDOMCode, "{");
var codeTreeMatches = Regex.Matches(codeTreeCode, "{");
Assert.NotEmpty(codeDOMMatches);
Assert.NotEmpty(codeTreeMatches);
if (codeDOMMatches.Count != codeTreeMatches.Count)
{
// 1 leniency for the design time helpers
Assert.Equal(codeDOMMatches.Count, codeTreeMatches.Count - 1);
}
else
{
Assert.Equal(codeDOMMatches.Count, codeTreeMatches.Count);
}
codeDOMMatches = Regex.Matches(codeDOMCode, "}");
codeTreeMatches = Regex.Matches(codeTreeCode, "}");
Assert.NotEmpty(codeDOMMatches);
Assert.NotEmpty(codeTreeMatches);
if (codeDOMMatches.Count != codeTreeMatches.Count)
{
// 1 leniency for the design time helpers
Assert.Equal(codeDOMMatches.Count, codeTreeMatches.Count - 1);
}
else
{
Assert.Equal(codeDOMMatches.Count, codeTreeMatches.Count);
}
}
private static void ValidateLambdas(string codeTreeCode, string codeDOMCode)
{
ValidateCount(codeTreeCode, codeDOMCode, " => ");
}
private static void ValidateMembers(string codeTreeCode, string codeDOMCode)
{
ValidateCodeTreeContainsAll(codeTreeCode, codeDOMCode, @"(public|private) [^\s\(]+ [^\s\(]+");
}
private static void ValidateReturns(string codeTreeCode, string codeDOMCode)
{
ValidateCodeTreeContainsAll(codeTreeCode, codeDOMCode, @"return [^\s\(;]+");
}
private static void ValidateBaseTypes(string codeTreeCode, string codeDOMCode)
{
ValidateCodeTreeContainsAll(codeTreeCode, codeDOMCode, @"class [^\s]+ : [^\s{]+");
}
private static void ValidateKeywords(string codeTreeCode, string codeDOMCode)
{
ValidateCount(codeTreeCode, codeDOMCode, "Execute");
ValidateCount(codeTreeCode, codeDOMCode, CSharpDesignTimeHelpersVisitor.InheritsHelper);
}
private static void ValidateCodeTreeContains(string codeTreeCode, string codeDOMCode, string regex)
{
var match = Regex.Match(codeDOMCode, regex);
Assert.NotEmpty(match.Groups);
Assert.True(codeTreeCode.IndexOf(match.Groups[0].Value) >= 0);
}
private static void ValidateCodeTreeContainsAll(string codeTreeCode, string codeDOMCode, string regex)
{
var matches = Regex.Matches(codeDOMCode, regex);
Assert.NotEmpty(matches);
for (int i = 0; i < matches.Count; i++)
{
var match = matches[i];
for (int j = 0; j < match.Groups.Count; j++)
{
Assert.True(codeTreeCode.IndexOf(match.Groups[j].Value) >= 0);
}
}
}
private static void ValidateCount(string codeTreeCode, string codeDOMCode, string regex)
{
var codeDOMMatches = Regex.Matches(codeDOMCode, regex);
var codeTreeMatches = Regex.Matches(codeTreeCode, regex);
Assert.Equal(codeDOMMatches.Count, codeTreeMatches.Count);
}
}
}

View File

@ -50,6 +50,7 @@
<Compile Include="Framework\RawTextSymbol.cs" />
<Compile Include="Framework\TestSpanBuilder.cs" />
<Compile Include="Generator\CodeTree\CodeTreeGenerationTest.cs" />
<Compile Include="Generator\CodeTree\CodeTreeOutputValidator.cs" />
<Compile Include="Generator\GeneratedCodeMappingTest.cs" />
<Compile Include="Generator\PaddingTest.cs" />
<Compile Include="Generator\TabTest.cs" />