This is an automated email from the ASF dual-hosted git repository. jamesbognar pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/juneau.git
commit 4d6ccd07522d97b2d29376ad76efd916d756fb41 Author: James Bognar <[email protected]> AuthorDate: Fri Jul 17 12:56:34 2026 -0400 TODO-238 — BUG × juneau-commons fixes (BUG-03 LocalDir hashCode, BUG-07 locale-safe casing, BUG-09 defensive copies, BUG-15 null guards, BUG-16 holder null-coerce) + make Version equals/hashCode/compareTo strict (prefix-matching moved to matches()). Breaking change (10.0.0). Co-authored-by: Cursor <[email protected]> --- .../juneau/commons/AppliedAnnotationObject.java | 2 +- .../commons/AppliedOnClassAnnotationObject.java | 2 +- .../juneau/commons/bean/BeanCtorAnnotation.java | 2 +- .../juneau/commons/bean/BeanIgnoreAnnotation.java | 2 +- .../juneau/commons/bean/BeanPropAnnotation.java | 4 +- .../juneau/commons/bean/BeanTypeAnnotation.java | 2 +- .../apache/juneau/commons/http/HeaderElement.java | 2 +- .../juneau/commons/inject/BasicBeanStore.java | 7 +++ .../juneau/commons/inject/BeanAnnotation.java | 4 +- .../org/apache/juneau/commons/io/LocalDir.java | 2 +- .../org/apache/juneau/commons/lang/ByteHolder.java | 27 +++++++---- .../apache/juneau/commons/lang/IntegerHolder.java | 27 +++++++---- .../org/apache/juneau/commons/lang/Version.java | 56 ++++++++++++++-------- .../apache/juneau/commons/utils/ClassUtils.java | 2 + .../apache/juneau/commons/utils/StringUtils.java | 15 +++--- .../apache/juneau/commons/lang/Version_Test.java | 33 +++++++++---- .../juneau/commons/utils/ClassUtils_Test.java | 2 +- 17 files changed, 125 insertions(+), 66 deletions(-) diff --git a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/AppliedAnnotationObject.java b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/AppliedAnnotationObject.java index e8ea00ea5f..78c44d49c8 100644 --- a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/AppliedAnnotationObject.java +++ b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/AppliedAnnotationObject.java @@ -713,6 +713,6 @@ public class AppliedAnnotationObject extends AnnotationObject { * @return The targets this annotation applies to. */ public String[] on() { - return on; + return copyOf(on); } } diff --git a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/AppliedOnClassAnnotationObject.java b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/AppliedOnClassAnnotationObject.java index 03591f7944..30498dee46 100644 --- a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/AppliedOnClassAnnotationObject.java +++ b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/AppliedOnClassAnnotationObject.java @@ -108,6 +108,6 @@ public class AppliedOnClassAnnotationObject extends AppliedAnnotationObject { * @return The targets this annotation applies to. */ public Class<?>[] onClass() { - return onClass; + return copyOf(onClass); } } \ No newline at end of file diff --git a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/bean/BeanCtorAnnotation.java b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/bean/BeanCtorAnnotation.java index 93fbdeaf22..3d3f032e73 100644 --- a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/bean/BeanCtorAnnotation.java +++ b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/bean/BeanCtorAnnotation.java @@ -104,7 +104,7 @@ public class BeanCtorAnnotation { @Override /* Overridden from BeanCtor */ public String[] description() { - return description; + return copyOf(description); } @Override /* Overridden from BeanCtor */ diff --git a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/bean/BeanIgnoreAnnotation.java b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/bean/BeanIgnoreAnnotation.java index 4e23994a1a..3b7e675e4b 100644 --- a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/bean/BeanIgnoreAnnotation.java +++ b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/bean/BeanIgnoreAnnotation.java @@ -104,7 +104,7 @@ public class BeanIgnoreAnnotation { @Override /* Overridden from BeanIgnore */ public String[] description() { - return description; + return copyOf(description); } @Override /* Overridden from BeanIgnore */ diff --git a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/bean/BeanPropAnnotation.java b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/bean/BeanPropAnnotation.java index aa8b0fad9b..da5f7d5971 100644 --- a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/bean/BeanPropAnnotation.java +++ b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/bean/BeanPropAnnotation.java @@ -228,7 +228,7 @@ public class BeanPropAnnotation { @Override /* Overridden from BeanProp */ public String[] description() { - return description; + return copyOf(description); } @Override /* Overridden from BeanProp */ @@ -248,7 +248,7 @@ public class BeanPropAnnotation { @Override /* Overridden from BeanProp */ public Class<?>[] params() { - return params; + return copyOf(params); } @Override /* Overridden from BeanProp */ diff --git a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/bean/BeanTypeAnnotation.java b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/bean/BeanTypeAnnotation.java index f1e38ca8ae..91b6b13e22 100644 --- a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/bean/BeanTypeAnnotation.java +++ b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/bean/BeanTypeAnnotation.java @@ -296,7 +296,7 @@ public class BeanTypeAnnotation { @Override /* Overridden from BeanType */ public String[] description() { - return description; + return copyOf(description); } @Override /* Overridden from BeanType */ diff --git a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/http/HeaderElement.java b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/http/HeaderElement.java index 9046dab64e..4536ea21a5 100644 --- a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/http/HeaderElement.java +++ b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/http/HeaderElement.java @@ -55,6 +55,6 @@ public class HeaderElement { * @return The parameters array, never <jk>null</jk>. */ public NameValuePair[] getParameters() { - return parameters; + return parameters.clone(); } } diff --git a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/inject/BasicBeanStore.java b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/inject/BasicBeanStore.java index aafd45c5f2..1077777d57 100644 --- a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/inject/BasicBeanStore.java +++ b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/inject/BasicBeanStore.java @@ -17,6 +17,7 @@ package org.apache.juneau.commons.inject; import static org.apache.juneau.commons.reflect.ReflectionUtils.*; +import static org.apache.juneau.commons.utils.AssertionUtils.*; import static org.apache.juneau.commons.utils.CollectionUtils.*; import static org.apache.juneau.commons.utils.Shorts.*; import static org.apache.juneau.commons.utils.StringUtils.*; @@ -97,6 +98,10 @@ public class BasicBeanStore implements WritableBeanStore { private static final String PROP_parent = "parent"; private static final String PROP_type = "type"; + // Argument name constants for assertArgNotNull + private static final String ARG_beanType = "beanType"; + private static final String ARG_onClassOrObject = "onClassOrObject"; + private final ConcurrentHashMap<Class<?>, ConcurrentHashMap<String, Supplier<?>>> entries; private final ConcurrentHashMap<Class<?>, ConcurrentHashMap<String, Supplier<?>>> defaults; private final ConcurrentHashMap<Class<?>, ConcurrentHashMap<String, BeanSourceMeta>> entryMetadata; @@ -704,6 +709,8 @@ public class BasicBeanStore implements WritableBeanStore { */ @Override public <T> Optional<T> createBeanFromMethod(Class<T> beanType, Object onClassOrObject, Predicate<MethodInfo> filter, Object... extraBeans) { + assertArgNotNull(ARG_beanType, beanType); + assertArgNotNull(ARG_onClassOrObject, onClassOrObject); Object resource = onClassOrObject instanceof Class ? null : onClassOrObject; Class<?> resourceClass = onClassOrObject instanceof Class<?> c ? c : onClassOrObject.getClass(); return info(resourceClass) diff --git a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/inject/BeanAnnotation.java b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/inject/BeanAnnotation.java index 39f1919e82..12562d535d 100644 --- a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/inject/BeanAnnotation.java +++ b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/inject/BeanAnnotation.java @@ -173,7 +173,7 @@ public class BeanAnnotation { @Override /* Overridden from Bean */ public String[] methodScope() { - return methodScope; + return copyOf(methodScope); } @Override /* Overridden from Bean */ @@ -188,7 +188,7 @@ public class BeanAnnotation { @Override /* Overridden from annotation */ public String[] description() { - return description; + return copyOf(description); } @Override /* Overridden from Bean */ diff --git a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/io/LocalDir.java b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/io/LocalDir.java index e33719a9d2..a9fd3b3e7d 100644 --- a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/io/LocalDir.java +++ b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/io/LocalDir.java @@ -151,7 +151,7 @@ public class LocalDir { this.clazz = assertArgNotNull(ARG_clazz, clazz); this.clazzPath = "/".equals(clazzPath) ? "/" : StringUtils.nullIfEmpty(trimTrailingSlashes(clazzPath)); this.path = null; - this.hashCode = h(clazz, clazzPath); + this.hashCode = h(clazz, this.clazzPath); } /** diff --git a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/lang/ByteHolder.java b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/lang/ByteHolder.java index f6348abd55..723ee68f0f 100644 --- a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/lang/ByteHolder.java +++ b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/lang/ByteHolder.java @@ -121,7 +121,8 @@ public class ByteHolder extends Holder<Byte> { * @return This object. */ public ByteHolder add(Byte x) { - set((byte)(get() + (x == null ? 0 : x))); + var v = get(); + set((byte)((v == null ? 0 : v) + (x == null ? 0 : x))); return this; } @@ -139,8 +140,10 @@ public class ByteHolder extends Holder<Byte> { * @return The new value after addition. */ public Byte addAndGet(Byte x) { - set((byte)(get() + (x == null ? 0 : x))); - return get(); + var v = get(); + var result = (byte)((v == null ? 0 : v) + (x == null ? 0 : x)); + set(result); + return result; } /** @@ -156,7 +159,8 @@ public class ByteHolder extends Holder<Byte> { * @return This object. */ public ByteHolder decrement() { - set((byte)(get() - 1)); + var v = get(); + set((byte)((v == null ? 0 : v) - 1)); return this; } @@ -173,8 +177,10 @@ public class ByteHolder extends Holder<Byte> { * @return The decremented value. */ public Byte decrementAndGet() { - set((byte)(get() - 1)); - return get(); + var v = get(); + var result = (byte)((v == null ? 0 : v) - 1); + set(result); + return result; } /** @@ -190,7 +196,8 @@ public class ByteHolder extends Holder<Byte> { * @return This object. */ public ByteHolder increment() { - set((byte)(get() + 1)); + var v = get(); + set((byte)((v == null ? 0 : v) + 1)); return this; } @@ -207,8 +214,10 @@ public class ByteHolder extends Holder<Byte> { * @return The incremented value. */ public Byte incrementAndGet() { - set((byte)(get() + 1)); - return get(); + var v = get(); + var result = (byte)((v == null ? 0 : v) + 1); + set(result); + return result; } /** diff --git a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/lang/IntegerHolder.java b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/lang/IntegerHolder.java index 57c8b6d0c1..1e72063585 100644 --- a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/lang/IntegerHolder.java +++ b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/lang/IntegerHolder.java @@ -121,7 +121,8 @@ public class IntegerHolder extends Holder<Integer> { * @return This object. */ public IntegerHolder add(Integer x) { - set(get() + (x == null ? 0 : x)); + var v = get(); + set((v == null ? 0 : v) + (x == null ? 0 : x)); return this; } @@ -139,8 +140,10 @@ public class IntegerHolder extends Holder<Integer> { * @return The new value after addition. */ public Integer addAndGet(Integer x) { - set(get() + (x == null ? 0 : x)); - return get(); + var v = get(); + var result = (v == null ? 0 : v) + (x == null ? 0 : x); + set(result); + return result; } /** @@ -156,7 +159,8 @@ public class IntegerHolder extends Holder<Integer> { * @return This object. */ public IntegerHolder decrement() { - set(get() - 1); + var v = get(); + set((v == null ? 0 : v) - 1); return this; } @@ -173,8 +177,10 @@ public class IntegerHolder extends Holder<Integer> { * @return The decremented value. */ public Integer decrementAndGet() { - set(get() - 1); - return get(); + var v = get(); + var result = (v == null ? 0 : v) - 1; + set(result); + return result; } /** @@ -212,7 +218,8 @@ public class IntegerHolder extends Holder<Integer> { * @return This object. */ public IntegerHolder increment() { - set(get() + 1); + var v = get(); + set((v == null ? 0 : v) + 1); return this; } @@ -229,8 +236,10 @@ public class IntegerHolder extends Holder<Integer> { * @return The incremented value. */ public Integer incrementAndGet() { - set(get() + 1); - return get(); + var v = get(); + var result = (v == null ? 0 : v) + 1; + set(result); + return result; } /** diff --git a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/lang/Version.java b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/lang/Version.java index 1fec0218aa..e0dd678ac0 100644 --- a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/lang/Version.java +++ b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/lang/Version.java @@ -27,6 +27,12 @@ import java.util.*; * <p> * Used to compare version numbers. * + * <h5 class='section'>Equality vs. matching:</h5> + * <p> + * {@link #equals(Object)}, {@link #hashCode()} and {@link #compareTo(Version)} are <b>strict</b> and + * mutually consistent — two versions are only equal when their full part sequences are identical + * (e.g. <js>"1.2"</js> is <b>not</b> equal to <js>"1.2.3"</js> or <js>"1.2.0"</js>). For the looser + * prefix/compatibility comparison (where trailing parts are ignored), use {@link #matches(Version)}. */ public class Version implements Comparable<Version> { @@ -93,26 +99,7 @@ public class Version implements Comparable<Version> { @Override /* Overridden from Object */ public boolean equals(Object o) { - return o instanceof Version o2 && eq(this, o2, Version::equals); - } - - /** - * Returns <jk>true</jk> if the specified version is equal to this version. - * - * <h5 class='section'>Example:</h5> - * <p class='bjava'> - * <jsm>assertTrue</jsm>(Version.<jsm>of</jsm>(<js>"1.2.3"</js>).isEqualsTo(Version.<jsm>of</jsm>(<js>"1.2.3"</js>))); - * <jsm>assertTrue</jsm>(Version.<jsm>of</jsm>(<js>"1.2.3"</js>).isEqualsTo(Version.<jsm>of</jsm>(<js>"1.2"</js>))); - * </p> - * - * @param v The version to compare to. - * @return <jk>true</jk> if the specified version is equal to this version. - */ - public boolean equals(Version v) { - for (int i = 0; i < Math.min(parts.length, v.parts.length); i++) - if (v.parts[i] - parts[i] != 0) - return false; - return true; + return o instanceof Version o2 && Arrays.equals(parts, o2.parts); } /** @@ -248,6 +235,35 @@ public class Version implements Comparable<Version> { return ! exclusive; } + /** + * Returns <jk>true</jk> if this version matches the specified version, comparing only the parts they have in + * common (i.e. one version is a prefix of the other). + * + * <p> + * This is a looser comparison than {@link #equals(Object)}, which requires the full version part sequences to be + * identical. Two versions <i>match</i> when every part up to the length of the shorter version is identical; any + * trailing parts on the longer version are ignored. Unlike {@link #equals(Object)}, this relation is <b>not</b> + * consistent with {@link #hashCode()} and must never be used as the basis for hash- or tree-based collection + * membership. + * + * <h5 class='section'>Example:</h5> + * <p class='bjava'> + * <jsm>assertTrue</jsm>(Version.<jsm>of</jsm>(<js>"1.2.3"</js>).matches(Version.<jsm>of</jsm>(<js>"1.2.3"</js>))); + * <jsm>assertTrue</jsm>(Version.<jsm>of</jsm>(<js>"1.2.3"</js>).matches(Version.<jsm>of</jsm>(<js>"1.2"</js>))); + * <jsm>assertTrue</jsm>(Version.<jsm>of</jsm>(<js>"1.2"</js>).matches(Version.<jsm>of</jsm>(<js>"1.2.3"</js>))); + * <jsm>assertFalse</jsm>(Version.<jsm>of</jsm>(<js>"1.2.3"</js>).matches(Version.<jsm>of</jsm>(<js>"1.2.4"</js>))); + * </p> + * + * @param v The version to compare to. + * @return <jk>true</jk> if this version matches the specified version on their common parts. + */ + public boolean matches(Version v) { + for (int i = 0; i < Math.min(parts.length, v.parts.length); i++) + if (v.parts[i] - parts[i] != 0) + return false; + return true; + } + @Override /* Overridden from Object */ public String toString() { return join(parts, '.'); diff --git a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/ClassUtils.java b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/ClassUtils.java index 6a532892ef..c5e507debe 100644 --- a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/ClassUtils.java +++ b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/ClassUtils.java @@ -48,6 +48,7 @@ public class ClassUtils { // Argument name constants for assertArgNotNull private static final String ARG_value = "value"; private static final String ARG_args = "args"; + private static final String ARG_paramTypes = "paramTypes"; private static final String ARG_x = "x"; /** @@ -357,6 +358,7 @@ public class ClassUtils { * matches (fast path optimization). */ public static Object[] getMatchingArgs(Class<?>[] paramTypes, Object...args) { + assertArgNotNull(ARG_paramTypes, paramTypes); assertArgNotNull(ARG_args, args); var needsShuffle = paramTypes.length != args.length; if (! needsShuffle) { diff --git a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/StringUtils.java b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/StringUtils.java index b5a48e6549..783ef5c977 100644 --- a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/StringUtils.java +++ b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/StringUtils.java @@ -516,7 +516,7 @@ public class StringUtils { if (i == 0) { result.append(uncapitalize(word)); } else { - result.append(capitalize(word.toLowerCase())); + result.append(capitalize(lowerCaseRoot(word))); } } @@ -2699,9 +2699,9 @@ public class StringUtils { if (end > lines.length) end = lines.length; var sb = new StringBuilder(); - var format = String.format("%%0%dd", digits); + var format = String.format(Locale.ROOT, "%%0%dd", digits); for (var l : fixedSizeList(lines).subList(start - 1, end)) - sb.append(String.format(format, start++)).append(": ").append(l).append("\n"); + sb.append(String.format(Locale.ROOT, format, start++)).append(": ").append(l).append("\n"); return sb.toString(); } @@ -3283,6 +3283,7 @@ public class StringUtils { "java:S3776" // Inherent branching in a hand-written JSON-number-grammar scanner (sign, integer part, optional fraction, optional exponent); splitting would harm readability. }) public static int matchNumberPrefix(String s, boolean allowLeadingZeros) { + assertArgNotNull(ARG_s, s); var len = s.length(); var i = 0; if (i < len && s.charAt(i) == '-') @@ -4249,7 +4250,7 @@ public class StringUtils { for (var i = 0; i < words.size(); i++) { if (i > 0) result.append('-'); - result.append(words.get(i).toLowerCase()); + result.append(lowerCaseRoot(words.get(i))); } return result.toString(); @@ -5609,7 +5610,7 @@ public class StringUtils { var result = new StringBuilder(); for (var word : words) { - result.append(capitalize(word.toLowerCase())); + result.append(capitalize(lowerCaseRoot(word))); } return result.toString(); @@ -5640,7 +5641,7 @@ public class StringUtils { if (count == 1) return word; - var lower = word.toLowerCase(); + var lower = lowerCaseRoot(word); var length = word.length(); // Words ending in s, x, z, ch, sh -> add "es" @@ -6380,7 +6381,7 @@ public class StringUtils { for (var i = 0; i < words.size(); i++) { if (i > 0) result.append('_'); - result.append(words.get(i).toLowerCase()); + result.append(lowerCaseRoot(words.get(i))); } return result.toString(); diff --git a/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/lang/Version_Test.java b/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/lang/Version_Test.java index 433b6051a5..689f9b9ff7 100644 --- a/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/lang/Version_Test.java +++ b/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/lang/Version_Test.java @@ -92,15 +92,26 @@ class Version_Test extends TestBase { assertTrue(x.isAtMost(of("1.3.0.1"))); } - @Test void a04_isEqualsTo() { + @Test void a04_equals() { var x = of("1.2.3"); + // equals(Object) is strict/exact: only identical part sequences are equal. assertEquals(x, of("1.2.3")); - assertEquals(x, of("1.2")); - assertEquals(x, of("1.2.3.4")); + assertNotEquals(x, of("1.2")); + assertNotEquals(x, of("1.2.3.4")); assertNotEquals(x, of("1.2.4")); } + @Test void a04b_matches() { + var x = of("1.2.3"); + + // matches(Version) is the looser prefix comparison (trailing parts ignored). + assertTrue(x.matches(of("1.2.3"))); + assertTrue(x.matches(of("1.2"))); + assertTrue(x.matches(of("1.2.3.4"))); + assertFalse(x.matches(of("1.2.4"))); + } + @Test void a05_compareTo() { var l = l( of("1.2.3"), @@ -165,18 +176,22 @@ class Version_Test extends TestBase { void b06_equalsObject_versionsWithDifferentLengths() { var v1 = of("1.2"); var v2 = of("1.2.0"); - // equals(Version) compares only common parts, so these should be equal - assertEquals(v1, v2); - assertEquals(v2, v1); + // equals(Object) is strict: differing lengths are not equal (but they still match()). + assertNotEquals(v1, v2); + assertNotEquals(v2, v1); + assertTrue(v1.matches(v2)); + assertTrue(v2.matches(v1)); } @Test void b07_equalsObject_versionsWithTrailingZeros() { var v1 = of("1.2.3"); var v2 = of("1.2.3.0"); - // equals(Version) compares only common parts, so these should be equal - assertEquals(v1, v2); - assertEquals(v2, v1); + // equals(Object) is strict: a trailing zero makes them unequal (but they still match()). + assertNotEquals(v1, v2); + assertNotEquals(v2, v1); + assertTrue(v1.matches(v2)); + assertTrue(v2.matches(v1)); } @Test diff --git a/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/utils/ClassUtils_Test.java b/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/utils/ClassUtils_Test.java index 1617787c4b..59c2fe1acc 100644 --- a/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/utils/ClassUtils_Test.java +++ b/juneau-core/juneau-commons/src/test/java/org/apache/juneau/commons/utils/ClassUtils_Test.java @@ -303,7 +303,7 @@ class ClassUtils_Test { assertNull(result7[1]); // Null paramTypes - should throw - assertThrows(NullPointerException.class, () -> { + assertThrows(IllegalArgumentException.class, () -> { getMatchingArgs(null, "test"); }); }
