pokemon-showdown/test/application/ladders-matchmaker.js
Guangcong Luo 88159c41bc Refactor BattleRoom -> GameRoom
BattleRoom is now GameRoom, a slightly more abstract room type capable
of holding any of a number of possible roomgames. Currently, battles
are the only such roomgame, but any future roomgame could possibly use
it.

Differences between ChatRoom and GameRoom:

- GameRooms start at the left, ChatRooms start at the right
- GameRooms have chat on the right, and a game area on the left, with a
  view area at the top left and a controls area at the bottom left
- GameRooms retain all their logs, ChatRooms only retain the latest 100
  lines
- GameRooms expire after 40 minutes of inactivity or 10 minutes of zero
  online users (configurable in the future)
- GameRooms are guaranteed to have an associated game, while ChatRooms
  may or may not
2017-10-18 05:41:03 -05:00

146 lines
4.2 KiB
JavaScript

'use strict';
const assert = require('assert');
global.Ladders = require('../../ladders');
const {Connection, User} = require('../../dev-tools/users-utils');
let matchmaker = Ladders.matchmaker;
describe('Matchmaker', function () {
const FORMATID = 'gen7ou';
const addSearch = (player, rating = 1000, formatid = FORMATID) => {
let search = new Ladders.Search(player.userid, player.team, rating);
matchmaker.addSearch(search, player, formatid);
return search;
};
const destroyPlayer = player => {
player.resetName();
player.disconnectAll();
player.destroy();
return null;
};
before(function () {
clearInterval(matchmaker.periodicMatchInterval);
matchmaker.periodicMatchInterval = null;
});
beforeEach(function () {
this.p1 = new User(new Connection('127.0.0.1'));
this.p1.forceRename('Morfent', true);
this.p1.connected = true;
this.p1.team = 'Gengar||||lick||252,252,4,,,|||||';
Users.users.set(this.p1.userid, this.p1);
this.p2 = new User(new Connection('0.0.0.0'));
this.p2.forceRename('Mrofnet', true);
this.p2.connected = true;
this.p2.team = 'Gengar||||lick||252,252,4,,,|||||';
Users.users.set(this.p2.userid, this.p2);
});
afterEach(function () {
this.p1 = destroyPlayer(this.p1);
this.p2 = destroyPlayer(this.p2);
});
it('should add a search', function () {
let s1 = addSearch(this.p1);
assert.ok(matchmaker.searches.has(FORMATID));
let formatSearches = matchmaker.searches.get(FORMATID);
assert.ok(formatSearches instanceof Map);
assert.strictEqual(formatSearches.size, 1);
assert.strictEqual(s1.userid, this.p1.userid);
assert.strictEqual(s1.team, this.p1.team);
assert.strictEqual(s1.rating, 1000);
});
it('should matchmake users when appropriate', function () {
addSearch(this.p1);
addSearch(this.p2);
assert.strictEqual(matchmaker.searches.get(FORMATID).size, 0);
});
it('should matchmake users within a reasonable rating range', function () {
addSearch(this.p1);
addSearch(this.p2, 2000);
assert.strictEqual(matchmaker.searches.get(FORMATID).size, 2);
});
it('should cancel searches', function () {
addSearch(this.p1);
matchmaker.cancelSearch(this.p1, FORMATID);
matchmaker.cancelSearches(this.p2);
assert.strictEqual(matchmaker.searches.get(FORMATID).size, 0);
});
it('should periodically matchmake users when appropriate', function () {
addSearch(this.p1);
let s2 = addSearch(this.p2, 2000);
assert.strictEqual(matchmaker.searches.get(FORMATID).size, 2);
s2.rating = 1000;
matchmaker.periodicMatch();
assert.strictEqual(matchmaker.searches.get(FORMATID).size, 0);
});
it('should create a new battle room after matchmaking', function () {
assert.strictEqual(this.p1.games.size, 0);
addSearch(this.p1);
addSearch(this.p2);
assert.strictEqual(this.p1.games.size, 1);
for (const roomid of this.p1.games) {
assert.ok(Rooms(roomid).battle);
}
});
it('should cancel search on disconnect', function () {
addSearch(this.p1);
this.p1.onDisconnect(this.p1.connections[0]);
assert.strictEqual(matchmaker.searches.get(FORMATID).size, 0);
});
it('should cancel search on merge', function () {
addSearch(this.p1);
this.p2.merge(this.p1);
assert.strictEqual(matchmaker.searches.get(FORMATID).size, 0);
});
describe('#startBattle', function () {
beforeEach(function () {
this.s1 = addSearch(this.p1);
this.s2 = addSearch(this.p2);
});
afterEach(function () {
this.s1 = null;
this.s2 = null;
});
it('should prevent battles from starting if both players are identical', function () {
Object.assign(this.s2, this.s1);
let room;
try {
room = Rooms.createBattle(FORMATID, {p1: this.p1, p2: this.p1, p1team: this.s1.team, p2team: this.s2.team, rated: 1000});
} catch (e) {}
assert.strictEqual(room, undefined);
});
before(function () {
this.lockdown = Rooms.global.lockdown;
Rooms.global.lockdown = true;
});
after(function () {
Rooms.global.lockdown = this.lockdown;
this.lockdown = null;
});
it('should prevent battles from starting if the server is in lockdown', function () {
let room = Rooms.createBattle(FORMATID, {p1: this.p1, p2: this.p2, p1team: this.s1.team, p2team: this.s2.team, rated: 1000});
assert.strictEqual(room, undefined);
});
});
});