From fc19e3a5b870db0751ab0add444ce32c04284e30 Mon Sep 17 00:00:00 2001 From: Alex Pinhasov Date: Tue, 8 Feb 2022 22:21:41 +0200 Subject: [PATCH 1/6] Add support for variables in text style. --- .../Helpers/Layers/CLDTextLayer.swift | 19 ++++++++++++++++- Example/Tests/GenerateUrlTests/UrlTests.swift | 21 +++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/Cloudinary/Classes/Core/Features/Helpers/Layers/CLDTextLayer.swift b/Cloudinary/Classes/Core/Features/Helpers/Layers/CLDTextLayer.swift index fe34b61c..ab245498 100644 --- a/Cloudinary/Classes/Core/Features/Helpers/Layers/CLDTextLayer.swift +++ b/Cloudinary/Classes/Core/Features/Helpers/Layers/CLDTextLayer.swift @@ -33,6 +33,7 @@ import Foundation internal var fontWeight: String? internal var textDecoration: String? internal var textAlign: String? + internal var textStyle: String? internal var stroke: String? internal var letterSpacing: String? internal var lineSpacing: String? @@ -66,6 +67,19 @@ import Foundation return self } + /** + Sets a text style identifier. + Note: If this is used, all other style attributes are ignored in favor of this identifier + + - parameter text: A variable string or an explicit style (e.g. "Arial_17_bold_antialias_best"). + + - returns: The same instance of CLDTextLayer. + */ + open func setTextStyle(textStyle: String) -> CLDTextLayer { + self.textStyle = textStyle + return self + } + /** Set the name of a font family. e.g. `arial`. @@ -333,7 +347,10 @@ import Foundation let optionalTextParams = getOptionalTextPropertiesArray() let mandatoryTextParams = getMandatoryTextPropertiesArray() - if optionalTextParams.isEmpty { + if let textStyle = textStyle { + components.append([textStyle].joined(separator: "_")) + } + else if optionalTextParams.isEmpty { if !mandatoryTextParams.isEmpty { components.append(mandatoryTextParams.joined(separator: "_")) } diff --git a/Example/Tests/GenerateUrlTests/UrlTests.swift b/Example/Tests/GenerateUrlTests/UrlTests.swift index 45ef0d34..595f46a1 100644 --- a/Example/Tests/GenerateUrlTests/UrlTests.swift +++ b/Example/Tests/GenerateUrlTests/UrlTests.swift @@ -1052,6 +1052,27 @@ class UrlTests: BaseTestCase { XCTAssertEqual(sut?.createUrl().setTransformation(CLDTransformation().setOverlayWithLayer(CLDFetchLayer(url: "https://res.cloudinary.com/demo/image/upload/sample"))).generate("test"), "\(prefix)/image/upload/l_fetch:aHR0cHM6Ly9yZXMuY2xvdWRpbmFyeS5jb20vZGVtby9pbWFnZS91cGxvYWQvc2FtcGxl/test") } + + func testTextStyle() { + XCTAssertEqual(sut?.createUrl().setTransformation(CLDTransformation().setVariable("$style", string: "!Arial_12!").chain().setOverlayWithLayer(CLDTextLayer().setText(text: "hello-world").setTextStyle(textStyle: "$style"))).generate("test"), "\(prefix)/image/upload/$style_!Arial_12!/l_text:$style:hello-world/test") + } + + func testTextStyleOverpowerOtherTextAttributes() { + let layer = CLDTextLayer() + .setText(text: "hello_world") + .setFontFamily(fontFamily: "Arial") + .setFontSize(18) + .setFontStyle(.italic) + .setFontWeight(.bold) + .setLetterSpacing(4) + .setTextStyle(textStyle: "$style") + + let transformation = CLDTransformation().setVariable("$style", string: "!Arial_12!").chain().setOverlayWithLayer(layer) + let url = sut?.createUrl().setTransformation(transformation).generate("test") + + XCTAssertNotNil(url) + XCTAssertFalse(url!.contains("Arial_18_bold_italic_letter_spacing_4"), "$style should overpower other text attributes.") + } func testOverlayErrors() { XCTAssertNil(sut?.createUrl().setTransformation(CLDTransformation().setOverlayWithLayer(CLDTextLayer().setText(text: "text").setFontStyle(.italic))).generate("test")) From 96609c96fd69907c4c29afb8a48eecfbb6cdb859 Mon Sep 17 00:00:00 2001 From: Alex Pinhasov Date: Thu, 10 Feb 2022 10:26:22 +0200 Subject: [PATCH 2/6] Add expression support for text styles --- .../Core/Features/Helpers/CLDExpression.swift | 15 ++++++++------- .../Features/Helpers/Layers/CLDTextLayer.swift | 13 +++++++++++++ Example/Tests/GenerateUrlTests/UrlTests.swift | 2 ++ 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/Cloudinary/Classes/Core/Features/Helpers/CLDExpression.swift b/Cloudinary/Classes/Core/Features/Helpers/CLDExpression.swift index aa3c8cf0..c3cb36fe 100644 --- a/Cloudinary/Classes/Core/Features/Helpers/CLDExpression.swift +++ b/Cloudinary/Classes/Core/Features/Helpers/CLDExpression.swift @@ -286,15 +286,16 @@ import Foundation // MARK: - provide content public func asString() -> String { - guard !currentKey.isEmpty && !currentValue.isEmpty else { - - return String() - } + guard !currentKey.isEmpty else { return String() } - let key = replaceAllExpressionKeys(in: currentKey) - let value = removeExtraDashes(from: replaceAllUnencodeChars(in: currentValue)) + let key = replaceAllExpressionKeys(in: currentKey) - return "\(key)_\(value)" + if currentValue.isEmpty { + return "\(key)" + } else { + let value = removeExtraDashes(from: replaceAllUnencodeChars(in: currentValue)) + return "\(key)_\(value)" + } } public func asParams() -> [String : String] { diff --git a/Cloudinary/Classes/Core/Features/Helpers/Layers/CLDTextLayer.swift b/Cloudinary/Classes/Core/Features/Helpers/Layers/CLDTextLayer.swift index ab245498..0eddf86e 100644 --- a/Cloudinary/Classes/Core/Features/Helpers/Layers/CLDTextLayer.swift +++ b/Cloudinary/Classes/Core/Features/Helpers/Layers/CLDTextLayer.swift @@ -80,6 +80,19 @@ import Foundation return self } + /** + Sets a text style identifier using an expression. + Note: If this is used, all other style attributes are ignored in favor of this identifier + + - parameter text: An expression instance referencing the style. + + - returns: The same instance of CLDTextLayer. + */ + open func setTextStyle(expression: CLDExpression) -> CLDTextLayer { + self.textStyle = expression.asString() + return self + } + /** Set the name of a font family. e.g. `arial`. diff --git a/Example/Tests/GenerateUrlTests/UrlTests.swift b/Example/Tests/GenerateUrlTests/UrlTests.swift index 595f46a1..173ccbd6 100644 --- a/Example/Tests/GenerateUrlTests/UrlTests.swift +++ b/Example/Tests/GenerateUrlTests/UrlTests.swift @@ -1055,6 +1055,8 @@ class UrlTests: BaseTestCase { func testTextStyle() { XCTAssertEqual(sut?.createUrl().setTransformation(CLDTransformation().setVariable("$style", string: "!Arial_12!").chain().setOverlayWithLayer(CLDTextLayer().setText(text: "hello-world").setTextStyle(textStyle: "$style"))).generate("test"), "\(prefix)/image/upload/$style_!Arial_12!/l_text:$style:hello-world/test") + + XCTAssertEqual(sut?.createUrl().setTransformation(CLDTransformation().setVariable("$style", string: "!Arial_12!").chain().setOverlayWithLayer(CLDTextLayer().setText(text: "hello-world").setTextStyle(expression: CLDExpression(value: "$style")))).generate("test"), "\(prefix)/image/upload/$style_!Arial_12!/l_text:$style:hello-world/test") } func testTextStyleOverpowerOtherTextAttributes() { From 9fbe6360577e2ca3372c3dfcc3dbb4eac0e6b124 Mon Sep 17 00:00:00 2001 From: Alex Pinhasov Date: Tue, 15 Feb 2022 12:37:03 +0200 Subject: [PATCH 3/6] Remove redundant else block --- Cloudinary/Classes/Core/Features/Helpers/CLDExpression.swift | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Cloudinary/Classes/Core/Features/Helpers/CLDExpression.swift b/Cloudinary/Classes/Core/Features/Helpers/CLDExpression.swift index c3cb36fe..b8891e9c 100644 --- a/Cloudinary/Classes/Core/Features/Helpers/CLDExpression.swift +++ b/Cloudinary/Classes/Core/Features/Helpers/CLDExpression.swift @@ -292,10 +292,9 @@ import Foundation if currentValue.isEmpty { return "\(key)" - } else { - let value = removeExtraDashes(from: replaceAllUnencodeChars(in: currentValue)) - return "\(key)_\(value)" } + let value = removeExtraDashes(from: replaceAllUnencodeChars(in: currentValue)) + return "\(key)_\(value)" } public func asParams() -> [String : String] { From 57f0c687cc8f915a0447b501498f1af546d7a835 Mon Sep 17 00:00:00 2001 From: Alex Pinhasov Date: Mon, 7 Mar 2022 10:17:56 +0200 Subject: [PATCH 4/6] Add new expression tests, refactor expression keys logic to use regex. --- .../Core/Features/Helpers/CLDExpression.swift | 83 ++-- .../CLDExpressionTests.swift | 358 ++++++++++++++++++ 2 files changed, 414 insertions(+), 27 deletions(-) diff --git a/Cloudinary/Classes/Core/Features/Helpers/CLDExpression.swift b/Cloudinary/Classes/Core/Features/Helpers/CLDExpression.swift index b8891e9c..da3459ff 100644 --- a/Cloudinary/Classes/Core/Features/Helpers/CLDExpression.swift +++ b/Cloudinary/Classes/Core/Features/Helpers/CLDExpression.swift @@ -36,9 +36,9 @@ import Foundation case initial_height case initialHeight + case initial_aspect_ratio case aspect_ratio case aspectRatio - case initial_aspect_ratio case initialAspectRatio case page_count @@ -73,9 +73,9 @@ import Foundation case .initial_height: return "ih" case .initialHeight : return "ih" + case .initial_aspect_ratio: return "iar" case .aspect_ratio : return "ar" case .aspectRatio : return "ar" - case .initial_aspect_ratio: return "iar" case .initialAspectRatio : return "iar" case .page_count: return "pc" @@ -106,7 +106,9 @@ import Foundation internal var currentKey : String private let consecutiveDashesRegex: String = "[ _]+" - + private let consecutiveSpaceRegex: String = "[ ]+" + private let userVariableRegex: String = "\\$_*[^_]+" + // MARK: - Init public override init() { self.currentKey = String() @@ -117,7 +119,7 @@ import Foundation public init(value: String) { var components = value.components(separatedBy: .whitespacesAndNewlines) self.currentKey = components.removeFirst() - self.currentValue = components.joined(separator: CLDVariable.elementsSeparator) + self.currentValue = value == " " ? "_" : components.joined(separator: CLDVariable.elementsSeparator) super.init() } @@ -286,14 +288,20 @@ import Foundation // MARK: - provide content public func asString() -> String { - guard !currentKey.isEmpty else { return String() } - - let key = replaceAllExpressionKeys(in: currentKey) - + guard !currentKey.isEmpty else { + if !currentValue.isEmpty { + return removeExtraSpaces(from: removeExtraDashes(from: replaceAllUnicodeChars(in: currentValue))) + } + return String() + + } + + let key = removeExtraDashes(from: replaceAllExpressionKeys(in: currentKey)) + if currentValue.isEmpty { return "\(key)" } - let value = removeExtraDashes(from: replaceAllUnencodeChars(in: currentValue)) + let value = removeExtraDashes(from: replaceAllUnicodeChars(in: currentValue)) return "\(key)_\(value)" } @@ -305,7 +313,7 @@ import Foundation } let key = replaceAllExpressionKeys(in: currentKey) - let value = removeExtraDashes(from: replaceAllUnencodeChars(in: currentValue)) + let value = removeExtraDashes(from: replaceAllUnicodeChars(in: currentValue)) return [key:value] } @@ -320,7 +328,7 @@ import Foundation } // MARK: - Private methods - private func replaceAllUnencodeChars(in string: String) -> String { + private func replaceAllUnicodeChars(in string: String) -> String { var wipString = string wipString = replaceAllOperators(in: string) @@ -353,26 +361,34 @@ import Foundation return wipString } - + private func replace(expressionKey: ExpressionKeys, in string: String) -> String { - - var result : String - + + var result : String! + if string.contains(CLDVariable.variableNamePrefix) { - - result = string.components(separatedBy: CLDVariable.elementsSeparator).map({ - - let temp : String - switch $0.hasPrefix(CLDVariable.variableNamePrefix) { - case true : temp = $0 - case false: temp = $0.replacingOccurrences(of: expressionKey.rawValue, with: expressionKey.asString) + let string = removeExtraDashes(from: string) + let range = NSRange(location: 0, length: string.utf16.count) + let regex = try? NSRegularExpression(pattern: userVariableRegex) + let allRanges = regex?.matches(in: removeExtraDashes(from: string), options: [], range: range).map({ $0.range }) ?? [] + + // Replace substring in between user variables. e.x $initial_aspect_ratio_$width, only '_aspect_ratio_' will be addressed. + for (index, range) in allRanges.enumerated() { + let location = range.length + range.location + var length = range.length + + if index + 1 == allRanges.count { + length = string.count + } else { + let nextRange = allRanges[index + 1] + length = nextRange.location } - return temp - - }).joined(separator: CLDVariable.elementsSeparator) - + + if let stringRange = Range(NSRange(location: location, length: length - location), in: string) { + result = string.replacingOccurrences(of: expressionKey.rawValue, with: expressionKey.asString, options: .regularExpression, range: stringRange) + } + } } else { - result = string.replacingOccurrences(of: expressionKey.rawValue, with: expressionKey.asString) } return result @@ -403,4 +419,17 @@ import Foundation private func removeExtraDashes(from string: String) -> String { return string.replacingOccurrences(of: consecutiveDashesRegex, with: CLDVariable.elementsSeparator, options: .regularExpression, range: nil) } + + private func removeExtraSpaces(from string: String) -> String { + let regex = try? NSRegularExpression(pattern: consecutiveSpaceRegex) + let range = NSRange(location: 0, length: string.utf16.count) + let isStringOnlySpaces = regex?.firstMatch(in: string, options: [], range: range) != nil + + if isStringOnlySpaces == true { + return "_" + } + + return string.replacingOccurrences(of: consecutiveSpaceRegex, with: CLDVariable.elementsSeparator, options: .regularExpression, range: nil) + } } + diff --git a/Example/Tests/TransformationTests/CLDExpressionTests/CLDExpressionTests.swift b/Example/Tests/TransformationTests/CLDExpressionTests/CLDExpressionTests.swift index f28494ac..1d34106d 100644 --- a/Example/Tests/TransformationTests/CLDExpressionTests/CLDExpressionTests.swift +++ b/Example/Tests/TransformationTests/CLDExpressionTests/CLDExpressionTests.swift @@ -877,4 +877,362 @@ class CLDExpressionTests: BaseTestCase { // Then XCTAssertEqual(actualResult, expectedResult, "Calling asParams, should remove extra dashes/spaces") } + + func test_powerString_shouldAppendValidValuex() { + // Given + let name = "$________height" + let initialValue = "$_____width" + let value = "30.3" + + let expectedValueResult = "$_height_$_width_pow_30.3" + + // When + sut = CLDExpression(value: "\(name) \(initialValue)").power(by: value) + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + func testExpressionNumber() { + // Given + let name = 10 + let expectedValueResult = "10" + + // When + sut = CLDExpression(value: "\(name)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + func testExpressionSingleSpace_underscore() { + // Given + let name = " " + let expectedValueResult = "_" + + // When + sut = CLDExpression(value: "\(name)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + + func testExpressionBlankString_underscore() { + // Given + let name = " " + let expectedValueResult = "_" + + // When + sut = CLDExpression(value: "\(name)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + + func testExpressionUnderscore_underscore() { + // Given + let name = "_" + let expectedValueResult = "_" + + // When + sut = CLDExpression(value: "\(name)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + + func testExpressionUnderscores_underscore() { + // Given + let name = "___" + let expectedValueResult = "_" + + // When + sut = CLDExpression(value: "\(name)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + + func testExpressionUnderscoresAndSpaces_underscore() { + // Given + let name = " _ __ _" + let expectedValueResult = "_" + + // When + sut = CLDExpression(value: "\(name)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + + func testExpressionArbitraryText_isNotAffected() { + // Given + let name = "foobar" + let expectedValueResult = "foobar" + + // When + sut = CLDExpression(value: "\(name)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + + func testExpressionDoubleAmpersand_replacedWithAndOperator() { + // Given + let name = "foo && bar" + let expectedValueResult = "foo_and_bar" + + // When + sut = CLDExpression(value: "\(name)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + + func testExpressionDoubleAmpersandWithNoSpaceAtEnd_isNotAffected() { + // Given + let name = "foo&&bar" + let expectedValueResult = "foo&&bar" + + // When + sut = CLDExpression(value: "\(name)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + + func testExpressionWidth_recognizedAsVariableAndReplacedWithW() { + // Given + let name = "width" + let expectedValueResult = "w" + + // When + sut = CLDExpression(value: "\(name)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + + func testExpressionInitialAspectRatio_recognizedAsVariableAndReplacedWithW() { + // Given + let name = "width" + let expectedValueResult = "w" + + // When + sut = CLDExpression(value: "\(name)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + + func testExpressionDollarWidth_recognizedAsUserVariableAndNotAffected() { + // Given + let name = "$width" + let expectedValueResult = "$width" + + // When + sut = CLDExpression(value: "\(name)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + + func testExpressionDollarInitialAspectRatio_recognizedAsUserVariableAndAsVariableReplacedWithAr() { + // Given + let name = "$initial_aspect_ratio" + let expectedValueResult = "$initial_ar" + + // When + sut = CLDExpression(value: "\(name)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + + func testExpressionDollarMyWidth_recognizedAsUserVariableAndNotAffected() { + // Given + let name = "$mywidth" + let expectedValueResult = "$mywidth" + + // When + sut = CLDExpression(value: "\(name)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + + func testExpressionDollarWidthWidth_recognizedAsUserVariableAndNotAffected() { + // Given + let name = "$widthwidth" + let expectedValueResult = "$widthwidth" + + // When + sut = CLDExpression(value: "\(name)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + + func testExpressionDollarUnderscoreWidth_recognizedAsUserVariableAndNotAffected() { + // Given + let name = "$_width" + let expectedValueResult = "$_width" + + // When + sut = CLDExpression(value: "\(name)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + func testExpressionDollarUnderscoreX2Width_recognizedAsUserVariableAndNotAffected() { + // Given + let name = "$__width" + let expectedValueResult = "$_width" + + // When + sut = CLDExpression(value: "\(name)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + + func testExpressionDollarX2Width_recognizedAsUserVariableAndNotAffected() { + // Given + let name = "$\\$width" + let expectedValueResult = "$\\$width" + + // When + sut = CLDExpression(value: "\(name)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + + func testExpressionDoesntReplaceVariable_1() { + // Given + let name = "$height" + let value = "100" + let expectedValueResult = "$height_100" + + // When + sut = CLDExpression(value: "\(name) \(value)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + + func testExpressionDoesntReplaceVariable_2() { + // Given + let name = "$heightt" + let value = "100" + let expectedValueResult = "$heightt_100" + + // When + sut = CLDExpression(value: "\(name) \(value)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + + func testExpressionDoesntReplaceVariable_3() { + // Given + let name = "$\\$height" + let value = "100" + let expectedValueResult = "$\\$height_100" + + // When + sut = CLDExpression(value: "\(name) \(value)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + + func testExpressionDoesntReplaceVariable_4() { + // Given + let name = "$heightmy" + let value = "100" + let expectedValueResult = "$heightmy_100" + + // When + sut = CLDExpression(value: "\(name) \(value)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + + func testExpressionDoesntReplaceVariable_5() { + // Given + let name = "$myheight" + let value = "100" + let expectedValueResult = "$myheight_100" + + // When + sut = CLDExpression(value: "\(name) \(value)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + + func testExpressionDoesntReplaceVariable_6() { + // Given + let name = "$heightheight" + let value = "100" + let expectedValueResult = "$heightheight_100" + + // When + sut = CLDExpression(value: "\(name) \(value)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + + func testExpressionDoesntReplaceVariable_7() { + // Given + let name = "$theheight" + let value = "100" + let expectedValueResult = "$theheight_100" + + // When + sut = CLDExpression(value: "\(name) \(value)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + + func testExpressionDoesntReplaceVariable_8() { + // Given + let name = "$________height" + let value = "100" + let expectedValueResult = "$_height_100" + + // When + sut = CLDExpression(value: "\(name) \(value)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } } From 484e29e8568b241a1f9c86ed8aa1967e3865eb3b Mon Sep 17 00:00:00 2001 From: Alex Pinhasov Date: Mon, 7 Mar 2022 10:18:25 +0200 Subject: [PATCH 5/6] Revert "Add new expression tests, refactor expression keys logic to use regex." This reverts commit 57f0c687cc8f915a0447b501498f1af546d7a835. --- .../Core/Features/Helpers/CLDExpression.swift | 83 ++-- .../CLDExpressionTests.swift | 358 ------------------ 2 files changed, 27 insertions(+), 414 deletions(-) diff --git a/Cloudinary/Classes/Core/Features/Helpers/CLDExpression.swift b/Cloudinary/Classes/Core/Features/Helpers/CLDExpression.swift index da3459ff..b8891e9c 100644 --- a/Cloudinary/Classes/Core/Features/Helpers/CLDExpression.swift +++ b/Cloudinary/Classes/Core/Features/Helpers/CLDExpression.swift @@ -36,9 +36,9 @@ import Foundation case initial_height case initialHeight - case initial_aspect_ratio case aspect_ratio case aspectRatio + case initial_aspect_ratio case initialAspectRatio case page_count @@ -73,9 +73,9 @@ import Foundation case .initial_height: return "ih" case .initialHeight : return "ih" - case .initial_aspect_ratio: return "iar" case .aspect_ratio : return "ar" case .aspectRatio : return "ar" + case .initial_aspect_ratio: return "iar" case .initialAspectRatio : return "iar" case .page_count: return "pc" @@ -106,9 +106,7 @@ import Foundation internal var currentKey : String private let consecutiveDashesRegex: String = "[ _]+" - private let consecutiveSpaceRegex: String = "[ ]+" - private let userVariableRegex: String = "\\$_*[^_]+" - + // MARK: - Init public override init() { self.currentKey = String() @@ -119,7 +117,7 @@ import Foundation public init(value: String) { var components = value.components(separatedBy: .whitespacesAndNewlines) self.currentKey = components.removeFirst() - self.currentValue = value == " " ? "_" : components.joined(separator: CLDVariable.elementsSeparator) + self.currentValue = components.joined(separator: CLDVariable.elementsSeparator) super.init() } @@ -288,20 +286,14 @@ import Foundation // MARK: - provide content public func asString() -> String { - guard !currentKey.isEmpty else { - if !currentValue.isEmpty { - return removeExtraSpaces(from: removeExtraDashes(from: replaceAllUnicodeChars(in: currentValue))) - } - return String() - - } - - let key = removeExtraDashes(from: replaceAllExpressionKeys(in: currentKey)) - + guard !currentKey.isEmpty else { return String() } + + let key = replaceAllExpressionKeys(in: currentKey) + if currentValue.isEmpty { return "\(key)" } - let value = removeExtraDashes(from: replaceAllUnicodeChars(in: currentValue)) + let value = removeExtraDashes(from: replaceAllUnencodeChars(in: currentValue)) return "\(key)_\(value)" } @@ -313,7 +305,7 @@ import Foundation } let key = replaceAllExpressionKeys(in: currentKey) - let value = removeExtraDashes(from: replaceAllUnicodeChars(in: currentValue)) + let value = removeExtraDashes(from: replaceAllUnencodeChars(in: currentValue)) return [key:value] } @@ -328,7 +320,7 @@ import Foundation } // MARK: - Private methods - private func replaceAllUnicodeChars(in string: String) -> String { + private func replaceAllUnencodeChars(in string: String) -> String { var wipString = string wipString = replaceAllOperators(in: string) @@ -361,34 +353,26 @@ import Foundation return wipString } - + private func replace(expressionKey: ExpressionKeys, in string: String) -> String { - - var result : String! - + + var result : String + if string.contains(CLDVariable.variableNamePrefix) { - let string = removeExtraDashes(from: string) - let range = NSRange(location: 0, length: string.utf16.count) - let regex = try? NSRegularExpression(pattern: userVariableRegex) - let allRanges = regex?.matches(in: removeExtraDashes(from: string), options: [], range: range).map({ $0.range }) ?? [] - - // Replace substring in between user variables. e.x $initial_aspect_ratio_$width, only '_aspect_ratio_' will be addressed. - for (index, range) in allRanges.enumerated() { - let location = range.length + range.location - var length = range.length - - if index + 1 == allRanges.count { - length = string.count - } else { - let nextRange = allRanges[index + 1] - length = nextRange.location - } - - if let stringRange = Range(NSRange(location: location, length: length - location), in: string) { - result = string.replacingOccurrences(of: expressionKey.rawValue, with: expressionKey.asString, options: .regularExpression, range: stringRange) + + result = string.components(separatedBy: CLDVariable.elementsSeparator).map({ + + let temp : String + switch $0.hasPrefix(CLDVariable.variableNamePrefix) { + case true : temp = $0 + case false: temp = $0.replacingOccurrences(of: expressionKey.rawValue, with: expressionKey.asString) } - } + return temp + + }).joined(separator: CLDVariable.elementsSeparator) + } else { + result = string.replacingOccurrences(of: expressionKey.rawValue, with: expressionKey.asString) } return result @@ -419,17 +403,4 @@ import Foundation private func removeExtraDashes(from string: String) -> String { return string.replacingOccurrences(of: consecutiveDashesRegex, with: CLDVariable.elementsSeparator, options: .regularExpression, range: nil) } - - private func removeExtraSpaces(from string: String) -> String { - let regex = try? NSRegularExpression(pattern: consecutiveSpaceRegex) - let range = NSRange(location: 0, length: string.utf16.count) - let isStringOnlySpaces = regex?.firstMatch(in: string, options: [], range: range) != nil - - if isStringOnlySpaces == true { - return "_" - } - - return string.replacingOccurrences(of: consecutiveSpaceRegex, with: CLDVariable.elementsSeparator, options: .regularExpression, range: nil) - } } - diff --git a/Example/Tests/TransformationTests/CLDExpressionTests/CLDExpressionTests.swift b/Example/Tests/TransformationTests/CLDExpressionTests/CLDExpressionTests.swift index 1d34106d..f28494ac 100644 --- a/Example/Tests/TransformationTests/CLDExpressionTests/CLDExpressionTests.swift +++ b/Example/Tests/TransformationTests/CLDExpressionTests/CLDExpressionTests.swift @@ -877,362 +877,4 @@ class CLDExpressionTests: BaseTestCase { // Then XCTAssertEqual(actualResult, expectedResult, "Calling asParams, should remove extra dashes/spaces") } - - func test_powerString_shouldAppendValidValuex() { - // Given - let name = "$________height" - let initialValue = "$_____width" - let value = "30.3" - - let expectedValueResult = "$_height_$_width_pow_30.3" - - // When - sut = CLDExpression(value: "\(name) \(initialValue)").power(by: value) - - // Then - XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") - } - - func testExpressionNumber() { - // Given - let name = 10 - let expectedValueResult = "10" - - // When - sut = CLDExpression(value: "\(name)") - - // Then - XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") - } - - func testExpressionSingleSpace_underscore() { - // Given - let name = " " - let expectedValueResult = "_" - - // When - sut = CLDExpression(value: "\(name)") - - // Then - XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") - } - - - func testExpressionBlankString_underscore() { - // Given - let name = " " - let expectedValueResult = "_" - - // When - sut = CLDExpression(value: "\(name)") - - // Then - XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") - } - - - func testExpressionUnderscore_underscore() { - // Given - let name = "_" - let expectedValueResult = "_" - - // When - sut = CLDExpression(value: "\(name)") - - // Then - XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") - } - - - func testExpressionUnderscores_underscore() { - // Given - let name = "___" - let expectedValueResult = "_" - - // When - sut = CLDExpression(value: "\(name)") - - // Then - XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") - } - - - func testExpressionUnderscoresAndSpaces_underscore() { - // Given - let name = " _ __ _" - let expectedValueResult = "_" - - // When - sut = CLDExpression(value: "\(name)") - - // Then - XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") - } - - - func testExpressionArbitraryText_isNotAffected() { - // Given - let name = "foobar" - let expectedValueResult = "foobar" - - // When - sut = CLDExpression(value: "\(name)") - - // Then - XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") - } - - - func testExpressionDoubleAmpersand_replacedWithAndOperator() { - // Given - let name = "foo && bar" - let expectedValueResult = "foo_and_bar" - - // When - sut = CLDExpression(value: "\(name)") - - // Then - XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") - } - - - func testExpressionDoubleAmpersandWithNoSpaceAtEnd_isNotAffected() { - // Given - let name = "foo&&bar" - let expectedValueResult = "foo&&bar" - - // When - sut = CLDExpression(value: "\(name)") - - // Then - XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") - } - - - func testExpressionWidth_recognizedAsVariableAndReplacedWithW() { - // Given - let name = "width" - let expectedValueResult = "w" - - // When - sut = CLDExpression(value: "\(name)") - - // Then - XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") - } - - - func testExpressionInitialAspectRatio_recognizedAsVariableAndReplacedWithW() { - // Given - let name = "width" - let expectedValueResult = "w" - - // When - sut = CLDExpression(value: "\(name)") - - // Then - XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") - } - - - func testExpressionDollarWidth_recognizedAsUserVariableAndNotAffected() { - // Given - let name = "$width" - let expectedValueResult = "$width" - - // When - sut = CLDExpression(value: "\(name)") - - // Then - XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") - } - - - func testExpressionDollarInitialAspectRatio_recognizedAsUserVariableAndAsVariableReplacedWithAr() { - // Given - let name = "$initial_aspect_ratio" - let expectedValueResult = "$initial_ar" - - // When - sut = CLDExpression(value: "\(name)") - - // Then - XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") - } - - - func testExpressionDollarMyWidth_recognizedAsUserVariableAndNotAffected() { - // Given - let name = "$mywidth" - let expectedValueResult = "$mywidth" - - // When - sut = CLDExpression(value: "\(name)") - - // Then - XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") - } - - - func testExpressionDollarWidthWidth_recognizedAsUserVariableAndNotAffected() { - // Given - let name = "$widthwidth" - let expectedValueResult = "$widthwidth" - - // When - sut = CLDExpression(value: "\(name)") - - // Then - XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") - } - - - func testExpressionDollarUnderscoreWidth_recognizedAsUserVariableAndNotAffected() { - // Given - let name = "$_width" - let expectedValueResult = "$_width" - - // When - sut = CLDExpression(value: "\(name)") - - // Then - XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") - } - - func testExpressionDollarUnderscoreX2Width_recognizedAsUserVariableAndNotAffected() { - // Given - let name = "$__width" - let expectedValueResult = "$_width" - - // When - sut = CLDExpression(value: "\(name)") - - // Then - XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") - } - - - func testExpressionDollarX2Width_recognizedAsUserVariableAndNotAffected() { - // Given - let name = "$\\$width" - let expectedValueResult = "$\\$width" - - // When - sut = CLDExpression(value: "\(name)") - - // Then - XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") - } - - - func testExpressionDoesntReplaceVariable_1() { - // Given - let name = "$height" - let value = "100" - let expectedValueResult = "$height_100" - - // When - sut = CLDExpression(value: "\(name) \(value)") - - // Then - XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") - } - - - func testExpressionDoesntReplaceVariable_2() { - // Given - let name = "$heightt" - let value = "100" - let expectedValueResult = "$heightt_100" - - // When - sut = CLDExpression(value: "\(name) \(value)") - - // Then - XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") - } - - - func testExpressionDoesntReplaceVariable_3() { - // Given - let name = "$\\$height" - let value = "100" - let expectedValueResult = "$\\$height_100" - - // When - sut = CLDExpression(value: "\(name) \(value)") - - // Then - XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") - } - - - func testExpressionDoesntReplaceVariable_4() { - // Given - let name = "$heightmy" - let value = "100" - let expectedValueResult = "$heightmy_100" - - // When - sut = CLDExpression(value: "\(name) \(value)") - - // Then - XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") - } - - - func testExpressionDoesntReplaceVariable_5() { - // Given - let name = "$myheight" - let value = "100" - let expectedValueResult = "$myheight_100" - - // When - sut = CLDExpression(value: "\(name) \(value)") - - // Then - XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") - } - - - func testExpressionDoesntReplaceVariable_6() { - // Given - let name = "$heightheight" - let value = "100" - let expectedValueResult = "$heightheight_100" - - // When - sut = CLDExpression(value: "\(name) \(value)") - - // Then - XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") - } - - - func testExpressionDoesntReplaceVariable_7() { - // Given - let name = "$theheight" - let value = "100" - let expectedValueResult = "$theheight_100" - - // When - sut = CLDExpression(value: "\(name) \(value)") - - // Then - XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") - } - - - func testExpressionDoesntReplaceVariable_8() { - // Given - let name = "$________height" - let value = "100" - let expectedValueResult = "$_height_100" - - // When - sut = CLDExpression(value: "\(name) \(value)") - - // Then - XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") - } } From 75e6ad727a5408e3c971229c25736ba85def489e Mon Sep 17 00:00:00 2001 From: GiniAppsPartners <80427522+GiniAppsPartners@users.noreply.github.com> Date: Sun, 27 Mar 2022 11:27:53 +0300 Subject: [PATCH 6/6] Fix expression normalize for user variables --- .../Core/Features/Helpers/CLDExpression.swift | 75 ++-- .../CLDExpressionTests.swift | 335 ++++++++++++++++++ 2 files changed, 382 insertions(+), 28 deletions(-) diff --git a/Cloudinary/Classes/Core/Features/Helpers/CLDExpression.swift b/Cloudinary/Classes/Core/Features/Helpers/CLDExpression.swift index b8891e9c..dd928c69 100644 --- a/Cloudinary/Classes/Core/Features/Helpers/CLDExpression.swift +++ b/Cloudinary/Classes/Core/Features/Helpers/CLDExpression.swift @@ -36,9 +36,9 @@ import Foundation case initial_height case initialHeight + case initial_aspect_ratio case aspect_ratio case aspectRatio - case initial_aspect_ratio case initialAspectRatio case page_count @@ -73,9 +73,9 @@ import Foundation case .initial_height: return "ih" case .initialHeight : return "ih" + case .initial_aspect_ratio: return "iar" case .aspect_ratio : return "ar" case .aspectRatio : return "ar" - case .initial_aspect_ratio: return "iar" case .initialAspectRatio : return "iar" case .page_count: return "pc" @@ -104,9 +104,11 @@ import Foundation internal var currentValue : String internal var currentKey : String - - private let consecutiveDashesRegex: String = "[ _]+" - + + private var allSpaceAndOrDash : Bool = false + private let consecutiveDashesRegex : String = "[ _]+" + private let userVariableRegex : String = "\\$_*[^_]+" + // MARK: - Init public override init() { self.currentKey = String() @@ -118,6 +120,9 @@ import Foundation var components = value.components(separatedBy: .whitespacesAndNewlines) self.currentKey = components.removeFirst() self.currentValue = components.joined(separator: CLDVariable.elementsSeparator) + let range = NSRange(location: 0, length: value.utf16.count) + let regex = try? NSRegularExpression(pattern: "^" + consecutiveDashesRegex) + self.allSpaceAndOrDash = !(regex?.firstMatch(in: value, options: [], range: range) == nil) super.init() } @@ -286,14 +291,19 @@ import Foundation // MARK: - provide content public func asString() -> String { - guard !currentKey.isEmpty else { return String() } - - let key = replaceAllExpressionKeys(in: currentKey) - + guard !currentKey.isEmpty else { + if allSpaceAndOrDash { + return "_" + } + return String() + } + + let key = removeExtraDashes(from: replaceAllExpressionKeys(in: currentKey)) + if currentValue.isEmpty { return "\(key)" } - let value = removeExtraDashes(from: replaceAllUnencodeChars(in: currentValue)) + let value = removeExtraDashes(from: replaceAllUnencodedChars(in: currentValue)) return "\(key)_\(value)" } @@ -305,7 +315,7 @@ import Foundation } let key = replaceAllExpressionKeys(in: currentKey) - let value = removeExtraDashes(from: replaceAllUnencodeChars(in: currentValue)) + let value = removeExtraDashes(from: replaceAllUnencodedChars(in: currentValue)) return [key:value] } @@ -320,7 +330,7 @@ import Foundation } // MARK: - Private methods - private func replaceAllUnencodeChars(in string: String) -> String { + private func replaceAllUnencodedChars(in string: String) -> String { var wipString = string wipString = replaceAllOperators(in: string) @@ -353,26 +363,34 @@ import Foundation return wipString } - + private func replace(expressionKey: ExpressionKeys, in string: String) -> String { - - var result : String - + + var result : String! + let string = removeExtraDashes(from: string) + if string.contains(CLDVariable.variableNamePrefix) { - - result = string.components(separatedBy: CLDVariable.elementsSeparator).map({ - - let temp : String - switch $0.hasPrefix(CLDVariable.variableNamePrefix) { - case true : temp = $0 - case false: temp = $0.replacingOccurrences(of: expressionKey.rawValue, with: expressionKey.asString) + let range = NSRange(location: 0, length: string.utf16.count) + let regex = try? NSRegularExpression(pattern: userVariableRegex) + let allRanges = regex?.matches(in: string, options: [], range: range).map({ $0.range }) ?? [] + + // Replace substring in between user variables. e.x $initial_aspect_ratio_$width, only '_aspect_ratio_' will be addressed. + for (index, range) in allRanges.enumerated() { + let location = range.length + range.location + var length = range.length + + if index + 1 == allRanges.count { + length = string.count + } else { + let nextRange = allRanges[index + 1] + length = nextRange.location } - return temp - - }).joined(separator: CLDVariable.elementsSeparator) - + + if let stringRange = Range(NSRange(location: location, length: length - location), in: string) { + result = string.replacingOccurrences(of: expressionKey.rawValue, with: expressionKey.asString, options: .regularExpression, range: stringRange) + } + } } else { - result = string.replacingOccurrences(of: expressionKey.rawValue, with: expressionKey.asString) } return result @@ -404,3 +422,4 @@ import Foundation return string.replacingOccurrences(of: consecutiveDashesRegex, with: CLDVariable.elementsSeparator, options: .regularExpression, range: nil) } } + diff --git a/Example/Tests/TransformationTests/CLDExpressionTests/CLDExpressionTests.swift b/Example/Tests/TransformationTests/CLDExpressionTests/CLDExpressionTests.swift index f28494ac..e63ba84a 100644 --- a/Example/Tests/TransformationTests/CLDExpressionTests/CLDExpressionTests.swift +++ b/Example/Tests/TransformationTests/CLDExpressionTests/CLDExpressionTests.swift @@ -877,4 +877,339 @@ class CLDExpressionTests: BaseTestCase { // Then XCTAssertEqual(actualResult, expectedResult, "Calling asParams, should remove extra dashes/spaces") } + + func test_powerString_shouldAppendValidValuex() { + // Given + let name = "$________height" + let initialValue = "$_____width" + let value = "30.3" + + let expectedValueResult = "$_height_$_width_pow_30.3" + + // When + sut = CLDExpression(value: "\(name) \(initialValue)").power(by: value) + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + func testExpressionNumber() { + // Given + let name = 10 + let expectedValueResult = "10" + + // When + sut = CLDExpression(value: "\(name)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + func testExpressionSingleSpace_underscore() { + // Given + let name = " " + let expectedValueResult = "_" + + // When + sut = CLDExpression(value: "\(name)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + func testExpressionBlankString_underscore() { + // Given + let name = " " + let expectedValueResult = "_" + + // When + sut = CLDExpression(value: "\(name)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + func testExpressionUnderscore_underscore() { + // Given + let name = "_" + let expectedValueResult = "_" + + // When + sut = CLDExpression(value: "\(name)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + func testExpressionUnderscores_underscore() { + // Given + let name = "___" + let expectedValueResult = "_" + + // When + sut = CLDExpression(value: "\(name)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + func testExpressionUnderscoresAndSpaces_underscore() { + // Given + let name = " _ __ _" + let expectedValueResult = "_" + + // When + sut = CLDExpression(value: "\(name)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + func testExpressionArbitraryText_isNotAffected() { + // Given + let name = "foobar" + let expectedValueResult = "foobar" + + // When + sut = CLDExpression(value: "\(name)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + func testExpressionDoubleAmpersand_replacedWithAndOperator() { + // Given + let name = "foo && bar" + let expectedValueResult = "foo_and_bar" + + // When + sut = CLDExpression(value: "\(name)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + func testExpressionDoubleAmpersandWithNoSpaceAtEnd_isNotAffected() { + // Given + let name = "foo&&bar" + let expectedValueResult = "foo&&bar" + + // When + sut = CLDExpression(value: "\(name)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + func testExpressionWidth_recognizedAsVariableAndReplacedWithW() { + // Given + let name = "width" + let expectedValueResult = "w" + + // When + sut = CLDExpression(value: "\(name)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + func testExpressionInitialAspectRatio_recognizedAsVariableAndReplacedWithW() { + // Given + let name = "width" + let expectedValueResult = "w" + + // When + sut = CLDExpression(value: "\(name)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + func testExpressionDollarWidth_recognizedAsUserVariableAndNotAffected() { + // Given + let name = "$width" + let expectedValueResult = "$width" + + // When + sut = CLDExpression(value: "\(name)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + func testExpressionDollarInitialAspectRatio_recognizedAsUserVariableAndAsVariableReplacedWithAr() { + // Given + let name = "$initial_aspect_ratio" + let expectedValueResult = "$initial_ar" + + // When + sut = CLDExpression(value: "\(name)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + func testExpressionDollarMyWidth_recognizedAsUserVariableAndNotAffected() { + // Given + let name = "$mywidth" + let expectedValueResult = "$mywidth" + + // When + sut = CLDExpression(value: "\(name)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + func testExpressionDollarWidthWidth_recognizedAsUserVariableAndNotAffected() { + // Given + let name = "$widthwidth" + let expectedValueResult = "$widthwidth" + + // When + sut = CLDExpression(value: "\(name)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + func testExpressionDollarUnderscoreWidth_recognizedAsUserVariableAndNotAffected() { + // Given + let name = "$_width" + let expectedValueResult = "$_width" + + // When + sut = CLDExpression(value: "\(name)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + func testExpressionDollarUnderscoreX2Width_recognizedAsUserVariableAndNotAffected() { + // Given + let name = "$__width" + let expectedValueResult = "$_width" + + // When + sut = CLDExpression(value: "\(name)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + func testExpressionDollarX2Width_recognizedAsUserVariableAndNotAffected() { + // Given + let name = "$\\$width" + let expectedValueResult = "$\\$width" + + // When + sut = CLDExpression(value: "\(name)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + func testExpressionDoesntReplaceVariable_1() { + // Given + let name = "$height" + let value = "100" + let expectedValueResult = "$height_100" + + // When + sut = CLDExpression(value: "\(name) \(value)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + func testExpressionDoesntReplaceVariable_2() { + // Given + let name = "$heightt" + let value = "100" + let expectedValueResult = "$heightt_100" + + // When + sut = CLDExpression(value: "\(name) \(value)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + func testExpressionDoesntReplaceVariable_3() { + // Given + let name = "$\\$height" + let value = "100" + let expectedValueResult = "$\\$height_100" + + // When + sut = CLDExpression(value: "\(name) \(value)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + func testExpressionDoesntReplaceVariable_4() { + // Given + let name = "$heightmy" + let value = "100" + let expectedValueResult = "$heightmy_100" + + // When + sut = CLDExpression(value: "\(name) \(value)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + func testExpressionDoesntReplaceVariable_5() { + // Given + let name = "$myheight" + let value = "100" + let expectedValueResult = "$myheight_100" + + // When + sut = CLDExpression(value: "\(name) \(value)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + func testExpressionDoesntReplaceVariable_6() { + // Given + let name = "$heightheight" + let value = "100" + let expectedValueResult = "$heightheight_100" + + // When + sut = CLDExpression(value: "\(name) \(value)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + func testExpressionDoesntReplaceVariable_7() { + // Given + let name = "$theheight" + let value = "100" + let expectedValueResult = "$theheight_100" + + // When + sut = CLDExpression(value: "\(name) \(value)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } + + func testExpressionDoesntReplaceVariable_8() { + // Given + let name = "$________height" + let value = "100" + let expectedValueResult = "$_height_100" + + // When + sut = CLDExpression(value: "\(name) \(value)") + + // Then + XCTAssertEqual(sut.asString(), expectedValueResult, "string should be equal to expectedValueResult") + } }