A playable console Minesweeper (arrow keys, chording, flags, question marks, pause, difficulty presets) plus a deduction-and-guess solver that can play the game headlessly. Game logic lives in src/Minesweeper/Game and has no console dependencies, so it is covered by 65 unit tests. Includes publishing helpers for self-contained, trimmed single-file binaries (publish.sh) and an .editorconfig that the sources conform to: UTF-8 BOM and 4-space indents for C#, 2-space indents for project files, LF endings and 2-space indents for shell scripts, System-first usings, no redundant `this.`, and s_/ _ prefixed private static and instance fields.
72 lines
2.6 KiB
C#
72 lines
2.6 KiB
C#
using Minesweeper.Cli;
|
|
using Minesweeper.Game;
|
|
using Xunit;
|
|
|
|
namespace Minesweeper.Tests;
|
|
|
|
public class CommandLineTests
|
|
{
|
|
[Fact]
|
|
public void DefaultsAreBeginner()
|
|
{
|
|
Assert.True(CommandLine.TryParse([], out var options, out var errors, out var help));
|
|
Assert.Empty(errors);
|
|
Assert.False(help);
|
|
Assert.Equal(DifficultyProfile.Beginner, options.Difficulty);
|
|
Assert.True(options.ReserveSafeZone);
|
|
Assert.True(options.QuestionMarks);
|
|
Assert.False(options.Auto);
|
|
Assert.Null(options.Seed);
|
|
}
|
|
|
|
[Fact]
|
|
public void PresetAndCustomSizesCombine()
|
|
{
|
|
Assert.True(CommandLine.TryParse(["-d", "expert"], out var options, out _, out _));
|
|
Assert.Equal(30, options.Difficulty.Width);
|
|
Assert.Equal(99, options.Difficulty.Mines);
|
|
|
|
Assert.True(CommandLine.TryParse(["--size", "12x8", "--mines", "5"], out options, out _, out _));
|
|
Assert.Equal((12, 8, 5), (options.Difficulty.Width, options.Difficulty.Height, options.Difficulty.Mines));
|
|
}
|
|
|
|
[Fact]
|
|
public void SwitchesAreHonoured()
|
|
{
|
|
Assert.True(CommandLine.TryParse(
|
|
["--auto-trace", "--seed", "42", "--no-safe-zone", "--no-question-marks", "--compact", "--ascii", "--no-color"],
|
|
out var options, out var errors, out _));
|
|
|
|
Assert.Empty(errors);
|
|
Assert.True(options.Auto);
|
|
Assert.True(options.AutoTrace);
|
|
Assert.Equal(42, options.Seed);
|
|
Assert.False(options.ReserveSafeZone);
|
|
Assert.False(options.QuestionMarks);
|
|
Assert.True(options.Compact);
|
|
Assert.True(options.Ascii);
|
|
Assert.False(options.Color);
|
|
}
|
|
|
|
[Fact]
|
|
public void HelpShortCircuitsEverythingElse()
|
|
{
|
|
Assert.True(CommandLine.TryParse(["--help"], out _, out var errors, out var help));
|
|
Assert.True(help);
|
|
Assert.Empty(errors);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData(new[] { "--nope" }, "Unknown option")]
|
|
[InlineData(new[] { "--seed" }, "needs a value")]
|
|
[InlineData(new[] { "--seed", "abc" }, "expects a whole number")]
|
|
[InlineData(new[] { "-d", "impossible" }, "Unknown difficulty")]
|
|
[InlineData(new[] { "--size", "9x9", "--mines", "900" }, "do not leave a safe square")]
|
|
[InlineData(new[] { "--auto-max-steps", "0" }, "expects a positive number")]
|
|
public void MistakesAreReported(string[] args, string expectedFragment)
|
|
{
|
|
Assert.False(CommandLine.TryParse(args, out _, out var errors, out _));
|
|
Assert.Contains(errors, error => error.Contains(expectedFragment, StringComparison.Ordinal));
|
|
}
|
|
}
|