MethodParams { static <E extends MessageEnvelope<?, ?, ?>, S extends ParameterSpec<E>> Optional<S> findMatching(Method method, Collection<S> paramSpecs) { MethodParams params = of(method); Optional<S> result = paramSpecs.stream() .filter(spec -> spec.matches(params)) .findFirst(); return result; } private  MethodParams(@Nullable ArgumentFilter filter, Class<?>... types); private  MethodParams(@Nullable ArgumentFilter filter, ImmutableList<Class<?>> params); static MethodParams of(SubscriberMethod method); static MethodParams of(Method method); int size(); Optional<ArgumentFilter> filter(); Class<?> type(int index); boolean is(TypeMatcher type); boolean are(Class<?>... types); boolean match(TypeMatcher... criteria); boolean match(List<TypeMatcher> criteria); static boolean firstIsCommand(Method method); @Override boolean equals(Object o); @Override int hashCode(); @SuppressWarnings("DuplicateStringLiteralInspection") // others also have the `filter` field. @Override String toString();  }
@Test @DisplayName("find a matching signature for the method among the predefined set of values") void findMatchingSignature() { Optional<ScheduleCommandParamSpec> matching = findMatching(twoParamCommandAndCtx(), ImmutableList.copyOf(ScheduleCommandParamSpec.values())); assertTrue(matching.isPresent()); assertEquals(ScheduleCommandParamSpec.MESSAGE_AND_CONTEXT, matching.get()); }
@Test @DisplayName("return `Optional.empty()` if there is no matching signature") void returnOptionalEmptyIfNoSignatureMatch() { Optional<ScheduleCommandParamSpec> matching = findMatching(singleParamCommand(), ImmutableList.copyOf(ScheduleCommandParamSpec.values())); assertFalse(matching.isPresent()); }