Remove test context from plugin testing framework

This commit is contained in:
Gary Tierney
2017-06-19 17:14:24 +01:00
parent b536b2ed9d
commit b532168551
6 changed files with 106 additions and 135 deletions
+2
View File
@@ -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
View File
@@ -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)
}
}
@@ -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)
}
}
+8 -10
View File
@@ -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))
}
}