From dce01381b90b1368377bf480cfbe1489f201748e Mon Sep 17 00:00:00 2001 From: RTLCoil Date: Sat, 1 Aug 2020 11:33:19 +0300 Subject: [PATCH 1/2] Fix normalize_expression for complex cases --- .../transformation/BaseExpression.java | 22 ++- .../transformation/ExpressionTest.java | 177 ++++++++++++++++++ 2 files changed, 196 insertions(+), 3 deletions(-) create mode 100644 cloudinary-core/src/test/java/com/cloudinary/transformation/ExpressionTest.java diff --git a/cloudinary-core/src/main/java/com/cloudinary/transformation/BaseExpression.java b/cloudinary-core/src/main/java/com/cloudinary/transformation/BaseExpression.java index 43415e4d..0da9d702 100644 --- a/cloudinary-core/src/main/java/com/cloudinary/transformation/BaseExpression.java +++ b/cloudinary-core/src/main/java/com/cloudinary/transformation/BaseExpression.java @@ -53,6 +53,7 @@ public abstract class BaseExpression { ); private static final Pattern PATTERN = getPattern(); + private static final Pattern USER_VARIABLE_PATTERN = Pattern.compile("\\$_*[^_]+"); protected List expressions = null; protected Transformation parent = null; @@ -77,10 +78,25 @@ public static String normalize(Object expression) { return String.valueOf(expression); } - String replacement; String conditionStr = StringUtils.mergeToSingleUnderscore(String.valueOf(expression)); - Matcher matcher = PATTERN.matcher(conditionStr); - StringBuffer result = new StringBuffer(conditionStr.length()); + + Matcher m = USER_VARIABLE_PATTERN.matcher(conditionStr); + StringBuilder builder = new StringBuilder(); + int lastMatchEnd = 0; + while (m.find()) { + String beforeMatch = conditionStr.substring(lastMatchEnd, m.start()); + builder.append(normalizeBuiltins(beforeMatch)); + builder.append(m.group()); + lastMatchEnd = m.end(); + } + builder.append(normalizeBuiltins(conditionStr.substring(lastMatchEnd))); + return builder.toString(); + } + + private static String normalizeBuiltins(String input) { + String replacement; + Matcher matcher = PATTERN.matcher(input); + StringBuffer result = new StringBuffer(input.length()); while (matcher.find()) { if (OPERATORS.containsKey(matcher.group())) { replacement = (String) OPERATORS.get(matcher.group()); diff --git a/cloudinary-core/src/test/java/com/cloudinary/transformation/ExpressionTest.java b/cloudinary-core/src/test/java/com/cloudinary/transformation/ExpressionTest.java new file mode 100644 index 00000000..733f1a2a --- /dev/null +++ b/cloudinary-core/src/test/java/com/cloudinary/transformation/ExpressionTest.java @@ -0,0 +1,177 @@ +package com.cloudinary.transformation; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +public class ExpressionTest { + + @Test + public void normalize_null_null() { + String result = Expression.normalize(null); + assertNull(result); + } + + @Test + public void normalize_number_number() { + String result = Expression.normalize(10); + assertEquals("10", result); + } + + @Test + public void normalize_emptyString_emptyString() { + String result = Expression.normalize(""); + assertEquals("", result); + } + + @Test + public void normalize_singleSpace_underscore() { + String result = Expression.normalize(" "); + assertEquals("_", result); + } + + @Test + public void normalize_blankString_underscore() { + String result = Expression.normalize(" "); + assertEquals("_", result); + } + + @Test + public void normalize_underscore_underscore() { + String result = Expression.normalize("_"); + assertEquals("_", result); + } + + @Test + public void normalize_underscores_underscore() { + String result = Expression.normalize("___"); + assertEquals("_", result); + } + + @Test + public void normalize_underscoresAndSpaces_underscore() { + String result = Expression.normalize(" _ __ _"); + assertEquals("_", result); + } + + @Test + public void normalize_arbitraryText_isNotAffected() { + String result = Expression.normalize("foobar"); + assertEquals("foobar", result); + } + + @Test + public void normalize_doubleAmpersand_replacedWithAndOperator() { + String result = Expression.normalize("foo && bar"); + assertEquals("foo_and_bar", result); + } + + @Test + public void normalize_doubleAmpersandWithNoSpaceAtEnd_isNotAffected() { + String result = Expression.normalize("foo&&bar"); + assertEquals("foo&&bar", result); + } + + @Test + public void normalize_width_recognizedAsVariableAndReplacedWithW() { + String result = Expression.normalize("width"); + assertEquals("w", result); + } + + @Test + public void normalize_initialAspectRatio_recognizedAsVariableAndReplacedWithW() { + String result = Expression.normalize("initial_aspect_ratio"); + assertEquals("iar", result); + } + + @Test + public void normalize_dollarWidth_recognizedAsUserVariableAndNotAffected() { + String result = Expression.normalize("$width"); + assertEquals("$width", result); + } + + @Test + public void normalize_dollarInitialAspectRatio_recognizedAsUserVariableAndAsVariableReplacedWithAr() { + String result = Expression.normalize("$initial_aspect_ratio"); + assertEquals("$initial_ar", result); + } + + @Test + public void normalize_dollarMyWidth_recognizedAsUserVariableAndNotAffected() { + String result = Expression.normalize("$mywidth"); + assertEquals("$mywidth", result); + } + + @Test + public void normalize_dollarWidthWidth_recognizedAsUserVariableAndNotAffected() { + String result = Expression.normalize("$widthwidth"); + assertEquals("$widthwidth", result); + } + + @Test + public void normalize_dollarUnderscoreWidth_recognizedAsUserVariableAndNotAffected() { + String result = Expression.normalize("$_width"); + assertEquals("$_width", result); + } + + @Test + public void normalize_dollarUnderscoreX2Width_recognizedAsUserVariableAndNotAffected() { + String result = Expression.normalize("$__width"); + assertEquals("$_width", result); + } + + @Test + public void normalize_dollarX2Width_recognizedAsUserVariableAndNotAffected() { + String result = Expression.normalize("$$width"); + assertEquals("$$width", result); + } + + @Test + public void normalize_doesntReplaceVariable_1() { + String actual = Expression.normalize("$height_100"); + assertEquals("$height_100", actual); + } + + @Test + public void normalize_doesntReplaceVariable_2() { + String actual = Expression.normalize("$heightt_100"); + assertEquals("$heightt_100", actual); + } + + @Test + public void normalize_doesntReplaceVariable_3() { + String actual = Expression.normalize("$$height_100"); + assertEquals("$$height_100", actual); + } + + @Test + public void normalize_doesntReplaceVariable_4() { + String actual = Expression.normalize("$heightmy_100"); + assertEquals("$heightmy_100", actual); + } + + @Test + public void normalize_doesntReplaceVariable_5() { + String actual = Expression.normalize("$myheight_100"); + assertEquals("$myheight_100", actual); + } + + @Test + public void normalize_doesntReplaceVariable_6() { + String actual = Expression.normalize("$heightheight_100"); + assertEquals("$heightheight_100", actual); + } + + @Test + public void normalize_doesntReplaceVariable_7() { + String actual = Expression.normalize("$theheight_100"); + assertEquals("$theheight_100", actual); + } + + @Test + public void normalize_doesntReplaceVariable_8() { + String actual = Expression.normalize("$__height_100"); + assertEquals("$_height_100", actual); + } +} \ No newline at end of file From aab097fcfe47f43e0e05f715839ac49e078ad7e2 Mon Sep 17 00:00:00 2001 From: RTLCoil Date: Thu, 3 Sep 2020 23:57:29 +0300 Subject: [PATCH 2/2] Fix review comments --- .../test/java/com/cloudinary/TransformationTest.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/cloudinary-core/src/test/java/com/cloudinary/TransformationTest.java b/cloudinary-core/src/test/java/com/cloudinary/TransformationTest.java index cadb8a97..0259dcc4 100644 --- a/cloudinary-core/src/test/java/com/cloudinary/TransformationTest.java +++ b/cloudinary-core/src/test/java/com/cloudinary/TransformationTest.java @@ -276,4 +276,16 @@ public void testRadiusArray2() { assertEquals("r_10:$v", t.generate()); } + + @Test + public void testUserVariableNamesContainingPredefinedNamesAreNotAffected() { + Transformation t = new Transformation() + .variable("$mywidth", "100") + .variable("$aheight", 300) + .chain() + .width("3 + $mywidth * 3 + 4 / 2 * initialWidth * $mywidth") + .height("3 * initialHeight + $aheight"); + + assertEquals("$aheight_300,$mywidth_100/h_3_mul_ih_add_$aheight,w_3_add_$mywidth_mul_3_add_4_div_2_mul_iw_mul_$mywidth", t.generate()); + } } \ No newline at end of file