Browse Source

wip commit of most test cases working

pull/1318/head
Chris Johnston 6 years ago
parent
commit
729564ffd3
2 changed files with 56 additions and 22 deletions
  1. +44
    -22
      src/Discord.Net.Rest/Entities/Messages/MessageHelper.cs
  2. +12
    -0
      test/Discord.Net.Tests/MessageHelperTests.cs

+ 44
- 22
src/Discord.Net.Rest/Entities/Messages/MessageHelper.cs View File

@@ -3,6 +3,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Linq; using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using Model = Discord.API.Message; using Model = Discord.API.Message;


@@ -101,34 +102,55 @@ namespace Discord.Rest
int index = 0; int index = 0;
int codeBlockIndex = 0; int codeBlockIndex = 0;
int closeIndex; int closeIndex;
bool isBlock = false;

//var codeBlockRegex = new Regex(@"((?!\\)`){3}", RegexOptions.Compiled);
////var codeInlineRegex = new Regex(@"[^\\]`", RegexOptions.Compiled);
//var codeInlineRegex = new Regex(@"((?!\\)`)", RegexOptions.Compiled);

var inlineRegex = new Regex(@"[^\\]?(`).+?[^\\](`)", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
var blockRegex = new Regex(@"[^\\]?(```).+?[^\\](```)", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);


// gets the next index of a codeblock stop/start
int IndexOfCode(int startIndex)
{
if (startIndex == -1)
return -1;
// code block has precedence over inline code
var codeIndex = text.IndexOf("```", startIndex);
if (codeIndex != -1)
return codeIndex + 3;
codeIndex = text.IndexOf('`', startIndex);
if (codeIndex != -1)
return codeIndex + 1;
return -1;
}
// checks if the tag being parsed is wrapped in code blocks // checks if the tag being parsed is wrapped in code blocks
bool CheckWrappedCode() bool CheckWrappedCode()
{ {
closeIndex = 0;
codeBlockIndex = IndexOfCode(codeBlockIndex);
// loop through all code blocks, before the starting index
while (codeBlockIndex != -1 && closeIndex != -1 && closeIndex < index)
// util to check if the index of a tag is within the bounds of the codeblock
bool EnclosedInBlock(Match m)
=> codeBlockIndex + m.Groups[1].Index < index && index < codeBlockIndex + m.Groups[2].Index;

// need to check if the upper bound is beyond the end of the regex
int upperBound = -1;
while (upperBound < index)
{ {
closeIndex = IndexOfCode(codeBlockIndex);
codeBlockIndex = IndexOfCode(closeIndex);
var blockMatch = blockRegex.Match(text, codeBlockIndex);
if (blockMatch.Success)
{
upperBound = blockMatch.Groups[2].Index + codeBlockIndex;
if (upperBound < index)
break;
if (EnclosedInBlock(blockMatch))
{
codeBlockIndex = blockMatch.Groups[2].Index + blockMatch.Groups[2].Length;
return true;
}
return false;
}
var inlineMatch = inlineRegex.Match(text, codeBlockIndex);
if (inlineMatch.Success)
{
upperBound = inlineMatch.Groups[2].Index + codeBlockIndex;
if (upperBound < index)
break;
if (EnclosedInBlock(inlineMatch))
{
codeBlockIndex = inlineMatch.Groups[2].Index + inlineMatch.Groups[2].Length;
return true;
}
return false;
}
return false;
} }
// break if unclosed code block, or code block beyond starting index
return closeIndex == -1 || closeIndex > index;
return false;
} }


while (true) while (true)


+ 12
- 0
test/Discord.Net.Tests/MessageHelperTests.cs View File

@@ -38,6 +38,8 @@ namespace Discord
[InlineData("``` code block 1 ``` ``` code block 2 ``` <@&163184946742034432>")] [InlineData("``` code block 1 ``` ``` code block 2 ``` <@&163184946742034432>")]
[InlineData("` code block 1 ``` ` code block 2 ``` <@&163184946742034432>")] [InlineData("` code block 1 ``` ` code block 2 ``` <@&163184946742034432>")]
[InlineData("<@&163184946742034432> ``` code block 1 ```")] [InlineData("<@&163184946742034432> ``` code block 1 ```")]
[InlineData("``` code ``` ``` code ``` @here ``` code ``` ``` more ```")]
[InlineData("``` code ``` @here ``` more ```")]
public void ParseTagsAroundCode(string testData) public void ParseTagsAroundCode(string testData)
{ {
// don't care that I'm passing in null channels/guilds/users // don't care that I'm passing in null channels/guilds/users
@@ -46,6 +48,16 @@ namespace Discord
Assert.NotEmpty(result); Assert.NotEmpty(result);
} }


[Theory]
[InlineData(@"\` @everyone \`")]
[InlineData(@"\`\`\` @everyone \`\`\`")]
[InlineData(@"hey\`\`\`@everyone\`\`\`!!")]
public void IgnoreEscapedCodeBlocks(string testData)
{
var result = MessageHelper.ParseTags(testData, null, null, null);
Assert.NotEmpty(result);
}

// cannot test parsing a user, as it uses the ReadOnlyCollection<IUser> arg. // cannot test parsing a user, as it uses the ReadOnlyCollection<IUser> arg.
// this could be done if mocked entities are merged in PR #1290 // this could be done if mocked entities are merged in PR #1290




Loading…
Cancel
Save