-
Notifications
You must be signed in to change notification settings - Fork 272
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Backport some improvements from branch 'kick-support' (#915)
* Create ReadOnlySpanTryReplaceNonEscapedTests.DoesNotSupportReplacingEscapeChars * Only target net6.0 for TwitchDownloaderCore.Tests * Improve performance of TimeSpanHFormat and return TimeSpan.ToString when format is null or empty * Update ReadOnlySpanExtensions * Use non-memory overload to prevent internal reallocation * Consolidate ChatCompression, ChatFormat, and TimestampFormat into Enums.cs * Relax IO access restrictions * Backport M3U8 parser and ReadOnlySpanExtensions: Count, UnEscapedIndexOf, and UnEscapedIndexOfAny & related tests * Implement M3U8 parser
- Loading branch information
Showing
25 changed files
with
1,644 additions
and
234 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
using TwitchDownloaderCore.Extensions; | ||
|
||
namespace TwitchDownloaderCore.Tests | ||
{ | ||
public class ReadOnlySpanCountTests | ||
{ | ||
[Fact] | ||
public void ReturnsNegativeOneWhenNotPresent() | ||
{ | ||
ReadOnlySpan<char> str = "SORRY FOR THE TRAFFIC NaM"; | ||
const int EXPECTED = -1; | ||
|
||
var actual = str.Count('L'); | ||
|
||
Assert.Equal(EXPECTED, actual); | ||
} | ||
|
||
[Fact] | ||
public void ReturnsNegativeOneForEmptyString() | ||
{ | ||
ReadOnlySpan<char> str = ""; | ||
const int EXPECTED = -1; | ||
|
||
var actual = str.Count('L'); | ||
|
||
Assert.Equal(EXPECTED, actual); | ||
} | ||
|
||
[Theory] | ||
[InlineData('S', 1)] | ||
[InlineData('R', 4)] | ||
[InlineData('a', 1)] | ||
[InlineData('F', 3)] | ||
[InlineData('M', 1)] | ||
public void ReturnsCorrectCharacterCount(char character, int expectedCount) | ||
{ | ||
ReadOnlySpan<char> str = "SORRY FOR THE TRAFFIC NaM"; | ||
|
||
var actual = str.Count(character); | ||
|
||
Assert.Equal(expectedCount, actual); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
115 changes: 115 additions & 0 deletions
115
TwitchDownloaderCore.Tests/ReadOnlySpanUnEscapedIndexOfAnyTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
using TwitchDownloaderCore.Extensions; | ||
|
||
namespace TwitchDownloaderCore.Tests | ||
{ | ||
public class ReadOnlySpanUnEscapedIndexOfAnyTests | ||
{ | ||
[Fact] | ||
public void CorrectlyFindsNextIndexWithoutEscapes() | ||
{ | ||
ReadOnlySpan<char> str = "SORRY FOR TRAFFIC NaM"; | ||
const string CHARS_TO_FIND = "abc"; | ||
const int CHAR_INDEX = 19; | ||
|
||
var actual = str.UnEscapedIndexOfAny(CHARS_TO_FIND); | ||
|
||
Assert.Equal(CHAR_INDEX, actual); | ||
} | ||
|
||
[Fact] | ||
public void DoesNotFindAnIndexWhenNotPresent() | ||
{ | ||
ReadOnlySpan<char> str = "SORRY FOR TRAFFIC NaM"; | ||
const string CHARS_TO_FIND = "LP"; | ||
const int CHAR_INDEX = -1; | ||
|
||
var actual = str.UnEscapedIndexOfAny(CHARS_TO_FIND); | ||
|
||
Assert.Equal(CHAR_INDEX, actual); | ||
} | ||
|
||
[Fact] | ||
public void CorrectlyFindsNextIndexWithBackslashEscapes() | ||
{ | ||
ReadOnlySpan<char> str = @"SORRY \FOR TRAFFIC NaM"; | ||
const string CHARS_TO_FIND = "FT"; | ||
const int CHAR_INDEX = 11; | ||
|
||
var actual = str.UnEscapedIndexOfAny(CHARS_TO_FIND); | ||
|
||
Assert.Equal(CHAR_INDEX, actual); | ||
} | ||
|
||
[Fact] | ||
public void DoesNotFindIndexWithBackslashEscapes() | ||
{ | ||
ReadOnlySpan<char> str = @"SORRY \FOR TRA\F\F\IC NaM"; | ||
const string CHARS_TO_FIND = "FI"; | ||
const int CHAR_INDEX = -1; | ||
|
||
var actual = str.UnEscapedIndexOfAny(CHARS_TO_FIND); | ||
|
||
Assert.Equal(CHAR_INDEX, actual); | ||
} | ||
|
||
[Fact] | ||
public void CorrectlyFindsNextIndexWithUnrelatedQuoteEscapes() | ||
{ | ||
ReadOnlySpan<char> str = "SORRY FOR \"TRAFFIC\" NaM"; | ||
const string CHARS_TO_FIND = "abc"; | ||
const int CHAR_INDEX = 21; | ||
|
||
var actual = str.UnEscapedIndexOfAny(CHARS_TO_FIND); | ||
|
||
Assert.Equal(CHAR_INDEX, actual); | ||
} | ||
|
||
[Fact] | ||
public void CorrectlyFindsNextIndexWithQuoteEscapes() | ||
{ | ||
ReadOnlySpan<char> str = "SORRY \"FOR\" TRAFFIC NaM"; | ||
const string CHARS_TO_FIND = "FM"; | ||
const int CHAR_INDEX = 15; | ||
|
||
var actual = str.UnEscapedIndexOfAny(CHARS_TO_FIND); | ||
|
||
Assert.Equal(CHAR_INDEX, actual); | ||
} | ||
|
||
[Fact] | ||
public void DoesNotFindAnIndexWithQuoteEscapes() | ||
{ | ||
ReadOnlySpan<char> str = "SORRY \"FOR\" \"TRAFFIC\" NaM"; | ||
const string CHARS_TO_FIND = "FA"; | ||
const int CHAR_INDEX = -1; | ||
|
||
var actual = str.UnEscapedIndexOfAny(CHARS_TO_FIND); | ||
|
||
Assert.Equal(CHAR_INDEX, actual); | ||
} | ||
|
||
[Theory] | ||
[InlineData("abc\\")] | ||
[InlineData("abc\'")] | ||
[InlineData("abc\"")] | ||
public void Throws_WhenEscapeCharIsPassed(string charsToFind) | ||
{ | ||
Assert.Throws<ArgumentOutOfRangeException>(() => | ||
{ | ||
ReadOnlySpan<char> str = "SO\\R\\RY \'FOR\' \"TRAFFIC\" NaM"; | ||
str.UnEscapedIndexOfAny(charsToFind); | ||
}); | ||
} | ||
|
||
[Fact] | ||
public void Throws_WhenImbalancedQuoteChar() | ||
{ | ||
Assert.Throws<FormatException>(() => | ||
{ | ||
const string CHARS_TO_FIND = "FT"; | ||
ReadOnlySpan<char> str = "SORRY \"FOR TRAFFIC NaM"; | ||
str.UnEscapedIndexOfAny(CHARS_TO_FIND); | ||
}); | ||
} | ||
} | ||
} |
115 changes: 115 additions & 0 deletions
115
TwitchDownloaderCore.Tests/ReadOnlySpanUnEscapedIndexOfTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
using TwitchDownloaderCore.Extensions; | ||
|
||
namespace TwitchDownloaderCore.Tests | ||
{ | ||
public class ReadOnlySpanUnEscapedIndexOfTests | ||
{ | ||
[Fact] | ||
public void CorrectlyFindsNextIndexWithoutEscapes() | ||
{ | ||
ReadOnlySpan<char> str = "SORRY FOR TRAFFIC NaM"; | ||
const char CHAR_TO_FIND = 'a'; | ||
const int CHAR_INDEX = 19; | ||
|
||
var actual = str.UnEscapedIndexOf(CHAR_TO_FIND); | ||
|
||
Assert.Equal(CHAR_INDEX, actual); | ||
} | ||
|
||
[Fact] | ||
public void DoesNotFindAnIndexWhenNotPresent() | ||
{ | ||
ReadOnlySpan<char> str = "SORRY FOR TRAFFIC NaM"; | ||
const char CHAR_TO_FIND = 'L'; | ||
const int CHAR_INDEX = -1; | ||
|
||
var actual = str.UnEscapedIndexOf(CHAR_TO_FIND); | ||
|
||
Assert.Equal(CHAR_INDEX, actual); | ||
} | ||
|
||
[Fact] | ||
public void CorrectlyFindsNextIndexWithBackslashEscapes() | ||
{ | ||
ReadOnlySpan<char> str = @"SORRY \FOR TRAFFIC NaM"; | ||
const char CHAR_TO_FIND = 'F'; | ||
const int CHAR_INDEX = 14; | ||
|
||
var actual = str.UnEscapedIndexOf(CHAR_TO_FIND); | ||
|
||
Assert.Equal(CHAR_INDEX, actual); | ||
} | ||
|
||
[Fact] | ||
public void DoesNotFindIndexWithBackslashEscapes() | ||
{ | ||
ReadOnlySpan<char> str = @"SORRY \FOR TRA\F\FIC NaM"; | ||
const char CHAR_TO_FIND = 'F'; | ||
const int CHAR_INDEX = -1; | ||
|
||
var actual = str.UnEscapedIndexOf(CHAR_TO_FIND); | ||
|
||
Assert.Equal(CHAR_INDEX, actual); | ||
} | ||
|
||
[Fact] | ||
public void CorrectlyFindsNextIndexWithUnrelatedQuoteEscapes() | ||
{ | ||
ReadOnlySpan<char> str = "SORRY FOR \"TRAFFIC\" NaM"; | ||
const char CHAR_TO_FIND = 'a'; | ||
const int CHAR_INDEX = 21; | ||
|
||
var actual = str.UnEscapedIndexOf(CHAR_TO_FIND); | ||
|
||
Assert.Equal(CHAR_INDEX, actual); | ||
} | ||
|
||
[Fact] | ||
public void CorrectlyFindsNextIndexWithQuoteEscapes() | ||
{ | ||
ReadOnlySpan<char> str = "SORRY \"FOR\" TRAFFIC NaM"; | ||
const char CHAR_TO_FIND = 'F'; | ||
const int CHAR_INDEX = 15; | ||
|
||
var actual = str.UnEscapedIndexOf(CHAR_TO_FIND); | ||
|
||
Assert.Equal(CHAR_INDEX, actual); | ||
} | ||
|
||
[Fact] | ||
public void DoesNotFindAnIndexWithQuoteEscapes() | ||
{ | ||
ReadOnlySpan<char> str = "SORRY \"FOR\" \"TRAFFIC\" NaM"; | ||
const char CHAR_TO_FIND = 'F'; | ||
const int CHAR_INDEX = -1; | ||
|
||
var actual = str.UnEscapedIndexOf(CHAR_TO_FIND); | ||
|
||
Assert.Equal(CHAR_INDEX, actual); | ||
} | ||
|
||
[Theory] | ||
[InlineData('\\')] | ||
[InlineData('\'')] | ||
[InlineData('\"')] | ||
public void Throws_WhenEscapeCharIsPassed(char charToFind) | ||
{ | ||
Assert.Throws<ArgumentOutOfRangeException>(() => | ||
{ | ||
ReadOnlySpan<char> str = "SO\\R\\RY \'FOR\' \"TRAFFIC\" NaM"; | ||
str.UnEscapedIndexOf(charToFind); | ||
}); | ||
} | ||
|
||
[Fact] | ||
public void Throws_WhenImbalancedQuoteChar() | ||
{ | ||
Assert.Throws<FormatException>(() => | ||
{ | ||
const char CHAR_TO_FIND = 'F'; | ||
ReadOnlySpan<char> str = "SORRY \"FOR TRAFFIC NaM"; | ||
str.UnEscapedIndexOf(CHAR_TO_FIND); | ||
}); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.