/src/Tests/UnitTests/Metadata/ArgumentFlagsTests.cs

https://github.com/reubeno/NClap · C# · 144 lines · 123 code · 21 blank · 0 comment · 1 complexity · 0573ee25ca30be0df161a2e1fac7ae8d MD5 · raw file

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Reflection;
  4. using FluentAssertions;
  5. using Microsoft.VisualStudio.TestTools.UnitTesting;
  6. using NClap.Exceptions;
  7. using NClap.Metadata;
  8. namespace NClap.Tests.Metadata
  9. {
  10. [TestClass]
  11. public class ArgumentFlagsTests
  12. {
  13. [ArgumentSet(Style = ArgumentSetStyle.WindowsCommandLine)]
  14. public class RequiredArguments<T>
  15. {
  16. [NamedArgument(ArgumentFlags.Required)]
  17. public T Value;
  18. }
  19. [ArgumentSet(Style = ArgumentSetStyle.WindowsCommandLine)]
  20. public class AtMostOnceArguments<T>
  21. {
  22. [NamedArgument(ArgumentFlags.AtMostOnce)]
  23. public T Value;
  24. }
  25. [ArgumentSet(Style = ArgumentSetStyle.WindowsCommandLine)]
  26. public class AtLeastOnceArguments<T>
  27. {
  28. [NamedArgument(ArgumentFlags.AtLeastOnce)]
  29. public T Value;
  30. }
  31. [ArgumentSet(Style = ArgumentSetStyle.WindowsCommandLine)]
  32. public class MultipleArguments<T>
  33. {
  34. [NamedArgument(ArgumentFlags.Multiple)]
  35. public T Value;
  36. }
  37. [ArgumentSet(Style = ArgumentSetStyle.WindowsCommandLine)]
  38. public class MultipleUniqueArguments<T>
  39. {
  40. [NamedArgument(ArgumentFlags.MultipleUnique)]
  41. public T Value;
  42. }
  43. [TestMethod]
  44. public void RequiredScalar()
  45. {
  46. ShouldFailToParse<RequiredArguments<string>>(Array.Empty<string>());
  47. ShouldParseAs<RequiredArguments<string>, string>(new[] { "/value:a" }, "a");
  48. ShouldFailToParse<RequiredArguments<string>>(new[] { "/value:a", "/value:b" });
  49. ShouldFailToParse<RequiredArguments<string>>(new[] { "/value:a", "/value:a" });
  50. }
  51. [TestMethod]
  52. public void AtMostOnceScalar()
  53. {
  54. ShouldParseAs<AtMostOnceArguments<string>, string>(Array.Empty<string>(), null);
  55. ShouldParseAs<AtMostOnceArguments<string>, string>(new[] { "/value:a" }, "a");
  56. ShouldFailToParse<AtMostOnceArguments<string>>(new[] { "/value:a", "/value:b" });
  57. ShouldFailToParse<AtMostOnceArguments<string>>(new[] { "/value:a", "/value:a" });
  58. }
  59. [TestMethod]
  60. public void AtLeastOnceScalar()
  61. {
  62. ShouldFailToParse<AtLeastOnceArguments<string>>(Array.Empty<string>());
  63. ShouldParseAs<AtLeastOnceArguments<string>, string>(new[] { "/value:a" }, "a");
  64. ShouldParseAs<AtLeastOnceArguments<string>, string>(new[] { "/value:a", "/value:b" }, "b");
  65. ShouldParseAs<AtLeastOnceArguments<string>, string>(new[] { "/value:a", "/value:a" }, "a");
  66. }
  67. [TestMethod]
  68. public void MultipleScalar()
  69. {
  70. ShouldParseAs<MultipleArguments<string>, string>(Array.Empty<string>(), null);
  71. ShouldParseAs<MultipleArguments<string>, string>(new[] { "/value:a" }, "a");
  72. ShouldParseAs<MultipleArguments<string>, string>(new[] { "/value:a", "/value:b" }, "b");
  73. ShouldParseAs<MultipleArguments<string>, string>(new[] { "/value:a", "/value:a" }, "a");
  74. }
  75. [TestMethod]
  76. public void MultipleUniqueScalar()
  77. {
  78. ShouldThrow<MultipleUniqueArguments<string>, InvalidArgumentSetException>(Array.Empty<string>());
  79. ShouldThrow<MultipleUniqueArguments<string>, InvalidArgumentSetException>(new[] { "/value:a" });
  80. ShouldThrow<MultipleUniqueArguments<string>, InvalidArgumentSetException>(new[] { "/value:a", "/value:b" });
  81. ShouldThrow<MultipleUniqueArguments<string>, InvalidArgumentSetException>(new[] { "/value:a", "/value:a" });
  82. }
  83. [TestMethod]
  84. public void MultipleUniqueCollection()
  85. {
  86. Parse(Array.Empty<string>(), out MultipleUniqueArguments<string[]> parsedArgs).Should().BeTrue();
  87. parsedArgs.Value.Should().BeEmpty();
  88. Parse(new[] { "/value:a" }, out parsedArgs).Should().BeTrue();
  89. parsedArgs.Value.Should().Equal("a");
  90. Parse(new[] { "/value:a", "/value:b" }, out parsedArgs).Should().BeTrue();
  91. parsedArgs.Value.Should().Equal("a", "b");
  92. Parse(new[] { "/value:a,b" }, out parsedArgs).Should().BeTrue();
  93. parsedArgs.Value.Should().Equal("a", "b");
  94. Parse(new[] { "/value:a", "/value:a" }, out parsedArgs).Should().BeFalse();
  95. Parse(new[] { "/value:a,a" }, out parsedArgs).Should().BeFalse();
  96. }
  97. private static void ShouldThrow<T, TException>(IEnumerable<string> args)
  98. where T : class, new()
  99. where TException : Exception
  100. {
  101. Action parse = () => Parse(args, out T parsedArgs);
  102. parse.Should().Throw<TException>();
  103. }
  104. private static void ShouldFailToParse<T>(IEnumerable<string> args) where T : class, new()
  105. {
  106. ValidateParse<T, object>(args, false);
  107. }
  108. private static void ShouldParseAs<T, TField>(IEnumerable<string> args, TField expectedValue) where T : class, new()
  109. {
  110. ValidateParse<T, TField>(args, true, expectedValue);
  111. }
  112. private static void ValidateParse<T, TField>(IEnumerable<string> args, bool expectedParseResult, TField expectedValue = default(TField)) where T : class, new()
  113. {
  114. Parse(args, out T parsedArgs).Should().Be(expectedParseResult);
  115. if (expectedParseResult)
  116. {
  117. typeof(T).GetTypeInfo().GetField("Value").GetValue(parsedArgs).Should().Be(expectedValue);
  118. }
  119. }
  120. private static bool Parse<T>(IEnumerable<string> args, out T parsedArgs) where T : class, new() =>
  121. CommandLineParser.TryParse(args, new CommandLineParserOptions { DisplayUsageInfoOnError = false }, out parsedArgs);
  122. }
  123. }