Klasse Validator eingefügt

This commit is contained in:
ngb 2022-07-06 20:16:37 +02:00
parent 62dc4190a1
commit 49063c9581
3 changed files with 283 additions and 1 deletions

View File

@ -6,11 +6,14 @@ und diese Projekt folgt [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
## [Unreleased]
## Version 0.0.21
### Added
- Parameter `stop_after_draw` im Konstruktor der `Zeichenmaschine` erlaubt es beim Erstellen festzulegen, ob nach dem ersten Frame die Zeichenmaschine gestoppt wird.
- `Picture.tint(Color)` färbt ein Bild ein.
- `Picture.flip(Options.Direction)` spiegelt ein Bild entlang einer Achse (`LEFT`/`RIGHT` für horizontal, `UP`/`DOWN` für vertikal).
- Abstrakte Klasse `Zeichenobjekt` als einheitliche Oberklasse für Objekte in Projekten. Die Klasse erbt von `Constants` und implementiert `Drawabale` und `Updatable` mit leeren Methoden.
- Abstrakte Klasse `Zeichenobjekt` als einheitliche Oberklasse für Objekte in Projekten. Die Klasse erbt von `Constants` und implementiert `Drawabale` und `Updatable` mit leeren Methoden.
- Klasse `java.util.Validator` übernimmt intern Parametervalidierung.
### Changed
- Objektvariablen der `Zeichenmaschine`, die von Unterklassen genutzt werden sollen, sind nun statisch in `Constants`. Dadurch können auch andere Klasse, die von `Constants` erben ohne Umwege auf diese Werte zugreifen (z.B. `width`/`height` der Zeichenleinwand).

View File

@ -0,0 +1,152 @@
package schule.ngb.zm.util;
import java.util.Objects;
import java.util.function.Predicate;
import java.util.function.Supplier;
public class Validator {
public static final <T> T requireNotNull( T obj ) {
return Objects.requireNonNull(obj);
}
public static final <T> T requireNotNull( T obj, CharSequence msg ) {
return Objects.requireNonNull(obj, msg::toString);
}
public static final <T> T requireNotNull( T obj, Supplier<String> msg ) {
return Objects.requireNonNull(obj, msg);
}
public static final String requireNotEmpty( String str ) {
return requireNotEmpty(str, (Supplier<String>)null);
}
public static final String requireNotEmpty( String str, CharSequence msg ) {
return requireNotEmpty(str, msg::toString);
}
public static final String requireNotEmpty( String str, Supplier<String> msg ) {
if( str.isEmpty() )
throw new IllegalArgumentException(msg == null ? String.format("Parameter may not be empty string (<%s> provided)", str) : msg.get());
return str;
}
public static final int requirePositive( int i ) {
return requirePositive(i, (Supplier<String>)null);
}
public static final int requirePositive( int i, CharSequence msg ) {
return requirePositive(i, msg::toString);
}
public static final int requirePositive( int i, Supplier<String> msg ) {
if( i <= 0 )
throw new IllegalArgumentException(msg == null ? String.format("Parameter must be positive (<%d> provided)", i) : msg.get());
return i;
}
public static final int requireNotNegative( int i ) {
return requireNotNegative(i, (Supplier<String>)null);
}
public static final int requireNotNegative( int i, CharSequence msg ) {
return requireNotNegative(i, msg::toString);
}
public static final int requireNotNegative( int i, Supplier<String> msg ) {
if( i < 0 )
throw new IllegalArgumentException(msg == null ? String.format("Parameter may not be negative (<%d> provided)", i) : msg.get());
return i;
}
public static final int requireInRange( int i, int min, int max ) {
return requireInRange(i, min, max, (Supplier<String>)null);
}
public static final int requireInRange( int i, int min, int max, CharSequence msg ) {
return requireInRange(i, min, max, msg::toString);
}
public static final int requireInRange( int i, int min, int max, Supplier<String> msg ) {
if( i < min || i > max )
throw new IllegalArgumentException(msg == null ? String.format("Parameter out of range <%d> to <%d> (<%d> provided)", min, max, i) : msg.get());
return i;
}
public static final double requirePositive( double i ) {
return requirePositive(i, (Supplier<String>)null);
}
public static final double requirePositive( double i, CharSequence msg ) {
return requirePositive(i, msg::toString);
}
public static final double requirePositive( double i, Supplier<String> msg ) {
if( i <= 0 )
throw new IllegalArgumentException(msg == null ? String.format("Parameter must be positive (<%f> provided)", i) : msg.get());
return i;
}
public static final double requireNotNegative( double i ) {
return requireNotNegative(i, (Supplier<String>)null);
}
public static final double requireNotNegative( double i, CharSequence msg ) {
return requireNotNegative(i, msg::toString);
}
public static final double requireNotNegative( double i, Supplier<String> msg ) {
if( i < 0 )
throw new IllegalArgumentException(msg == null ? String.format("Parameter may not be negative (<%f> provided)", i) : msg.get());
return i;
}
public static final double requireInRange( double i, double min, double max ) {
return requireInRange(i, min, max, (Supplier<String>)null);
}
public static final double requireInRange( double i, double min, double max, CharSequence msg ) {
return requireInRange(i, min, max, msg::toString);
}
public static final double requireInRange( double i, double min, double max, Supplier<String> msg ) {
if( i < min || i > max )
throw new IllegalArgumentException(msg == null ? String.format("Parameter out of range <%f> to <%f> (<%f> provided)", min, max, i) : msg.get());
return i;
}
/*
public static final <N extends Number> N requirePositive( N num, Supplier<String> msg ) {
if( num.doubleValue() <= 0 )
throw new IllegalArgumentException(msg == null ? String.format("Parameter must be positive (<%s> provided)", num.toString()) : msg.get());
return num;
}
public static final <N extends Number> N requireNotNegative( N num, Supplier<String> msg ) {
if( num.doubleValue() < 0 )
throw new IllegalArgumentException(msg == null ? String.format("Parameter may not be negative (<%s> provided)", num.toString()) : msg.get());
return num;
}
public static final <N extends Number> N requireInRange( N num, N min, N max, Supplier<String> msg ) {
if( num.doubleValue() < min.doubleValue() || num.doubleValue() > max.doubleValue() )
throw new IllegalArgumentException(msg == null ? String.format("Parameter out of range <%s> to <%s> (<%s> provided)", min.toString(), max.toString(), num.toString()) : msg.get());
return num;
}
*/
public static final <T> T[] requireNotEmpty( T[] arr, Supplier<String> msg ) {
return requireSize(arr, 0, ()->"Parameter array may not be empty");
}
public static final <T> T[] requireSize( T[] arr, int size, Supplier<String> msg ) {
if( arr.length != size )
throw new IllegalArgumentException(msg == null ? String.format("Parameter array must have <%d> elements (<%d> provided)", size) : msg.get());
return arr;
}
private Validator() {
}
}

View File

@ -0,0 +1,127 @@
package schule.ngb.zm.util;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class ValidatorTest {
@Test
void requireNotNull() {
StringBuilder sb = new StringBuilder("Message");
Object o1 = new Object();
assertEquals(o1, Validator.requireNotNull(o1));
assertEquals(o1, Validator.requireNotNull(o1, "Message"));
assertEquals(o1, Validator.requireNotNull(o1, sb));
assertEquals(o1, Validator.requireNotNull(o1, ()->"Message"));
String o2 = null;
assertThrowsExactly(NullPointerException.class, () -> Validator.requireNotNull(o2));
assertThrowsExactly(NullPointerException.class, () -> Validator.requireNotNull(o2, "Message"));
assertThrowsExactly(NullPointerException.class, () -> Validator.requireNotNull(o2, ()->"Message"));
}
@Test
void requireNotEmpty() {
StringBuilder sb = new StringBuilder("Message");
String s1 = "Content";
assertEquals(s1, Validator.requireNotEmpty(s1));
assertEquals(s1, Validator.requireNotEmpty(s1, "Message"));
assertEquals(s1, Validator.requireNotEmpty(s1, sb));
assertEquals(s1, Validator.requireNotEmpty(s1, ()->"Message"));
String s2 = "";
assertThrowsExactly(IllegalArgumentException.class, () -> Validator.requireNotEmpty(s2));
assertThrowsExactly(IllegalArgumentException.class, () -> Validator.requireNotEmpty(s2, "Message"));
assertThrowsExactly(IllegalArgumentException.class, () -> Validator.requireNotEmpty(s2, ()->"Message"));
}
@Test
void requirePositive() {
int i = 1;
assertEquals(i, Validator.requirePositive(i));
assertEquals(i, Validator.requirePositive(i, "Message"));
assertEquals(i, Validator.requirePositive(i, ()->"Message"));
assertThrowsExactly(IllegalArgumentException.class, () -> Validator.requirePositive(i-1));
assertThrowsExactly(IllegalArgumentException.class, () -> Validator.requirePositive(i-1, "Message"));
assertThrowsExactly(IllegalArgumentException.class, () -> Validator.requirePositive(i-1, ()->"Message"));
double k = 1.0;
assertEquals(k, Validator.requirePositive(i));
assertEquals(k, Validator.requirePositive(i, "Message"));
assertEquals(k, Validator.requirePositive(i, ()->"Message"));
assertThrowsExactly(IllegalArgumentException.class, () -> Validator.requirePositive(k-1.0));
assertThrowsExactly(IllegalArgumentException.class, () -> Validator.requirePositive(k-1.0, "Message"));
assertThrowsExactly(IllegalArgumentException.class, () -> Validator.requirePositive(k-1.0, ()->"Message"));
}
@Test
void requireNotNegative() {
int i = 0;
assertEquals(i, Validator.requireNotNegative(i));
assertEquals(i, Validator.requireNotNegative(i, "Message"));
assertEquals(i, Validator.requireNotNegative(i, ()->"Message"));
assertThrowsExactly(IllegalArgumentException.class, () -> Validator.requireNotNegative(i-1));
assertThrowsExactly(IllegalArgumentException.class, () -> Validator.requireNotNegative(i-1, "Message"));
assertThrowsExactly(IllegalArgumentException.class, () -> Validator.requireNotNegative(i-1, ()->"Message"));
double k = 0.0;
assertEquals(k, Validator.requireNotNegative(i));
assertEquals(k, Validator.requireNotNegative(i, "Message"));
assertEquals(k, Validator.requireNotNegative(i, ()->"Message"));
assertThrowsExactly(IllegalArgumentException.class, () -> Validator.requireNotNegative(k-1.0));
assertThrowsExactly(IllegalArgumentException.class, () -> Validator.requireNotNegative(k-1.0, "Message"));
assertThrowsExactly(IllegalArgumentException.class, () -> Validator.requireNotNegative(k-1.0, ()->"Message"));
}
@Test
void requireInRange() {
int min = 50, max = 100;
for( int ii = min; ii < max; ii++ ) {
final int i = ii;
assertEquals(i, Validator.requireInRange(i, min, max));
assertEquals(i, Validator.requireInRange(i, min, max, "Message"));
assertEquals(i, Validator.requireInRange(i, min, max, () -> "Message"));
}
for( int ii = 0; ii < min; ii++ ) {
final int i = ii;
assertThrowsExactly(IllegalArgumentException.class, () -> Validator.requireInRange(i, min, max));
assertThrowsExactly(IllegalArgumentException.class, () -> Validator.requireInRange(i, min, max));
assertThrowsExactly(IllegalArgumentException.class, () -> Validator.requireInRange(i, min, max));
}
for( int ii = max+1; ii < 2*max; ii++ ) {
final int i = ii;
assertThrowsExactly(IllegalArgumentException.class, () -> Validator.requireInRange(i, min, max));
assertThrowsExactly(IllegalArgumentException.class, () -> Validator.requireInRange(i, min, max));
assertThrowsExactly(IllegalArgumentException.class, () -> Validator.requireInRange(i, min, max));
}
double dmin = 50, dmax = 60;
for( double dd = dmin; dd < dmax; dd+=0.1 ) {
final double d = dd;
assertEquals(d, Validator.requireInRange(d, dmin, dmax));
assertEquals(d, Validator.requireInRange(d, dmin, dmax, "Message"));
assertEquals(d, Validator.requireInRange(d, dmin, dmax, () -> "Message"));
}
for( double dd = dmin-10.0; dd < dmin; dd+=0.1 ) {
final double d = dd;
assertThrowsExactly(IllegalArgumentException.class, () -> Validator.requireInRange(d, dmin, dmax));
assertThrowsExactly(IllegalArgumentException.class, () -> Validator.requireInRange(d, dmin, dmax));
assertThrowsExactly(IllegalArgumentException.class, () -> Validator.requireInRange(d, dmin, dmax));
}
for( double dd = dmax+0.1; dd < dmax+10.0; dd+=0.1 ) {
final double d = dd;
assertThrowsExactly(IllegalArgumentException.class, () -> Validator.requireInRange(d, dmin, dmax));
assertThrowsExactly(IllegalArgumentException.class, () -> Validator.requireInRange(d, dmin, dmax));
assertThrowsExactly(IllegalArgumentException.class, () -> Validator.requireInRange(d, dmin, dmax));
}
}
}