diff --git a/mods/lobby/buttons.lua b/mods/lobby/buttons.lua index c5919a9..587cdb2 100644 --- a/mods/lobby/buttons.lua +++ b/mods/lobby/buttons.lua @@ -342,16 +342,7 @@ minetest.register_node('lobby:button_1', { color = {a = 0, r = 255, g = 255, b = 255} }) puncher:set_properties({visual_size = {x = 0, y = 0}, collisionbox = {-0.3, 0.0, -0.3, 0.3, 1.7, 0.3}}) - player_attributes:set_string('mode', 'solo') - local privs = minetest.get_player_privs(name) - local player_inv = puncher:get_inventory() - player_inv:set_list('main', {}) - player_inv:set_size('main', 16) - privs.fly = nil - privs.fast = nil - privs.creative = nil - privs.areas = nil - minetest.set_player_privs(name, privs) + lobby.builder_to_player(puncher) puncher:set_pos(game_pos) lobby.game[name] = map_id..'_solo' minetest.chat_send_player(name, 'Travel back to the lobby with the /lobby chat command.') diff --git a/mods/lobby/functions.lua b/mods/lobby/functions.lua index 6e424b0..739302c 100644 --- a/mods/lobby/functions.lua +++ b/mods/lobby/functions.lua @@ -235,3 +235,63 @@ function lobby.traitor_win(traitor, map_id) local map_name = game_data['map_name'] or map_id minetest.chat_send_all('The traitor was victorious on this round in the '..map_name) end + +--[[ is_builder(player: ObjectRef): bool + +Return true if `player` has builder privs. +--]] +function lobby.is_builder(player) + if player == nil then return nil end + + local name = player:get_player_name() + return minetest.check_player_privs(name, {builder = true}) +end + +--[[ builder_to_player(player: ObjectRef) + +Cast builder into regular player, including switching inventories, revoking privs, etc. +--]] +function lobby.builder_to_player(player) + if player == nil then return end + + local pl_name = player:get_player_name() + local pl_attr = player:get_meta() + local pl_priv = minetest.get_player_privs(pl_name) + pl_priv.creative = nil + pl_priv.fly = nil + pl_priv.fast = nil + pl_priv.worldedit = nil + pl_priv.areas = nil + minetest.set_player_privs(pl_name, pl_priv) + pl_attr:set_string('mode', 'solo') + local inv = player:get_inventory() + local old_inv = inv:get_list('main') + inv:set_list('builder', old_inv) + inv:set_size('main', 16) + inv:set_list('main', {}) +end + +--[[ player_to_builder(player: ObjectRef) + +Cast regular player into builder, including switching inventories, granting privs, etc. +Does NOT check if the player has acquired the builder priv. Call lobby.is_builder() +beforehand to make sure player is allowed to be lifted. +--]] +function lobby.player_to_builder(player) + if player == nil then return end + + local pl_name = player:get_player_name() + local pl_attr = player:get_meta() + local pl_priv = minetest.get_player_privs(pl_name) + pl_priv.creative = true + pl_priv.fly = true + pl_priv.fast = true + minetest.set_player_privs(pl_name, pl_priv) + pl_attr:set_string('mode', 'builder') + local inv = player:get_inventory() + local old_inv = inv:get_list('builder') + inv:set_list('builder', {}) + inv:set_size('main', 32) + inv:set_list('main', old_inv) +end + diff --git a/mods/lobby/shop.lua b/mods/lobby/shop.lua index 7ba51ae..08d12c7 100644 --- a/mods/lobby/shop.lua +++ b/mods/lobby/shop.lua @@ -1,8 +1,3 @@ -local function not_builder(player) - local name = player:get_player_name() - return not minetest.check_player_privs(name, { builder = true }) -end - local function lobby_shop_priv(player) local player_attributes = player:get_meta() local xp = player_attributes:get_float('xp') @@ -57,7 +52,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) if formname == 'lobby:shop_priv' then local player_attributes = player:get_meta() if fields.builder then - if lobby.take_xp(player, 100) and not_builder(player) then + if lobby.take_xp(player, 100) and not lobby.is_builder(player) then minetest.chat_send_player(player:get_player_name(), 'You just bought the Builder Privilege!') local privs = minetest.get_player_privs(name) privs.builder = true @@ -72,35 +67,14 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) end minetest.show_formspec(name, 'lobby:shop_priv', lobby_shop_priv(player)) elseif fields.toggle_build then - if not not_builder(player) then + if lobby.is_builder(player) then local privs = minetest.get_player_privs(name) if privs.creative == true then - local privs = minetest.get_player_privs(name) - privs.creative = nil - privs.fly = nil - privs.fast = nil - privs.worldedit = nil - privs.areas = nil - minetest.set_player_privs(name, privs) + lobby.builder_to_player(player) minetest.chat_send_player(name, 'Privs revoked! Play some games in the lobby') - player_attributes:set_string('mode', 'solo') - local inv = player:get_inventory() - local old_inv = inv:get_list('main') - inv:set_list('builder', old_inv) - inv:set_size('main', 16) - inv:set_list('main', {}) else - privs.creative = true - privs.fly = true - privs.fast = true - minetest.set_player_privs(name, privs) + lobby.player_to_builder(player) minetest.chat_send_player(name, 'Privs restored!') - player_attributes:set_string('mode', 'builder') - local inv = player:get_inventory() - local old_inv = inv:get_list('builder') - inv:set_list('builder', {}) - inv:set_size('main', 32) - inv:set_list('main', old_inv) end else minetest.chat_send_player(name, 'You need to buy the Builder priv first!') diff --git a/test/all-tests.lua b/test/all-tests.lua index d93203d..22c3b23 100644 --- a/test/all-tests.lua +++ b/test/all-tests.lua @@ -1,158 +1,17 @@ lu = require('luaunit/luaunit') + +-- mtmock pulls in all other mocks atm mtmock = require('mtmock') +-- load in testable code, so the suites don't have to bother with it dofile(mtmock.MODDIR .. 'lobby/lobby.lua') dofile(mtmock.MODDIR .. 'lobby/chat.lua') dofile(mtmock.MODDIR .. 'lobby/stats.lua') +dofile(mtmock.MODDIR .. 'lobby/functions.lua') --- test stats.lua -TestStats = {} - function TestStats:setUp() - lobby.savedata = {} - lobby.savedata.stats = {} - end - - function TestStats:testSoloVisit1() - lobby.update_stats('0', 'solo') - lu.assertNotNil(lobby.savedata) - lu.assertNotNil(lobby.savedata.stats) - stats = lobby.savedata.stats['0'] - lu.assertNotNil(stats) - lu.assertEquals(stats.solo_play, 1) - lu.assertEquals(stats.multi_play, 0) - lu.assertEquals(stats.winner_traitor, 0) - lu.assertEquals(stats.winner_team, 0) - lu.assertEquals(stats.max_players, 0) - lu.assertEquals(stats.player_count, 0) - end - - function TestStats:testSoloVisitN() - lobby.update_stats('1', 'solo') - lobby.update_stats('1', 'solo') - lobby.update_stats('1', 'solo') - lobby.update_stats('1', 'solo') - lobby.update_stats('1', 'solo') - lobby.update_stats('1', 'solo') - stats = lobby.savedata.stats['1'] - lu.assertNotNil(stats) - lu.assertEquals(stats.solo_play, 6) - lu.assertEquals(stats.multi_play, 0) - lu.assertEquals(stats.winner_traitor, 0) - lu.assertEquals(stats.winner_team, 0) - lu.assertEquals(stats.max_players, 0) - lu.assertEquals(stats.player_count, 0) - end - - function TestStats:testMultiVisit1() - lobby.update_stats('0', 'player', '', 0) - lobby.update_stats('5', 'player', '', 5) - lobby.update_stats('42', 'player', '', 42) - stats = lobby.savedata.stats['0'] - lu.assertNotNil(stats) - lu.assertEquals(stats.solo_play, 0) - lu.assertEquals(stats.multi_play, 1) - lu.assertEquals(stats.winner_traitor, 0) - lu.assertEquals(stats.winner_team, 0) - lu.assertEquals(stats.max_players, 0) - lu.assertEquals(stats.player_count, 0) - stats = lobby.savedata.stats['5'] - lu.assertNotNil(stats) - lu.assertEquals(stats.solo_play, 0) - lu.assertEquals(stats.multi_play, 1) - lu.assertEquals(stats.winner_traitor, 0) - lu.assertEquals(stats.winner_team, 0) - lu.assertEquals(stats.max_players, 5) - lu.assertEquals(stats.player_count, 5) - stats = lobby.savedata.stats['42'] - lu.assertNotNil(stats) - lu.assertEquals(stats.solo_play, 0) - lu.assertEquals(stats.multi_play, 1) - lu.assertEquals(stats.winner_traitor, 0) - lu.assertEquals(stats.winner_team, 0) - lu.assertEquals(stats.max_players, 42) - lu.assertEquals(stats.player_count, 42) - end - - function TestStats:testMultiVisitN() - lobby.update_stats('N', 'player', '', 3) - lobby.update_stats('N', 'player', '', 3) - lobby.update_stats('N', 'player', '', 3) - lobby.update_stats('N', 'player', '', 3) - lobby.update_stats('N', 'player', '', 3) - lobby.update_stats('N', 'player', '', 3) - lobby.update_stats('N', 'player', '', 3) - stats = lobby.savedata.stats['N'] - lu.assertNotNil(stats) - lu.assertEquals(stats.multi_play, 7) - end - - function TestStats:testTeamPlays() - -- stats #1 - lobby.update_stats('2', 'player', '', 4) - lobby.update_stats('2', '', 'traitor') - stats = lobby.savedata.stats['2'] - lu.assertEquals(stats.solo_play, 0) - lu.assertEquals(stats.multi_play, 1) - lu.assertEquals(stats.winner_traitor, 1) - lu.assertEquals(stats.winner_team, 0) - lu.assertEquals(stats.max_players, 4) - lu.assertEquals(stats.player_count, 4) - - -- stats #2 - lobby.update_stats('2', 'player', '', 2) - lobby.update_stats('2', '', 'team') - lu.assertEquals(stats.solo_play, 0) - lu.assertEquals(stats.multi_play, 2) - lu.assertEquals(stats.winner_traitor, 1) - lu.assertEquals(stats.winner_team, 1) - lu.assertEquals(stats.max_players, 4) - lu.assertEquals(stats.player_count, 3) - - -- stats #3 - lobby.update_stats('2', 'player', '', 3) - lobby.update_stats('2', '', 'traitor') - lu.assertEquals(stats.solo_play, 0) - lu.assertEquals(stats.multi_play, 3) - lu.assertEquals(stats.winner_traitor, 2) - lu.assertEquals(stats.winner_team, 1) - lu.assertEquals(stats.max_players, 4) - lu.assertEquals(stats.player_count, 3) - - -- stats #4 - lobby.update_stats('2', 'player', '', 7) - lobby.update_stats('2', '', 'team') - lu.assertEquals(stats.solo_play, 0) - lu.assertEquals(stats.multi_play, 4) - lu.assertEquals(stats.winner_traitor, 2) - lu.assertEquals(stats.winner_team, 2) - lu.assertEquals(stats.max_players, 7) - lu.assertEquals(stats.player_count, 4) - end - - -- Test for mixed plays, ignoring solo plays completely - -- (i.e., player_count _only_ averages team plays) - function TestStats:testMixedPlays() - lobby.update_stats('3', 'player', '', 4) - lobby.update_stats('3', '', 'team') - lobby.update_stats('3', 'player', '', 4) - lobby.update_stats('3', '', 'team') - lobby.update_stats('3', 'player', '', 4) - lobby.update_stats('3', '', 'team') - lobby.update_stats('3', 'player', '', 4) - lobby.update_stats('3', '', 'traitor') - lobby.update_stats('3', 'solo') - lobby.update_stats('3', 'solo') - lobby.update_stats('3', 'solo') - stats = lobby.savedata.stats['3'] - lu.assertEquals(stats.solo_play, 3) - lu.assertEquals(stats.multi_play, 4) - lu.assertEquals(stats.winner_traitor, 1) - lu.assertEquals(stats.winner_team, 3) - lu.assertEquals(stats.max_players, 4) - lu.assertEquals(stats.player_count, 4) -- 4 team plays x 4 players / 4 rounds - end - ---[[ TestStats ]]-- +-- include all test suites +dofile('suites/lobby_stats.lua') +dofile('suites/lobby_functions.lua') os.exit(lu.LuaUnit.run()) diff --git a/test/mocks/inventory.lua b/test/mocks/inventory.lua new file mode 100644 index 0000000..c8f00c4 --- /dev/null +++ b/test/mocks/inventory.lua @@ -0,0 +1,30 @@ +-- inventory mock +InventoryMock = {} +InventoryMock.__index = InventoryMock + +function InventoryMock:new() + inventory = {} + inventory.lists = {} + inventory.sizes = {} + inventory.lists.main = {} + inventory.sizes.main = 32 + setmetatable(inventory, self) + return inventory +end + +function InventoryMock:get_list(name) + return self.lists[name] +end + +function InventoryMock:set_list(name, list) + self.lists[name] = list +end + +function InventoryMock:get_size(name) + return self.sizes[name] +end + +function InventoryMock:set_size(name, new_size) + self.sizes[name] = new_size +end + diff --git a/test/mocks/player.lua b/test/mocks/player.lua new file mode 100644 index 0000000..258e13f --- /dev/null +++ b/test/mocks/player.lua @@ -0,0 +1,25 @@ +-- player mock +PlayerMock = {} +PlayerMock.__index = PlayerMock + +function PlayerMock:new(pl_name) + player = {} + player.name = pl_name + player.meta = SettingsMock:new() + player.inventory = InventoryMock:new() + setmetatable(player, self) + return player +end + +function PlayerMock:get_player_name() + return self.name +end + +function PlayerMock:get_meta() + return self.meta +end + +function PlayerMock:get_inventory() + return self.inventory +end + diff --git a/test/mocks/settings.lua b/test/mocks/settings.lua new file mode 100644 index 0000000..a17db78 --- /dev/null +++ b/test/mocks/settings.lua @@ -0,0 +1,23 @@ +-- settings mock +SettingsMock = {} +SettingsMock.__index = SettingsMock + +function SettingsMock:new() + settings = {} + setmetatable(settings, self) + return settings +end + +function SettingsMock:get_bool(key) + -- TODO: add basic type checks + return self[key] +end + +function SettingsMock:get_string(key) + return self[key] +end + +function SettingsMock:set_string(key, value) + self[key] = value +end + diff --git a/test/mtmock.lua b/test/mtmock.lua index a5abb02..4a33c1e 100644 --- a/test/mtmock.lua +++ b/test/mtmock.lua @@ -1,18 +1,46 @@ mtmock = {} -mtmock.settings = {} +mtmock.mod_storage = {} dofile('mtmock.conf') +dofile('mocks/settings.lua') +dofile('mocks/inventory.lua') +dofile('mocks/player.lua') + +mtmock.settings = SettingsMock:new() -- bind minetest and core aliases and -- work with minetest alias from here on minetest = mtmock core = mtmock +--[[ //////////////////// CORE STUBS -- BEGIN \\\\\\\\\\\\\\\\\\\\ ]]-- + function core.get_builtin_path() return core.SCRIPTDIR end +function core.register_on_joinplayer(join_fun) +end + +function core.register_on_leaveplayer(leave_fun) +end + +--[[ \\\\\\\\\\\\\\\\\\\\ CORE STUBS -- END //////////////////// ]]-- + + +--[[ //////////////////// MTMOCK API -- BEGIN \\\\\\\\\\\\\\\\\\\\ ]]-- + +function mtmock.add_player(pl_name) + player = PlayerMock:new(pl_name) + minetest.connected_players[pl_name] = player + return player +end + +--[[ \\\\\\\\\\\\\\\\\\\\ MTMOCK API -- END //////////////////// ]]-- + + -- load MT's serialize functions dofile(core.get_builtin_path() .. 'common/serialize.lua') +dofile(core.get_builtin_path() .. 'game/misc.lua') minetest.connected_players = {} minetest.worldpath = mtmock.WORLDDIR @@ -42,4 +70,20 @@ function minetest.setting_get_pos(setting) end end +function minetest.get_mod_storage() + return mtmock.mod_storage +end + +function minetest.get_player_privs(pl_name) + if pl_name == nil or minetest.privs == nil then return nil end + return minetest.privs[pl_name] +end + +function minetest.set_player_privs(pl_name, pl_privs) + if pl_name ~= nil and minetest.privs ~= nil then + minetest.privs[pl_name] = pl_privs + end +end + + return mtmock diff --git a/test/suites/lobby_functions.lua b/test/suites/lobby_functions.lua new file mode 100644 index 0000000..2a370c0 --- /dev/null +++ b/test/suites/lobby_functions.lua @@ -0,0 +1,114 @@ +-- lobby/functions.lua +TestLobbyFunctions = {} + function TestLobbyFunctions:setUp() + mtmock.privs = { + ['p1'] = {}, + ['p2'] = {creative=true, fly=true, fast=true}, + ['p3'] = {builder=false, creative=true, fly=true, fast=true}, + ['p4'] = {builder=false, creative=false, fly=true, fast=true}, + ['b1'] = {builder=true, creative=true, fly=true, fast=true}, + ['b2'] = {builder=true, creative=false, fly=true, fast=true}, + } + end + + function TestLobbyFunctions:testIsBuilder() + p1 = mtmock.add_player('p1') + p2 = mtmock.add_player('p2') + p3 = mtmock.add_player('p3') + p4 = mtmock.add_player('p4') + b1 = mtmock.add_player('b1') + b2 = mtmock.add_player('b2') + lu.assertIsNil(lobby.is_builder(nil)) + lu.assertIsFalse(lobby.is_builder(p1)) + lu.assertIsFalse(lobby.is_builder(p2)) + lu.assertIsFalse(lobby.is_builder(p3)) + lu.assertIsFalse(lobby.is_builder(p4)) + lu.assertIsTrue(lobby.is_builder(b1)) + lu.assertIsTrue(lobby.is_builder(b2)) + end + + -- does lobby.builder_to_player() reset the player privileges? + function TestLobbyFunctions:testBuilderToPlayerResetsPrivs() + b1 = mtmock.add_player('b1') + lobby.builder_to_player(b1) + b1_privs = minetest.get_player_privs('b1') + lu.assertIsNil(b1_privs.creative) + lu.assertIsNil(b1_privs.fly) + lu.assertIsNil(b1_privs.fast) + + b2 = mtmock.add_player('b2') + lobby.builder_to_player(b2) + b2_privs = minetest.get_player_privs('b2') + lu.assertIsNil(b2_privs.creative) + lu.assertIsNil(b2_privs.fly) + lu.assertIsNil(b2_privs.fast) + end + + -- does lobby.builder_to_player() set the player mode to 'solo'? + function TestLobbyFunctions:testBuilderToPlayerSetsSoloMode() + b1 = mtmock.add_player('b1') + lobby.builder_to_player(b1) + b1_attrs = b1:get_meta() + lu.assertEquals(b1_attrs:get_string('mode'), 'solo') + + b2 = mtmock.add_player('b2') + lobby.builder_to_player(b2) + b2_attrs = b2:get_meta() + lu.assertEquals(b2_attrs:get_string('mode'), 'solo') + end + + -- does lobby.player_to_builder() restore builder privs? + function TestLobbyFunctions:testPlayerToBuilderRestoresPrivs() + p1 = mtmock.add_player('p1') + lobby.player_to_builder(p1) + p1_privs = minetest.get_player_privs('p1') + lu.assertIsTrue(p1_privs.creative) + lu.assertIsTrue(p1_privs.fly) + lu.assertIsTrue(p1_privs.fast) + + p2 = mtmock.add_player('p2') + lobby.player_to_builder(p2) + p2_privs = minetest.get_player_privs('p2') + lu.assertIsTrue(p2_privs.creative) + lu.assertIsTrue(p2_privs.fly) + lu.assertIsTrue(p2_privs.fast) + + p3 = mtmock.add_player('p3') + lobby.player_to_builder(p3) + p3_privs = minetest.get_player_privs('p3') + lu.assertIsTrue(p3_privs.creative) + lu.assertIsTrue(p3_privs.fly) + lu.assertIsTrue(p3_privs.fast) + + p4 = mtmock.add_player('p4') + lobby.player_to_builder(p4) + p4_privs = minetest.get_player_privs('p4') + lu.assertIsTrue(p4_privs.creative) + lu.assertIsTrue(p4_privs.fly) + lu.assertIsTrue(p4_privs.fast) + end + + -- does lobby.player_to_builder() set the player mode to 'builder'? + function TestLobbyFunctions:testPlayerToBuilderSetsBuilderMode() + p1 = mtmock.add_player('p1') + lobby.player_to_builder(p1) + p1_attrs = p1:get_meta() + lu.assertEquals(p1_attrs:get_string('mode'), 'builder') + + p2 = mtmock.add_player('p2') + lobby.player_to_builder(p2) + p2_attrs = p2:get_meta() + lu.assertEquals(p2_attrs:get_string('mode'), 'builder') + + p3 = mtmock.add_player('p3') + lobby.player_to_builder(p3) + p3_attrs = p3:get_meta() + lu.assertEquals(p3_attrs:get_string('mode'), 'builder') + + p4 = mtmock.add_player('p4') + lobby.player_to_builder(p4) + p4_attrs = p4:get_meta() + lu.assertEquals(p4_attrs:get_string('mode'), 'builder') + end + +--[[ TestLobbyFunctions ]]-- diff --git a/test/suites/lobby_stats.lua b/test/suites/lobby_stats.lua new file mode 100644 index 0000000..9ae63c6 --- /dev/null +++ b/test/suites/lobby_stats.lua @@ -0,0 +1,149 @@ +-- lobby/stats.lua +TestLobbyStats = {} + function TestLobbyStats:setUp() + lobby.savedata = {} + lobby.savedata.stats = {} + end + + function TestLobbyStats:testSoloVisit1() + lobby.update_stats('0', 'solo') + lu.assertNotNil(lobby.savedata) + lu.assertNotNil(lobby.savedata.stats) + stats = lobby.savedata.stats['0'] + lu.assertNotNil(stats) + lu.assertEquals(stats.solo_play, 1) + lu.assertEquals(stats.multi_play, 0) + lu.assertEquals(stats.winner_traitor, 0) + lu.assertEquals(stats.winner_team, 0) + lu.assertEquals(stats.max_players, 0) + lu.assertEquals(stats.player_count, 0) + end + + function TestLobbyStats:testSoloVisitN() + lobby.update_stats('1', 'solo') + lobby.update_stats('1', 'solo') + lobby.update_stats('1', 'solo') + lobby.update_stats('1', 'solo') + lobby.update_stats('1', 'solo') + lobby.update_stats('1', 'solo') + stats = lobby.savedata.stats['1'] + lu.assertNotNil(stats) + lu.assertEquals(stats.solo_play, 6) + lu.assertEquals(stats.multi_play, 0) + lu.assertEquals(stats.winner_traitor, 0) + lu.assertEquals(stats.winner_team, 0) + lu.assertEquals(stats.max_players, 0) + lu.assertEquals(stats.player_count, 0) + end + + function TestLobbyStats:testMultiVisit1() + lobby.update_stats('0', 'player', '', 0) + lobby.update_stats('5', 'player', '', 5) + lobby.update_stats('42', 'player', '', 42) + stats = lobby.savedata.stats['0'] + lu.assertNotNil(stats) + lu.assertEquals(stats.solo_play, 0) + lu.assertEquals(stats.multi_play, 1) + lu.assertEquals(stats.winner_traitor, 0) + lu.assertEquals(stats.winner_team, 0) + lu.assertEquals(stats.max_players, 0) + lu.assertEquals(stats.player_count, 0) + stats = lobby.savedata.stats['5'] + lu.assertNotNil(stats) + lu.assertEquals(stats.solo_play, 0) + lu.assertEquals(stats.multi_play, 1) + lu.assertEquals(stats.winner_traitor, 0) + lu.assertEquals(stats.winner_team, 0) + lu.assertEquals(stats.max_players, 5) + lu.assertEquals(stats.player_count, 5) + stats = lobby.savedata.stats['42'] + lu.assertNotNil(stats) + lu.assertEquals(stats.solo_play, 0) + lu.assertEquals(stats.multi_play, 1) + lu.assertEquals(stats.winner_traitor, 0) + lu.assertEquals(stats.winner_team, 0) + lu.assertEquals(stats.max_players, 42) + lu.assertEquals(stats.player_count, 42) + end + + function TestLobbyStats:testMultiVisitN() + lobby.update_stats('N', 'player', '', 3) + lobby.update_stats('N', 'player', '', 3) + lobby.update_stats('N', 'player', '', 3) + lobby.update_stats('N', 'player', '', 3) + lobby.update_stats('N', 'player', '', 3) + lobby.update_stats('N', 'player', '', 3) + lobby.update_stats('N', 'player', '', 3) + stats = lobby.savedata.stats['N'] + lu.assertNotNil(stats) + lu.assertEquals(stats.multi_play, 7) + end + + function TestLobbyStats:testTeamPlays() + -- stats #1 + lobby.update_stats('2', 'player', '', 4) + lobby.update_stats('2', '', 'traitor') + stats = lobby.savedata.stats['2'] + lu.assertEquals(stats.solo_play, 0) + lu.assertEquals(stats.multi_play, 1) + lu.assertEquals(stats.winner_traitor, 1) + lu.assertEquals(stats.winner_team, 0) + lu.assertEquals(stats.max_players, 4) + lu.assertEquals(stats.player_count, 4) + + -- stats #2 + lobby.update_stats('2', 'player', '', 2) + lobby.update_stats('2', '', 'team') + lu.assertEquals(stats.solo_play, 0) + lu.assertEquals(stats.multi_play, 2) + lu.assertEquals(stats.winner_traitor, 1) + lu.assertEquals(stats.winner_team, 1) + lu.assertEquals(stats.max_players, 4) + lu.assertEquals(stats.player_count, 3) + + -- stats #3 + lobby.update_stats('2', 'player', '', 3) + lobby.update_stats('2', '', 'traitor') + lu.assertEquals(stats.solo_play, 0) + lu.assertEquals(stats.multi_play, 3) + lu.assertEquals(stats.winner_traitor, 2) + lu.assertEquals(stats.winner_team, 1) + lu.assertEquals(stats.max_players, 4) + lu.assertEquals(stats.player_count, 3) + + -- stats #4 + lobby.update_stats('2', 'player', '', 7) + lobby.update_stats('2', '', 'team') + lu.assertEquals(stats.solo_play, 0) + lu.assertEquals(stats.multi_play, 4) + lu.assertEquals(stats.winner_traitor, 2) + lu.assertEquals(stats.winner_team, 2) + lu.assertEquals(stats.max_players, 7) + lu.assertEquals(stats.player_count, 4) + end + + -- Test for mixed plays, ignoring solo plays completely + -- (i.e., player_count _only_ averages team plays) + function TestLobbyStats:testMixedPlays() + lobby.update_stats('3', 'player', '', 4) + lobby.update_stats('3', '', 'team') + lobby.update_stats('3', 'player', '', 4) + lobby.update_stats('3', '', 'team') + lobby.update_stats('3', 'player', '', 4) + lobby.update_stats('3', '', 'team') + lobby.update_stats('3', 'player', '', 4) + lobby.update_stats('3', '', 'traitor') + lobby.update_stats('3', 'solo') + lobby.update_stats('3', 'solo') + lobby.update_stats('3', 'solo') + stats = lobby.savedata.stats['3'] + lu.assertEquals(stats.solo_play, 3) + lu.assertEquals(stats.multi_play, 4) + lu.assertEquals(stats.winner_traitor, 1) + lu.assertEquals(stats.winner_team, 3) + lu.assertEquals(stats.max_players, 4) + lu.assertEquals(stats.player_count, 4) -- 4 team plays x 4 players / 4 rounds + end + +--[[ TestLobbyStats ]]-- +