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);
                }
Beispiel #5
0
                public void ReturnsUnsuccessfulIfThereAreTooManyRootLevelCommands()
                {
                    var builder = new CommandTreeBuilder();

                    builder.RegisterModule <TooManyCommands>();

                    var tree = builder.Build();

                    var result = tree.CreateApplicationCommands();

                    ResultAssert.Unsuccessful(result);
                }
Beispiel #6
0
                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);
                }
Beispiel #8
0
                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);
            }
Beispiel #10
0
                public void ReturnsUnsuccessfulIfACommandContainsASwitchParameter()
                {
                    var builder = new CommandTreeBuilder();

                    builder.RegisterModule <SwitchesAreNotSupported>();

                    var tree = builder.Build();

                    var result = tree.CreateApplicationCommands(out _);

                    ResultAssert.Unsuccessful(result);
                }
Beispiel #11
0
                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);
            }
Beispiel #13
0
                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);
                }
Beispiel #14
0
                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);
                }
Beispiel #15
0
                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);
                }
Beispiel #16
0
        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}");
                    }
                });
            }
Beispiel #18
0
                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 !);
                    }
                }
Beispiel #19
0
        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);
        }
Beispiel #20
0
                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);
                }
Beispiel #21
0
                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);
                }
Beispiel #22
0
                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);
                }
Beispiel #23
0
        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)
            );
        }
Beispiel #24
0
                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);
                }
Beispiel #25
0
        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);
                    }
Beispiel #28
0
        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);
        }
Beispiel #29
0
                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);
                    }
                    );
                }
Beispiel #30
0
 public void Build(ICommandNode node, Command parent = null)
 {
     CommandTreeBuilder.Build(this, node, parent);
 }