mirror of
https://github.com/2006-Scape/apollo.git
synced 2026-07-03 00:38:21 +00:00
Remove test context from plugin testing framework
This commit is contained in:
@@ -33,6 +33,8 @@ dependencies {
|
||||
compile group: 'org.jetbrains.kotlin', name: 'kotlin-stdlib-jre8', version: "$kotlinVersion"
|
||||
compile group: 'org.jetbrains.kotlin', name: 'kotlin-compiler-embeddable', version: "$kotlinVersion"
|
||||
|
||||
// https://mvnrepository.com/artifact/org.hamcrest/hamcrest-all
|
||||
testCompile group: 'org.hamcrest', name: 'hamcrest-all', version: '1.3'
|
||||
testCompile "org.jetbrains.kotlin:kotlin-test-junit:$kotlinVersion"
|
||||
}
|
||||
|
||||
|
||||
+7
-5
@@ -17,11 +17,7 @@ buildscript {
|
||||
}
|
||||
|
||||
task testPlugins {
|
||||
group = "plugin-verification"
|
||||
|
||||
doLast {
|
||||
println("Finished executing plugin tests")
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
@@ -95,7 +91,6 @@ def configurePluginTasks(String name, SourceSet mainSources, SourceSet testSourc
|
||||
binResultsDir = file("$buildDir/plugin-test-results/binary/$name")
|
||||
|
||||
reports {
|
||||
html.destination = "$buildDir/reports/plugin-tests/$name"
|
||||
junitXml.destination = "$buildDir/plugin-tests/$name"
|
||||
}
|
||||
|
||||
@@ -206,3 +201,10 @@ pluginMap.values().each {
|
||||
configurePluginDependencies(it.mainSources, it.testSources, dependencies)
|
||||
configurePluginTasks(it.normalizedName, it.mainSources, it.testSources, it.scriptFiles, dependencies)
|
||||
}
|
||||
|
||||
task testPluginsReport(type: TestReport) {
|
||||
destinationDir = file("$buildDir/reports/plugin-tests")
|
||||
reportOn tasks.findAll { it.group.equals("plugin-verification"); }
|
||||
}
|
||||
|
||||
testPlugins.finalizedBy testPluginsReport
|
||||
@@ -1,21 +1,26 @@
|
||||
package org.apollo.game.plugins.testing
|
||||
|
||||
import org.apollo.cache.def.NpcDefinition
|
||||
import org.apollo.game.action.Action
|
||||
import org.apollo.game.message.handler.MessageHandler
|
||||
import org.apollo.game.message.handler.MessageHandlerChainSet
|
||||
import org.apollo.game.model.Position
|
||||
import org.apollo.game.model.World
|
||||
import org.apollo.game.model.entity.Player
|
||||
import org.apollo.game.message.impl.*
|
||||
import org.apollo.game.model.*
|
||||
import org.apollo.game.model.entity.*
|
||||
import org.apollo.game.model.entity.obj.GameObject
|
||||
import org.apollo.game.model.entity.obj.StaticGameObject
|
||||
import org.apollo.game.plugin.*
|
||||
import org.apollo.net.message.Message
|
||||
import org.apollo.util.security.PlayerCredentials
|
||||
import org.junit.After
|
||||
import org.junit.Assert
|
||||
import org.junit.Before
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.ArgumentCaptor
|
||||
import org.mockito.Matchers.any
|
||||
import org.mockito.Mockito.mock
|
||||
import org.mockito.Mockito
|
||||
import org.mockito.invocation.InvocationOnMock
|
||||
import org.mockito.stubbing.Answer
|
||||
import org.powermock.api.mockito.PowerMockito.spy
|
||||
import org.powermock.api.mockito.PowerMockito
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest
|
||||
import org.powermock.modules.junit4.PowerMockRunner
|
||||
import java.util.*
|
||||
@@ -23,24 +28,22 @@ import java.util.*
|
||||
@RunWith(PowerMockRunner::class)
|
||||
@PrepareForTest(World::class, PluginContext::class, Player::class)
|
||||
abstract class KotlinPluginTest {
|
||||
private var ctx: KotlinPluginTestContext? = null
|
||||
|
||||
protected fun context(): KotlinPluginTestContext {
|
||||
return ctx ?: throw IllegalStateException("Setup method not called")
|
||||
}
|
||||
lateinit var world: World
|
||||
lateinit var player: Player
|
||||
lateinit var messageHandlers: MessageHandlerChainSet
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
val messageHandlerChainSet = MessageHandlerChainSet()
|
||||
val world = spy<World>(World())
|
||||
messageHandlers = MessageHandlerChainSet()
|
||||
world = PowerMockito.spy(World())
|
||||
|
||||
val answer = Answer<Any?> { invocation: InvocationOnMock ->
|
||||
messageHandlerChainSet.putHandler(
|
||||
messageHandlers.putHandler(
|
||||
invocation.arguments[0] as Class<Message>,
|
||||
invocation.arguments[1] as MessageHandler<*>)
|
||||
}
|
||||
|
||||
val pluginContext = mock<PluginContext>(PluginContext::class.java, answer)
|
||||
val pluginContext = PowerMockito.mock<PluginContext>(PluginContext::class.java, answer)
|
||||
val pluginEnvironment = KotlinPluginEnvironment(world)
|
||||
|
||||
pluginEnvironment.setContext(pluginContext)
|
||||
@@ -48,21 +51,63 @@ abstract class KotlinPluginTest {
|
||||
|
||||
val credentials = PlayerCredentials("test", "test", 1, 1, "0.0.0.0")
|
||||
val position = Position(3200, 3200, 0)
|
||||
|
||||
val player = spy<Player>(Player(world, credentials, position))
|
||||
org.powermock.api.mockito.PowerMockito.doNothing().`when`(player).send(any<Message>())
|
||||
|
||||
world.register(player)
|
||||
|
||||
val region = world.regionRepository.fromPosition(position)
|
||||
|
||||
player = PowerMockito.spy(Player(world, credentials, position))
|
||||
world.register(player)
|
||||
region.addEntity(player)
|
||||
|
||||
ctx = KotlinPluginTestContext(world, player, messageHandlerChainSet)
|
||||
PowerMockito.doNothing().`when`(player).send(any())
|
||||
}
|
||||
|
||||
@After
|
||||
fun destroy() {
|
||||
ctx!!.shutdown()
|
||||
fun interactWith(entity: Entity, option: Int = 1) {
|
||||
player.position = entity.position.step(1, Direction.NORTH)
|
||||
|
||||
when (entity) {
|
||||
is GameObject -> notify(ObjectActionMessage(option, entity.id, entity.position))
|
||||
is Npc -> notify(NpcActionMessage(option, entity.index))
|
||||
is Player -> notify(PlayerActionMessage(option, entity.index))
|
||||
}
|
||||
}
|
||||
|
||||
fun spawnNpc(id: Int, position: Position): Npc {
|
||||
val definition = NpcDefinition(id)
|
||||
val npc = Npc(world, position, definition, arrayOfNulls(4))
|
||||
val region = world.regionRepository.fromPosition(position)
|
||||
val npcs = world.npcRepository
|
||||
|
||||
npcs.add(npc)
|
||||
region.addEntity(npc)
|
||||
|
||||
return npc
|
||||
}
|
||||
|
||||
fun spawnObject(id: Int, position: Position): GameObject {
|
||||
val obj = StaticGameObject(world, id, position, 0, 0)
|
||||
|
||||
world.spawn(obj)
|
||||
|
||||
return obj
|
||||
}
|
||||
|
||||
fun notify(message: Message) {
|
||||
messageHandlers.notify(player, message)
|
||||
}
|
||||
|
||||
fun waitForActionCompletion(predicate: (Action<Player>) -> Boolean = { _ -> true }, timeout: Int = 15) {
|
||||
val actionCaptor: ArgumentCaptor<Action<*>> = ArgumentCaptor.forClass(Action::class.java)
|
||||
Mockito.verify(player).startAction(actionCaptor.capture())
|
||||
|
||||
val action: Action<Player> = actionCaptor.value as Action<Player>
|
||||
Assert.assertTrue("Found wrong action type", predicate.invoke(action))
|
||||
|
||||
var pulses = 0
|
||||
|
||||
do {
|
||||
action.pulse()
|
||||
} while (action.isRunning && pulses++ < timeout)
|
||||
|
||||
Assert.assertFalse("Exceeded timeout waiting for action completion", pulses > timeout)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
-74
@@ -1,74 +0,0 @@
|
||||
package org.apollo.game.plugins.testing
|
||||
|
||||
import org.apollo.cache.def.NpcDefinition
|
||||
import org.apollo.game.action.Action
|
||||
import org.apollo.game.message.handler.MessageHandlerChainSet
|
||||
import org.apollo.game.message.impl.*
|
||||
import org.apollo.game.model.*
|
||||
import org.apollo.game.model.entity.*
|
||||
import org.apollo.game.model.entity.obj.GameObject
|
||||
import org.apollo.game.model.entity.obj.StaticGameObject
|
||||
import org.apollo.net.message.Message
|
||||
import org.junit.Assert
|
||||
import org.mockito.ArgumentCaptor
|
||||
import org.mockito.Mockito
|
||||
|
||||
|
||||
class KotlinPluginTestContext(val world: World, val activePlayer: Player, val messageHandlers: MessageHandlerChainSet) {
|
||||
|
||||
fun interactWith(entity: Entity, option: Int = 1) {
|
||||
activePlayer.position = entity.position.step(1, Direction.NORTH)
|
||||
|
||||
when (entity) {
|
||||
is GameObject -> notify(ObjectActionMessage(option, entity.id, entity.position))
|
||||
is Npc -> notify(NpcActionMessage(option, entity.index))
|
||||
is Player -> notify(PlayerActionMessage(option, entity.index))
|
||||
}
|
||||
}
|
||||
|
||||
fun spawnNpc(id: Int, position: Position): Npc {
|
||||
val definition = NpcDefinition(id)
|
||||
val npc = Npc(world, position, definition, arrayOfNulls(4))
|
||||
val region = world.regionRepository.fromPosition(position)
|
||||
val npcs = world.npcRepository
|
||||
|
||||
world.register(npc)
|
||||
npcs.add(npc)
|
||||
region.addEntity(npc)
|
||||
|
||||
return npc
|
||||
}
|
||||
|
||||
fun spawnObject(id: Int, position: Position): GameObject {
|
||||
val obj = StaticGameObject(world, id, position, 0, 0)
|
||||
|
||||
world.spawn(obj)
|
||||
|
||||
return obj
|
||||
}
|
||||
|
||||
fun notify(message: Message) {
|
||||
messageHandlers.notify(activePlayer, message)
|
||||
}
|
||||
|
||||
fun shutdown() {
|
||||
|
||||
}
|
||||
|
||||
fun waitForActionCompletion(predicate: (Action<Player>) -> Boolean = { _ -> true }, timeout: Int = 15) {
|
||||
val actionCaptor: ArgumentCaptor<Action<*>> = ArgumentCaptor.forClass(Action::class.java)
|
||||
Mockito.verify(activePlayer).startAction(actionCaptor.capture())
|
||||
|
||||
val action: Action<Player> = actionCaptor.value as Action<Player>
|
||||
Assert.assertTrue("Found wrong action type", predicate.invoke(action))
|
||||
|
||||
var pulses = 0
|
||||
|
||||
do {
|
||||
action.pulse()
|
||||
} while (action.isRunning && pulses++ < timeout)
|
||||
|
||||
Assert.assertFalse("Exceeded timeout waiting for action completion", pulses > timeout)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,25 +14,23 @@ class OpenBankTest() : KotlinPluginTest() {
|
||||
|
||||
@Test
|
||||
fun `Interacting with a bank teller should open the players bank`() {
|
||||
val ctx = context()
|
||||
val bankTeller = ctx.spawnNpc(BANK_TELLER_ID, BANK_POSITION)
|
||||
val bankTeller = spawnNpc(BANK_TELLER_ID, BANK_POSITION)
|
||||
|
||||
// @todo - these option numbers only match by coincidence, we should be looking up the correct ones
|
||||
ctx.interactWith(bankTeller, option = 2)
|
||||
ctx.waitForActionCompletion()
|
||||
interactWith(bankTeller, option = 2)
|
||||
waitForActionCompletion()
|
||||
|
||||
verify(ctx.activePlayer).openBank()
|
||||
verify(player).openBank()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Interacting with a bank booth object should open the players bank`() {
|
||||
val ctx = context()
|
||||
val bankBooth = ctx.spawnObject(BANK_BOOTH_ID, BANK_POSITION)
|
||||
val bankBooth = spawnObject(BANK_BOOTH_ID, BANK_POSITION)
|
||||
|
||||
ctx.interactWith(bankBooth, option = 2)
|
||||
ctx.waitForActionCompletion()
|
||||
interactWith(bankBooth, option = 2)
|
||||
waitForActionCompletion()
|
||||
|
||||
verify(ctx.activePlayer).openBank()
|
||||
verify(player).openBank()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,12 +1,10 @@
|
||||
import org.apollo.game.model.Position
|
||||
import org.apollo.game.model.entity.Skill
|
||||
import org.apollo.game.model.entity.SkillSet
|
||||
import org.apollo.game.plugins.testing.KotlinPluginTest
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.hamcrest.Matchers.*
|
||||
import org.junit.Assert.*
|
||||
import org.junit.Test
|
||||
import org.mockito.Matchers
|
||||
import org.mockito.Matchers.*
|
||||
import org.mockito.Mockito.verify
|
||||
import org.mockito.Mockito.*
|
||||
|
||||
class TrainingDummyTest : KotlinPluginTest() {
|
||||
|
||||
@@ -16,30 +14,30 @@ class TrainingDummyTest : KotlinPluginTest() {
|
||||
}
|
||||
|
||||
@Test fun `Hitting the training dummy should give the player attack experience`() {
|
||||
val ctx = context()
|
||||
val dummy = ctx.spawnObject(DUMMY_ID, DUMMY_POSITION)
|
||||
val skills = ctx.activePlayer.skillSet
|
||||
val attackExp = skills.getExperience(Skill.ATTACK)
|
||||
val dummy = spawnObject(DUMMY_ID, DUMMY_POSITION)
|
||||
val skills = player.skillSet
|
||||
val beforeExp = skills.getExperience(Skill.ATTACK)
|
||||
|
||||
ctx.interactWith(dummy, option = 2)
|
||||
ctx.waitForActionCompletion()
|
||||
interactWith(dummy, option = 2)
|
||||
waitForActionCompletion()
|
||||
|
||||
assertTrue("Did not gain exp after hitting dummy", skills.getExperience(Skill.ATTACK) > attackExp)
|
||||
val afterExp = skills.getExperience(Skill.ATTACK)
|
||||
assertThat(afterExp, greaterThan(beforeExp))
|
||||
}
|
||||
|
||||
@Test fun `The player should stop getting attack experience from the training dummy at level 8`() {
|
||||
val ctx = context()
|
||||
|
||||
val dummy = ctx.spawnObject(DUMMY_ID, DUMMY_POSITION)
|
||||
val skills = ctx.activePlayer.skillSet
|
||||
val dummy = spawnObject(DUMMY_ID, DUMMY_POSITION)
|
||||
val skills = player.skillSet
|
||||
skills.setMaximumLevel(Skill.ATTACK, 8)
|
||||
val attackExp = skills.getExperience(Skill.ATTACK)
|
||||
val beforeExp = skills.getExperience(Skill.ATTACK)
|
||||
|
||||
ctx.interactWith(dummy, option = 2)
|
||||
ctx.waitForActionCompletion()
|
||||
interactWith(dummy, option = 2)
|
||||
waitForActionCompletion()
|
||||
|
||||
verify(ctx.activePlayer).sendMessage(contains("nothing more you can learn"))
|
||||
assertTrue("Attack exp has changed since hitting the dummy", attackExp == skills.getExperience(Skill.ATTACK))
|
||||
val afterExp = skills.getExperience(Skill.ATTACK)
|
||||
|
||||
verify(player).sendMessage(contains("nothing more you can learn"))
|
||||
assertThat(afterExp, equalTo(beforeExp))
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user