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 c24f4004ef374fc54c2a7286a5b0787909d756f2
Author: James Bognar <[email protected]>
AuthorDate: Mon May 11 15:44:33 2026 -0400

    test: fill in coverage gaps for inject and builder classes; fix Javadoc 
links and remove CreatableBeanStore
---
 .../juneau/commons/inject/CreatableBeanStore.java  | 272 --------------
 .../java/org/apache/juneau/annotation/Named.java   |   2 +-
 .../httppart/bean/RequestBeanPropertyMeta.java     |   2 +-
 .../httppart/bean/ResponseBeanPropertyMeta.java    |   2 +-
 .../java/org/apache/juneau/rest/RestContext.java   |   2 +-
 .../juneau/commons/inject/BasicBeanStore_Test.java | 416 +++++++++++++++++++++
 .../commons/inject/BeanInstantiator_Test.java      |  64 ++++
 .../apache/juneau/encoders/EncoderSet_Test.java    |  93 +++++
 .../httppart/bean/HttpPartBeanMeta_Test.java       | 163 ++++++++
 .../org/apache/juneau/parser/ParserSet_Test.java   | 158 ++++++++
 .../client/remote/RemoteOperationArg_Test.java     |  75 ++++
 .../juneau/serializer/SerializerSet_Test.java      | 183 +++++++++
 12 files changed, 1156 insertions(+), 276 deletions(-)

diff --git 
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/inject/CreatableBeanStore.java
 
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/inject/CreatableBeanStore.java
deleted file mode 100644
index 86df9c7b5b..0000000000
--- 
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/inject/CreatableBeanStore.java
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * 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.juneau.commons.inject;
-
-import static org.apache.juneau.commons.utils.AssertionUtils.*;
-import static org.apache.juneau.commons.utils.Utils.*;
-
-import java.util.*;
-import java.util.concurrent.*;
-import java.util.function.*;
-
-/**
- * A bean store that provides convenient access to {@link BeanInstantiator} 
instances for creating beans.
- *
- * <p>
- * This class extends {@link BasicBeanStore} and adds methods to manage {@link 
BeanInstantiator} instances
- * for different bean types. Creators are lazily created and cached for 
efficient reuse.
- *
- * <h5 class='section'>Example:</h5>
- * <p class='bjava'>
- *     <jc>// Create a creatable bean store</jc>
- *     CreatableBeanStore <jv>store</jv> = <jk>new</jk> 
CreatableBeanStore(<jk>null</jk>);
- *
- *     <jc>// Get or create a creator for MyBean</jc>
- *     BeanInstantiator&lt;MyBean&gt; <jv>creator</jv> = 
<jv>store</jv>.getCreator(MyBean.<jk>class</jk>);
- *
- *     <jc>// Use the creator to create a bean</jc>
- *     MyBean <jv>bean</jv> = <jv>creator</jv>.create();
- *
- *     <jc>// Explicitly add a creator (optional, getCreator will create if 
missing)</jc>
- *     <jv>store</jv>.addCreator(MyOtherBean.<jk>class</jk>);
- * </p>
- *
- * <h5 class='section'>See Also:</h5><ul>
- *     <li class='jc'>{@link BasicBeanStore}
- *     <li class='jc'>{@link BeanInstantiator}
- * </ul>
- */
-@SuppressWarnings({
-       "java:S115" // Constants use UPPER_snakeCase convention
-})
-public class CreatableBeanStore extends BasicBeanStore {
-
-       // Argument name constants for assertArgNotNull
-       private static final String ARG_beanType = "beanType";
-
-       private final ConcurrentHashMap<Class<?>, BeanInstantiator<?>> creators 
= new ConcurrentHashMap<>();
-       private final Object enclosingInstance;
-
-       /**
-        * Constructor.
-        *
-        * @param parent The parent bean store.  Can be <jk>null</jk>.  Bean 
searches are performed recursively up this parent chain.
-        * @param enclosingInstance The enclosing instance object to use when 
instantiating inner classes. Can be <jk>null</jk>.
-        */
-       public CreatableBeanStore(BeanStore parent, Object enclosingInstance) {
-               super(parent);
-               this.enclosingInstance = enclosingInstance;
-       }
-
-       /**
-        * Same as {@link #addCreator(Class)} but returns the creator instead 
of this object for fluent calls.
-        *
-        * @param <T> The bean type.
-        * @param beanType The bean type to create a creator for. Cannot be 
<jk>null</jk>.
-        * @return The creator that was created and stored.
-        */
-       public <T> BeanInstantiator<T> add(Class<T> beanType) {
-               assertArgNotNull(ARG_beanType, beanType);
-               var creator = BeanInstantiator.of(beanType, this, null, 
enclosingInstance).build();
-               creators.put(beanType, creator);
-               return creator;
-       }
-
-       /**
-        * Same as {@link #addCreator(Class, String)} but returns the creator 
instead of this object for fluent calls.
-        *
-        * @param <T> The bean type.
-        * @param beanType The bean type to create a creator for. Cannot be 
<jk>null</jk>.
-        * @param name The bean name. Can be <jk>null</jk>.
-        * @return The creator that was created and stored.
-        */
-       public <T> BeanInstantiator<T> add(Class<T> beanType, String name) {
-               assertArgNotNull(ARG_beanType, beanType);
-               var creator = BeanInstantiator.of(beanType, this, name, 
enclosingInstance).build();
-               creators.put(beanType, creator);
-               return creator;
-       }
-
-       /**
-        * Creates and stores a {@link BeanInstantiator} for the specified bean 
type.
-        *
-        * <p>
-        * If a creator for this type already exists, it is replaced with a new 
one.
-        *
-        * <h5 class='section'>Example:</h5>
-        * <p class='bjava'>
-        *      <jc>// Create and store a creator</jc>
-        *      <jv>store</jv>.addCreator(MyBean.<jk>class</jk>);
-        *
-        *      <jc>// Get the creator</jc>
-        *      BeanInstantiator&lt;MyBean&gt; <jv>creator</jv> = 
<jv>store</jv>.getCreator(MyBean.<jk>class</jk>);
-        * </p>
-        *
-        * @param <T> The bean type.
-        * @param beanType The bean type to create a creator for. Cannot be 
<jk>null</jk>.
-        * @return This object.
-        */
-       public <T> CreatableBeanStore addCreator(Class<T> beanType) {
-               assertArgNotNull(ARG_beanType, beanType);
-               var creator = BeanInstantiator.of(beanType, this, null, 
enclosingInstance).build();
-               creators.put(beanType, creator);
-               return this;
-       }
-
-       /**
-        * Creates and stores a {@link BeanInstantiator} for the specified bean 
type with a name.
-        *
-        * <p>
-        * If a creator for this type already exists, it is replaced with a new 
one.
-        *
-        * <h5 class='section'>Example:</h5>
-        * <p class='bjava'>
-        *      <jc>// Create and store a creator with a name</jc>
-        *      <jv>store</jv>.addCreator(MyBean.<jk>class</jk>, 
<js>"myBean"</js>);
-        *
-        *      <jc>// Get the creator</jc>
-        *      BeanInstantiator&lt;MyBean&gt; <jv>creator</jv> = 
<jv>store</jv>.getCreator(MyBean.<jk>class</jk>, <js>"myBean"</js>);
-        * </p>
-        *
-        * @param <T> The bean type.
-        * @param beanType The bean type to create a creator for. Cannot be 
<jk>null</jk>.
-        * @param name The bean name. Can be <jk>null</jk>.
-        * @return This object.
-        */
-       public <T> CreatableBeanStore addCreator(Class<T> beanType, String 
name) {
-               assertArgNotNull(ARG_beanType, beanType);
-               var creator = BeanInstantiator.of(beanType, this, name, 
enclosingInstance).build();
-               creators.put(beanType, creator);
-               return this;
-       }
-
-       /**
-        * Returns the {@link BeanInstantiator} for the specified bean type, 
creating it if it doesn't exist.
-        *
-        * <p>
-        * If a creator for this type doesn't exist, a new one is created with 
this bean store configured
-        * and stored for future use.
-        *
-        * <h5 class='section'>Example:</h5>
-        * <p class='bjava'>
-        *      <jc>// Get or create a creator</jc>
-        *      BeanInstantiator&lt;MyBean&gt; <jv>creator</jv> = 
<jv>store</jv>.getCreator(MyBean.<jk>class</jk>);
-        *
-        *      <jc>// Use the creator to create a bean</jc>
-        *      MyBean <jv>bean</jv> = <jv>creator</jv>.create();
-        * </p>
-        *
-        * @param <T> The bean type.
-        * @param beanType The bean type to get a creator for. Cannot be 
<jk>null</jk>.
-        * @return The creator for the specified bean type. Never <jk>null</jk>.
-        */
-       @SuppressWarnings({
-               "unchecked" // Type erasure requires cast to BeanInstantiator<T>
-       })
-       public <T> BeanInstantiator<T> getCreator(Class<T> beanType) {
-               assertArgNotNull(ARG_beanType, beanType);
-               return (BeanInstantiator<T>)creators.computeIfAbsent(beanType, 
k -> BeanInstantiator.of((Class<T>)k, this, null, enclosingInstance).build());
-       }
-
-       /**
-        * Returns the {@link BeanInstantiator} for the specified bean type 
with a name, creating it if it doesn't exist.
-        *
-        * <p>
-        * If a creator for this type doesn't exist, a new one is created with 
this bean store configured
-        * and stored for future use.
-        *
-        * <h5 class='section'>Example:</h5>
-        * <p class='bjava'>
-        *      <jc>// Get or create a creator with a name</jc>
-        *      BeanInstantiator&lt;MyBean&gt; <jv>creator</jv> = 
<jv>store</jv>.getCreator(MyBean.<jk>class</jk>, <js>"myBean"</js>);
-        *
-        *      <jc>// Use the creator to create a bean</jc>
-        *      MyBean <jv>bean</jv> = <jv>creator</jv>.create();
-        * </p>
-        *
-        * @param <T> The bean type.
-        * @param beanType The bean type to get a creator for. Cannot be 
<jk>null</jk>.
-        * @param name The bean name. Can be <jk>null</jk>.
-        * @return The creator for the specified bean type. Never <jk>null</jk>.
-        */
-       @SuppressWarnings({
-               "unchecked" // Type erasure requires cast to BeanInstantiator<T>
-       })
-       public <T> BeanInstantiator<T> getCreator(Class<T> beanType, String 
name) {
-               assertArgNotNull(ARG_beanType, beanType);
-               return (BeanInstantiator<T>)creators.computeIfAbsent(beanType, 
k -> BeanInstantiator.of((Class<T>)k, this, name, enclosingInstance).build());
-       }
-
-       /**
-        * Resolves a bean supplier by checking creators for matching bean or 
builder types.
-        *
-        * <p>
-        * This method searches through all registered creators to find one 
that can create the requested bean type.
-        * It checks both the creator's bean type and any builder types 
associated with the creator.
-        *
-        * <p>
-        * If no matching creator is found, delegates to the parent store's 
resolve method.
-        *
-        * @param <T> The bean type.
-        * @param beanType The bean type to resolve.
-        * @param name The bean name.  Can be <jk>null</jk>.
-        * @return The supplier, or {@link Optional#empty()} if no matching 
creator or supplier exists.
-        */
-       @Override
-       @SuppressWarnings({
-               "unchecked" // Type erasure requires cast for supplier 
resolution
-       })
-       protected <T> Optional<Supplier<T>> resolve(Class<T> beanType, String 
name) {
-               // First check if there's a creator for the exact bean type
-               var creator = creators.get(beanType);
-               if (nn(creator)) {
-                       return opt(() -> (T)creator.run());
-               }
-
-               // Check all creators for matching bean types (for inheritance)
-               for (var entry : creators.entrySet()) {
-                       var creatorBeanType = entry.getKey();
-                       var c = entry.getValue();
-
-                       // Check if creator's bean type is assignable to the 
requested type
-                       // (i.e., creator creates a subtype that can be cast to 
requested type)
-                       if (nn(creatorBeanType) && 
beanType.isAssignableFrom(creatorBeanType)) {
-                               return opt(() -> (T)c.run());
-                       }
-
-                       // Check builder types - if requested type matches a 
builder type, return the creator
-                       var builderTypes = safeOpt(c::getBuilderTypes);
-                       if (builderTypes.isPresent()) {
-                               for (var builderType : builderTypes.get()) {
-                                       if (nn(builderType) && 
builderType.is(beanType)) {
-                                               return opt(() -> 
(T)c.getBuilder());
-                                       }
-                               }
-                       }
-               }
-
-               // If not found, delegate to parent
-               return super.resolve(beanType, name);
-       }
-
-       @Override
-       public CreatableBeanStore clear() {
-               super.clear();
-               creators.clear();
-               return this;
-       }
-}
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/Named.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/Named.java
index 92438e7d2b..def1f6d446 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/Named.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/Named.java
@@ -61,7 +61,7 @@ import java.lang.annotation.*;
  *
  * <h5 class='section'>See Also:</h5><ul>
  *     <li class='ja'>{@link Name}
- *     <li class='jc'>{@link BeanStore}
+ *     <li class='jc'>{@link org.apache.juneau.commons.inject.BeanStore}
  * </ul>
  */
 @Documented
diff --git 
a/juneau-rest/juneau-rest-common/src/main/java/org/apache/juneau/httppart/bean/RequestBeanPropertyMeta.java
 
b/juneau-rest/juneau-rest-common/src/main/java/org/apache/juneau/httppart/bean/RequestBeanPropertyMeta.java
index 3c33d2f8bf..943c797789 100644
--- 
a/juneau-rest/juneau-rest-common/src/main/java/org/apache/juneau/httppart/bean/RequestBeanPropertyMeta.java
+++ 
b/juneau-rest/juneau-rest-common/src/main/java/org/apache/juneau/httppart/bean/RequestBeanPropertyMeta.java
@@ -114,7 +114,7 @@ public class RequestBeanPropertyMeta {
         *
         * @return The HTTP part name, or <jk>null</jk> if it doesn't have a 
part name.
         */
-       public String getPartName() { return schema == null ? null : 
schema.getName(); }
+       public String getPartName() { return schema.getName(); }
 
        /**
         * Returns the HTTP part type for this property (query parameter for 
example).
diff --git 
a/juneau-rest/juneau-rest-common/src/main/java/org/apache/juneau/httppart/bean/ResponseBeanPropertyMeta.java
 
b/juneau-rest/juneau-rest-common/src/main/java/org/apache/juneau/httppart/bean/ResponseBeanPropertyMeta.java
index 9dec884706..59a167db4c 100644
--- 
a/juneau-rest/juneau-rest-common/src/main/java/org/apache/juneau/httppart/bean/ResponseBeanPropertyMeta.java
+++ 
b/juneau-rest/juneau-rest-common/src/main/java/org/apache/juneau/httppart/bean/ResponseBeanPropertyMeta.java
@@ -112,7 +112,7 @@ public class ResponseBeanPropertyMeta {
         *
         * @return The HTTP part name, or <jk>null</jk> if it doesn't have a 
part name.
         */
-       public Optional<String> getPartName() { return opt(schema == null ? 
null : schema.getName()); }
+       public Optional<String> getPartName() { return opt(schema.getName()); }
 
        /**
         * Returns the HTTP part type for this property (query parameter for 
example).
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
index d6ba0deca1..25b538a18d 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
@@ -2228,7 +2228,7 @@ public class RestContext extends Context {
         *
         * <p>
         * Per-op {@link RestOpArg} instances are resolved separately at per-op 
setup via the bean store
-        * (see {@link #findRestOperationArgs(Method, WritableBeanStore)}); 
this getter returns the class list
+        * (see {@link #findRestOperationArgs(Method, BeanStore)}); this getter 
returns the class list
         * that drives that resolution.
         *
         * <h5 class='section'>See Also:</h5><ul>
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/commons/inject/BasicBeanStore_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/commons/inject/BasicBeanStore_Test.java
index a84558d888..73a5822e51 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/commons/inject/BasicBeanStore_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/commons/inject/BasicBeanStore_Test.java
@@ -23,6 +23,8 @@ import java.util.*;
 import java.util.stream.Stream;
 
 import org.apache.juneau.*;
+import org.apache.juneau.annotation.Named;
+import org.apache.juneau.commons.reflect.*;
 import org.junit.jupiter.api.*;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.Arguments;
@@ -1107,5 +1109,419 @@ class BasicBeanStore_Test extends TestBase {
                // "d" only in defaults.
                assertEquals("default-d", beans.get("d").getName());
        }
+
+       // 
=========================================================================
+       // T - hasDefaultSupplier / getDefaultSupplier (uncovered paths)
+       // 
=========================================================================
+
+       @Test
+       void t01_hasDefaultSupplier_unnamed_delegatesToNamed() {
+               var store = new BasicBeanStore(null);
+               assertFalse(store.hasDefaultSupplier(TestBean.class));
+               store.addDefaultSupplier(TestBean.class, () -> new 
TestBean("x"));
+               assertTrue(store.hasDefaultSupplier(TestBean.class));
+       }
+
+       @Test
+       void t02_hasDefaultSupplier_named_notRegistered_returnsFalse() {
+               var store = new BasicBeanStore(null);
+               assertFalse(store.hasDefaultSupplier(TestBean.class, 
"missing"));
+       }
+
+       @Test
+       void 
t06_hasDefaultSupplier_named_typeMapExistsButKeyAbsent_returnsFalse() {
+               var store = new BasicBeanStore(null);
+               // Register a default for the unnamed variant so typeMap is 
non-null
+               store.addDefaultSupplier(TestBean.class, () -> new 
TestBean("unnamed"));
+               // Now check a different (named) key that was never registered
+               assertFalse(store.hasDefaultSupplier(TestBean.class, 
"unregistered-name"));
+       }
+
+       @Test
+       void t03_getDefaultSupplier_unnamed_delegatesToNamed() {
+               var store = new BasicBeanStore(null);
+               assertTrue(store.getDefaultSupplier(TestBean.class).isEmpty());
+               store.addDefaultSupplier(TestBean.class, () -> new 
TestBean("via-default"));
+               assertEquals("via-default", 
store.getDefaultSupplier(TestBean.class).orElseThrow().get().getName());
+       }
+
+       @Test
+       void t04_getDefaultSupplier_named_typeMapNull_returnsEmpty() {
+               var store = new BasicBeanStore(null);
+               assertTrue(store.getDefaultSupplier(TestBean.class, 
"nope").isEmpty());
+       }
+
+       @Test
+       void t05_getDefaultSupplier_named_supplierNull_returnsEmpty() {
+               var store = new BasicBeanStore(null);
+               store.addDefaultSupplier(TestBean.class, () -> new 
TestBean("other"), "other");
+               assertTrue(store.getDefaultSupplier(TestBean.class, 
"missing").isEmpty());
+       }
+
+       // 
=========================================================================
+       // U - createBeanFromMethod edge cases
+       // 
=========================================================================
+
+       static class U_Resource {
+               public static TestBean makeBean(String msg) { return new 
TestBean(msg); }
+               public static TestBean throwingFactory() { throw new 
RuntimeException("factory-boom"); }
+       }
+
+       @Test
+       void u01_createBeanFromMethod_passClass_callsStaticMethod() {
+               var store = new BasicBeanStore(null);
+               store.addBean(String.class, "hello");
+               var result = store.createBeanFromMethod(TestBean.class, 
U_Resource.class, null);
+               assertTrue(result.isPresent());
+               assertEquals("hello", result.get().getName());
+       }
+
+       @Test
+       void 
u02_createBeanFromMethod_throwingFactory_wrapsBeanCreationException() {
+               var store = new BasicBeanStore(null);
+               assertThrows(BeanCreationException.class,
+                       () -> store.createBeanFromMethod(TestBean.class, 
U_Resource.class, m -> m.getNameSimple().equals("throwingFactory")));
+       }
+
+       static class U_InstanceResource {
+               public TestBean makeBean(String msg) { return new 
TestBean(msg); }
+       }
+
+       @Test
+       void u03_createBeanFromMethod_passInstance_callsInstanceMethod() {
+               var store = new BasicBeanStore(null);
+               store.addBean(String.class, "from-instance");
+               var result = store.createBeanFromMethod(TestBean.class, new 
U_InstanceResource(), null);
+               assertTrue(result.isPresent());
+               assertEquals("from-instance", result.get().getName());
+       }
+
+       static class U_NonStaticResource {
+               public TestBean makeBean() { return new TestBean("non-static"); 
}
+       }
+
+       @Test
+       void 
u04_createBeanFromMethod_passClass_nonStaticMethodSkipped_returnsEmpty() {
+               // When passing a Class (resource=null), non-static methods are 
excluded (line 578 false branch).
+               var store = new BasicBeanStore(null);
+               var result = store.createBeanFromMethod(TestBean.class, 
U_NonStaticResource.class, null);
+               assertTrue(result.isEmpty());
+       }
+
+       @Test
+       void 
u05_createBeanFromMethod_methodHasUnresolvableParams_returnsEmpty() {
+               // makeBean needs a String but none is in store → 
canResolveAllParameters false branch
+               var store = new BasicBeanStore(null);
+               var result = store.createBeanFromMethod(TestBean.class, 
U_Resource.class, m -> m.getNameSimple().equals("makeBean"));
+               assertTrue(result.isEmpty());
+       }
+
+       // 
=========================================================================
+       // V - toString / properties (defaults list, non-BasicBeanStore 
overriding parent)
+       // 
=========================================================================
+
+       @Test
+       void v01_toString_withDefaults_includesDefaultsSection() {
+               var store = new BasicBeanStore(null);
+               store.addDefaultSupplier(TestBean.class, () -> new 
TestBean("default"));
+               var s = store.toString();
+               assertNotNull(s);
+               assertTrue(s.contains("defaults"));
+       }
+
+       @Test
+       void v02a_toString_basicBeanStoreOverridingParent_usesProperties() {
+               var overriding = new BasicBeanStore(null);
+               overriding.addBean(TestBean.class, new 
TestBean("override-val"));
+               var store = new BasicBeanStore(null, overriding);
+               var s = store.toString();
+               assertNotNull(s);
+       }
+
+       @Test
+       void v02_toString_nonBasicOverridingParent_usesStringForm() {
+               var overriding = new BeanStore() {
+                       @Override public <T> 
Optional<java.util.function.Supplier<T>> getBeanSupplier(Class<T> t) { return 
Optional.empty(); }
+                       @Override public <T> 
Optional<java.util.function.Supplier<T>> getBeanSupplier(Class<T> t, String n) 
{ return Optional.empty(); }
+                       @Override public boolean hasBean(Class<?> t) { return 
false; }
+                       @Override public boolean hasBean(Class<?> t, String n) 
{ return false; }
+                       @Override public <T> Optional<T> getBean(Class<T> t) { 
return Optional.empty(); }
+                       @Override public <T> Optional<T> getBean(Class<T> t, 
String n) { return Optional.empty(); }
+                       @Override public <T> java.util.Map<String, T> 
getBeansOfType(Class<T> t) { return java.util.Map.of(); }
+               };
+               var store = new BasicBeanStore(null, overriding);
+               var s = store.toString();
+               assertNotNull(s);
+       }
+
+       // 
=========================================================================
+       // W - WritableBeanStore.add() convenience defaults
+       //     BasicBeanStore overrides add(), so we need a minimal wrapper that
+       //     delegates only addBean() in order to exercise the interface 
defaults.
+       // 
=========================================================================
+
+       /** Minimal WritableBeanStore that does NOT override add(), relying on 
interface defaults. */
+       static class MinimalWritable implements WritableBeanStore {
+               private final BasicBeanStore delegate = new 
BasicBeanStore(null);
+
+               @Override public <T> WritableBeanStore addBean(Class<T> t, T b) 
{ return delegate.addBean(t, b); }
+               @Override public <T> WritableBeanStore addBean(Class<T> t, T b, 
String n) { return delegate.addBean(t, b, n); }
+               @Override public <T> WritableBeanStore addSupplier(Class<T> t, 
java.util.function.Supplier<T> s) { return delegate.addSupplier(t, s); }
+               @Override public <T> WritableBeanStore addSupplier(Class<T> t, 
java.util.function.Supplier<T> s, String n) { return delegate.addSupplier(t, s, 
n); }
+               @Override public <T> WritableBeanStore 
addDefaultSupplier(Class<T> t, java.util.function.Supplier<T> s) { return 
delegate.addDefaultSupplier(t, s); }
+               @Override public <T> WritableBeanStore 
addDefaultSupplier(Class<T> t, java.util.function.Supplier<T> s, String n) { 
return delegate.addDefaultSupplier(t, s, n); }
+               @Override public WritableBeanStore clear() { return 
delegate.clear(); }
+               @Override public boolean hasDefaultSupplier(Class<?> t) { 
return delegate.hasDefaultSupplier(t); }
+               @Override public boolean hasDefaultSupplier(Class<?> t, String 
n) { return delegate.hasDefaultSupplier(t, n); }
+               @Override public <T> WritableBeanStore addBeanType(Class<T> t, 
Class<? extends T> i) { return delegate.addBeanType(t, i); }
+               @Override public <T> Optional<java.util.function.Supplier<T>> 
getBeanSupplier(Class<T> t) { return delegate.getBeanSupplier(t); }
+               @Override public <T> Optional<java.util.function.Supplier<T>> 
getBeanSupplier(Class<T> t, String n) { return delegate.getBeanSupplier(t, n); }
+               @Override public boolean hasBean(Class<?> t) { return 
delegate.hasBean(t); }
+               @Override public boolean hasBean(Class<?> t, String n) { return 
delegate.hasBean(t, n); }
+               @Override public <T> Optional<T> getBean(Class<T> t) { return 
delegate.getBean(t); }
+               @Override public <T> Optional<T> getBean(Class<T> t, String n) 
{ return delegate.getBean(t, n); }
+               @Override public <T> java.util.Map<String, T> 
getBeansOfType(Class<T> t) { return delegate.getBeansOfType(t); }
+       }
+
+       @Test
+       void w01_writableBeanStore_add_unnamed_returnsBean() {
+               var store = new MinimalWritable();
+               var bean = new TestBean("fluent");
+               var returned = store.add(TestBean.class, bean);
+               assertSame(bean, returned);
+               assertSame(bean, store.getBean(TestBean.class).orElseThrow());
+       }
+
+       @Test
+       void w02_writableBeanStore_add_named_returnsBean() {
+               var store = new MinimalWritable();
+               var bean = new TestBean("fluent-named");
+               var returned = store.add(TestBean.class, bean, "myBean");
+               assertSame(bean, returned);
+               assertSame(bean, store.getBean(TestBean.class, 
"myBean").orElseThrow());
+       }
+
+       // 
=========================================================================
+       // X - BeanStore default methods: outer-instance, Optional, 
named-qualifier
+       // 
=========================================================================
+
+       interface X_Iface {
+               TestBean create(Object outer, String msg);
+               TestBean createNamed(@Named("msg") String msg);
+               TestBean createOptional(Optional<String> optMsg);
+               TestBean createMissingNamed(@Named("absent") String msg);
+               TestBean createWithOptionalFirst(Optional<String> optFirst, 
@Named("extra") String extra);
+       }
+
+       @Test
+       void x01_hasAllParams_outerInstanceSkippedAtPosition0() throws 
Exception {
+               var store = new BasicBeanStore(null);
+               store.addBean(String.class, "hello");
+               var outer = new Object();
+               var m = MethodInfo.of(X_Iface.class.getMethod("create", 
Object.class, String.class));
+               assertTrue(store.hasAllParams(m, outer));
+       }
+
+       @Test
+       void x02_hasAllParams_optionalParamAlwaysSatisfied() throws Exception {
+               var store = new BasicBeanStore(null);
+               var m = MethodInfo.of(X_Iface.class.getMethod("createOptional", 
Optional.class));
+               assertTrue(store.hasAllParams(m, null));
+       }
+
+       @Test
+       void x03_hasAllParams_namedQualifier_present() throws Exception {
+               var store = new BasicBeanStore(null);
+               store.addBean(String.class, "hi", "msg");
+               var m = MethodInfo.of(X_Iface.class.getMethod("createNamed", 
String.class));
+               assertTrue(store.hasAllParams(m, null));
+       }
+
+       @Test
+       void x04_hasAllParams_namedQualifier_absent_returnsFalse() throws 
Exception {
+               var store = new BasicBeanStore(null);
+               var m = 
MethodInfo.of(X_Iface.class.getMethod("createMissingNamed", String.class));
+               assertFalse(store.hasAllParams(m, null));
+       }
+
+       @Test
+       void x05_getParams_outerInstanceInjectedAtPosition0() throws Exception {
+               var store = new BasicBeanStore(null);
+               store.addBean(String.class, "world");
+               var outer = new Object();
+               var m = MethodInfo.of(X_Iface.class.getMethod("create", 
Object.class, String.class));
+               var params = store.getParams(m, outer);
+               assertSame(outer, params[0]);
+               assertEquals("world", params[1]);
+       }
+
+       @Test
+       void x06_getParams_namedQualifier_resolved() throws Exception {
+               var store = new BasicBeanStore(null);
+               store.addBean(String.class, "named-val", "msg");
+               var m = MethodInfo.of(X_Iface.class.getMethod("createNamed", 
String.class));
+               var params = store.getParams(m, null);
+               assertEquals("named-val", params[0]);
+       }
+
+       @Test
+       void x07_getParams_optionalParam_wrappedInOptional() throws Exception {
+               var store = new BasicBeanStore(null);
+               store.addBean(String.class, "opt-val");
+               var m = MethodInfo.of(X_Iface.class.getMethod("createOptional", 
Optional.class));
+               var params = store.getParams(m, null);
+               assertTrue(params[0] instanceof Optional);
+               assertEquals("opt-val", ((Optional<?>) params[0]).orElse(null));
+       }
+
+       @Test
+       void x08_getMissingParams_outerAndOptionalSkipped() throws Exception {
+               var store = new BasicBeanStore(null);
+               store.addBean(String.class, "present");
+               var outer = new Object();
+               var m = MethodInfo.of(X_Iface.class.getMethod("create", 
Object.class, String.class));
+               assertNull(store.getMissingParams(m, outer));
+       }
+
+       @Test
+       void x09_getMissingParams_namedQualifier_absent_listed() throws 
Exception {
+               var store = new BasicBeanStore(null);
+               var m = 
MethodInfo.of(X_Iface.class.getMethod("createMissingNamed", String.class));
+               var missing = store.getMissingParams(m, null);
+               assertNotNull(missing);
+               assertTrue(missing.contains("absent"));
+       }
+
+       static class SimpleNoArgBean {
+               public SimpleNoArgBean() {}
+       }
+
+       @Test
+       void x10_beanStore_instantiate_createsBean() {
+               var store = new BasicBeanStore(null);
+               var bean = store.instantiate(SimpleNoArgBean.class);
+               assertNotNull(bean);
+       }
+
+       @Test
+       void 
x11_beanStore_createBeanFromMethod_twoArgOverload_delegatesToFullOverload() {
+               var store = new BasicBeanStore(null);
+               store.addBean(String.class, "world");
+               var result = store.createBeanFromMethod(TestBean.class, 
U_Resource.class);
+               assertTrue(result.isPresent());
+               assertEquals("world", result.get().getName());
+       }
+
+       @Test
+       void x12_getMissingParams_namedQualifier_present_notListedAsMissing() 
throws Exception {
+               var store = new BasicBeanStore(null);
+               store.addBean(String.class, "hi", "msg");
+               var m = MethodInfo.of(X_Iface.class.getMethod("createNamed", 
String.class));
+               assertNull(store.getMissingParams(m, null));
+       }
+
+       /** Minimal BeanStore that uses all BeanStore defaults (not 
overridden). */
+       static class MinimalBeanStore implements BeanStore {
+               private final BasicBeanStore delegate = new 
BasicBeanStore(null);
+               @Override public <T> Optional<java.util.function.Supplier<T>> 
getBeanSupplier(Class<T> t) { return delegate.getBeanSupplier(t); }
+               @Override public <T> Optional<java.util.function.Supplier<T>> 
getBeanSupplier(Class<T> t, String n) { return delegate.getBeanSupplier(t, n); }
+               @Override public boolean hasBean(Class<?> t) { return 
delegate.hasBean(t); }
+               @Override public boolean hasBean(Class<?> t, String n) { return 
delegate.hasBean(t, n); }
+               @Override public <T> Optional<T> getBean(Class<T> t) { return 
delegate.getBean(t); }
+               @Override public <T> Optional<T> getBean(Class<T> t, String n) 
{ return delegate.getBean(t, n); }
+               @Override public <T> java.util.Map<String, T> 
getBeansOfType(Class<T> t) { return delegate.getBeansOfType(t); }
+       }
+
+       @Test
+       void x13_beanStore_defaultCreateBeanFromMethod_returnsEmpty() {
+               var store = new MinimalBeanStore();
+               var result = store.createBeanFromMethod(TestBean.class, 
U_Resource.class, null);
+               assertTrue(result.isEmpty());
+       }
+
+       @Test
+       void x14_beanStore_defaultCreateBeanFromMethod_twoArg_returnsEmpty() {
+               var store = new MinimalBeanStore();
+               var result = store.createBeanFromMethod(TestBean.class, 
U_Resource.class);
+               assertTrue(result.isEmpty());
+       }
+
+       @Test
+       void x15_beanStore_defaultGetBeanType_returnsEmpty() {
+               var store = new MinimalBeanStore();
+               assertTrue(store.getBeanType(TestBean.class).isEmpty());
+       }
+
+       interface X_BasicIface {
+               TestBean create(String msg);
+               TestBean createMissingUnnamed(Integer missingInt);
+       }
+
+       @Test
+       void x16_hasAllParams_unnamedParam_absent_returnsFalse() throws 
Exception {
+               var store = new BasicBeanStore(null);
+               // no Integer bean in store
+               var m = 
MethodInfo.of(X_BasicIface.class.getMethod("createMissingUnnamed", 
Integer.class));
+               assertFalse(store.hasAllParams(m, null));
+       }
+
+       @Test
+       void x17_getMissingParams_unnamedBean_absent_listed() throws Exception {
+               var store = new BasicBeanStore(null);
+               // Integer is not in the store
+               var m = 
MethodInfo.of(X_BasicIface.class.getMethod("createMissingUnnamed", 
Integer.class));
+               var missing = store.getMissingParams(m, null);
+               assertNotNull(missing);
+               assertTrue(missing.contains("Integer"));
+       }
+
+       @Test
+       void x18_getMissingParams_optionalParamAtNonZero_skipped() throws 
Exception {
+               // createWithOptionalFirst: i=0 → Optional (D path of 
condition), i=1 → named "extra"
+               var store = new BasicBeanStore(null);
+               store.addBean(String.class, "val", "extra");
+               var m = 
MethodInfo.of(X_Iface.class.getMethod("createWithOptionalFirst", 
Optional.class, String.class));
+               // Optional at i=0 is always satisfied (skipped); named "extra" 
is in store → null
+               assertNull(store.getMissingParams(m, null));
+       }
+
+       @Test
+       void 
x19_getMissingParams_outerNonNull_typeNoMatch_paramCheckedNormally() throws 
Exception {
+               // i=0, nn(outer)=true, !pt.isInstance(outer) → falls through 
to check bean
+               var store = new BasicBeanStore(null);
+               store.addBean(Integer.class, 42);
+               var outer = "type-mismatch";   // outer is String, param[0] is 
Integer → no skip
+               var m = 
MethodInfo.of(X_BasicIface.class.getMethod("createMissingUnnamed", 
Integer.class));
+               // Integer IS in store → no missing params
+               assertNull(store.getMissingParams(m, outer));
+       }
+
+       // 
=========================================================================
+       // Y - BeanCreationException constructors
+       // 
=========================================================================
+
+       @Test
+       void y01_beanCreationException_messageOnly() {
+               var ex = new BeanCreationException("msg");
+               assertEquals("msg", ex.getMessage());
+               assertNull(ex.getCause());
+       }
+
+       @Test
+       void y02_beanCreationException_causeOnly() {
+               var cause = new RuntimeException("cause");
+               var ex = new BeanCreationException(cause);
+               assertSame(cause, ex.getCause());
+       }
+
+       @Test
+       void y03_beanCreationException_messageAndCause_coveredByU02() {
+               // BeanCreationException(String, Throwable) is exercised by u02 
above;
+               // verify direct construction too for completeness.
+               var cause = new IllegalStateException("boom");
+               var ex = new BeanCreationException("wrapper", cause);
+               assertEquals("wrapper", ex.getMessage());
+               assertSame(cause, ex.getCause());
+       }
 }
 
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/commons/inject/BeanInstantiator_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/commons/inject/BeanInstantiator_Test.java
index 2bdcc6e104..6d6951df54 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/commons/inject/BeanInstantiator_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/commons/inject/BeanInstantiator_Test.java
@@ -4118,5 +4118,69 @@ class BeanInstantiator_Test extends TestBase {
                }
        }
 
+       
//====================================================================================================
+       // U - Convenience statics: createOrNull, optionalOf, createOrDefault
+       
//====================================================================================================
+       @Nested
+       @DisplayName("U - Convenience statics")
+       class U_convenienceStatics {
+
+               public static class U_Bean {
+                       final String value;
+                       public U_Bean() { this.value = "created"; }
+               }
+
+               // --- createOrNull ---
+
+               @Test
+               @DisplayName("U01 - createOrNull(null) returns null")
+               void u01_createOrNull_null() {
+                       assertNull(BeanInstantiator.createOrNull(null));
+               }
+
+               @Test
+               @DisplayName("U02 - createOrNull(Class) instantiates the bean")
+               void u02_createOrNull_nonNull() {
+                       var bean = BeanInstantiator.createOrNull(U_Bean.class);
+                       assertNotNull(bean);
+                       assertEquals("created", bean.value);
+               }
+
+               // --- optionalOf ---
+
+               @Test
+               @DisplayName("U03 - optionalOf(null) returns Optional.empty()")
+               void u03_optionalOf_null() {
+                       assertTrue(BeanInstantiator.optionalOf(null).isEmpty());
+               }
+
+               @Test
+               @DisplayName("U04 - optionalOf(Class) returns Optional 
containing the bean")
+               void u04_optionalOf_nonNull() {
+                       var opt = BeanInstantiator.optionalOf(U_Bean.class);
+                       assertTrue(opt.isPresent());
+                       assertEquals("created", opt.get().value);
+               }
+
+               // --- createOrDefault ---
+
+               @Test
+               @DisplayName("U05 - createOrDefault(null, default) returns the 
default")
+               void u05_createOrDefault_null() {
+                       var fallback = new U_Bean();
+                       var result = BeanInstantiator.createOrDefault(null, 
fallback);
+                       assertSame(fallback, result);
+               }
+
+               @Test
+               @DisplayName("U06 - createOrDefault(Class, default) 
instantiates the bean")
+               void u06_createOrDefault_nonNull() {
+                       var fallback = new U_Bean();
+                       var result = 
BeanInstantiator.createOrDefault(U_Bean.class, fallback);
+                       assertNotNull(result);
+                       assertNotSame(fallback, result, "Should create a new 
instance, not return the default");
+               }
+       }
+
 }
 
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/encoders/EncoderSet_Test.java 
b/juneau-utest/src/test/java/org/apache/juneau/encoders/EncoderSet_Test.java
index d7871f8437..fbbd0cc8fa 100755
--- a/juneau-utest/src/test/java/org/apache/juneau/encoders/EncoderSet_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/encoders/EncoderSet_Test.java
@@ -21,6 +21,7 @@ import static org.apache.juneau.junit.bct.BctAssertions.*;
 import static org.junit.jupiter.api.Assertions.*;
 
 import org.apache.juneau.*;
+import org.apache.juneau.commons.inject.*;
 import org.junit.jupiter.api.*;
 
 class EncoderSet_Test extends TestBase {
@@ -114,4 +115,96 @@ class EncoderSet_Test extends TestBase {
                        return a("E5");
                }
        }
+
+       
//====================================================================================================
+       // Builder edge-case coverage
+       
//====================================================================================================
+
+       @Test void b01_builder_addInstancesDirectly() {
+               var instance = new E1();
+               var s = EncoderSet.create().add(instance).build();
+               assertInstanceOf(E1.class, s.getEncoder("E1"));
+       }
+
+       @Test void b02_builder_addNoInheritClearsEntries() {
+               var sb = EncoderSet.create().add(E1.class, E2.class);
+               assertEquals(2, sb.inner().size());
+               // Adding NoInherit triggers clear() on the first pass; E1 and 
E2 are gone
+               sb.add(EncoderSet.NoInherit.class, E3.class);
+               assertTrue(sb.inner().stream().noneMatch(x -> 
x.equals(E1.class)));
+               assertTrue(sb.inner().stream().noneMatch(x -> 
x.equals(E2.class)));
+       }
+
+       @Test void b03_builder_addInvalidClassThrows() {
+               assertThrows(IllegalArgumentException.class, () ->
+                       EncoderSet.create().add(String.class));
+       }
+
+       @Test void b04_builder_setWithInherit() {
+               var sb = EncoderSet.create().add(E1.class, E2.class);
+               // Inherit preserves existing entries and inserts them
+               sb.set(E3.class, EncoderSet.Inherit.class);
+               var s = sb.build();
+               var codings = s.getSupportedEncodings();
+               assertTrue(codings.contains("E3"));
+               assertTrue(codings.contains("E1"));
+               assertTrue(codings.contains("E2"));
+       }
+
+       @Test void b05_builder_setWithInvalidClassThrows() {
+               assertThrows(IllegalArgumentException.class, () ->
+                       EncoderSet.create().set(String.class));
+       }
+
+       @Test void b06_builder_implBypassesBuild() {
+               var preset = EncoderSet.create().add(E1.class).build();
+               var s = EncoderSet.create().impl(preset).build();
+               assertSame(preset, s);
+       }
+
+       @Test void b07_builder_inner_returnsEntries() {
+               var sb = EncoderSet.create().add(E1.class);
+               var inner = sb.inner();
+               assertFalse(inner.isEmpty());
+       }
+
+       @Test void b08_builder_isEmpty() {
+               var sb = EncoderSet.create();
+               assertTrue(sb.isEmpty());
+               sb.add(E1.class);
+               assertFalse(sb.isEmpty());
+       }
+
+       @Test void b09_builder_toStringWithClass() {
+               var sb = EncoderSet.create().add(E1.class);
+               var s = sb.toString();
+               assertTrue(s.contains("class:"));
+       }
+
+       @Test void b10_builder_toStringWithInstance() {
+               var sb = EncoderSet.create().add(new E1());
+               var s = sb.toString();
+               assertTrue(s.contains("object:"));
+       }
+
+       @Test void b11_builder_toStringWithNull() {
+               var sb = EncoderSet.create();
+               sb.inner().add(null);
+               var s = sb.toString();
+               assertTrue(s.contains("null"));
+       }
+
+       @Test void b12_builder_create_withBeanStore() {
+               var bs = new BasicBeanStore(null);
+               var sb = EncoderSet.create(bs);
+               assertSame(bs, sb.beanStore());
+       }
+
+       @Test void b13_builder_copy_isIndependent() {
+               var sb1 = EncoderSet.create().add(E1.class);
+               var sb2 = sb1.copy();
+               sb2.add(E2.class);
+               // sb1 should not have E2
+               assertFalse(sb1.inner().stream().anyMatch(x -> 
x.equals(E2.class)));
+       }
 }
\ No newline at end of file
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/httppart/bean/HttpPartBeanMeta_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/httppart/bean/HttpPartBeanMeta_Test.java
new file mode 100644
index 0000000000..031c71243c
--- /dev/null
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/httppart/bean/HttpPartBeanMeta_Test.java
@@ -0,0 +1,163 @@
+/*
+ * 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.juneau.httppart.bean;
+
+import static org.apache.juneau.commons.httppart.HttpPartType.*;
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.commons.httppart.*;
+import org.apache.juneau.commons.reflect.*;
+import org.apache.juneau.http.annotation.*;
+import org.apache.juneau.httppart.*;
+import org.apache.juneau.uon.*;
+import org.junit.jupiter.api.*;
+
+/**
+ * Tests for uncovered getter paths in RequestBeanPropertyMeta and 
ResponseBeanPropertyMeta.
+ */
+class HttpPartBeanMeta_Test {
+
+       // --------------------------------------------------
+       // RequestBeanPropertyMeta
+       // --------------------------------------------------
+
+       static class ReqInterface {
+               @Query("q") public String getQuery() { return "q-value"; }
+               @Header("h") public String getHeader() { return "h-value"; }
+       }
+
+       private RequestBeanPropertyMeta buildReqMeta(String methodName, 
HttpPartSerializer serializer, HttpPartParser parser) throws Exception {
+               var m = MethodInfo.of(ReqInterface.class.getMethod(methodName));
+               var b = RequestBeanPropertyMeta.create(QUERY, Query.class, m);
+               return b.build(serializer, parser);
+       }
+
+       @Test
+       void req01_getGetter_returnsMethod() throws Exception {
+               var meta = buildReqMeta("getQuery", null, null);
+               assertEquals("getQuery", meta.getGetter().getName());
+       }
+
+       @Test
+       void req02_getPartType_returnsQueryType() throws Exception {
+               var meta = buildReqMeta("getQuery", null, null);
+               assertEquals(QUERY, meta.getPartType());
+       }
+
+       @Test
+       void req03_getSchema_returnsNonNull() throws Exception {
+               var meta = buildReqMeta("getQuery", null, null);
+               assertNotNull(meta.getSchema());
+               assertEquals("q", meta.getPartName());
+       }
+
+       @Test
+       void req04_getParser_parserNull_returnsDefault() throws Exception {
+               var meta = buildReqMeta("getQuery", null, null);
+               var session = mock(HttpPartParserSession.class);
+               assertSame(session, meta.getParser(session));
+       }
+
+       @Test
+       void req04b_getParser_parserNotNull_returnsParserSession() throws 
Exception {
+               // Pass a real parser as the default; schema has no parser 
class, so meta.parser = the default parser
+               var meta = buildReqMeta("getQuery", null, UonParser.DEFAULT);
+               var result = meta.getParser(null);
+               assertNotNull(result);
+       }
+
+       @Test
+       void req05_getSerializer_noSchemaSerializer_returnsEmpty() throws 
Exception {
+               var meta = buildReqMeta("getQuery", null, null);
+               assertFalse(meta.getSerializer().isPresent());
+       }
+
+       // --------------------------------------------------
+       // ResponseBeanPropertyMeta
+       // --------------------------------------------------
+
+       static class RespInterface {
+               @Header("x-status") public int getStatus() { return 200; }
+               @Content public String getBody() { return "body"; }
+       }
+
+       private ResponseBeanPropertyMeta buildRespMeta(String methodName) 
throws Exception {
+               var m = 
MethodInfo.of(RespInterface.class.getMethod(methodName));
+               var b = ResponseBeanPropertyMeta.create(HEADER, m);
+               return b.build(Optional.empty(), Optional.empty());
+       }
+
+       @Test
+       void resp01_getGetter_returnsMethod() throws Exception {
+               var meta = buildRespMeta("getStatus");
+               assertEquals("getStatus", meta.getGetter().getName());
+       }
+
+       @Test
+       void resp02_getPartType_returnsHeaderType() throws Exception {
+               var meta = buildRespMeta("getStatus");
+               assertEquals(HEADER, meta.getPartType());
+       }
+
+       @Test
+       void resp03_getSchema_returnsNonNull() throws Exception {
+               var meta = buildRespMeta("getStatus");
+               assertNotNull(meta.getSchema());
+       }
+
+       @Test
+       void resp04_getPartName_withSchema_returnsName() throws Exception {
+               var schema = HttpPartSchema.create().name("x-status").build();
+               var m = 
MethodInfo.of(RespInterface.class.getMethod("getStatus"));
+               var b = ResponseBeanPropertyMeta.create(HEADER, schema, m);
+               var meta = b.build(Optional.empty(), Optional.empty());
+               assertTrue(meta.getPartName().isPresent());
+               assertEquals("x-status", meta.getPartName().orElseThrow());
+       }
+
+       @Test
+       void resp05_getParser_noSchemaParser_returnsEmpty() throws Exception {
+               var meta = buildRespMeta("getStatus");
+               assertFalse(meta.getParser().isPresent());
+       }
+
+       @Test
+       void resp06_getSerializer_noSchemaSerializer_returnsEmpty() throws 
Exception {
+               var meta = buildRespMeta("getStatus");
+               assertFalse(meta.getSerializer().isPresent());
+       }
+
+       @Test
+       void resp07_builderName_setsName() throws Exception {
+               // ResponseBeanPropertyMeta.Builder.name() is a package-private 
setter — cover it here.
+               var m = 
MethodInfo.of(RespInterface.class.getMethod("getStatus"));
+               var b = ResponseBeanPropertyMeta.create(HEADER, m);
+               b.name("overridden");   // exercises the name() setter (lines 
54-56)
+               var meta = b.build(Optional.empty(), Optional.empty());
+               assertNotNull(meta);
+       }
+
+       // Minimal mock to avoid requiring full HttpPartParserSession 
instantiation
+       private static HttpPartParserSession mock(Class<HttpPartParserSession> 
cls) {
+               return new HttpPartParserSession() {
+                       @Override public <T> T parse(HttpPartType partType, 
HttpPartSchema schema, String in, ClassMeta<T> type) { return null; }
+               };
+       }
+}
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/parser/ParserSet_Test.java 
b/juneau-utest/src/test/java/org/apache/juneau/parser/ParserSet_Test.java
index b8400a8a23..7e93143078 100755
--- a/juneau-utest/src/test/java/org/apache/juneau/parser/ParserSet_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/parser/ParserSet_Test.java
@@ -20,6 +20,8 @@ import static org.apache.juneau.junit.bct.BctAssertions.*;
 import static org.junit.jupiter.api.Assertions.*;
 
 import org.apache.juneau.*;
+import org.apache.juneau.commons.http.MediaType;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.json.*;
 import org.junit.jupiter.api.*;
 
@@ -73,4 +75,160 @@ class ParserSet_Test extends TestBase {
        public static class P3 extends JsonParser { public 
P3(JsonParser.Builder b) { super(b.consumes("text/3")); }}
        public static class P4 extends JsonParser { public 
P4(JsonParser.Builder b) { super(b.consumes("text/4,text/4a"));} }
        public static class P5 extends JsonParser { public 
P5(JsonParser.Builder b) { super(b.consumes("text/5"));}}
+
+       public static class SimpleParser extends JsonParser {
+               public SimpleParser() {
+                       super(JsonParser.create().consumes("text/simple"));
+               }
+       }
+
+       
//====================================================================================================
+       // Builder edge-case coverage
+       
//====================================================================================================
+
+       @Test void b01_builder_addInstancesDirectly() {
+               var instance = new P1(JsonParser.create().consumes("text/1"));
+               var s = ParserSet.create().add(instance).build();
+               assertInstanceOf(P1.class, s.getParser("text/1"));
+       }
+
+       @Test void b02_builder_clear_removesAllEntries() {
+               var sb = ParserSet.create().add(P1.class, P2.class);
+               assertEquals(2, sb.inner().size());
+               sb.clear();
+               assertTrue(sb.inner().isEmpty());
+       }
+
+       @Test void b03_builder_addInvalidClassThrows() {
+               assertThrows(RuntimeException.class, () ->
+                       ParserSet.create().add(String.class));
+       }
+
+       @Test void b04_builder_setWithInherit() {
+               var sb = ParserSet.create().add(P1.class, P2.class);
+               sb.set(ParserSet.Inherit.class, P3.class);
+               var s = sb.build();
+               assertInstanceOf(P1.class, s.getParser("text/1"));
+               assertInstanceOf(P2.class, s.getParser("text/2"));
+               assertInstanceOf(P3.class, s.getParser("text/3"));
+       }
+
+       @Test void b05_builder_setWithInvalidClassThrows() {
+               assertThrows(RuntimeException.class, () ->
+                       ParserSet.create().set(String.class));
+       }
+
+       @Test void b06_builder_implBypassesBuild() {
+               var preset = ParserSet.create().add(P1.class).build();
+               var s = ParserSet.create().impl(preset).build();
+               assertSame(preset, s);
+       }
+
+       @Test void b07_builder_inner_returnsEntries() {
+               var sb = ParserSet.create().add(P1.class);
+               assertFalse(sb.inner().isEmpty());
+       }
+
+       @Test void b08_builder_toStringWithBuilder() {
+               var sb = ParserSet.create().add(JsonParser.class);
+               assertTrue(sb.toString().contains("builder:"));
+       }
+
+       @Test void b09_builder_toStringWithInstance() {
+               var sb = ParserSet.create().add(new 
P1(JsonParser.create().consumes("text/1")));
+               assertTrue(sb.toString().contains("parser:"));
+       }
+
+       @Test void b10_builder_toStringWithNull() {
+               var sb = ParserSet.create();
+               sb.inner().add(null);
+               assertTrue(sb.toString().contains("null"));
+       }
+
+       @Test void b11_builder_create_withBeanStore() {
+               var bs = new BasicBeanStore(null);
+               var sb = ParserSet.create(bs);
+               assertSame(bs, sb.beanStore());
+       }
+
+       @Test void b12_builder_copy_isIndependent() {
+               var sb1 = ParserSet.create().add(P1.class);
+               var sb2 = sb1.copy();
+               sb2.add(P2.class);
+               assertTrue(sb2.build().getParser("text/2") instanceof P2);
+               assertNull(sb1.build().getParser("text/2"));
+       }
+
+       @Test void b13_builder_beanContext_propagatesToBuilders() {
+               var bcb = BeanContext.create();
+               var sb = ParserSet.create().add(JsonParser.class);
+               sb.beanContext(bcb);
+               assertNotNull(sb.beanStore());
+       }
+
+       @Test void b14_builder_beanContext_consumer_withNonNullBcBuilder() {
+               boolean[] called = {false};
+               var sb = ParserSet.create().add(JsonParser.class);
+               sb.beanContext(BeanContext.create());
+               sb.beanContext((BeanContext.Builder b) -> called[0] = true);
+               assertTrue(called[0]);
+       }
+
+       @Test void b15_builder_beanContext_consumer_withNullBcBuilder_isNoop() {
+               boolean[] called = {false};
+               var sb = ParserSet.create().add(JsonParser.class);
+               // bcBuilder is null by default — consumer should NOT be called
+               sb.beanContext((BeanContext.Builder b) -> called[0] = true);
+               assertFalse(called[0]);
+       }
+
+       @Test void b16_builder_forEachRP_actsOnReaderParsers() {
+               int[] count = {0};
+               ParserSet.create().add(JsonParser.class).forEachRP(b -> 
count[0]++);
+               assertEquals(1, count[0]);
+       }
+
+       @Test void b17_builder_forEachISP_noAction_whenNoISPEntries() {
+               int[] count = {0};
+               ParserSet.create().add(JsonParser.class).forEachISP(b -> 
count[0]++);
+               assertEquals(0, count[0]);
+       }
+
+       @Test void b18_builder_copy_withBcBuilder_propagatesBcBuilder() {
+               var sb = ParserSet.create().add(JsonParser.class);
+               sb.beanContext(BeanContext.create());
+               var copy = sb.copy();
+               assertNotNull(copy.beanStore());
+       }
+
+       @Test void b19_builder_addAfterBcBuilder_propagatesContext() {
+               var sb = ParserSet.create();
+               sb.beanContext(BeanContext.create());
+               sb.add(JsonParser.class);
+               assertFalse(sb.inner().isEmpty());
+       }
+
+       @Test void b20_parserSet_copy_returnsNewBuilder() {
+               var s = ParserSet.create().add(P1.class).build();
+               var copy = s.copy();
+               assertInstanceOf(P1.class, copy.build().getParser("text/1"));
+       }
+
+       @Test void b21_getParser_byMediaType() {
+               var s = ParserSet.create().add(P1.class).build();
+               assertInstanceOf(P1.class, s.getParser(MediaType.of("text/1")));
+               assertNull(s.getParser(MediaType.of("text/unknown")));
+       }
+
+       @Test void b22_add_parserWithNoArgConstructor_instantiatesDirectly() {
+               var s = ParserSet.create().add(SimpleParser.class).build();
+               assertInstanceOf(SimpleParser.class, 
s.getParser("text/simple"));
+       }
+
+       @Test void b23_copy_withParserInstance_coversNonBuilderBranch() {
+               var instance = new SimpleParser();
+               var sb = ParserSet.create().add(instance);
+               var copy = sb.copy();
+               assertFalse(copy.inner().isEmpty());
+       }
 }
\ No newline at end of file
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/rest/client/remote/RemoteOperationArg_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/rest/client/remote/RemoteOperationArg_Test.java
new file mode 100644
index 0000000000..4f5976b70d
--- /dev/null
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/rest/client/remote/RemoteOperationArg_Test.java
@@ -0,0 +1,75 @@
+/*
+ * 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.juneau.rest.client.remote;
+
+import static org.apache.juneau.commons.httppart.HttpPartType.*;
+import static org.junit.jupiter.api.Assertions.*;
+
+import org.apache.juneau.commons.reflect.*;
+import org.apache.juneau.http.annotation.*;
+import org.junit.jupiter.api.*;
+
+/**
+ * Tests for the {@link RemoteOperationArg#create(ParameterInfo)} factory,
+ * specifically the branches not yet covered by integration tests.
+ */
+class RemoteOperationArg_Test {
+
+       // Interface whose single method covers the PathRemainder branch
+       interface PathRemainderIface {
+               void get(@PathRemainder String remainder);
+       }
+
+       @Test
+       void a01_create_pathRemainder_returnsPATHWithSlashStar() throws 
Exception {
+               var m = MethodInfo.of(PathRemainderIface.class.getMethod("get", 
String.class));
+               var pi = m.getParameter(0);
+               var arg = RemoteOperationArg.create(pi);
+               assertNotNull(arg, "create() should return non-null for 
@PathRemainder param");
+               assertEquals(PATH, arg.getPartType());
+               assertEquals("/*", arg.getName());
+       }
+
+       // Verify null is returned for unannotated parameters
+       interface NoAnnotationIface {
+               void get(String plain);
+       }
+
+       @Test
+       void a02_create_noAnnotation_returnsNull() throws Exception {
+               var m = MethodInfo.of(NoAnnotationIface.class.getMethod("get", 
String.class));
+               var pi = m.getParameter(0);
+               assertNull(RemoteOperationArg.create(pi));
+       }
+
+       // Verify @Path branch (already covered upstream, but check getName / 
getSchema)
+       interface PathIface {
+               void get(@Path("id") String id);
+       }
+
+       @Test
+       void a03_create_path_returnsCorrectArg() throws Exception {
+               var m = MethodInfo.of(PathIface.class.getMethod("get", 
String.class));
+               var pi = m.getParameter(0);
+               var arg = RemoteOperationArg.create(pi);
+               assertNotNull(arg);
+               assertEquals(PATH, arg.getPartType());
+               assertEquals("id", arg.getName());
+               assertEquals(0, arg.getIndex());
+               assertNotNull(arg.getSchema());
+       }
+}
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/serializer/SerializerSet_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/serializer/SerializerSet_Test.java
index 60a451e511..eb423e1a30 100755
--- 
a/juneau-utest/src/test/java/org/apache/juneau/serializer/SerializerSet_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/serializer/SerializerSet_Test.java
@@ -20,6 +20,8 @@ import static org.apache.juneau.junit.bct.BctAssertions.*;
 import static org.junit.jupiter.api.Assertions.*;
 
 import org.apache.juneau.*;
+import org.apache.juneau.commons.http.MediaType;
+import org.apache.juneau.commons.inject.*;
 import org.apache.juneau.json.*;
 import org.junit.jupiter.api.*;
 
@@ -145,4 +147,185 @@ class SerializerSet_Test extends TestBase {
                        super(builder.accept("*/*"));
                }
        }
+
+       public static class SimpleSerializer extends JsonSerializer {
+               public SimpleSerializer() {
+                       super(JsonSerializer.create().accept("text/simple"));
+               }
+       }
+
+       
//====================================================================================================
+       // Builder edge-case coverage
+       
//====================================================================================================
+
+       @Test void b01_builder_addInstancesDirectly() {
+               var instance = new 
SB1(JsonSerializer.create().accept("text/1"));
+               var s = SerializerSet.create().add(instance).build();
+               assertInstanceOf(SB1.class, s.getSerializer("text/1"));
+       }
+
+       @Test void b02_builder_addInvalidClassThrows() {
+               assertThrows(RuntimeException.class, () ->
+                       SerializerSet.create().add(String.class));
+       }
+
+       @Test void b03_builder_setWithInherit() {
+               var sb = SerializerSet.create().add(SB1.class, SB2.class);
+               sb.set(SerializerSet.Inherit.class, SB3.class);
+               var s = sb.build();
+               assertInstanceOf(SB1.class, s.getSerializer("text/1"));
+               assertInstanceOf(SB2.class, s.getSerializer("text/2"));
+               assertInstanceOf(SB3.class, s.getSerializer("text/3"));
+       }
+
+       @Test void b04_builder_setWithInvalidClassThrows() {
+               assertThrows(RuntimeException.class, () ->
+                       SerializerSet.create().set(String.class));
+       }
+
+       @Test void b05_builder_implBypassesBuild() {
+               var preset = SerializerSet.create().add(SB1.class).build();
+               var s = SerializerSet.create().impl(preset).build();
+               assertSame(preset, s);
+       }
+
+       @Test void b06_builder_inner_returnsEntries() {
+               var sb = SerializerSet.create().add(SB1.class);
+               assertFalse(sb.inner().isEmpty());
+       }
+
+       @Test void b07_builder_toStringWithBuilder() {
+               var sb = SerializerSet.create().add(JsonSerializer.class);
+               assertTrue(sb.toString().contains("builder:"));
+       }
+
+       @Test void b08_builder_toStringWithInstance() {
+               var sb = SerializerSet.create().add(new 
SB1(JsonSerializer.create().accept("text/1")));
+               assertTrue(sb.toString().contains("serializer:"));
+       }
+
+       @Test void b09_builder_toStringWithNull() {
+               var sb = SerializerSet.create();
+               sb.inner().add(null);
+               assertTrue(sb.toString().contains("null"));
+       }
+
+       @Test void b10_builder_create_withBeanStore() {
+               var bs = new BasicBeanStore(null);
+               var sb = SerializerSet.create(bs);
+               assertSame(bs, sb.beanStore());
+       }
+
+       @Test void b11_builder_copy_isIndependent() {
+               var sb1 = SerializerSet.create().add(SB1.class);
+               var sb2 = sb1.copy();
+               sb2.add(SB2.class);
+               assertNotNull(sb2.build().getSerializer("text/2"));
+               assertNull(sb1.build().getSerializer("text/2"));
+       }
+
+       @Test void b12_builder_beanContext_propagatesToBuilders() {
+               var bcb = BeanContext.create();
+               var sb = SerializerSet.create().add(JsonSerializer.class);
+               sb.beanContext(bcb);
+               assertNotNull(sb.beanStore());
+       }
+
+       @Test void b13_builder_beanContext_consumer_withNonNullBcBuilder() {
+               boolean[] called = {false};
+               var sb = SerializerSet.create().add(JsonSerializer.class);
+               sb.beanContext(BeanContext.create());
+               sb.beanContext((BeanContext.Builder b) -> called[0] = true);
+               assertTrue(called[0]);
+       }
+
+       @Test void b14_builder_beanContext_consumer_withNullBcBuilder_isNoop() {
+               boolean[] called = {false};
+               var sb = SerializerSet.create().add(JsonSerializer.class);
+               sb.beanContext((BeanContext.Builder b) -> called[0] = true);
+               assertFalse(called[0]);
+       }
+
+       @Test void b15_builder_forEachWS_actsOnWriterSerializers() {
+               int[] count = {0};
+               SerializerSet.create().add(JsonSerializer.class).forEachWS(b -> 
count[0]++);
+               assertEquals(1, count[0]);
+       }
+
+       @Test void b16_builder_forEachOSS_noAction_whenNoOSSEntries() {
+               int[] count = {0};
+               SerializerSet.create().add(JsonSerializer.class).forEachOSS(b 
-> count[0]++);
+               assertEquals(0, count[0]);
+       }
+
+       @Test void b17_builder_copy_withBcBuilder_propagatesBcBuilder() {
+               var sb = SerializerSet.create().add(JsonSerializer.class);
+               sb.beanContext(BeanContext.create());
+               var copy = sb.copy();
+               assertNotNull(copy.beanStore());
+       }
+
+       @Test void b18_builder_addAfterBcBuilder_propagatesContext() {
+               var sb = SerializerSet.create();
+               sb.beanContext(BeanContext.create());
+               sb.add(JsonSerializer.class);
+               assertFalse(sb.inner().isEmpty());
+       }
+
+       @Test void b19_serializerSet_copy_returnsNewBuilder() {
+               var s = SerializerSet.create().add(SB1.class).build();
+               var copy = s.copy();
+               assertInstanceOf(SB1.class, 
copy.build().getSerializer("text/1"));
+       }
+
+       @Test void b20_getSerializer_byMediaType() {
+               var s = SerializerSet.create().add(SB1.class).build();
+               assertInstanceOf(SB1.class, 
s.getSerializer(MediaType.of("text/1")));
+               assertNull(s.getSerializer(MediaType.of("text/unknown")));
+       }
+
+       @Test void b21_getSerializer_nullMediaType_returnsNull() {
+               var s = SerializerSet.create().add(SB1.class).build();
+               assertNull(s.getSerializer((MediaType) null));
+       }
+
+       @Test void b22_builder_clear_removesAllEntries() {
+               var sb = SerializerSet.create().add(SB1.class, SB2.class);
+               assertEquals(2, sb.inner().size());
+               sb.clear();
+               assertTrue(sb.inner().isEmpty());
+       }
+
+       @Test void b23_getSerializerMatch_byMediaType() {
+               var s = SerializerSet.create().add(SB1.class).build();
+               assertNotNull(s.getSerializerMatch(MediaType.of("text/1")));
+       }
+
+       @Test void b24_getSerializerMatch_nullString_returnsNull() {
+               var s = SerializerSet.create().add(SB1.class).build();
+               assertNull(s.getSerializerMatch((String) null));
+       }
+
+       @Test void b25_getWriterSerializer_byMediaType() {
+               var s = SerializerSet.create().add(SB1.class).build();
+               assertInstanceOf(SB1.class, 
s.getWriterSerializer(MediaType.of("text/1")));
+       }
+
+       @Test void 
b26_add_serializerWithNoArgConstructor_instantiatesDirectly() {
+               var s = 
SerializerSet.create().add(SimpleSerializer.class).build();
+               assertInstanceOf(SimpleSerializer.class, 
s.getSerializer("text/simple"));
+       }
+
+       @Test void b27_copy_withSerializerInstance_coversNonBuilderBranch() {
+               var instance = new SimpleSerializer();
+               var sb = SerializerSet.create().add(instance);
+               var copy = sb.copy();
+               assertFalse(copy.inner().isEmpty());
+       }
+
+       @Test void b28_getStreamSerializer_withNoMatch_returnsNull() {
+               var s = SerializerSet.create().add(SB1.class).build();
+               assertNull(s.getStreamSerializer(MediaType.of("text/unknown")));
+               assertNull(s.getStreamSerializer("text/unknown"));
+       }
 }
\ No newline at end of file

Reply via email to