Merge branch 'main' into release/4.0.0

This commit is contained in:
Oliver Booth 2023-08-09 15:24:33 +01:00
commit b977b7a4ec
Signed by: oliverbooth
GPG Key ID: 725DB725A0D9EE61
7 changed files with 59 additions and 40 deletions

View File

@ -29,12 +29,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed ### Changed
- X10D: `DateTime.Age(DateTime)` and `DateTimeOffset.Age(DateTimeOffset)` parameter renamed from `asOf` to `referenceDate`. - X10D: DateTime.Age(DateTime) and DateTimeOffset.Age(DateTimeOffset) parameter renamed from asOf to referenceDate.
### Removed ### Removed
- X10D: Removed `IEnumerable<T>.ConcatOne` - this functionality already exists with `Append`. - X10D: Removed `IEnumerable<T>.ConcatOne` - this functionality already exists with `Append`.
## [3.2.2] - 2023-06-05
### Added
- X10D.DSharpPlus: Added support for new usernames. See https://discord.com/blog/usernames
## 3.2.1 - 2023-06-05
ERRONEOUS RELEASE.
## [3.2.0] - 2023-04-03 ## [3.2.0] - 2023-04-03
### Added ### Added
@ -597,7 +607,8 @@ please [open an issue](https://github.com/oliverbooth/X10D/issues)!
Earlier versions of this package are undocumented and unlisted from package results. Earlier versions of this package are undocumented and unlisted from package results.
[unreleased]: https://github.com/oliverbooth/X10D/compare/v3.2.0...main [unreleased]: https://github.com/oliverbooth/X10D/compare/v3.2.2...main
[3.2.2]: https://github.com/oliverbooth/X10D/releases/tag/v3.2.2
[3.2.0]: https://github.com/oliverbooth/X10D/releases/tag/v3.2.0 [3.2.0]: https://github.com/oliverbooth/X10D/releases/tag/v3.2.0
[3.1.0]: https://github.com/oliverbooth/X10D/releases/tag/v3.1.0 [3.1.0]: https://github.com/oliverbooth/X10D/releases/tag/v3.1.0
[3.0.0]: https://github.com/oliverbooth/X10D/releases/tag/v3.0.0 [3.0.0]: https://github.com/oliverbooth/X10D/releases/tag/v3.0.0

View File

@ -68,6 +68,12 @@ public static class DiscordUserExtensions
throw new ArgumentNullException(nameof(user)); throw new ArgumentNullException(nameof(user));
} }
if (user.Discriminator == "0")
{
// user has a new username. see: https://discord.com/blog/usernames
return user.Username;
}
return $"{user.Username}#{user.Discriminator}"; return $"{user.Username}#{user.Discriminator}";
} }

View File

@ -17,7 +17,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.1"/> <PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.1"/>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0"/> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0"/>
<PackageReference Include="Moq" Version="4.18.4"/> <PackageReference Include="NSubstitute" Version="5.0.0"/>
<PackageReference Include="NUnit" Version="3.13.3"/> <PackageReference Include="NUnit" Version="3.13.3"/>
<PackageReference Include="NUnit3TestAdapter" Version="4.4.2"/> <PackageReference Include="NUnit3TestAdapter" Version="4.4.2"/>
<PackageReference Include="NUnit.Analyzers" Version="3.6.1"/> <PackageReference Include="NUnit.Analyzers" Version="3.6.1"/>

View File

@ -1,5 +1,5 @@
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using Moq; using NSubstitute;
using NUnit.Framework; using NUnit.Framework;
using X10D.Collections; using X10D.Collections;
@ -13,16 +13,17 @@ public partial class CollectionTests
[Test] [Test]
public void ClearAndDisposeAll_ShouldClearAndDisposeAllItems_WhenCalledWithValidList() public void ClearAndDisposeAll_ShouldClearAndDisposeAllItems_WhenCalledWithValidList()
{ {
var mock1 = new Mock<IDisposable>(); var substitute1 = Substitute.For<IDisposable>();
var mock2 = new Mock<IDisposable>(); var substitute2 = Substitute.For<IDisposable>();
var mock3 = new Mock<IDisposable>(); var substitute3 = Substitute.For<IDisposable>();
var list = new List<IDisposable> {mock1.Object, mock2.Object, mock3.Object}; var list = new List<IDisposable> {substitute1, substitute2, substitute3};
list.ClearAndDisposeAll(); list.ClearAndDisposeAll();
mock1.Verify(i => i.Dispose(), Times.Once); substitute1.Received(1).Dispose();
mock2.Verify(i => i.Dispose(), Times.Once); substitute2.Received(1).Dispose();
mock3.Verify(i => i.Dispose(), Times.Once); substitute3.Received(1).Dispose();
Assert.That(list, Is.Empty); Assert.That(list, Is.Empty);
} }
@ -36,8 +37,8 @@ public partial class CollectionTests
[Test] [Test]
public void ClearAndDisposeAll_ShouldThrowInvalidOperationException_WhenCalledWithReadOnlyList() public void ClearAndDisposeAll_ShouldThrowInvalidOperationException_WhenCalledWithReadOnlyList()
{ {
var mock = new Mock<IDisposable>(); var substitute = Substitute.For<IDisposable>();
var list = new ReadOnlyCollection<IDisposable>(new List<IDisposable> {mock.Object}); var list = new ReadOnlyCollection<IDisposable>(new List<IDisposable> {substitute});
Assert.Throws<InvalidOperationException>(() => list.ClearAndDisposeAll()); Assert.Throws<InvalidOperationException>(() => list.ClearAndDisposeAll());
} }

View File

@ -1,5 +1,5 @@
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using Moq; using NSubstitute;
using NUnit.Framework; using NUnit.Framework;
using X10D.Collections; using X10D.Collections;
@ -13,16 +13,17 @@ public partial class CollectionTests
[Test] [Test]
public async Task ClearAndDisposeAllAsync_ShouldClearAndDisposeAllItems_WhenCalledWithValidList() public async Task ClearAndDisposeAllAsync_ShouldClearAndDisposeAllItems_WhenCalledWithValidList()
{ {
var mock1 = new Mock<IAsyncDisposable>(); var substitute1 = Substitute.For<IAsyncDisposable>();
var mock2 = new Mock<IAsyncDisposable>(); var substitute2 = Substitute.For<IAsyncDisposable>();
var mock3 = new Mock<IAsyncDisposable>(); var substitute3 = Substitute.For<IAsyncDisposable>();
var list = new List<IAsyncDisposable> {mock1.Object, mock2.Object, mock3.Object}; var list = new List<IAsyncDisposable> {substitute1, substitute2, substitute3};
await list.ClearAndDisposeAllAsync().ConfigureAwait(false); await list.ClearAndDisposeAllAsync().ConfigureAwait(false);
mock1.Verify(i => i.DisposeAsync(), Times.Once); await substitute1.Received(1).DisposeAsync();
mock2.Verify(i => i.DisposeAsync(), Times.Once); await substitute2.Received(1).DisposeAsync();
mock3.Verify(i => i.DisposeAsync(), Times.Once); await substitute3.Received(1).DisposeAsync();
Assert.That(list, Is.Empty); Assert.That(list, Is.Empty);
} }
@ -36,8 +37,8 @@ public partial class CollectionTests
[Test] [Test]
public void ClearAndDisposeAllAsync_ShouldThrowInvalidOperationException_WhenCalledWithReadOnlyList() public void ClearAndDisposeAllAsync_ShouldThrowInvalidOperationException_WhenCalledWithReadOnlyList()
{ {
var mock = new Mock<IAsyncDisposable>(); var substitute = Substitute.For<IAsyncDisposable>();
var list = new ReadOnlyCollection<IAsyncDisposable>(new List<IAsyncDisposable> {mock.Object}); var list = new ReadOnlyCollection<IAsyncDisposable>(new List<IAsyncDisposable> {substitute});
Assert.ThrowsAsync<InvalidOperationException>(list.ClearAndDisposeAllAsync); Assert.ThrowsAsync<InvalidOperationException>(list.ClearAndDisposeAllAsync);
} }

View File

@ -1,4 +1,4 @@
using Moq; using NSubstitute;
using NUnit.Framework; using NUnit.Framework;
using X10D.Collections; using X10D.Collections;
@ -12,16 +12,16 @@ public partial class EnumerableTests
[Test] [Test]
public void DisposeAll_ShouldDisposeAllItems_WhenCalledWithValidList() public void DisposeAll_ShouldDisposeAllItems_WhenCalledWithValidList()
{ {
var mock1 = new Mock<IDisposable>(); var substitute1 = Substitute.For<IDisposable>();
var mock2 = new Mock<IDisposable>(); var substitute2 = Substitute.For<IDisposable>();
var mock3 = new Mock<IDisposable>(); var substitute3 = Substitute.For<IDisposable>();
var list = new List<IDisposable> {mock1.Object, mock2.Object, null!, mock3.Object}; var list = new List<IDisposable> { substitute1, substitute2, null!, substitute3 };
list.DisposeAll(); list.DisposeAll();
mock1.Verify(i => i.Dispose(), Times.Once); substitute1.Received(1).Dispose();
mock2.Verify(i => i.Dispose(), Times.Once); substitute2.Received(1).Dispose();
mock3.Verify(i => i.Dispose(), Times.Once); substitute3.Received(1).Dispose();
} }
[Test] [Test]

View File

@ -1,4 +1,4 @@
using Moq; using NSubstitute;
using NUnit.Framework; using NUnit.Framework;
using X10D.Collections; using X10D.Collections;
@ -12,16 +12,16 @@ public partial class EnumerableTests
[Test] [Test]
public async Task DisposeAllAsync_ShouldDisposeAllItems_WhenCalledWithValidList() public async Task DisposeAllAsync_ShouldDisposeAllItems_WhenCalledWithValidList()
{ {
var mock1 = new Mock<IAsyncDisposable>(); var substitute1 = Substitute.For<IAsyncDisposable>();
var mock2 = new Mock<IAsyncDisposable>(); var substitute2 = Substitute.For<IAsyncDisposable>();
var mock3 = new Mock<IAsyncDisposable>(); var substitute3 = Substitute.For<IAsyncDisposable>();
var list = new List<IAsyncDisposable> {mock1.Object, mock2.Object, null!, mock3.Object}; var list = new List<IAsyncDisposable> { substitute1, substitute2, null!, substitute3 };
await list.DisposeAllAsync().ConfigureAwait(false); await list.DisposeAllAsync().ConfigureAwait(false);
mock1.Verify(i => i.DisposeAsync(), Times.Once); await substitute1.Received(1).DisposeAsync();
mock2.Verify(i => i.DisposeAsync(), Times.Once); await substitute2.Received(1).DisposeAsync();
mock3.Verify(i => i.DisposeAsync(), Times.Once); await substitute3.Received(1).DisposeAsync();
} }
[Test] [Test]