# session_test.ludic - the roster, the roles, the nearest player, the shared night and votes, # with a fake local player import "ludic.session" import "ludic.base" program SessionTest { numbers float state SessionTestState { me_x: float = 0.0 me_rest: float = 1.0 } let me_z: float = 0.0 function fx(session_test_st: SessionTestState) -> float { return session_test_st.me_x } function fy() -> float { return 0.0 } function fz() -> float { return me_z } function fname() -> string { return "me" } function frest(session_test_st: SessionTestState) -> float { return session_test_st.me_rest } bind SessionLocal { x: fn fx, y: fn fy, z: fn fz, rest: fn frest, name: fn fname } function whats(session_st: SessionState) -> []int { let fs = q_drain(ses_facts(session_st)) let out = new []int for i in 0 .. len(fs) { push(out, fs[i].what) } return out } function last_of(session_st: SessionState, what: int) -> SessionFact { let fs = q_drain(ses_facts(session_st)) var f: SessionFact = null for i in 0 .. len(fs) { if fs[i].what == what { f = fs[i] } } return f } # a host with n guests, pids 2.., facts drained function party(session_st: mut SessionState, n: int) -> void { ses_set_role(session_st, SES_HOST) for i in 0 .. n { ply_join(session_st, 2 + i) } q_clear(ses_facts(session_st)) } test "slot 0 is the local player, read live; others join at its feet and leave" (session_st: mut SessionState, session_test_st: mut SessionTestState) { session_test_st.me_x = 5.0 expect(ply_on(session_st, 0)) expect_near(ply_x(session_st, 0), 5.0, 0.001) expect(ply_name(session_st, 0) == "me") let p = ply_join(session_st, 7) expect_eq(p, 1) expect_near(ply_x(session_st, p), 5.0, 0.001) expect_eq(ply_slot_of(session_st, 7), 1) expect_eq(ply_count(session_st), 2) expect_eq(ply_join(session_st, 0), -1) ply_leave(session_st, p) expect_eq(ply_slot_of(session_st, 7), -1) expect_eq(ply_count(session_st), 1) let w = whats(session_st) expect_eq(len(w), 2) expect_eq(w[0], SES_JOINED) expect_eq(w[1], SES_LEFT) } test "the roster fills at twelve" (session_st: mut SessionState) { for i in 0 .. PLY_MAX - 1 { expect(ply_join(session_st, 10 + i) > 0) } expect_eq(ply_join(session_st, 99), -1) expect_eq(ply_count(session_st), PLY_MAX) ply_leave(session_st, 2) expect(not ply_on(session_st, 2)) expect_eq(ply_join(session_st, 98), 2) ply_leave_all(session_st) expect_eq(ply_count(session_st), 1) } test "alone, the nearest player is this one, at its own distance" (session_st: mut SessionState, session_test_st: mut SessionTestState) { session_test_st.me_x = 3.0 expect_near(ply_near(session_st, 40.0, -21.0), Math.sqrt(37.0 * 37.0 + 21.0 * 21.0), 0.001) expect_eq(ply_near_i(session_st), 0) } test "the party's rest is the least-resting player's: one sitting does not hurry the other" (session_st: mut SessionState, session_test_st: mut SessionTestState) { session_test_st.me_rest = 4.0 expect(ply_rest_least(session_st) == 4.0) let p = ply_join(session_st, 21) expect(ply_rest_least(session_st) == 1.0) ply_report_rest(session_st, p, 3.0, false) expect(ply_rest_least(session_st) == 3.0) ply_leave(session_st, p) expect(ply_rest_least(session_st) == 4.0) session_test_st.me_rest = 1.0 expect(ply_rest_least(session_st) == 1.0) } test "the nearest player, whoever it is" (session_st: mut SessionState, session_test_st: mut SessionTestState) { session_test_st.me_x = 100.0 let p = ply_join(session_st, 2) ply_report(session_st, p, 3.0, 0.0, 4.0, 0.0, 1.0) expect_near(ply_near(session_st, 0.0, 0.0), 5.0, 0.001) expect_eq(ply_near_i(session_st), p) expect_near(ply_dist(session_st, 0, 100.0, 0.0), 0.0, 0.001) } test "roles: alone owns the world, a guest does not, and a change is a fact" (session_st: mut SessionState) { expect(ses_owns_world(session_st)) expect(not ses_live(session_st)) expect(ses_night_passes(session_st)) ses_set_role(session_st, SES_GUEST) expect(not ses_owns_world(session_st)) expect(ses_live(session_st)) expect(not ses_night_passes(session_st)) let f = last_of(session_st, SES_ROLE) expect_eq(f.role, SES_GUEST) ses_set_role(session_st, SES_HOST) expect(ses_owns_world(session_st)) expect(not ses_night_passes(session_st)) } test "the party's size and door" (session_st: mut SessionState) { ses_set_party(session_st, 20, true) expect_eq(ses_max(session_st), PLY_MAX) ses_set_party(session_st, 3, true) party(session_st, 1) expect(ses_room_for_one(session_st)) ply_join(session_st, 9) expect(not ses_room_for_one(session_st)) ses_set_party(session_st, 12, false) expect(not ses_room_for_one(session_st)) } test "the night passes when the host and every guest have turned in" (session_st: mut SessionState) { party(session_st, 2) expect(ses_sleep(session_st, true)) expect_eq(ses_sleep_waiting(session_st), 2) ses_sleep_ready(session_st, 1, true) expect(last_of(session_st, SES_NIGHT) == null) ses_sleep_ready(session_st, 2, true) expect(last_of(session_st, SES_NIGHT) != null) ses_night_passed(session_st) expect(not ses_sleeping(session_st)) } test "a guest's turning in is a fact for the host to hear; alone a bed just sleeps" (session_st: mut SessionState) { expect(not ses_sleep(session_st, true)) ses_set_role(session_st, SES_GUEST) q_clear(ses_facts(session_st)) expect(ses_sleep(session_st, true)) let f = last_of(session_st, SES_SLEEP) expect(f.yes) ses_sleep(session_st, false) expect(not ses_sleeping(session_st)) } test "a vote passes on a majority, the host's yes counted" (session_st: mut SessionState) { party(session_st, 2) expect_eq(ses_may(session_st, 4, 9, "set out"), SES_MAY_ASKED) expect(ses_vote_live(session_st)) expect_eq(ses_may(session_st, 4, 9, "set out"), SES_MAY_BUSY) ses_vote_heard(session_st, ses_vote_id(session_st), true) let f = last_of(session_st, SES_VOTE_RESOLVED) expect(f.yes) expect_eq(f.param, 9) expect(f.text == "set out") expect(not ses_vote_live(session_st)) } test "a vote fails on half saying no, or when the time runs out" (session_st: mut SessionState) { party(session_st, 1) ses_vote_open(session_st, 1, 0, "a") ses_vote_heard(session_st, ses_vote_id(session_st), false) expect(not last_of(session_st, SES_VOTE_RESOLVED).yes) party(session_st, 3) ses_vote_open(session_st, 1, 0, "b") ses_vote_tick(session_st, 31.0) let f = last_of(session_st, SES_VOTE_RESOLVED) expect(f != null) expect(not f.yes) } test "alone it may go; a guest may not, and its vote goes to the host" (session_st: mut SessionState) { expect_eq(ses_may(session_st, 1, 0, "x"), SES_MAY_GO) ses_set_role(session_st, SES_GUEST) expect_eq(ses_may(session_st, 1, 0, "x"), SES_MAY_HOSTS) ses_vote_told(session_st, 5, 1, "x") expect(ses_vote_live(session_st)) q_clear(ses_facts(session_st)) ses_vote_cast(session_st, true) let f = last_of(session_st, SES_VOTE_CAST) expect_eq(f.id, 5) expect(f.yes) ses_vote_ended(session_st, 5, true) expect_eq(ses_vote_passed(session_st), 1) } test "a reset leaves everyone and stands alone" (session_st: mut SessionState) { party(session_st, 2) ses_sleep(session_st, true) ses_reset(session_st) expect_eq(ply_count(session_st), 1) expect_eq(ses_role(session_st), SES_SOLO) expect(not ses_sleeping(session_st)) } }