using System; using System.IO; using Xunit; namespace GitConverter.TestsApp.ConsoleApp { /// /// Tests for command-line argument parsing edge cases. /// Ensures the CLI handles malformed or unusual inputs gracefully. /// [Collection("Logging")] public class ArgumentParsingTests : IDisposable { private readonly TextWriter _originalOut; private readonly TextWriter _originalErr; private readonly StringWriter _outWriter; private readonly StringWriter _errWriter; public ArgumentParsingTests() { _originalOut = Console.Out; _originalErr = Console.Error; _outWriter = new StringWriter(); _errWriter = new StringWriter(); Console.SetOut(_outWriter); Console.SetError(_errWriter); } public void Dispose() { Console.SetOut(_originalOut); Console.SetError(_originalErr); _outWriter.Dispose(); _errWriter.Dispose(); } [Fact(DisplayName = "Too few arguments returns app error and shows usage")] public void Run_TooFewArgs_ReturnsAppError() { var args = new[] { "gis_convert", "somefile.csv" }; var exit = GitConverter.ConsoleApp.Program.Run(args); var output = _outWriter.ToString(); Assert.Contains("usage:", output.ToLowerInvariant()); Assert.Equal(1, exit); } [Fact(DisplayName = "Empty string arguments are handled without crashing")] public void Run_EmptyStringArgs_HandledGracefully() { var args = new[] { "gis_convert", "", "Csv", "", "", "Log", "" }; var exit = GitConverter.ConsoleApp.Program.Run(args); Assert.NotEqual(3, exit); } [Fact(DisplayName = "Help flags return expected exit code")] public void Run_HelpFlag_ReturnsExpectedCode() { var exitHelp = GitConverter.ConsoleApp.Program.Run(new[] { "help" }); var exitDashHelp = GitConverter.ConsoleApp.Program.Run(new[] { "--help" }); var exitH = GitConverter.ConsoleApp.Program.Run(new[] { "-h" }); Assert.Equal(1, exitHelp); Assert.Equal(1, exitDashHelp); Assert.Equal(1, exitH); } [Fact(DisplayName = "Unknown command returns app error")] public void Run_UnknownCommand_ReturnsAppError() { var args = new[] { "unknown_command", "arg1", "arg2" }; var exit = GitConverter.ConsoleApp.Program.Run(args); var output = _outWriter.ToString(); Assert.Contains("unknown command", output.ToLowerInvariant()); Assert.Equal(1, exit); } [Theory(DisplayName = "Special characters in paths are preserved")] [InlineData("file with spaces.csv")] [InlineData("file_with_underscore.csv")] [InlineData("file-with-dash.csv")] [InlineData("file.multiple.dots.csv")] public void Run_SpecialCharsInPath_PreservedCorrectly(string filename) { var tempRoot = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N")); Directory.CreateDirectory(tempRoot); var inputPath = Path.Combine(tempRoot, filename); File.WriteAllText(inputPath, "x,y\n1,2"); var outDir = Path.Combine(tempRoot, "out"); var tempDir = Path.Combine(tempRoot, "temp"); var args = new[] { "gis_convert", inputPath, "Csv", outDir, tempDir, "unused" }; _outWriter.GetStringBuilder().Clear(); _errWriter.GetStringBuilder().Clear(); var exit = GitConverter.ConsoleApp.Program.Run(args); var combined = _outWriter.ToString() + _errWriter.ToString(); Assert.DoesNotContain("not found", combined.ToLowerInvariant()); try { if (Directory.Exists(tempRoot)) Directory.Delete(tempRoot, true); } catch { } } [Fact(DisplayName = "Format options are case-insensitive")] public void Run_FormatOption_CaseInsensitive() { var tempRoot = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N")); Directory.CreateDirectory(tempRoot); var inputPath = Path.Combine(tempRoot, "test.csv"); File.WriteAllText(inputPath, "x,y\n1,2"); var outDir = Path.Combine(tempRoot, "out"); var tempDir = Path.Combine(tempRoot, "temp"); var argsLower = new[] { "gis_convert", inputPath, "csv", outDir, tempDir, "unused" }; var argsUpper = new[] { "gis_convert", inputPath, "CSV", outDir, tempDir, "unused" }; var argsMixed = new[] { "gis_convert", inputPath, "CsV", outDir, tempDir, "unused" }; _outWriter.GetStringBuilder().Clear(); var exit1 = GitConverter.ConsoleApp.Program.Run(argsLower); var output1 = _outWriter.ToString(); _outWriter.GetStringBuilder().Clear(); var exit2 = GitConverter.ConsoleApp.Program.Run(argsUpper); var output2 = _outWriter.ToString(); _outWriter.GetStringBuilder().Clear(); var exit3 = GitConverter.ConsoleApp.Program.Run(argsMixed); var output3 = _outWriter.ToString(); Assert.DoesNotContain("unknown", output1.ToLowerInvariant()); Assert.DoesNotContain("unknown", output2.ToLowerInvariant()); Assert.DoesNotContain("unknown", output3.ToLowerInvariant()); try { if (Directory.Exists(tempRoot)) Directory.Delete(tempRoot, true); } catch { } } } }