Extend tersting for Passable + move NCPCore tests to NCPPlugin.

Tests (partly re-) added and extended, classes moved, some methods
moved.

Some tests will fail if you don't use the next commit as well.
This commit is contained in:
asofold 2014-08-05 18:49:35 +02:00
parent 5245dcca9a
commit 4e9e935b1e
7 changed files with 169 additions and 97 deletions

View File

@ -19,6 +19,9 @@ public class FakeBlockCache extends BlockCache {
/** Cached data values. */
private final CoordMap<Integer> dataMapStored = new CoordMap<Integer>(23);
/** Cached shape values. */
private final CoordMap<double[]> boundsMapStored = new CoordMap<double[]>(23);
/**
* Set with data=0 and bounds=full.
* @param x
@ -30,8 +33,17 @@ public class FakeBlockCache extends BlockCache {
set(x, y, z, BlockProperties.getId(type));
}
/** Cached shape values. */
private final CoordMap<double[]> boundsMapStored = new CoordMap<double[]>(23);
/**
* Set with data=0-
* @param x
* @param y
* @param z
* @param type
* @param bounds
*/
public void set(int x, int y, int z, Material type, double[] bounds) {
set(x, y, z, BlockProperties.getId(type), 0, bounds);
}
/**
* Set with data=0 and bounds=full.

View File

@ -1,7 +1,5 @@
package fr.neatmonster.nocheatplus.test;
import static org.junit.Assert.fail;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@ -12,8 +10,6 @@ import fr.neatmonster.nocheatplus.config.DefaultConfig;
import fr.neatmonster.nocheatplus.config.RawConfigFile;
import fr.neatmonster.nocheatplus.config.WorldConfigProvider;
import fr.neatmonster.nocheatplus.utilities.BlockProperties;
import fr.neatmonster.nocheatplus.utilities.RayTracing;
import fr.neatmonster.nocheatplus.utilities.TrigUtil;
/**
* Auxiliary classes packed in here.
@ -62,47 +58,4 @@ public class BlockTests {
BlockProperties.init(new MCAccessBukkit(), new DefaultConfigWorldConfigProvider());
}
public static void runCoordinates(RayTracing rt, double[] setup, boolean expectCollide, boolean expectNotCollide, double stepsManhattan, boolean reverse, String tag) {
if (reverse) {
rt.set(setup[3], setup [4], setup[5], setup[0], setup[1], setup[2]);
tag += "/reversed";
} else {
rt.set(setup[0], setup[1], setup[2], setup[3], setup [4], setup[5]);
}
rt.loop();
if (rt.collides()) {
if (expectNotCollide) {
fail("Expect not to collide, "+ tag + ".");
}
} else {
if (expectCollide) {
fail("Expect to collide, "+ tag + ".");
}
}
if (stepsManhattan > 0.0) {
final double maxSteps = stepsManhattan * TrigUtil.manhattan(setup[0], setup[1], setup[2], setup[3], setup[4], setup[5]);
if ((double) rt.getStepsDone() > maxSteps) {
fail("Expect less than " + maxSteps + " steps for moving straight through a block, "+ tag + ".");
}
}
}
/**
*
* @param rt
* @param setups Array of Arrays of 6 doubles as argument for RayTracing.set(...).
* @param stepsManhattan
* @return Int array of size 2: {not colliding, colliding}
*/
public static void runCoordinates(RayTracing rt, double[][] setups, boolean expectCollide, boolean expectNotCollide, double stepsManhattan, boolean testReversed) {
for (int i = 0; i < setups.length; i++) {
double[] setup = setups[i];
runCoordinates(rt, setup, expectCollide, expectNotCollide, stepsManhattan, false, "index=" + i);
if (testReversed) {
// Reverse.
runCoordinates(rt, setup, expectCollide, expectNotCollide, stepsManhattan, true, "index=" + i);
}
}
}
}

View File

@ -1,7 +1,5 @@
package fr.neatmonster.nocheatplus.test;
import static org.junit.Assert.fail;
import org.bukkit.Material;
import org.junit.Test;
@ -11,7 +9,12 @@ import fr.neatmonster.nocheatplus.utilities.PassableRayTracing;
public class TestPassableRayTracing {
// TODO: Moving into a block, moving out of a block, just moving on ground, moving up stairs etc.
// TODO: Moving into a block,
// TODO: Moving out of a block
// TODO: Moving horizontally on various kinds of ground (normal, half blocks)
// TODO: Moving up stairs etc ?
// TODO: From ground and onto ground moves, onto-edge moves (block before edge, into block, etc).
// TODO: Randomized tests (Collide with inner sphere, not collide with outer sphere).
public TestPassableRayTracing() {
LogUtil.setUseBukkitLogger(false);
@ -24,13 +27,14 @@ public class TestPassableRayTracing {
FakeBlockCache bc = new FakeBlockCache();
PassableRayTracing rt = new PassableRayTracing();
rt.setBlockCache(bc);
rt.set(0.5, 0.5, -0.5, 0.5, 0.5, 1.5);
double[] coords = new double[]{0.5, 0.5, -0.5, 0.5, 0.5, 1.5};
rt.set(coords[0], coords[1], coords[2], coords[3], coords[4], coords[5]);
rt.loop();
if (rt.collides()) {
fail("Expect not to collide when moving through a block.");
TestRayTracing.doFail("Expect not to collide when moving through a block.", coords);
}
if (rt.getStepsDone() > 4) {
fail("Expect less than 4 steps for moving straight through a block of air.");
TestRayTracing.doFail("Expect less than 4 steps for moving straight through a block of air.", coords);
}
rt.cleanup();
bc.cleanup();
@ -58,41 +62,99 @@ public class TestPassableRayTracing {
// TODO: More of each and other... + generic set-ups?
};
BlockTests.runCoordinates(rt, setups, true, false, 2.0, true);
TestRayTracing.runCoordinates(rt, setups, true, false, 3.0, true);
rt.cleanup();
bc.cleanup();
}
// /**
// * Moving diagonally through an "empty corner", seen from above:<br>
// * ox<br>
// * xo
// */
// @Test
// public void testEmptyCorner() {
// FakeBlockCache bc = new FakeBlockCache();
// // The "empty corner" setup.
// bc.set(10, 70, 10, Material.STONE);
// bc.set(11, 70, 11, Material.STONE);
// // Ground.
// for (int x = 9; x < 13; x++) {
// for (int z = 9; z < 13; z++) {
// bc.set(x, 69, z, Material.STONE);
// }
// }
// PassableRayTracing rt = new PassableRayTracing();
// rt.setBlockCache(bc);
// // TODO: More Directions, over a corner, sides, etc.
// double[][] setups = new double[][] {
// // Slightly off the middle (11, y, 11)
// {11.4, 70.0, 10.4, 10.6, 70.0, 11.4},
// // Going exactly through the middle (11, y, 11)
// {11.4, 70.0, 10.6, 10.6, 70.0, 11.4},
// {11.5, 70.0, 10.5, 10.5, 70.0, 11.5},
// };
// BlockTests.runCoordinates(rt, setups, true, false, 2.0, true);
// rt.cleanup();
// bc.cleanup();
// }
/**
* Moving diagonally through an "empty corner", seen from above:<br>
* ox<br>
* xo
*/
@Test
public void testEmptyCorner() {
FakeBlockCache bc = new FakeBlockCache();
// The "empty corner" setup.
bc.set(10, 70, 10, Material.STONE);
bc.set(11, 70, 11, Material.STONE);
// Ground.
for (int x = 9; x < 13; x++) {
for (int z = 9; z < 13; z++) {
bc.set(x, 69, z, Material.STONE);
}
}
PassableRayTracing rt = new PassableRayTracing();
rt.setBlockCache(bc);
// TODO: More Directions, over a corner, sides, etc.
double[][] setups = new double[][] {
// Slightly off the middle (11, y, 11)
{11.4, 70.0, 10.4, 10.6, 70.0, 11.4},
// Going exactly through the middle (11, y, 11)
{11.4, 70.0, 10.6, 10.6, 70.0, 11.4},
{11.5, 70.0, 10.5, 10.5, 70.0, 11.5},
};
TestRayTracing.runCoordinates(rt, setups, true, false, 3.0, true);
rt.cleanup();
bc.cleanup();
}
@Test
public void testGround() {
FakeBlockCache bc = new FakeBlockCache();
// Ground using full blocks.
for (int x = 0; x < 16; x++) {
for (int z = 0; z < 16; z++) {
bc.set(x, 65, z, Material.STONE);
}
}
PassableRayTracing rt = new PassableRayTracing();
rt.setBlockCache(bc);
// TODO: More Directions, also from air underneath to ground).
double[][] noCollision = new double[][] {
{1.3, 66.0, 2.43, 5.25, 66.0, 7.12},
};
TestRayTracing.runCoordinates(rt, noCollision, false, true, 3.0, true);
double[][] shouldCollide = new double[][] {
{1.3, 65.1, 2.43, 2.3, 65.1, 4.43},
{1.3, 65.0, 2.43, 2.3, 65.0, 4.43},
{1.3, 66.0, 2.43, 1.3, 65.9, 2.43},
{1.3, 66.0, 2.43, 5.25, 65.9, 7.12},
{1.3, 65.4, 2.43, 1.3, 65.4, 2.43}, // No distance.
};
TestRayTracing.runCoordinates(rt, shouldCollide, true, false, 3.0, true);
rt.cleanup();
bc.cleanup();
}
@Test
public void testGroundSteps() {
FakeBlockCache bc = new FakeBlockCache();
// Ground using 0.5 high step blocks.
final double[] stepBounds = new double[]{0.0, 0.0, 0.0, 1.0, 0.5, 1.0};
for (int x = 0; x < 16; x++) {
for (int z = 0; z < 16; z++) {
// STONE = HACK (CompatBukkit block-flags problem).
bc.set(x, 65, z, Material.STONE, stepBounds);
}
}
PassableRayTracing rt = new PassableRayTracing();
rt.setBlockCache(bc);
// TODO: More Directions, also from air underneath to ground).
double[][] noCollision = new double[][] {
{1.3, 65.5, 2.43, 5.25, 65.5, 7.12},
};
TestRayTracing.runCoordinates(rt, noCollision, false, true, 3.0, true);
double[][] shouldCollide = new double[][] {
{1.3, 65.1, 2.43, 2.3, 65.1, 7.43},
{1.3, 65.0, 2.43, 2.3, 65.0, 7.43},
{1.3, 65.5, 2.43, 1.3, 65.4, 2.43},
{1.3, 65.5, 2.43, 5.25, 65.4, 7.12},
{1.3, 65.4, 2.43, 1.3, 65.4, 2.43}, // No distance.
};
TestRayTracing.runCoordinates(rt, shouldCollide, true, false, 3.0, true);
rt.cleanup();
bc.cleanup();
}
}

View File

@ -9,6 +9,7 @@ import org.junit.Test;
import fr.neatmonster.nocheatplus.utilities.RayTracing;
import fr.neatmonster.nocheatplus.utilities.StringUtil;
import fr.neatmonster.nocheatplus.utilities.TrigUtil;
import fr.neatmonster.nocheatplus.utilities.build.BuildParameters;
public class TestRayTracing {
@ -89,9 +90,9 @@ public class TestRayTracing {
step = 0;
}
private boolean ignEdge(double offset, double dTotal){
return offset == 1 && dTotal > 0 || offset == 0 && dTotal < 0;
}
// private boolean ignEdge(double offset, double dTotal){
// return offset == 1 && dTotal > 0 || offset == 0 && dTotal < 0;
// }
@Override
protected boolean step(int blockX, int blockY, int blockZ, double oX, double oY, double oZ, double dT) {
@ -101,12 +102,13 @@ public class TestRayTracing {
if (dT < 0.0){
doFail("dT < 0 at t = " + StringUtil.fdec3.format(t), coords);
}
if (dT == 0 && 1.0 - (t + dT) > tol){
if (!ignEdge(oX, dX) && !ignEdge(oY, dY) && !ignEdge(oZ, dZ)){
doFail("Premature dT = 0 at t = " + StringUtil.fdec3.format(t), coords);
}
}
// TODO: Check if this check makes sense at all (dT=0 happens during multi-transitions.)l.
// if (dT == 0.0 && 1.0 - (t + dT) > tol){
// if (!ignEdge(oX, dX) && !ignEdge(oY, dY) && !ignEdge(oZ, dZ)){
// doFail("Premature dT = 0 at t = " + StringUtil.fdec3.format(t), coords);
// }
// }
checkOffset(oX, "x");
checkOffset(oY, "y");
@ -193,7 +195,7 @@ public class TestRayTracing {
@Test
public void testNumberOfSteps(){
// Hand picked stuff.
checkNumberOfSteps(new double[]{0.5, 0.5, 0.5, 1.5, -0.5, 1.5}, 2);
checkNumberOfSteps(new double[]{0.5, 0.5, 0.5, 1.5, -0.5, 1.5}, 4);
}
@Test
@ -226,4 +228,47 @@ public class TestRayTracing {
// TODO: Add tests for typical coordinates a with interact, passable.
}
public static void runCoordinates(RayTracing rt, double[] setup, boolean expectCollide, boolean expectNotCollide, double stepsManhattan, boolean reverse, String tag) {
if (reverse) {
rt.set(setup[3], setup [4], setup[5], setup[0], setup[1], setup[2]);
tag += "/reversed";
} else {
rt.set(setup[0], setup[1], setup[2], setup[3], setup [4], setup[5]);
}
rt.loop();
if (rt.collides()) {
if (expectNotCollide) {
doFail("Expect not to collide, "+ tag + ".", setup);
}
} else {
if (expectCollide) {
doFail("Expect to collide, "+ tag + ".", setup);
}
}
if (stepsManhattan > 0.0) {
final double maxSteps = stepsManhattan * Math.max(1.0, TrigUtil.manhattan(setup[0], setup[1], setup[2], setup[3], setup[4], setup[5]));
if ((double) rt.getStepsDone() > maxSteps) {
doFail("Expect less than " + maxSteps + " steps, "+ tag + ".", setup);
}
}
}
/**
*
* @param rt
* @param setups Array of Arrays of 6 doubles as argument for RayTracing.set(...).
* @param stepsManhattan
* @return Int array of size 2: {not colliding, colliding}
*/
public static void runCoordinates(RayTracing rt, double[][] setups, boolean expectCollide, boolean expectNotCollide, double stepsManhattan, boolean testReversed) {
for (int i = 0; i < setups.length; i++) {
double[] setup = setups[i];
runCoordinates(rt, setup, expectCollide, expectNotCollide, stepsManhattan, false, "index=" + i);
if (testReversed) {
// Reverse.
runCoordinates(rt, setup, expectCollide, expectNotCollide, stepsManhattan, true, "index=" + i);
}
}
}
}