mirror of
https://github.com/psforever/PSF-LoginServer.git
synced 2026-03-04 21:10:23 +00:00
117 lines
4.3 KiB
Scala
117 lines
4.3 KiB
Scala
|
|
// Copyright (c) 2021 PSForever
|
||
|
|
package objects
|
||
|
|
|
||
|
|
import net.psforever.objects.guid.{Task, TaskBundle, TaskWorkflow}
|
||
|
|
import org.scalatest.flatspec.AsyncFlatSpec
|
||
|
|
|
||
|
|
import scala.concurrent.Future
|
||
|
|
import scala.util.Failure
|
||
|
|
|
||
|
|
class AsyncTaskWorkflowTest extends AsyncFlatSpec {
|
||
|
|
case class StringAppendTask(product: StringBuilder, str: String) extends Task {
|
||
|
|
def action() = { Future({ product.append(str) }) }
|
||
|
|
def undo() = {
|
||
|
|
val index = product.indexOf(str)
|
||
|
|
product.replace(index, index + str.length, "[successful task undo]")
|
||
|
|
}
|
||
|
|
def isSuccessful() = { product.indexOf(str) > -1 }
|
||
|
|
}
|
||
|
|
|
||
|
|
case class FailedStringAppendTask(product: StringBuilder, str: String) extends Task {
|
||
|
|
def action() = { Future(Failure(new Exception("intentional failure"))) }
|
||
|
|
def undo() = {
|
||
|
|
val index = product.indexOf(str)
|
||
|
|
product.replace(index, index + str.length, "[failed task undo]")
|
||
|
|
}
|
||
|
|
def isSuccessful() = { product.indexOf(str) > -1 }
|
||
|
|
}
|
||
|
|
|
||
|
|
behavior of "TaskWorkFlow"
|
||
|
|
|
||
|
|
it should "append a string as a task" in {
|
||
|
|
val test: StringBuilder = new StringBuilder()
|
||
|
|
assert(test.mkString.isEmpty)
|
||
|
|
val result = TaskWorkflow.execute(TaskBundle(StringAppendTask(test, "hello")))
|
||
|
|
result map { _ =>
|
||
|
|
assert(test.mkString.equals("hello"), "async result does not equal 'hello'")
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
it should "append the strings in order of subtask then main task" in {
|
||
|
|
val test: StringBuilder = new StringBuilder()
|
||
|
|
assert(test.mkString.isEmpty)
|
||
|
|
val result = TaskWorkflow.execute(TaskBundle(StringAppendTask(test, " world"), StringAppendTask(test, "hello")))
|
||
|
|
result map { _ =>
|
||
|
|
assert(test.mkString.equals("hello world"), "async result does not equal 'hello world'")
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
it should "append the strings in order of subtasks then main task, with the subtasks being in either order" in {
|
||
|
|
val test: StringBuilder = new StringBuilder()
|
||
|
|
assert(test.mkString.isEmpty)
|
||
|
|
val result = TaskWorkflow.execute(TaskBundle(
|
||
|
|
StringAppendTask(test, " world"),
|
||
|
|
Seq(
|
||
|
|
TaskBundle(StringAppendTask(test, " hello")),
|
||
|
|
TaskBundle(StringAppendTask(test, " or goodbye"))
|
||
|
|
)
|
||
|
|
))
|
||
|
|
result map { _ =>
|
||
|
|
val output = test.mkString
|
||
|
|
assert(
|
||
|
|
output.equals(" or goodbye hello world") || output.equals(" hello or goodbye world"),
|
||
|
|
s"async result '$output' does not equal either pattern"
|
||
|
|
)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
it should "if a task fails, do not undo it" in {
|
||
|
|
val test: StringBuilder = new StringBuilder()
|
||
|
|
assert(test.mkString.isEmpty)
|
||
|
|
val result = TaskWorkflow.execute(TaskBundle(FailedStringAppendTask(test, " world")))
|
||
|
|
result map { _ =>
|
||
|
|
val output = test.mkString
|
||
|
|
assert(output.equals(""),"async result was written when should have not been written")
|
||
|
|
//see implementation of FailedStringAppendTask.undo
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
it should "if a middling subtask fails, its parent task will not be executed or undone, but its own subtask will be undone (1)" in {
|
||
|
|
val test: StringBuilder = new StringBuilder()
|
||
|
|
assert(test.mkString.isEmpty)
|
||
|
|
val result = TaskWorkflow.execute(TaskBundle(
|
||
|
|
StringAppendTask(test, " world"),
|
||
|
|
TaskBundle(FailedStringAppendTask(test, "hello"), StringAppendTask(test, " or goodbye")))
|
||
|
|
)
|
||
|
|
result map { _ =>
|
||
|
|
val output = test.mkString
|
||
|
|
assert(output.equals("[successful task undo]"),s"async result, formerly successful, was written as if it had failed - $output")
|
||
|
|
//see implementation of StringAppendTask.undo
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
it should "if a middling subtask fails, its parent task will not be executed or undone, but its own subtasks will be undone (2)" in {
|
||
|
|
val test: StringBuilder = new StringBuilder()
|
||
|
|
assert(test.mkString.isEmpty)
|
||
|
|
val result = TaskWorkflow.execute(TaskBundle(
|
||
|
|
StringAppendTask(test, " world"),
|
||
|
|
TaskBundle(FailedStringAppendTask(test, "hello"), List(
|
||
|
|
TaskBundle(StringAppendTask(test, " or goodbye")),
|
||
|
|
TaskBundle(StringAppendTask(test, " or something"))
|
||
|
|
))
|
||
|
|
))
|
||
|
|
result map { _ =>
|
||
|
|
val output = test.mkString
|
||
|
|
assert(
|
||
|
|
output.equals("[successful task undo][successful task undo]"),
|
||
|
|
s"async result, formerly successful, was written as if it had failed - $output"
|
||
|
|
)
|
||
|
|
//see implementation of StringAppendTask.undo
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
object TaskWorkflowTest {
|
||
|
|
/** placeholder */
|
||
|
|
}
|