Files
drobor-ai 2ba405b19c Initial commit: terminal Minesweeper in C# for .NET 10
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.
2026-09-08 07:12:51 +00:00

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));
}
}