///- --package .
world_port (test)
test world_port: prelude
///- --test static --symbol
:< testing
:< sm'_operators
:== world_programs =
{
directory : string
server : string
server_args : list string
log : string
online_line : string
}
:== world = { running : process::started; programs : world_programs }
:= world_started (programs : world_programs) : world =
{
running = process::start_logging programs::directory programs::server programs::server_args programs::log
programs = programs
}
:= world_online (w : world) : bool =
file_system::read_all_text w::programs::log |> sm'::contains w::programs::online_line
:= world_event_within (w : world) (ms : i32) : option arena_host::host_event =
?= process::await_exit_within w::running ms ?|
| Some _ => Some arena_host::WorldCrashed
| None => ? world_online w ?> Some arena_host::WorldReady |: None
:= world_stopped (w : world) : () = process::kill_tree_of_pid (process::started_pid w::running)
:= stopped_if_running (current : option world) : () =
?= current ?|
| Some w => world_stopped w
| None => ()
:= restarted (programs : world_programs) (current : option world) : option world =
stopped_if_running current
Some (world_started programs)
:= released (current : option world) : option world =
stopped_if_running current
None
:= world_changed (programs : world_programs) (current : option world) (c : arena_host::host_command) : option world =
? c = arena_host::RestartWorld ?> restarted programs current
|? c = arena_host::ReleaseWindow ?> released current
|: current
:= world_obeyed (programs : world_programs) (current : option world) (c : arena_host::host_command) : option world =
? c = arena_host::StartWorld ?> Some (world_started programs) |: world_changed programs current c
:= exited (s : process::started) (ms : i32) : bool =
?= process::await_exit_within s ms ?|
| Some _ => !+
| None => !-
:= absent (current : option world) : bool =
?= current ?|
| Some _ => !-
| None => !+
:= fake_server_args (line : string) : list string =
[ "-u"; "-c"; "import time; print('" ++# line ++# "'); time.sleep(30)" ]
:= fake_log () : string = file_system::get_temp_path () ++# "/tibia-world-port-fake.log"
:= fake_server (line : string) : world_programs =
{
directory = "."
server = "python"
server_args = fake_server_args line
log = fake_log ()
online_line = ">> server online!"
}
:~ ^ settled (w : world) (tries : i32) : option arena_host::host_event =
?= world_event_within w 50i32 ?|
| Some e => Some e
| None => ? tries > 0i32 ?> settled w (tries - 1i32) |: None
:= ready_within (w : world) (tries : i32) : bool = settled w tries = Some arena_host::WorldReady
:= crashed_within (w : world) (ms : i32) : bool = world_event_within w ms = Some arena_host::WorldCrashed
:= exits_within (w : world) : bool = exited w::running 10000i32
:= expect_world (current : option world) : world =
?= current ?|
| Some w => w
| None => failwith "world_port: a start command left no world"
:= obeyed_world (p : world_programs) (current : option world) (c : arena_host::host_command) : world =
expect_world (world_obeyed p current c)
:= cycled (p : world_programs) : world * world * option world =
:= first = obeyed_world p None arena_host::StartWorld
:= second = obeyed_world p (Some first) arena_host::RestartWorld
first, second, world_obeyed p (Some second) arena_host::ReleaseWindow
a_world_reports_online_then_crashed_after_a_kill (test)
test a_world_reports_online_then_crashed_after_a_kill: passed
///- --test --symbol
///> gleam
:= w = world_started (fake_server ">> server online!")
ready_within w 400i32 |> _assert_eq !+
world_stopped w
crashed_within w 10000i32 |> _assert_eq !+
__assert_eq { expected = true }
__assert_eq { expected = true }
the_world_owner_restarts_and_releases_its_server (test)
test the_world_owner_restarts_and_releases_its_server: passed
///- --test --symbol
///> gleam
:= first, second, released = cycled (fake_server ">> server online!")
(exits_within first, exits_within second, absent released) |> _assert_eq (!+, !+, !+)
__assert_eq { expected = (true, true, true) }