diff --git a/Shared.Tests/Transformations/Common/ExpressionTest.cs b/Shared.Tests/Transformations/Common/ExpressionTest.cs index 13940203..fa1b5c0b 100644 --- a/Shared.Tests/Transformations/Common/ExpressionTest.cs +++ b/Shared.Tests/Transformations/Common/ExpressionTest.cs @@ -309,5 +309,38 @@ public void TestShouldSupportPowOperator() Assert.AreEqual("$small_150,$big_$small_pow_1.5", transformation.Generate()); } + + [TestCase(null, null)] + [TestCase("", null)] + [TestCase(" ", "_")] + [TestCase(" ", "_")] + [TestCase("_", "_")] + [TestCase("___", "_")] + [TestCase(" _ __ _", "_")] + [TestCase("foobar", "foobar")] + [TestCase("foo && bar", "foo_and_bar")] + [TestCase("foo&&bar", "foo&&bar")] + [TestCase("width", "w")] + [TestCase("initial_aspect_ratio", "iar")] + [TestCase("$width", "$width")] + [TestCase("$initial_aspect_ratio", "$initial_ar")] + [TestCase("$mywidth", "$mywidth")] + [TestCase("$widthwidth", "$widthwidth")] + [TestCase("$_width", "$_width")] + [TestCase("$__width", "$_width")] + [TestCase("$$width", "$$width")] + [TestCase("$height_100", "$height_100")] + [TestCase("$heightt_100", "$heightt_100")] + [TestCase("$$height_100", "$$height_100")] + [TestCase("$heightmy_100", "$heightmy_100")] + [TestCase("$myheight_100", "$myheight_100")] + [TestCase("$heightheight_100", "$heightheight_100")] + [TestCase("$theheight_100", "$theheight_100")] + [TestCase("$__height_100", "$_height_100")] + public void TestNormalizeExpressionComplexCases(string expression, string expected) + { + var actual = Expression.Normalize(expression); + Assert.AreEqual(expected, actual); + } } } diff --git a/Shared.Tests/Transformations/Common/TransformationTest.cs b/Shared.Tests/Transformations/Common/TransformationTest.cs index cca03561..f5dcf0d4 100644 --- a/Shared.Tests/Transformations/Common/TransformationTest.cs +++ b/Shared.Tests/Transformations/Common/TransformationTest.cs @@ -171,5 +171,19 @@ public void TestVideoLayersUnmodifiableFields() Assert.Throws(() => textLayer.Format(testValue)); Assert.Throws(() => textLayer.Type(testValue)); } + + [Test] + public void TestUserVariableNamesContainingPredefinedNamesAreNotAffected() + { + var transformation = new Transformation() + .Variable("$mywidth", "100") + .Variable("$aheight", 300) + .Chain() + .Width("3 + $mywidth * 3 + 4 / 2 * initialWidth * $mywidth") + .Height("3 * initialHeight + $aheight"); + + const string expected = "$aheight_300,$mywidth_100/h_3_mul_ih_add_$aheight,w_3_add_$mywidth_mul_3_add_4_div_2_mul_iw_mul_$mywidth"; + Assert.AreEqual(expected, transformation.Generate()); + } } } diff --git a/Shared/Transforms/BaseExpression.cs b/Shared/Transforms/BaseExpression.cs index ebfd2555..ce9f2487 100644 --- a/Shared/Transforms/BaseExpression.cs +++ b/Shared/Transforms/BaseExpression.cs @@ -104,8 +104,25 @@ public static string Normalize(string expression) } expression = Regex.Replace(expression, "[ _]+", "_"); - string pattern = GetPattern(); - return Regex.Replace(expression, pattern, m => GetOperatorReplacement(m.Value)); + const string userVariablePattern = "\\$_*[^_]+"; + + var generalPattern = GetPattern(); + var matcher = new Regex(userVariablePattern, RegexOptions.IgnoreCase).Match(expression); + var sb = new StringBuilder(); + var lastMatchEnd = 0; + while (matcher.Success) + { + var matcherGroup = matcher.Groups[0]; + var beforeMatch = expression.Substring(lastMatchEnd, matcherGroup.Index - lastMatchEnd); + sb.Append(Regex.Replace(beforeMatch, generalPattern, m => GetOperatorReplacement(m.Value))); + sb.Append(matcherGroup.Value); + lastMatchEnd = matcherGroup.Index + matcherGroup.Length; + matcher = matcher.NextMatch(); + } + + var tail = expression.Substring(lastMatchEnd); + sb.Append(Regex.Replace(tail, generalPattern, m => GetOperatorReplacement(m.Value))); + return sb.ToString(); } ///