diff --git a/SabreTools.CommandLine.Test/Inputs/UserInputTests.cs b/SabreTools.CommandLine.Test/Inputs/UserInputTests.cs index 531ea18..ce45511 100644 --- a/SabreTools.CommandLine.Test/Inputs/UserInputTests.cs +++ b/SabreTools.CommandLine.Test/Inputs/UserInputTests.cs @@ -114,6 +114,63 @@ namespace SabreTools.CommandLine.Test.Inputs #endregion + #region GetFeature + + [Fact] + public void GetFeature_InvalidKey_Null() + { + UserInput userInput = new MockUserInput("a", "a", "a"); + var child = new MockFeature("b", "b", "b"); + userInput.Add(child); + + Feature? actual = userInput.GetFeature("c"); + Assert.Null(actual); + } + + [Fact] + public void GetFeature_Exists_WrongType_Throws() + { + UserInput userInput = new MockUserInput("a", "a", "a"); + var child = new MockUserInput("b", "b", "b"); + userInput.Add(child); + + Assert.Throws(() => _ = userInput.GetFeature("b")); + } + + [Fact] + public void GetFeature_Exists_Returns() + { + UserInput userInput = new MockUserInput("a", "a", "a"); + var child = new MockFeature("b", "b", "b"); + userInput.Add(child); + + int index = 0; + child.ProcessInput(["b"], ref index); + + Feature? actual = userInput.GetFeature("b"); + Assert.NotNull(actual); + Assert.Equal("b", actual.Name); + Assert.True(actual.Value); + } + + [Fact] + public void GetFeature_NestedExists_Null() + { + UserInput userInput = new MockUserInput("a", "a", "a"); + var child = new MockUserInput("b", "b", "b"); + userInput.Add(child); + var subChild = new MockFeature("c", "c", "c"); + child.Add(subChild); + + int index = 0; + subChild.ProcessInput(["c"], ref index); + + Feature? actual = userInput.GetFeature("c"); + Assert.Null(actual); + } + + #endregion + #region GetInt8 [Fact] @@ -666,6 +723,28 @@ namespace SabreTools.CommandLine.Test.Inputs #endregion + /// + /// Mock Feature implementation for testing + /// + private class MockFeature : Feature + { + public MockFeature(string name, string flag, string description, string? detailed = null) + : base(name, flag, description, detailed) + { + } + + public MockFeature(string name, string[] flags, string description, string? detailed = null) + : base(name, flags, description, detailed) + { + } + + /// + public override bool Execute() => true; + + /// + public override bool VerifyInputs() => true; + } + /// /// Mock UserInput implementation for testing /// diff --git a/SabreTools.CommandLine/Inputs/UserInput.cs b/SabreTools.CommandLine/Inputs/UserInput.cs index f4f5d06..5c4be3c 100644 --- a/SabreTools.CommandLine/Inputs/UserInput.cs +++ b/SabreTools.CommandLine/Inputs/UserInput.cs @@ -135,6 +135,19 @@ namespace SabreTools.CommandLine.Inputs return defaultValue; } + /// + /// Get a Feature value from a named input + /// + /// Input name to retrieve, if possible + /// The value if found, null otherwise + public Feature? GetFeature(string key) + { + if (TryGetFeature(key, out Feature? value)) + return value; + + return null; + } + /// /// Get an Int8 value from a named input /// @@ -312,6 +325,29 @@ namespace SabreTools.CommandLine.Inputs return false; } + /// + /// Get a Feature value from a named input + /// + /// Input name to retrieve, if possible + /// Value that was found, default value otherwise + /// True if the value was found, false otherwise + public bool TryGetFeature(string key, out Feature? value) + { + // Try to check immediate children + if (Children.TryGetValue(key, out var input)) + { + if (input is not Feature i) + throw new ArgumentException("Input is not a Feature"); + + value = i; + return true; + } + + // TODO: Investigate if nested features should be supported + value = null; + return false; + } + /// /// Get an Int8 value from a named input ///