Skip to content

Commit

Permalink
fix(T4.BuildTools): evaluate T4Transform/T4Preprocess Metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
T-Ernst committed Dec 13, 2024
1 parent f54ec9f commit 381de2d
Show file tree
Hide file tree
Showing 26 changed files with 461 additions and 55 deletions.
192 changes: 167 additions & 25 deletions Mono.TextTemplating.Build.Tests/MSBuildExecutionTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using System.Linq;
using Xunit;

Expand All @@ -10,108 +11,249 @@ namespace Mono.TextTemplating.Tests
[CollectionDefinition (nameof (MSBuildExecutionTests), DisableParallelization = true)]
public class MSBuildExecutionTests : IClassFixture<MSBuildFixture>
{
[Fact]
public void TransformExplicitWithArguments ()
[Theory]
[InlineData ("TransformTemplates", "foo.txt", "Hello 2019!")]
[InlineData ("TransformTemplateFromRelativePath", "Nested/Template/Folder/foo.txt", "Hello 2024!")]
[InlineData ("TransformTemplateWithExtension", "foo.html", "<h1>Hello 2024!</h1>")]
public void TransformExplicitWithArguments (string projectName, string expectedFilePath, string expectedText)
{
using var ctx = new MSBuildTestContext ();
var project = ctx.LoadTestProject ("TransformTemplates");
var project = ctx.LoadTestProject (projectName);

var instance = project.Build ("TransformTemplates");

var generated = project.DirectoryPath["foo.txt"].AssertTextStartsWith ("Hello 2019!");
var generated = project.DirectoryPath[expectedFilePath].AssertTextStartsWith (expectedText);

instance.AssertSingleItem ("GeneratedTemplates", withFullPath: generated);
instance.AssertNoItems ("PreprocessedTemplates");
}

[Fact]
public void TransformOnBuild ()
[Theory]
[InlineData ("TransformTemplates", "foo.txt", "Hello 2019!")]
[InlineData ("TransformTemplateFromRelativePath", "Nested/Template/Folder/foo.txt", "Hello 2024!")]
[InlineData ("TransformTemplateWithExtension", "foo.html", "<h1>Hello 2024!</h1>")]
public void TransformOnBuild (string projectName, string expectedFilePath, string expectedText)
{
using var ctx = new MSBuildTestContext ();
var project = ctx.LoadTestProject ("TransformTemplates")
var project = ctx.LoadTestProject (projectName)
.WithProperty ("TransformOnBuild", "true");

project.Restore ();

var instance = project.Build ("Build");

var generatedFilePath = project.DirectoryPath["foo.txt"].AssertTextStartsWith ("Hello 2019!");
var generatedFilePath = project.DirectoryPath[expectedFilePath].AssertTextStartsWith (expectedText);

instance.AssertSingleItem ("GeneratedTemplates", withFullPath: generatedFilePath);
instance.AssertNoItems ("PreprocessedTemplates");
}

[Fact]
public void TransformOnBuildDisabled ()
[Theory]
[InlineData ("TransformTemplates", "foo.txt")]
[InlineData ("TransformTemplateFromRelativePath", "Nested/Template/Folder/foo.txt")]
[InlineData ("TransformTemplateWithExtension", "foo.html")]
public void TransformOnBuildDisabled (string projectName, string expectedFilePath)
{
using var ctx = new MSBuildTestContext ();
var project = ctx.LoadTestProject ("TransformTemplates");
var project = ctx.LoadTestProject (projectName);

project.Restore ();

var instance = project.Build ("Build");

project.DirectoryPath["foo.txt"].AssertFileExists (false);
project.DirectoryPath[expectedFilePath].AssertFileExists (false);

instance.AssertNoItems ("GeneratedTemplates", "PreprocessedTemplates");
}

[Fact]
public void PreprocessLegacy ()
public void TransformMetadata ()
{
// Arrange
using var ctx = new MSBuildTestContext ();
var project = ctx.LoadTestProject ("TransformTemplateMetadata");

var outputDirectory = project.DirectoryPath["Demo/Output/OutputDirectory.txt"];
var outputFilePath = project.DirectoryPath["Demo/LegacyOutput/OutputFilePath.txt"];
var outputFileName = project.DirectoryPath["Demo/OutputFileNameTest"];
var outputDirectoryAndOutputFileName = project.DirectoryPath["Demo/Output/OutputDirectoryAndFileNameTest.log"];

// Act
var instance = project.Build ("TransformTemplates");

// Assert
Assert.Multiple (() => {
outputDirectory.AssertTextStartsWith ("Hello Metadata OutputDirectory 2024!");
outputFilePath.AssertTextStartsWith ("Hello Metadata OutputFilePath 2024!");
outputFileName.AssertTextStartsWith ("Hello Metadata OutputFileName 2024!");
outputDirectoryAndOutputFileName.AssertTextStartsWith ("Hello Metadata OutputDirectory and OutputFileName 2024!");
});

instance.AssertNoItems ("PreprocessedTemplates");
}

[Theory]
[InlineData (
"PreprocessTemplate",
"foo.cs",
new string[] {
"namespace PreprocessTemplate {",
"public partial class foo : fooBase {"
}
)]
[InlineData (
"PreprocessTemplateFromRelativePath",
"Nested/Template/Folder/foo.cs",
new string[] {
"namespace PreprocessTemplateFromRelativePath.Nested.Template.Folder {",
"public partial class foo : fooBase {"
}
)]
[InlineData (
"PreprocessTemplateWithExtension",
"foo.g.cs",
new string[] {
"namespace PreprocessTemplateWithExtension {",
"public partial class foo : fooBase {"
}
)]
public void PreprocessLegacy (string projectName, string expectedFilePath, string[] expectedContents)
{
using var ctx = new MSBuildTestContext ();
var project = ctx.LoadTestProject ("PreprocessTemplate")
var project = ctx.LoadTestProject (projectName)
.WithProperty ("UseLegacyT4Preprocessing", "true");

var instance = project.Build ("TransformTemplates");

var generatedFilePath = project.DirectoryPath["foo.cs"].AssertTextStartsWith ("//--------");
var generatedFilePath = project.DirectoryPath[expectedFilePath]
.AssertContainsText
(
StringComparison.Ordinal,
expectedContents
);

instance.AssertSingleItem ("PreprocessedTemplates", generatedFilePath);
instance.AssertNoItems ("GeneratedTemplates");
}

[Fact]
public void PreprocessOnBuild ()
[Theory]
[InlineData (
"PreprocessTemplate",
"TextTransform/foo.cs",
"PreprocessTemplate.foo"
)]
[InlineData (
"PreprocessTemplateFromRelativePath",
"TextTransform/Nested/Template/Folder/foo.cs",
"PreprocessTemplateFromRelativePath.Nested.Template.Folder.foo"
)]
[InlineData (
"PreprocessTemplateWithExtension",
"TextTransform/foo.g.cs",
"PreprocessTemplateWithExtension.foo"
)]
public void PreprocessOnBuild (string projectName, string expectedFilePath, string expectedType)
{
using var ctx = new MSBuildTestContext ();
var project = ctx.LoadTestProject ("PreprocessTemplate");
var project = ctx.LoadTestProject (projectName);

project.Restore ();

var instance = project.Build ("Build");
var objDir = project.DirectoryPath["obj", "Debug", "netstandard2.0"];

var generatedFilePath = instance.GetIntermediateDirFile ("TextTransform", "foo.cs")
var generatedFilePath = instance.GetIntermediateDirFile (expectedFilePath)
.AssertTextStartsWith ("//--------");

instance.AssertSingleItem ("PreprocessedTemplates", generatedFilePath);
instance.AssertNoItems ("GeneratedTemplates");

instance.GetTargetPath ()
.AssertFileName ("PreprocessTemplate.dll")
.AssertAssemblyContainsType ("PreprocessTemplate.foo");
.AssertFileName ($"{projectName}.dll")
.AssertAssemblyContainsType (expectedType);
}

[Fact]
public void PreprocessOnDesignTimeBuild ()
[Theory]
[InlineData (
"PreprocessTemplate",
"TextTransform/foo.cs"
)]
[InlineData (
"PreprocessTemplateFromRelativePath",
"TextTransform/Nested/Template/Folder/foo.cs"
)]
[InlineData (
"PreprocessTemplateWithExtension",
"TextTransform/foo.g.cs"
)]
public void PreprocessOnDesignTimeBuild (string projectName, string expectedFilePath)
{
using var ctx = new MSBuildTestContext ();
var project = ctx.LoadTestProject ("PreprocessTemplate")
var project = ctx.LoadTestProject (projectName)
.WithProperty ("DesignTimeBuild", "true")
.WithProperty ("SkipCompilerExecution", "true");

project.Restore ();

var instance = project.Build ("CoreCompile");

var generatedFilePath = instance.GetIntermediateDirFile ("TextTransform", "foo.cs")
var generatedFilePath = instance.GetIntermediateDirFile (expectedFilePath)
.AssertTextStartsWith ("//--------");

instance.AssertSingleItem ("PreprocessedTemplates", generatedFilePath);
instance.AssertNoItems ("GeneratedTemplates");
}

[Fact]
public void PreprocessLegacyMetadata ()
{
// Arrange
using var ctx = new MSBuildTestContext ();
var project = ctx.LoadTestProject ("PreprocessTemplateMetadata")
.WithProperty ("UseLegacyT4Preprocessing", "true");

var outputDirectory = project.DirectoryPath["Demo/Output/OutputDirectory.cs"];
var outputFilePath = project.DirectoryPath["Demo/LegacyOutput/OutputFilePath.cs"];
var outputFileName = project.DirectoryPath["Demo/OutputFileNameTest.cs"];
var outputFileNameAndOutputDirectory = project.DirectoryPath["Demo/Output/OutputDirectoryAndFileNameTest.g.cs"];

// Act
var instance = project.Build ("TransformTemplates");

// Assert
Assert.Multiple (() => {
outputDirectory.AssertContainsText
(
StringComparison.Ordinal,
"namespace PreprocessTemplateMetadata.Demo.Output {",
"partial class OutputDirectory"
);

outputFilePath.AssertContainsText
(
StringComparison.Ordinal,
"namespace PreprocessTemplateMetadata.Demo.LegacyOutput {",
"partial class OutputFilePath"
);

outputFileName.AssertContainsText
(
StringComparison.Ordinal,
"namespace PreprocessTemplateMetadata.Demo {",
"partial class OutputFileNameTest"
);

outputFileNameAndOutputDirectory.AssertContainsText
(
StringComparison.Ordinal,
"namespace PreprocessTemplateMetadata.Demo.Output {",
"partial class OutputDirectoryAndFileNameTest"
);
});

instance.AssertNoItems ("GeneratedTemplates");
}

[Fact]
public void IncrementalTransform ()
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<#@ template language="C#" #>
Hello World
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="$(TemplatingTargetsPath)\T4.BuildTools.props" />

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<T4Preprocess Include="./Nested/Template/Folder/foo.tt" />
<PackageReference Include="System.CodeDom" Version="5.0.0" />
</ItemGroup>

<Import Project="$(TemplatingTargetsPath)\T4.BuildTools.targets" />
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<#@ template language="C#" #>
Hello Item Metadata OutputDirectory
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<#@ template language="C#" #>
Hello Item Metadata OutputDirectory And OutputDFileName
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<#@ template language="C#" #>
<#@ output extension=".generated.cs" #>
Hello Item Metadata OutputDFileName
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<#@ template language="C#" #>
Hello Item Metadata OutputFilePath
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="$(TemplatingTargetsPath)\T4.BuildTools.props" />

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<T4Preprocess Include="OutputDirectory.tt">
<OutputDirectory>Demo/Output</OutputDirectory>
</T4Preprocess>
<T4Preprocess Include="OutputFilePath.tt">
<OutputFilePath>Demo/LegacyOutput</OutputFilePath>
</T4Preprocess>
<T4Preprocess Include="OutputFileName.tt">
<OutputFileName>Demo/OutputFileNameTest.cs</OutputFileName>
</T4Preprocess>
<T4Preprocess Include="OutputDirectoryAndOutputFileName.tt">
<OutputDirectory>Demo/Output</OutputDirectory>
<OutputFileName>OutputDirectoryAndFileNameTest.g.cs</OutputFileName>
</T4Preprocess>
<PackageReference Include="System.CodeDom" Version="5.0.0" />
</ItemGroup>

<Import Project="$(TemplatingTargetsPath)\T4.BuildTools.targets" />
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="$(TemplatingTargetsPath)\T4.BuildTools.props" />

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<T4Preprocess Include="foo.tt" />
<PackageReference Include="System.CodeDom" Version="5.0.0" />
</ItemGroup>

<Import Project="$(TemplatingTargetsPath)\T4.BuildTools.targets" />
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<#@ template language="C#" #>
<#@ output extension=".g.cs" #>
Hello World
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<#@ template language="C#" #>
<#@ parameter name="Year" type="int" #>
<#@ parameter name="Greeting" #>
<#=Greeting#> <#=Year#>!
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="$(TemplatingTargetsPath)\T4.BuildTools.props" />

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<T4Transform Include="Nested\Template\Folder\foo.tt" />
<T4Argument Include="Greeting=Hello" />
<T4Argument Include="Year" Value="2024" />
</ItemGroup>

<Import Project="$(TemplatingTargetsPath)\T4.BuildTools.targets" />
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<#@ template language="C#" #>
<#@ parameter name="Year" type="int" #>
<#@ parameter name="Greeting" #>
<#=Greeting#> OutputDirectory <#=Year#>!
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<#@ template language="C#" #>
<#@ parameter name="Year" type="int" #>
<#@ parameter name="Greeting" #>
<#=Greeting#> OutputDirectory and OutputFileName <#=Year#>!
Loading

0 comments on commit 381de2d

Please sign in to comment.