From bd6a24b833653824fa2853ff8aac37990992a6e5 Mon Sep 17 00:00:00 2001 From: Vlada Shubina Date: Fri, 4 Nov 2022 16:38:03 +0100 Subject: [PATCH] improved `CoalesceMacro` logic --- .../Macros/CoalesceMacro.cs | 27 ++++++++++++--- .../MacroTests/CoalesceMacroTests.cs | 34 +++++++++++++++++-- 2 files changed, 55 insertions(+), 6 deletions(-) diff --git a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/Macros/CoalesceMacro.cs b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/Macros/CoalesceMacro.cs index 7cce7b505c2..6f2850c9b4f 100644 --- a/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/Macros/CoalesceMacro.cs +++ b/src/Microsoft.TemplateEngine.Orchestrator.RunnableProjects/Macros/CoalesceMacro.cs @@ -19,15 +19,34 @@ public override void Evaluate(IEngineEnvironmentSettings environmentSettings, IV { if (variableCollection.TryGetValue(config.SourceVariableName, out object currentSourceValue) && currentSourceValue != null) { - if (config.DefaultValue != null && currentSourceValue.Equals(config.DefaultValue)) + if (config.DefaultValue != null && currentSourceValue.ToString().Equals(config.DefaultValue)) { environmentSettings.Host.Logger.LogDebug("[{macro}]: '{var}': source value '{source}' is not used, because it is equal to default value '{default}'.", nameof(CoalesceMacro), config.VariableName, currentSourceValue, config.DefaultValue); } else { - variableCollection[config.VariableName] = currentSourceValue; - environmentSettings.Host.Logger.LogDebug("[{macro}]: Assigned variable '{var}' to '{value}'.", nameof(CoalesceMacro), config.VariableName, currentSourceValue); - return; + if (currentSourceValue is string str && string.IsNullOrEmpty(str)) + { + //do nothing, empty value for string is equivalent to null. + environmentSettings.Host.Logger.LogDebug("[{macro}]: '{var}': source value '{source}' is an empty string, fall back.", nameof(CoalesceMacro), config.VariableName, currentSourceValue); + } + else if (currentSourceValue.GetType().IsValueType && Activator.CreateInstance(currentSourceValue.GetType()).Equals(currentSourceValue)) + { + //do nothing, the value is a value type and is a default. + environmentSettings.Host.Logger.LogDebug( + "[{macro}]: '{var}': source value '{source}' of type '{type}' is equivalent to its default value '{default}', fall back.", + nameof(CoalesceMacro), + config.VariableName, + config.SourceVariableName, + currentSourceValue.GetType().Name, + currentSourceValue); + } + else + { + variableCollection[config.VariableName] = currentSourceValue; + environmentSettings.Host.Logger.LogDebug("[{macro}]: Assigned variable '{var}' to '{value}'.", nameof(CoalesceMacro), config.VariableName, currentSourceValue); + return; + } } } if (variableCollection.TryGetValue(config.FallbackVariableName, out object currentFallbackValue) && currentFallbackValue != null) diff --git a/test/Microsoft.TemplateEngine.Orchestrator.RunnableProjects.UnitTests/MacroTests/CoalesceMacroTests.cs b/test/Microsoft.TemplateEngine.Orchestrator.RunnableProjects.UnitTests/MacroTests/CoalesceMacroTests.cs index 049ed019c14..aa41e46c73c 100644 --- a/test/Microsoft.TemplateEngine.Orchestrator.RunnableProjects.UnitTests/MacroTests/CoalesceMacroTests.cs +++ b/test/Microsoft.TemplateEngine.Orchestrator.RunnableProjects.UnitTests/MacroTests/CoalesceMacroTests.cs @@ -3,6 +3,8 @@ using System; using System.Collections.Generic; +using System.Linq; +using Microsoft.Extensions.Logging; using Microsoft.TemplateEngine.Abstractions; using Microsoft.TemplateEngine.Core; using Microsoft.TemplateEngine.Orchestrator.RunnableProjects.ConfigModel; @@ -16,17 +18,19 @@ namespace Microsoft.TemplateEngine.Orchestrator.RunnableProjects.UnitTests.Macro public class CoalesceMacroTests : IClassFixture { private readonly IEngineEnvironmentSettings _engineEnvironmentSettings; + private readonly EnvironmentSettingsHelper _environmentSettingsHelper; public CoalesceMacroTests(EnvironmentSettingsHelper environmentSettingsHelper) { _engineEnvironmentSettings = environmentSettingsHelper.CreateEnvironment(hostIdentifier: GetType().Name, virtualize: true); + _environmentSettingsHelper = environmentSettingsHelper; } [Theory] [InlineData(null, null, null, null)] [InlineData("", "", null, "")] [InlineData(null, "fallback", null, "fallback")] - [InlineData("", "fallback", null, "")] + [InlineData("", "fallback", null, "fallback")] [InlineData("def", "fallback", "def", "fallback")] [InlineData("def", "fallback", "", "def")] public void CoalesceMacroTest(string? sourceValue, string? fallbackValue, string? defaultValue, string? expectedResult) @@ -60,7 +64,7 @@ public void CoalesceMacroTest(string? sourceValue, string? fallbackValue, string [InlineData(null, null, null, null)] [InlineData("", "", null, "")] [InlineData(null, "fallback", null, "fallback")] - [InlineData("", "fallback", null, "")] + [InlineData("", "fallback", null, "fallback")] [InlineData("def", "fallback", "def", "fallback")] [InlineData("def", "fallback", "", "def")] public void GeneratedSymbolTest(string? sourceValue, string? fallbackValue, string? defaultValue, string? expectedResult) @@ -99,6 +103,32 @@ public void GeneratedSymbolTest(string? sourceValue, string? fallbackValue, stri } } + [Fact] + public void GeneratedSymbolTest_DefaultValueLeadsToFallback() + { + List<(LogLevel Level, string Message)> loggedMessages = new(); + InMemoryLoggerProvider loggerProvider = new(loggedMessages); + IEngineEnvironmentSettings environmentSettings = _environmentSettingsHelper.CreateEnvironment(virtualize: true, addLoggerProviders: new[] { loggerProvider }); + + CoalesceMacro macro = new(); + + Dictionary jsonParameters = new(StringComparer.OrdinalIgnoreCase) + { + { "sourceVariableName", JExtensions.ToJsonString("varA") }, + { "fallbackVariableName", JExtensions.ToJsonString("varB") } + }; + + VariableCollection variables = new() + { + ["varA"] = 0, + ["varB"] = 10 + }; + + macro.Evaluate(environmentSettings, variables, new GeneratedSymbol("test", "coalesce", jsonParameters)); + Assert.Equal(10, variables["test"]); + Assert.Equal("[CoalesceMacro]: 'test': source value 'varA' of type 'Int32' is equivalent to its default value '0', fall back.", loggedMessages.First().Message); + } + [Fact] public void InvalidConfigurationTest_Source() {