192 lines
6.1 KiB
C#
192 lines
6.1 KiB
C#
using Minesweeper.Cli;
|
|
using Minesweeper.Core;
|
|
|
|
namespace Minesweeper.Core.Tests;
|
|
|
|
public class CommandParserTests
|
|
{
|
|
[Theory]
|
|
[InlineData("q")]
|
|
[InlineData("quit")]
|
|
[InlineData("EXIT")]
|
|
public void Parse_QuitVerbs(string input) =>
|
|
Assert.IsType<Command.Quit>(CommandParser.Parse(input));
|
|
|
|
[Theory]
|
|
[InlineData("n")]
|
|
[InlineData("new")]
|
|
public void Parse_NewGame(string input) =>
|
|
Assert.IsType<Command.NewGame>(CommandParser.Parse(input));
|
|
|
|
[Theory]
|
|
[InlineData("h")]
|
|
[InlineData("help")]
|
|
[InlineData("?")]
|
|
[InlineData("HELP")]
|
|
public void Parse_Help(string input) =>
|
|
Assert.IsType<Command.ShowHelp>(CommandParser.Parse(input));
|
|
|
|
[Theory]
|
|
[InlineData("")]
|
|
[InlineData(" ")]
|
|
public void Parse_BlankInput_IsANoOp(string input) =>
|
|
Assert.IsType<Command.Noop>(CommandParser.Parse(input));
|
|
|
|
[Fact]
|
|
public void Parse_RevealVerb_IsZeroBased()
|
|
{
|
|
var command = Assert.IsType<Command.Reveal>(CommandParser.Parse("reveal 3 4"));
|
|
|
|
Assert.Equal(new CellLocation(2, 3), command.Cell);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("2 5")]
|
|
[InlineData("2,5")]
|
|
[InlineData(" 2 ; 5 ")]
|
|
[InlineData("2 5")]
|
|
public void Parse_BareCoordinates_Reveal(string input)
|
|
{
|
|
var command = Assert.IsType<Command.Reveal>(CommandParser.Parse(input));
|
|
|
|
Assert.Equal(new CellLocation(1, 4), command.Cell);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("r 1 1")]
|
|
[InlineData("open 1 1")]
|
|
public void Parse_RevealAliases(string input) =>
|
|
Assert.IsType<Command.Reveal>(CommandParser.Parse(input));
|
|
|
|
[Theory]
|
|
[InlineData("f 2 3")]
|
|
[InlineData("flag 2 3")]
|
|
[InlineData("mark 2 3")]
|
|
public void Parse_FlagAliases(string input)
|
|
{
|
|
var command = Assert.IsType<Command.Flag>(CommandParser.Parse(input));
|
|
|
|
Assert.Equal(new CellLocation(1, 2), command.Cell);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("c 4 5")]
|
|
[InlineData("chord 4 5")]
|
|
public void Parse_ChordAliases(string input)
|
|
{
|
|
var command = Assert.IsType<Command.Chord>(CommandParser.Parse(input));
|
|
|
|
Assert.Equal(new CellLocation(3, 4), command.Cell);
|
|
}
|
|
|
|
[Fact]
|
|
public void Parse_GotoMovesTheCursor()
|
|
{
|
|
var command = Assert.IsType<Command.SetCursor>(CommandParser.Parse("go 6 7"));
|
|
|
|
Assert.Equal(new CellLocation(5, 6), command.Cell);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("d 1", GameDifficulty.Beginner)]
|
|
[InlineData("difficulty beginner", GameDifficulty.Beginner)]
|
|
[InlineData("d EASY", GameDifficulty.Beginner)]
|
|
[InlineData("d 2", GameDifficulty.Intermediate)]
|
|
[InlineData("difficulty INTERMEDIATE", GameDifficulty.Intermediate)]
|
|
[InlineData("d medium", GameDifficulty.Intermediate)]
|
|
[InlineData("d 3", GameDifficulty.Expert)]
|
|
[InlineData("difficulty expert", GameDifficulty.Expert)]
|
|
[InlineData("d HARD", GameDifficulty.Expert)]
|
|
public void Parse_DifficultyAliases(string input, GameDifficulty expected)
|
|
{
|
|
var command = Assert.IsType<Command.ChangeDifficulty>(CommandParser.Parse(input));
|
|
|
|
Assert.Equal(expected, command.Difficulty);
|
|
}
|
|
|
|
[Fact]
|
|
public void Parse_DifficultyWithoutValue_ShowsHelp() =>
|
|
Assert.IsType<Command.ShowHelp>(CommandParser.Parse("difficulty"));
|
|
|
|
[Theory]
|
|
[InlineData("banana")]
|
|
[InlineData("reveal 3")]
|
|
[InlineData("reveal x y")]
|
|
[InlineData("flag -1 4")]
|
|
[InlineData("flag 0 4")]
|
|
[InlineData("reveal 1 0")]
|
|
[InlineData("d nonsense")]
|
|
[InlineData(" reveal")]
|
|
public void Parse_InvalidInput_ReportsUnknown(string input)
|
|
{
|
|
var command = Assert.IsType<Command.Unknown>(CommandParser.Parse(input));
|
|
|
|
Assert.NotEmpty(command.Input);
|
|
}
|
|
|
|
[Fact]
|
|
public void Parse_KeepsUnknownTextForEchoing()
|
|
{
|
|
var command = Assert.IsType<Command.Unknown>(CommandParser.Parse(" frobnicate 9 "));
|
|
|
|
Assert.Equal("frobnicate 9", command.Input);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData(ConsoleKey.UpArrow, -1, 0)]
|
|
[InlineData(ConsoleKey.DownArrow, 1, 0)]
|
|
[InlineData(ConsoleKey.LeftArrow, 0, -1)]
|
|
[InlineData(ConsoleKey.RightArrow, 0, 1)]
|
|
public void FromKey_ArrowsMoveTheCursor(ConsoleKey key, int row, int column)
|
|
{
|
|
var command = Assert.IsType<Command.MoveCursor>(CommandParser.FromKey(Key(key)));
|
|
|
|
Assert.Equal(row, command.RowDelta);
|
|
Assert.Equal(column, command.ColumnDelta);
|
|
}
|
|
|
|
[Fact]
|
|
public void FromKey_EnterAndSpaceRevealAtCursor()
|
|
{
|
|
Assert.IsType<Command.RevealAtCursor>(CommandParser.FromKey(Key(ConsoleKey.Enter)));
|
|
Assert.IsType<Command.RevealAtCursor>(CommandParser.FromKey(Key(ConsoleKey.Spacebar)));
|
|
}
|
|
|
|
[Fact]
|
|
public void FromKey_FlagAndChordActOnCursor()
|
|
{
|
|
Assert.IsType<Command.FlagAtCursor>(CommandParser.FromKey(Key(ConsoleKey.F, 'f')));
|
|
Assert.IsType<Command.ChordAtCursor>(CommandParser.FromKey(Key(ConsoleKey.C, 'c')));
|
|
}
|
|
|
|
[Fact]
|
|
public void FromKey_DifficultyShortcuts()
|
|
{
|
|
Assert.Equal(GameDifficulty.Beginner,
|
|
Assert.IsType<Command.ChangeDifficulty>(CommandParser.FromKey(Key(ConsoleKey.D1, '1'))).Difficulty);
|
|
Assert.Equal(GameDifficulty.Intermediate,
|
|
Assert.IsType<Command.ChangeDifficulty>(CommandParser.FromKey(Key(ConsoleKey.D2, '2'))).Difficulty);
|
|
Assert.Equal(GameDifficulty.Expert,
|
|
Assert.IsType<Command.ChangeDifficulty>(CommandParser.FromKey(Key(ConsoleKey.D3, '3'))).Difficulty);
|
|
}
|
|
|
|
[Fact]
|
|
public void FromKey_NewAndQuit()
|
|
{
|
|
Assert.IsType<Command.NewGame>(CommandParser.FromKey(Key(ConsoleKey.N, 'n')));
|
|
Assert.IsType<Command.Quit>(CommandParser.FromKey(Key(ConsoleKey.Escape)));
|
|
Assert.IsType<Command.Quit>(CommandParser.FromKey(Key(ConsoleKey.Q, 'q')));
|
|
}
|
|
|
|
[Fact]
|
|
public void FromKey_Help() =>
|
|
Assert.IsType<Command.ShowHelp>(CommandParser.FromKey(Key(ConsoleKey.H, 'h')));
|
|
|
|
[Fact]
|
|
public void FromKey_UnmappedKey_IsANoOp() =>
|
|
Assert.IsType<Command.Noop>(CommandParser.FromKey(Key(ConsoleKey.B, 'b')));
|
|
|
|
private static ConsoleKeyInfo Key(ConsoleKey key, char character = '\0') =>
|
|
new(character, key, shift: false, alt: false, control: false);
|
|
}
|