Newer
Older
Labyrinth / src / GameServer.spec.ts
// to get rid of "[ts] could not find module ..." in vs code realod the window: f1 -> type "reload window"
// official issue for this: https://github.com/Microsoft/TypeScript/issues/10346

import {expect} from "chai";
import {GameServer} from "./GameServer";
import { Direction, MazeMap, MazeTile } from "./MazeMap";
// import { describe, it } from "mocha";

function createTrivialMap(): MazeMap
{
    const maze = new MazeMap("lvl1");
    let tile = new MazeTile("1");
    tile.paths.push(Direction.right);
    tile.paths.push(Direction.bottom);
    maze.layout.push([tile]);
    tile = new MazeTile("2");
    tile.paths.push(Direction.left);
    tile.paths.push(Direction.bottom);
    maze.layout[0].push(tile);

    tile = new MazeTile("3");
    tile.paths.push(Direction.right);
    tile.paths.push(Direction.top);
    maze.layout.push([tile]);
    tile = new MazeTile("4");
    tile.paths.push(Direction.left);
    tile.paths.push(Direction.top);
    maze.layout[1].push(tile);

    maze.startPosition = [0,0];

    return maze;
}

function createGameServer(): GameServer
{
    const server = new GameServer();
    server.addMap(createTrivialMap());
    return server;
}

describe("Scenario: Accessing current position", function(){
    const userID = "UserID";
    const mapID = "lvl1";
    describe("When a game has been started for a player", function(){
        const games = createGameServer();
        games.startGame(userID, mapID);
        it("then the position must not be null", function(){
            const position = games.currentPosition(userID);
            expect(position).to.be.not.null;
        });
    });

    describe("When no game for player has been started", function(){
        const games = createGameServer();
        it("then null should be returned for that player", function(){
            const position = games.currentPosition(userID);
            expect(position).to.be.null;
        });
    });
});

describe("Scenario: Starting the game", function(){
    const userID = "UserID";
    const mapID = "lvl1";
    describe("when a user starts an existing valid level", function(){
        const games = createGameServer();
        const position = games.startGame(userID, mapID);

        it("then the start position must exist", function(){
            expect(position).to.be.not.null;
        });

        it("then the start position must be remembered for the user", function(){
            const current = games.currentPosition(userID);
            expect(current.id).to.equal(position.id);
        });
    });
});

describe("Scenario: Navigating in ongoing game", function(){
    const userID = "UserID";
    const mapID = "lvl1";

    describe("When player navigates in existing direction", function(){
        const games = createGameServer();
        const startPosition = games.startGame(userID, mapID);
        const naviagtionDirection = startPosition.paths[0];
        const nextPosition = games.navigate(userID, naviagtionDirection);
        it("then the new position has to have a different id", function(){
            expect(nextPosition.id).to.not.equal(startPosition.id);
        });

        it("then the new position must be remembered for the user", function(){
            const current = games.currentPosition(userID);
            expect(current.id).to.equal(nextPosition.id);
        });
    });

    describe("When a player navigates outside the map boundaries", function(){
        const games = createGameServer();
        games.startGame(userID, mapID);
        it("then it should throw an exception", function(){
            function expectedToFail(){
                games.navigate(userID, Direction.left);
            }
            expect(expectedToFail).to.throw(/.*invalid direction.*/i);
        });
    });

    describe("When a player navigates inside the map in non existing direction", function(){
        const games = createGameServer();
        const maze2 = createTrivialMap();
        maze2.id = "lvl2";
        maze2.layout[0][0].paths = maze2.layout[0][0].paths.filter(p => p !== Direction.bottom);
        maze2.layout[1][0].paths = maze2.layout[1][0].paths.filter(p => p !== Direction.top);
        games.addMap(maze2);

        games.startGame(userID, maze2.id);

        it("then it should throw an exception", function(){
            function expectedToFail(){
                games.navigate(userID, Direction.bottom);
            }
            expect(expectedToFail).to.throw(/.*invalid direction.*/i);
        });
    });
});