mirror of
https://github.com/2006-Scape/apollo.git
synced 2026-07-07 08:39:17 +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-stdlib-jre8', version: "$kotlinVersion"
|
||||||
compile group: 'org.jetbrains.kotlin', name: 'kotlin-compiler-embeddable', 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"
|
testCompile "org.jetbrains.kotlin:kotlin-test-junit:$kotlinVersion"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+7
-5
@@ -17,11 +17,7 @@ buildscript {
|
|||||||
}
|
}
|
||||||
|
|
||||||
task testPlugins {
|
task testPlugins {
|
||||||
group = "plugin-verification"
|
|
||||||
|
|
||||||
doLast {
|
|
||||||
println("Finished executing plugin tests")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
@@ -95,7 +91,6 @@ def configurePluginTasks(String name, SourceSet mainSources, SourceSet testSourc
|
|||||||
binResultsDir = file("$buildDir/plugin-test-results/binary/$name")
|
binResultsDir = file("$buildDir/plugin-test-results/binary/$name")
|
||||||
|
|
||||||
reports {
|
reports {
|
||||||
html.destination = "$buildDir/reports/plugin-tests/$name"
|
|
||||||
junitXml.destination = "$buildDir/plugin-tests/$name"
|
junitXml.destination = "$buildDir/plugin-tests/$name"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,3 +201,10 @@ pluginMap.values().each {
|
|||||||
configurePluginDependencies(it.mainSources, it.testSources, dependencies)
|
configurePluginDependencies(it.mainSources, it.testSources, dependencies)
|
||||||
configurePluginTasks(it.normalizedName, it.mainSources, it.testSources, it.scriptFiles, 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
|
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.MessageHandler
|
||||||
import org.apollo.game.message.handler.MessageHandlerChainSet
|
import org.apollo.game.message.handler.MessageHandlerChainSet
|
||||||
import org.apollo.game.model.Position
|
import org.apollo.game.message.impl.*
|
||||||
import org.apollo.game.model.World
|
import org.apollo.game.model.*
|
||||||
import org.apollo.game.model.entity.Player
|
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.game.plugin.*
|
||||||
import org.apollo.net.message.Message
|
import org.apollo.net.message.Message
|
||||||
import org.apollo.util.security.PlayerCredentials
|
import org.apollo.util.security.PlayerCredentials
|
||||||
import org.junit.After
|
import org.junit.Assert
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
|
import org.mockito.ArgumentCaptor
|
||||||
import org.mockito.Matchers.any
|
import org.mockito.Matchers.any
|
||||||
import org.mockito.Mockito.mock
|
import org.mockito.Mockito
|
||||||
import org.mockito.invocation.InvocationOnMock
|
import org.mockito.invocation.InvocationOnMock
|
||||||
import org.mockito.stubbing.Answer
|
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.core.classloader.annotations.PrepareForTest
|
||||||
import org.powermock.modules.junit4.PowerMockRunner
|
import org.powermock.modules.junit4.PowerMockRunner
|
||||||
import java.util.*
|
import java.util.*
|
||||||
@@ -23,24 +28,22 @@ import java.util.*
|
|||||||
@RunWith(PowerMockRunner::class)
|
@RunWith(PowerMockRunner::class)
|
||||||
@PrepareForTest(World::class, PluginContext::class, Player::class)
|
@PrepareForTest(World::class, PluginContext::class, Player::class)
|
||||||
abstract class KotlinPluginTest {
|
abstract class KotlinPluginTest {
|
||||||
private var ctx: KotlinPluginTestContext? = null
|
lateinit var world: World
|
||||||
|
lateinit var player: Player
|
||||||
protected fun context(): KotlinPluginTestContext {
|
lateinit var messageHandlers: MessageHandlerChainSet
|
||||||
return ctx ?: throw IllegalStateException("Setup method not called")
|
|
||||||
}
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setup() {
|
fun setup() {
|
||||||
val messageHandlerChainSet = MessageHandlerChainSet()
|
messageHandlers = MessageHandlerChainSet()
|
||||||
val world = spy<World>(World())
|
world = PowerMockito.spy(World())
|
||||||
|
|
||||||
val answer = Answer<Any?> { invocation: InvocationOnMock ->
|
val answer = Answer<Any?> { invocation: InvocationOnMock ->
|
||||||
messageHandlerChainSet.putHandler(
|
messageHandlers.putHandler(
|
||||||
invocation.arguments[0] as Class<Message>,
|
invocation.arguments[0] as Class<Message>,
|
||||||
invocation.arguments[1] as MessageHandler<*>)
|
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)
|
val pluginEnvironment = KotlinPluginEnvironment(world)
|
||||||
|
|
||||||
pluginEnvironment.setContext(pluginContext)
|
pluginEnvironment.setContext(pluginContext)
|
||||||
@@ -48,21 +51,63 @@ abstract class KotlinPluginTest {
|
|||||||
|
|
||||||
val credentials = PlayerCredentials("test", "test", 1, 1, "0.0.0.0")
|
val credentials = PlayerCredentials("test", "test", 1, 1, "0.0.0.0")
|
||||||
val position = Position(3200, 3200, 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)
|
val region = world.regionRepository.fromPosition(position)
|
||||||
|
|
||||||
|
player = PowerMockito.spy(Player(world, credentials, position))
|
||||||
|
world.register(player)
|
||||||
region.addEntity(player)
|
region.addEntity(player)
|
||||||
|
|
||||||
ctx = KotlinPluginTestContext(world, player, messageHandlerChainSet)
|
PowerMockito.doNothing().`when`(player).send(any())
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
fun interactWith(entity: Entity, option: Int = 1) {
|
||||||
fun destroy() {
|
player.position = entity.position.step(1, Direction.NORTH)
|
||||||
ctx!!.shutdown()
|
|
||||||
|
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
|
@Test
|
||||||
fun `Interacting with a bank teller should open the players bank`() {
|
fun `Interacting with a bank teller should open the players bank`() {
|
||||||
val ctx = context()
|
val bankTeller = spawnNpc(BANK_TELLER_ID, BANK_POSITION)
|
||||||
val bankTeller = ctx.spawnNpc(BANK_TELLER_ID, BANK_POSITION)
|
|
||||||
|
|
||||||
// @todo - these option numbers only match by coincidence, we should be looking up the correct ones
|
// @todo - these option numbers only match by coincidence, we should be looking up the correct ones
|
||||||
ctx.interactWith(bankTeller, option = 2)
|
interactWith(bankTeller, option = 2)
|
||||||
ctx.waitForActionCompletion()
|
waitForActionCompletion()
|
||||||
|
|
||||||
verify(ctx.activePlayer).openBank()
|
verify(player).openBank()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `Interacting with a bank booth object should open the players bank`() {
|
fun `Interacting with a bank booth object should open the players bank`() {
|
||||||
val ctx = context()
|
val bankBooth = spawnObject(BANK_BOOTH_ID, BANK_POSITION)
|
||||||
val bankBooth = ctx.spawnObject(BANK_BOOTH_ID, BANK_POSITION)
|
|
||||||
|
|
||||||
ctx.interactWith(bankBooth, option = 2)
|
interactWith(bankBooth, option = 2)
|
||||||
ctx.waitForActionCompletion()
|
waitForActionCompletion()
|
||||||
|
|
||||||
verify(ctx.activePlayer).openBank()
|
verify(player).openBank()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,12 +1,10 @@
|
|||||||
import org.apollo.game.model.Position
|
import org.apollo.game.model.Position
|
||||||
import org.apollo.game.model.entity.Skill
|
import org.apollo.game.model.entity.Skill
|
||||||
import org.apollo.game.model.entity.SkillSet
|
|
||||||
import org.apollo.game.plugins.testing.KotlinPluginTest
|
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.junit.Test
|
||||||
import org.mockito.Matchers
|
import org.mockito.Mockito.*
|
||||||
import org.mockito.Matchers.*
|
|
||||||
import org.mockito.Mockito.verify
|
|
||||||
|
|
||||||
class TrainingDummyTest : KotlinPluginTest() {
|
class TrainingDummyTest : KotlinPluginTest() {
|
||||||
|
|
||||||
@@ -16,30 +14,30 @@ class TrainingDummyTest : KotlinPluginTest() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test fun `Hitting the training dummy should give the player attack experience`() {
|
@Test fun `Hitting the training dummy should give the player attack experience`() {
|
||||||
val ctx = context()
|
val dummy = spawnObject(DUMMY_ID, DUMMY_POSITION)
|
||||||
val dummy = ctx.spawnObject(DUMMY_ID, DUMMY_POSITION)
|
val skills = player.skillSet
|
||||||
val skills = ctx.activePlayer.skillSet
|
val beforeExp = skills.getExperience(Skill.ATTACK)
|
||||||
val attackExp = skills.getExperience(Skill.ATTACK)
|
|
||||||
|
|
||||||
ctx.interactWith(dummy, option = 2)
|
interactWith(dummy, option = 2)
|
||||||
ctx.waitForActionCompletion()
|
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`() {
|
@Test fun `The player should stop getting attack experience from the training dummy at level 8`() {
|
||||||
val ctx = context()
|
val dummy = spawnObject(DUMMY_ID, DUMMY_POSITION)
|
||||||
|
val skills = player.skillSet
|
||||||
val dummy = ctx.spawnObject(DUMMY_ID, DUMMY_POSITION)
|
|
||||||
val skills = ctx.activePlayer.skillSet
|
|
||||||
skills.setMaximumLevel(Skill.ATTACK, 8)
|
skills.setMaximumLevel(Skill.ATTACK, 8)
|
||||||
val attackExp = skills.getExperience(Skill.ATTACK)
|
val beforeExp = skills.getExperience(Skill.ATTACK)
|
||||||
|
|
||||||
ctx.interactWith(dummy, option = 2)
|
interactWith(dummy, option = 2)
|
||||||
ctx.waitForActionCompletion()
|
waitForActionCompletion()
|
||||||
|
|
||||||
verify(ctx.activePlayer).sendMessage(contains("nothing more you can learn"))
|
val afterExp = skills.getExperience(Skill.ATTACK)
|
||||||
assertTrue("Attack exp has changed since hitting the dummy", attackExp == skills.getExperience(Skill.ATTACK))
|
|
||||||
|
verify(player).sendMessage(contains("nothing more you can learn"))
|
||||||
|
assertThat(afterExp, equalTo(beforeExp))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user