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
The following commit(s) were added to refs/heads/master by this push:
new 1addbc9c8 Test modernization
1addbc9c8 is described below
commit 1addbc9c813e27f949e96b280e636763f1e9e75f
Author: James Bognar <[email protected]>
AuthorDate: Fri Sep 12 14:30:50 2025 -0400
Test modernization
---
.../apache/juneau/dto/swagger/Contact_Test.java | 2 +-
.../dto/swagger/ExternalDocumentation_Test.java | 2 +-
.../apache/juneau/dto/swagger/HeaderInfo_Test.java | 2 +-
.../org/apache/juneau/dto/swagger/Info_Test.java | 2 +-
.../org/apache/juneau/dto/swagger/Items_Test.java | 2 +-
.../apache/juneau/dto/swagger/License_Test.java | 2 +-
.../apache/juneau/dto/swagger/Operation_Test.java | 2 +-
.../juneau/dto/swagger/ParameterInfo_Test.java | 2 +-
.../juneau/dto/swagger/ResponseInfo_Test.java | 2 +-
.../apache/juneau/dto/swagger/SchemaInfo_Test.java | 2 +-
.../juneau/dto/swagger/SecurityScheme_Test.java | 2 +-
.../apache/juneau/dto/swagger/Swagger_Test.java | 2 +-
.../org/apache/juneau/dto/swagger/Tag_Test.java | 2 +-
.../org/apache/juneau/dto/swagger/Xml_Test.java | 2 +-
.../org/apache/juneau/junit/bct/AssertionArgs.java | 2 +-
.../juneau/junit/bct/BasicBeanConverter.java | 7 +-
.../juneau/junit/bct/BasicBeanConverter_Test.java | 19 +++--
.../org/apache/juneau/junit/bct/BctAssertions.java | 73 +++++++++++++++----
.../juneau/junit/bct/BctAssertions_Test.java | 73 ++++++++++++++++++-
.../juneau/junit/bct/BeanConverter_Test.java | 2 +-
.../org/apache/juneau/junit/bct/Listifiers.java | 64 +++++++++++++++--
.../apache/juneau/junit/bct/Listifiers_Test.java | 81 ++++++++++++++++++++--
.../apache/juneau/junit/bct/NestedTokenizer.java | 2 +-
.../org/apache/juneau/junit/bct/Stringifiers.java | 12 ++--
.../java/org/apache/juneau/junit/bct/Utils.java | 2 +-
.../org/apache/juneau/junit/bct/Utils_Test.java | 2 +-
26 files changed, 301 insertions(+), 66 deletions(-)
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/Contact_Test.java
b/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/Contact_Test.java
index 59c6d4c33..03daac638 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/Contact_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/Contact_Test.java
@@ -115,6 +115,6 @@ class Contact_Test extends SimpleTestBase {
.set("email", "c")
.set("$ref", "d");
- assertList(t.keySet(), "email", "name", "url", "$ref");
+ assertList(t.keySet(), "$ref", "email", "name", "url");
}
}
\ No newline at end of file
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/ExternalDocumentation_Test.java
b/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/ExternalDocumentation_Test.java
index ddb09d221..56aadd6ff 100644
---
a/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/ExternalDocumentation_Test.java
+++
b/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/ExternalDocumentation_Test.java
@@ -111,6 +111,6 @@ class ExternalDocumentation_Test extends SimpleTestBase {
.set("url", "bar")
.set("$ref", "baz");
- assertList(t.keySet(), "description", "url", "$ref");
+ assertList(t.keySet(), "$ref", "description", "url");
}
}
\ No newline at end of file
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/HeaderInfo_Test.java
b/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/HeaderInfo_Test.java
index c88faf541..78ec56b13 100644
---
a/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/HeaderInfo_Test.java
+++
b/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/HeaderInfo_Test.java
@@ -233,7 +233,7 @@ class HeaderInfo_Test extends SimpleTestBase {
.set("type", "j")
.set("uniqueItems", true);
- assertList(t.keySet(), "collectionFormat", "default",
"description", "enum", "example", "exclusiveMaximum", "exclusiveMinimum",
"format", "items", "maximum", "maxItems", "maxLength", "minimum", "minItems",
"minLength", "multipleOf", "pattern", "$ref", "type", "uniqueItems");
+ assertList(t.keySet(), "$ref", "collectionFormat", "default",
"description", "enum", "example", "exclusiveMaximum", "exclusiveMinimum",
"format", "items", "maxItems", "maxLength", "maximum", "minItems", "minLength",
"minimum", "multipleOf", "pattern", "type", "uniqueItems");
}
@Test void c01_strict() {
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/Info_Test.java
b/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/Info_Test.java
index 6b53d16c4..8f55a589a 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/Info_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/Info_Test.java
@@ -149,6 +149,6 @@ class Info_Test extends SimpleTestBase {
.set("version", "f")
.set("$ref", "ref");
- assertList(t.keySet(), "contact", "description", "license",
"termsOfService", "title", "version", "$ref");
+ assertList(t.keySet(), "$ref", "contact", "description",
"license", "termsOfService", "title", "version");
}
}
\ No newline at end of file
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/Items_Test.java
b/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/Items_Test.java
index 6b0efbe0d..31a0513a4 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/Items_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/Items_Test.java
@@ -226,7 +226,7 @@ class Items_Test extends SimpleTestBase {
assertList(
t.keySet(),
- "collectionFormat", "default", "enum",
"exclusiveMaximum", "exclusiveMinimum", "format", "items", "maximum",
"maxItems", "maxLength", "minimum", "minItems", "minLength", "multipleOf",
"pattern", "$ref", "type", "uniqueItems"
+ "$ref", "collectionFormat", "default", "enum",
"exclusiveMaximum", "exclusiveMinimum", "format", "items", "maxItems",
"maxLength", "maximum", "minItems", "minLength", "minimum", "multipleOf",
"pattern", "type", "uniqueItems"
);
}
}
\ No newline at end of file
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/License_Test.java
b/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/License_Test.java
index 2e6a4cc60..2baf0d94e 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/License_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/License_Test.java
@@ -126,6 +126,6 @@ class License_Test extends SimpleTestBase {
.set("url", URI.create("b"))
.set("$ref", "c");
- assertList(t.keySet(), "name", "url", "$ref");
+ assertList(t.keySet(), "$ref", "name", "url");
}
}
\ No newline at end of file
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/Operation_Test.java
b/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/Operation_Test.java
index 46e69d523..374fe7750 100644
---
a/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/Operation_Test.java
+++
b/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/Operation_Test.java
@@ -208,6 +208,6 @@ class Operation_Test extends SimpleTestBase {
.set("tags", set("k"))
.set("$ref", "l");
- assertList(t.keySet(), "consumes", "deprecated", "description",
"externalDocs", "operationId", "parameters", "produces", "responses",
"schemes", "security", "summary", "tags", "$ref");
+ assertList(t.keySet(), "$ref", "consumes", "deprecated",
"description", "externalDocs", "operationId", "parameters", "produces",
"responses", "schemes", "security", "summary", "tags");
}
}
\ No newline at end of file
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/ParameterInfo_Test.java
b/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/ParameterInfo_Test.java
index a2ae03b8a..8d42167f5 100644
---
a/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/ParameterInfo_Test.java
+++
b/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/ParameterInfo_Test.java
@@ -258,6 +258,6 @@ class ParameterInfo_Test extends SimpleTestBase {
.set("uniqueItems", true)
.set("$ref", "l");
- assertList(t.keySet(), "allowEmptyValue", "collectionFormat",
"default", "description", "enum", "exclusiveMaximum", "exclusiveMinimum",
"format", "in", "items", "maximum", "maxItems", "maxLength", "minimum",
"minItems", "minLength", "multipleOf", "name", "pattern", "required", "schema",
"type", "uniqueItems", "$ref");
+ assertList(t.keySet(), "$ref", "allowEmptyValue",
"collectionFormat", "default", "description", "enum", "exclusiveMaximum",
"exclusiveMinimum", "format", "in", "items", "maxItems", "maxLength",
"maximum", "minItems", "minLength", "minimum", "multipleOf", "name", "pattern",
"required", "schema", "type", "uniqueItems");
}
}
\ No newline at end of file
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/ResponseInfo_Test.java
b/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/ResponseInfo_Test.java
index 386ee618c..a131267c4 100644
---
a/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/ResponseInfo_Test.java
+++
b/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/ResponseInfo_Test.java
@@ -158,6 +158,6 @@ class ResponseInfo_Test extends SimpleTestBase {
.set("schema", schemaInfo().setType("d"))
.set("$ref", "e");
- assertList(t.keySet(), "description", "examples", "headers",
"schema", "$ref");
+ assertList(t.keySet(), "$ref", "description", "examples",
"headers", "schema");
}
}
\ No newline at end of file
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/SchemaInfo_Test.java
b/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/SchemaInfo_Test.java
index 153a2eb48..186c13aec 100644
---
a/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/SchemaInfo_Test.java
+++
b/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/SchemaInfo_Test.java
@@ -295,6 +295,6 @@ class SchemaInfo_Test extends SimpleTestBase {
.set("uniqueItems", true)
.set("xml", xml().setName("o"));
- assertList(t.keySet(), "additionalProperties", "allOf",
"default", "description", "discriminator", "enum", "example",
"exclusiveMaximum", "exclusiveMinimum", "externalDocs", "format", "items",
"maximum", "maxItems", "maxLength", "maxProperties", "minimum", "minItems",
"minLength", "minProperties", "multipleOf", "pattern", "properties",
"readOnly", "$ref", "requiredProperties", "title", "type", "uniqueItems",
"xml");
+ assertList(t.keySet(), "$ref", "additionalProperties", "allOf",
"default", "description", "discriminator", "enum", "example",
"exclusiveMaximum", "exclusiveMinimum", "externalDocs", "format", "items",
"maxItems", "maxLength", "maxProperties", "maximum", "minItems", "minLength",
"minProperties", "minimum", "multipleOf", "pattern", "properties", "readOnly",
"requiredProperties", "title", "type", "uniqueItems", "xml");
}
}
\ No newline at end of file
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/SecurityScheme_Test.java
b/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/SecurityScheme_Test.java
index 24326dcb5..bf4f45187 100644
---
a/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/SecurityScheme_Test.java
+++
b/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/SecurityScheme_Test.java
@@ -165,6 +165,6 @@ class SecurityScheme_Test extends SimpleTestBase {
.set("type", "g")
.set("$ref", "ref");
- assertList(t.keySet(), "authorizationUrl", "description",
"flow", "in", "name", "scopes", "tokenUrl", "type", "$ref");
+ assertList(t.keySet(), "$ref", "authorizationUrl",
"description", "flow", "in", "name", "scopes", "tokenUrl", "type");
}
}
\ No newline at end of file
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/Swagger_Test.java
b/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/Swagger_Test.java
index 245a244ef..2aa1f77e6 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/Swagger_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/Swagger_Test.java
@@ -248,6 +248,6 @@ class Swagger_Test extends SimpleTestBase {
.set("tags", set(tag("o")))
.set("$ref", "p");
- assertList(t.keySet(), "basePath", "consumes", "definitions",
"externalDocs", "host", "info", "parameters", "paths", "produces", "responses",
"schemes", "security", "securityDefinitions", "swagger", "tags", "$ref");
+ assertList(t.keySet(), "$ref", "basePath", "consumes",
"definitions", "externalDocs", "host", "info", "parameters", "paths",
"produces", "responses", "schemes", "security", "securityDefinitions",
"swagger", "tags");
}
}
\ No newline at end of file
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/Tag_Test.java
b/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/Tag_Test.java
index 4ad10a920..ed41be930 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/Tag_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/Tag_Test.java
@@ -134,6 +134,6 @@ class Tag_Test extends SimpleTestBase {
.set("name", "c")
.set("$ref", "ref");
- assertList(t.keySet(), "description", "externalDocs", "name",
"$ref");
+ assertList(t.keySet(), "$ref", "description", "externalDocs",
"name");
}
}
\ No newline at end of file
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/Xml_Test.java
b/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/Xml_Test.java
index cd4f000b8..01bfd233c 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/Xml_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/Xml_Test.java
@@ -143,6 +143,6 @@ class Xml_Test extends SimpleTestBase {
.set("wrapped", true)
.set("$ref", "d");
- assertList(t.keySet(), "attribute", "name", "namespace",
"prefix", "wrapped", "$ref");
+ assertList(t.keySet(), "$ref", "attribute", "name",
"namespace", "prefix", "wrapped");
}
}
\ No newline at end of file
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/junit/bct/AssertionArgs.java
b/juneau-utest/src/test/java/org/apache/juneau/junit/bct/AssertionArgs.java
index 911cec8fb..72e50498a 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/junit/bct/AssertionArgs.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/junit/bct/AssertionArgs.java
@@ -82,7 +82,7 @@ import java.util.function.*;
* <h5 class='section'>Error Message Composition:</h5>
* <p>When assertion failures occur, error messages are intelligently
composed:</p>
* <ul>
- * <li><b>Base Message:</b> Custom message set via {@link
#setMessage(String, Object)} or {@link #setMessage(Supplier)}</li>
+ * <li><b>Base Message:</b> Custom message set via {@link
#setMessage(String, Object...)} or {@link #setMessage(Supplier)}</li>
* <li><b>Assertion Context:</b> Specific context provided by individual
assertion methods</li>
* <li><b>Composite Format:</b> <js>"{base message}, Caused by: {assertion
context}"</js></li>
* </ul>
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/junit/bct/BasicBeanConverter.java
b/juneau-utest/src/test/java/org/apache/juneau/junit/bct/BasicBeanConverter.java
index a1e28f1c7..a7766f553 100644
---
a/juneau-utest/src/test/java/org/apache/juneau/junit/bct/BasicBeanConverter.java
+++
b/juneau-utest/src/test/java/org/apache/juneau/junit/bct/BasicBeanConverter.java
@@ -13,8 +13,8 @@
package org.apache.juneau.junit.bct;
import static java.util.Optional.*;
-import static java.util.stream.Collectors.*;
import static org.apache.juneau.junit.bct.Utils.*;
+import static java.util.stream.Collectors.*;
import java.io.*;
import java.lang.reflect.*;
@@ -623,8 +623,11 @@ public class BasicBeanConverter implements BeanConverter {
addStringifier(List.class,
Stringifiers.listStringifier());
addStringifier(Map.class,
Stringifiers.mapStringifier());
- addListifier(Collection.class,
Listifiers.collectionListifier());
+ // Note: Listifiers are processed in reverse
registration order (last registered wins).
+ // Collection must be registered after Iterable so it
takes precedence for Sets,
+ // ensuring TreeSet conversion for deterministic
ordering.
addListifier(Iterable.class,
Listifiers.iterableListifier());
+ addListifier(Collection.class,
Listifiers.collectionListifier());
addListifier(Iterator.class,
Listifiers.iteratorListifier());
addListifier(Enumeration.class,
Listifiers.enumerationListifier());
addListifier(Stream.class,
Listifiers.streamListifier());
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/junit/bct/BasicBeanConverter_Test.java
b/juneau-utest/src/test/java/org/apache/juneau/junit/bct/BasicBeanConverter_Test.java
index d227711b9..1ec8a31f7 100644
---
a/juneau-utest/src/test/java/org/apache/juneau/junit/bct/BasicBeanConverter_Test.java
+++
b/juneau-utest/src/test/java/org/apache/juneau/junit/bct/BasicBeanConverter_Test.java
@@ -12,8 +12,8 @@
//
***************************************************************************************************************************
package org.apache.juneau.junit.bct;
-import static org.apache.juneau.junit.bct.BasicBeanConverter.*;
import static org.apache.juneau.junit.bct.BctAssertions.*;
+import static org.apache.juneau.junit.bct.BasicBeanConverter.*;
import static org.junit.jupiter.api.Assertions.*;
import java.time.*;
@@ -182,12 +182,9 @@ class BasicBeanConverter_Test extends TestBase {
void b04_stringify_handlesCollections() {
assertEquals("[1,2,3]",
converter.stringify(Arrays.asList(1, 2, 3)));
assertEquals("[]",
converter.stringify(Collections.emptyList()));
- // Set order is not guaranteed, so check length and
content
- var setResult = converter.stringify(Set.of("a", "b",
"c"));
- assertEquals(7, setResult.length()); // Should be
"[x,y,z]" format
- assertTrue(setResult.contains("a"));
- assertTrue(setResult.contains("b"));
- assertTrue(setResult.contains("c"));
+ // Set converted to TreeSet for deterministic ordering
+ var setResult = converter.stringify(Set.of("z", "a",
"m"));
+ assertEquals("[a,m,z]", setResult); // TreeSet ensures
natural order
}
@Test
@@ -226,11 +223,11 @@ class BasicBeanConverter_Test extends TestBase {
@Test
@DisplayName("b09_listify() handles collections")
- void b09_listify_handlesCollections() {
- var set = Set.of("a", "b", "c");
+ void b09_listify_handlesCollections() {
+ var set = Set.of("z", "a", "m");
var result = converter.listify(set);
- assertEquals(3, result.size());
- assertTrue(result.containsAll(Arrays.asList("a", "b",
"c")));
+ // TreeSet conversion ensures natural ordering
+ assertList(result, "a", "m", "z");
}
@Test
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/junit/bct/BctAssertions.java
b/juneau-utest/src/test/java/org/apache/juneau/junit/bct/BctAssertions.java
index 365397576..2573e8184 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/junit/bct/BctAssertions.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/junit/bct/BctAssertions.java
@@ -619,8 +619,30 @@ public class BctAssertions {
assertNotNull(actual, "Value was null.");
var a =
args.getBeanConverter().orElse(DEFAULT_CONVERTER).stringify(actual);
- for (var e : expected)
- assertTrue(a.contains(e), args.getMessage("String did
not contain expected substring. ==> expected: <{0}> but was: <{1}>", e, a));
+ var errors = new ArrayList<AssertionFailedError>();
+
+ for (var e : expected) {
+ if (!a.contains(e)) {
+ errors.add(assertEqualsFailed(true, false,
args.getMessage("String did not contain expected substring. ==> expected:
<{0}> but was: <{1}>", e, a)));
+ }
+ }
+
+ if (errors.isEmpty()) return;
+
+ if (errors.size() == 1) throw errors.get(0);
+
+ var missingSubstrings = new ArrayList<String>();
+ for (var e : expected) {
+ if (!a.contains(e)) {
+ missingSubstrings.add(e);
+ }
+ }
+
+ throw assertEqualsFailed(
+
missingSubstrings.stream().map(Utils::escapeForJava).collect(joining("\", \"",
"\"", "\"")),
+ Utils.escapeForJava(a),
+ args.getMessage("{0} substring assertions
failed:\n{1}", errors.size(), errors.stream().map(x ->
x.getMessage()).collect(joining("\n")))
+ );
}
/**
@@ -767,19 +789,44 @@ public class BctAssertions {
var converter =
args.getBeanConverter().orElse(DEFAULT_CONVERTER);
var list = converter.listify(actual);
- assertEquals(expected.length, list.size(),
args.getMessage("Wrong list length."));
-
- for (var i = 0; i < expected.length; i++) {
- var x = list.get(i);
- var e = expected[i];
- if (e instanceof String e2) {
- assertEquals(e2, converter.stringify(x),
args.getMessage("Element at index {0} did not match.", i));
- } else if (e instanceof Predicate e2) { // NOSONAR
- assertTrue(e2.test(x), args.getMessage("Element
at index {0} did not pass predicate. ==> actual: <{1}>", i,
converter.stringify(x)));
- } else {
- assertEquals(e, x, args.getMessage("Element at
index {0} did not match. ==> expected: <{1}({2})> but was: <{3}(4)>", i, e,
t(e), x, t(x)));
+ var errors = new ArrayList<AssertionFailedError>();
+
+ if (ne(expected.length, list.size())) {
+ errors.add(assertEqualsFailed(expected.length,
list.size(), args.getMessage("Wrong list length.")));
+ } else {
+ for (var i = 0; i < expected.length; i++) {
+ var x = list.get(i);
+ var e = expected[i];
+ if (e instanceof String e2) {
+ if (ne(e2, converter.stringify(x))) {
+
errors.add(assertEqualsFailed(e2, converter.stringify(x),
args.getMessage("Element at index {0} did not match.", i)));
+ }
+ } else if (e instanceof Predicate e2) { //
NOSONAR
+ if (!e2.test(x)) {
+ errors.add(new
AssertionFailedError(args.getMessage("Element at index {0} did not pass
predicate. ==> actual: <{1}>", i, converter.stringify(x)).get()));
+ }
+ } else {
+ if (ne(e, x)) {
+
errors.add(assertEqualsFailed(e, x, args.getMessage("Element at index {0} did
not match. ==> expected: <{1}({2})> but was: <{3}({4})>", i, e, t(e), x,
t(x))));
+ }
+ }
}
}
+
+ if (errors.isEmpty()) return;
+
+ var actualStrings = new ArrayList<String>();
+ for (var o : list) {
+ actualStrings.add(converter.stringify(o));
+ }
+
+ if (errors.size() == 1) throw errors.get(0);
+
+ throw assertEqualsFailed(
+
Stream.of(expected).map(converter::stringify).map(Utils::escapeForJava).collect(joining("\",
\"", "[\"", "\"]")),
+
actualStrings.stream().map(Utils::escapeForJava).collect(joining("\", \"",
"[\"", "\"]")),
+ args.getMessage("{0} list assertions failed:\n{1}",
errors.size(), errors.stream().map(x -> x.getMessage()).collect(joining("\n")))
+ );
}
/**
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/junit/bct/BctAssertions_Test.java
b/juneau-utest/src/test/java/org/apache/juneau/junit/bct/BctAssertions_Test.java
index b4bc6917e..19cfdb1e9 100644
---
a/juneau-utest/src/test/java/org/apache/juneau/junit/bct/BctAssertions_Test.java
+++
b/juneau-utest/src/test/java/org/apache/juneau/junit/bct/BctAssertions_Test.java
@@ -23,7 +23,7 @@ import org.junit.jupiter.api.*;
import org.opentest4j.*;
/**
- * Unit tests for the {@link BctAssertions} class.
+ * Unit tests for the {@link Assertions2} class.
*
* <p>This test class focuses on testing the assertion methods' behavior,
error handling,
* and argument passing. The underlying BeanConverter functionality is tested
separately
@@ -243,6 +243,42 @@ class BctAssertions_Test extends TestBase {
var e = assertThrows(AssertionFailedError.class, () ->
assertContainsAll((Object)null, "test"));
assertContains("Value was null", e.getMessage());
}
+
+ @Test
+ void f05_multipleErrors() {
+ // Test that multiple missing substrings are collected
and reported together
+ var text = "Hello World Testing";
+ var expected = new String[]{"Hello", "Missing1",
"World", "Missing2", "Testing"};
+
+ var e = assertThrows(AssertionFailedError.class, () ->
assertContainsAll(text, expected));
+
+ // Should report multiple errors in a single assertion
failure
+ var message = e.getMessage();
+ assertContains("2 substring assertions failed",
message);
+ assertContains("String did not contain expected
substring", message);
+
+ // Should mention both missing substrings
+ assertContains("Missing1", message);
+ assertContains("Missing2", message);
+
+ // Should include the actual text
+ assertContains("Hello World Testing", message);
+ }
+
+ @Test
+ void f06_singleError() {
+ // Test that single errors are still reported as single
assertion failures
+ var text = "Hello World";
+ var expected = new String[]{"Hello", "Missing",
"World"};
+
+ var e = assertThrows(AssertionFailedError.class, () ->
assertContainsAll(text, expected));
+
+ // Should report single error normally (not as "1
substring assertions failed")
+ var message = e.getMessage();
+ assertDoesNotThrow(() ->
assertTrue(!message.contains("1 substring assertions failed")));
+ assertContains("String did not contain expected
substring", message);
+ assertContains("Missing", message);
+ }
}
//
====================================================================================================
@@ -337,6 +373,41 @@ class BctAssertions_Test extends TestBase {
assertContains("Element at index 0 did not pass
predicate", e.getMessage());
assertContains("actual: <1>", e.getMessage());
}
+
+ @Test
+ void h07_multipleErrors() {
+ // Test that multiple assertion errors are collected
and reported together
+ var list = Arrays.asList("a", "wrong1", "c", "wrong2",
"e");
+ var expected = new Object[]{"a", "b", "c", "d", "e"};
+
+ var e = assertThrows(AssertionFailedError.class, () ->
assertList(list, expected));
+
+ // Should report multiple errors in a single assertion
failure
+ var message = e.getMessage();
+ assertContains("2 list assertions failed", message);
+ assertContains("Element at index 1 did not match",
message);
+ assertContains("Element at index 3 did not match",
message);
+
+ // Should include both expected and actual values
+ assertContains("expected: <b>", message);
+ assertContains("but was: <wrong1>", message);
+ assertContains("expected: <d>", message);
+ assertContains("but was: <wrong2>", message);
+ }
+
+ @Test
+ void h08_singleError() {
+ // Test that single errors are still reported as single
assertion failures
+ var list = Arrays.asList("a", "wrong", "c");
+ var expected = new Object[]{"a", "b", "c"};
+
+ var e = assertThrows(AssertionFailedError.class, () ->
assertList(list, expected));
+
+ // Should report single error normally (not as "1 list
assertions failed")
+ var message = e.getMessage();
+ assertDoesNotThrow(() ->
assertTrue(!message.contains("1 list assertions failed")));
+ assertContains("Element at index 1 did not match",
message);
+ }
}
//
====================================================================================================
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/junit/bct/BeanConverter_Test.java
b/juneau-utest/src/test/java/org/apache/juneau/junit/bct/BeanConverter_Test.java
index 0c2dc82fe..9a188b30c 100644
---
a/juneau-utest/src/test/java/org/apache/juneau/junit/bct/BeanConverter_Test.java
+++
b/juneau-utest/src/test/java/org/apache/juneau/junit/bct/BeanConverter_Test.java
@@ -12,8 +12,8 @@
//
***************************************************************************************************************************
package org.apache.juneau.junit.bct;
-import static org.apache.juneau.junit.bct.Utils.*;
import static org.junit.jupiter.api.Assertions.*;
+import static org.apache.juneau.junit.bct.Utils.*;
import java.util.*;
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/junit/bct/Listifiers.java
b/juneau-utest/src/test/java/org/apache/juneau/junit/bct/Listifiers.java
index 58fb03a43..e0185c5a6 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/junit/bct/Listifiers.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/junit/bct/Listifiers.java
@@ -91,6 +91,15 @@ public class Listifiers {
* <li><b>Non-empty collections:</b> Returns new ArrayList with all
elements in iteration order</li>
* <li><b>Empty collections:</b> Returns new empty ArrayList</li>
* <li><b>Preserves order:</b> Maintains the iteration order of the
source collection</li>
+ * <li><b>Set ordering:</b> Converts unordered Sets (HashSet, etc.)
to TreeSet for deterministic ordering</li>
+ * </ul>
+ *
+ * <h5 class='section'>Set Ordering Behavior:</h5>
+ * <p>To ensure predictable test results, this listifier handles Sets
with unreliable ordering:</p>
+ * <ul>
+ * <li><b>{@link SortedSet} (TreeSet, etc.):</b> Preserves existing
sort order</li>
+ * <li><b>{@link LinkedHashSet}:</b> Preserves insertion order</li>
+ * <li><b>{@link HashSet} and other unordered Sets:</b> Converts to
{@link TreeSet} for natural ordering</li>
* </ul>
*
* <h5 class='section'>Usage Examples:</h5>
@@ -99,8 +108,13 @@ public class Listifiers {
* <jk>var</jk> <jv>list</jv> = List.<jsm>of</jsm>(<js>"a"</js>,
<js>"b"</js>, <js>"c"</js>);
* <jsm>assertList</jsm>(<jv>list</jv>, <js>"a"</js>, <js>"b"</js>,
<js>"c"</js>);
*
- * <jk>var</jk> <jv>set</jv> = Set.<jsm>of</jsm>(<js>"x"</js>,
<js>"y"</js>);
- * <jsm>assertList</jsm>(<jv>set</jv>, <js>"x"</js>, <js>"y"</js>);
<jc>// Order may vary</jc>
+ * <jc>// HashSet converted to TreeSet for predictable ordering</jc>
+ * <jk>var</jk> <jv>set</jv> = Set.<jsm>of</jsm>(<js>"z"</js>,
<js>"a"</js>, <js>"m"</js>);
+ * <jsm>assertList</jsm>(<jv>set</jv>, <js>"a"</js>, <js>"m"</js>,
<js>"z"</js>); <jc>// Natural ordering</jc>
+ *
+ * <jc>// LinkedHashSet preserves insertion order</jc>
+ * <jk>var</jk> <jv>linkedSet</jv> = <jk>new</jk>
LinkedHashSet<>(Arrays.<jsm>asList</jsm>(<js>"first"</js>,
<js>"second"</js>));
+ * <jsm>assertList</jsm>(<jv>linkedSet</jv>, <js>"first"</js>,
<js>"second"</js>);
*
* <jk>var</jk> <jv>queue</jv> = <jk>new</jk>
LinkedList<>(Arrays.<jsm>asList</jsm>(<js>"first"</js>,
<js>"second"</js>));
* <jsm>assertList</jsm>(<jv>queue</jv>, <js>"first"</js>,
<js>"second"</js>);
@@ -108,14 +122,22 @@ public class Listifiers {
*
* <h5 class='section'>Performance:</h5>
* <p>This listifier creates a new ArrayList and copies all elements,
so it has O(n) time
- * and space complexity. For large collections, consider the memory
implications.</p>
+ * and space complexity. For unordered Sets, an additional TreeSet
conversion adds O(n log n)
+ * sorting overhead. For large collections, consider the memory
implications.</p>
*
* @return A {@link Listifier} for {@link Collection} objects
* @see Collection
* @see ArrayList
+ * @see TreeSet
+ * @see LinkedHashSet
*/
public static Listifier<Collection> collectionListifier() {
- return (bc, collection) -> new ArrayList<>(collection);
+ return (bc, collection) -> {
+ if (collection instanceof Set && !(collection
instanceof SortedSet) && !(collection instanceof LinkedHashSet)) {
+ collection = new TreeSet<>(collection);
+ }
+ return new ArrayList<>(collection);
+ };
}
/**
@@ -275,13 +297,29 @@ public class Listifiers {
* <li><b>Entry conversion:</b> Each key-value pair becomes a
Map.Entry in the list</li>
* <li><b>Order preservation:</b> Maintains the map's iteration
order</li>
* <li><b>Empty maps:</b> Returns empty list for empty maps</li>
+ * <li><b>Map ordering:</b> Converts unordered Maps (HashMap, etc.)
to TreeMap for deterministic ordering</li>
+ * </ul>
+ *
+ * <h5 class='section'>Map Ordering Behavior:</h5>
+ * <p>To ensure predictable test results, this listifier handles Maps
with unreliable ordering:</p>
+ * <ul>
+ * <li><b>{@link SortedMap} (TreeMap, etc.):</b> Preserves existing
sort order</li>
+ * <li><b>{@link LinkedHashMap}:</b> Preserves insertion order</li>
+ * <li><b>{@link HashMap} and other unordered Maps:</b> Converts to
{@link TreeMap} for natural key ordering</li>
* </ul>
*
* <h5 class='section'>Usage Examples:</h5>
* <p class='bjava'>
- * <jc>// Test map contents</jc>
- * <jk>var</jk> <jv>map</jv> = Map.<jsm>of</jsm>(<js>"key1"</js>,
<js>"value1"</js>, <js>"key2"</js>, <js>"value2"</js>);
+ * <jc>// Test map contents with deterministic ordering</jc>
+ * <jk>var</jk> <jv>map</jv> = Map.<jsm>of</jsm>(<js>"z"</js>,
<js>"value1"</js>, <js>"a"</js>, <js>"value2"</js>);
* <jsm>assertSize</jsm>(<jv>map</jv>, <jv>2</jv>);
+ * <jc>// Entries will be ordered by key: [a=value2, z=value1]</jc>
+ *
+ * <jc>// LinkedHashMap preserves insertion order</jc>
+ * <jk>var</jk> <jv>linkedMap</jv> = <jk>new</jk>
LinkedHashMap<>();
+ * <jv>linkedMap</jv>.put(<js>"first"</js>, <js>"1"</js>);
+ * <jv>linkedMap</jv>.put(<js>"second"</js>, <js>"2"</js>);
+ * <jc>// Entries will maintain insertion order: [first=1,
second=2]</jc>
*
* <jc>// Test empty map</jc>
* <jk>var</jk> <jv>emptyMap</jv> = Map.<jsm>of</jsm>();
@@ -296,11 +334,23 @@ public class Listifiers {
* <p>The resulting Map.Entry objects can be further processed by other
parts of the
* conversion system, typically being stringified to
<js>"key=value"</js> format.</p>
*
+ * <h5 class='section'>Performance:</h5>
+ * <p>This listifier creates a new ArrayList from the map's entrySet.
For unordered Maps,
+ * an additional TreeMap conversion adds O(n log n) sorting overhead
based on key ordering.
+ * For large maps, consider the memory implications.</p>
+ *
* @return A {@link Listifier} for {@link Map} objects
* @see Map
* @see Map.Entry
+ * @see TreeMap
+ * @see LinkedHashMap
*/
public static Listifier<Map> mapListifier() {
- return (bc, map) -> new ArrayList<>(map.entrySet());
+ return (bc, map) -> {
+ if (!(map instanceof SortedMap) && !(map instanceof
LinkedHashMap)) {
+ map = new TreeMap<>(map);
+ }
+ return new ArrayList<>(map.entrySet());
+ };
}
}
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/junit/bct/Listifiers_Test.java
b/juneau-utest/src/test/java/org/apache/juneau/junit/bct/Listifiers_Test.java
index c0e5eaccb..56a12fb2b 100644
---
a/juneau-utest/src/test/java/org/apache/juneau/junit/bct/Listifiers_Test.java
+++
b/juneau-utest/src/test/java/org/apache/juneau/junit/bct/Listifiers_Test.java
@@ -41,13 +41,31 @@ class Listifiers_Test extends TestBase {
@Test
void a02_listifySet() {
var listifier = Listifiers.collectionListifier();
- var input = Set.of("x", "y", "z");
+ var input = Set.of("z", "a", "m"); // Unordered input
var result = listifier.apply(null, input);
- assertEquals(3, result.size());
- assertTrue(result.contains("x"));
- assertTrue(result.contains("y"));
- assertTrue(result.contains("z"));
+ // TreeSet conversion ensures natural ordering
+ assertList(result, "a", "m", "z");
+ }
+
+ @Test
+ void a02a_listifySetTypes() {
+ var listifier = Listifiers.collectionListifier();
+
+ // HashSet (unordered) -> converted to TreeSet for
natural ordering
+ var hashSet = new HashSet<>(Arrays.asList("z", "a",
"m"));
+ var hashResult = listifier.apply(null, hashSet);
+ assertList(hashResult, "a", "m", "z");
+
+ // LinkedHashSet preserves insertion order
+ var linkedSet = new LinkedHashSet<>(Arrays.asList("z",
"a", "m"));
+ var linkedResult = listifier.apply(null, linkedSet);
+ assertList(linkedResult, "z", "a", "m"); // Insertion
order
+
+ // TreeSet already sorted, preserves its order
+ var treeSet = new TreeSet<>(Arrays.asList("z", "a",
"m"));
+ var treeResult = listifier.apply(null, treeSet);
+ assertList(treeResult, "a", "m", "z"); // Natural order
}
@Test
@@ -278,12 +296,63 @@ class Listifiers_Test extends TestBase {
@Test
void f01_listifyMap() {
var listifier = Listifiers.mapListifier();
- var input = Map.of("key1", "value1", "key2", "value2");
+ var input = Map.of("z", "value1", "a", "value2"); //
Unordered input
var result = listifier.apply(null, input);
assertEquals(2, result.size());
// Result should contain Map.Entry objects
assertTrue(result.stream().allMatch(obj -> obj
instanceof Map.Entry));
+
+ // TreeMap conversion ensures natural key ordering
+ var entries = result.stream()
+ .map(obj -> (Map.Entry<?, ?>) obj)
+ .toList();
+ assertEquals("a", entries.get(0).getKey());
+ assertEquals("z", entries.get(1).getKey());
+ }
+
+ @Test
+ void f01a_listifyMapTypes() {
+ var listifier = Listifiers.mapListifier();
+
+ // HashMap (unordered) -> converted to TreeMap for
natural key ordering
+ var hashMap = new HashMap<String, String>();
+ hashMap.put("z", "value1");
+ hashMap.put("a", "value2");
+ hashMap.put("m", "value3");
+ var hashResult = listifier.apply(null, hashMap);
+ var hashEntries = hashResult.stream()
+ .map(obj -> (Map.Entry<?, ?>) obj)
+ .toList();
+ assertEquals("a", hashEntries.get(0).getKey());
+ assertEquals("m", hashEntries.get(1).getKey());
+ assertEquals("z", hashEntries.get(2).getKey());
+
+ // LinkedHashMap preserves insertion order
+ var linkedMap = new LinkedHashMap<String, String>();
+ linkedMap.put("z", "value1");
+ linkedMap.put("a", "value2");
+ linkedMap.put("m", "value3");
+ var linkedResult = listifier.apply(null, linkedMap);
+ var linkedEntries = linkedResult.stream()
+ .map(obj -> (Map.Entry<?, ?>) obj)
+ .toList();
+ assertEquals("z", linkedEntries.get(0).getKey()); //
Insertion order
+ assertEquals("a", linkedEntries.get(1).getKey());
+ assertEquals("m", linkedEntries.get(2).getKey());
+
+ // TreeMap already sorted, preserves its order
+ var treeMap = new TreeMap<String, String>();
+ treeMap.put("z", "value1");
+ treeMap.put("a", "value2");
+ treeMap.put("m", "value3");
+ var treeResult = listifier.apply(null, treeMap);
+ var treeEntries = treeResult.stream()
+ .map(obj -> (Map.Entry<?, ?>) obj)
+ .toList();
+ assertEquals("a", treeEntries.get(0).getKey()); //
Natural order
+ assertEquals("m", treeEntries.get(1).getKey());
+ assertEquals("z", treeEntries.get(2).getKey());
}
@Test
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/junit/bct/NestedTokenizer.java
b/juneau-utest/src/test/java/org/apache/juneau/junit/bct/NestedTokenizer.java
index 0ca546eb5..e005885b2 100644
---
a/juneau-utest/src/test/java/org/apache/juneau/junit/bct/NestedTokenizer.java
+++
b/juneau-utest/src/test/java/org/apache/juneau/junit/bct/NestedTokenizer.java
@@ -14,8 +14,8 @@ package org.apache.juneau.junit.bct;
import static java.util.Collections.*;
import static java.util.stream.Collectors.*;
-import static org.apache.juneau.junit.bct.NestedTokenizer.ParseState.*;
import static org.apache.juneau.junit.bct.Utils.*;
+import static org.apache.juneau.junit.bct.NestedTokenizer.ParseState.*;
import java.util.*;
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/junit/bct/Stringifiers.java
b/juneau-utest/src/test/java/org/apache/juneau/junit/bct/Stringifiers.java
index 85e98580d..ade6c4083 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/junit/bct/Stringifiers.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/junit/bct/Stringifiers.java
@@ -411,7 +411,7 @@ public class Stringifiers {
* @see Class
*/
public static Stringifier<Class> classStringifier() {
- return (bc, clazz) -> stringifyClass(bc, clazz);
+ return Stringifiers::stringifyClass;
}
/**
@@ -442,8 +442,8 @@ public class Stringifiers {
* @see Constructor
*/
public static Stringifier<Constructor> constructorStringifier() {
- return (bc, constructor) -> {
- return new StringBuilder()
+ return (bc, constructor) ->
+ new StringBuilder()
.append(stringifyClass(bc, ((Constructor<?>)
constructor).getDeclaringClass()))
.append('(')
.append(
@@ -454,7 +454,6 @@ public class Stringifiers {
)
.append(')')
.toString();
- };
}
/**
@@ -485,8 +484,8 @@ public class Stringifiers {
* @see Method
*/
public static Stringifier<Method> methodStringifier() {
- return (bc, method) -> {
- return new StringBuilder()
+ return (bc, method) ->
+ new StringBuilder()
.append(method.getName())
.append('(')
.append(
@@ -496,7 +495,6 @@ public class Stringifiers {
)
.append(')')
.toString();
- };
}
/**
diff --git a/juneau-utest/src/test/java/org/apache/juneau/junit/bct/Utils.java
b/juneau-utest/src/test/java/org/apache/juneau/junit/bct/Utils.java
index 57e5c48f8..d0a4fd408 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/junit/bct/Utils.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/junit/bct/Utils.java
@@ -36,7 +36,7 @@ import org.opentest4j.*;
*
* <h5 class='section'>Usage Examples:</h5>
* <p class='bjava'>
- * <jk>import static</jk> com.sfdc.junit.bct.Utils.*;
+ * <jk>import static</jk> org.apache.juneau.junit.bct.Utils.*;
*
* <jc>// String formatting</jc>
* String <jv>msg</jv> = <jsm>f</jsm>(<js>"User {0} has {1} items"</js>,
<js>"Alice"</js>, 5);
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/junit/bct/Utils_Test.java
b/juneau-utest/src/test/java/org/apache/juneau/junit/bct/Utils_Test.java
index 5b246c856..0cc683e79 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/junit/bct/Utils_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/junit/bct/Utils_Test.java
@@ -12,8 +12,8 @@
//
***************************************************************************************************************************
package org.apache.juneau.junit.bct;
-import static org.apache.juneau.junit.bct.BctAssertions.*;
import static org.apache.juneau.junit.bct.Utils.*;
+import static org.apache.juneau.junit.bct.BctAssertions.*;
import static org.junit.jupiter.api.Assertions.*;
import java.util.*;