Skip to content

Commit

Permalink
Add tests for effects (#6204)
Browse files Browse the repository at this point in the history
* Add tests for EffActionBar

* Fix order of operations issue in EffApplyBoneMeal

* Add tests for EffApplyBoneMeal

* Add tests for EffDoIf

* Add tests for EffSwingHand

* Replace static imports

* Add tests for EffFeed

* Fix EffSwingHandTest on unsupported versions

* Add tests for EffMakeFly

* Add tests for EffPvP

* Remove double whitespace

* Add tests for EffOp

---------

Co-authored-by: sovdee <10354869+sovdeeth@users.noreply.github.com>
  • Loading branch information
Pikachu920 and sovdeeth authored Jan 1, 2024
1 parent 58ca469 commit 5843ec8
Showing 15 changed files with 554 additions and 45 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
@@ -40,7 +40,7 @@ dependencies {
implementation fileTree(dir: 'lib', include: '*.jar')

testShadow group: 'junit', name: 'junit', version: '4.13.2'
testShadow group: 'org.easymock', name: 'easymock', version: '5.2.0'
testShadow group: 'org.easymock', name: 'easymock', version: '5.0.1'
}

task checkAliases {
3 changes: 3 additions & 0 deletions src/main/java/ch/njol/skript/Skript.java
Original file line number Diff line number Diff line change
@@ -691,6 +691,9 @@ protected void afterErrors() {
long milliseconds = 0, tests = 0, fails = 0, ignored = 0, size = 0;
try {
List<Class<?>> classes = Lists.newArrayList(Utils.getClasses(Skript.getInstance(), "org.skriptlang.skript.test", "tests"));
// Don't attempt to run inner/anonymous classes as tests
classes.removeIf(Class::isAnonymousClass);
classes.removeIf(Class::isLocalClass);
// Test that requires package access. This is only present when compiling with src/test.
classes.add(Class.forName("ch.njol.skript.variables.FlatFileStorageTest"));
size = classes.size();
2 changes: 1 addition & 1 deletion src/main/java/ch/njol/skript/effects/EffApplyBoneMeal.java
Original file line number Diff line number Diff line change
@@ -71,7 +71,7 @@ protected void execute(Event event) {

@Override
public String toString(@Nullable Event event, boolean debug) {
return "apply " + amount != null ? amount.toString(event, debug) + " " : "" + "bone meal to " + blocks.toString(event, debug);
return "apply " + (amount != null ? amount.toString(event, debug) + " " : "" + "bone meal to " + blocks.toString(event, debug));
}

}
2 changes: 1 addition & 1 deletion src/main/java/ch/njol/skript/effects/EffSwingHand.java
Original file line number Diff line number Diff line change
@@ -46,7 +46,7 @@ public class EffSwingHand extends Effect {
"make %livingentities% swing [their] off[ ]hand");
}

private static final boolean SWINGING_IS_SUPPORTED = Skript.methodExists(LivingEntity.class, "swingMainHand");
public static final boolean SWINGING_IS_SUPPORTED = Skript.methodExists(LivingEntity.class, "swingMainHand");

@SuppressWarnings("null")
private Expression<LivingEntity> entities;
Original file line number Diff line number Diff line change
@@ -38,7 +38,7 @@
public abstract class SkriptJUnitTest {

static {
World world = Bukkit.getWorlds().get(0);
World world = getTestWorld();
world.setGameRule(GameRule.MAX_ENTITY_CRAMMING, 1000);
world.setGameRule(GameRule.DO_WEATHER_CYCLE, false);
// Natural entity spawning
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/**
* This file is part of Skript.
*
* Skript 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.
*
* Skript 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 Skript. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright Peter Güttinger, SkriptLang team and contributors
*/
package org.skriptlang.skript.test.tests.syntaxes.effects;


import ch.njol.skript.lang.Effect;
import ch.njol.skript.lang.TriggerItem;
import ch.njol.skript.lang.util.ContextlessEvent;
import ch.njol.skript.test.runner.SkriptJUnitTest;
import ch.njol.skript.variables.Variables;
import net.md_5.bungee.api.ChatMessageType;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.TextComponent;
import org.bukkit.entity.Player;
import org.easymock.EasyMock;
import org.easymock.IArgumentMatcher;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;


@SuppressWarnings("deprecation")
public class EffActionBarTest extends SkriptJUnitTest {

private Player testPlayer;
private Player.Spigot testSpigotPlayer;
private Effect actionBarEffect;

@Before
public void setup() {
testPlayer = EasyMock.niceMock(Player.class);
testSpigotPlayer = EasyMock.niceMock(Player.Spigot.class);
actionBarEffect = Effect.parse("send actionbar {_content} to {_player}", null);
}

@Test
public void test() {
if (actionBarEffect == null)
Assert.fail("Effect is null");

String expectedActionBarContent = "hello world";

EasyMock.expect(testPlayer.spigot()).andAnswer(() -> testSpigotPlayer);

testSpigotPlayer.sendMessage(
EasyMock.eq(ChatMessageType.ACTION_BAR),
(BaseComponent[]) componentMatcher(expectedActionBarContent)
);

EasyMock.expectLastCall();

EasyMock.replay(testPlayer, testSpigotPlayer);

ContextlessEvent event = ContextlessEvent.get();
Variables.setVariable("content", expectedActionBarContent, event, true);
Variables.setVariable("player", testPlayer, event, true);
TriggerItem.walk(actionBarEffect, event);

EasyMock.verify(testPlayer, testSpigotPlayer);
}

private <T> T componentMatcher(String expectedContent) {
EasyMock.reportMatcher(new IArgumentMatcher() {
@Override
public boolean matches(Object argument) {
if (argument instanceof TextComponent) {
return ((TextComponent) argument).getText().equals(expectedContent);
}
return false;
}

@Override
public void appendTo(StringBuffer buffer) {
buffer.append("[component matcher]");
}
});

return null;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/**
* This file is part of Skript.
*
* Skript 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.
*
* Skript 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 Skript. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright Peter Güttinger, SkriptLang team and contributors
*/
package org.skriptlang.skript.test.tests.syntaxes.effects;


import ch.njol.skript.Skript;
import ch.njol.skript.effects.EffApplyBoneMeal;
import ch.njol.skript.lang.Effect;
import ch.njol.skript.lang.SyntaxElementInfo;
import ch.njol.skript.lang.TriggerItem;
import ch.njol.skript.lang.util.ContextlessEvent;
import ch.njol.skript.test.runner.SkriptJUnitTest;
import ch.njol.skript.variables.Variables;
import org.bukkit.block.Block;
import org.easymock.EasyMock;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

public class EffApplyBoneMealTest {

private Block stubTestBlock;
private Effect applyBonemealEffect;
private Effect applyMultipleBonemealEffect;

@Before
public void setup() {
stubTestBlock = EasyMock.niceMock(Block.class);
applyBonemealEffect = Effect.parse("apply bonemeal to {_block}", null);
applyMultipleBonemealEffect = Effect.parse("apply {_times} bonemeal to {_block}", null);
}

@Test
public void test() {
boolean bonemealEffectRegistered = Skript.getEffects().stream()
.map(SyntaxElementInfo::getElementClass)
.anyMatch(EffApplyBoneMeal.class::equals);
if (!bonemealEffectRegistered)
return;
if (applyBonemealEffect == null)
Assert.fail("Effect is null");
if (applyMultipleBonemealEffect == null)
Assert.fail("Multiple effect is null");

int countOfBonemealToApply = 5;
ContextlessEvent event = ContextlessEvent.get();
Variables.setVariable("block", getMockBlock(), event, true);
Variables.setVariable("times", countOfBonemealToApply, event, true);

EasyMock.expect(stubTestBlock.applyBoneMeal(EasyMock.notNull())).andReturn(true).times(1);
EasyMock.replay(stubTestBlock);
TriggerItem.walk(applyBonemealEffect, event);
EasyMock.verify(stubTestBlock);

EasyMock.resetToNice(stubTestBlock);
EasyMock.expect(stubTestBlock.applyBoneMeal(EasyMock.notNull())).andReturn(true).times(2);
EasyMock.replay(stubTestBlock);
TriggerItem.walk(applyMultipleBonemealEffect, event);
EasyMock.verify(stubTestBlock);
}

private Block getMockBlock() {
Block realBlock = SkriptJUnitTest.getBlock();

// we need to intercept applyBoneMeal calls so that easymock can detect them
// but we need to pass the other calls to a real block so that a real blockdata,
// material, location, etc are available
InvocationHandler handler = (proxy, method, args) -> {
if (method.getName().equals("applyBoneMeal")) {
return method.invoke(stubTestBlock, args);
}
return method.invoke(realBlock, args);
};

return (Block) Proxy.newProxyInstance(getClass().getClassLoader(), new Class<?>[] { Block.class }, handler);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/**
* This file is part of Skript.
*
* Skript 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.
*
* Skript 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 Skript. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright Peter Güttinger, SkriptLang team and contributors
*/
package org.skriptlang.skript.test.tests.syntaxes.effects;

import ch.njol.skript.lang.Effect;
import ch.njol.skript.lang.TriggerItem;
import ch.njol.skript.lang.util.ContextlessEvent;
import ch.njol.skript.test.runner.SkriptJUnitTest;
import ch.njol.skript.variables.Variables;
import org.bukkit.entity.Player;
import org.easymock.EasyMock;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

public class EffFeedTest extends SkriptJUnitTest {

private Player easyMockPlayer;
private Effect feedFullyEffect;
private Effect feedPartiallyEffect;

@Before
public void setup() {
easyMockPlayer = EasyMock.niceMock(Player.class);
feedFullyEffect = Effect.parse("feed {_player}", null);
feedPartiallyEffect = Effect.parse("feed {_player} by {_amount} beef", null);
}

@Test
public void test() {
if (feedFullyEffect == null)
Assert.fail("Fully effect is null");
if (feedPartiallyEffect == null)
Assert.fail("Partially effect is null");

int amountToFeed = 1;
int maxFoodLevel = 20;
ContextlessEvent event = ContextlessEvent.get();
Variables.setVariable("player", getMockPlayer(), event, true);
Variables.setVariable("amount", amountToFeed, event, true);

easyMockPlayer.setFoodLevel(EasyMock.eq(maxFoodLevel));
EasyMock.expectLastCall();
EasyMock.replay(easyMockPlayer);
TriggerItem.walk(feedFullyEffect, event);
EasyMock.verify(easyMockPlayer);

EasyMock.resetToNice(easyMockPlayer);
easyMockPlayer.setFoodLevel(EasyMock.eq(amountToFeed));
EasyMock.expectLastCall();
EasyMock.replay(easyMockPlayer);
TriggerItem.walk(feedPartiallyEffect, event);
EasyMock.verify(easyMockPlayer);
}

private Player getMockPlayer() {
InvocationHandler handler = (proxy, method, args) -> {
if (method.getName().equals("getFoodLevel"))
return 0;
return method.invoke(easyMockPlayer, args);
};
return (Player) Proxy.newProxyInstance(getClass().getClassLoader(), new Class[] { Player.class }, handler);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/**
* This file is part of Skript.
*
* Skript 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.
*
* Skript 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 Skript. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright Peter Güttinger, SkriptLang team and contributors
*/
package org.skriptlang.skript.test.tests.syntaxes.effects;

import ch.njol.skript.lang.Effect;
import ch.njol.skript.lang.TriggerItem;
import ch.njol.skript.lang.util.ContextlessEvent;
import ch.njol.skript.test.runner.SkriptJUnitTest;
import ch.njol.skript.variables.Variables;
import org.bukkit.entity.Player;
import org.easymock.EasyMock;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

public class EffMakeFlyTest extends SkriptJUnitTest {

private Player testPlayer;
private Effect startFlyingEffect;
private Effect stopFlyingEffect;

@Before
public void setup() {
testPlayer = EasyMock.niceMock(Player.class);
startFlyingEffect = Effect.parse("make {_player} start flying", null);
stopFlyingEffect = Effect.parse("make {_player} stop flying", null);
}

@Test
public void test() {
if (startFlyingEffect == null)
Assert.fail("Start flying effect is null");
if (stopFlyingEffect == null)
Assert.fail("Stop flying effect is null");

ContextlessEvent event = ContextlessEvent.get();
Variables.setVariable("player", testPlayer, event, true);

testPlayer.setAllowFlight(true);
EasyMock.expectLastCall();
testPlayer.setFlying(true);
EasyMock.expectLastCall();
EasyMock.replay(testPlayer);
TriggerItem.walk(startFlyingEffect, event);
EasyMock.verify(testPlayer);

EasyMock.resetToNice(testPlayer);
testPlayer.setAllowFlight(false);
EasyMock.expectLastCall();
testPlayer.setFlying(false);
EasyMock.expectLastCall();
EasyMock.replay(testPlayer);
TriggerItem.walk(stopFlyingEffect, event);
EasyMock.verify(testPlayer);
}

}
Loading

0 comments on commit 5843ec8

Please sign in to comment.