From 9d04c8a8af808afc8fc3162555030ad7faed5beb Mon Sep 17 00:00:00 2001 From: Alexey Semenyuk Date: Tue, 10 Mar 2026 23:46:53 +0000 Subject: [PATCH] 8379432: jpackage: Make default equals() in jdk.jpackage.test.CannedFormattedString class work as expected Reviewed-by: almatvee --- .../jdk/jpackage/test/CannedArgumentTest.java | 39 ++++++++ .../test/CannedFormattedStringTest.java | 99 +++++++++++++++++++ .../test/JPackageStringBundleTest.java | 19 ++++ .../jdk/jpackage/test/CannedArgument.java | 30 ++++++ .../jpackage/test/CannedFormattedString.java | 60 +++++------ .../jdk/jpackage/test/JPackageCommand.java | 4 +- .../jpackage/test/JPackageStringBundle.java | 11 ++- test/jdk/tools/jpackage/share/ErrorTest.java | 2 +- 8 files changed, 218 insertions(+), 46 deletions(-) create mode 100644 test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/CannedArgumentTest.java create mode 100644 test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/CannedFormattedStringTest.java diff --git a/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/CannedArgumentTest.java b/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/CannedArgumentTest.java new file mode 100644 index 00000000000..8653e9c7508 --- /dev/null +++ b/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/CannedArgumentTest.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.jpackage.test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.nio.file.Path; +import jdk.jpackage.test.CannedFormattedStringTest.Formatter; +import org.junit.jupiter.api.Test; + +class CannedArgumentTest { + + @Test + void test_cannedAbsolutePath() { + var a = Formatter.MESSAGE_FORMAT.create("Current directory: {0}", CannedArgument.cannedAbsolutePath("foo")); + assertEquals("Current directory: " + Path.of("foo").toAbsolutePath(), a.getValue()); + assertEquals("Current directory: {0}+[AbsolutePath(foo)]", a.toString()); + } +} diff --git a/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/CannedFormattedStringTest.java b/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/CannedFormattedStringTest.java new file mode 100644 index 00000000000..2e4ad9ab754 --- /dev/null +++ b/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/CannedFormattedStringTest.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.jpackage.test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNotSame; + +import java.text.MessageFormat; +import java.util.List; +import java.util.function.BiFunction; +import org.junit.jupiter.api.Test; + +class CannedFormattedStringTest { + + @Test + void test_getValue() { + var a = Formatter.MESSAGE_FORMAT.create("Hello {0}! Bye {0}", "Duke"); + assertEquals("Hello Duke! Bye Duke", a.getValue()); + assertEquals("Hello {0}! Bye {0}+[Duke]", a.toString()); + + var b = Formatter.MESSAGE_FORMAT.create("Hello {0}! Bye {0}"); + assertEquals("Hello {0}! Bye {0}", b.getValue()); + assertEquals("Hello {0}! Bye {0}", b.toString()); + } + + @Test + void test_equals() { + var a = Formatter.MESSAGE_FORMAT.create("Hello {0}! Bye {0}", "Duke"); + var b = Formatter.MESSAGE_FORMAT.create("Hello {0}! Bye {0}", "Duke"); + + assertEquals(a, b); + + a = Formatter.MESSAGE_FORMAT.create("Hello {0}! Bye {0}", "Duke"); + b = Formatter.MESSAGE_FORMAT.create("Hello {0}! Bye {0}", "Java"); + + assertNotEquals(a, b); + } + + @Test + void test_addPrefix() { + var a = Formatter.MESSAGE_FORMAT.create("Hello {0}! Bye {0}", "Duke"); + var b = a.addPrefix("{0} and {0}").addPrefix("They say: {0}"); + var str = "Hello Duke! Bye Duke"; + assertEquals(str, a.getValue()); + assertEquals("They say: " + str + " and " + str, b.getValue()); + assertEquals("They say: {0}+[{0} and {0}, Hello {0}! Bye {0}, Duke]", b.toString()); + + var c = a.addPrefix("{0} and {0}").addPrefix("They say: {0}"); + assertEquals(c, b); + assertNotSame(b, c); + } + + @Test + void test_mapArgs() { + var a = Formatter.MESSAGE_FORMAT.create("Hello {0}! Bye {0}", "Duke"); + var b = a.mapArgs(arg -> { + assertEquals("Duke", arg); + return "Java"; + }); + + assertEquals("Hello Duke! Bye Duke", a.getValue()); + assertEquals("Hello Java! Bye Java", b.getValue()); + } + + enum Formatter implements BiFunction { + MESSAGE_FORMAT { + @Override + public String apply(String format, Object[] formatArgs) { + return MessageFormat.format(format, formatArgs); + } + }, + ; + + CannedFormattedString create(String format, Object ... formatArgs) { + return new CannedFormattedString(this, format, List.of(formatArgs)); + } + } +} diff --git a/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/JPackageStringBundleTest.java b/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/JPackageStringBundleTest.java index bf1eb2bdaec..0512d03b76a 100644 --- a/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/JPackageStringBundleTest.java +++ b/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/JPackageStringBundleTest.java @@ -24,6 +24,7 @@ package jdk.jpackage.test; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertThrowsExactly; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -46,6 +47,24 @@ class JPackageStringBundleTest { assertFalse(JPackageStringBundle.MAIN.cannedFormattedString("error.version-string-empty").getValue().isBlank()); } + @Test + void test_cannedFormattedString_equals() { + var a = JPackageStringBundle.MAIN.cannedFormattedString("error.version-string-empty"); + var b = JPackageStringBundle.MAIN.cannedFormattedString("error.version-string-empty"); + + assertEquals(a, b); + + a = JPackageStringBundle.MAIN.cannedFormattedString("message.error-header", "foo"); + b = JPackageStringBundle.MAIN.cannedFormattedString("message.error-header", "foo"); + + assertEquals(a, b); + + a = JPackageStringBundle.MAIN.cannedFormattedString("message.error-header", "foo"); + b = JPackageStringBundle.MAIN.cannedFormattedString("message.error-header", "bar"); + + assertNotEquals(a, b); + } + @Test void test_cannedFormattedStringAsPattern() { var pred = JPackageStringBundle.MAIN.cannedFormattedStringAsPattern("error.version-string-empty", UNREACHABLE_FORMAT_ARG_MAPPER).asMatchPredicate(); diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/CannedArgument.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/CannedArgument.java index b50d12ac4ec..346b172fa35 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/CannedArgument.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/CannedArgument.java @@ -22,7 +22,37 @@ */ package jdk.jpackage.test; +import java.nio.file.Path; +import java.util.Objects; +import java.util.function.Supplier; + @FunctionalInterface public interface CannedArgument { + public String getValue(); + + public static CannedArgument create(Supplier supplier, String label) { + Objects.requireNonNull(supplier); + Objects.requireNonNull(label); + return new CannedArgument() { + + @Override + public String getValue() { + return supplier.get().toString(); + } + + @Override + public String toString( ) { + return label; + } + }; + } + + public static Object cannedAbsolutePath(Path v) { + return create(v::toAbsolutePath, String.format("AbsolutePath(%s)", v)); + } + + public static Object cannedAbsolutePath(String v) { + return cannedAbsolutePath(Path.of(v)); + } } diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/CannedFormattedString.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/CannedFormattedString.java index 09f867da786..d5248ee2b17 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/CannedFormattedString.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/CannedFormattedString.java @@ -22,55 +22,29 @@ */ package jdk.jpackage.test; -import java.nio.file.Path; import java.util.Arrays; import java.util.List; import java.util.Objects; import java.util.function.BiFunction; -import java.util.function.Supplier; import java.util.function.UnaryOperator; import java.util.stream.Stream; -public record CannedFormattedString(BiFunction formatter, String key, Object[] args) implements CannedArgument { - - public static CannedArgument cannedArgument(Supplier supplier, String label) { - Objects.requireNonNull(supplier); - Objects.requireNonNull(label); - return new CannedArgument() { - - @Override - public String getValue() { - return supplier.get().toString(); - } - - @Override - public String toString( ) { - return label; - } - }; - } - - public static Object cannedAbsolutePath(Path v) { - return cannedArgument(() -> v.toAbsolutePath(), String.format("AbsolutePath(%s)", v)); - } - - public static Object cannedAbsolutePath(String v) { - return cannedAbsolutePath(Path.of(v)); - } +public record CannedFormattedString(BiFunction formatter, String key, List args) implements CannedArgument { public CannedFormattedString mapArgs(UnaryOperator mapper) { - return new CannedFormattedString(formatter, key, Stream.of(args).map(mapper).toArray()); + return new CannedFormattedString(formatter, key, args.stream().map(mapper).toList()); } public CannedFormattedString { Objects.requireNonNull(formatter); Objects.requireNonNull(key); Objects.requireNonNull(args); - List.of(args).forEach(Objects::requireNonNull); + args.forEach(Objects::requireNonNull); } + @Override public String getValue() { - return formatter.apply(key, Stream.of(args).map(arg -> { + return formatter.apply(key, args.stream().map(arg -> { if (arg instanceof CannedArgument cannedArg) { return cannedArg.getValue(); } else { @@ -80,19 +54,29 @@ public record CannedFormattedString(BiFunction formatt } public CannedFormattedString addPrefix(String prefixKey) { - Objects.requireNonNull(prefixKey); - return new CannedFormattedString((theKey, theArgs) -> { - var str = formatter.apply((String)theArgs[0], Arrays.copyOfRange(theArgs, 1, theArgs.length)); - return formatter.apply(theKey, new Object[] {str}); - }, prefixKey, Stream.concat(Stream.of(key), Stream.of(args)).toArray()); + return new CannedFormattedString( + new AddPrefixFormatter(formatter), prefixKey, Stream.concat(Stream.of(key), args.stream()).toList()); } @Override public String toString() { - if (args.length == 0) { + if (args.isEmpty()) { return String.format("%s", key); } else { - return String.format("%s+%s", key, List.of(args)); + return String.format("%s+%s", key, args); + } + } + + private record AddPrefixFormatter(BiFunction formatter) implements BiFunction { + + AddPrefixFormatter { + Objects.requireNonNull(formatter); + } + + @Override + public String apply(String format, Object[] formatArgs) { + var str = formatter.apply((String)formatArgs[0], Arrays.copyOfRange(formatArgs, 1, formatArgs.length)); + return formatter.apply(format, new Object[] {str}); } } } diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java index f68ac90d284..67c0ba41e3f 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java @@ -966,13 +966,13 @@ public class JPackageCommand extends CommandArguments { } public String getValue(CannedFormattedString str) { - return new CannedFormattedString(str.formatter(), str.key(), Stream.of(str.args()).map(arg -> { + return new CannedFormattedString(str.formatter(), str.key(), str.args().stream().map(arg -> { if (arg instanceof CannedArgument cannedArg) { return cannedArg.value(this); } else { return arg; } - }).toArray()).getValue(); + }).toList()).getValue(); } public JPackageCommand validateOut(CannedFormattedString... strings) { diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageStringBundle.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageStringBundle.java index cd8ffd853b7..dcf994a0e93 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageStringBundle.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageStringBundle.java @@ -31,6 +31,7 @@ import java.text.MessageFormat; import java.util.List; import java.util.Objects; import java.util.Optional; +import java.util.function.BiFunction; import java.util.function.Function; import java.util.regex.Pattern; @@ -48,6 +49,9 @@ public enum JPackageStringBundle { } catch (ClassNotFoundException|NoSuchMethodException ex) { throw toUnchecked(ex); } + formatter = (String key, Object[] args) -> { + return new FormattedMessage(key, args).value(); + }; } /** @@ -61,12 +65,8 @@ public enum JPackageStringBundle { } } - private String getFormattedString(String key, Object[] args) { - return new FormattedMessage(key, args).value(); - } - public CannedFormattedString cannedFormattedString(String key, Object ... args) { - return new CannedFormattedString(this::getFormattedString, key, args); + return new CannedFormattedString(formatter, key, List.of(args)); } public Pattern cannedFormattedStringAsPattern(String key, Function formatArgMapper, Object ... args) { @@ -153,4 +153,5 @@ public enum JPackageStringBundle { private final Class i18nClass; private final Method i18nClass_getString; + private final BiFunction formatter; } diff --git a/test/jdk/tools/jpackage/share/ErrorTest.java b/test/jdk/tools/jpackage/share/ErrorTest.java index db87263884b..2797115b202 100644 --- a/test/jdk/tools/jpackage/share/ErrorTest.java +++ b/test/jdk/tools/jpackage/share/ErrorTest.java @@ -713,7 +713,7 @@ public final class ErrorTest { private static void testMacSignWithoutIdentityWithNewTKitState(TestSpec spec) { final Token keychainToken = spec.expectedMessages().stream().flatMap(cannedStr -> { - return Stream.of(cannedStr.args()).filter(Token.class::isInstance).map(Token.class::cast).filter(token -> { + return cannedStr.args().stream().filter(Token.class::isInstance).map(Token.class::cast).filter(token -> { switch (token) { case EMPTY_KEYCHAIN, KEYCHAIN_WITH_APP_IMAGE_CERT, KEYCHAIN_WITH_PKG_CERT -> { return true;