test(04-03): add failing tests for DefineValidation (name regex + componentwise min/max)

This commit is contained in:
2026-04-24 14:10:19 +02:00
parent 3070353579
commit 4b10dbce6c
@@ -0,0 +1,93 @@
package com.mythlane.gravityflip.command;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* Pure-data tests for {@link DefineValidation} — no Hytale runtime dependency.
*
* <p>Covers :
* <ul>
* <li>Name regex accepts alnum + underscore + dash, 1..32 chars.</li>
* <li>Name regex rejects blank, spaces, special chars, non-ASCII, over-length.</li>
* <li>Componentwise min/max return smallest/largest per axis.</li>
* <li>Inflate-max-by-1 convention (max block is INSIDE the AABB only if we add 1 per axis).</li>
* </ul>
*/
class DefineValidationTest {
// ---------- name regex ----------
@Test
void validName_acceptsAlnumUnderscoreDash() {
assertTrue(DefineValidation.isValidName("abc"));
assertTrue(DefineValidation.isValidName("my-zone_1"));
assertTrue(DefineValidation.isValidName("Z"));
assertTrue(DefineValidation.isValidName("a".repeat(32)));
assertTrue(DefineValidation.isValidName("ABC_123-xyz"));
}
@Test
void validName_rejectsNullEmptyBlankAndInvalidChars() {
assertFalse(DefineValidation.isValidName(null));
assertFalse(DefineValidation.isValidName(""));
assertFalse(DefineValidation.isValidName(" "));
assertFalse(DefineValidation.isValidName("my zone"));
assertFalse(DefineValidation.isValidName("a".repeat(33)));
assertFalse(DefineValidation.isValidName("name!"));
assertFalse(DefineValidation.isValidName("名前"));
assertFalse(DefineValidation.isValidName("../etc/passwd"));
assertFalse(DefineValidation.isValidName("has.dot"));
}
// ---------- componentwise min/max ----------
@Test
void componentwiseMin_returnsSmallestPerAxis() {
int[] a = {5, 10, -3};
int[] b = {1, 20, -7};
assertArrayEquals(new int[]{1, 10, -7}, DefineValidation.componentwiseMin(a, b));
}
@Test
void componentwiseMax_returnsLargestPerAxis() {
int[] a = {5, 10, -3};
int[] b = {1, 20, -7};
assertArrayEquals(new int[]{5, 20, -3}, DefineValidation.componentwiseMax(a, b));
}
@Test
void componentwise_orderIndependent() {
int[] a = {1, 2, 3};
int[] b = {4, 5, 6};
assertArrayEquals(
DefineValidation.componentwiseMin(a, b),
DefineValidation.componentwiseMin(b, a));
assertArrayEquals(
DefineValidation.componentwiseMax(a, b),
DefineValidation.componentwiseMax(b, a));
}
// ---------- inflate-max convention (block inclusion) ----------
/**
* A block occupies the cube between (x,y,z) and (x+1,y+1,z+1). If an AABB's max is the
* raw block coord (maxBlockX, maxBlockY, maxBlockZ), a player standing on top of that
* block is OUTSIDE the AABB. We therefore inflate max by +1 per axis.
*/
@Test
void boxFromCorners_inflateMax_includesMaxBlock() {
int[] mn = {0, 64, 0};
int[] mx = {10, 70, 10};
// Player feet at (10.5, 70.5, 10.5) — standing in the maxBlock cube.
double px = 10.5, py = 70.5, pz = 10.5;
// Without inflate: max = (10,70,10) — player OUT.
assertFalse(px < mx[0] && py < mx[1] && pz < mx[2]);
// With inflate: max = (11,71,11) — player IN.
int[] mxInflated = {mx[0] + 1, mx[1] + 1, mx[2] + 1};
assertTrue(px < mxInflated[0] && py < mxInflated[1] && pz < mxInflated[2]);
}
}