From c2871ccbf618bb4db9d14bdbfcc8ce63cc844d64 Mon Sep 17 00:00:00 2001 From: BrammyS Date: Sun, 3 May 2026 16:40:42 +0200 Subject: [PATCH 1/3] feat: Support for multi assembly command structures --- .../Builders/ISlashCommandBuildService.cs | 8 +- .../Services/ISlashCommandService.cs | 38 +++++++--- .../Builders/SlashCommandBuildService.cs | 74 ++++++++++--------- .../Implementations/SlashCommandService.cs | 57 ++++++++------ 4 files changed, 106 insertions(+), 71 deletions(-) diff --git a/src/Color-Chan.Discord.Commands/Services/Builders/ISlashCommandBuildService.cs b/src/Color-Chan.Discord.Commands/Services/Builders/ISlashCommandBuildService.cs index b88365f7..0ce25aef 100644 --- a/src/Color-Chan.Discord.Commands/Services/Builders/ISlashCommandBuildService.cs +++ b/src/Color-Chan.Discord.Commands/Services/Builders/ISlashCommandBuildService.cs @@ -12,12 +12,12 @@ namespace Color_Chan.Discord.Commands.Services.Builders; public interface ISlashCommandBuildService { /// - /// Builds all commands in a specific and stores them in a + /// Builds all commands in a specific and stores them in a /// of of , /// . /// - /// - /// The where the will search for commands. + /// + /// The s where the will search for commands. /// /// /// A of of , @@ -25,7 +25,7 @@ public interface ISlashCommandBuildService /// The key contains the command name. /// And the value contains the commands information to execute it. /// - IReadOnlyList> BuildSlashCommandInfos(Assembly assembly); + IReadOnlyList> BuildSlashCommandInfos(params Assembly[] assemblies); /// /// Get all the interaction command modules. diff --git a/src/Color-Chan.Discord.Commands/Services/ISlashCommandService.cs b/src/Color-Chan.Discord.Commands/Services/ISlashCommandService.cs index 8fee67f4..679cacaf 100644 --- a/src/Color-Chan.Discord.Commands/Services/ISlashCommandService.cs +++ b/src/Color-Chan.Discord.Commands/Services/ISlashCommandService.cs @@ -18,10 +18,10 @@ public interface ISlashCommandService /// /// Add all interaction commands in an to the . /// - /// The where the commands are located. + /// The s where the commands are located. /// /// - Task AddInteractionCommandsAsync(Assembly assembly); + Task AddInteractionCommandsAsync(params Assembly[] assemblies); /// /// Execute a specific command with their dependencies. @@ -41,9 +41,14 @@ public interface ISlashCommandService /// /// /// - Task> ExecuteSlashCommandAsync(MethodInfo commandMethod, IEnumerable? options, - IEnumerable? requirements, ISlashCommandContext context, - List? suppliedOptions = null, IServiceProvider? serviceProvider = null); + Task> ExecuteSlashCommandAsync( + MethodInfo commandMethod, + IEnumerable? options, + IEnumerable? requirements, + ISlashCommandContext context, + List? suppliedOptions = null, + IServiceProvider? serviceProvider = null + ); /// /// Execute a specific command with their dependencies. @@ -61,8 +66,12 @@ Task> ExecuteSlashCommandAsync(MethodInfo co /// /// /// - Task> ExecuteSlashCommandAsync(ISlashCommandInfo commandInfo, ISlashCommandContext context, List? suppliedOptions = null, - IServiceProvider? serviceProvider = null); + Task> ExecuteSlashCommandAsync( + ISlashCommandInfo commandInfo, + ISlashCommandContext context, + List? suppliedOptions = null, + IServiceProvider? serviceProvider = null + ); /// /// Execute a specific command with their dependencies. @@ -80,8 +89,12 @@ Task> ExecuteSlashCommandAsync(ISlashCommand /// /// /// - Task> ExecuteSlashCommandAsync(ISlashCommandOptionInfo commandOptionInfo, ISlashCommandContext context, - List? suppliedOptions = null, IServiceProvider? serviceProvider = null); + Task> ExecuteSlashCommandAsync( + ISlashCommandOptionInfo commandOptionInfo, + ISlashCommandContext context, + List? suppliedOptions = null, + IServiceProvider? serviceProvider = null + ); /// /// Execute a specific command with their dependencies. @@ -98,8 +111,11 @@ Task> ExecuteSlashCommandAsync(ISlashCommand /// /// /// - Task> ExecuteSlashCommandAsync(ISlashCommandContext context, IEnumerable? options = null, - IServiceProvider? serviceProvider = null); + Task> ExecuteSlashCommandAsync( + ISlashCommandContext context, + IEnumerable? options = null, + IServiceProvider? serviceProvider = null + ); /// /// Search for a command by its . diff --git a/src/Color-Chan.Discord.Commands/Services/Implementations/Builders/SlashCommandBuildService.cs b/src/Color-Chan.Discord.Commands/Services/Implementations/Builders/SlashCommandBuildService.cs index 937ebf1c..c1b88213 100644 --- a/src/Color-Chan.Discord.Commands/Services/Implementations/Builders/SlashCommandBuildService.cs +++ b/src/Color-Chan.Discord.Commands/Services/Implementations/Builders/SlashCommandBuildService.cs @@ -41,8 +41,11 @@ public class SlashCommandBuildService : ISlashCommandBuildService /// The that will get and build the /// s. /// - public SlashCommandBuildService(ISlashCommandRequirementBuildService requirementBuildService, ISlashCommandGuildBuildService guildBuildService, ILogger logger, - ISlashCommandOptionBuildService optionBuildService) + public SlashCommandBuildService( + ISlashCommandRequirementBuildService requirementBuildService, + ISlashCommandGuildBuildService guildBuildService, + ILogger logger, + ISlashCommandOptionBuildService optionBuildService) { _requirementBuildService = requirementBuildService; _guildBuildService = guildBuildService; @@ -51,40 +54,45 @@ public SlashCommandBuildService(ISlashCommandRequirementBuildService requirement } /// - public IReadOnlyList> BuildSlashCommandInfos(Assembly assembly) + public IReadOnlyList> BuildSlashCommandInfos(params Assembly[] assemblies) { - _logger.LogInformation("Loading interaction commands for assembly {AssemblyName}", assembly.FullName); var validCommands = new List>(); - foreach (var parentModule in GetSlashCommandModules(assembly)) + foreach (var assembly in assemblies) { - if (IsValidCommandGroupModuleDefinition(parentModule)) + _logger.LogInformation("Loading interaction commands for assembly {AssemblyName}", assembly.FullName); + + foreach (var parentModule in GetSlashCommandModules(assembly)) { - var groupAttribute = parentModule.GetCustomAttribute(); - if (groupAttribute is null) + if (IsValidCommandGroupModuleDefinition(parentModule)) { - _logger.LogWarning("Can not load command group {ModuleName} since it doesn't have the SlashCommandGroupAttribute attribute", parentModule.Name); - continue; + var groupAttribute = parentModule.GetCustomAttribute(); + if (groupAttribute is null) + { + _logger.LogWarning("Can not load command group {ModuleName} since it doesn't have the SlashCommandGroupAttribute attribute", parentModule.Name); + continue; + } + + var commandInfoKeyValuePair = BuildCommandGroupInfoKeyValuePair(groupAttribute, parentModule); + validCommands.Add(commandInfoKeyValuePair); + _logger.LogDebug("Found valid command in command module {TopLevelCommandName}", commandInfoKeyValuePair.Key); } - var commandInfoKeyValuePair = BuildCommandGroupInfoKeyValuePair(groupAttribute, parentModule); - validCommands.Add(commandInfoKeyValuePair); - _logger.LogDebug("Found valid command in command module {TopLevelCommandName}", commandInfoKeyValuePair.Key); - } - - // The command is not a sub command / group. + // The command is not a sub command / group. - foreach (var validMethod in GetValidSlashCommandsMethods(parentModule)) - { - var commandInfoKeyValuePair = BuildCommandInfoKeyValuePair(validMethod, parentModule); + foreach (var validMethod in GetValidSlashCommandsMethods(parentModule)) + { + var commandInfoKeyValuePair = BuildCommandInfoKeyValuePair(validMethod, parentModule); - if (!commandInfoKeyValuePair.HasValue) continue; - validCommands.Add(commandInfoKeyValuePair.Value); - _logger.LogDebug("Found valid command in command module {TopLevelCommandName}", commandInfoKeyValuePair.Value.Key); + if (!commandInfoKeyValuePair.HasValue) continue; + validCommands.Add(commandInfoKeyValuePair.Value); + _logger.LogDebug("Found valid command in command module {TopLevelCommandName}", commandInfoKeyValuePair.Value.Key); + } } + + _logger.LogDebug("Found {CommandCount} valid commands in assembly {AssemblyName}", validCommands.Count.ToString(), assembly.FullName); } - _logger.LogDebug("Found {CommandCount} valid commands in assembly {AssemblyName}", validCommands.Count.ToString(), assembly.FullName); return validCommands; } @@ -183,12 +191,12 @@ private KeyValuePair BuildCommandGroupInfoKeyValuePai var commandRequirements = _requirementBuildService.GetCommandRequirements(rawValidCommand); var options = _optionBuildService.GetCommandOptions(rawValidCommand); var subCommand = new SlashCommandOptionInfo(subCommandAttribute.Name, - subCommandAttribute.Description, - subCommandAttribute.Acknowledge, - rawValidCommand, - parentModule, - commandRequirements, - options.ToList()); + subCommandAttribute.Description, + subCommandAttribute.Acknowledge, + rawValidCommand, + parentModule, + commandRequirements, + options.ToList()); // Check if the command doesn't belong to a sub command group. if (subCommandGroupAttribute is null) @@ -235,8 +243,8 @@ private IEnumerable GetValidSlashCommandsMethods(Type parentModule) if (IsValidCommandGroupModuleDefinition(parentModule)) return new List(); return parentModule - .GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) - .Where(IsValidCommandDefinition); + .GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) + .Where(IsValidCommandDefinition); } /// @@ -251,8 +259,8 @@ private IEnumerable GetValidSubSlashCommandsMethods(Type parentModul if (!IsValidCommandGroupModuleDefinition(parentModule)) return new List(); return parentModule - .GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) - .Where(IsValidCommandDefinition); + .GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) + .Where(IsValidCommandDefinition); } /// diff --git a/src/Color-Chan.Discord.Commands/Services/Implementations/SlashCommandService.cs b/src/Color-Chan.Discord.Commands/Services/Implementations/SlashCommandService.cs index f1935981..05b0a213 100644 --- a/src/Color-Chan.Discord.Commands/Services/Implementations/SlashCommandService.cs +++ b/src/Color-Chan.Discord.Commands/Services/Implementations/SlashCommandService.cs @@ -42,8 +42,11 @@ public class SlashCommandService : ISlashCommandService /// The that handles all the syncing of /// the slash commands. /// - public SlashCommandService(ILogger logger, ISlashCommandBuildService slashCommandBuildService, - ISlashCommandRequirementService requirementService, ISlashCommandAutoSyncService commandAutoSyncService) + public SlashCommandService( + ILogger logger, + ISlashCommandBuildService slashCommandBuildService, + ISlashCommandRequirementService requirementService, + ISlashCommandAutoSyncService commandAutoSyncService) { _logger = logger; _slashCommandBuildService = slashCommandBuildService; @@ -52,12 +55,12 @@ public SlashCommandService(ILogger logger, ISlashCommandBui } /// - public async Task AddInteractionCommandsAsync(Assembly assembly) + public async Task AddInteractionCommandsAsync(params Assembly[] assemblies) { _logger.LogDebug("Registering slash commands..."); // Build all commands in a specific assembly. - var commandInfos = _slashCommandBuildService.BuildSlashCommandInfos(assembly); + var commandInfos = _slashCommandBuildService.BuildSlashCommandInfos(assemblies); foreach (var (key, commandInfo) in commandInfos) { if (_slashCommands.TryAdd(key, commandInfo)) continue; @@ -70,18 +73,18 @@ public async Task AddInteractionCommandsAsync(Assembly assembly) _logger.LogInformation("Registered {Count} slash commands to the command registry", _slashCommands.Count.ToString()); - var result = await _commandAutoSyncService.UpdateApplicationCommandsAsync(commandInfos.Select(x => x.Value)).ConfigureAwait(false); - + var result = await _commandAutoSyncService.UpdateApplicationCommandsAsync(_slashCommands.Select(x => x.Value)).ConfigureAwait(false); if (!result.IsSuccessful) throw new UpdateSlashCommandException(result.ErrorResult?.ErrorMessage ?? "Failed to sync the slash command to discord."); } /// - public async Task> ExecuteSlashCommandAsync(MethodInfo commandMethod, - IEnumerable? options, - IEnumerable? requirements, - ISlashCommandContext context, - List? suppliedOptions = null, - IServiceProvider? serviceProvider = null) + public async Task> ExecuteSlashCommandAsync( + MethodInfo commandMethod, + IEnumerable? options, + IEnumerable? requirements, + ISlashCommandContext context, + List? suppliedOptions = null, + IServiceProvider? serviceProvider = null) { serviceProvider ??= DefaultServiceProvider.Instance; @@ -140,8 +143,11 @@ public async Task> ExecuteSlashCommandAsync( } /// - public async Task> ExecuteSlashCommandAsync(ISlashCommandInfo commandInfo, ISlashCommandContext context, - List? suppliedOptions = null, IServiceProvider? serviceProvider = null) + public async Task> ExecuteSlashCommandAsync( + ISlashCommandInfo commandInfo, + ISlashCommandContext context, + List? suppliedOptions = null, + IServiceProvider? serviceProvider = null) { if (commandInfo.CommandMethod is not null) { @@ -153,17 +159,20 @@ public async Task> ExecuteSlashCommandAsync( } /// - public async Task> ExecuteSlashCommandAsync(ISlashCommandOptionInfo commandOptionInfo, ISlashCommandContext context, - List? suppliedOptions = null, IServiceProvider? serviceProvider = null) + public async Task> ExecuteSlashCommandAsync( + ISlashCommandOptionInfo commandOptionInfo, + ISlashCommandContext context, + List? suppliedOptions = null, + IServiceProvider? serviceProvider = null) { if (commandOptionInfo.CommandMethod is not null) { return await ExecuteSlashCommandAsync(commandOptionInfo.CommandMethod, - commandOptionInfo.CommandOptions, - commandOptionInfo.Requirements, - context, - suppliedOptions, - serviceProvider).ConfigureAwait(false); + commandOptionInfo.CommandOptions, + commandOptionInfo.Requirements, + context, + suppliedOptions, + serviceProvider).ConfigureAwait(false); } _logger.LogWarning("Interaction: {Id} : Failed to executed {Name} since it was a command group or a sub command group", context.InteractionId, commandOptionInfo.Name); @@ -171,8 +180,10 @@ public async Task> ExecuteSlashCommandAsync( } /// - public async Task> ExecuteSlashCommandAsync(ISlashCommandContext context, IEnumerable? options = null, - IServiceProvider? serviceProvider = null) + public async Task> ExecuteSlashCommandAsync( + ISlashCommandContext context, + IEnumerable? options = null, + IServiceProvider? serviceProvider = null) { var arr = context.SlashCommandName.ToArray(); var count = arr.Length; From 4aa4253f29d79d7ebd76c8c63759124d30746f6b Mon Sep 17 00:00:00 2001 From: BrammyS Date: Sun, 3 May 2026 17:00:10 +0200 Subject: [PATCH 2/3] fix: correct docs --- .../Services/Builders/ISlashCommandBuildService.cs | 2 +- .../Services/ISlashCommandService.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Color-Chan.Discord.Commands/Services/Builders/ISlashCommandBuildService.cs b/src/Color-Chan.Discord.Commands/Services/Builders/ISlashCommandBuildService.cs index 0ce25aef..ec554b67 100644 --- a/src/Color-Chan.Discord.Commands/Services/Builders/ISlashCommandBuildService.cs +++ b/src/Color-Chan.Discord.Commands/Services/Builders/ISlashCommandBuildService.cs @@ -12,7 +12,7 @@ namespace Color_Chan.Discord.Commands.Services.Builders; public interface ISlashCommandBuildService { /// - /// Builds all commands in a specific and stores them in a + /// Builds all commands in specific and stores them in a /// of of , /// . /// diff --git a/src/Color-Chan.Discord.Commands/Services/ISlashCommandService.cs b/src/Color-Chan.Discord.Commands/Services/ISlashCommandService.cs index 679cacaf..54777463 100644 --- a/src/Color-Chan.Discord.Commands/Services/ISlashCommandService.cs +++ b/src/Color-Chan.Discord.Commands/Services/ISlashCommandService.cs @@ -16,7 +16,7 @@ namespace Color_Chan.Discord.Commands.Services; public interface ISlashCommandService { /// - /// Add all interaction commands in an to the . + /// Add all interaction commands in s to the . /// /// The s where the commands are located. /// From f1a68ac6aad5017f1236794c5064288ad7817a54 Mon Sep 17 00:00:00 2001 From: BrammyS Date: Sun, 3 May 2026 17:00:32 +0200 Subject: [PATCH 3/3] feat: more unit tests to validate multi assembly commands registrations --- Color-Chan.Discord.sln | 7 ++++++ .../Color-Chan.Discord.Commands.Tests.csproj | 1 + .../Builders/SlashCommandBuildServiceTests.cs | 25 ++++++++++++++++--- ...-Chan.Discord.Commands.Tests.Valid2.csproj | 14 +++++++++++ .../ValidMockCommandModule0.cs | 15 +++++++++++ 5 files changed, 59 insertions(+), 3 deletions(-) create mode 100644 tests/mockCommandAssemblies/Color-Chan.Discord.Commands.Tests.Valid2/Color-Chan.Discord.Commands.Tests.Valid2.csproj create mode 100644 tests/mockCommandAssemblies/Color-Chan.Discord.Commands.Tests.Valid2/ValidMockCommandModule0.cs diff --git a/Color-Chan.Discord.sln b/Color-Chan.Discord.sln index 4c8b5cf5..e2699ffa 100644 --- a/Color-Chan.Discord.sln +++ b/Color-Chan.Discord.sln @@ -54,6 +54,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ButtonArgs", "samples\Butto EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ComponentsV2", "samples\ComponentsV2\ComponentsV2.csproj", "{3D545B51-0245-43BF-9588-2C299B7DD9A5}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Color-Chan.Discord.Commands.Tests.Valid2", "tests\mockCommandAssemblies\Color-Chan.Discord.Commands.Tests.Valid2\Color-Chan.Discord.Commands.Tests.Valid2.csproj", "{A19857F5-7AC6-4CAE-BAB4-7CE371F96300}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -136,6 +138,10 @@ Global {3D545B51-0245-43BF-9588-2C299B7DD9A5}.Debug|Any CPU.Build.0 = Debug|Any CPU {3D545B51-0245-43BF-9588-2C299B7DD9A5}.Release|Any CPU.ActiveCfg = Release|Any CPU {3D545B51-0245-43BF-9588-2C299B7DD9A5}.Release|Any CPU.Build.0 = Release|Any CPU + {A19857F5-7AC6-4CAE-BAB4-7CE371F96300}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A19857F5-7AC6-4CAE-BAB4-7CE371F96300}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A19857F5-7AC6-4CAE-BAB4-7CE371F96300}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A19857F5-7AC6-4CAE-BAB4-7CE371F96300}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -162,6 +168,7 @@ Global {4D344610-2AD1-44D1-A3FE-76908972AA9B} = {B2D862F3-8ED1-4D09-8248-8D4B5EB2737A} {7F0D86B2-209D-4C6A-BB68-489C59756FC2} = {B2D862F3-8ED1-4D09-8248-8D4B5EB2737A} {3D545B51-0245-43BF-9588-2C299B7DD9A5} = {B2D862F3-8ED1-4D09-8248-8D4B5EB2737A} + {A19857F5-7AC6-4CAE-BAB4-7CE371F96300} = {ADBC5773-D0F4-4A9E-BC6F-6EF9220718A4} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {AC84D902-ABC1-47C3-9993-F769F483E5CE} diff --git a/tests/Color-Chan.Discord.Commands.Tests/Color-Chan.Discord.Commands.Tests.csproj b/tests/Color-Chan.Discord.Commands.Tests/Color-Chan.Discord.Commands.Tests.csproj index bea85111..1285968f 100644 --- a/tests/Color-Chan.Discord.Commands.Tests/Color-Chan.Discord.Commands.Tests.csproj +++ b/tests/Color-Chan.Discord.Commands.Tests/Color-Chan.Discord.Commands.Tests.csproj @@ -19,6 +19,7 @@ + diff --git a/tests/Color-Chan.Discord.Commands.Tests/Services/Implementations/Builders/SlashCommandBuildServiceTests.cs b/tests/Color-Chan.Discord.Commands.Tests/Services/Implementations/Builders/SlashCommandBuildServiceTests.cs index 0834e110..1b047826 100644 --- a/tests/Color-Chan.Discord.Commands.Tests/Services/Implementations/Builders/SlashCommandBuildServiceTests.cs +++ b/tests/Color-Chan.Discord.Commands.Tests/Services/Implementations/Builders/SlashCommandBuildServiceTests.cs @@ -4,6 +4,7 @@ using Color_Chan.Discord.Commands.Services.Implementations.Builders; using Color_Chan.Discord.Commands.Tests.Invalid; using Color_Chan.Discord.Commands.Tests.Valid; +using Color_Chan.Discord.Commands.Tests.Valid2; using FluentAssertions; using Microsoft.Extensions.Logging; using Moq; @@ -14,7 +15,8 @@ namespace Color_Chan.Discord.Commands.Tests.Services.Implementations.Builders; [TestFixture] public class SlashCommandBuildServiceTests { - private static readonly Assembly ValidAssembly = typeof(ValidMockCommandModule1).Assembly; + private static readonly Assembly ValidAssembly1 = typeof(ValidMockCommandModule1).Assembly; + private static readonly Assembly ValidAssembly2 = typeof(ValidMockCommandModule0).Assembly; private static readonly Assembly InValidAssembly = typeof(InValidMockCommandModule1).Assembly; [Test] @@ -28,11 +30,28 @@ public void Should_get_interaction_command_modules() var buildService = new SlashCommandBuildService(requirementBuilderMock.Object, guildBuilderMock.Object, loggerMock.Object, optionBuilderMock.Object); // Act - var types = buildService.GetSlashCommandModules(ValidAssembly); + var types = buildService.GetSlashCommandModules(ValidAssembly1); // Assert types.Count().Should().Be(8); } + + [Test] + public void Should_get_interaction_commands_with_multiple_assemblies() + { + // Arrange + var loggerMock = new Mock>(); + var requirementBuilderMock = new Mock(); + var guildBuilderMock = new Mock(); + var optionBuilderMock = new Mock(); + var buildService = new SlashCommandBuildService(requirementBuilderMock.Object, guildBuilderMock.Object, loggerMock.Object, optionBuilderMock.Object); + + // Act + var commands = buildService.BuildSlashCommandInfos(ValidAssembly1, ValidAssembly2); + + // Assert + commands.Count.Should().Be(21); + } [Test] public void Should_get_interaction_commands() @@ -45,7 +64,7 @@ public void Should_get_interaction_commands() var buildService = new SlashCommandBuildService(requirementBuilderMock.Object, guildBuilderMock.Object, loggerMock.Object, optionBuilderMock.Object); // Act - var commands = buildService.BuildSlashCommandInfos(ValidAssembly); + var commands = buildService.BuildSlashCommandInfos(ValidAssembly1); // Assert commands.Count.Should().Be(20); diff --git a/tests/mockCommandAssemblies/Color-Chan.Discord.Commands.Tests.Valid2/Color-Chan.Discord.Commands.Tests.Valid2.csproj b/tests/mockCommandAssemblies/Color-Chan.Discord.Commands.Tests.Valid2/Color-Chan.Discord.Commands.Tests.Valid2.csproj new file mode 100644 index 00000000..928ccbfb --- /dev/null +++ b/tests/mockCommandAssemblies/Color-Chan.Discord.Commands.Tests.Valid2/Color-Chan.Discord.Commands.Tests.Valid2.csproj @@ -0,0 +1,14 @@ + + + + net10.0 + Color_Chan.Discord.Commands.Tests.Valid2 + enable + enable + + + + + + + diff --git a/tests/mockCommandAssemblies/Color-Chan.Discord.Commands.Tests.Valid2/ValidMockCommandModule0.cs b/tests/mockCommandAssemblies/Color-Chan.Discord.Commands.Tests.Valid2/ValidMockCommandModule0.cs new file mode 100644 index 00000000..cb344b89 --- /dev/null +++ b/tests/mockCommandAssemblies/Color-Chan.Discord.Commands.Tests.Valid2/ValidMockCommandModule0.cs @@ -0,0 +1,15 @@ +using Color_Chan.Discord.Commands.Attributes; +using Color_Chan.Discord.Commands.Modules; +using Color_Chan.Discord.Core.Common.Models.Interaction; +using Color_Chan.Discord.Core.Results; + +namespace Color_Chan.Discord.Commands.Tests.Valid2; + +public class ValidMockCommandModule0 : SlashCommandModule +{ + [SlashCommand("AGoodCommand", "a unit test command.")] + public Task> AGoodCommand() + { + throw new Exception(); + } +} \ No newline at end of file