This is an automated email from the ASF dual-hosted git repository.

uros-b pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/spark.git


The following commit(s) were added to refs/heads/master by this push:
     new 6e695dd878a9 [SPARK-58689][CORE][TEST] Add tests for SparkStringUtils 
padding and abbreviation helpers
6e695dd878a9 is described below

commit 6e695dd878a9eeacefe99fc40ae89944a58e91c1
Author: Uros <[email protected]>
AuthorDate: Tue Aug 18 09:36:35 2026 +0000

    [SPARK-58689][CORE][TEST] Add tests for SparkStringUtils padding and 
abbreviation helpers
    
    ### What changes were proposed in this pull request?
    
    Adds `SparkStringUtilsSuite`, covering `isBlank`/`isNotBlank`, `leftPad`, 
both `rightPad` overloads, both `abbreviate` overloads, `strip`, and 
`stringToSeq`.
    
    ### Why are the changes needed?
    
    `SparkStringUtils` currently has no test suite, while the sibling utilities 
in the same module (`SparkErrorUtilsSuite`, `SparkFileUtilsSuite`, 
`VersionUtilsSuite`, ...) each have one. The helpers are not incidental: 
`leftPad`/`rightPad` format the column output of `Dataset.show`, and 
`abbreviate` is used to build Kubernetes application-name labels. The methods 
arrived across a series of changes that replaced Apache Commons and Guava 
equivalents, and none of those added direct tests.
    
    The three-argument `rightPad(str, width, padStr)` holds the most 
error-prone arithmetic in the file (pad repetition plus truncation of the final 
repetition) and currently has no caller, so it had no coverage of any kind.
    
    ### Does this PR introduce _any_ user-facing change?
    
    No. Tests only.
    
    ### How was this patch tested?
    
    This is the test. Every expected value was derived by executing the current 
implementations rather than computed by hand, including the pad-truncation 
cases (`rightPad("a", 4, "xy")` is `"axyx"`) and the null pass-through paths. 
The suite was run locally: 6 tests, 27 assertions, all passing.
    
    The suite extends `AnyFunSuite` with the `scalastyle:ignore funsuite` 
marker, matching every sibling suite in this module; `common/utils` does not 
depend on `spark-core`, so `SparkFunSuite` is not available here.
    
    ### Was this patch authored or co-authored using generative AI tooling?
    
    Generated-by: Claude Code (Opus 4.8)
    
    Closes #57890 from uros-b/test-sparkstringutils.
    
    Authored-by: Uros <[email protected]>
    Signed-off-by: Uros Bojanic <[email protected]>
---
 .../apache/spark/util/SparkStringUtilsSuite.scala  | 85 ++++++++++++++++++++++
 1 file changed, 85 insertions(+)

diff --git 
a/common/utils/src/test/scala/org/apache/spark/util/SparkStringUtilsSuite.scala 
b/common/utils/src/test/scala/org/apache/spark/util/SparkStringUtilsSuite.scala
new file mode 100644
index 000000000000..93fb4a745d44
--- /dev/null
+++ 
b/common/utils/src/test/scala/org/apache/spark/util/SparkStringUtilsSuite.scala
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.spark.util
+
+import org.scalatest.funsuite.AnyFunSuite // scalastyle:ignore funsuite
+
+class SparkStringUtilsSuite extends AnyFunSuite { // scalastyle:ignore funsuite
+
+  test("isBlank treats null and whitespace-only strings as blank") {
+    assert(SparkStringUtils.isBlank(null))
+    assert(SparkStringUtils.isBlank(""))
+    assert(SparkStringUtils.isBlank("   "))
+    assert(!SparkStringUtils.isBlank("a"))
+    assert(SparkStringUtils.isNotBlank("a"))
+    assert(!SparkStringUtils.isNotBlank("   "))
+  }
+
+  test("leftPad and rightPad pad with spaces up to the requested width") {
+    assert(SparkStringUtils.leftPad("hi", 5) === "   hi")
+    assert(SparkStringUtils.rightPad("hi", 5) === "hi   ")
+    // A width that is not larger than the input is a no-op, and null is 
passed through.
+    assert(SparkStringUtils.leftPad("hello", 5) === "hello")
+    assert(SparkStringUtils.rightPad("hello", 3) === "hello")
+    assert(SparkStringUtils.leftPad(null, 5) === null)
+    assert(SparkStringUtils.rightPad(null, 5) === null)
+  }
+
+  test("rightPad repeats the pad string and truncates the last repetition") {
+    assert(SparkStringUtils.rightPad("x", 6, "*") === "x*****")
+    assert(SparkStringUtils.rightPad("a", 5, "xy") === "axyxy")
+    // Only the first character of the final "xy" fits within the width.
+    assert(SparkStringUtils.rightPad("a", 4, "xy") === "axyx")
+    assert(SparkStringUtils.rightPad("hello", 3, "*") === "hello")
+    assert(SparkStringUtils.rightPad(null, 5, "*") === null)
+  }
+
+  test("rightPad with an empty pad string fails when padding is required") {
+    // The pad length is used as a divisor, so an empty pad string divides by 
zero.
+    // Documented here rather than guarded, since callers are expected to pass 
a
+    // non-empty pad string.
+    intercept[ArithmeticException] {
+      SparkStringUtils.rightPad("a", 5, "")
+    }
+    // No padding is needed in these cases, so the divisor is never reached.
+    assert(SparkStringUtils.rightPad("hello", 5, "") === "hello")
+    assert(SparkStringUtils.rightPad("hello", 3, "") === "hello")
+    assert(SparkStringUtils.rightPad(null, 5, "") === null)
+  }
+
+  test("abbreviate truncates with the marker and leaves short inputs 
untouched") {
+    assert(SparkStringUtils.abbreviate("hello world", 8) === "hello...")
+    assert(SparkStringUtils.abbreviate("abc", 8) === "abc")
+    assert(SparkStringUtils.abbreviate("abcdefgh", "..", 4) === "ab..")
+    // An empty marker makes abbreviate a plain truncation.
+    assert(SparkStringUtils.abbreviate("abcdefgh", "", 3) === "abc")
+    assert(SparkStringUtils.abbreviate(null, 5) === null)
+    assert(SparkStringUtils.abbreviate("abc", null, 2) === null)
+  }
+
+  test("strip removes the given prefix and suffix when present") {
+    assert(SparkStringUtils.strip("\"path\"", "\"") === "path")
+    assert(SparkStringUtils.strip("path", "\"") === "path")
+    assert(SparkStringUtils.strip(null, "\"") === null)
+    assert(SparkStringUtils.strip("path", null) === "path")
+  }
+
+  test("stringToSeq trims entries and drops empty ones") {
+    assert(SparkStringUtils.stringToSeq(" a, b ,,c ") === Seq("a", "b", "c"))
+    assert(SparkStringUtils.stringToSeq("") === Seq.empty)
+  }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to