diff --git a/src/de/steamwar/command/AbstractSWCommand.java b/src/de/steamwar/command/AbstractSWCommand.java index 7e76d62..9ff2e28 100644 --- a/src/de/steamwar/command/AbstractSWCommand.java +++ b/src/de/steamwar/command/AbstractSWCommand.java @@ -35,7 +35,6 @@ public abstract class AbstractSWCommand { private boolean initialized = false; protected final List> commandList = new ArrayList<>(); - protected final List> commandHelpList = new ArrayList<>(); private final Map> localTypeMapper = new HashMap<>(); private final Map> localValidators = new HashMap<>(); @@ -109,15 +108,8 @@ public abstract class AbstractSWCommand { List errors = new ArrayList<>(); try { if (!commandList.stream().anyMatch(s -> s.invoke(errors::add, sender, alias, finalArgs))) { - if (!errors.isEmpty()) { - errors.forEach(Runnable::run); - return; - } - commandHelpList.stream().anyMatch(s -> s.invoke((ignore) -> { - }, sender, alias, finalArgs)); + errors.forEach(Runnable::run); } - } catch (CommandNoHelpException e) { - // Ignored } catch (CommandFrameworkException e) { commandSystemError(sender, e); throw e; @@ -139,12 +131,8 @@ public abstract class AbstractSWCommand { .collect(Collectors.toList()); } - private void initialize() { + private synchronized void initialize() { if (initialized) return; - createMapping(); - } - - private synchronized void createMapping() { List methods = methods(); for (Method method : methods) { Cached cached = method.getAnnotation(Cached.class); @@ -181,32 +169,13 @@ public abstract class AbstractSWCommand { } for (Method method : methods) { add(Register.class, method, i -> i > 0, true, null, (anno, parameters) -> { - if (!anno.help()) return; - boolean error = false; - if (parameters.length != 2) { - commandSystemWarning(() -> "The method '" + method.toString() + "' is lacking parameters or has too many"); - error = true; - } - if (!parameters[parameters.length - 1].isVarArgs()) { - commandSystemWarning(() -> "The method '" + method.toString() + "' is lacking the varArgs parameters as last Argument"); - error = true; - } - if (parameters[parameters.length - 1].getType().getComponentType() != String.class) { - commandSystemWarning(() -> "The method '" + method.toString() + "' is lacking the varArgs parameters of type '" + String.class.getTypeName() + "' as last Argument"); - error = true; - } - if (error) return; - commandHelpList.add(new SubCommand<>(this, method, anno.value(), new HashMap<>(), new HashMap<>(), true, null, anno.noTabComplete())); - }); - - add(Register.class, method, i -> i > 0, true, null, (anno, parameters) -> { - if (anno.help()) return; for (int i = 1; i < parameters.length; i++) { Parameter parameter = parameters[i]; Class clazz = parameter.getType(); if (parameter.isVarArgs() && i == parameters.length - 1) { clazz = parameter.getType().getComponentType(); } + checkAnnotationApplicability(parameter, clazz); Mapper mapper = parameter.getAnnotation(Mapper.class); if (clazz.isEnum() && mapper == null && !SWCommandUtils.getMAPPER_FUNCTIONS().containsKey(clazz.getTypeName())) { continue; @@ -217,7 +186,7 @@ public abstract class AbstractSWCommand { return; } } - commandList.add(new SubCommand<>(this, method, anno.value(), localTypeMapper, localValidators, false, anno.description(), anno.noTabComplete())); + commandList.add(new SubCommand<>(this, method, anno.value(), localTypeMapper, localValidators, anno.description(), anno.noTabComplete())); }); } @@ -229,18 +198,28 @@ public abstract class AbstractSWCommand { return Integer.compare(o1.comparableValue, o2.comparableValue); } }); - commandHelpList.sort((o1, o2) -> { - int compare = Integer.compare(-o1.subCommand.length, -o2.subCommand.length); - if (compare != 0) { - return compare; - } else { - return Integer.compare(o1.method.getDeclaringClass() == AbstractSWCommand.class ? 1 : 0, - o2.method.getDeclaringClass() == AbstractSWCommand.class ? 1 : 0); - } - }); initialized = true; } + private void checkAnnotationApplicability(Parameter parameter, Class clazz) { + Annotation[] annotations = parameter.getAnnotations(); + for (Annotation annotation : annotations) { + ApplicableTypes applicableTypes = annotation.annotationType().getAnnotation(ApplicableTypes.class); + if (applicableTypes == null) continue; + Class[] types = applicableTypes.value(); + boolean applicable = false; + for (Class type : types) { + if (type.isAssignableFrom(clazz)) { + applicable = true; + break; + } + } + if (!applicable) { + commandSystemWarning(() -> "The parameter '" + parameter.toString() + "' is using an unsupported annotation of type '" + annotation.annotationType().getName() + "'"); + } + } + } + private void add(Class annotation, Method method, IntPredicate parameterTester, boolean firstParameter, Class returnType, BiConsumer consumer) { T[] anno = SWCommandUtils.getAnnotation(method, annotation); if (anno == null || anno.length == 0) return; @@ -300,12 +279,22 @@ public abstract class AbstractSWCommand { return methods; } + // --- Annotation for the command --- + + /** + * Annotation for registering a method as a command + */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) @Repeatable(Register.Registeres.class) protected @interface Register { + + /** + * Identifier of subcommand + */ String[] value() default {}; + @Deprecated boolean help() default false; String[] description() default {}; @@ -359,8 +348,11 @@ public abstract class AbstractSWCommand { boolean local() default false; } + // --- Implicit TypeMapper --- + @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.PARAMETER}) + @ApplicableTypes({String.class, int.class, Integer.class, boolean.class, Boolean.class}) protected @interface StaticValue { String[] value(); @@ -391,6 +383,8 @@ public abstract class AbstractSWCommand { boolean onlyUINIG() default false; } + // --- Implicit Validator --- + @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.PARAMETER}) protected @interface ErrorMessage { @@ -415,6 +409,31 @@ public abstract class AbstractSWCommand { */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.PARAMETER}) + @ApplicableTypes({String.class}) protected @interface Quotable { } + + @Retention(RetentionPolicy.RUNTIME) + @Target({ElementType.PARAMETER}) + @ApplicableTypes({int.class, Integer.class, long.class, Long.class, float.class, Float.class, double.class, Double.class}) + protected @interface Min { + int intValue() default Integer.MIN_VALUE; + long longValue() default Long.MIN_VALUE; + float floatValue() default Float.MIN_VALUE; + double doubleValue() default Double.MIN_VALUE; + + boolean inclusive() default true; + } + + @Retention(RetentionPolicy.RUNTIME) + @Target({ElementType.PARAMETER}) + @ApplicableTypes({int.class, Integer.class, long.class, Long.class, float.class, Float.class, double.class, Double.class}) + protected @interface Max { + int intValue() default Integer.MAX_VALUE; + long longValue() default Long.MAX_VALUE; + float floatValue() default Float.MAX_VALUE; + double doubleValue() default Double.MAX_VALUE; + + boolean inclusive() default true; + } } diff --git a/src/de/steamwar/command/AbstractValidator.java b/src/de/steamwar/command/AbstractValidator.java index aab4876..7dc0b72 100644 --- a/src/de/steamwar/command/AbstractValidator.java +++ b/src/de/steamwar/command/AbstractValidator.java @@ -38,10 +38,12 @@ public interface AbstractValidator { */ boolean validate(K sender, T value, MessageSender messageSender); + @Deprecated default Validator validate(C value, MessageSender messageSender) { return new Validator<>(value, messageSender); } + @Deprecated @RequiredArgsConstructor class Validator { private final C value; diff --git a/src/de/steamwar/command/CommandNoHelpException.java b/src/de/steamwar/command/ApplicableTypes.java similarity index 69% rename from src/de/steamwar/command/CommandNoHelpException.java rename to src/de/steamwar/command/ApplicableTypes.java index e3d476a..2385b43 100644 --- a/src/de/steamwar/command/CommandNoHelpException.java +++ b/src/de/steamwar/command/ApplicableTypes.java @@ -1,7 +1,7 @@ /* * This file is a part of the SteamWar software. * - * Copyright (C) 2020 SteamWar.de-Serverteam + * Copyright (C) 2022 SteamWar.de-Serverteam * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by @@ -19,7 +19,13 @@ package de.steamwar.command; -class CommandNoHelpException extends RuntimeException { - - CommandNoHelpException() {} +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.ANNOTATION_TYPE) +@interface ApplicableTypes { + Class[] value(); } diff --git a/src/de/steamwar/command/CommandPart.java b/src/de/steamwar/command/CommandPart.java index a81c646..bb39119 100644 --- a/src/de/steamwar/command/CommandPart.java +++ b/src/de/steamwar/command/CommandPart.java @@ -24,6 +24,7 @@ import lombok.Setter; import java.lang.reflect.Array; import java.lang.reflect.Parameter; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; @@ -41,7 +42,7 @@ class CommandPart { private AbstractSWCommand command; private AbstractTypeMapper typeMapper; - private AbstractValidator validator; + private List> validators = new ArrayList<>(); private Class varArgType; private String optional; @@ -53,19 +54,12 @@ class CommandPart { @Setter private boolean onlyUseIfNoneIsGiven = false; - @Setter - private boolean allowNullValues = false; - - @Setter - private boolean quotable = false; - private Parameter parameter; private int parameterIndex; - public CommandPart(AbstractSWCommand command, AbstractTypeMapper typeMapper, AbstractValidator validator, Class varArgType, String optional, Parameter parameter, int parameterIndex) { + public CommandPart(AbstractSWCommand command, AbstractTypeMapper typeMapper, Class varArgType, String optional, Parameter parameter, int parameterIndex) { this.command = command; this.typeMapper = typeMapper; - this.validator = validator; this.varArgType = varArgType; this.optional = optional; this.parameter = parameter; @@ -74,6 +68,11 @@ class CommandPart { validatePart(); } + void addValidator(AbstractValidator validator) { + if (validator == null) return; + validators.add(validator); + } + public void setNext(CommandPart next) { if (varArgType != null) { throw new IllegalArgumentException("There can't be a next part if this is a vararg part! In method " + parameter.getDeclaringExecutable() + " with parameter " + parameterIndex); @@ -97,10 +96,12 @@ class CommandPart { } Array.set(array, i - startIndex, validArgument.value); } - if (validator != null && !validator.validate(sender, array, (s, objects) -> { - errors.accept(() -> command.sendMessage(sender, s, objects)); - })) { - throw new CommandParseException(); + for (AbstractValidator validator : validators) { + if (!validator.validate(sender, array, (s, objects) -> { + errors.accept(() -> command.sendMessage(sender, s, objects)); + })) { + throw new CommandParseException(); + } } current.add(array); return; @@ -136,7 +137,8 @@ class CommandPart { public void generateTabComplete(List current, T sender, String[] args, int startIndex) { if (varArgType != null) { for (int i = startIndex; i < args.length - 1; i++) { - CheckArgumentResult validArgument = checkArgument((ignore) -> {}, sender, args, i); + CheckArgumentResult validArgument = checkArgument((ignore) -> { + }, sender, args, i); if (!validArgument.success) { return; } @@ -149,7 +151,8 @@ class CommandPart { } if (args.length - 1 > startIndex) { - CheckArgumentResult checkArgumentResult = checkArgument((ignore) -> {}, sender, args, startIndex); + CheckArgumentResult checkArgumentResult = checkArgument((ignore) -> { + }, sender, args, startIndex); if (checkArgumentResult.success && next != null) { next.generateTabComplete(current, sender, args, startIndex + 1); return; @@ -186,10 +189,7 @@ class CommandPart { } catch (Exception e) { return new CheckArgumentResult(false, null); } - if (value instanceof String && !quotable && ((String) value).contains(" ")) { - return new CheckArgumentResult(false, null); - } - if (validator != null && errors != null) { + for (AbstractValidator validator : validators) { try { if (!validator.validate(sender, value, (s, objects) -> { errors.accept(() -> { @@ -202,6 +202,6 @@ class CommandPart { throw CommandFrameworkException.commandPartExceptions("validating", e, args[index], (varArgType != null ? varArgType : parameter.getType()), parameter.getDeclaringExecutable(), parameterIndex); } } - return new CheckArgumentResult(allowNullValues || value != null, value); + return new CheckArgumentResult(true, value); } } diff --git a/src/de/steamwar/command/SWCommandUtils.java b/src/de/steamwar/command/SWCommandUtils.java index 871439a..203bdd8 100644 --- a/src/de/steamwar/command/SWCommandUtils.java +++ b/src/de/steamwar/command/SWCommandUtils.java @@ -82,44 +82,6 @@ public class SWCommandUtils { MAPPER_FUNCTIONS.put(alternativeClazz.getTypeName(), mapper); } - static CommandPart generateCommandPart(AbstractSWCommand command, boolean help, String[] subCommand, Parameter[] parameters, Map> localTypeMapper, Map> localValidator) { - CommandPart first = null; - CommandPart current = null; - for (String s : subCommand) { - CommandPart commandPart = new CommandPart(command, createMapper(s), null, null, null, null, -1); - commandPart.setIgnoreAsArgument(true); - if (current != null) { - current.setNext(commandPart); - } - current = commandPart; - if (first == null) { - first = current; - } - } - for (int i = 1; i < parameters.length; i++) { - Parameter parameter = parameters[i]; - AbstractTypeMapper typeMapper = getTypeMapper(parameter, localTypeMapper); - AbstractValidator validator = (AbstractValidator) getValidator(parameter, localValidator); - Class varArgType = parameter.isVarArgs() ? parameter.getType().getComponentType() : null; - AbstractSWCommand.OptionalValue optionalValue = parameter.getAnnotation(AbstractSWCommand.OptionalValue.class); - AbstractSWCommand.AllowNull allowNull = parameter.getAnnotation(AbstractSWCommand.AllowNull.class); - AbstractSWCommand.Quotable quotable = parameter.getAnnotation(AbstractSWCommand.Quotable.class); - - CommandPart commandPart = new CommandPart<>(command, typeMapper, validator, varArgType, optionalValue != null ? optionalValue.value() : null, parameter, i); - commandPart.setOnlyUseIfNoneIsGiven(optionalValue != null && optionalValue.onlyUINIG()); - commandPart.setAllowNullValues(allowNull != null); - commandPart.setQuotable(quotable != null); - if (current != null) { - current.setNext(commandPart); - } - current = commandPart; - if (first == null) { - first = current; - } - } - return first; - } - public static AbstractTypeMapper getTypeMapper(Parameter parameter, Map> localTypeMapper) { Class clazz = parameter.getType(); if (parameter.isVarArgs()) { diff --git a/src/de/steamwar/command/SubCommand.java b/src/de/steamwar/command/SubCommand.java index 9eb6e4f..bf11674 100644 --- a/src/de/steamwar/command/SubCommand.java +++ b/src/de/steamwar/command/SubCommand.java @@ -43,7 +43,7 @@ public class SubCommand { private CommandPart commandPart; - SubCommand(AbstractSWCommand abstractSWCommand, Method method, String[] subCommand, Map> localTypeMapper, Map> localValidator, boolean help, String[] description, boolean noTabComplete) { + SubCommand(AbstractSWCommand abstractSWCommand, Method method, String[] subCommand, Map> localTypeMapper, Map> localValidator, String[] description, boolean noTabComplete) { this.abstractSWCommand = abstractSWCommand; this.method = method; try { @@ -60,7 +60,7 @@ public class SubCommand { validator = (AbstractValidator) SWCommandUtils.getValidator(parameters[0], localValidator); - commandPart = SWCommandUtils.generateCommandPart(abstractSWCommand, help, subCommand, parameters, localTypeMapper, localValidator); + commandPart = generateCommandPart(abstractSWCommand, subCommand, parameters, localTypeMapper, localValidator); senderPredicate = t -> parameters[0].getType().isAssignableFrom(t.getClass()); senderFunction = t -> parameters[0].getType().cast(t); @@ -97,7 +97,7 @@ public class SubCommand { objects.add(0, senderFunction.apply(sender)); method.invoke(abstractSWCommand, objects.toArray()); } - } catch (CommandNoHelpException | CommandFrameworkException e) { + } catch (CommandFrameworkException e) { throw e; } catch (CommandParseException e) { return false; @@ -124,4 +124,110 @@ public class SubCommand { commandPart.generateTabComplete(list, sender, args, 0); return list; } + + private static CommandPart generateCommandPart(AbstractSWCommand command, String[] subCommand, Parameter[] parameters, Map> localTypeMapper, Map> localValidator) { + CommandPart first = null; + CommandPart current = null; + for (String s : subCommand) { + CommandPart commandPart = new CommandPart(command, SWCommandUtils.createMapper(s), null, null, null, -1); + commandPart.addValidator(NULL_FILTER); + commandPart.setIgnoreAsArgument(true); + if (current != null) { + current.setNext(commandPart); + } + current = commandPart; + if (first == null) { + first = current; + } + } + for (int i = 1; i < parameters.length; i++) { + Parameter parameter = parameters[i]; + AbstractTypeMapper typeMapper = SWCommandUtils.getTypeMapper(parameter, localTypeMapper); + AbstractValidator validator = (AbstractValidator) SWCommandUtils.getValidator(parameter, localValidator); + Class varArgType = parameter.isVarArgs() ? parameter.getType().getComponentType() : null; + AbstractSWCommand.OptionalValue optionalValue = parameter.getAnnotation(AbstractSWCommand.OptionalValue.class); + AbstractSWCommand.Min min = parameter.getAnnotation(AbstractSWCommand.Min.class); + AbstractSWCommand.Max max = parameter.getAnnotation(AbstractSWCommand.Max.class); + + CommandPart commandPart = new CommandPart<>(command, typeMapper, varArgType, optionalValue != null ? optionalValue.value() : null, parameter, i); + commandPart.setOnlyUseIfNoneIsGiven(optionalValue != null && optionalValue.onlyUINIG()); + if (parameter.getAnnotation(AbstractSWCommand.Quotable.class) == null) { + commandPart.addValidator((AbstractValidator) STRING_SPACE_FILTER); + } + commandPart.addValidator(validator); + if (min != null) { + commandPart.addValidator((AbstractValidator) createMinValidator(varArgType != null ? varArgType : parameter.getType(), min)); + } + if (max != null) { + commandPart.addValidator((AbstractValidator) createMaxValidator(varArgType != null ? varArgType : parameter.getType(), max)); + } + if (parameter.getAnnotation(AbstractSWCommand.AllowNull.class) == null) { + commandPart.addValidator((AbstractValidator) NULL_FILTER); + } + if (current != null) { + current.setNext(commandPart); + } + current = commandPart; + if (first == null) { + first = current; + } + } + return first; + } + + private static final AbstractValidator NULL_FILTER = (sender, value, messageSender) -> value != null; + + private static final AbstractValidator STRING_SPACE_FILTER = (sender, value, messageSender) -> { + if (!(value instanceof String)) return true; + String s = (String) value; + return !s.contains(" "); + }; + + private static AbstractValidator createMinValidator(Class clazz, AbstractSWCommand.Min min) { + Function comparator; + if (clazz == int.class || clazz == Integer.class) { + int minValue = min.intValue(); + comparator = number -> Integer.compare(number.intValue(), minValue); + } else if (clazz == long.class || clazz == Long.class) { + long minValue = min.longValue(); + comparator = number -> Long.compare(number.longValue(), minValue); + } else if (clazz == float.class || clazz == Float.class) { + float minValue = min.floatValue(); + comparator = number -> Float.compare(number.floatValue(), minValue); + } else if (clazz == double.class || clazz == Double.class) { + double minValue = min.doubleValue(); + comparator = number -> Double.compare(number.doubleValue(), minValue); + } else { + throw new IllegalArgumentException("Min annotation is not supported for " + clazz); + } + if (min.inclusive()) { + return (sender, value, messageSender) -> comparator.apply((Number) value).intValue() >= 0; + } else { + return (sender, value, messageSender) -> comparator.apply((Number) value).intValue() > 0; + } + } + + private static AbstractValidator createMaxValidator(Class clazz, AbstractSWCommand.Max max) { + Function comparator; + if (clazz == int.class || clazz == Integer.class) { + int minValue = max.intValue(); + comparator = number -> Integer.compare(number.intValue(), minValue); + } else if (clazz == long.class || clazz == Long.class) { + long minValue = max.longValue(); + comparator = number -> Long.compare(number.longValue(), minValue); + } else if (clazz == float.class || clazz == Float.class) { + float minValue = max.floatValue(); + comparator = number -> Float.compare(number.floatValue(), minValue); + } else if (clazz == double.class || clazz == Double.class) { + double minValue = max.doubleValue(); + comparator = number -> Double.compare(number.doubleValue(), minValue); + } else { + throw new IllegalArgumentException("Max annotation is not supported for " + clazz); + } + if (max.inclusive()) { + return (sender, value, messageSender) -> comparator.apply((Number) value).intValue() <= 0; + } else { + return (sender, value, messageSender) -> comparator.apply((Number) value).intValue() < 0; + } + } } diff --git a/testsrc/de/steamwar/command/BetterExceptionCommand.java b/testsrc/de/steamwar/command/BetterExceptionCommand.java index cd38179..d014186 100644 --- a/testsrc/de/steamwar/command/BetterExceptionCommand.java +++ b/testsrc/de/steamwar/command/BetterExceptionCommand.java @@ -45,6 +45,7 @@ public class BetterExceptionCommand extends TestSWCommand { @Override public boolean validate(String sender, String value, MessageSender messageSender) { + System.out.println("Validate: " + value); throw new SecurityException(); } diff --git a/testsrc/de/steamwar/command/NumberValidatorCommand.java b/testsrc/de/steamwar/command/NumberValidatorCommand.java new file mode 100644 index 0000000..9ba53a6 --- /dev/null +++ b/testsrc/de/steamwar/command/NumberValidatorCommand.java @@ -0,0 +1,35 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2022 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command; + +import de.steamwar.command.dto.ExecutionIdentifier; +import de.steamwar.command.dto.TestSWCommand; + +public class NumberValidatorCommand extends TestSWCommand { + + public NumberValidatorCommand() { + super("numberValidator"); + } + + @Register + public void test(String sender, @Min(intValue = 0) @Max(intValue = 10) int i) { + throw new ExecutionIdentifier("RunNumberValidator with int"); + } +} diff --git a/testsrc/de/steamwar/command/NumberValidatorCommandTest.java b/testsrc/de/steamwar/command/NumberValidatorCommandTest.java new file mode 100644 index 0000000..c45b4a8 --- /dev/null +++ b/testsrc/de/steamwar/command/NumberValidatorCommandTest.java @@ -0,0 +1,51 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2022 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command; + +import de.steamwar.command.dto.ExecutionIdentifier; +import org.junit.Test; + +import static de.steamwar.AssertionUtils.assertCMDFramework; + +public class NumberValidatorCommandTest { + + @Test + public void testMinValue() { + NumberValidatorCommand command = new NumberValidatorCommand(); + command.execute("sender", "", new String[]{"-1"}); + } + + @Test + public void testMaxValue() { + NumberValidatorCommand command = new NumberValidatorCommand(); + command.execute("sender", "", new String[]{"11"}); + } + + @Test + public void testValidValue() { + try { + NumberValidatorCommand command = new NumberValidatorCommand(); + command.execute("sender", "", new String[]{"2"}); + assert false; + } catch (Exception e) { + assertCMDFramework(e, ExecutionIdentifier.class, "RunNumberValidator with int"); + } + } +} diff --git a/testsrc/de/steamwar/command/SimpleCommand.java b/testsrc/de/steamwar/command/SimpleCommand.java index 95aa43d..7388633 100644 --- a/testsrc/de/steamwar/command/SimpleCommand.java +++ b/testsrc/de/steamwar/command/SimpleCommand.java @@ -19,7 +19,6 @@ package de.steamwar.command; -import de.steamwar.command.AbstractSWCommand.Register; import de.steamwar.command.dto.ExecutionIdentifier; import de.steamwar.command.dto.TestSWCommand; @@ -29,7 +28,7 @@ public class SimpleCommand extends TestSWCommand { super("simple"); } - @Register(value = "a", help = true) + @Register(value = "a", noTabComplete = true) public void test(String s, String... varargs) { throw new ExecutionIdentifier("RunSimple with Varargs"); } diff --git a/testsrc/de/steamwar/command/dto/TestSWCommand.java b/testsrc/de/steamwar/command/dto/TestSWCommand.java index 5fd3b3f..e0ac34b 100644 --- a/testsrc/de/steamwar/command/dto/TestSWCommand.java +++ b/testsrc/de/steamwar/command/dto/TestSWCommand.java @@ -51,9 +51,11 @@ public class TestSWCommand extends AbstractSWCommand { @Override protected void commandSystemError(String sender, CommandFrameworkException e) { + System.out.println("CommandSystemError: " + e.getMessage()); } @Override protected void commandSystemWarning(Supplier message) { + System.out.println("CommandSystemWarning: " + message.get()); } }