documentation and tests; added projectile names; changed logging level for ActorTests to OFF to remove the majority of log clutter; issue with number pool hub re-assignment and the existence of fixed objects (LocalProjectile) that requires unrelated tests be modified

This commit is contained in:
FateJH 2018-06-15 14:50:42 -04:00
parent c57999d676
commit 000652c969
12 changed files with 556 additions and 191 deletions

View file

@ -3,11 +3,21 @@ package objects
import akka.actor.ActorSystem
import akka.testkit.{ImplicitSender, TestKit}
import com.typesafe.config.{ConfigFactory, ConfigValueFactory}
import org.scalatest.{BeforeAndAfterAll, Matchers, WordSpecLike}
import org.specs2.specification.Scope
abstract class ActorTest(sys : ActorSystem = ActorSystem("system")) extends TestKit(sys) with Scope with ImplicitSender with WordSpecLike with Matchers with BeforeAndAfterAll {
abstract class ActorTest(sys : ActorSystem = ActorSystem("system", ConfigFactory.parseMap(ActorTest.LoggingConfig)))
extends TestKit(sys) with Scope with ImplicitSender with WordSpecLike with Matchers with BeforeAndAfterAll {
override def afterAll {
TestKit.shutdownActorSystem(system)
}
}
object ActorTest {
import scala.collection.JavaConverters._
private val LoggingConfig = Map(
"akka.loglevel" -> ConfigValueFactory.fromAnyRef("OFF"),
"akka.stdout-loglevel" -> ConfigValueFactory.fromAnyRef("OFF")
).asJava
}

View file

@ -0,0 +1,198 @@
// Copyright (c) 2017 PSForever
package objects
import net.psforever.objects.{GlobalDefinitions, LocalProjectile, Tool}
import net.psforever.objects.ballistics.{DamageType, Projectile, ProjectileResolution, Projectiles}
import net.psforever.objects.definition.ProjectileDefinition
import net.psforever.types.Vector3
import org.specs2.mutable.Specification
class ProjectileTest extends Specification {
"LocalProjectile" should {
"construct" in {
val obj = new LocalProjectile() //since they're just placeholders, they only need to construct
obj.Definition.ObjectId mustEqual 0
obj.Definition.Name mustEqual "projectile"
}
}
"ProjectileDefinition" should {
"define (default)" in {
val obj = new ProjectileDefinition(31) //9mmbullet_projectile
obj.ProjectileType mustEqual Projectiles.bullet_9mm_projectile
obj.ObjectId mustEqual 31
obj.Damage0 mustEqual 0
obj.Damage1 mustEqual 0
obj.Damage2 mustEqual 0
obj.Damage3 mustEqual 0
obj.Damage4 mustEqual 0
obj.Acceleration mustEqual 0
obj.AccelerationUntil mustEqual 0f
obj.ProjectileDamageType mustEqual DamageType.None
obj.ProjectileDamageTypeSecondary mustEqual DamageType.None
obj.DegradeDelay mustEqual 1f
obj.DegradeMultiplier mustEqual 1f
obj.InitialVelocity mustEqual 1
obj.Lifespan mustEqual 1f
obj.DamageAtEdge mustEqual 1f
obj.DamageRadius mustEqual 1f
obj.UseDamage1Subtract mustEqual false
}
"define (custom)" in {
val obj = new ProjectileDefinition(31) //9mmbullet_projectile
obj.Damage0 = 2
obj.Damage1 = 4
obj.Damage2 = 8
obj.Damage3 = 16
obj.Damage4 = 32
obj.Acceleration = 5
obj.AccelerationUntil = 5.5f
obj.ProjectileDamageType = DamageType.Splash
obj.ProjectileDamageTypeSecondary = DamageType.Radiation
obj.DegradeDelay = 11.1f
obj.DegradeMultiplier = 22.2f
obj.InitialVelocity = 50
obj.Lifespan = 11.2f
obj.DamageAtEdge = 3f
obj.DamageRadius = 3f
obj.UseDamage1Subtract = true
obj.Damage0 mustEqual 2
obj.Damage1 mustEqual 4
obj.Damage2 mustEqual 8
obj.Damage3 mustEqual 16
obj.Damage4 mustEqual 32
obj.Acceleration mustEqual 5
obj.AccelerationUntil mustEqual 5.5f
obj.ProjectileDamageType mustEqual DamageType.Splash
obj.ProjectileDamageTypeSecondary mustEqual DamageType.Radiation
obj.DegradeDelay mustEqual 11.1f
obj.DegradeMultiplier mustEqual 22.2f
obj.InitialVelocity mustEqual 50
obj.Lifespan mustEqual 11.2f
obj.DamageAtEdge mustEqual 3f
obj.DamageRadius mustEqual 3f
obj.UseDamage1Subtract mustEqual true
}
"define (failure)" in {
Projectiles(31) mustEqual Projectiles.bullet_9mm_projectile
try {
ProjectileDefinition(Projectiles.bullet_9mm_projectile) //passes
}
catch {
case _ : NoSuchElementException =>
ko
}
Projectiles(2) must throwA[NoSuchElementException]
new ProjectileDefinition(2) must throwA[NoSuchElementException]
}
"cascade damage values" in {
val obj = new ProjectileDefinition(31) //9mmbullet_projectile
obj.Damage4 = 32
obj.Damage3 = 16
obj.Damage2 = 8
obj.Damage1 = 4
obj.Damage0 = 2
//initial
obj.Damage4 mustEqual 32
obj.Damage3 mustEqual 16
obj.Damage2 mustEqual 8
obj.Damage1 mustEqual 4
obj.Damage0 mustEqual 2
//negate Damage4
obj.Damage4 = None
obj.Damage4 mustEqual 16
obj.Damage3 mustEqual 16
obj.Damage2 mustEqual 8
obj.Damage1 mustEqual 4
obj.Damage0 mustEqual 2
//negate Damage3
obj.Damage3 = None
obj.Damage4 mustEqual 8
obj.Damage3 mustEqual 8
obj.Damage2 mustEqual 8
obj.Damage1 mustEqual 4
obj.Damage0 mustEqual 2
//negate Damage2
obj.Damage2 = None
obj.Damage4 mustEqual 4
obj.Damage3 mustEqual 4
obj.Damage2 mustEqual 4
obj.Damage1 mustEqual 4
obj.Damage0 mustEqual 2
//negate Damage1
obj.Damage1 = None
obj.Damage4 mustEqual 2
obj.Damage3 mustEqual 2
obj.Damage2 mustEqual 2
obj.Damage1 mustEqual 2
obj.Damage0 mustEqual 2
//negate Damage0
obj.Damage0 = None
obj.Damage4 mustEqual 0
obj.Damage3 mustEqual 0
obj.Damage2 mustEqual 0
obj.Damage1 mustEqual 0
obj.Damage0 mustEqual 0
//set Damage3, set Damage0
obj.Damage3 = 13
obj.Damage0 = 7
obj.Damage4 mustEqual 13
obj.Damage3 mustEqual 13
obj.Damage2 mustEqual 7
obj.Damage1 mustEqual 7
obj.Damage0 mustEqual 7
}
}
"Projectile" should {
"construct" in {
val beamer_wep = Tool(GlobalDefinitions.beamer)
val projectile = beamer_wep.Projectile
val obj = Projectile(projectile, beamer_wep.Definition, Vector3(1.2f, 3.4f, 5.6f), Vector3(0.2f, 0.4f, 0.6f))
obj.profile mustEqual beamer_wep.Projectile
obj.tool_def mustEqual GlobalDefinitions.beamer
obj.shot_origin mustEqual Vector3(1.2f, 3.4f, 5.6f)
obj.shot_angle mustEqual Vector3(0.2f, 0.4f, 0.6f)
obj.resolution mustEqual ProjectileResolution.Unresolved
obj.fire_time <= System.nanoTime mustEqual true
obj.hit_time mustEqual 0
}
"resolve" in {
val beamer_wep = Tool(GlobalDefinitions.beamer)
val projectile = beamer_wep.Projectile
val obj = Projectile(projectile, beamer_wep.Definition, Vector3(1.2f, 3.4f, 5.6f), Vector3(0.2f, 0.4f, 0.6f))
val obj2 = obj.Resolve(ProjectileResolution.MissedShot)
obj.resolution mustEqual ProjectileResolution.Unresolved
obj.fire_time <= System.nanoTime mustEqual true
obj.hit_time mustEqual 0
obj2.resolution mustEqual ProjectileResolution.MissedShot
obj2.fire_time == obj.fire_time mustEqual true
obj2.hit_time <= System.nanoTime mustEqual true
obj2.fire_time <= obj2.hit_time mustEqual true
}
"resolve, with coordinates" in {
val beamer_wep = Tool(GlobalDefinitions.beamer)
val projectile = beamer_wep.Projectile
val obj = Projectile(projectile, beamer_wep.Definition, Vector3(1.2f, 3.4f, 5.6f), Vector3(0.2f, 0.4f, 0.6f))
val obj2 = obj.Resolve(Vector3(7.2f, 8.4f, 9.6f), Vector3(1.2f, 1.4f, 1.6f), ProjectileResolution.Resolved)
obj.resolution mustEqual ProjectileResolution.Unresolved
obj.current.Position mustEqual Vector3.Zero
obj.current.Orientation mustEqual Vector3.Zero
obj2.resolution mustEqual ProjectileResolution.Resolved
obj2.current.Position mustEqual Vector3(7.2f, 8.4f, 9.6f)
obj2.current.Orientation mustEqual Vector3(1.2f, 1.4f, 1.6f)
}
}
}

View file

@ -3,6 +3,7 @@ package objects
import akka.actor.{ActorRef, ActorSystem, Props}
import akka.testkit.TestProbe
import net.psforever.objects.ballistics.Projectile
import net.psforever.objects.serverobject.mount.Mountable
import net.psforever.objects.serverobject.pad.{VehicleSpawnControl, VehicleSpawnPad}
import net.psforever.objects.serverobject.structures.StructureType
@ -326,7 +327,7 @@ object VehicleSpawnPadControlTest {
val zone = new Zone("test-zone", map, 0)
val vehicle = Vehicle(GlobalDefinitions.two_man_assault_buggy)
val weapon = vehicle.WeaponControlledFromSeat(1).get.asInstanceOf[Tool]
val guid : NumberPoolHub = new NumberPoolHub(LimitedNumberSource(3))
val guid : NumberPoolHub = new NumberPoolHub(LimitedNumberSource(40150))
guid.AddPool("test-pool", (0 to 2).toList)
guid.register(vehicle, "test-pool")
guid.register(weapon, "test-pool")

View file

@ -16,6 +16,7 @@ import net.psforever.types.{CharacterGender, CharacterVoice, PlanetSideEmpire, V
import net.psforever.objects.serverobject.structures.{Building, FoundationBuilder, StructureType}
import net.psforever.objects.zones.{Zone, ZoneActor, ZoneMap}
import net.psforever.objects.Vehicle
import net.psforever.objects.ballistics.Projectile
import org.specs2.mutable.Specification
import scala.concurrent.duration._
@ -96,18 +97,15 @@ class ZoneTest extends Specification {
"can have its unique identifier system changed if no objects were added to it" in {
val zone = new Zone("home3", map13, 13)
val guid1 : NumberPoolHub = new NumberPoolHub(new LimitedNumberSource(100))
guid1.AddPool("pool1", (0 to 50).toList)
guid1.AddPool("pool2", (51 to 75).toList)
zone.GUID(guid1) mustEqual true
zone.AddPool("pool1", (0 to 50).toList)
zone.AddPool("pool2", (51 to 75).toList)
val obj = new TestObject()
guid1.register(obj, "pool2").isSuccess mustEqual true
guid1.WhichPool(obj) mustEqual Some("pool2")
val guid2 : NumberPoolHub = new NumberPoolHub(new LimitedNumberSource(150))
guid2.AddPool("pool3", (0 to 50).toList)
guid2.AddPool("pool4", (51 to 75).toList)
zone.GUID(guid2) mustEqual false
zone.GUID(new NumberPoolHub(new LimitedNumberSource(150))) mustEqual false
}
}
}
@ -121,6 +119,48 @@ class ZoneActorTest extends ActorTest {
assert(zone.Actor != ActorRef.noSender)
}
"create new number pools before the Actor is started" in {
val zone = new Zone("test", new ZoneMap("map6"), 1)
zone.GUID(new NumberPoolHub(new LimitedNumberSource(10)))
assert( zone.AddPool("test1", 1 to 2) )
zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), "test-add-pool-actor") //note: not Init'd yet
assert( zone.AddPool("test2", 3 to 4) )
}
"remove existing number pools before the Actor is started" in {
val zone = new Zone("test", new ZoneMap("map6"), 1)
zone.GUID(new NumberPoolHub(new LimitedNumberSource(10)))
assert( zone.AddPool("test1", 1 to 2) )
assert( zone.RemovePool("test1") )
zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), "test-remove-pool-actor") //note: not Init'd yet
assert( zone.AddPool("test2", 3 to 4) )
assert( zone.RemovePool("test2") )
}
"refuse new number pools after the Actor is started" in {
val zone = new Zone("test", new ZoneMap("map6"), 1)
zone.GUID(new NumberPoolHub(new LimitedNumberSource(40150)))
zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), "test-add-pool-actor-init")
zone.Actor ! Zone.Init()
expectNoMsg(Duration.create(300, "ms"))
assert( !zone.AddPool("test1", 1 to 2) )
}
"refuse to remove number pools after the Actor is started" in {
val zone = new Zone("test", new ZoneMap("map6"), 1)
zone.GUID(new NumberPoolHub(new LimitedNumberSource(40150)))
zone.AddPool("test", 1 to 2)
zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), "test-remove-pool-actor-init")
zone.Actor ! Zone.Init()
expectNoMsg(Duration.create(300, "ms"))
assert( !zone.RemovePool("test") )
}
"set up spawn groups based on buildings" in {
val map6 = new ZoneMap("map6") {
LocalBuilding(1, FoundationBuilder(Building.Structure(StructureType.Building, Vector3(1,1,1))))
@ -225,6 +265,20 @@ class ZoneActorTest extends ActorTest {
assert(reply.asInstanceOf[Zone.Lattice.NoValidSpawnPoint].spawn_group.contains(7))
}
}
"populate a series of reference projectiles" in {
val zone = new Zone("test", new ZoneMap("map6"), 1)
zone.Actor = system.actorOf(Props(classOf[ZoneActor], zone), "test-projectiles")
zone.Actor ! Zone.Init()
expectNoMsg(Duration.create(300, "ms"))
(Projectile.BaseUID until Projectile.RangeUID)
.map { zone.GUID }
.collect {
case Some(_ : LocalProjectile) => ; //pass
case _ => assert(false)
}
}
}
class ZonePopulationTest extends ActorTest {
@ -466,7 +520,7 @@ class ZonePopulationTest extends ActorTest {
class ZoneGroundDropItemTest extends ActorTest {
val item = AmmoBox(GlobalDefinitions.bullet_9mm)
val hub = new NumberPoolHub(new LimitedNumberSource(20))
val hub = new NumberPoolHub(new LimitedNumberSource(40150))
hub.register(item, 10)
val zone = new Zone("test", new ZoneMap("test-map"), 0)
zone.GUID(hub)
@ -490,7 +544,7 @@ class ZoneGroundDropItemTest extends ActorTest {
class ZoneGroundCanNotDropItem1Test extends ActorTest {
val item = AmmoBox(GlobalDefinitions.bullet_9mm)
val hub = new NumberPoolHub(new LimitedNumberSource(20))
val hub = new NumberPoolHub(new LimitedNumberSource(40150))
//hub.register(item, 10) //!important
val zone = new Zone("test", new ZoneMap("test-map"), 0)
zone.GUID(hub)
@ -538,7 +592,7 @@ class ZoneGroundCanNotDropItem2Test extends ActorTest {
class ZoneGroundCanNotDropItem3Test extends ActorTest {
val item = AmmoBox(GlobalDefinitions.bullet_9mm)
val hub = new NumberPoolHub(new LimitedNumberSource(20))
val hub = new NumberPoolHub(new LimitedNumberSource(40150))
hub.register(item, 10) //!important
val zone = new Zone("test", new ZoneMap("test-map"), 0)
zone.GUID(hub) //!important
@ -570,7 +624,7 @@ class ZoneGroundCanNotDropItem3Test extends ActorTest {
class ZoneGroundPickupItemTest extends ActorTest {
val item = AmmoBox(GlobalDefinitions.bullet_9mm)
val hub = new NumberPoolHub(new LimitedNumberSource(20))
val hub = new NumberPoolHub(new LimitedNumberSource(40150))
hub.register(item, 10)
val zone = new Zone("test", new ZoneMap("test-map"), 0)
zone.GUID(hub)
@ -597,7 +651,7 @@ class ZoneGroundPickupItemTest extends ActorTest {
class ZoneGroundCanNotPickupItemTest extends ActorTest {
val item = AmmoBox(GlobalDefinitions.bullet_9mm)
val hub = new NumberPoolHub(new LimitedNumberSource(20))
val hub = new NumberPoolHub(new LimitedNumberSource(40150))
hub.register(item, 10)
val zone = new Zone("test", new ZoneMap("test-map"), 0)
zone.GUID(hub) //still registered to this zone
@ -620,7 +674,7 @@ class ZoneGroundCanNotPickupItemTest extends ActorTest {
class ZoneGroundRemoveItemTest extends ActorTest {
val item = AmmoBox(GlobalDefinitions.bullet_9mm)
val hub = new NumberPoolHub(new LimitedNumberSource(20))
val hub = new NumberPoolHub(new LimitedNumberSource(40150))
hub.register(item, 10)
val zone = new Zone("test", new ZoneMap("test-map"), 0)
zone.GUID(hub) //still registered to this zone