@@ -106,13 +106,17 @@ namespace Discord | |||||
get => _nameLocalizations; | get => _nameLocalizations; | ||||
set | set | ||||
{ | { | ||||
foreach (var (locale, name) in value) | |||||
if (value != null) | |||||
{ | { | ||||
if(!Regex.IsMatch(locale, @"^\w{2}(?:-\w{2})?$")) | |||||
throw new ArgumentException($"Invalid locale: {locale}", nameof(locale)); | |||||
foreach (var (locale, name) in value) | |||||
{ | |||||
if(!Regex.IsMatch(locale, @"^\w{2}(?:-\w{2})?$")) | |||||
throw new ArgumentException($"Invalid locale: {locale}", nameof(locale)); | |||||
EnsureValidOptionName(name); | |||||
EnsureValidOptionName(name); | |||||
} | |||||
} | } | ||||
_nameLocalizations = value; | _nameLocalizations = value; | ||||
} | } | ||||
} | } | ||||
@@ -126,13 +130,17 @@ namespace Discord | |||||
get => _descriptionLocalizations; | get => _descriptionLocalizations; | ||||
set | set | ||||
{ | { | ||||
foreach (var (locale, description) in value) | |||||
if (value != null) | |||||
{ | { | ||||
if(!Regex.IsMatch(locale, @"^\w{2}(?:-\w{2})?$")) | |||||
throw new ArgumentException($"Invalid locale: {locale}", nameof(locale)); | |||||
foreach (var (locale, description) in value) | |||||
{ | |||||
if(!Regex.IsMatch(locale, @"^\w{2}(?:-\w{2})?$")) | |||||
throw new ArgumentException($"Invalid locale: {locale}", nameof(locale)); | |||||
EnsureValidOptionDescription(description); | |||||
EnsureValidOptionDescription(description); | |||||
} | |||||
} | } | ||||
_descriptionLocalizations = value; | _descriptionLocalizations = value; | ||||
} | } | ||||
} | } | ||||
@@ -55,18 +55,21 @@ namespace Discord | |||||
get => _nameLocalizations; | get => _nameLocalizations; | ||||
set | set | ||||
{ | { | ||||
foreach (var (locale, name) in value) | |||||
if (value != null) | |||||
{ | { | ||||
if (!Regex.IsMatch(locale, @"^\w{2}(?:-\w{2})?$")) | |||||
throw new ArgumentException("Key values of the dictionary must be valid language codes."); | |||||
switch (name.Length) | |||||
foreach (var (locale, name) in value) | |||||
{ | { | ||||
case > 100: | |||||
throw new ArgumentOutOfRangeException(nameof(value), | |||||
"Name length must be less than or equal to 100."); | |||||
case 0: | |||||
throw new ArgumentOutOfRangeException(nameof(value), "Name length must at least 1."); | |||||
if (!Regex.IsMatch(locale, @"^\w{2}(?:-\w{2})?$")) | |||||
throw new ArgumentException("Key values of the dictionary must be valid language codes."); | |||||
switch (name.Length) | |||||
{ | |||||
case > 100: | |||||
throw new ArgumentOutOfRangeException(nameof(value), | |||||
"Name length must be less than or equal to 100."); | |||||
case 0: | |||||
throw new ArgumentOutOfRangeException(nameof(value), "Name length must at least 1."); | |||||
} | |||||
} | } | ||||
} | } | ||||
@@ -35,17 +35,21 @@ namespace Discord | |||||
get => _nameLocalizations; | get => _nameLocalizations; | ||||
set | set | ||||
{ | { | ||||
foreach (var (locale, name) in value) | |||||
if (value != null) | |||||
{ | { | ||||
if(!Regex.IsMatch(locale, @"^\w{2}(?:-\w{2})?$")) | |||||
throw new ArgumentException($"Invalid locale: {locale}", nameof(locale)); | |||||
foreach (var (locale, name) in value) | |||||
{ | |||||
if (!Regex.IsMatch(locale, @"^\w{2}(?:-\w{2})?$")) | |||||
throw new ArgumentException($"Invalid locale: {locale}", nameof(locale)); | |||||
Preconditions.AtLeast(name.Length, 1, nameof(name)); | |||||
Preconditions.AtMost(name.Length, SlashCommandBuilder.MaxNameLength, nameof(name)); | |||||
Preconditions.AtLeast(name.Length, 1, nameof(name)); | |||||
Preconditions.AtMost(name.Length, SlashCommandBuilder.MaxNameLength, nameof(name)); | |||||
if (Type == ApplicationCommandType.Slash && !Regex.IsMatch(name, @"^[-_\p{L}\p{N}\p{IsDevanagari}\p{IsThai}]{1,32}$")) | |||||
throw new ArgumentException(@"Name must match the regex ^[-_\p{L}\p{N}\p{IsDevanagari}\p{IsThai}]{1,32}$", nameof(name)); | |||||
if (Type == ApplicationCommandType.Slash && !Regex.IsMatch(name, @"^[-_\p{L}\p{N}\p{IsDevanagari}\p{IsThai}]{1,32}$")) | |||||
throw new ArgumentException(@"Name must match the regex ^[-_\p{L}\p{N}\p{IsDevanagari}\p{IsThai}]{1,32}$", nameof(name)); | |||||
} | |||||
} | } | ||||
_nameLocalizations = value; | _nameLocalizations = value; | ||||
} | } | ||||
} | } | ||||
@@ -58,14 +62,18 @@ namespace Discord | |||||
get => _descriptionLocalizations; | get => _descriptionLocalizations; | ||||
set | set | ||||
{ | { | ||||
foreach (var (locale, description) in value) | |||||
if (value != null) | |||||
{ | { | ||||
if(!Regex.IsMatch(locale, @"^\w{2}(?:-\w{2})?$")) | |||||
throw new ArgumentException($"Invalid locale: {locale}", nameof(locale)); | |||||
foreach (var (locale, description) in value) | |||||
{ | |||||
if (!Regex.IsMatch(locale, @"^\w{2}(?:-\w{2})?$")) | |||||
throw new ArgumentException($"Invalid locale: {locale}", nameof(locale)); | |||||
Preconditions.AtLeast(description.Length, 1, nameof(description)); | |||||
Preconditions.AtMost(description.Length, SlashCommandBuilder.MaxDescriptionLength, nameof(description)); | |||||
Preconditions.AtLeast(description.Length, 1, nameof(description)); | |||||
Preconditions.AtMost(description.Length, SlashCommandBuilder.MaxDescriptionLength, nameof(description)); | |||||
} | |||||
} | } | ||||
_descriptionLocalizations = value; | _descriptionLocalizations = value; | ||||
} | } | ||||
} | } | ||||
@@ -907,7 +907,7 @@ namespace Discord | |||||
if (descriptionLocalizations is null) | if (descriptionLocalizations is null) | ||||
throw new ArgumentNullException(nameof(descriptionLocalizations)); | throw new ArgumentNullException(nameof(descriptionLocalizations)); | ||||
foreach (var (locale, description) in _descriptionLocalizations) | |||||
foreach (var (locale, description) in descriptionLocalizations) | |||||
{ | { | ||||
if(!Regex.IsMatch(locale, @"^\w{2}(?:-\w{2})?$")) | if(!Regex.IsMatch(locale, @"^\w{2}(?:-\w{2})?$")) | ||||
throw new ArgumentException($"Invalid locale: {locale}", nameof(locale)); | throw new ArgumentException($"Invalid locale: {locale}", nameof(locale)); | ||||
@@ -0,0 +1,37 @@ | |||||
using System; | |||||
using Discord; | |||||
using Xunit; | |||||
namespace Discord; | |||||
public class CommandBuilderTests | |||||
{ | |||||
[Fact] | |||||
public void BuildSimpleSlashCommand() | |||||
{ | |||||
var command = new SlashCommandBuilder() | |||||
.WithName("command") | |||||
.WithDescription("description") | |||||
.AddOption( | |||||
"option1", | |||||
ApplicationCommandOptionType.String, | |||||
"option1 description", | |||||
isRequired: true, | |||||
choices: new [] | |||||
{ | |||||
new ApplicationCommandOptionChoiceProperties() | |||||
{ | |||||
Name = "choice1", Value = "1" | |||||
} | |||||
}) | |||||
.AddOptions(new SlashCommandOptionBuilder() | |||||
.WithName("option2") | |||||
.WithDescription("option2 description") | |||||
.WithType(ApplicationCommandOptionType.String) | |||||
.WithRequired(true) | |||||
.AddChannelType(ChannelType.Text) | |||||
.AddChoice("choice1", "1") | |||||
.AddChoice("choice2", "2")); | |||||
command.Build(); | |||||
} | |||||
} |