diff --git a/.eslintrc b/.eslintrc index a4f11d858d19..baacdc920409 100644 --- a/.eslintrc +++ b/.eslintrc @@ -15,7 +15,7 @@ "Config": false, "Monitor": false, "toId": false, "Dex": false, "LoginServer": false, "Users": false, "Punishments": false, "Rooms": false, "Verifier": false, "Chat": false, "Tournaments": false, "Dnsbl": false, "Sockets": false, "TeamValidator": false, - "TeamValidatorAsync": false, "Ladders": false + "TeamValidatorAsync": false, "Ladders": false, "beforeAll": false, "afterAll": false }, "extends": "eslint:recommended", "rules": { diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 000000000000..b79e17ceef65 --- /dev/null +++ b/jest.config.js @@ -0,0 +1,7 @@ +'use strict'; + +module.exports = { + testEnvironment: 'node', + setupFilesAfterEnv: ['/test/main.js'], + testMatch: ['/test/simulator/**/*.js', '/test/application/*.js', '/test/chat-plugins/*.js', '/test/dev-tools/*.js'], +}; diff --git a/package.json b/package.json index e9652379d19a..72c616ac06cd 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "description": "The server for the Pokémon Showdown battle simulator", "version": "0.11.2", "dependencies": { + "jest": "^24.7.1", "probe-image-size": "^4.0.0", "sockjs": "0.3.19", "sucrase": "^3.10.1" @@ -21,7 +22,7 @@ "scripts": { "start": "node pokemon-showdown start", "build": "node build", - "test": "eslint --cache . && tslint --project . && node build && mocha && tsc", + "test": "eslint --cache . && tslint --project . && node build && jest && tsc", "tsc": "tsc", "lint": "eslint --cache ." }, @@ -63,7 +64,6 @@ "@types/sockjs": "^0.3.31", "eslint": "^5.16.0", "husky": "^1.1.2", - "mocha": "^6.1.2", "tslint": "^5.15.0", "typescript": "^3.4.2" } diff --git a/test/application/ladders-matchmaker.js b/test/application/ladders-matchmaker.js index 6652a064c674..6d0c8ffba268 100644 --- a/test/application/ladders-matchmaker.js +++ b/test/application/ladders-matchmaker.js @@ -5,6 +5,9 @@ const assert = require('assert'); global.Ladders = require('../../server/ladders'); const {Connection, User} = require('../../dev-tools/users-utils'); +let p1, p2; +let s1, s2; + describe('Matchmaker', function () { const FORMATID = 'gen7ou'; const addSearch = (player, rating = 1000, formatid = FORMATID) => { @@ -19,64 +22,64 @@ describe('Matchmaker', function () { return null; }; - before(function () { + beforeAll(function () { clearInterval(Ladders.periodicMatchInterval); Ladders.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); + p1 = new User(new Connection('127.0.0.1')); + p1.forceRename('Morfent', true); + p1.connected = true; + p1.team = 'Gengar||||lick||252,252,4,,,|||||'; + Users.users.set(p1.userid, p1); + + p2 = new User(new Connection('0.0.0.0')); + p2.forceRename('Mrofnet', true); + p2.connected = true; + p2.team = 'Gengar||||lick||252,252,4,,,|||||'; + Users.users.set(p2.userid, p2); }); afterEach(function () { - this.p1 = destroyPlayer(this.p1); - this.p2 = destroyPlayer(this.p2); + p1 = destroyPlayer(p1); + p2 = destroyPlayer(p2); }); it('should add a search', function () { - let s1 = addSearch(this.p1); + let s1 = addSearch(p1); assert.ok(Ladders.searches.has(FORMATID)); let formatSearches = Ladders.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.userid, p1.userid); + assert.strictEqual(s1.team, p1.team); assert.strictEqual(s1.rating, 1000); }); it('should matchmake users when appropriate', function () { - addSearch(this.p1); - addSearch(this.p2); + addSearch(p1); + addSearch(p2); assert.strictEqual(Ladders.searches.get(FORMATID).size, 0); }); it('should matchmake users within a reasonable rating range', function () { - addSearch(this.p1); - addSearch(this.p2, 2000); + addSearch(p1); + addSearch(p2, 2000); assert.strictEqual(Ladders.searches.get(FORMATID).size, 2); }); it('should cancel searches', function () { - addSearch(this.p1); - Ladders(FORMATID).cancelSearch(this.p1); - Ladders.cancelSearches(this.p2); + addSearch(p1); + Ladders(FORMATID).cancelSearch(p1); + Ladders.cancelSearches(p2); assert.strictEqual(Ladders.searches.get(FORMATID).size, 0); }); it('should periodically matchmake users when appropriate', function () { - addSearch(this.p1); - let s2 = addSearch(this.p2, 2000); + addSearch(p1); + let s2 = addSearch(p2, 2000); assert.strictEqual(Ladders.searches.get(FORMATID).size, 2); s2.rating = 1000; @@ -85,59 +88,59 @@ describe('Matchmaker', function () { }); 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.strictEqual(p1.games.size, 0); + addSearch(p1); + addSearch(p2); + assert.strictEqual(p1.games.size, 1); + for (const roomid of p1.games) { assert.ok(Rooms(roomid).battle); } }); it('should cancel search on disconnect', function () { - addSearch(this.p1); - this.p1.onDisconnect(this.p1.connections[0]); + addSearch(p1); + p1.onDisconnect(p1.connections[0]); assert.strictEqual(Ladders.searches.get(FORMATID).size, 0); }); it('should cancel search on merge', function () { - addSearch(this.p1); - this.p2.merge(this.p1); + addSearch(p1); + p2.merge(p1); assert.strictEqual(Ladders.searches.get(FORMATID).size, 0); }); describe('#startBattle', function () { beforeEach(function () { - this.s1 = addSearch(this.p1); - this.s2 = addSearch(this.p2); + s1 = addSearch(p1); + s2 = addSearch(p2); }); afterEach(function () { - this.s1 = null; - this.s2 = null; + s1 = null; + s2 = null; }); it('should prevent battles from starting if both players are identical', function () { - Object.assign(this.s2, this.s1); + Object.assign(s2, s1); let room; try { - room = Rooms.createBattle(FORMATID, {p1: this.p1, p2: this.p1, p1team: this.s1.team, p2team: this.s2.team, rated: 1000}); + room = Rooms.createBattle(FORMATID, {p1: p1, p2: p1, p1team: s1.team, p2team: s2.team, rated: 1000}); } catch (e) {} assert.strictEqual(room, undefined); }); - before(function () { + beforeAll(function () { this.lockdown = Rooms.global.lockdown; Rooms.global.lockdown = true; }); - after(function () { + afterAll(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}); + let room = Rooms.createBattle(FORMATID, {p1: p1, p2: p2, p1team: s1.team, p2team: s2.team, rated: 1000}); assert.strictEqual(room, undefined); }); }); diff --git a/test/application/sockets.js b/test/application/sockets.js index 331c000074a7..bbd324e1eb4f 100644 --- a/test/application/sockets.js +++ b/test/application/sockets.js @@ -12,7 +12,7 @@ describe.skip('Sockets', function () { }) ); - before(function () { + beforeAll(function () { cluster.settings.silent = true; cluster.removeAllListeners('disconnect'); }); diff --git a/test/application/users.js b/test/application/users.js index 1e59f13ba87f..95e0f30b6733 100644 --- a/test/application/users.js +++ b/test/application/users.js @@ -6,6 +6,8 @@ let userUtils = require('./../../dev-tools/users-utils'); let Connection = userUtils.Connection; let User = userUtils.User; +let connection; + describe('Users features', function () { describe('Users', function () { describe('get', function () { @@ -30,17 +32,17 @@ describe('Users features', function () { describe('Connection', function () { describe('#onDisconnect', function () { beforeEach(function () { - this.connection = new Connection('127.0.0.1'); + connection = new Connection('127.0.0.1'); }); it('should remove the connection from Users.connections', function () { - let connectionid = this.connection.id; - this.connection.destroy(); + let connectionid = connection.id; + connection.destroy(); assert.strictEqual(Users.connections.has(connectionid), false); }); it('should destroy any user on the connection as well', function () { - let user = new User(this.connection); + let user = new User(connection); let {userid} = user; user.disconnectAll(); user.destroy(); @@ -50,25 +52,25 @@ describe('Users features', function () { describe('#joinRoom', function () { beforeEach(function () { - this.connection = new Connection('127.0.0.1'); + connection = new Connection('127.0.0.1'); }); afterEach(function () { - this.connection.destroy(); + connection.destroy(); }); it('should join a room if not already present', function () { - this.connection.joinRoom(Rooms.lobby); - assert.ok(this.connection.inRooms.has('lobby')); + connection.joinRoom(Rooms.lobby); + assert.ok(connection.inRooms.has('lobby')); }); }); describe('#leaveRoom', function () { it('should leave a room that is present', function () { - this.connection = new Connection('127.0.0.1'); - this.connection.joinRoom(Rooms.lobby); - this.connection.leaveRoom(Rooms.lobby); - assert.ok(!this.connection.inRooms.has('lobby')); + connection = new Connection('127.0.0.1'); + connection.joinRoom(Rooms.lobby); + connection.leaveRoom(Rooms.lobby); + assert.ok(!connection.inRooms.has('lobby')); }); }); }); diff --git a/test/chat-plugins/trivia.js b/test/chat-plugins/trivia.js index b2a387bc444d..5b41eb5dc31c 100644 --- a/test/chat-plugins/trivia.js +++ b/test/chat-plugins/trivia.js @@ -28,8 +28,10 @@ function destroyUser(user) { user.destroy(); } +let room, user, user2, user3, tarUser, game, player; + describe('Trivia', function () { - before(function () { + beforeAll(function () { // The trivia module cannot be loaded outside of this scope because // it makes reference to global.Config in the modules outermost scope, // which makes the module fail to be loaded. Within the scope of thess @@ -41,282 +43,282 @@ describe('Trivia', function () { NumberModeTrivia = trivia.NumberModeTrivia; Rooms.global.addChatRoom('Trivia'); - this.room = Rooms('trivia'); + room = Rooms('trivia'); }); beforeEach(function () { let questions = [{question: '', answers: ['answer'], category: 'ae'}]; - this.user = makeUser('Morfent', new Connection('127.0.0.1')); - this.tarUser = makeUser('ReallyNotMorfent', new Connection('127.0.0.2')); - this.game = this.room.game = new Trivia(this.room, 'first', 'ae', 'short', questions); + user = makeUser('Morfent', new Connection('127.0.0.1')); + tarUser = makeUser('ReallyNotMorfent', new Connection('127.0.0.2')); + game = room.game = new Trivia(room, 'first', 'ae', 'short', questions); }); afterEach(function () { - destroyUser(this.user); - destroyUser(this.tarUser); - if (this.room.game) { - clearTimeout(this.room.game.phaseTimeout); - this.room.game.phaseTimeout = null; - this.room.game.destroy(); + destroyUser(user); + destroyUser(tarUser); + if (room.game) { + clearTimeout(room.game.phaseTimeout); + room.game.phaseTimeout = null; + room.game.destroy(); } }); - after(function () { - this.user = null; - this.tarUser = null; - this.room.destroy(); - this.room = null; + afterAll(function () { + user = null; + tarUser = null; + room.destroy(); + room = null; }); it('should add new players', function () { - this.game.addPlayer(this.user); - assert.strictEqual(this.game.playerCount, 1); + game.addPlayer(user); + assert.strictEqual(game.playerCount, 1); }); it('should not add a player if they have already joined', function () { - this.game.addPlayer(this.user); - this.game.addPlayer(this.user); - assert.strictEqual(this.game.playerCount, 1); + game.addPlayer(user); + game.addPlayer(user); + assert.strictEqual(game.playerCount, 1); }); it('should not add a player if another one on the same IP has joined', function () { - this.game.addPlayer(this.user); + game.addPlayer(user); let user2 = makeUser('Not Morfent', new Connection('127.0.0.1')); - this.game.addPlayer(user2); + game.addPlayer(user2); - assert.strictEqual(this.game.playerCount, 1); + assert.strictEqual(game.playerCount, 1); destroyUser(user2); }); it('should not add a player if another player had their username previously', function () { - let userid = this.user.userid; - let name = this.user.name; - this.game.addPlayer(this.user); - this.user.forceRename('Not Morfent', true); - this.user.prevNames[userid] = name; + let userid = user.userid; + let name = user.name; + game.addPlayer(user); + user.forceRename('Not Morfent', true); + user.prevNames[userid] = name; let user2 = makeUser(name, new Connection('127.0.0.3')); - this.game.addPlayer(user2); + game.addPlayer(user2); - assert.strictEqual(this.game.playerCount, 1); + assert.strictEqual(game.playerCount, 1); destroyUser(user2); }); it('should not add a player if they were kicked from the game', function () { - this.game.kickedUsers.add(this.tarUser.userid); - this.game.addPlayer(this.tarUser); - assert.strictEqual(this.game.playerCount, 0); + game.kickedUsers.add(tarUser.userid); + game.addPlayer(tarUser); + assert.strictEqual(game.playerCount, 0); }); it('should kick players from the game', function () { - this.game.addPlayer(this.tarUser); - this.game.kick(this.tarUser, this.user); - assert.strictEqual(this.game.playerCount, 0); + game.addPlayer(tarUser); + game.kick(tarUser, user); + assert.strictEqual(game.playerCount, 0); }); it('should not kick players already kicked from the game', function () { - this.game.addPlayer(this.tarUser); - this.game.kick(this.tarUser, this.user); - let res = this.game.kick(this.tarUser, this.user); + game.addPlayer(tarUser); + game.kick(tarUser, user); + let res = game.kick(tarUser, user); assert.strictEqual(typeof res, 'string'); }); it('should not kick users who were kicked under another name', function () { - this.game.addPlayer(this.tarUser); - this.game.kick(this.tarUser, this.user); - - let userid = this.tarUser.userid; - let name = this.tarUser.name; - this.tarUser.forceRename('Not Morfent', true); - this.tarUser.prevNames[userid] = name; - this.game.addPlayer(this.tarUser); - assert.strictEqual(this.game.playerCount, 0); + game.addPlayer(tarUser); + game.kick(tarUser, user); + + let userid = tarUser.userid; + let name = tarUser.name; + tarUser.forceRename('Not Morfent', true); + tarUser.prevNames[userid] = name; + game.addPlayer(tarUser); + assert.strictEqual(game.playerCount, 0); }); it('should not add users who were kicked under another IP', function () { - this.game.addPlayer(this.tarUser); - this.game.kick(this.tarUser, this.user); + game.addPlayer(tarUser); + game.kick(tarUser, user); - let name = this.tarUser.name; - this.tarUser.resetName(); + let name = tarUser.name; + tarUser.resetName(); let user2 = makeUser(name, new Connection('127.0.0.2')); - this.game.addPlayer(user2); - assert.strictEqual(this.game.playerCount, 0); + game.addPlayer(user2); + assert.strictEqual(game.playerCount, 0); destroyUser(user2); }); it('should not kick users that aren\'t players in the game', function () { - this.game.kick(this.tarUser, this.user); - assert.strictEqual(this.game.playerCount, 0); + game.kick(tarUser, user); + assert.strictEqual(game.playerCount, 0); }); it('should make players leave the game', function () { - this.game.leave(this.user); - assert.strictEqual(this.game.players[this.user.userid], undefined); + game.leave(user); + assert.strictEqual(game.players[user.userid], undefined); }); it('should not make users who are not players leave the game', function () { - this.game.leave(this.user); - let res = this.game.leave(this.user); + game.leave(user); + let res = game.leave(user); assert.strictEqual(typeof res, 'string'); }); it('should verify answers correctly', function () { - this.game.askQuestion(); - assert.strictEqual(this.game.verifyAnswer('answer'), true); - assert.strictEqual(this.game.verifyAnswer('anser'), true); - assert.strictEqual(this.game.verifyAnswer('not the right answer'), false); + game.askQuestion(); + assert.strictEqual(game.verifyAnswer('answer'), true); + assert.strictEqual(game.verifyAnswer('anser'), true); + assert.strictEqual(game.verifyAnswer('not the right answer'), false); }); it('should not throw when attempting to broadcast after the game has ended', function () { - this.game.destroy(); - assert.doesNotThrow(() => this.game.broadcast('ayy', 'lmao')); + game.destroy(); + assert.doesNotThrow(() => game.broadcast('ayy', 'lmao')); }); - context('marking player absence', function () { + describe('marking player absence', function () { beforeEach(function () { let questions = [null, null].fill({question: '', answers: ['answer'], category: 'ae'}); - let game = new FirstModeTrivia(this.room, 'first', 'ae', 'short', questions); - - this.user = makeUser('Morfent', new Connection('127.0.0.1')); - this.user2 = makeUser('user2', new Connection('127.0.0.2')); - this.user3 = makeUser('user3', new Connection('127.0.0.3')); - - this.user.joinRoom(this.room); - game.addPlayer(this.user); - this.user2.joinRoom(this.room); - game.addPlayer(this.user2); - this.user3.joinRoom(this.room); - game.addPlayer(this.user3); + let game = new FirstModeTrivia(room, 'first', 'ae', 'short', questions); + + user = makeUser('Morfent', new Connection('127.0.0.1')); + user2 = makeUser('user2', new Connection('127.0.0.2')); + user3 = makeUser('user3', new Connection('127.0.0.3')); + + user.joinRoom(room); + game.addPlayer(user); + user2.joinRoom(room); + game.addPlayer(user2); + user3.joinRoom(room); + game.addPlayer(user3); game.start(); game.askQuestion(); clearTimeout(game.phaseTimeout); game.phaseTimeout = null; - this.game = this.room.game = game; - this.player = this.room.game.players[this.user.userid]; + game = room.game = game; + player = room.game.players[user.userid]; }); afterEach(function () { - destroyUser(this.user); - destroyUser(this.user2); - destroyUser(this.user3); - if (this.room.game) { - clearTimeout(this.game.phaseTimeout); - this.game.phaseTimeout = null; - this.game.destroy(); + destroyUser(user); + destroyUser(user2); + destroyUser(user3); + if (room.game) { + clearTimeout(game.phaseTimeout); + game.phaseTimeout = null; + game.destroy(); } }); it('should mark a player absent on leave and pause the game', function () { - this.user.leaveRoom(this.room); - assert.strictEqual(this.player.isAbsent, true); - assert.strictEqual(this.game.phase, 'limbo'); - assert.strictEqual(this.game.phaseTimeout, null); + user.leaveRoom(room); + assert.strictEqual(player.isAbsent, true); + assert.strictEqual(game.phase, 'limbo'); + assert.strictEqual(game.phaseTimeout, null); }); it('should unpause the game once enough players have returned', function () { - this.user.leaveRoom(this.room); - this.user.joinRoom(this.room); - assert.strictEqual(this.player.isAbsent, false); - assert.strictEqual(this.game.phase, 'question'); - assert.ok(this.game.phaseTimeout); + user.leaveRoom(room); + user.joinRoom(room); + assert.strictEqual(player.isAbsent, false); + assert.strictEqual(game.phase, 'question'); + assert.ok(game.phaseTimeout); }); }); - context('first mode', function () { + describe('first mode', function () { beforeEach(function () { let questions = [{question: '', answers: ['answer'], category: 'ae'}]; - let game = new FirstModeTrivia(this.room, 'first', 'ae', 'short', questions); + let game = new FirstModeTrivia(room, 'first', 'ae', 'short', questions); - this.user = makeUser('Morfent', new Connection('127.0.0.1')); - this.user2 = makeUser('user2', new Connection('127.0.0.2')); - this.user3 = makeUser('user3', new Connection('127.0.0.3')); + user = makeUser('Morfent', new Connection('127.0.0.1')); + user2 = makeUser('user2', new Connection('127.0.0.2')); + user3 = makeUser('user3', new Connection('127.0.0.3')); - game.addPlayer(this.user); - game.addPlayer(this.user2); - game.addPlayer(this.user3); + game.addPlayer(user); + game.addPlayer(user2); + game.addPlayer(user3); game.start(); game.askQuestion(); - this.game = this.room.game = game; - this.player = game.players[this.user.userid]; + game = room.game = game; + player = game.players[user.userid]; }); afterEach(function () { - destroyUser(this.user); - destroyUser(this.user2); - destroyUser(this.user3); - if (this.room.game) { - clearTimeout(this.game.phaseTimeout); - this.game.phaseTimeout = null; - this.game.destroy(); + destroyUser(user); + destroyUser(user2); + destroyUser(user3); + if (room.game) { + clearTimeout(game.phaseTimeout); + game.phaseTimeout = null; + game.destroy(); } }); it('should calculate player points correctly', function () { - let points = this.game.calculatePoints(); + let points = game.calculatePoints(); assert.strictEqual(points, 5); }); it('should allow users to answer questions correctly', function () { - this.game.answerQuestion('answer', this.user); - assert.strictEqual(this.player.correctAnswers, 1); + game.answerQuestion('answer', user); + assert.strictEqual(player.correctAnswers, 1); }); it('should mark players who answer incorrectly', function () { - this.game.answerQuestion('not the right answer', this.user); - assert.strictEqual(this.player.correctAnswers, 0); + game.answerQuestion('not the right answer', user); + assert.strictEqual(player.correctAnswers, 0); }); it('should only reward a player points once per question', function () { - this.game.answerQuestion('answer', this.user); - this.game.answerQuestion('answer', this.user); - assert.strictEqual(this.player.correctAnswers, 1); + game.answerQuestion('answer', user); + game.answerQuestion('answer', user); + assert.strictEqual(player.correctAnswers, 1); }); it('should clear player answers if none answer correctly', function () { - this.game.answerQuestion('not the right answer', this.user); - this.game.tallyAnswers(); - assert.strictEqual(this.player.answer, ''); + game.answerQuestion('not the right answer', user); + game.tallyAnswers(); + assert.strictEqual(player.answer, ''); }); it('should not give NaN points to correct responders', function () { - this.game.answerQuestion('answer', this.user); - this.game.tallyAnswers(); - assert.ok(!isNaN(this.player.points)); + game.answerQuestion('answer', user); + game.tallyAnswers(); + assert.ok(!isNaN(player.points)); }); }); - context('timer mode', function () { + describe('timer mode', function () { beforeEach(function () { let questions = [{question: '', answers: ['answer'], category: 'ae'}]; - let game = new TimerModeTrivia(this.room, 'first', 'ae', 'short', questions); + let game = new TimerModeTrivia(room, 'first', 'ae', 'short', questions); - this.user = makeUser('Morfent', new Connection('127.0.0.1')); - this.user2 = makeUser('user2', new Connection('127.0.0.2')); - this.user3 = makeUser('user3', new Connection('127.0.0.3')); + user = makeUser('Morfent', new Connection('127.0.0.1')); + user2 = makeUser('user2', new Connection('127.0.0.2')); + user3 = makeUser('user3', new Connection('127.0.0.3')); - game.addPlayer(this.user); - game.addPlayer(this.user2); - game.addPlayer(this.user3); + game.addPlayer(user); + game.addPlayer(user2); + game.addPlayer(user3); game.start(); game.askQuestion(); - this.game = this.room.game = game; - this.player = game.players[this.user.userid]; + game = room.game = game; + player = game.players[user.userid]; }); afterEach(function () { - destroyUser(this.user); - destroyUser(this.user2); - destroyUser(this.user3); - if (this.room.game) { - clearTimeout(this.game.phaseTimeout); - this.game.phaseTimeout = null; - this.game.destroy(); + destroyUser(user); + destroyUser(user2); + destroyUser(user3); + if (room.game) { + clearTimeout(game.phaseTimeout); + game.phaseTimeout = null; + game.destroy(); } }); @@ -325,33 +327,33 @@ describe('Trivia', function () { let diff = -1; for (let i = 6; i--;) { diff += totalDiff / 5; - let points = this.game.calculatePoints(diff, totalDiff); + let points = game.calculatePoints(diff, totalDiff); assert.strictEqual(points, i); } }); it('should set players as having answered correctly or incorrectly', function () { - this.game.answerQuestion('not the right answer', this.user); - assert.strictEqual(this.player.isCorrect, false); - this.game.answerQuestion('answer', this.user); - assert.strictEqual(this.player.isCorrect, true); + game.answerQuestion('not the right answer', user); + assert.strictEqual(player.isCorrect, false); + game.answerQuestion('answer', user); + assert.strictEqual(player.isCorrect, true); }); it('should give points for correct answers', function () { - this.game.answerQuestion('answer', this.user); - this.game.tallyAnswers(); - assert.strictEqual(this.player.correctAnswers, 1); + game.answerQuestion('answer', user); + game.tallyAnswers(); + assert.strictEqual(player.correctAnswers, 1); }); it('should choose the quicker answerer on tie', function (done) { - this.game.answerQuestion('answer', this.user); + game.answerQuestion('answer', user); setImmediate(() => { - this.game.answerQuestion('answer', this.user2); - this.game.tallyAnswers(); + game.answerQuestion('answer', user2); + game.tallyAnswers(); const hrtimeToNanoseconds = hrtime => hrtime[0] * 1e9 + hrtime[1]; - let playerNs = hrtimeToNanoseconds(this.player.answeredAt); - let player2Ns = hrtimeToNanoseconds(this.game.players[this.user2.userid].answeredAt); + let playerNs = hrtimeToNanoseconds(player.answeredAt); + let player2Ns = hrtimeToNanoseconds(game.players[user2.userid].answeredAt); assert.ok(playerNs <= player2Ns); done(); @@ -359,46 +361,46 @@ describe('Trivia', function () { }); it('should not give NaN points to correct responders', function () { - this.game.answerQuestion('answer', this.user); - this.game.tallyAnswers(); - assert.ok(!isNaN(this.player.points)); + game.answerQuestion('answer', user); + game.tallyAnswers(); + assert.ok(!isNaN(player.points)); }); }); - context('number mode', function () { + describe('number mode', function () { beforeEach(function () { let questions = [{question: '', answers: ['answer'], category: 'ae'}]; - let game = new NumberModeTrivia(this.room, 'first', 'ae', 'short', questions); + let game = new NumberModeTrivia(room, 'first', 'ae', 'short', questions); - this.user = makeUser('Morfent', new Connection('127.0.0.1')); - this.user2 = makeUser('user2', new Connection('127.0.0.2')); - this.user3 = makeUser('user3', new Connection('127.0.0.3')); + user = makeUser('Morfent', new Connection('127.0.0.1')); + user2 = makeUser('user2', new Connection('127.0.0.2')); + user3 = makeUser('user3', new Connection('127.0.0.3')); - game.addPlayer(this.user); - game.addPlayer(this.user2); - game.addPlayer(this.user3); + game.addPlayer(user); + game.addPlayer(user2); + game.addPlayer(user3); game.start(); game.askQuestion(); - this.game = this.room.game = game; - this.player = game.players[this.user.userid]; + game = room.game = game; + player = game.players[user.userid]; }); afterEach(function () { - destroyUser(this.user); - destroyUser(this.user2); - destroyUser(this.user3); - if (this.room.game) { - clearTimeout(this.game.phaseTimeout); - this.game.phaseTimeout = null; - this.game.destroy(); + destroyUser(user); + destroyUser(user2); + destroyUser(user3); + if (room.game) { + clearTimeout(game.phaseTimeout); + game.phaseTimeout = null; + game.destroy(); } }); it('should calculate points correctly', function () { - this.game.playerCount = 5; + game.playerCount = 5; for (let i = 1; i <= 5; i++) { - assert.strictEqual(this.game.calculatePoints(i), 6 - i); + assert.strictEqual(game.calculatePoints(i), 6 - i); } }); @@ -406,21 +408,21 @@ describe('Trivia', function () { // to that of timer mode. it('should not give points for answering incorrectly', function () { - this.game.answerQuestion('not the right answer', this.user); - this.game.tallyAnswers(); - assert.strictEqual(this.player.correctAnswers, 0); + game.answerQuestion('not the right answer', user); + game.tallyAnswers(); + assert.strictEqual(player.correctAnswers, 0); }); it('should give points for answering correctly', function () { - this.game.answerQuestion('answer', this.user); - this.game.tallyAnswers(); - assert.strictEqual(this.player.correctAnswers, 1); + game.answerQuestion('answer', user); + game.tallyAnswers(); + assert.strictEqual(player.correctAnswers, 1); }); it('should not give NaN points to correct responders', function () { - this.game.answerQuestion('answer', this.user); - this.game.tallyAnswers(); - assert.ok(!isNaN(this.player.points)); + game.answerQuestion('answer', user); + game.tallyAnswers(); + assert.ok(!isNaN(player.points)); }); }); }); diff --git a/test/main.js b/test/main.js index 24c8938c5158..9f7138e7acbb 100644 --- a/test/main.js +++ b/test/main.js @@ -5,8 +5,7 @@ const fs = require('fs'); const noop = () => {}; -before('initialization', function () { - this.timeout(0); // Remove timeout limitation +beforeAll(function () { process.on('unhandledRejection', err => { // I'd throw the err, but we have a heisenbug on our hands and I'd // rather not have it screw with Travis in the interim @@ -48,4 +47,4 @@ before('initialization', function () { LoginServer.disabled = true; Ladders.disabled = true; -}); +}, 0); diff --git a/test/mocha.opts b/test/mocha.opts deleted file mode 100644 index 18275aa96fd0..000000000000 --- a/test/mocha.opts +++ /dev/null @@ -1,4 +0,0 @@ -test/main.js test/simulator/**/*.js test/application/*.js test/chat-plugins/*.js test/dev-tools/*.js --R dot --u bdd ---exit diff --git a/test/simulator/abilities/arenatrap.js b/test/simulator/abilities/arenatrap.js index 4c447ed5fdfb..838271f1de02 100644 --- a/test/simulator/abilities/arenatrap.js +++ b/test/simulator/abilities/arenatrap.js @@ -11,7 +11,6 @@ describe('Arena Trap', function () { }); it('should prevent grounded Pokemon that are not immune to trapping from switching out normally', function () { - this.timeout(0); battle = common.createBattle(); battle.setPlayer('p1', {team: [{species: "Dugtrio", ability: 'arenatrap', moves: ['snore', 'telekinesis', 'gravity']}]}); battle.setPlayer('p2', {team: [ @@ -53,5 +52,5 @@ describe('Arena Trap', function () { assert.trapped(() => battle.makeChoices('', 'switch 4'), true); // Tornadus is trapped assert.species(p2active[0], 'Tornadus'); - }); + }, 0); }); diff --git a/test/simulator/abilities/contrary.js b/test/simulator/abilities/contrary.js index d97c0441ec71..3e897e2a8fcd 100644 --- a/test/simulator/abilities/contrary.js +++ b/test/simulator/abilities/contrary.js @@ -11,7 +11,6 @@ describe('Contrary', function () { }); it('should invert relative stat changes', function () { - this.timeout(0); battle = common.createBattle(); battle.setPlayer('p1', {team: [{species: "Spinda", ability: 'contrary', moves: ['superpower']}]}); battle.setPlayer('p2', {team: [{species: "Dragonite", ability: 'multiscale', moves: ['dragondance']}]}); @@ -19,7 +18,7 @@ describe('Contrary', function () { battle.makeChoices('move superpower', 'move dragondance'); assert.statStage(contraryMon, 'atk', 1); assert.statStage(contraryMon, 'def', 1); - }); + }, 0); it('should not invert absolute stat changes', function () { battle = common.createBattle(); diff --git a/test/simulator/abilities/lightningrod.js b/test/simulator/abilities/lightningrod.js index a7fb66b51cc7..94aae0ec797b 100644 --- a/test/simulator/abilities/lightningrod.js +++ b/test/simulator/abilities/lightningrod.js @@ -37,7 +37,6 @@ describe('Lightning Rod', function () { }); it('should redirect single-target Electric-type attacks to the user if it is a valid target', function () { - this.timeout(3000); battle = common.createBattle({gameType: 'triples'}); battle.setPlayer('p1', {team: [ {species: 'Manectric', ability: 'lightningrod', moves: ['sleeptalk']}, @@ -53,7 +52,7 @@ describe('Lightning Rod', function () { assert.statStage(battle.p1.active[0], 'spa', 3); assert.false.fullHP(battle.p1.active[2]); assert.false.fullHP(battle.p2.active[0]); - }); + }, 3000); it('should redirect to the fastest Pokemon with the ability', function () { battle = common.createBattle({gameType: 'doubles'}); diff --git a/test/simulator/abilities/pressure.js b/test/simulator/abilities/pressure.js index 75f0a175221b..26e994a0ac9e 100644 --- a/test/simulator/abilities/pressure.js +++ b/test/simulator/abilities/pressure.js @@ -47,7 +47,6 @@ describe('Pressure', function () { }); it('should deduct PP for each Pressure Pokemon targetted', function () { - this.timeout(3000); battle = common.createBattle({gameType: 'triples'}); battle.setPlayer('p1', {team: [ {species: "Giratina", ability: 'pressure', moves: ['rest']}, @@ -63,10 +62,9 @@ describe('Pressure', function () { assert.strictEqual(battle.p2.active[0].getMoveData(Dex.getMove('hail')).pp, 12); assert.strictEqual(battle.p2.active[1].getMoveData(Dex.getMove('spikes')).pp, 28); assert.strictEqual(battle.p2.active[2].getMoveData(Dex.getMove('rockslide')).pp, 13); - }); + }, 3000); it('should deduct PP for each opposing Pressure Pokemon when Snatch of Imprison are used', function () { - this.timeout(3000); battle = common.createBattle({gameType: 'triples'}); battle.setPlayer('p1', {team: [ {species: "Giratina", ability: 'pressure', moves: ['rest']}, @@ -81,7 +79,7 @@ describe('Pressure', function () { battle.makeChoices('move rest, move rest, move rest', 'move snatch, move imprison, move rest'); assert.strictEqual(battle.p2.active[0].getMoveData(Dex.getMove('snatch')).pp, 12); assert.strictEqual(battle.p2.active[1].getMoveData(Dex.getMove('imprison')).pp, 12); - }); + }, 3000); }); describe('Pressure [Gen 4]', function () { diff --git a/test/simulator/misc/random-teams.js b/test/simulator/misc/random-teams.js index 4f6fd25c167b..e454fa5b1296 100644 --- a/test/simulator/misc/random-teams.js +++ b/test/simulator/misc/random-teams.js @@ -29,7 +29,6 @@ function isValidSet(gen, set) { describe(`Random Team generator`, function () { for (const gen of ALL_GENS) { it(`should successfully create valid Gen ${gen} teams`, function () { - this.timeout(0); const generator = Dex.getTeamGenerator(`gen${gen}randombattle`); if (generator.gen !== gen) return; // format doesn't exist for this gen @@ -45,14 +44,13 @@ describe(`Random Team generator`, function () { throw err; } } - }); + }, 0); } }); describe(`Challenge Cup Team generator`, function () { for (const gen of ALL_GENS) { it(`should successfully create valid Gen ${gen} teams`, function () { - this.timeout(0); const generator = Dex.getTeamGenerator(`gen${gen}challengecup`); if (generator.gen !== gen) return; // format doesn't exist for this gen @@ -68,14 +66,13 @@ describe(`Challenge Cup Team generator`, function () { throw err; } } - }); + }, 0); } }); describe(`Hackmons Cup Team generator`, function () { for (const gen of ALL_GENS) { it(`should successfully create valid Gen ${gen} teams`, function () { - this.timeout(0); const generator = Dex.getTeamGenerator(`gen${gen}hackmonscup`); if (generator.gen !== gen) return; // format doesn't exist for this gen @@ -91,14 +88,13 @@ describe(`Hackmons Cup Team generator`, function () { throw err; } } - }); + }, 5000); } }); describe(`Factory sets`, function () { for (const filename of ['bss-factory-sets', 'factory-sets']) { it(`should have valid sets in ${filename}.json`, function () { - this.timeout(5000); const setsJSON = require(`../../../data/${filename}.json`); for (const type in setsJSON) { diff --git a/test/simulator/misc/statusmoves.js b/test/simulator/misc/statusmoves.js index 8d3d043e1417..50ad0d2d7ef3 100644 --- a/test/simulator/misc/statusmoves.js +++ b/test/simulator/misc/statusmoves.js @@ -33,8 +33,6 @@ describe('Most status moves', function () { }); it('should fail when the opposing Pokemon is immune to the status effect it sets', function () { - this.timeout(0); - battle = common.createBattle(); battle.setPlayer('p1', {team: [{species: "Smeargle", ability: 'noguard', item: 'laggingtail', moves: ['thunderwave', 'willowisp', 'poisongas', 'toxic']}]}); battle.setPlayer('p2', {team: [ @@ -67,7 +65,7 @@ describe('Most status moves', function () { battle.makeChoices('move toxic', 'move magnetrise'); assert.strictEqual(battle.p2.active[0].status, ''); assert.ok(battle.log[battle.lastMoveLine + 1].startsWith('|-immune|')); - }); + }, 0); }); describe('Poison-inflicting status moves [Gen 2]', function () { diff --git a/test/simulator/moves/followme.js b/test/simulator/moves/followme.js index a332135e2907..dbccc5661c57 100644 --- a/test/simulator/moves/followme.js +++ b/test/simulator/moves/followme.js @@ -11,8 +11,6 @@ describe('Follow Me', function () { }); it('should redirect single-target moves towards it if it is a valid target', function () { - this.timeout(5000); - battle = common.createBattle({gameType: 'triples'}); battle.setPlayer('p1', {team: [ {species: 'Clefable', ability: 'unaware', moves: ['followme']}, @@ -32,7 +30,7 @@ describe('Follow Me', function () { }); battle.makeChoices('move followme, move calmmind, move calmmind', 'move lowkick 2, move lowkick 2, move lowkick 2'); assert.strictEqual(hitCount, 2); - }); + }, 5000); it('should not redirect self-targetting moves', function () { battle = common.createBattle({gameType: 'doubles'}); diff --git a/test/simulator/moves/ragepowder.js b/test/simulator/moves/ragepowder.js index 38f154b12ac1..b87f57003ef7 100644 --- a/test/simulator/moves/ragepowder.js +++ b/test/simulator/moves/ragepowder.js @@ -12,8 +12,6 @@ describe('Rage Powder', function () { }); it('should redirect single-target moves towards it if it is a valid target', function () { - this.timeout(5000); - battle = common.createBattle({gameType: 'triples'}); battle.setPlayer('p1', {team: [ {species: 'Amoonguss', ability: 'overcoat', item: 'safetygoggles', moves: ['ragepowder']}, @@ -42,7 +40,7 @@ describe('Rage Powder', function () { assert.strictEqual(hitCount[0], 2); assert.strictEqual(hitCount[1], 1); assert.strictEqual(hitCount[2], 0); - }); + }, 5000); it('should not affect Pokemon with Powder immunities', function () { battle = common.createBattle({gameType: 'triples'});