Feature/1.17 (#1120)

* start v6

* Update classes to v6 method signatures

* change rootVersion to signify p2v6 compat

* Use 16 as toolchain version but target 11 for build output

* add minimessage as api

* Require v6 and don't attempt to "setup" hook from FAWE

* Address comments

* *address /all/ comments

* FAWE classes should only act as a delegate

* Uppercase logger

* Settings for v6-hook have moved to P2-v6, remove unneeded if statements

* Rename classes to Delegate

* add whenDone task to setCuboids

* Remove bad spaces

* Fix plot swap

* Initial work on 1.17 support

* Remove data versions from the Bukkit adapters (#1507)

* Remove data versions from the Bukkit adapters

* Don't allow saving schematics without an adapter in place on Bukkit.

* Removed confusing line

(cherry picked from commit 2056218b4a8644836b1d127105dfa289e9cdbc1c)

* More progress

* Fix chunk sending

* Repackage from com.boydti to com.fastasyncworldedit.<module> (#1119)

* Preliminary work on repackaging

* Rename build artifacts matching our pattern

* Finish up repackaging

* Fix a few field accesses and old imports

* Dirty fix for chunks container ChunkSections outside of 0-15

* Correctly read from NibbleArrays for lighting

* Fix getSections and BlockMaterial for 1.17

* Fix writing blocks to the world.
 - The issue isn't the presence of a "-1" chunk, it's the constructor for ChunkSection requiring the layer (0 to 15) rather than the y chord

* Fix more field accesses

* More work towards 1.17

* Update Upstream

a57f66f Fix watchdog, add negative y support. (1782)

* Add azalea tree to `/tool tree`

* Don't define toolchain twice

* Repackage GriefDefender

* Relocate under new namespace

* Bye bye ecma left overs

* Add 1.17 to issue templates and instructions

* Move to adventure-nbt (#918)

* Initial work for adventure-nbt

* Some more FAWE specific stuff

* Fix erroneous deprecation check

* Workflow change

* Continued merging all adventure NBT related changes

* Continued merging all adventure NBT related changes

* Made a constructor public again

This needs to be public for BlockTransformExtent.java

* Finished converting all NBT data to adventure.

* Make this compile

* Fix conflicts

Co-authored-by: Matt <4009945+MattBDev@users.noreply.github.com>

* Update adapters to 1.17

* Change build prefix to 1.17

* Move more nms classes to adapters

* Move left over nms classes

* Move Spigot 1.17 class

* Remove unneeded adapter loader code
The loader will find the appropriate class now itself

* Update adapters

* Update adapters

* Lazy fix tests

* Update adapters

* Update Upstream

43da91a Remove method reflection for getMinHeight in BukkitWorld. (1796)

* Relocate adventure-nbt under proper namespace

* Add LazyCompoundTag as a non-version-specific class to be used by adapters

* Better integration between old NBT and Adventure NBT - begin fixing the issues seen recently

* Correctly NBT conversion method

* LazyCompoundTags should actually be overriding and correctly returning a CompoundBinaryTag.

* Update worldedit-adapters
Fixes #1141

* Remove unnecessary massive lag machine

* Refactor apply to applyBlock in subclasses

* applyBlock should be overriden by all subclasses.
Default apply to applyBlock

* Closes #1130 Closes #1132

* Squashed commit of the following:

commit a9bfa1a07c77083c844a0c3ba62f4bd94bed107c
Author: NotMyFault <mc.cache@web.de>
Date:   Sun Jun 27 21:53:21 2021 +0200

    [ci skip] Update gradle wrapper validation

commit aa7471f95317d28a16f62e4b200de8d0fea2fa95
Author: Matthew Miller <mnmiller1@me.com>
Date:   Sat Oct 10 15:49:13 2020 +1000

    Add ^x,y,z relative offset support to the offset parser (#1545)

    * Add ^x,y,z relative offset support to the offset parser

    * Wrap in a try-catch

    (cherry picked from commit 28bdf7ff9254bbc85bb4f5f792b303943a3930a8)

* Add `fawe.error.schematic.not.found` translation key

* Update Upstream

728a152 Skip notify if chunk section doesn't exist (1794)

* Fixed #1157

* Add a null check to prevent NPE in nbt code

* Update adapters

* Update Upstream

fbb047a Optimize legacy schematic loading (1808)

* Hurr durr I don't want to update Java

* Update Upstream

0790e6e Fix CLI Mess (1811)

* Fixes #1160

* Expose minimessage transitively thru PlotSquared

Touches #32

* [ci skip] Remove unneeded maven repository

* Steal tab completion from PlotSquared for P2 related commands

* Don't error on startup when building locally

Co-Authored-By: goldfishapp <8278196+goldfishapp@users.noreply.github.com>

* [ci skip] Update gh actions to Java 16

* Update textures to grab 1.17 jar

Co-authored-by: NotMyFault <mc.cache@web.de>
Co-authored-by: SirYwell <hannesgreule@outlook.de>
Co-authored-by: Matthew Miller <mnmiller1@me.com>
Co-authored-by: Matt <4009945+MattBDev@users.noreply.github.com>
Co-authored-by: goldfishapp <8278196+goldfishapp@users.noreply.github.com>
This commit is contained in:
dordsor21
2021-07-01 21:16:25 +01:00
committed by GitHub
parent b0c0689887
commit aa3ae63682
798 changed files with 5101 additions and 16727 deletions

View File

@ -25,8 +25,10 @@ import com.sk89q.worldedit.event.platform.PlatformsRegisteredEvent;
import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.extension.platform.Preference;
import com.sk89q.worldedit.util.test.ResourceLockKeys;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.parallel.ResourceLock;
import java.util.function.Function;
import java.util.stream.Collectors;
@ -39,13 +41,14 @@ import static org.mockito.Mockito.when;
/**
* Common setup code for expression tests.
*/
@ResourceLock(ResourceLockKeys.WORLDEDIT_PLATFORM)
class BaseExpressionTest {
static double readSlot(Expression expr, String name) {
return expr.getSlots().getSlotValue(name).orElseThrow(IllegalStateException::new);
}
private Platform mockPlat = mock(Platform.class);
private final Platform mockPlat = mock(Platform.class);
@BeforeEach
void setup() {
@ -92,22 +95,22 @@ class BaseExpressionTest {
@Override
public int getBlockTypeAbs(double x, double y, double z) {
return (int) x*10;
return (int) x * 10;
}
@Override
public int getBlockDataAbs(double x, double y, double z) {
return (int) y*10;
return (int) y * 10;
}
@Override
public int getBlockTypeRel(double x, double y, double z) {
return (int) x*100;
return (int) x * 100;
}
@Override
public int getBlockDataRel(double x, double y, double z) {
return (int) y*100;
return (int) y * 100;
}
});

View File

@ -19,18 +19,25 @@
package com.sk89q.worldedit.math;
import com.sk89q.worldedit.util.test.VariedVectors;
import com.sk89q.worldedit.util.test.VariedVectorGenerator;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
@DisplayName("A 3D block vector")
public class BlockVector3Test {
@VariedVectors.Test(capToVanilla = true, divisionsXZ = 50, divisionsY = 50)
@Test
@DisplayName("survives a round-trip through long-packing")
void longPackingRoundTrip(BlockVector3 vec) {
assertEquals(vec, BlockVector3.fromLongPackedForm(vec.toLongPackedForm()));
void longPackingRoundTrip() {
new VariedVectorGenerator(true, 25, 25).makeVectorsStream()
.forEach(vec ->
assertEquals(
vec,
BlockVector3.fromLongPackedForm(vec.toLongPackedForm())
)
);
}
}
}

View File

@ -17,13 +17,66 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/*
package com.sk89q.worldedit.util.collection;
import com.google.common.collect.ImmutableMap;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.event.platform.PlatformsRegisteredEvent;
import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.extension.platform.PlatformManager;
import com.sk89q.worldedit.extension.platform.Preference;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.registry.Registry;
import com.sk89q.worldedit.util.test.ResourceLockKeys;
import com.sk89q.worldedit.util.test.VariedVectorGenerator;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
import com.sk89q.worldedit.world.registry.BundledRegistries;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.parallel.Execution;
import org.junit.jupiter.api.parallel.ExecutionMode;
import org.junit.jupiter.api.parallel.ResourceLock;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.lang.reflect.Field;
import java.util.AbstractMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assumptions.assumeFalse;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
@Execution(ExecutionMode.CONCURRENT)
@ResourceLock(ResourceLockKeys.WORLDEDIT_PLATFORM)
@DisplayName("An ordered block map")
class BlockMapTest {
/*
private static final Platform MOCKED_PLATFORM = mock(Platform.class);
@BeforeAll
@ -31,8 +84,8 @@ class BlockMapTest {
when(MOCKED_PLATFORM.getRegistries()).thenReturn(new BundledRegistries() {
});
when(MOCKED_PLATFORM.getCapabilities()).thenReturn(
Stream.of(Capability.values())
.collect(Collectors.toMap(Function.identity(), __ -> Preference.NORMAL))
Stream.of(Capability.values())
.collect(Collectors.toMap(Function.identity(), __ -> Preference.NORMAL))
);
PlatformManager platformManager = WorldEdit.getInstance().getPlatformManager();
platformManager.register(MOCKED_PLATFORM);
@ -64,21 +117,22 @@ class BlockMapTest {
private final BaseBlock air = checkNotNull(BlockTypes.AIR).getDefaultState().toBaseBlock();
private final BaseBlock oakWood = checkNotNull(BlockTypes.OAK_WOOD).getDefaultState().toBaseBlock();
private final BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
private AutoCloseable mocks;
@BeforeEach
void setUp() {
MockitoAnnotations.initMocks(this);
mocks = MockitoAnnotations.openMocks(this);
}
@AfterEach
void tearDown() {
map.clear();
void tearDown() throws Exception {
mocks.close();
}
@Test
@DisplayName("throws ClassCastException if invalid argument to get")
void throwsFromGetOnInvalidArgument() {
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
assertThrows(ClassCastException.class, () -> map.get(""));
}
@ -89,30 +143,35 @@ class BlockMapTest {
@Test
@DisplayName("is empty")
void isEmpty() {
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
assertEquals(0, map.size());
}
@Test
@DisplayName("is equal to another empty map")
void isEqualToEmptyMap() {
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
assertEquals(ImmutableMap.of(), map);
}
@Test
@DisplayName("has the same hashCode as another empty map")
void isHashCodeEqualToEmptyMap() {
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
assertEquals(ImmutableMap.of().hashCode(), map.hashCode());
}
@Test
@DisplayName("returns `null` from get")
void returnsNullFromGet() {
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
assertNull(map.get(BlockVector3.ZERO));
}
@Test
@DisplayName("contains no keys")
void containsNoKeys() {
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
assertEquals(0, map.keySet().size());
assertFalse(map.containsKey(BlockVector3.ZERO));
}
@ -120,6 +179,7 @@ class BlockMapTest {
@Test
@DisplayName("contains no values")
void containsNoValues() {
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
assertEquals(0, map.values().size());
assertFalse(map.containsValue(air));
}
@ -127,32 +187,41 @@ class BlockMapTest {
@Test
@DisplayName("contains no entries")
void containsNoEntries() {
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
assertEquals(0, map.entrySet().size());
}
@Test
@DisplayName("returns the default value from getOrDefault")
void returnsDefaultFromGetOrDefault() {
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
assertEquals(air, map.getOrDefault(BlockVector3.ZERO, air));
}
@Test
@DisplayName("never calls the forEach action")
void neverCallsForEachAction() {
map.forEach(biConsumer);
verifyNoMoreInteractions(biConsumer);
void neverCallsForEachAction() throws Exception {
try (AutoCloseable ignored = MockitoAnnotations.openMocks(this)) {
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
map.forEach(biConsumer);
verifyNoMoreInteractions(biConsumer);
}
}
@Test
@DisplayName("never calls the replaceAll function")
void neverCallsReplaceAllFunction() {
map.replaceAll(biFunction);
verifyNoMoreInteractions(biFunction);
void neverCallsReplaceAllFunction() throws Exception {
try (AutoCloseable ignored = MockitoAnnotations.openMocks(this)) {
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
map.replaceAll(biFunction);
verifyNoMoreInteractions(biFunction);
}
}
@Test
@DisplayName("inserts on putIfAbsent")
void insertOnPutIfAbsent() {
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
assertNull(map.putIfAbsent(BlockVector3.ZERO, air));
assertEquals(1, map.size());
assertEquals(air, map.get(BlockVector3.ZERO));
@ -161,18 +230,21 @@ class BlockMapTest {
@Test
@DisplayName("remove(key) returns null")
void removeKeyReturnsNull() {
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
assertNull(map.remove(BlockVector3.ZERO));
}
@Test
@DisplayName("remove(key, value) returns false")
void removeKeyValueReturnsFalse() {
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
assertFalse(map.remove(BlockVector3.ZERO, air));
}
@Test
@DisplayName("does nothing on replace")
void doesNothingOnReplace() {
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
assertNull(map.replace(BlockVector3.ZERO, air));
assertEquals(0, map.size());
assertFalse(map.replace(BlockVector3.ZERO, null, air));
@ -182,6 +254,7 @@ class BlockMapTest {
@Test
@DisplayName("inserts on computeIfAbsent")
void insertOnComputeIfAbsent() {
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
assertEquals(air, map.computeIfAbsent(BlockVector3.ZERO, k -> air));
assertEquals(1, map.size());
assertEquals(air, map.get(BlockVector3.ZERO));
@ -190,6 +263,7 @@ class BlockMapTest {
@Test
@DisplayName("inserts on compute")
void insertOnCompute() {
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
assertEquals(air, map.compute(BlockVector3.ZERO, (k, v) -> air));
assertEquals(1, map.size());
assertEquals(air, map.get(BlockVector3.ZERO));
@ -198,17 +272,21 @@ class BlockMapTest {
@Test
@DisplayName("does nothing on computeIfPresent")
void doesNothingOnComputeIfPresent() {
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
assertNull(map.computeIfPresent(BlockVector3.ZERO, (k, v) -> air));
assertEquals(0, map.size());
}
@Test
@DisplayName("inserts on merge, without calling merge function")
void insertsOnMerge() {
assertEquals(air, map.merge(BlockVector3.ZERO, air, mergeFunction));
assertEquals(1, map.size());
assertEquals(air, map.get(BlockVector3.ZERO));
verifyNoMoreInteractions(mergeFunction);
void insertsOnMerge() throws Exception {
try (AutoCloseable ignored = MockitoAnnotations.openMocks(this)) {
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
assertEquals(air, map.merge(BlockVector3.ZERO, air, mergeFunction));
assertEquals(1, map.size());
assertEquals(air, map.get(BlockVector3.ZERO));
verifyNoMoreInteractions(mergeFunction);
}
}
}
@ -217,328 +295,450 @@ class BlockMapTest {
@DisplayName("after having an entry added")
class AfterEntryAdded {
// Note: This section of tests would really benefit from
// being able to parameterize classes. It's not part of JUnit
// yet though: https://github.com/junit-team/junit5/issues/878
private final VariedVectorGenerator generator = new VariedVectorGenerator();
@VariedVectors.Test
@Test
@DisplayName("has a size of one")
void hasSizeOne(BlockVector3 vec) {
map.put(vec, air);
assertEquals(1, map.size());
void hasSizeOne() {
generator.makeVectorsStream().forEach(vec -> {
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
map.put(vec, air);
assertEquals(1, map.size());
});
}
@VariedVectors.Test
@Test
@DisplayName("is equal to another map with the same entry")
void isEqualToSimilarMap(BlockVector3 vec) {
map.put(vec, air);
assertEquals(ImmutableMap.of(vec, air), map);
void isEqualToSimilarMap() {
generator.makeVectorsStream().forEach(vec -> {
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
map.put(vec, air);
assertEquals(ImmutableMap.of(vec, air), map);
});
}
@VariedVectors.Test(provideNonMatching = true)
@Test
@DisplayName("is not equal to another map with a different key")
void isNotEqualToDifferentKeyMap(BlockVector3 vec, BlockVector3 nonMatch) {
map.put(vec, air);
assertNotEquals(ImmutableMap.of(nonMatch, air), map);
void isNotEqualToDifferentKeyMap() {
generator.makePairedVectorsStream().forEach(pair -> {
BlockVector3 vec = pair.first;
BlockVector3 nonMatch = pair.second;
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
map.put(vec, air);
assertNotEquals(ImmutableMap.of(nonMatch, air), map);
});
}
@VariedVectors.Test
@Test
@DisplayName("is not equal to another map with a different value")
void isNotEqualToDifferentValueMap(BlockVector3 vec) {
map.put(vec, air);
assertNotEquals(ImmutableMap.of(vec, oakWood), map);
void isNotEqualToDifferentValueMap() {
generator.makeVectorsStream().forEach(vec -> {
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
map.put(vec, air);
assertNotEquals(ImmutableMap.of(vec, oakWood), map);
});
}
@VariedVectors.Test
@Test
@DisplayName("is not equal to an empty map")
void isNotEqualToEmptyMap(BlockVector3 vec) {
map.put(vec, air);
assertNotEquals(ImmutableMap.of(), map);
void isNotEqualToEmptyMap() {
generator.makeVectorsStream().forEach(vec -> {
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
map.put(vec, air);
assertNotEquals(ImmutableMap.of(), map);
});
}
@VariedVectors.Test
@Test
@DisplayName("has the same hashCode as another map with the same entry")
void isHashCodeEqualToSimilarMap(BlockVector3 vec) {
map.put(vec, air);
assertEquals(ImmutableMap.of(vec, air).hashCode(), map.hashCode());
void isHashCodeEqualToSimilarMap() {
generator.makeVectorsStream().forEach(vec -> {
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
map.put(vec, air);
assertEquals(ImmutableMap.of(vec, air).hashCode(), map.hashCode());
});
}
@VariedVectors.Test(provideNonMatching = true)
@Test
@DisplayName("has a different hashCode from another map with a different key")
void isHashCodeNotEqualToDifferentKeyMap(BlockVector3 vec, BlockVector3 nonMatch) {
assumeFalse(vec.hashCode() == nonMatch.hashCode(),
"Vectors have equivalent hashCodes, maps will too.");
map.put(vec, air);
assertNotEquals(ImmutableMap.of(nonMatch, air).hashCode(), map.hashCode());
void isHashCodeNotEqualToDifferentKeyMap() {
generator.makePairedVectorsStream().forEach(pair -> {
BlockVector3 vec = pair.first;
BlockVector3 nonMatch = pair.second;
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
assumeFalse(vec.hashCode() == nonMatch.hashCode(),
"Vectors have equivalent hashCodes, maps will too.");
map.put(vec, air);
assertNotEquals(ImmutableMap.of(nonMatch, air).hashCode(), map.hashCode());
});
}
@VariedVectors.Test
@Test
@DisplayName("has a different hashCode from another map with a different value")
void isHashCodeNotEqualToDifferentValueMap(BlockVector3 vec) {
map.put(vec, air);
assertNotEquals(ImmutableMap.of(vec, oakWood).hashCode(), map.hashCode());
void isHashCodeNotEqualToDifferentValueMap() {
generator.makeVectorsStream().forEach(vec -> {
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
map.put(vec, air);
assertNotEquals(ImmutableMap.of(vec, oakWood).hashCode(), map.hashCode());
});
}
@VariedVectors.Test
@Test
@DisplayName("has a different hashCode from an empty map")
void isHashCodeNotEqualToEmptyMap(BlockVector3 vec) {
map.put(vec, air);
assertNotEquals(ImmutableMap.of().hashCode(), map.hashCode());
void isHashCodeNotEqualToEmptyMap() {
generator.makeVectorsStream().forEach(vec -> {
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
map.put(vec, air);
assertNotEquals(ImmutableMap.of().hashCode(), map.hashCode());
});
}
@VariedVectors.Test
@Test
@DisplayName("returns value from get")
void returnsValueFromGet(BlockVector3 vec) {
map.put(vec, air);
assertEquals(air, map.get(vec));
void returnsValueFromGet() {
generator.makeVectorsStream().forEach(vec -> {
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
map.put(vec, air);
assertEquals(air, map.get(vec));
});
}
@VariedVectors.Test(provideNonMatching = true)
@Test
@DisplayName("returns `null` from get with different key")
void returnsValueFromGet(BlockVector3 vec, BlockVector3 nonMatch) {
map.put(vec, air);
assertNotEquals(air, map.get(nonMatch));
void returnsValueFromGetDifferentKey() {
generator.makePairedVectorsStream().forEach(pair -> {
BlockVector3 vec = pair.first;
BlockVector3 nonMatch = pair.second;
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
map.put(vec, air);
assertNotEquals(air, map.get(nonMatch));
});
}
@VariedVectors.Test
@Test
@DisplayName("contains the key")
void containsTheKey(BlockVector3 vec) {
map.put(vec, air);
assertEquals(1, map.keySet().size());
assertTrue(map.keySet().contains(vec));
assertTrue(map.containsKey(vec));
void containsTheKey() {
generator.makeVectorsStream().forEach(vec -> {
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
map.put(vec, air);
assertEquals(1, map.keySet().size());
assertTrue(map.keySet().contains(vec));
assertTrue(map.containsKey(vec));
});
}
@VariedVectors.Test
@Test
@DisplayName("contains the value")
void containsTheValue(BlockVector3 vec) {
map.put(vec, air);
assertEquals(1, map.values().size());
assertTrue(map.values().contains(air));
assertTrue(map.containsValue(air));
void containsTheValue() {
generator.makeVectorsStream().forEach(vec -> {
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
map.put(vec, air);
assertEquals(1, map.values().size());
assertTrue(map.values().contains(air));
assertTrue(map.containsValue(air));
});
}
@VariedVectors.Test
@Test
@DisplayName("contains the entry")
void containsTheEntry(BlockVector3 vec) {
map.put(vec, air);
assertEquals(1, map.entrySet().size());
assertEquals(new AbstractMap.SimpleImmutableEntry<>(vec, air), map.entrySet().iterator().next());
void containsTheEntry() {
generator.makeVectorsStream().forEach(vec -> {
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
map.put(vec, air);
assertEquals(1, map.entrySet().size());
assertEquals(new AbstractMap.SimpleImmutableEntry<>(vec, air), map.entrySet().iterator().next());
});
}
@VariedVectors.Test
@Test
@DisplayName("returns the provided value from getOrDefault")
void returnsProvidedFromGetOrDefault(BlockVector3 vec) {
map.put(vec, air);
assertEquals(air, map.getOrDefault(vec, oakWood));
void returnsProvidedFromGetOrDefault() {
generator.makeVectorsStream().forEach(vec -> {
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
map.put(vec, air);
assertEquals(air, map.getOrDefault(vec, oakWood));
});
}
@VariedVectors.Test(provideNonMatching = true)
@Test
@DisplayName("returns the default value from getOrDefault with a different key")
void returnsDefaultFromGetOrDefaultWrongKey(BlockVector3 vec, BlockVector3 nonMatch) {
map.put(vec, air);
assertEquals(oakWood, map.getOrDefault(nonMatch, oakWood));
void returnsDefaultFromGetOrDefaultWrongKey() {
generator.makePairedVectorsStream().forEach(pair -> {
BlockVector3 vec = pair.first;
BlockVector3 nonMatch = pair.second;
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
map.put(vec, air);
assertEquals(oakWood, map.getOrDefault(nonMatch, oakWood));
});
}
@VariedVectors.Test
@Test
@DisplayName("calls the forEach action once")
void neverCallsForEachAction(BlockVector3 vec) {
map.put(vec, air);
map.forEach(biConsumer);
verify(biConsumer).accept(vec, air);
verifyNoMoreInteractions(biConsumer);
void neverCallsForEachAction() {
generator.makeVectorsStream().sequential().forEach(vec -> {
try (AutoCloseable ignored = MockitoAnnotations.openMocks(this)) {
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
map.put(vec, air);
map.forEach(biConsumer);
verify(biConsumer).accept(vec, air);
verifyNoMoreInteractions(biConsumer);
} catch (Exception e) {
throw new AssertionError(e);
}
});
}
@VariedVectors.Test
@Test
@DisplayName("replaces value using replaceAll")
void neverCallsReplaceAllFunction(BlockVector3 vec) {
map.put(vec, air);
map.replaceAll((v, b) -> oakWood);
assertEquals(oakWood, map.get(vec));
void neverCallsReplaceAllFunction() {
generator.makeVectorsStream().forEach(vec -> {
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
map.put(vec, air);
map.replaceAll((v, b) -> oakWood);
assertEquals(oakWood, map.get(vec));
});
}
@VariedVectors.Test
@Test
@DisplayName("does not insert on `putIfAbsent`")
void noInsertOnPutIfAbsent(BlockVector3 vec) {
map.put(vec, air);
assertEquals(air, map.putIfAbsent(vec, oakWood));
assertEquals(1, map.size());
assertEquals(air, map.get(vec));
void noInsertOnPutIfAbsent() {
generator.makeVectorsStream().forEach(vec -> {
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
map.put(vec, air);
assertEquals(air, map.putIfAbsent(vec, oakWood));
assertEquals(1, map.size());
assertEquals(air, map.get(vec));
});
}
@VariedVectors.Test(provideNonMatching = true)
@Test
@DisplayName("inserts on `putIfAbsent` to a different key")
void insertOnPutIfAbsentDifferentKey(BlockVector3 vec, BlockVector3 nonMatch) {
map.put(vec, air);
assertNull(map.putIfAbsent(nonMatch, oakWood));
assertEquals(2, map.size());
assertEquals(air, map.get(vec));
assertEquals(oakWood, map.get(nonMatch));
void insertOnPutIfAbsentDifferentKey() {
generator.makePairedVectorsStream().forEach(pair -> {
BlockVector3 vec = pair.first;
BlockVector3 nonMatch = pair.second;
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
map.put(vec, air);
assertNull(map.putIfAbsent(nonMatch, oakWood));
assertEquals(2, map.size());
assertEquals(air, map.get(vec));
assertEquals(oakWood, map.get(nonMatch));
});
}
@VariedVectors.Test
@Test
@DisplayName("remove(key) returns the old value")
void removeKeyReturnsOldValue(BlockVector3 vec) {
map.put(vec, air);
assertEquals(air, map.remove(vec));
assertEquals(0, map.size());
void removeKeyReturnsOldValue() {
generator.makeVectorsStream().forEach(vec -> {
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
map.put(vec, air);
assertEquals(air, map.remove(vec));
assertEquals(0, map.size());
});
}
@VariedVectors.Test
@Test
@DisplayName("keySet().remove(key) removes the entry from the map")
void keySetRemovePassesThrough(BlockVector3 vec) {
map.put(vec, air);
assertTrue(map.keySet().remove(vec));
assertEquals(0, map.size());
void keySetRemovePassesThrough() {
generator.makeVectorsStream().forEach(vec -> {
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
map.put(vec, air);
assertTrue(map.keySet().remove(vec));
assertEquals(0, map.size());
});
}
@VariedVectors.Test
@Test
@DisplayName("entrySet().iterator().remove() removes the entry from the map")
void entrySetIteratorRemovePassesThrough(BlockVector3 vec) {
map.put(vec, air);
Iterator<Map.Entry<BlockVector3, BaseBlock>> iterator = map.entrySet().iterator();
assertTrue(iterator.hasNext());
Map.Entry<BlockVector3, BaseBlock> entry = iterator.next();
assertEquals(entry.getKey(), vec);
iterator.remove();
assertEquals(0, map.size());
void entrySetIteratorRemovePassesThrough() {
generator.makeVectorsStream().forEach(vec -> {
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
map.put(vec, air);
Iterator<Map.Entry<BlockVector3, BaseBlock>> iterator = map.entrySet().iterator();
assertTrue(iterator.hasNext());
Map.Entry<BlockVector3, BaseBlock> entry = iterator.next();
assertEquals(entry.getKey(), vec);
iterator.remove();
assertEquals(0, map.size());
});
}
@VariedVectors.Test(provideNonMatching = true)
@Test
@DisplayName("remove(nonMatch) returns null")
void removeNonMatchingKeyReturnsNull(BlockVector3 vec, BlockVector3 nonMatch) {
map.put(vec, air);
assertNull(map.remove(nonMatch));
assertEquals(1, map.size());
void removeNonMatchingKeyReturnsNull() {
generator.makePairedVectorsStream().forEach(pair -> {
BlockVector3 vec = pair.first;
BlockVector3 nonMatch = pair.second;
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
map.put(vec, air);
assertNull(map.remove(nonMatch));
assertEquals(1, map.size());
});
}
@VariedVectors.Test
@Test
@DisplayName("remove(key, value) returns true")
void removeKeyValueReturnsTrue(BlockVector3 vec) {
map.put(vec, air);
assertTrue(map.remove(vec, air));
assertEquals(0, map.size());
void removeKeyValueReturnsTrue() {
generator.makeVectorsStream().forEach(vec -> {
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
map.put(vec, air);
assertTrue(map.remove(vec, air));
assertEquals(0, map.size());
});
}
@VariedVectors.Test
@Test
@DisplayName("remove(key, value) returns false for wrong value")
void removeKeyValueReturnsFalseWrongValue(BlockVector3 vec) {
map.put(vec, air);
assertFalse(map.remove(vec, oakWood));
assertEquals(1, map.size());
void removeKeyValueReturnsFalseWrongValue() {
generator.makeVectorsStream().forEach(vec -> {
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
map.put(vec, air);
assertFalse(map.remove(vec, oakWood));
assertEquals(1, map.size());
});
}
@VariedVectors.Test
@Test
@DisplayName("replaces value at key")
void replacesValueAtKey(BlockVector3 vec) {
map.put(vec, air);
void replacesValueAtKey() {
generator.makeVectorsStream().forEach(vec -> {
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
map.put(vec, air);
assertEquals(air, map.replace(vec, oakWood));
assertEquals(1, map.size());
assertEquals(oakWood, map.get(vec));
assertEquals(air, map.replace(vec, oakWood));
assertEquals(1, map.size());
assertEquals(oakWood, map.get(vec));
assertTrue(map.replace(vec, oakWood, air));
assertEquals(1, map.size());
assertEquals(air, map.get(vec));
assertTrue(map.replace(vec, oakWood, air));
assertEquals(1, map.size());
assertEquals(air, map.get(vec));
});
}
@VariedVectors.Test(provideNonMatching = true)
@Test
@DisplayName("does not replace value at different key")
void doesNotReplaceAtDifferentKey(BlockVector3 vec, BlockVector3 nonMatch) {
map.put(vec, air);
void doesNotReplaceAtDifferentKey() {
generator.makePairedVectorsStream().forEach(pair -> {
BlockVector3 vec = pair.first;
BlockVector3 nonMatch = pair.second;
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
map.put(vec, air);
assertNull(map.replace(nonMatch, oakWood));
assertEquals(1, map.size());
assertEquals(air, map.get(vec));
assertNull(map.replace(nonMatch, oakWood));
assertEquals(1, map.size());
assertEquals(air, map.get(vec));
assertFalse(map.replace(nonMatch, air, oakWood));
assertEquals(1, map.size());
assertEquals(air, map.get(vec));
assertFalse(map.replace(nonMatch, air, oakWood));
assertEquals(1, map.size());
assertEquals(air, map.get(vec));
});
}
@VariedVectors.Test
@Test
@DisplayName("does not insert on computeIfAbsent")
void doesNotInsertComputeIfAbsent(BlockVector3 vec) {
map.put(vec, air);
assertEquals(air, map.computeIfAbsent(vec, k -> {
assertEquals(vec, k);
return oakWood;
}));
assertEquals(1, map.size());
assertEquals(air, map.get(vec));
void doesNotInsertComputeIfAbsent() {
generator.makeVectorsStream().forEach(vec -> {
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
map.put(vec, air);
assertEquals(air, map.computeIfAbsent(vec, k -> {
assertEquals(vec, k);
return oakWood;
}));
assertEquals(1, map.size());
assertEquals(air, map.get(vec));
});
}
@VariedVectors.Test(provideNonMatching = true)
@Test
@DisplayName("inserts on computeIfAbsent with different key")
void insertsOnComputeIfAbsentDifferentKey(BlockVector3 vec, BlockVector3 nonMatch) {
map.put(vec, air);
assertEquals(oakWood, map.computeIfAbsent(nonMatch, k -> {
assertEquals(nonMatch, k);
return oakWood;
}));
assertEquals(2, map.size());
assertEquals(air, map.get(vec));
assertEquals(oakWood, map.get(nonMatch));
void insertsOnComputeIfAbsentDifferentKey() {
generator.makePairedVectorsStream().forEach(pair -> {
BlockVector3 vec = pair.first;
BlockVector3 nonMatch = pair.second;
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
map.put(vec, air);
assertEquals(oakWood, map.computeIfAbsent(nonMatch, k -> {
assertEquals(nonMatch, k);
return oakWood;
}));
assertEquals(2, map.size());
assertEquals(air, map.get(vec));
assertEquals(oakWood, map.get(nonMatch));
});
}
@VariedVectors.Test
@Test
@DisplayName("replaces on compute")
void replaceOnCompute(BlockVector3 vec) {
map.put(vec, air);
assertEquals(oakWood, map.compute(vec, (k, v) -> {
assertEquals(vec, k);
assertEquals(air, v);
return oakWood;
}));
assertEquals(1, map.size());
assertEquals(oakWood, map.get(vec));
assertNull(map.compute(vec, (k, v) -> null));
assertEquals(0, map.size());
void replaceOnCompute() {
generator.makeVectorsStream().forEach(vec -> {
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
map.put(vec, air);
assertEquals(oakWood, map.compute(vec, (k, v) -> {
assertEquals(vec, k);
assertEquals(air, v);
return oakWood;
}));
assertEquals(1, map.size());
assertEquals(oakWood, map.get(vec));
assertNull(map.compute(vec, (k, v) -> null));
assertEquals(0, map.size());
});
}
@VariedVectors.Test(provideNonMatching = true)
@Test
@DisplayName("inserts on compute with different key")
void insertOnComputeDifferentKey(BlockVector3 vec, BlockVector3 nonMatch) {
map.put(vec, air);
assertEquals(oakWood, map.compute(nonMatch, (k, v) -> {
assertEquals(nonMatch, k);
assertNull(v);
return oakWood;
}));
assertEquals(2, map.size());
assertEquals(air, map.get(vec));
assertEquals(oakWood, map.get(nonMatch));
assertNull(map.compute(nonMatch, (k, v) -> null));
assertEquals(1, map.size());
assertEquals(air, map.get(vec));
void insertOnComputeDifferentKey() {
generator.makePairedVectorsStream().forEach(pair -> {
BlockVector3 vec = pair.first;
BlockVector3 nonMatch = pair.second;
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
map.put(vec, air);
assertEquals(oakWood, map.compute(nonMatch, (k, v) -> {
assertEquals(nonMatch, k);
assertNull(v);
return oakWood;
}));
assertEquals(2, map.size());
assertEquals(air, map.get(vec));
assertEquals(oakWood, map.get(nonMatch));
assertNull(map.compute(nonMatch, (k, v) -> null));
assertEquals(1, map.size());
assertEquals(air, map.get(vec));
});
}
@VariedVectors.Test
@Test
@DisplayName("replaces on computeIfPresent")
void replacesOnComputeIfPresent(BlockVector3 vec) {
map.put(vec, air);
assertEquals(oakWood, map.computeIfPresent(vec, (k, v) -> {
assertEquals(vec, k);
assertEquals(air, v);
return oakWood;
}));
assertEquals(1, map.size());
assertEquals(oakWood, map.get(vec));
assertNull(map.computeIfPresent(vec, (k, v) -> null));
assertEquals(0, map.size());
void replacesOnComputeIfPresent() {
generator.makeVectorsStream().forEach(vec -> {
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
map.put(vec, air);
assertEquals(oakWood, map.computeIfPresent(vec, (k, v) -> {
assertEquals(vec, k);
assertEquals(air, v);
return oakWood;
}));
assertEquals(1, map.size());
assertEquals(oakWood, map.get(vec));
assertNull(map.computeIfPresent(vec, (k, v) -> null));
assertEquals(0, map.size());
});
}
@VariedVectors.Test
@Test
@DisplayName("inserts on merge, with call to merge function")
void insertsOnMerge(BlockVector3 vec) {
map.put(vec, air);
assertEquals(oakWood, map.merge(vec, oakWood, (o, n) -> {
assertEquals(air, o);
assertEquals(oakWood, n);
return n;
}));
assertEquals(1, map.size());
assertEquals(oakWood, map.get(vec));
void insertsOnMerge() {
generator.makeVectorsStream().forEach(vec -> {
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
map.put(vec, air);
assertEquals(oakWood, map.merge(vec, oakWood, (o, n) -> {
assertEquals(air, o);
assertEquals(oakWood, n);
return n;
}));
assertEquals(1, map.size());
assertEquals(oakWood, map.get(vec));
});
}
}
@ -546,9 +746,10 @@ class BlockMapTest {
@Test
@DisplayName("contains all inserted vectors")
void containsAllInsertedVectors() {
BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
Set<BlockVector3> allVectors = new VariedVectorGenerator()
.makeVectorsStream()
.collect(Collectors.toSet());
.makeVectorsStream()
.collect(Collectors.toSet());
for (BlockVector3 vec : allVectors) {
map.put(vec, air);
}
@ -559,5 +760,6 @@ class BlockMapTest {
assertEquals(air, entry.getValue());
}
}
*/
}
*/

View File

@ -19,9 +19,9 @@
package com.sk89q.worldedit.util.collection;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.util.test.VariedVectors;
import com.sk89q.worldedit.util.test.VariedVectorGenerator;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
@ -29,70 +29,91 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
abstract class PositionListTest {
static class Long extends PositionListTest {
protected Long() {
super(new LongPositionList());
@Override
protected PositionList createPositionList() {
return new LongPositionList();
}
}
static class Vector extends PositionListTest {
protected Vector() {
super(new VectorPositionList());
@Override
protected PositionList createPositionList() {
return new VectorPositionList();
}
}
private final PositionList positionList;
private final VariedVectorGenerator generator = new VariedVectorGenerator(true);
protected PositionListTest(PositionList positionList) {
this.positionList = positionList;
}
protected abstract PositionList createPositionList();
@VariedVectors.Test(capToVanilla = true)
@Test
@DisplayName("calling add(vec) increases size by 1")
void addIncreasesSizeByOne(BlockVector3 vec) {
positionList.add(vec);
assertEquals(1, positionList.size());
void addIncreasesSizeByOne() {
generator.makeVectorsStream().forEach(vec -> {
PositionList positionList = createPositionList();
positionList.add(vec);
assertEquals(1, positionList.size());
});
}
@VariedVectors.Test(capToVanilla = true)
@Test
@DisplayName("calling get(0) after add(vec) returns vec")
void canGetVectorAfterAdd(BlockVector3 vec) {
positionList.add(vec);
assertEquals(vec, positionList.get(0));
void canGetVectorAfterAdd() {
generator.makeVectorsStream().forEach(vec -> {
PositionList positionList = createPositionList();
positionList.add(vec);
assertEquals(vec, positionList.get(0));
});
}
@VariedVectors.Test(capToVanilla = true)
@Test
@DisplayName("calling iterator().hasNext() after add(vec) returns true")
void hasNextAfterAdd(BlockVector3 vec) {
positionList.add(vec);
assertTrue(positionList.iterator().hasNext());
void hasNextAfterAdd() {
generator.makeVectorsStream().forEach(vec -> {
PositionList positionList = createPositionList();
positionList.add(vec);
assertTrue(positionList.iterator().hasNext());
});
}
@VariedVectors.Test(capToVanilla = true)
@Test
@DisplayName("calling iterator().next() after add(vec) returns vec")
void nextAfterAdd(BlockVector3 vec) {
positionList.add(vec);
assertEquals(vec, positionList.iterator().next());
void nextAfterAdd() {
generator.makeVectorsStream().forEach(vec -> {
PositionList positionList = createPositionList();
positionList.add(vec);
assertEquals(vec, positionList.iterator().next());
});
}
@VariedVectors.Test(capToVanilla = true)
@Test
@DisplayName("calling reverseIterator().hasNext() after add(vec) returns true")
void reverseHasNextAfterAdd(BlockVector3 vec) {
positionList.add(vec);
assertTrue(positionList.reverseIterator().hasNext());
void reverseHasNextAfterAdd() {
generator.makeVectorsStream().forEach(vec -> {
PositionList positionList = createPositionList();
positionList.add(vec);
assertTrue(positionList.reverseIterator().hasNext());
});
}
@VariedVectors.Test(capToVanilla = true)
@Test
@DisplayName("calling reverseIterator().next() after add(vec) returns vec")
void reverseNextAfterAdd(BlockVector3 vec) {
positionList.add(vec);
assertEquals(vec, positionList.reverseIterator().next());
void reverseNextAfterAdd() {
generator.makeVectorsStream().forEach(vec -> {
PositionList positionList = createPositionList();
positionList.add(vec);
assertEquals(vec, positionList.reverseIterator().next());
});
}
@VariedVectors.Test(capToVanilla = true)
@Test
@DisplayName("calling clear() after add(vec) makes the size() zero")
void clearAfterAdd(BlockVector3 vec) {
positionList.add(vec);
positionList.clear();
assertEquals(0, positionList.size());
void clearAfterAdd() {
generator.makeVectorsStream().forEach(vec -> {
PositionList positionList = createPositionList();
positionList.add(vec);
positionList.clear();
assertEquals(0, positionList.size());
});
}
}

View File

@ -0,0 +1,27 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.util.test;
public class ResourceLockKeys {
public static final String WORLDEDIT_PLATFORM = "WORLDEDIT_PLATFORM";
private ResourceLockKeys() {
}
}

View File

@ -30,12 +30,10 @@ import java.util.stream.Stream;
public class VariedVectorGenerator {
// For better coverage assurance, increase these values for a local Gradle run.
// Don't do it for IntelliJ, it'll probably run out of memory.
private static final int DEFAULT_DIVISIONS_XZ =
Integer.getInteger("variedvecs.divisions.xz", 5);
Integer.getInteger("variedvecs.divisions.xz", 10);
private static final int DEFAULT_DIVISIONS_Y =
Integer.getInteger("variedvecs.divisions.y", 5);
Integer.getInteger("variedvecs.divisions.y", 10);
public final int divisionsXZ;
public final int divisionsY;
@ -46,29 +44,42 @@ public class VariedVectorGenerator {
public final Set<BlockVector3> alwaysInclude;
public VariedVectorGenerator() {
this(false, -1, -1);
this(false);
}
public VariedVectorGenerator(boolean vanilla) {
this(vanilla, -1, -1);
}
public VariedVectorGenerator(boolean vanilla, int divisionsXZ, int divisionsY) {
this.divisionsXZ = divisionsXZ == -1 ? DEFAULT_DIVISIONS_XZ : divisionsXZ;
this.divisionsY = divisionsY == -1 ? DEFAULT_DIVISIONS_Y : divisionsY;
maxXZ = 30_000_000;
maxY = vanilla ? 255 : Integer.MAX_VALUE;
maxY = vanilla ? 2047 : Integer.MAX_VALUE;
xzStep = (maxXZ * 2) / this.divisionsXZ;
yStep = (maxY * 2) / this.divisionsY;
alwaysInclude =
ImmutableSet.of(BlockVector3.ZERO, BlockVector3.ONE,
BlockVector3.at(-maxXZ, 0, -maxXZ),
BlockVector3.at(maxXZ, 0, maxXZ),
BlockVector3.at(-maxXZ, maxY, -maxXZ),
BlockVector3.at(maxXZ, maxY, maxXZ));
ImmutableSet.of(BlockVector3.ZERO, BlockVector3.ONE,
BlockVector3.at(-maxXZ, -maxY - 1, -maxXZ),
BlockVector3.at(maxXZ, -maxY - 1, maxXZ),
BlockVector3.at(-maxXZ, maxY, -maxXZ),
BlockVector3.at(maxXZ, maxY, maxXZ));
}
public Stream<BlockVector3> makeVectorsStream() {
return Stream.concat(
alwaysInclude.stream(),
Streams.stream(generateVectors()).filter(v -> !alwaysInclude.contains(v))
);
alwaysInclude.stream(),
Streams.stream(generateVectors()).filter(v -> !alwaysInclude.contains(v))
).parallel();
}
/**
* Gives two vectors from {@link #makeVectorsStream()} that aren't the same.
*/
public Stream<VariedVectorPair> makePairedVectorsStream() {
return makeVectorsStream()
.flatMap(vec -> makeVectorsStream().filter(v -> !v.equals(vec))
.map(v -> new VariedVectorPair(vec, v)));
}
private Iterator<BlockVector3> generateVectors() {
@ -86,7 +97,7 @@ public class VariedVectorGenerator {
BlockVector3 newVector = BlockVector3.at(x, (int) y, z);
y += yStep;
if (y > maxY) {
y = 0;
y = -maxY - 1;
z += xzStep;
if (z > maxXZ) {
z = -maxXZ;

View File

@ -0,0 +1,32 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.util.test;
import com.sk89q.worldedit.math.BlockVector3;
public class VariedVectorPair {
public final BlockVector3 first;
public final BlockVector3 second;
public VariedVectorPair(BlockVector3 first, BlockVector3 second) {
this.first = first;
this.second = second;
}
}

View File

@ -1,87 +0,0 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.util.test;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.ArgumentsProvider;
import org.junit.jupiter.params.provider.ArgumentsSource;
import org.junit.jupiter.params.support.AnnotationConsumer;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.stream.Stream;
/**
* Argument provider for various vectors.
*/
public final class VariedVectors implements ArgumentsProvider, AnnotationConsumer<VariedVectors.Test> {
@Target({ ElementType.ANNOTATION_TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@ArgumentsSource(VariedVectors.class)
@ParameterizedTest(name = ParameterizedTest.ARGUMENTS_PLACEHOLDER)
public @interface Test {
/**
* If {@code true}, provide a non-matching vector from
* the existing vectors set as well. This will nearly
* square the number of tests executed, since it will
* test <em>every</em> non-matching vector.
*/
boolean provideNonMatching() default false;
/**
* If {@code true}, only provide vectors inside the range of Vanilla MC.
* This caps the Y value to 255.
*/
boolean capToVanilla() default false;
int divisionsXZ() default -1;
int divisionsY() default -1;
}
private boolean provideNonMatching;
private VariedVectorGenerator generator;
@Override
public void accept(Test test) {
provideNonMatching = test.provideNonMatching();
generator = new VariedVectorGenerator(test.capToVanilla(), test.divisionsXZ(), test.divisionsY());
}
@Override
public Stream<? extends Arguments> provideArguments(ExtensionContext context) {
if (provideNonMatching) {
return generator.makeVectorsStream()
.flatMap(vec -> generator.makeVectorsStream().filter(v -> !v.equals(vec))
.map(v -> Arguments.of(vec, v)));
}
return generator.makeVectorsStream().map(Arguments::of);
}
}

View File

@ -2,4 +2,4 @@ junit.jupiter.execution.parallel.enabled=true
junit.jupiter.execution.parallel.mode.default=concurrent
junit.jupiter.execution.parallel.mode.classes.default=same_thread
junit.jupiter.execution.parallel.config.strategy=dynamic
junit.jupiter.execution.parallel.config.dynamic.factor=1
junit.jupiter.execution.parallel.config.dynamic.factor=4