### Question:
FormulaFunctions { public static String formatSignature(FormulaFunction function) { List<String> arguments = new ArrayList<>(); for (int i = 0; i < function.getArgumentTypes().size() - 1; i++) { arguments.add(function.getArgumentTypes().get(i).getSimpleName() + " " + function.getArgumentNames().get(i)); } StringBuilder lastArgument = new StringBuilder(); lastArgument.append(function.getArgumentTypes().get(function.getArgumentTypes().size() - 1).getSimpleName()); if (function.isVarArgs()) { lastArgument.append("..."); } lastArgument.append(" ").append(function.getArgumentNames().get(function.getArgumentTypes().size() - 1)); arguments.add(lastArgument.toString()); StringBuilder sb = new StringBuilder(); sb.append(format(function.getName(), arguments)); sb.append(": "); sb.append(function.getReturnType().getSimpleName()); return sb.toString(); }  static boolean matchArgumentTypes(List<Object> arguments, FormulaFunction function); static boolean matchArgumentTypes(List<Object> arguments, FormulaFunction function, boolean allowNull); static boolean matchArgumentCount(int nArguments, FormulaFunction function); static FormulaFunction findFirstMatch(List<Object> arguments, Collection<FormulaFunction> formulaFunctions); static Collection<FormulaFunction> findArgTypeMatch(List<Class<?>> argTypes, Collection<FormulaFunction> formulaFunctions); static String formatSignature(FormulaFunction function); static String format(String function, List<String> args);  }### Answer:
@Test public void formatSignature1() { FormulaFunction function = new FormulaFunction() { @Override public boolean isPure() { return true; } @Override public boolean isVarArgs() { return true; } @Override public String getName() { return "arrayOf"; } @Override public String getDescription() { return ""; } @Override public List<Class<?>> getArgumentTypes() { return Arrays.asList(VNumber.class); } @Override public List<String> getArgumentNames() { return Arrays.asList("args"); } @Override public Class<?> getReturnType() { return VNumberArray.class; } @Override public Object calculate(List<Object> args) { throw new UnsupportedOperationException("Not supported."); } }; assertThat(FormulaFunctions.formatSignature(function), equalTo("arrayOf(VNumber... args): VNumberArray")); }
@Test public void formatSignature2() { FormulaFunction function = new AbstractVNumberToVNumberFormulaFunction("log", "desc", "input") { @Override public double calculate(double arg) { throw new UnsupportedOperationException("Not supported yet."); } }; assertThat(FormulaFunctions.formatSignature(function), equalTo("log(VNumber input): VNumber")); }
@Test public void formatSignature3() { FormulaFunction function = new VNumberFunctionSet().findFunctions("+").iterator().next(); assertThat(FormulaFunctions.formatSignature(function), equalTo("(VNumber arg1 + VNumber arg2): VNumber")); }