public void DoesNotFillOptionsAndArguments() { var builder = new CommandTreeBuilder(_singleAssemblyProvider); var tree = builder.BuildBaseTree(); var commands = from commandGroup in tree.CommandGroups from command in commandGroup.Commands where command.Arguments.Any() || command.Options.Any() select new { commandGroup, command }; Assert.IsEmpty(commands, $"Found {commands.Count()} Commands with filled Options and/or Arguments. These should not be filled when building the base tree."); }
public void ReturnsSuccessfulIfAnEnumHasTooManyChoices() { var builder = new CommandTreeBuilder(); builder.RegisterModule <TooManyChoiceValues>(); var tree = builder.Build(); var result = tree.CreateApplicationCommands(out _); ResultAssert.Successful(result); }
public void SearchIsUnsuccessfulIfNoMatchingCommandExists() { var builder = new CommandTreeBuilder(); builder.RegisterModule <NamedGroupWithCommandsWithNestedNamedGroupWithCommands>(); var tree = builder.Build(); var result = tree.Search("a d c"); Assert.Empty(result); }
public void ReturnsSuccessForValidTree() { var builder = new CommandTreeBuilder(); builder.RegisterModule <ValidCommandGroup>(); var tree = builder.Build(); var result = tree.CreateApplicationCommands(out _); ResultAssert.Successful(result); }
public void ReturnsUnsuccessfulIfThereAreTooManyRootLevelCommands() { var builder = new CommandTreeBuilder(); builder.RegisterModule <TooManyCommands>(); var tree = builder.Build(); var result = tree.CreateApplicationCommands(); ResultAssert.Unsuccessful(result); }
public void ReturnsUnsuccessfulIfAGroupHasTooManyCommands() { var builder = new CommandTreeBuilder(); builder.RegisterModule <TooManyGroupCommands>(); var tree = builder.Build(); var result = tree.CreateApplicationCommands(out _); ResultAssert.Unsuccessful(result); }
public void ReturnsUnsuccessfulIfGroupsAreTooDeeplyNested() { var builder = new CommandTreeBuilder(); builder.RegisterModule <TooDeeplyNested>(); var tree = builder.Build(); var result = tree.CreateApplicationCommands(out _); ResultAssert.Unsuccessful(result); }
public void ReturnsUnsuccessfulIfAParameterDescriptionIsTooLong() { var builder = new CommandTreeBuilder(); builder.RegisterModule <TooLongParameterDescription>(); var tree = builder.Build(); var result = tree.CreateApplicationCommands(); ResultAssert.Unsuccessful(result); }
public void SearchIsSuccessfulIfAMatchingCommandExists() { var builder = new CommandTreeBuilder(); builder.RegisterModule <NamedGroupWithCommandsWithNestedNamedGroupWithCommands>(); var tree = builder.Build(); var result = tree.Search("a c d", new Dictionary <string, IReadOnlyList <string> >()); Assert.NotEmpty(result); }
public void ReturnsUnsuccessfulIfACommandContainsASwitchParameter() { var builder = new CommandTreeBuilder(); builder.RegisterModule <SwitchesAreNotSupported>(); var tree = builder.Build(); var result = tree.CreateApplicationCommands(out _); ResultAssert.Unsuccessful(result); }
public void ReturnsUnsuccessfulIfThereAreOverloadsAtTheRootLevel() { var builder = new CommandTreeBuilder(); builder.RegisterModule <OverloadsAreNotSupportedInRoot>(); var tree = builder.Build(); var result = tree.CreateApplicationCommands(out _); ResultAssert.Unsuccessful(result); }
public void CanFindCommandByCommandAliasAndGroupAlias() { var builder = new CommandTreeBuilder(); builder.RegisterModule <AliasedGroupWithAliasedCommand>(); var tree = builder.Build(); var result = tree.Search("t c", new Dictionary <string, IReadOnlyList <string> >()); Assert.NotEmpty(result); }
public void NestedEmptyGroupsAreOptimizedOut() { var builder = new CommandTreeBuilder(); builder.RegisterModule <NestedGroupThatIsEmptyAfterExclusion>(); var tree = builder.Build(); var result = tree.CreateApplicationCommands(); var commands = result.Entity !; Assert.Empty(commands); }
public void CanExcludeGroup() { var builder = new CommandTreeBuilder(); builder.RegisterModule <ExcludedGroup>(); var tree = builder.Build(); var result = tree.CreateApplicationCommands(); var commands = result.Entity !; Assert.Empty(commands); }
public void ReturnsUnsuccessfulIfMultipleNamedGroupsWithTheSameNameHaveADefaultPermissionAttribute() { var builder = new CommandTreeBuilder(); builder.RegisterModule <AtMostOneDefaultPermissionAttributeAllowed.Named.GroupOne>(); builder.RegisterModule <AtMostOneDefaultPermissionAttributeAllowed.Named.GroupTwo>(); var tree = builder.Build(); var result = tree.CreateApplicationCommands(); ResultAssert.Unsuccessful(result); }
public void CommandGroupHelp(CommandGroup commandGroup) { if (commandGroup == null) { throw new ArgumentNullException(nameof(commandGroup)); } var appName = Assembly.GetEntryAssembly().GetName().Name; Console.WriteLine($"Command group: {commandGroup.Name}"); // Print all the commands except the help command itself(that's the one we're currently in). // Use the MethodHandle to compare. var currentMethodHandle = MethodBase.GetCurrentMethod().MethodHandle; var commands = commandGroup.Commands .Where(q => !q.CommandMethodInfo.MethodHandle.Equals(currentMethodHandle)); Console.WriteLine($"Syntax: {appName} {commandGroup.Name} [command] [option:value] [[--]argument:value]"); Console.WriteLine(); Console.WriteLine($"Available commands:"); foreach (var command in commands) { CommandTreeBuilder.FillOptionsAndArguments(command); Console.WriteLine($"{command.CommandAttribute.Name} - {command.CommandAttribute.Description}"); if (command.Options.Any()) { Console.WriteLine($" Options:"); ConsoleUtilities.WriteDictionary( command.Options.ToDictionary(key => key.CommandOptionAttribute.Name, value => value.CommandOptionAttribute.Description), 5, 4); } if (command.Arguments.Any()) { Console.WriteLine($" Arguments:"); ConsoleUtilities.WriteDictionary( command.Arguments.ToDictionary(key => key.CommandArgumentAttribute.Name, value => value.CommandArgumentAttribute.Description), 5, 4); } if (!string.IsNullOrWhiteSpace(command.CommandAttribute.ExampleUsage)) { Console.WriteLine($" Example usage:"); Console.WriteLine($" {command.CommandAttribute.ExampleUsage}"); } Console.WriteLine(); } Console.WriteLine(); }
public void FindsCommandsInCommandGroups(Type commandGroupType, string[] commandMethodNames) { var builder = new CommandTreeBuilder(_singleAssemblyProvider); var tree = builder.BuildBaseTree(); var commandGroup = tree.CommandGroups.First(q => q.CommandGroupType == commandGroupType); Assert.Multiple(() => { foreach (var methodName in commandMethodNames) { var methodInfo = commandGroupType.GetMethod(methodName); var found = commandGroup.Commands.Any(q => q.CommandMethodInfo.MethodHandle == methodInfo.MethodHandle); Assert.True(found, $"Command with MethodName {methodName} has not been found in CommandGroup for Type {commandGroupType.Name}"); } }); }
public void DoesNotCreateChoicesIfAnEnumHasTooManyChoices() { var builder = new CommandTreeBuilder(); builder.RegisterModule <TooManyChoiceValues>(); var tree = builder.Build(); _ = tree.CreateApplicationCommands(out var commands); var command = commands !.Single(); if (command.Choices.HasValue) { Assert.Empty(command.Choices.Value !); } }
public void IncludesConfiguredDescriptions() { var builder = new CommandTreeBuilder(); builder.RegisterModule <DescribedGroup>(); var tree = builder.Build(); var root = tree.Root; var group = (GroupNode)root.Children.Single(); var command = (CommandNode)group.Children.Single(); var parameter = command.Shape.Parameters.Single(); Assert.Equal("Group description", group.Description); Assert.Equal("Command description", command.Shape.Description); Assert.Equal("Parameter description", parameter.Description); }
public void CanFindCommandWithDifferentCasing() { var builder = new CommandTreeBuilder(); builder.RegisterModule <GroupWithCasingDifferences>(); var tree = builder.Build(); var options = new TreeSearchOptions(StringComparison.OrdinalIgnoreCase); var result = tree.Search ( "test somecommand", searchOptions: options ); Assert.NotEmpty(result); }
public void CreatesNamedGroupWithDefaultPermissionCorrectly() { var builder = new CommandTreeBuilder(); builder.RegisterModule <NamedGroupWithDefaultPermission>(); var tree = builder.Build(); var result = tree.CreateApplicationCommands(); var commands = result.Entity; ResultAssert.Successful(result); Assert.NotNull(commands); var command = commands !.SingleOrDefault(); Assert.True(command !.DefaultPermission.Value); }
public void CreatesValidTreeCorrectly() { var builder = new CommandTreeBuilder(); builder.RegisterModule <ValidCommandGroup>(); var tree = builder.Build(); var result = tree.CreateApplicationCommands(); var commands = result.Entity; ResultAssert.Successful(result); Assert.NotNull(commands); Assert.Equal(2, commands !.Count); var topLevelCommand = commands.FirstOrDefault(c => c.Name == "top-level-command"); Assert.NotNull(topLevelCommand); var topLevelGroup = commands.FirstOrDefault(c => c.Name == "top-level-group"); Assert.NotNull(topLevelGroup); Assert.True(topLevelGroup !.Options.HasValue); Assert.Equal(2, topLevelGroup.Options.Value.Count); var firstNestedCommand = topLevelGroup.Options.Value.FirstOrDefault(c => c.Type == SubCommand); Assert.NotNull(firstNestedCommand); var nestedGroup = topLevelGroup.Options.Value.FirstOrDefault(c => c.Type == SubCommandGroup); Assert.NotNull(nestedGroup); Assert.True(nestedGroup !.Options.HasValue); Assert.Single(nestedGroup.Options.Value); var secondNestedCommand = nestedGroup.Options.Value.FirstOrDefault(c => c.Type == SubCommand); Assert.NotNull(secondNestedCommand); }
public void ParsesGroupWithVariousReturnTypesCorrectly() { var builder = new CommandTreeBuilder(); builder.RegisterModule <GroupWithVariousReturnTypes>(); var tree = builder.Build(); var root = tree.Root; Assert.Collection ( root.Children, a => Assert.Equal(nameof(a), a.Key), b => Assert.Equal(nameof(b), b.Key), c => Assert.Equal(nameof(c), c.Key), d => Assert.Equal(nameof(d), d.Key), e => Assert.Equal(nameof(e), e.Key), f => Assert.Equal(nameof(f), f.Key) ); }
public void CreatesUngroupedTopLevelCommandsWithDefaultPermissionCorrectly() { var builder = new CommandTreeBuilder(); builder.RegisterModule <MultipleCommandsWithDefaultPermission.GroupOne>(); builder.RegisterModule <MultipleCommandsWithDefaultPermission.GroupTwo>(); var tree = builder.Build(); var result = tree.CreateApplicationCommands(); var commands = result.Entity; ResultAssert.Successful(result); Assert.NotNull(commands); Assert.Equal(2, commands !.Count); var a = commands[0]; var b = commands[1]; Assert.True(a.DefaultPermission.Value); Assert.False(b.DefaultPermission.Value); }
public void ParsesNamedGroupWithCommandsWithNestedNamedGroupWithCommandsCorrectly() { var builder = new CommandTreeBuilder(); builder.RegisterModule <NamedGroupWithCommandsWithNestedNamedGroupWithCommands>(); var tree = builder.Build(); var root = tree.Root; Assert.Single(root.Children); Assert.IsType <GroupNode>(root.Children[0]); var groupNode = (GroupNode)root.Children[0]; Assert.Equal("a", groupNode.Key); var groupType = Assert.Single(groupNode.GroupTypes); Assert.Equal(typeof(NamedGroupWithCommandsWithNestedNamedGroupWithCommands), groupType); Assert.Equal(2, groupNode.Children.Count); Assert.Contains(groupNode.Children, n => n is GroupNode); Assert.Contains(groupNode.Children, n => n is CommandNode); var command1 = (CommandNode)groupNode.Children.First(n => n is CommandNode); Assert.Equal("b", command1.Key); var nestedGroupNode = (GroupNode)groupNode.Children.First(n => n is GroupNode); Assert.Equal("c", nestedGroupNode.Key); Assert.Single(nestedGroupNode.Children); var command2 = (CommandNode)nestedGroupNode.Children[0]; Assert.Equal("d", command2.Key); }
public void FillsArguments(Type commandGroupType, string commandMethodName) { var methodInfo = commandGroupType.GetMethod(commandMethodName); _expectedArgumentsPerCommand.TryGetValue(methodInfo, out var expectedArguments); Assert.NotNull(expectedArguments, $"Test setup not correct. Missing expectedArguments for command of method {commandGroupType.Name}.{commandMethodName}"); var command = new Command() { CommandMethodInfo = methodInfo }; CommandTreeBuilder.FillOptionsAndArguments(command); Assert.Multiple(() => { foreach (var expected in expectedArguments) { var found = command.Arguments.Any( q => q.CommandArgumentAttribute.Name == expected.Name && q.ParameterInfo.ParameterType == expected.ParameterType); Assert.True(found, $"Argument {expected.Name} with parameter type {expected.ParameterType.Name} for command of method {commandGroupType.Name}.{commandMethodName} was not found."); } }); }
public void CreatesTypedOptionsCorrectly() { var builder = new CommandTreeBuilder(); builder.RegisterModule <TypedCommands>(); var tree = builder.Build(); var result = tree.CreateApplicationCommands(); var commands = result.Entity; ResultAssert.Successful(result); Assert.NotNull(commands); void AssertExistsWithType(string commandName, ApplicationCommandOptionType type) { var command = commands !.FirstOrDefault(c => c.Name == commandName); Assert.NotNull(command); var parameter = command !.Options.Value ![0]; Assert.Equal(type, parameter.Type); }
public void ParsesAliasedGroupWithCommandCorrectly() { var builder = new CommandTreeBuilder(); builder.RegisterModule <AliasedGroupWithCommand>(); var tree = builder.Build(); var root = tree.Root; Assert.Single(root.Children); var firstChild = root.Children[0]; Assert.IsType <GroupNode>(firstChild); var group = (GroupNode)firstChild; Assert.Equal("test", group.Key); var groupType = Assert.Single(group.GroupTypes); Assert.Equal(typeof(AliasedGroupWithCommand), groupType); Assert.Collection(group.Aliases, a => Assert.Equal("t", a)); Assert.Single(group.Children); var firstGroupChild = group.Children[0]; Assert.IsType <CommandNode>(firstGroupChild); var command = (CommandNode)firstGroupChild; Assert.Equal("command", command.Key); Assert.Empty(command.Aliases); }
public void CreatesTypedOptionsCorrectly() { var builder = new CommandTreeBuilder(); builder.RegisterModule <TypedCommands>(); var tree = builder.Build(); var result = tree.CreateApplicationCommands(out var commands); ResultAssert.Successful(result); Assert.NotNull(commands); void AssertExistsWithType(string commandName, ApplicationCommandOptionType type) { var command = commands !.FirstOrDefault(c => c.Name == commandName); Assert.NotNull(command); var parameter = command !.Options.Value !.First(); Assert.Equal(type, parameter.Type); } AssertExistsWithType("sbyte-value", Integer); AssertExistsWithType("byte-value", Integer); AssertExistsWithType("short-value", Integer); AssertExistsWithType("ushort-value", Integer); AssertExistsWithType("int-value", Integer); AssertExistsWithType("uint-value", Integer); AssertExistsWithType("long-value", Integer); AssertExistsWithType("ulong-value", Integer); AssertExistsWithType("float-value", String); AssertExistsWithType("double-value", String); AssertExistsWithType("decimal-value", String); AssertExistsWithType("string-value", String); AssertExistsWithType("bool-value", Boolean); AssertExistsWithType("role-value", Role); AssertExistsWithType("user-value", User); AssertExistsWithType("channel-value", Channel); AssertExistsWithType("member-value", User); AssertExistsWithType("enum-value", String); var enumCommand = commands !.First(c => c.Name == "enum-value"); var enumParameter = enumCommand.Options.Value !.First(); Assert.True(enumParameter.Choices.HasValue); var enumChoices = enumParameter.Choices.Value !; Assert.Equal(2, enumChoices.Count); Assert.Collection ( enumChoices, choice => { Assert.Equal(nameof(TestEnum.Value1), choice.Name); Assert.True(choice.Value.IsT0); Assert.Equal(nameof(TestEnum.Value1), choice.Value.AsT0); }, choice => { Assert.Equal(nameof(TestEnum.Value2), choice.Name); Assert.True(choice.Value.IsT0); Assert.Equal(nameof(TestEnum.Value2), choice.Value.AsT0); } ); }
public void Build(ICommandNode node, Command parent = null) { CommandTreeBuilder.Build(this, node, parent); }