using Minesweeper.Cli; using Minesweeper.Core; namespace Minesweeper.Core.Tests; public class CommandLineTests { [Fact] public void TryParse_WithoutArguments_UsesBeginnerDefaults() { Assert.True(CommandLine.TryParse([], out var options, out var error)); Assert.Empty(error); Assert.Equal(GameDifficulty.Beginner, options.Difficulty); Assert.Null(options.Seed); Assert.False(options.UseKeys); Assert.False(options.ShowHelp); } [Theory] [InlineData("-d", "expert", GameDifficulty.Expert)] [InlineData("--difficulty", "EXPERT", GameDifficulty.Expert)] [InlineData("-d", "hard", GameDifficulty.Expert)] [InlineData("-d", "3", GameDifficulty.Expert)] [InlineData("-d", "e", GameDifficulty.Expert)] [InlineData("-d", "beginner", GameDifficulty.Beginner)] [InlineData("-d", "easy", GameDifficulty.Beginner)] [InlineData("-d", "1", GameDifficulty.Beginner)] [InlineData("-d", "intermediate", GameDifficulty.Intermediate)] [InlineData("-d", "medium", GameDifficulty.Intermediate)] [InlineData("-d", "2", GameDifficulty.Intermediate)] public void TryParse_DifficultySwitch(string flag, string value, GameDifficulty expected) { Assert.True(CommandLine.TryParse([flag, value], out var options, out _)); Assert.Equal(expected, options.Difficulty); } [Theory] [InlineData(new[] { "-b" }, GameDifficulty.Beginner)] [InlineData(new[] { "-i" }, GameDifficulty.Intermediate)] [InlineData(new[] { "-e" }, GameDifficulty.Expert)] public void TryParse_DifficultyShorthands(string[] args, GameDifficulty expected) { Assert.True(CommandLine.TryParse(args, out var options, out _)); Assert.Equal(expected, options.Difficulty); } [Fact] public void TryParse_CombinesOptions() { Assert.True(CommandLine.TryParse(["-e", "--seed", "42", "-k"], out var options, out _)); Assert.Equal(GameDifficulty.Expert, options.Difficulty); Assert.Equal(42, options.Seed); Assert.True(options.UseKeys); } [Theory] [InlineData("0")] [InlineData("-7")] [InlineData("999999999")] public void TryParse_AcceptsAnyIntegerSeed(string seed) { Assert.True(CommandLine.TryParse(["--seed", seed], out var options, out _)); Assert.Equal(int.Parse(seed), options.Seed); } [Fact] public void TryParse_Help() { Assert.True(CommandLine.TryParse(["--help"], out var options, out _)); Assert.True(options.ShowHelp); Assert.True(CommandLine.TryParse(["-h"], out options, out _)); Assert.True(options.ShowHelp); } [Fact] public void TryParse_Keys() { Assert.True(CommandLine.TryParse(["--keys"], out var options, out _)); Assert.True(options.UseKeys); Assert.True(CommandLine.TryParse(["-k"], out options, out _)); Assert.True(options.UseKeys); } [Theory] [InlineData("--difficulty")] [InlineData("-d")] public void TryParse_DifficultyWithoutValue_Fails(string flag) { Assert.False(CommandLine.TryParse([flag], out var options, out var error)); Assert.Null(options); Assert.Contains("difficulty", error); } [Theory] [InlineData("impossible")] [InlineData("")] public void TryParse_UnknownDifficulty_Fails(string value) { Assert.False(CommandLine.TryParse(["-d", value], out var options, out var error)); Assert.Null(options); Assert.Contains("difficulty", error); } [Theory] [InlineData("--seed")] [InlineData("--seed", "abc")] [InlineData("--seed", "1.5")] public void TryParse_BadSeed_Fails(params string[] args) { Assert.False(CommandLine.TryParse(args, out var options, out var error)); Assert.Null(options); Assert.Contains("seed", error); } [Fact] public void TryParse_UnknownOption_FailsAndNamesIt() { Assert.False(CommandLine.TryParse(["--turbo"], out var options, out var error)); Assert.Null(options); Assert.Contains("--turbo", error); } [Fact] public void Usage_MentionsEveryOption() { Assert.Contains("--difficulty", CommandLine.Usage); Assert.Contains("--seed", CommandLine.Usage); Assert.Contains("--keys", CommandLine.Usage); Assert.Contains("--help", CommandLine.Usage); } [Fact] public void HelpText_ListsEveryCommandVerb() { foreach (var verb in new[] { "reveal", "flag", "chord", "go", "difficulty", "new", "help", "quit" }) { Assert.Contains(verb, GameSession.HelpText); } } }