diff --git a/test/Microsoft.TemplateEngine.Core.UnitTests/ConditionalTests.CStyleEvaluator.cs b/test/Microsoft.TemplateEngine.Core.UnitTests/ConditionalTests.CStyleEvaluator.cs index 5bceb15c582..eb426095485 100644 --- a/test/Microsoft.TemplateEngine.Core.UnitTests/ConditionalTests.CStyleEvaluator.cs +++ b/test/Microsoft.TemplateEngine.Core.UnitTests/ConditionalTests.CStyleEvaluator.cs @@ -1,6 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable enable + using System.Globalization; using System.IO; using System.Text; @@ -1633,8 +1635,7 @@ public void VerifyMisstypedIfTokenDoesntCrash(string varName, bool varValue) { string value = @"#ifdef GAGA -#endif -"; +#endif"; string expected = varName == "def" && varValue ? @"GAGA " : ""; diff --git a/test/Microsoft.TemplateEngine.Core.UnitTests/ConditionalTests.XmlBlockComments.cs b/test/Microsoft.TemplateEngine.Core.UnitTests/ConditionalTests.XmlBlockComments.cs index a126d849279..99aa5c27772 100644 --- a/test/Microsoft.TemplateEngine.Core.UnitTests/ConditionalTests.XmlBlockComments.cs +++ b/test/Microsoft.TemplateEngine.Core.UnitTests/ConditionalTests.XmlBlockComments.cs @@ -1,7 +1,11 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#nullable enable + using System.Collections.Generic; +using System.IO; +using System.Text; using Microsoft.TemplateEngine.Core.Contracts; using Xunit; @@ -1341,5 +1345,31 @@ Trailing stuff RunAndVerify(test, outerElseHappensExpectedValue, processor, 9999); } } + +#pragma warning disable xUnit1004 // Test methods should not be skipped + [Fact(Skip = "https://github.com/dotnet/templating/issues/4988")] +#pragma warning restore xUnit1004 // Test methods should not be skipped + public void VerifyXMLConditionAtEnd() + { + string value = @"Hello + +"; + string expected = @"Hello +"; + + byte[] valueBytes = Encoding.UTF8.GetBytes(value); + MemoryStream input = new MemoryStream(valueBytes); + MemoryStream output = new MemoryStream(); + + VariableCollection vc = new VariableCollection(); + IProcessor processor = SetupXmlStyleProcessor(vc); + + //Changes should be made + bool changed = processor.Run(input, output, 50); + Verify(Encoding.UTF8, output, changed, value, expected); + } + } } diff --git a/test/Microsoft.TemplateEngine.Orchestrator.RunnableProjects.UnitTests/RunnableProjectGeneratorTests.cs b/test/Microsoft.TemplateEngine.Orchestrator.RunnableProjects.UnitTests/RunnableProjectGeneratorTests.cs index a975d6153f3..63e1deb3ad0 100644 --- a/test/Microsoft.TemplateEngine.Orchestrator.RunnableProjects.UnitTests/RunnableProjectGeneratorTests.cs +++ b/test/Microsoft.TemplateEngine.Orchestrator.RunnableProjects.UnitTests/RunnableProjectGeneratorTests.cs @@ -642,5 +642,176 @@ public async void Test_CoaleseWithInvalidSetup() string resultContent = settings.Host.FileSystem.ReadAllText(Path.Combine(targetDir, "sourceFile")); Assert.Equal(expectedSnippet, resultContent); } + +#pragma warning disable xUnit1004 // Test methods should not be skipped + [Fact(Skip = "https://github.com/dotnet/templating/issues/4988")] +#pragma warning restore xUnit1004 // Test methods should not be skipped + public async void XMLConditionFailure() + { + // + // Template content preparation + // + + var templateConfig = new + { + identity = "test.template", + symbols = new + { + A = new + { + type = "parameter", + dataType = "bool", + defaultValue = "false" + }, + B = new + { + type = "parameter", + dataType = "bool", + defaultValue = "false" + }, + } + }; + + string sourceSnippet = @" + + +foo + + +This text should not be generated, just to make file content longer to prove the bug. +If the buffer is advanced when evaluating condition, the bug won't be reproduced. +This text ensures that buffer is long enough even considering very-very-long env variable names available on CI machine. + +"; + + string expectedSnippet = @" + +foo +"; + + IDictionary templateSourceFiles = new Dictionary + { + // template.json + { TestFileSystemHelper.DefaultConfigRelativePath, JsonConvert.SerializeObject(templateConfig, Formatting.Indented) }, + + //content + { "sourceFile.md", sourceSnippet } + }; + + // + // Dependencies preparation and mounting + // + IEngineEnvironmentSettings settings = _environmentSettingsHelper.CreateEnvironment(virtualize: true); + string sourceBasePath = FileSystemHelpers.GetNewVirtualizedPath(settings); + string targetDir = FileSystemHelpers.GetNewVirtualizedPath(settings); + + TestFileSystemHelper.WriteTemplateSource(settings, sourceBasePath, templateSourceFiles); + IMountPoint? sourceMountPoint = TestFileSystemHelper.CreateMountPoint(settings, sourceBasePath); + RunnableProjectGenerator rpg = new(); + + TemplateConfigModel configModel = TemplateConfigModel.FromJObject(JObject.FromObject(templateConfig)); + RunnableProjectConfig runnableConfig = new(settings, rpg, configModel, sourceMountPoint.FileInfo(TestFileSystemHelper.DefaultConfigRelativePath)); + ParameterSetData parameters = new( + runnableConfig, + new Dictionary() { { "A", true } }); + IDirectory sourceDir = sourceMountPoint!.DirectoryInfo("/")!; + + // + // Running the actual scenario: template files processing and generating output (including macros processing) + // + await rpg.CreateAsync(settings, runnableConfig, sourceDir, parameters, targetDir, CancellationToken.None); + + // + // Veryfying the outputs + // + + string resultContent = settings.Host.FileSystem.ReadAllText(Path.Combine(targetDir, "sourceFile.md")); + Assert.Equal(expectedSnippet, resultContent); + } + +#pragma warning disable xUnit1004 // Test methods should not be skipped + [Fact(Skip = "https://github.com/dotnet/templating/issues/4988")] +#pragma warning restore xUnit1004 // Test methods should not be skipped + public async void HashConditionFailure() + { + // + // Template content preparation + // + + var templateConfig = new + { + identity = "test.template", + symbols = new + { + A = new + { + type = "parameter", + dataType = "bool", + defaultValue = "false" + }, + B = new + { + type = "parameter", + dataType = "bool", + defaultValue = "false" + }, + } + }; + + string sourceSnippet = @" +#if (A) +# comment foo +foo +#endif +##if (B) +This text should not be generated, just to make file content longer to prove the bug. +If the buffer is advanced when evaluating condition, the bug won't be reproduced. +This text ensures that buffer is long enough even considering very-very-long env variable names available on CI machine. +#endif +"; + + string expectedSnippet = @" +# comment foo +foo +"; + + IDictionary templateSourceFiles = new Dictionary + { + // template.json + { TestFileSystemHelper.DefaultConfigRelativePath, JsonConvert.SerializeObject(templateConfig, Formatting.Indented) }, + + //content + { "sourceFile.yaml", sourceSnippet } + }; + + // + // Dependencies preparation and mounting + // + IEngineEnvironmentSettings settings = _environmentSettingsHelper.CreateEnvironment(virtualize: true); + string sourceBasePath = FileSystemHelpers.GetNewVirtualizedPath(settings); + string targetDir = FileSystemHelpers.GetNewVirtualizedPath(settings); + + TestFileSystemHelper.WriteTemplateSource(settings, sourceBasePath, templateSourceFiles); + IMountPoint? sourceMountPoint = TestFileSystemHelper.CreateMountPoint(settings, sourceBasePath); + RunnableProjectGenerator rpg = new(); + TemplateConfigModel configModel = TemplateConfigModel.FromJObject(JObject.FromObject(templateConfig)); + RunnableProjectConfig runnableConfig = new(settings, rpg, configModel, sourceMountPoint.FileInfo(TestFileSystemHelper.DefaultConfigRelativePath)); + ParameterSetData parameters = new( + runnableConfig, + new Dictionary() { { "A", true } }); + IDirectory sourceDir = sourceMountPoint!.DirectoryInfo("/")!; + + // + // Running the actual scenario: template files processing and generating output (including macros processing) + // + await rpg.CreateAsync(settings, runnableConfig, sourceDir, parameters, targetDir, CancellationToken.None); + + // + // Veryfying the outputs + // + + string resultContent = settings.Host.FileSystem.ReadAllText(Path.Combine(targetDir, "sourceFile.yaml")); + Assert.Equal(expectedSnippet, resultContent); + } } } diff --git a/test/Microsoft.TemplateEngine.TestHelper/TestHost.cs b/test/Microsoft.TemplateEngine.TestHelper/TestHost.cs index 5544c1549cf..314582df70f 100644 --- a/test/Microsoft.TemplateEngine.TestHelper/TestHost.cs +++ b/test/Microsoft.TemplateEngine.TestHelper/TestHost.cs @@ -52,7 +52,7 @@ internal TestHost( _loggerFactory = new TestLoggerFactory(); addLoggerProviders?.ToList().ForEach(_loggerFactory.AddProvider); - _logger = _loggerFactory.CreateLogger("Test Host"); + _logger = _loggerFactory.CreateLogger(hostIdentifier); _fallbackNames = fallbackNames ?? new[] { "dotnetcli" }; }