This commit is contained in:
Oliver Booth 2024-06-12 13:44:20 +01:00 committed by GitHub
commit 968e0748d2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
520 changed files with 5361 additions and 17353 deletions

View File

@ -1,18 +0,0 @@
name: Acquire activation file
on:
workflow_dispatch: {}
jobs:
activation:
name: Request manual activation file 🔑
runs-on: ubuntu-latest
steps:
# Request manual activation file
- name: Request manual activation file
id: getManualLicenseFile
uses: game-ci/unity-request-activation-file@v2
# Upload artifact (Unity_v20XX.X.XXXX.alf)
- name: Expose as artifact
uses: actions/upload-artifact@v2
with:
name: ${{ steps.getManualLicenseFile.outputs.filePath }}
path: ${{ steps.getManualLicenseFile.outputs.filePath }}

View File

@ -23,9 +23,8 @@ jobs:
uses: actions/setup-dotnet@v3
with:
dotnet-version: |
3.1.x
6.0.x
7.0.x
8.0.x
- name: Add NuGet source
run: dotnet nuget add source --username oliverbooth --password ${{ secrets.GITHUB_TOKEN }} --store-password-in-clear-text --name github "https://nuget.pkg.github.com/oliverbooth/index.json"
@ -33,36 +32,18 @@ jobs:
- name: Restore dependencies
run: dotnet restore
- name: Install coverage tools
run: |
dotnet tool install --global JetBrains.dotCover.GlobalTool
dotnet tool install --global dotnet-reportgenerator-globaltool
- name: Build
run: dotnet build --no-restore --configuration Release
- name: Test .NET Core 3.1
run: dotnet test --no-build --verbosity normal --configuration Release --framework netcoreapp3.1
- name: Test .NET 6
run: dotnet test --no-build --verbosity normal --configuration Release --framework net6.0
- name: Test .NET 7
run: dotnet test --no-build --verbosity normal --configuration Release --framework net7.0
run: dotnet test --no-build --verbosity normal --configuration Release --framework net6.0 --collect:"XPlat Code Coverage" --results-directory test-results/net6.0
- name: Test .NET 8
run: dotnet test --no-build --verbosity normal --configuration Release --framework net8.0
- name: Collect coverage
run: dotnet dotcover test --dcReportType=DetailedXML
- name: Convert coverage
run: reportgenerator -reports:./dotCover.Output.xml -targetdir:. -reporttypes:Cobertura
run: dotnet test --no-build --verbosity normal --configuration Release --framework net8.0 --collect:"XPlat Code Coverage" --results-directory test-results/net8.0
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v4.0.0
with:
disable_search: true
file: Cobertura.xml
directory: test-results
token: ${{ secrets.CODECOV_TOKEN }}
slug: oliverbooth/X10D

View File

@ -18,7 +18,7 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
dotnet-version: 7.0.x
dotnet-version: 8.0.x
- name: Add GitHub NuGet source
run: dotnet nuget add source --username oliverbooth --password ${{ secrets.GITHUB_TOKEN }} --store-password-in-clear-text --name github "https://nuget.pkg.github.com/oliverbooth/index.json"
@ -33,9 +33,7 @@ jobs:
run: |
mkdir build
dotnet pack X10D --configuration Debug --no-build -p:SymbolPackageFormat=snupkg --include-symbols --include-source -o build -p:VersionSuffix='nightly' -p:BuildNumber=${{ github.run_number }}
dotnet pack X10D.DSharpPlus --configuration Debug --no-build -p:SymbolPackageFormat=snupkg --include-symbols --include-source -o build -p:VersionSuffix='nightly' -p:BuildNumber=${{ github.run_number }}
dotnet pack X10D.Hosting --configuration Debug --no-build -p:SymbolPackageFormat=snupkg --include-symbols --include-source -o build -p:VersionSuffix='nightly' -p:BuildNumber=${{ github.run_number }}
dotnet pack X10D.Unity --configuration Debug --no-build -p:SymbolPackageFormat=snupkg --include-symbols --include-source -o build -p:VersionSuffix='nightly' -p:BuildNumber=${{ github.run_number }}
- name: Push NuGet Package to GitHub
run: dotnet nuget push "build/*" --source "github" --api-key ${{ secrets.GITHUB_TOKEN }} --skip-duplicate
@ -48,42 +46,3 @@ jobs:
with:
name: build
path: build/
- name: Checkout upm branch
uses: actions/checkout@v3
with:
ref: upm
path: upm
- name: Build package.json
run: |
dotnet run --project ./tools/UpmPackageGenerator/UpmPackageGenerator.csproj "./X10D/bin/Debug/netstandard2.1/X10D.dll"
cp package.json upm/package.json
- name: Copy built artifacts to upm
run: |
cd upm
cp ../X10D/bin/Debug/netstandard2.1/X10D.dll ./X10D.dll
cp ../X10D/bin/Debug/netstandard2.1/X10D.xml ./X10D.xml
cp ../X10D.Unity/bin/Debug/netstandard2.1/X10D.Unity.dll ./X10D.Unity.dll
cp ../X10D.Unity/bin/Debug/netstandard2.1/X10D.Unity.xml ./X10D.Unity.xml
- name: Check for changes
run: |
cd upm
git diff --quiet
continue-on-error: true
- name: Commit update
if: ${{ success() }}
run: |
cd upm
git config user.name github-actions
git config user.email github-actions@github.com
git add X10D.dll
git add X10D.Unity.dll
git add X10D.xml
git add X10D.Unity.xml
git add package.json
git commit -m "Update upm branch ($GITHUB_SHA)"
git push

View File

@ -17,7 +17,7 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
dotnet-version: 7.0.x
dotnet-version: 8.0.x
- name: Add GitHub NuGet source
run: dotnet nuget add source --username oliverbooth --password ${{ secrets.GITHUB_TOKEN }} --store-password-in-clear-text --name github "https://nuget.pkg.github.com/oliverbooth/index.json"
@ -32,9 +32,7 @@ jobs:
run: |
mkdir build
dotnet pack X10D --configuration Release --no-build -p:SymbolPackageFormat=snupkg --include-symbols --include-source -o build -p:VersionSuffix='prerelease' -p:BuildNumber=${{ github.run_number }}
dotnet pack X10D.DSharpPlus --configuration Release --no-build -p:SymbolPackageFormat=snupkg --include-symbols --include-source -o build -p:VersionSuffix='prerelease' -p:BuildNumber=${{ github.run_number }}
dotnet pack X10D.Hosting --configuration Release --no-build -p:SymbolPackageFormat=snupkg --include-symbols --include-source -o build -p:VersionSuffix='prerelease' -p:BuildNumber=${{ github.run_number }}
dotnet pack X10D.Unity --configuration Release --no-build -p:SymbolPackageFormat=snupkg --include-symbols --include-source -o build -p:VersionSuffix='prerelease' -p:BuildNumber=${{ github.run_number }}
- name: Push NuGet Package to GitHub
run: dotnet nuget push "build/*" --source "github" --api-key ${{ secrets.GITHUB_TOKEN }} --skip-duplicate
@ -53,42 +51,3 @@ jobs:
with:
repo_token: "${{ secrets.GITHUB_TOKEN }}"
prerelease: true
- name: Checkout upm branch
uses: actions/checkout@v3
with:
ref: upm
path: upm
- name: Build package.json
run: |
dotnet run --project ./tools/UpmPackageGenerator/UpmPackageGenerator.csproj "./X10D/bin/Release/netstandard2.1/X10D.dll"
cp package.json upm/package.json
- name: Copy built artifacts to upm
run: |
cd upm
cp ../X10D/bin/Release/netstandard2.1/X10D.dll ./X10D.dll
cp ../X10D/bin/Release/netstandard2.1/X10D.xml ./X10D.xml
cp ../X10D.Unity/bin/Release/netstandard2.1/X10D.Unity.dll ./X10D.Unity.dll
cp ../X10D.Unity/bin/Release/netstandard2.1/X10D.Unity.xml ./X10D.Unity.xml
- name: Check for changes
run: |
cd upm
git diff --quiet
continue-on-error: true
- name: Commit update
if: ${{ success() }}
run: |
cd upm
git config user.name github-actions
git config user.email github-actions@github.com
git add X10D.dll
git add X10D.Unity.dll
git add X10D.xml
git add X10D.Unity.xml
git add package.json
git commit -m "Update upm branch ($GITHUB_SHA)"
git push

View File

@ -17,7 +17,7 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
dotnet-version: 7.0.x
dotnet-version: 8.0.x
- name: Add GitHub NuGet source
run: dotnet nuget add source --username oliverbooth --password ${{ secrets.GITHUB_TOKEN }} --store-password-in-clear-text --name github "https://nuget.pkg.github.com/oliverbooth/index.json"
@ -32,9 +32,7 @@ jobs:
run: |
mkdir build
dotnet pack X10D --configuration Release --no-build -p:SymbolPackageFormat=snupkg --include-symbols --include-source -o build
dotnet pack X10D.DSharpPlus --configuration Release --no-build -p:SymbolPackageFormat=snupkg --include-symbols --include-source -o build
dotnet pack X10D.Hosting --configuration Release --no-build -p:SymbolPackageFormat=snupkg --include-symbols --include-source -o build
dotnet pack X10D.Unity --configuration Release --no-build -p:SymbolPackageFormat=snupkg --include-symbols --include-source -o build
- name: Push NuGet Package to GitHub
run: dotnet nuget push "build/*" --source "github" --api-key ${{ secrets.GITHUB_TOKEN }} --skip-duplicate
@ -53,42 +51,3 @@ jobs:
with:
repo_token: "${{ secrets.GITHUB_TOKEN }}"
prerelease: false
- name: Checkout upm branch
uses: actions/checkout@v3
with:
ref: upm
path: upm
- name: Build package.json
run: |
dotnet run --project ./tools/UpmPackageGenerator/UpmPackageGenerator.csproj "./X10D/bin/Release/netstandard2.1/X10D.dll"
cp package.json upm/package.json
- name: Copy built artifacts to upm
run: |
cd upm
cp ../X10D/bin/Release/netstandard2.1/X10D.dll ./X10D.dll
cp ../X10D/bin/Release/netstandard2.1/X10D.xml ./X10D.xml
cp ../X10D.Unity/bin/Release/netstandard2.1/X10D.Unity.dll ./X10D.Unity.dll
cp ../X10D.Unity/bin/Release/netstandard2.1/X10D.Unity.xml ./X10D.Unity.xml
- name: Check for changes
run: |
cd upm
git diff --quiet
continue-on-error: true
- name: Commit update
if: ${{ success() }}
run: |
cd upm
git config user.name github-actions
git config user.email github-actions@github.com
git add X10D.dll
git add X10D.Unity.dll
git add X10D.xml
git add X10D.Unity.xml
git add package.json
git commit -m "Update upm branch ($GITHUB_SHA)"
git push

View File

@ -19,7 +19,7 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
dotnet-version: 7.0.x
dotnet-version: 8.0.x
- name: Add GitHub NuGet source
run: dotnet nuget add source --username oliverbooth --password ${{ secrets.GITHUB_TOKEN }} --store-password-in-clear-text --name github "https://nuget.pkg.github.com/oliverbooth/index.json"
@ -31,4 +31,4 @@ jobs:
run: dotnet build -c Debug
- name: Run Source Validation
run: dotnet run --project ./tools/SourceValidator/SourceValidator.csproj ./X10D/src ./X10D.Unity/src
run: dotnet run --project ./tools/SourceValidator/SourceValidator.csproj ./X10D/src

View File

@ -1,50 +0,0 @@
name: Unity Test Runner
on:
push:
branches:
- '*'
- '*/*'
pull_request:
branches:
- '*'
- '*/*'
jobs:
build:
name: "Unity Test Runner"
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
dotnet-version: 7.0.x
- name: Add GitHub NuGet source
run: dotnet nuget add source --username oliverbooth --password ${{ secrets.GITHUB_TOKEN }} --store-password-in-clear-text --name github "https://nuget.pkg.github.com/oliverbooth/index.json"
- name: Restore dependencies
run: dotnet restore
- name: Build
run: dotnet build -c Release
- name: Copy artifacts to project
run: |
mkdir -p ./X10D.Unity.Tests/Assets/Libraries
cp -r ./X10D/bin/Release/netstandard2.1/X10D.dll ./X10D.Unity.Tests/Assets/Libraries/X10D.dll
cp -r ./X10D.Unity/bin/Release/netstandard2.1/X10D.Unity.dll ./X10D.Unity.Tests/Assets/Libraries/X10D.Unity.dll
- name: Unity - Test runner
uses: game-ci/unity-test-runner@v2.1.0
env:
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
with:
projectPath: X10D.Unity.Tests
githubToken: ${{ secrets.GITHUB_TOKEN }}

View File

@ -5,10 +5,61 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## 4.0.0 - [Unreleased]
### Added
- X10D: Add support for generic math interfaces.
- X10D: Added extension methods for `DateOnly`, for parity with `DateTime` and `DateTimeOffset`.
- X10D: Added math-related extension methods for `BigInteger`.
- X10D: Added `Span<T>.Replace(T, T)`.
- X10D: Added `CountDigits` for integer types.
- X10D: Added `IEnumerable<T>.Except(T)`.
- X10D: Added `Progress<T>.OnProgressChanged([T])`.
- X10D: Added `TextWriter.WriteNoAlloc(int[, ReadOnlySpan<char>[, IFormatProvider]])`.
- X10D: Added `TextWriter.WriteNoAlloc(uint[, ReadOnlySpan<char>[, IFormatProvider]])`.
- X10D: Added `TextWriter.WriteNoAlloc(long[, ReadOnlySpan<char>[, IFormatProvider]])`.
- X10D: Added `TextWriter.WriteNoAlloc(ulong[, ReadOnlySpan<char>[, IFormatProvider]])`.
- X10D: Added `TextWriter.WriteLineNoAlloc(int[, ReadOnlySpan<char>[, IFormatProvider]])`.
- X10D: Added `TextWriter.WriteLineNoAlloc(uint[, ReadOnlySpan<char>[, IFormatProvider]])`.
- X10D: Added `TextWriter.WriteLineNoAlloc(long[, ReadOnlySpan<char>[, IFormatProvider]])`.
- X10D: Added `TextWriter.WriteLineNoAlloc(ulong[, ReadOnlySpan<char>[, IFormatProvider]])`.
- X10D: Added `Range.GetEnumerator` (and `RangeEnumerator`), implementing Python-esque `for` loops in C#.
- X10D: Added `string.ConcatIf`.
- X10D: Added `string.MDBold`, `string.MDCode`, `string.MDCodeBlock([string])`, `string.MDHeading(int)`,
`string.MDItalic`, `string.MDLink`, `string.MDStrikeOut`, and `string.MDUnderline` for Markdown formatting.
- X10D: Added Span overloads which complement `char.Repeat` and `string.Repeat`.
### Fixed
- X10D: Fixed XMLDoc for `Line3D` to read "single-precision floating-point" instead of "32-bit signed integer".
### Changed
- X10D: DateTime.Age(DateTime) and DateTimeOffset.Age(DateTimeOffset) parameter renamed from asOf to referenceDate.
- X10D: Methods which accepted the `Endianness` enum as an argument have been replaced with explicit
BigEndian/LittleEndian methods.
- X10D: `Stream.GetHash<>` and `Stream.TryWriteHash<>` now throw ArgumentException in lieu of
TypeInitializationException.
- X10D: `char.IsEmoji` no longer allocates for .NET 7+.
- X10D: `string.Repeat` is now more efficient.
### Removed
- X10D: Removed `IEnumerable<T>.ConcatOne` - this functionality already exists with `Append`.
- X10D: Removed `Endianness` enum.
- X10D: Removed `Span<T>.Replace(T, T)` for .NET 8 target.
- X10D: Removed .NET Standard 2.1 target.
- X10D: Removed extensions for `Progress<T>`. These are already provided by [`Observable.FromEventPattern`](https://learn.microsoft.com/en-us/previous-versions/dotnet/reactive-extensions/hh229424(v=vs.103)).
- X10D.Hosting: Removed .NET Standard 2.1 target.
- X10D.DSharpPlus: Complete sunset of library. This library will not be updated to support DSharpPlus v5.0.0 (#83).
- X10D.Unity: Complete sunset of library. This library will not be updated effective immediately (#86).
## [3.3.1] - 2023-08-21
### Fixed
- X10D: Fixed `decimal.TryWriteBigEndianBytes` and `decimal.TryWriteLittleEndianBytes`.
- X10D.Hosting: Fixed `AddHostedSingleton` not accepting an interface as the service type.
## [3.3.0] - 2023-08-21

View File

@ -5,7 +5,7 @@ or submit a pull request.
### Pull request guidelines
This project uses C# 11.0 language features where feasible, and adheres to StyleCop rules with some minor adjustments.
This project uses C# 12.0 language features where feasible, and adheres to StyleCop rules with some minor adjustments.
There is an `.editorconfig` included in this repository. For quick and painless pull requests, ensure that the analyzer does not
throw warnings.
@ -17,7 +17,7 @@ convetional commits specification.
Below are a few pointers to which you may refer, but keep in mind this is not an exhaustive list:
- Use C# 11.0 features where possible
- Use C# 12.0 features where possible
- Try to ensure code is CLS-compliant. Where this is not possible, decorate methods with `CLSCompliantAttribute` and pass `false`
- Follow all .NET guidelines and coding conventions.
See https://docs.microsoft.com/en-us/dotnet/csharp/fundamentals/coding-style/coding-conventions

View File

@ -1,11 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project>
<PropertyGroup>
<TargetFrameworks>net7.0;net6.0;netstandard2.1</TargetFrameworks>
<LangVersion>11.0</LangVersion>
<LangVersion>12.0</LangVersion>
<Optimize>true</Optimize>
<ImplicitUsings>true</ImplicitUsings>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<EnableNETAnalyzers>true</EnableNETAnalyzers>
<DebugType>pdbonly</DebugType>
<DebugSymbols>true</DebugSymbols>
<VersionPrefix>4.0.0</VersionPrefix>
<Authors>Oliver Booth</Authors>
<Nullable>enable</Nullable>
<NeutralLanguage>en</NeutralLanguage>
<RepositoryUrl>https://github.com/oliverbooth/X10D</RepositoryUrl>
<RepositoryType>git</RepositoryType>
@ -14,16 +19,9 @@
<PackageIcon>branding_Icon.png</PackageIcon>
<PackageIconUrl/>
<PackageTags>dotnet extension-methods</PackageTags>
<PackageReleaseNotes>$([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)/../CHANGELOG.md"))</PackageReleaseNotes>
<PackageReadmeFile>README.md</PackageReadmeFile>
<PackageReleaseNotes>See CHANGELOG.md for a full list of changes.</PackageReleaseNotes>
<CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>
<VersionPrefix>3.3.1</VersionPrefix>
<Nullable>enable</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<ExcludeFromCodeCoverage>true</ExcludeFromCodeCoverage>
<EnableNETAnalyzers>true</EnableNETAnalyzers>
<DebugType>pdbonly</DebugType>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<PropertyGroup Condition="'$(GITHUB_ACTIONS)' == 'true'">
@ -48,10 +46,6 @@
<FileVersion>$(VersionPrefix).0</FileVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="DSharpPlus" Version="4.3.0" PrivateAssets="All"/>
</ItemGroup>
<ItemGroup>
<None Include="..\branding_Icon.png">
<Pack>True</Pack>
@ -61,10 +55,13 @@
<Pack>True</Pack>
<PackagePath/>
</None>
<None Include="..\README.md">
<Pack>True</Pack>
<PackagePath/>
</None>
<None Include="..\CHANGELOG.md">
<Pack>True</Pack>
<PackagePath/>
</None>
</ItemGroup>
</Project>
</Project>

100
README.md
View File

@ -9,29 +9,115 @@
<a href="https://github.com/oliverbooth/X10D/blob/master/LICENSE.md"><img src="https://img.shields.io/github/license/oliverbooth/X10D?style=flat-square" alt="MIT License" title="MIT License"></a>
</p>
### About
## About
X10D (pronounced *extend*), is a .NET package that provides extension methods for numerous types. The purpose of this library is to simplify a codebase by reducing the need for repeated code when performing common operations. Simplify your codebase. Take advantage of .NET. Use extension methods.
*(I'm also [dogfooding](https://www.pcmag.com/encyclopedia/term/dogfooding) this library, so there's that.)*
### What are extension methods?
Extension methods are a clever .NET feature that augment existing types with new functionality. They are defined as
static methods in a static class, and are called as if they were instance methods on the type they are extending. Take,
for example, the following code:
```csharp
public static class Program
{
public static void Main()
{
string str = "Hello, world!";
Console.WriteLine(str.Reverse());
}
}
public static class StringExtensions
{
public static string Reverse(this string str)
{
char[] chars = str.ToCharArray();
Array.Reverse(chars);
return new string(chars);
}
}
```
This will print `!dlrow ,olleH` to the console. The `Reverse` method is defined in the `StringExtensions` class, yet is
called as if it were an instance method on the `str` variable, even though it's not.
### Why use extension methods?
Extension methods were introduced when LINQ was added to .NET. LINQ is a set of extension methods that provide a way to
query, filter, and transform data. If you were to access LINQ's methods statically, you would have to write code like
this:
```csharp
public static class Program
{
public static void Main()
{
int[] numbers = { 1, 2, 3, 4, 5 };
IEnumerable<int> evenNumbers = Enumerable.Where(numbers, x => x % 2 == 0);
IEnumerable<int> doubledNumbers = Enumerable.Select(evenNumbers, x => x * 2);
int sum = Enumerable.Sum(doubledNumbers);
Console.WriteLine(sum);
}
}
```
And if you wanted to one-line this, you'd have to write this:
```csharp
public static class Program
{
public static void Main()
{
int[] numbers = { 1, 2, 3, 4, 5 };
Console.WriteLine(Enumerable.Sum(Enumerable.Select(Enumerable.Where(numbers, x => x % 2 == 0), x => x * 2)));
}
}
```
This is a lot of code to write, and it's not very readable. The nested method calls make it incredibly difficult to
follow. However, because LINQ is implemented as extension methods, you can write the following code instead:
```csharp
public static class Program
{
public static void Main()
{
int[] numbers = { 1, 2, 3, 4, 5 };
Console.WriteLine(numbers.Where(x => x % 2 == 0).Select(x => x * 2).Sum());
}
}
```
Because the methods are called as if they were instance methods on `IEnumerable<T>`, they can be chained together,
making the code much more readable.
X10D aims to provide these same benefits as LINQ, but for dozens of other types and for countless other use cases. See
the [documentation](#documentation) for a complete breakdown of what's available.
## Installation
### NuGet installation
```ps
Install-Package X10D -Version 3.3.1
Install-Package X10D -Version 4.0.0
```
### Manual installation
Download the [latest release](https://github.com/oliverbooth/X10D/releases/latest) from this repository and adding a direct assembly reference for your chosen platform.
### Unity installation
For the Unity installation guide, refer to the [README.md in X10D.Unity](X10D.Unity/README.md).
## Documentation
## Features
I'm planning on writing complete and extensive documentation in the near future. As of this time, feel free to browse the source or the API using your favourite IDE.
For those familiar with the 2.6.0 API, please read [CHANGELOG.md](CHANGELOG.md) for a complete list of changes. **3.0.0 is a major release and introduces many breaking changes.**
Documentation and the API reference is available at https://oliverbooth.github.io/X10D/index.html. *I'm sorry this took
so long to get up and running. DocFX will be the death of me.*
## Contributing
Contributions are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md).
## License
X10D is released under the MIT License. See [here](https://github.com/oliverbooth/X10D/blob/main/LICENSE.md) for more details.

View File

@ -1 +0,0 @@
[assembly: CLSCompliant(false)]

View File

@ -1,80 +0,0 @@
using DSharpPlus;
using DSharpPlus.Entities;
namespace X10D.DSharpPlus;
/// <summary>
/// Extension methods for <see cref="DiscordChannel" />.
/// </summary>
public static class DiscordChannelExtensions
{
/// <summary>
/// Gets the category of this channel.
/// </summary>
/// <param name="channel">The channel whose category to retrieve.</param>
/// <returns>
/// The category of <paramref name="channel" />, or <paramref name="channel" /> itself if it is already a category;
/// <see langword="null" /> if this channel is not defined in a category.
/// </returns>
/// <exception cref="ArgumentNullException"><paramref name="channel" /> is <see langword="null" />.</exception>
public static DiscordChannel? GetCategory(this DiscordChannel channel)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(channel);
#else
if (channel is null)
{
throw new ArgumentNullException(nameof(channel));
}
#endif
while (true)
{
if (channel.IsCategory)
{
return channel;
}
if (channel.Parent is not { } parent)
{
return null;
}
channel = parent;
}
}
/// <summary>
/// Normalizes a <see cref="DiscordChannel" /> so that the internal client is assured to be a specified value.
/// </summary>
/// <param name="channel">The <see cref="DiscordChannel" /> to normalize.</param>
/// <param name="client">The target client.</param>
/// <returns>
/// A <see cref="DiscordChannel" /> whose public values will match <paramref name="channel" />, but whose internal client
/// is <paramref name="client" />.
/// </returns>
/// <exception cref="ArgumentNullException">
/// <para><paramref name="channel" /> is <see langword="null" /></para>
/// -or-
/// <para><paramref name="client" /> is <see langword="null" /></para>
/// </exception>
public static async Task<DiscordChannel> NormalizeClientAsync(this DiscordChannel channel, DiscordClient client)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(channel);
ArgumentNullException.ThrowIfNull(client);
#else
if (channel is null)
{
throw new ArgumentNullException(nameof(channel));
}
if (client is null)
{
throw new ArgumentNullException(nameof(client));
}
#endif
return await client.GetChannelAsync(channel.Id).ConfigureAwait(false);
}
}

View File

@ -1,79 +0,0 @@
using DSharpPlus;
using DSharpPlus.Entities;
using DSharpPlus.Exceptions;
namespace X10D.DSharpPlus;
/// <summary>
/// Extension methods for <see cref="DiscordClient" />.
/// </summary>
public static class DiscordClientExtensions
{
/// <summary>
/// Instructs the client to automatically join all existing threads, and any newly-created threads.
/// </summary>
/// <param name="client">The <see cref="DiscordClient" /> whose events should be subscribed.</param>
/// <param name="rejoinIfRemoved">
/// <see langword="true" /> to automatically rejoin a thread if this client was removed; otherwise,
/// <see langword="false" />.
/// </param>
/// <exception cref="ArgumentNullException"><paramref name="client" /> is <see langword="null" />.</exception>
public static void AutoJoinThreads(this DiscordClient client, bool rejoinIfRemoved = true)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(client);
#else
if (client is null)
{
throw new ArgumentNullException(nameof(client));
}
#endif
client.GuildAvailable += (_, args) => args.Guild.JoinAllThreadsAsync();
client.ThreadCreated += (_, args) => args.Thread.JoinThreadAsync();
if (rejoinIfRemoved)
{
client.ThreadMembersUpdated += (_, args) =>
{
if (args.RemovedMembers.Any(m => m.Id == client.CurrentUser.Id))
return args.Thread.JoinThreadAsync();
return Task.CompletedTask;
};
}
}
/// <summary>
/// Gets a user by their ID. If the user is not found, <see langword="null" /> is returned instead of
/// <see cref="NotFoundException" /> being thrown.
/// </summary>
/// <param name="client">The Discord client.</param>
/// <param name="userId">The ID of the user to retrieve.</param>
/// <exception cref="ArgumentNullException"><paramref name="client" /> is <see langword="null" />.</exception>
public static async Task<DiscordUser?> GetUserOrNullAsync(this DiscordClient client, ulong userId)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(client);
#else
if (client is null)
{
throw new ArgumentNullException(nameof(client));
}
#endif
try
{
// we should never use exceptions for flow control but this is D#+ we're talking about.
// NotFoundException isn't even documented, and yet it gets thrown when a user doesn't exist.
// so this method should hopefully clearly express that - and at least using exceptions for flow control *here*,
// removes the need to do the same in consumer code.
// god I hate this.
return await client.GetUserAsync(userId).ConfigureAwait(false);
}
catch (NotFoundException)
{
return null;
}
}
}

View File

@ -1,239 +0,0 @@
using DSharpPlus.Entities;
namespace X10D.DSharpPlus;
/// <summary>
/// Extension methods for <see cref="DiscordEmbedBuilder" />.
/// </summary>
public static class DiscordEmbedBuilderExtensions
{
/// <summary>
/// Adds a field of any value type to the embed.
/// </summary>
/// <param name="builder">The <see cref="DiscordEmbedBuilder" /> to modify.</param>
/// <param name="name">The name of the embed field.</param>
/// <param name="value">The value of the embed field.</param>
/// <param name="inline"><see langword="true" /> to display this field inline; otherwise, <see langword="false" />.</param>
/// <typeparam name="T">The type of <paramref name="value" />.</typeparam>
/// <returns>The current instance of <see cref="DiscordEmbedBuilder" />; that is, <paramref name="builder" />.</returns>
/// <exception cref="ArgumentNullException"><paramref name="builder" /> is <see langword="null" />.</exception>
public static DiscordEmbedBuilder AddField<T>(
this DiscordEmbedBuilder builder,
string name,
T? value,
bool inline = false)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(builder);
#else
if (builder is null)
{
throw new ArgumentNullException(nameof(builder));
}
#endif
return builder.AddField(name, value?.ToString(), inline);
}
/// <summary>
/// Conditionally adds a field to the embed.
/// </summary>
/// <param name="builder">The <see cref="DiscordEmbedBuilder" /> to modify.</param>
/// <param name="condition">The condition whose value is used to determine whether the field will be added.</param>
/// <param name="name">The name of the embed field.</param>
/// <param name="value">The value of the embed field.</param>
/// <param name="inline"><see langword="true" /> to display this field inline; otherwise, <see langword="false" />.</param>
/// <typeparam name="T">The type of <paramref name="value" />.</typeparam>
/// <returns>The current instance of <see cref="DiscordEmbedBuilder" />; that is, <paramref name="builder" />.</returns>
/// <exception cref="ArgumentNullException"><paramref name="builder" /> is <see langword="null" />.</exception>
public static DiscordEmbedBuilder AddFieldIf<T>(
this DiscordEmbedBuilder builder,
bool condition,
string name,
T? value,
bool inline = false)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(builder);
#else
if (builder is null)
{
throw new ArgumentNullException(nameof(builder));
}
#endif
if (condition)
{
builder.AddField(name, value?.ToString(), inline);
}
return builder;
}
/// <summary>
/// Conditionally adds a field to the embed.
/// </summary>
/// <param name="builder">The <see cref="DiscordEmbedBuilder" /> to modify.</param>
/// <param name="predicate">The predicate whose return value is used to determine whether the field will be added.</param>
/// <param name="name">The name of the embed field.</param>
/// <param name="value">The value of the embed field.</param>
/// <param name="inline"><see langword="true" /> to display this field inline; otherwise, <see langword="false" />.</param>
/// <typeparam name="T">The type of <paramref name="value" />.</typeparam>
/// <returns>The current instance of <see cref="DiscordEmbedBuilder" />; that is, <paramref name="builder" />.</returns>
/// <exception cref="ArgumentNullException">
/// <para><paramref name="builder" /> is <see langword="null" />.</para>
/// -or-
/// <para><paramref name="predicate" /> is <see langword="null" />.</para>
/// </exception>
public static DiscordEmbedBuilder AddFieldIf<T>(
this DiscordEmbedBuilder builder,
Func<bool> predicate,
string name,
T? value,
bool inline = false)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(builder);
ArgumentNullException.ThrowIfNull(predicate);
#else
if (builder is null)
{
throw new ArgumentNullException(nameof(builder));
}
if (predicate is null)
{
throw new ArgumentNullException(nameof(predicate));
}
#endif
if (predicate.Invoke())
{
builder.AddField(name, value?.ToString(), inline);
}
return builder;
}
/// <summary>
/// Conditionally adds a field to the embed.
/// </summary>
/// <param name="builder">The <see cref="DiscordEmbedBuilder" /> to modify.</param>
/// <param name="predicate">The predicate whose return value is used to determine whether the field will be added.</param>
/// <param name="name">The name of the embed field.</param>
/// <param name="valueFactory">The delegate whose return value will be used as the value of the embed field.</param>
/// <param name="inline"><see langword="true" /> to display this field inline; otherwise, <see langword="false" />.</param>
/// <typeparam name="T">The return type of <paramref name="valueFactory" />.</typeparam>
/// <returns>The current instance of <see cref="DiscordEmbedBuilder" />; that is, <paramref name="builder" />.</returns>
/// <exception cref="ArgumentNullException">
/// <para><paramref name="builder" /> is <see langword="null" />.</para>
/// -or-
/// <para><paramref name="predicate" /> is <see langword="null" />.</para>
/// -or-
/// <para><paramref name="valueFactory" /> is <see langword="null" />.</para>
/// </exception>
public static DiscordEmbedBuilder AddFieldIf<T>(
this DiscordEmbedBuilder builder,
Func<bool> predicate,
string name,
Func<T?> valueFactory,
bool inline = false)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(builder);
ArgumentNullException.ThrowIfNull(predicate);
ArgumentNullException.ThrowIfNull(valueFactory);
#else
if (builder is null)
{
throw new ArgumentNullException(nameof(builder));
}
if (predicate is null)
{
throw new ArgumentNullException(nameof(predicate));
}
if (valueFactory is null)
{
throw new ArgumentNullException(nameof(valueFactory));
}
#endif
if (predicate.Invoke())
{
builder.AddField(name, valueFactory.Invoke()?.ToString(), inline);
}
return builder;
}
/// <summary>
/// Conditionally adds a field to the embed.
/// </summary>
/// <param name="builder">The <see cref="DiscordEmbedBuilder" /> to modify.</param>
/// <param name="condition">The condition whose value is used to determine whether the field will be added.</param>
/// <param name="name">The name of the embed field.</param>
/// <param name="valueFactory">The delegate whose return value will be used as the value of the embed field.</param>
/// <param name="inline"><see langword="true" /> to display this field inline; otherwise, <see langword="false" />.</param>
/// <typeparam name="T">The return type of <paramref name="valueFactory" />.</typeparam>
/// <returns>The current instance of <see cref="DiscordEmbedBuilder" />; that is, <paramref name="builder" />.</returns>
/// <exception cref="ArgumentNullException">
/// <para><paramref name="builder" /> is <see langword="null" />.</para>
/// -or-
/// <para><paramref name="valueFactory" /> is <see langword="null" />.</para>
/// </exception>
public static DiscordEmbedBuilder AddFieldIf<T>(
this DiscordEmbedBuilder builder,
bool condition,
string name,
Func<T?> valueFactory,
bool inline = false)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(builder);
ArgumentNullException.ThrowIfNull(valueFactory);
#else
if (builder is null)
{
throw new ArgumentNullException(nameof(builder));
}
if (valueFactory is null)
{
throw new ArgumentNullException(nameof(valueFactory));
}
#endif
if (condition)
{
builder.AddField(name, valueFactory.Invoke()?.ToString(), inline);
}
return builder;
}
/// <summary>
/// Sets the embed's author.
/// </summary>
/// <param name="builder">The embed builder to modify.</param>
/// <param name="user">The author.</param>
/// <returns>The current instance of <see cref="DiscordEmbedBuilder" />.</returns>
public static DiscordEmbedBuilder WithAuthor(this DiscordEmbedBuilder builder, DiscordUser user)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(builder);
ArgumentNullException.ThrowIfNull(user);
#else
if (builder is null)
{
throw new ArgumentNullException(nameof(builder));
}
if (user is null)
{
throw new ArgumentNullException(nameof(user));
}
#endif
return builder.WithAuthor(user.GetUsernameWithDiscriminator(), iconUrl: user.AvatarUrl);
}
}

View File

@ -1,97 +0,0 @@
using DSharpPlus;
using DSharpPlus.Entities;
using DSharpPlus.Exceptions;
namespace X10D.DSharpPlus;
/// <summary>
/// Extension methods for <see cref="DiscordGuild" />.
/// </summary>
public static class DiscordGuildExtensions
{
/// <summary>
/// Joins all active threads in the guild that this client has permission to view.
/// </summary>
/// <param name="guild">The guild whose active threads to join.</param>
/// <exception cref="ArgumentNullException"><paramref name="guild" /> is <see langword="null" />.</exception>
public static async Task JoinAllThreadsAsync(this DiscordGuild guild)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(guild);
#else
if (guild is null)
{
throw new ArgumentNullException(nameof(guild));
}
#endif
await Task.WhenAll(guild.Threads.Values.Select(t => t.JoinThreadAsync())).ConfigureAwait(false);
}
/// <summary>
/// Gets a guild member by their ID. If the member is not found, <see langword="null" /> is returned instead of
/// <see cref="NotFoundException" /> being thrown.
/// </summary>
/// <param name="guild">The guild whose member list to search.</param>
/// <param name="userId">The ID of the member to retrieve.</param>
/// <exception cref="ArgumentNullException"><paramref name="guild" /> is <see langword="null" />.</exception>
public static async Task<DiscordMember?> GetMemberOrNullAsync(this DiscordGuild guild, ulong userId)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(guild);
#else
if (guild is null)
{
throw new ArgumentNullException(nameof(guild));
}
#endif
try
{
// we should never use exceptions for flow control but this is D#+ we're talking about.
// NotFoundException isn't even documented, and yet it gets thrown when a member doesn't exist.
// so this method should hopefully clearly express that - and at least using exceptions for flow control *here*,
// removes the need to do the same in consumer code.
// god I hate this.
return await guild.GetMemberAsync(userId).ConfigureAwait(false);
}
catch (NotFoundException)
{
return null;
}
}
/// <summary>
/// Normalizes a <see cref="DiscordGuild" /> so that the internal client is assured to be a specified value.
/// </summary>
/// <param name="guild">The <see cref="DiscordGuild" /> to normalize.</param>
/// <param name="client">The target client.</param>
/// <returns>
/// A <see cref="DiscordGuild" /> whose public values will match <paramref name="guild" />, but whose internal client is
/// <paramref name="client" />.
/// </returns>
/// <exception cref="ArgumentNullException">
/// <para><paramref name="guild" /> is <see langword="null" /></para>
/// -or-
/// <para><paramref name="client" /> is <see langword="null" /></para>
/// </exception>
public static async Task<DiscordGuild> NormalizeClientAsync(this DiscordGuild guild, DiscordClient client)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(guild);
ArgumentNullException.ThrowIfNull(client);
#else
if (guild is null)
{
throw new ArgumentNullException(nameof(guild));
}
if (client is null)
{
throw new ArgumentNullException(nameof(client));
}
#endif
return await client.GetGuildAsync(guild.Id).ConfigureAwait(false);
}
}

View File

@ -1,73 +0,0 @@
using DSharpPlus;
using DSharpPlus.Entities;
namespace X10D.DSharpPlus;
/// <summary>
/// Extension methods for <see cref="DiscordMember" />.
/// </summary>
public static class DiscordMemberExtensions
{
/// <summary>
/// Returns a value indicating whether this member has the specified role.
/// </summary>
/// <param name="member">The member whose roles to search.</param>
/// <param name="role">The role for which to check.</param>
/// <returns>
/// <see langword="true" /> if <paramref name="member" /> has the role; otherwise, <see langword="false" />.
/// </returns>
public static bool HasRole(this DiscordMember member, DiscordRole role)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(member);
ArgumentNullException.ThrowIfNull(role);
#else
if (member is null)
{
throw new ArgumentNullException(nameof(member));
}
if (role is null)
{
throw new ArgumentNullException(nameof(role));
}
#endif
return member.Roles.Contains(role);
}
/// <summary>
/// Normalizes a <see cref="DiscordMember" /> so that the internal client is assured to be a specified value.
/// </summary>
/// <param name="member">The <see cref="DiscordMember" /> to normalize.</param>
/// <param name="client">The target client.</param>
/// <returns>
/// A <see cref="DiscordMember" /> whose public values will match <paramref name="member" />, but whose internal client
/// is <paramref name="client" />.
/// </returns>
/// <exception cref="ArgumentNullException">
/// <para><paramref name="member" /> is <see langword="null" /></para>
/// -or-
/// <para><paramref name="client" /> is <see langword="null" /></para>
/// </exception>
public static async Task<DiscordMember> NormalizeClientAsync(this DiscordMember member, DiscordClient client)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(member);
ArgumentNullException.ThrowIfNull(client);
#else
if (member is null)
{
throw new ArgumentNullException(nameof(member));
}
if (client is null)
{
throw new ArgumentNullException(nameof(client));
}
#endif
DiscordGuild guild = await member.Guild.NormalizeClientAsync(client).ConfigureAwait(false);
return await guild.GetMemberAsync(member.Id).ConfigureAwait(false);
}
}

View File

@ -1,89 +0,0 @@
using DSharpPlus;
using DSharpPlus.Entities;
namespace X10D.DSharpPlus;
/// <summary>
/// Extension methods for <see cref="DiscordMessage" />.
/// </summary>
public static class DiscordMessageExtensions
{
/// <summary>
/// Deletes this message after a specified delay.
/// </summary>
/// <param name="message">The message to delete.</param>
/// <param name="delay">The delay before deletion.</param>
/// <param name="reason">The reason for the deletion.</param>
/// <exception cref="ArgumentNullException"><paramref name="message" /> is <see langword="null" />.</exception>
public static async Task DeleteAfterAsync(this DiscordMessage message, TimeSpan delay, string? reason = null)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(message);
#else
if (message is null)
{
throw new ArgumentNullException(nameof(message));
}
#endif
await Task.Delay(delay).ConfigureAwait(false);
await message.DeleteAsync(reason).ConfigureAwait(false);
}
/// <summary>
/// Deletes the message as created by this task after a specified delay.
/// </summary>
/// <param name="task">The task whose <see cref="DiscordMessage" /> result should be deleted.</param>
/// <param name="delay">The delay before deletion.</param>
/// <param name="reason">The reason for the deletion.</param>
/// <exception cref="ArgumentNullException"><paramref name="task" /> is <see langword="null" />.</exception>
public static async Task DeleteAfterAsync(this Task<DiscordMessage> task, TimeSpan delay, string? reason = null)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(task);
#else
if (task is null)
{
throw new ArgumentNullException(nameof(task));
}
#endif
DiscordMessage message = await task.ConfigureAwait(false);
await message.DeleteAfterAsync(delay, reason).ConfigureAwait(false);
}
/// <summary>
/// Normalizes a <see cref="DiscordMessage" /> so that the internal client is assured to be a specified value.
/// </summary>
/// <param name="message">The <see cref="DiscordMessage" /> to normalize.</param>
/// <param name="client">The target client.</param>
/// <returns>
/// A <see cref="DiscordMessage" /> whose public values will match <paramref name="message" />, but whose internal client
/// is <paramref name="client" />.
/// </returns>
/// <exception cref="ArgumentNullException">
/// <para><paramref name="message" /> is <see langword="null" /></para>
/// -or-
/// <para><paramref name="client" /> is <see langword="null" /></para>
/// </exception>
public static async Task<DiscordMessage> NormalizeClientAsync(this DiscordMessage message, DiscordClient client)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(message);
ArgumentNullException.ThrowIfNull(client);
#else
if (message is null)
{
throw new ArgumentNullException(nameof(message));
}
if (client is null)
{
throw new ArgumentNullException(nameof(client));
}
#endif
DiscordChannel channel = await message.Channel.NormalizeClientAsync(client).ConfigureAwait(false);
return await channel.GetMessageAsync(message.Id).ConfigureAwait(false);
}
}

View File

@ -1,164 +0,0 @@
using DSharpPlus;
using DSharpPlus.Entities;
using DSharpPlus.Exceptions;
namespace X10D.DSharpPlus;
/// <summary>
/// Extension methods for <see cref="DiscordUser" />.
/// </summary>
public static class DiscordUserExtensions
{
/// <summary>
/// Returns the current <see cref="DiscordUser" /> as a member of the specified guild.
/// </summary>
/// <param name="user">The user to transform.</param>
/// <param name="guild">The guild whose member list to search.</param>
/// <returns>
/// A <see cref="DiscordMember" /> whose <see cref="DiscordMember.Guild" /> is equal to <paramref name="guild" />, or
/// <see langword="null" /> if this user is not in the specified <paramref name="guild" />.
/// </returns>
/// <exception cref="ArgumentNullException">
/// <para><paramref name="user" /> is <see langword="null" />.</para>
/// -or-
/// <para><paramref name="guild" /> is <see langword="null" />.</para>
/// </exception>
public static async Task<DiscordMember?> GetAsMemberOfAsync(this DiscordUser user, DiscordGuild guild)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(user);
ArgumentNullException.ThrowIfNull(guild);
#else
if (user is null)
{
throw new ArgumentNullException(nameof(user));
}
if (guild is null)
{
throw new ArgumentNullException(nameof(guild));
}
#endif
if (user is DiscordMember member && member.Guild == guild)
{
return member;
}
if (guild.Members.TryGetValue(user.Id, out member!))
{
return member;
}
try
{
return await guild.GetMemberAsync(user.Id).ConfigureAwait(false);
}
catch (NotFoundException)
{
return null;
}
}
/// <summary>
/// Returns the user's username with the discriminator, in the format <c>username#discriminator</c>.
/// </summary>
/// <param name="user">The user whose username and discriminator to retrieve.</param>
/// <returns>A string in the format <c>username#discriminator</c></returns>
/// <exception cref="ArgumentNullException"><paramref name="user" /> is <see langword="null" />.</exception>
public static string GetUsernameWithDiscriminator(this DiscordUser user)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(user);
#else
if (user is null)
{
throw new ArgumentNullException(nameof(user));
}
#endif
if (user.Discriminator == "0")
{
// user has a new username. see: https://discord.com/blog/usernames
return user.Username;
}
return $"{user.Username}#{user.Discriminator}";
}
/// <summary>
/// Returns a value indicating whether the current user is in the specified guild.
/// </summary>
/// <param name="user">The user to check.</param>
/// <param name="guild">The guild whose member list to search.</param>
/// <returns>
/// <see langword="true" /> if <paramref name="user" /> is a member of <paramref name="guild" />; otherwise,
/// <see langword="false" />.
/// </returns>
public static async Task<bool> IsInGuildAsync(this DiscordUser user, DiscordGuild guild)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(user);
ArgumentNullException.ThrowIfNull(guild);
#else
if (user is null)
{
throw new ArgumentNullException(nameof(user));
}
if (guild is null)
{
throw new ArgumentNullException(nameof(guild));
}
#endif
if (guild.Members.TryGetValue(user.Id, out _))
{
return true;
}
try
{
DiscordMember? member = await guild.GetMemberAsync(user.Id).ConfigureAwait(false);
return member is not null;
}
catch (NotFoundException)
{
return false;
}
}
/// <summary>
/// Normalizes a <see cref="DiscordUser" /> so that the internal client is assured to be a specified value.
/// </summary>
/// <param name="user">The <see cref="DiscordUser" /> to normalize.</param>
/// <param name="client">The target client.</param>
/// <returns>
/// A <see cref="DiscordUser" /> whose public values will match <paramref name="user" />, but whose internal client is
/// <paramref name="client" />.
/// </returns>
/// <exception cref="ArgumentNullException">
/// <para><paramref name="user" /> is <see langword="null" /></para>
/// -or-
/// <para><paramref name="client" /> is <see langword="null" /></para>
/// </exception>
public static async Task<DiscordUser> NormalizeClientAsync(this DiscordUser user, DiscordClient client)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(user);
ArgumentNullException.ThrowIfNull(client);
#else
if (user is null)
{
throw new ArgumentNullException(nameof(user));
}
if (client is null)
{
throw new ArgumentNullException(nameof(client));
}
#endif
return await client.GetUserAsync(user.Id).ConfigureAwait(false);
}
}

View File

@ -1,329 +0,0 @@
using System.Globalization;
namespace X10D.DSharpPlus;
/// <summary>
/// Provides methods for encoding and decoding Discord mention strings.
/// </summary>
/// <remarks>
/// The implementations in this class are designed to resemble <c>MentionUtils</c> as provided by Discord.NET. The source is
/// available
/// <a href="https://github.com/discord-net/Discord.Net/blob/dev/src/Discord.Net.Core/Utils/MentionUtils.cs">
/// here
/// </a>.
/// </remarks>
public static class MentionUtility
{
/// <summary>
/// Returns a channel mention string built from the specified channel ID.
/// </summary>
/// <param name="id">The ID of the channel to mention.</param>
/// <returns>A channel mention string in the format <c>&lt;#123&gt;</c>.</returns>
public static string MentionChannel(decimal id)
{
return $"<#{id:N0}>";
}
/// <summary>
/// Returns a channel mention string built from the specified channel ID.
/// </summary>
/// <param name="id">The ID of the channel to mention.</param>
/// <returns>A channel mention string in the format <c>&lt;#123&gt;</c>.</returns>
[CLSCompliant(false)]
public static string MentionChannel(ulong id)
{
return $"<#{id}>";
}
/// <summary>
/// Returns a role mention string built from the specified channel ID.
/// </summary>
/// <param name="id">The ID of the role to mention.</param>
/// <returns>A role mention string in the format <c>&lt;@&amp;123&gt;</c>.</returns>
public static string MentionRole(decimal id)
{
return $"<@&{id:N0}>";
}
/// <summary>
/// Returns a role mention string built from the specified role ID.
/// </summary>
/// <param name="id">The ID of the role to mention.</param>
/// <returns>A role mention string in the format <c>&lt;@&amp;123&gt;</c>.</returns>
[CLSCompliant(false)]
public static string MentionRole(ulong id)
{
return $"<@&{id}>";
}
/// <summary>
/// Returns a user mention string built from the specified user ID.
/// </summary>
/// <param name="id">The ID of the user to mention.</param>
/// <returns>A user mention string in the format <c>&lt;@123&gt;</c>.</returns>
[CLSCompliant(false)]
public static string MentionUser(decimal id)
{
return MentionUser(id, false);
}
/// <summary>
/// Returns a user mention string built from the specified user ID.
/// </summary>
/// <param name="id">The ID of the user to mention.</param>
/// <param name="nickname">
/// <see langword="true" /> if the mention string should account for nicknames; otherwise, <see langword="false" />.
/// </param>
/// <returns>
/// A user mention string in the format <c>&lt;@!123&gt;</c> if <paramref name="nickname" /> is <see langword="true" />,
/// or in the format <c>&lt;@123&gt;</c> if <paramref name="nickname" /> is <see langword="false" />.
/// </returns>
[CLSCompliant(false)]
public static string MentionUser(decimal id, bool nickname)
{
return nickname ? $"<@!{id:N0}>" : $"<@{id:N0}>";
}
/// <summary>
/// Returns a user mention string built from the specified user ID.
/// </summary>
/// <param name="id">The ID of the user to mention.</param>
/// <returns>A user mention string in the format <c>&lt;@123&gt;</c>.</returns>
[CLSCompliant(false)]
public static string MentionUser(ulong id)
{
return MentionUser(id, false);
}
/// <summary>
/// Returns a user mention string built from the specified user ID.
/// </summary>
/// <param name="id">The ID of the user to mention.</param>
/// <param name="nickname">
/// <see langword="true" /> if the mention string should account for nicknames; otherwise, <see langword="false" />.
/// </param>
/// <returns>
/// A user mention string in the format <c>&lt;@!123&gt;</c> if <paramref name="nickname" /> is <see langword="true" />,
/// or in the format <c>&lt;@123&gt;</c> if <paramref name="nickname" /> is <see langword="false" />.
/// </returns>
[CLSCompliant(false)]
public static string MentionUser(ulong id, bool nickname)
{
return nickname ? $"<@!{id}>" : $"<@{id}>";
}
/// <summary>
/// Parses a provided channel mention string to a decimal value representing the channel ID. A return value indicates
/// whether the parse succeeded.
/// </summary>
/// <param name="value">A string containing a mention string to parse, in the format <c>&lt;#123&gt;</c>.</param>
/// <param name="result">
/// When this method returns, contains the decimal value representing the channel ID contained within
/// <paramref name="value" />, if the conversion succeeded, or zero if the conversion failed. The conversion fails if the
/// <paramref name="value" /> parameter is <see langword="null" /> or <see cref="string.Empty" />, is not of the correct
/// format, or represents a number less than <see cref="ulong.MinValue" /> or greater than <see cref="ulong.MaxValue" />.
/// </param>
/// <returns><see langword="true" /> if the parse was successful; otherwise, <see langword="false" />.</returns>
public static bool TryParseChannel(string? value, out decimal result)
{
result = 0;
if (string.IsNullOrWhiteSpace(value))
{
return false;
}
if (value.Length < 3 || value[0] != '<' || value[1] != '#' || value[^1] != '>')
{
return false;
}
value = value.Substring(2, value.Length - 3); // <#123>
if (!ulong.TryParse(value, NumberStyles.None, CultureInfo.InvariantCulture, out ulong actual))
{
return false;
}
result = actual;
return true;
}
/// <summary>
/// Parses a provided channel mention string to a 64-bit unsigned integer representing the channel ID. A return value
/// indicates whether the parse succeeded.
/// </summary>
/// <param name="value">A string containing a mention string to parse, in the format <c>&lt;#123&gt;</c>.</param>
/// <param name="result">
/// When this method returns, contains the 64-bit unsigned integer value representing the channel ID contained within
/// <paramref name="value" />, if the conversion succeeded, or zero if the conversion failed. The conversion fails if the
/// <paramref name="value" /> parameter is <see langword="null" /> or <see cref="string.Empty" />, is not of the correct
/// format, or represents a number less than <see cref="ulong.MinValue" /> or greater than <see cref="ulong.MaxValue" />.
/// </param>
/// <returns><see langword="true" /> if the parse was successful; otherwise, <see langword="false" />.</returns>
[CLSCompliant(false)]
public static bool TryParseChannel(string? value, out ulong result)
{
result = 0;
if (string.IsNullOrWhiteSpace(value))
{
return false;
}
if (value.Length < 3 || value[0] != '<' || value[1] != '#' || value[^1] != '>')
{
return false;
}
value = value.Substring(2, value.Length - 3); // <#123>
return ulong.TryParse(value, NumberStyles.None, CultureInfo.InvariantCulture, out result);
}
/// <summary>
/// Parses a provided role mention string to a decimal value representing the role ID. A return value indicates whether
/// the parse succeeded.
/// </summary>
/// <param name="value">A string containing a mention string to parse, in the format <c>&lt;@&amp;123&gt;</c>.</param>
/// <param name="result">
/// When this method returns, contains the decimal value representing the role ID contained within
/// <paramref name="value" />, if the conversion succeeded, or zero if the conversion failed. The conversion fails if the
/// <paramref name="value" /> parameter is <see langword="null" /> or <see cref="string.Empty" />, is not of the correct
/// format, or represents a number less than <see cref="ulong.MinValue" /> or greater than <see cref="ulong.MaxValue" />.
/// </param>
/// <returns><see langword="true" /> if the parse was successful; otherwise, <see langword="false" />.</returns>
public static bool TryParseRole(string? value, out decimal result)
{
result = 0;
if (string.IsNullOrWhiteSpace(value))
{
return false;
}
if (value.Length < 4 || value[0] != '<' || value[1] != '@' || value[2] != '&' || value[^1] != '>')
{
return false;
}
value = value.Substring(3, value.Length - 4); // <@&123>
if (!ulong.TryParse(value, NumberStyles.None, CultureInfo.InvariantCulture, out ulong actual))
{
return false;
}
result = actual;
return true;
}
/// <summary>
/// Parses a provided role mention string to a 64-bit unsigned integer representing the role ID. A return value indicates
/// whether the parse succeeded.
/// </summary>
/// <param name="value">A string containing a mention string to parse, in the format <c>&lt;@&amp;123&gt;</c>.</param>
/// <param name="result">
/// When this method returns, contains the 64-bit unsigned integer value representing the role ID contained within
/// <paramref name="value" />, if the conversion succeeded, or zero if the conversion failed. The conversion fails if the
/// <paramref name="value" /> parameter is <see langword="null" /> or <see cref="string.Empty" />, is not of the correct
/// format, or represents a number less than <see cref="ulong.MinValue" /> or greater than <see cref="ulong.MaxValue" />.
/// </param>
/// <returns><see langword="true" /> if the parse was successful; otherwise, <see langword="false" />.</returns>
[CLSCompliant(false)]
public static bool TryParseRole(string? value, out ulong result)
{
result = 0;
if (string.IsNullOrWhiteSpace(value))
{
return false;
}
if (value.Length < 4 || value[0] != '<' || value[1] != '@' || value[2] != '&' || value[^1] != '>')
{
return false;
}
value = value.Substring(3, value.Length - 4); // <@&123>
return ulong.TryParse(value, NumberStyles.None, CultureInfo.InvariantCulture, out result);
}
/// <summary>
/// Parses a provided user mention string to a decimal value representing the user ID. A return value indicates whether
/// the parse succeeded.
/// </summary>
/// <param name="value">
/// A string containing a mention string to parse, in the format <c>&lt;@123&gt;</c> or <c>&lt;@!123&gt;</c>.
/// </param>
/// <param name="result">
/// When this method returns, contains the decimal value representing the user ID contained within
/// <paramref name="value" />, if the conversion succeeded, or zero if the conversion failed. The conversion fails if the
/// <paramref name="value" /> parameter is <see langword="null" /> or <see cref="string.Empty" />, is not of the correct
/// format, or represents a number less than <see cref="ulong.MinValue" /> or greater than <see cref="ulong.MaxValue" />.
/// </param>
/// <returns><see langword="true" /> if the parse was successful; otherwise, <see langword="false" />.</returns>
public static bool TryParseUser(string? value, out decimal result)
{
result = 0;
if (string.IsNullOrWhiteSpace(value))
{
return false;
}
if (value.Length < 3 || value[0] != '<' || value[1] != '@' || value[^1] != '>')
{
return false;
}
if (value.Length >= 4 && value[2] == '!')
{
value = value.Substring(3, value.Length - 4); // <@!123>
}
else
{
value = value.Substring(2, value.Length - 3); // <@123>
}
if (!ulong.TryParse(value, NumberStyles.None, CultureInfo.InvariantCulture, out ulong actual))
{
return false;
}
result = actual;
return true;
}
/// <summary>
/// Parses a provided user mention string to a 64-bit unsigned integer representing the user ID. A return value indicates
/// whether the parse succeeded.
/// </summary>
/// <param name="value">
/// A string containing a mention string to parse, in the format <c>&lt;@123&gt;</c> or <c>&lt;@!123&gt;</c>.
/// </param>
/// <param name="result">
/// When this method returns, contains the 64-bit unsigned integer value representing the user ID contained within
/// <paramref name="value" />, if the conversion succeeded, or zero if the conversion failed. The conversion fails if the
/// <paramref name="value" /> parameter is <see langword="null" /> or <see cref="string.Empty" />, is not of the correct
/// format, or represents a number less than <see cref="ulong.MinValue" /> or greater than <see cref="ulong.MaxValue" />.
/// </param>
/// <returns><see langword="true" /> if the parse was successful; otherwise, <see langword="false" />.</returns>
[CLSCompliant(false)]
public static bool TryParseUser(string? value, out ulong result)
{
result = 0;
if (string.IsNullOrWhiteSpace(value))
{
return false;
}
if (value.Length < 3 || value[0] != '<' || value[1] != '@' || value[^1] != '>')
{
return false;
}
if (value.Length >= 4 && value[2] == '!')
{
value = value.Substring(3, value.Length - 4); // <@!123>
}
else
{
value = value.Substring(2, value.Length - 3); // <@123>
}
return ulong.TryParse(value, NumberStyles.None, CultureInfo.InvariantCulture, out result);
}
}

View File

@ -1,69 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net7.0;net6.0;netstandard2.1</TargetFrameworks>
<LangVersion>11.0</LangVersion>
<Optimize>true</Optimize>
<ImplicitUsings>true</ImplicitUsings>
<Authors>Oliver Booth</Authors>
<NeutralLanguage>en</NeutralLanguage>
<RepositoryUrl>https://github.com/oliverbooth/X10D</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<Description>Extension methods on crack.</Description>
<PackageLicenseFile>LICENSE.md</PackageLicenseFile>
<PackageIcon>branding_Icon.png</PackageIcon>
<PackageIconUrl/>
<PackageTags>dotnet extension-methods</PackageTags>
<PackageReleaseNotes>$([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)/../CHANGELOG.md"))</PackageReleaseNotes>
<CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>
<VersionPrefix>3.3.1</VersionPrefix>
<Nullable>enable</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<EnableNETAnalyzers>true</EnableNETAnalyzers>
<DebugType>pdbonly</DebugType>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<PropertyGroup Condition="'$(GITHUB_ACTIONS)' == 'true'">
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
</PropertyGroup>
<PropertyGroup Condition="'$(VersionSuffix)' != '' And '$(BuildNumber)' == ''">
<Version>$(VersionPrefix)-$(VersionSuffix)</Version>
<AssemblyVersion>$(VersionPrefix).0</AssemblyVersion>
<FileVersion>$(VersionPrefix).0</FileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(VersionSuffix)' != '' And '$(BuildNumber)' != ''">
<Version>$(VersionPrefix)-$(VersionSuffix).$(BuildNumber)</Version>
<AssemblyVersion>$(VersionPrefix).$(BuildNumber)</AssemblyVersion>
<FileVersion>$(VersionPrefix).$(BuildNumber)</FileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(VersionSuffix)' == ''">
<Version>$(VersionPrefix)</Version>
<AssemblyVersion>$(VersionPrefix).0</AssemblyVersion>
<FileVersion>$(VersionPrefix).0</FileVersion>
<TargetFrameworks>net8.0;net6.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="7.0.0"/>
</ItemGroup>
<ItemGroup>
<None Include="..\branding_Icon.png">
<Pack>True</Pack>
<PackagePath/>
</None>
<None Include="..\LICENSE.md">
<Pack>True</Pack>
<PackagePath/>
</None>
<None Include="..\CHANGELOG.md">
<Pack>True</Pack>
<PackagePath/>
</None>
</ItemGroup>
</Project>

View File

@ -1 +1 @@
[assembly: CLSCompliant(true)]
[assembly: CLSCompliant(true)]

View File

@ -1,4 +1,4 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace X10D.Hosting.DependencyInjection;

View File

@ -1,4 +1,4 @@
2
2
3
5
7

View File

@ -1,13 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net7.0;net6.0;netcoreapp3.1</TargetFrameworks>
<LangVersion>11.0</LangVersion>
<TargetFrameworks>net8.0;net6.0</TargetFrameworks>
<IsPackable>false</IsPackable>
<Nullable>enable</Nullable>
<ImplicitUsings>true</ImplicitUsings>
<CoverletOutputFormat>json,cobertura</CoverletOutputFormat>
<IsTestProject>true</IsTestProject>
<CoverletOutputFormat>xml,cobertura</CoverletOutputFormat>
<CollectCoverage>true</CollectCoverage>
<CodeAnalysisTreatWarningsAsErrors>false</CodeAnalysisTreatWarningsAsErrors>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)' == 'netcoreapp3.1'">
@ -15,14 +14,14 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.1"/>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0"/>
<PackageReference Include="NSubstitute" Version="5.0.0"/>
<PackageReference Include="NUnit" Version="3.13.3"/>
<PackageReference Include="NUnit3TestAdapter" Version="4.4.2"/>
<PackageReference Include="NUnit.Analyzers" Version="3.6.1"/>
<PackageReference Include="coverlet.collector" Version="3.2.0"/>
<PackageReference Include="System.Reactive" Version="5.0.0"/>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0"/>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0"/>
<PackageReference Include="NSubstitute" Version="5.1.0"/>
<PackageReference Include="NUnit" Version="3.14.0"/>
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0"/>
<PackageReference Include="NUnit.Analyzers" Version="3.9.0"/>
<PackageReference Include="coverlet.collector" Version="6.0.0"/>
<PackageReference Include="System.Reactive" Version="6.0.0"/>
</ItemGroup>
<ItemGroup>

View File

@ -1 +1 @@
[assembly: CLSCompliant(true)]
[assembly: CLSCompliant(false)]

View File

@ -1,12 +1,12 @@
using NUnit.Framework;
using NUnit.Framework;
using X10D.Collections;
namespace X10D.Tests.Collections;
public partial class ArrayTests
internal static partial class ArrayTests
{
[TestFixture]
public class AsReadOnlyTests
internal class AsReadOnlyTests
{
[Test]
public void AsReadOnly_ShouldReturnReadOnlyCollection_WhenArrayIsNotNull()

View File

@ -1,9 +1,9 @@
using NUnit.Framework;
using NUnit.Framework;
using X10D.Collections;
namespace X10D.Tests.Collections;
public partial class ArrayTests
internal static partial class ArrayTests
{
[TestFixture]
public class ClearTests

View File

@ -1,8 +1,8 @@
using NUnit.Framework;
using NUnit.Framework;
namespace X10D.Tests.Collections;
[TestFixture]
public partial class ArrayTests
internal static partial class ArrayTests
{
}

View File

@ -1,10 +1,10 @@
using NUnit.Framework;
using NUnit.Framework;
using X10D.Collections;
namespace X10D.Tests.Collections;
[TestFixture]
public class BoolListTests
internal class BoolListTests
{
[Test]
public void PackByte_Should_Pack_Correctly()

View File

@ -1,11 +1,11 @@
using System.Runtime.Intrinsics.X86;
using System.Runtime.Intrinsics.X86;
using NUnit.Framework;
using X10D.Collections;
namespace X10D.Tests.Collections;
[TestFixture]
public class ByteTests
internal class ByteTests
{
[Test]
public void Unpack_ShouldUnpackToArrayCorrectly()
@ -47,7 +47,6 @@ public class ByteTests
});
}
#if NET5_0_OR_GREATER
[Test]
public void UnpackInternal_Fallback_ShouldUnpackToSpanCorrectly()
{
@ -92,7 +91,6 @@ public class ByteTests
Assert.That(bits[7], Is.True);
});
}
#endif
[Test]
public void Unpack_ShouldRepackEqually()

View File

@ -1,11 +1,11 @@
using System.Collections.ObjectModel;
using System.Collections.ObjectModel;
using NSubstitute;
using NUnit.Framework;
using X10D.Collections;
namespace X10D.Tests.Collections;
public partial class CollectionTests
internal partial class CollectionTests
{
[TestFixture]
public class ClearAndDisposeAllTests

View File

@ -1,11 +1,11 @@
using System.Collections.ObjectModel;
using System.Collections.ObjectModel;
using NSubstitute;
using NUnit.Framework;
using X10D.Collections;
namespace X10D.Tests.Collections;
public partial class CollectionTests
internal partial class CollectionTests
{
[TestFixture]
public class ClearAndDisposeAllAsyncTests

View File

@ -1,8 +1,8 @@
using NUnit.Framework;
using NUnit.Framework;
namespace X10D.Tests.Collections;
[TestFixture]
public partial class CollectionTests
internal partial class CollectionTests
{
}

View File

@ -1,10 +1,10 @@
using NUnit.Framework;
using NUnit.Framework;
using X10D.Collections;
namespace X10D.Tests.Collections;
[TestFixture]
public class DictionaryTests
internal class DictionaryTests
{
[Test]
public void AddOrUpdate_ShouldAddNewKey_IfNotExists_GivenConcreteDictionary()

View File

@ -1,10 +1,10 @@
using NSubstitute;
using NSubstitute;
using NUnit.Framework;
using X10D.Collections;
namespace X10D.Tests.Collections;
public partial class EnumerableTests
internal partial class EnumerableTests
{
[TestFixture]
public class DisposeAllTests

View File

@ -1,10 +1,10 @@
using NSubstitute;
using NSubstitute;
using NUnit.Framework;
using X10D.Collections;
namespace X10D.Tests.Collections;
public partial class EnumerableTests
internal partial class EnumerableTests
{
[TestFixture]
public class DisposeAllAsyncTests

View File

@ -1,11 +1,11 @@
using NUnit.Framework;
using NUnit.Framework;
using X10D.Collections;
using X10D.Core;
namespace X10D.Tests.Collections;
[TestFixture]
public partial class EnumerableTests
internal partial class EnumerableTests
{
[Test]
public void CountWhereNot_ShouldReturnCorrectCount_GivenSequence()

View File

@ -1,11 +1,11 @@
using System.Runtime.Intrinsics.X86;
using System.Runtime.Intrinsics.X86;
using NUnit.Framework;
using X10D.Collections;
namespace X10D.Tests.Collections;
[TestFixture]
public class Int16Tests
internal class Int16Tests
{
[Test]
public void Unpack_ShouldUnpackToArrayCorrectly()
@ -82,7 +82,6 @@ public class Int16Tests
});
}
#if NET5_0_OR_GREATER
[Test]
public void UnpackInternal_Ssse3_ShouldUnpackToSpanCorrectly()
{
@ -113,7 +112,6 @@ public class Int16Tests
}
});
}
#endif
[Test]
public void Unpack_ShouldRepackEqually()

View File

@ -1,11 +1,11 @@
using System.Runtime.Intrinsics.X86;
using System.Runtime.Intrinsics.X86;
using NUnit.Framework;
using X10D.Collections;
namespace X10D.Tests.Collections;
[TestFixture]
public class Int32Tests
internal class Int32Tests
{
[Test]
public void Unpack_ShouldUnpackToArrayCorrectly()
@ -83,7 +83,6 @@ public class Int32Tests
});
}
#if NET5_0_OR_GREATER
[Test]
public void UnpackInternal_Ssse3_ShouldUnpackToSpanCorrectly()
{
@ -143,7 +142,6 @@ public class Int32Tests
}
});
}
#endif
[Test]
public void Unpack_ShouldRepackEqually()

View File

@ -1,11 +1,12 @@
using System.Diagnostics;
using System.Diagnostics;
using System.Globalization;
using NUnit.Framework;
using X10D.Collections;
namespace X10D.Tests.Collections;
[TestFixture]
public class Int64Tests
internal class Int64Tests
{
[Test]
public void UnpackBits_ShouldUnpackToArrayCorrectly()
@ -29,7 +30,7 @@ public class Int64Tests
for (var index = 8; index < 64; index++)
{
Assert.That(bits[index], Is.False, index.ToString());
Assert.That(bits[index], Is.False, index.ToString(CultureInfo.InvariantCulture));
}
});
}
@ -53,7 +54,7 @@ public class Int64Tests
for (var index = 8; index < 64; index++)
{
Assert.That(bits[index], Is.False, index.ToString());
Assert.That(bits[index], Is.False, index.ToString(CultureInfo.InvariantCulture));
}
});
}

View File

@ -1,13 +1,12 @@
using NUnit.Framework;
using NUnit.Framework;
using X10D.Collections;
namespace X10D.Tests.Collections;
[TestFixture]
public class ListTests
internal class ListTests
{
[CLSCompliant(false)]
[Test]
[Test]
[TestCase(1)]
[TestCase(1, 2, 3)]
[TestCase(1, 2, 3, 4, 5)]
@ -26,8 +25,7 @@ public class ListTests
CollectionAssert.AreEqual(all42, list);
}
[CLSCompliant(false)]
[Test]
[Test]
[TestCase(1)]
[TestCase(1, 2, 3)]
[TestCase(1, 2, 3, 4, 5)]
@ -177,9 +175,9 @@ public class ListTests
}
[Test]
public void RemoveRange_ShouldThrowArgumentException_GivenEndIndexLessThanStart()
public void RemoveRange_ShouldThrowArgumentOutOfRangeException_GivenEndIndexLessThanStart()
{
Assert.Throws<ArgumentException>(() => new List<int>().RemoveRange(2..0));
Assert.Throws<ArgumentOutOfRangeException>(() => new List<int>().RemoveRange(2..0));
}
[Test]

View File

@ -1,10 +1,10 @@
using NUnit.Framework;
using NUnit.Framework;
using X10D.Collections;
namespace X10D.Tests.Collections;
[TestFixture]
public class SpanTest
internal class SpanTest
{
[Test]
public void Count_ShouldReturn0_GivenEmptySpan()

View File

@ -1,10 +1,10 @@
using NUnit.Framework;
using NUnit.Framework;
using X10D.Core;
namespace X10D.Tests.Core;
[TestFixture]
public class CoreTests
internal class CoreTests
{
[Test]
[TestCase(1)]

View File

@ -1,10 +1,10 @@
using NUnit.Framework;
using NUnit.Framework;
using X10D.Core;
namespace X10D.Tests.Core;
[TestFixture]
public class EnumTests
internal class EnumTests
{
// Microsoft wrongfully decided to have Sunday be 0, Monday be 1, etc.
// I personally hate this, Sunday is not the first day of the week.

View File

@ -1,4 +1,3 @@
#if NET6_0_OR_GREATER
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.X86;
using NUnit.Framework;
@ -7,7 +6,7 @@ using X10D.Core;
namespace X10D.Tests.Core;
[TestFixture]
public class IntrinsicTests
internal class IntrinsicTests
{
[Test]
public void CorrectBoolean_ShouldReturnExpectedVector64Result_GivenInputVector()
@ -223,4 +222,3 @@ public class IntrinsicTests
Assert.That(result, Is.EqualTo(expectedResult));
}
}
#endif

View File

@ -1,10 +1,10 @@
using NUnit.Framework;
using NUnit.Framework;
using X10D.Core;
namespace X10D.Tests.Core;
[TestFixture]
public class NullableTests
internal class NullableTests
{
[Test]
public void TryGetValue_ShouldBeTrue_GivenValue()

View File

@ -1,11 +1,11 @@
using NUnit.Framework;
using NUnit.Framework;
using X10D.Collections;
using X10D.Core;
namespace X10D.Tests.Core;
[TestFixture]
public class RandomTests
internal class RandomTests
{
[Test]
public void NextBoolean_ShouldBeFalse_GivenSeed1234()

View File

@ -0,0 +1,66 @@
using NUnit.Framework;
using X10D.Core;
namespace X10D.Tests.Core;
[TestFixture]
internal class RangeTests
{
[Test]
public void Range_GetEnumerator_ShouldReturnRangeEnumerator()
{
Assert.Multiple(() =>
{
Assert.That(5..10, Is.TypeOf<Range>());
Assert.That((5..10).GetEnumerator(), Is.TypeOf<RangeEnumerator>());
});
}
[Test]
public void Loop_OverRange0To10_ShouldCountFrom0To10Inclusive()
{
int value = 0;
foreach (int i in 0..10)
{
Assert.That(i, Is.EqualTo(value));
value++;
}
}
[Test]
public void Loop_OverRangeNegative5To5_ShouldCountFromNegative5To5Inclusive()
{
int value = -5;
foreach (int i in ^5..5)
{
Assert.That(i, Is.EqualTo(value));
value++;
}
}
[Test]
public void Loop_OverRange5ToNegative5_ShouldCountFrom5ToNegative5Inclusive()
{
int value = 5;
foreach (int i in 5..^5)
{
Assert.That(i, Is.EqualTo(value));
value--;
}
}
[Test]
public void Loop_OverRange10To0_ShouldCountFrom10To0Inclusive()
{
int value = 10;
foreach (int i in 10..0)
{
Assert.That(i, Is.EqualTo(value));
value--;
}
}
}

View File

@ -1,14 +1,12 @@
#if NET5_0_OR_GREATER
using System.Runtime.Intrinsics.Arm;
using System.Runtime.Intrinsics.X86;
#endif
using NUnit.Framework;
using X10D.Core;
namespace X10D.Tests.Core;
[TestFixture]
public class SpanTest
internal class SpanTest
{
[Test]
public void Contains_ShouldReturnFalse_GivenReadOnlySpanWithNoMatchingElements_UsingByteEnum()
@ -209,7 +207,6 @@ public class SpanTest
Assert.That(actual, Is.EqualTo(expected));
}
#if NET5_0_OR_GREATER
[Test]
public void PackByteInternal_Sse2_ShouldReturnCorrectByte_GivenReadOnlySpan_Using()
{
@ -226,23 +223,6 @@ public class SpanTest
Assert.That(actual, Is.EqualTo(expected));
}
[Test]
public void PackByteInternal_AdvSimd_ShouldReturnCorrectByte_GivenReadOnlySpan_Using()
{
if (!AdvSimd.IsSupported)
{
return;
}
const byte expected = 0b00110011;
ReadOnlySpan<bool> span = stackalloc bool[8] {true, true, false, false, true, true, false, false};
byte actual = span.PackByteInternal_AdvSimd();
Assert.That(actual, Is.EqualTo(expected));
}
#endif
[Test]
public void PackInt16_ShouldReturnSameAsPackByte_WhenSpanHasLength8()
{
@ -268,7 +248,6 @@ public class SpanTest
Assert.That(actual, Is.EqualTo(expected));
}
#if NET5_0_OR_GREATER
[Test]
public void PackInt16Internal_Sse2_ShouldReturnCorrectInt16_GivenReadOnlySpan_Using()
{
@ -287,7 +266,6 @@ public class SpanTest
Assert.That(actual, Is.EqualTo(expected));
}
#endif
[Test]
public void PackInt32Internal_Fallback_ShouldReturnCorrectInt32_GivenReadOnlySpan()
@ -304,7 +282,6 @@ public class SpanTest
Assert.That(actual, Is.EqualTo(expected));
}
#if NET5_0_OR_GREATER
[Test]
public void PackInt32Internal_Sse2_ShouldReturnCorrectInt32_GivenReadOnlySpan()
{
@ -345,27 +322,6 @@ public class SpanTest
Assert.That(actual, Is.EqualTo(expected));
}
[Test]
public void PackInt32Internal_AdvSimd_ShouldReturnCorrectInt32_GivenReadOnlySpan()
{
if (!AdvSimd.IsSupported)
{
return;
}
const int expected = 0b01010101_10101010_01010101_10101010;
ReadOnlySpan<bool> span = stackalloc bool[32]
{
false, true, false, true, false, true, false, true, true, false, true, false, true, false, true, false, false,
true, false, true, false, true, false, true, true, false, true, false, true, false, true, false,
};
int actual = span.PackInt32Internal_AdvSimd();
Assert.That(actual, Is.EqualTo(expected));
}
#endif
[Test]
public void PackInt32_ShouldReturnSameAsPackByte_WhenSpanHasLength8_UsingReadOnlySpan()
{

View File

@ -1,11 +1,11 @@
using System.Drawing;
using System.Drawing;
using NUnit.Framework;
using X10D.Drawing;
namespace X10D.Tests.Drawing;
[TestFixture]
public class CircleFTests
internal class CircleFTests
{
[Test]
public void Area_ShouldBePiRadiusRadius_GivenUnitCircle()

View File

@ -1,10 +1,10 @@
using NUnit.Framework;
using NUnit.Framework;
using X10D.Drawing;
namespace X10D.Tests.Drawing;
[TestFixture]
public class CircleTests
internal class CircleTests
{
[Test]
public void Area_ShouldBePiRadiusRadius_GivenUnitCircle()

View File

@ -1,11 +1,11 @@
using System.Drawing;
using System.Drawing;
using NUnit.Framework;
using X10D.Drawing;
namespace X10D.Tests.Drawing;
[TestFixture]
public class ColorTests
internal class ColorTests
{
private static readonly Color Black = Color.FromArgb(0, 0, 0);
private static readonly Color White = Color.FromArgb(255, 255, 255);
@ -207,9 +207,7 @@ public class ColorTests
Assert.That(Color.Plum.GetClosestConsoleColor(), Is.EqualTo(ConsoleColor.DarkGray));
Assert.That(Color.PowderBlue.GetClosestConsoleColor(), Is.EqualTo(ConsoleColor.DarkGray));
Assert.That(Color.Purple.GetClosestConsoleColor(), Is.EqualTo(ConsoleColor.DarkMagenta));
#if NET6_0_OR_GREATER
Assert.That(Color.RebeccaPurple.GetClosestConsoleColor(), Is.EqualTo(ConsoleColor.DarkMagenta));
#endif
Assert.That(Color.Red.GetClosestConsoleColor(), Is.EqualTo(ConsoleColor.Red));
Assert.That(Color.RosyBrown.GetClosestConsoleColor(), Is.EqualTo(ConsoleColor.DarkGray));
Assert.That(Color.RoyalBlue.GetClosestConsoleColor(), Is.EqualTo(ConsoleColor.DarkCyan));

View File

@ -1,11 +1,11 @@
using System.Numerics;
using System.Numerics;
using NUnit.Framework;
using X10D.Drawing;
namespace X10D.Tests.Drawing;
[TestFixture]
public class CuboidTests
internal class CuboidTests
{
[Test]
public void Corners_ShouldBeCorrect_GivenCubeOfSize1()

View File

@ -1,4 +1,4 @@
using System.Drawing;
using System.Drawing;
using System.Numerics;
using NUnit.Framework;
using X10D.Drawing;
@ -6,7 +6,7 @@ using X10D.Drawing;
namespace X10D.Tests.Drawing;
[TestFixture]
public class EllipseFTests
internal class EllipseFTests
{
[Test]
public void Area_ShouldBePiRadiusRadius_GivenUnitEllipse()

View File

@ -1,11 +1,11 @@
using System.Drawing;
using System.Drawing;
using NUnit.Framework;
using X10D.Drawing;
namespace X10D.Tests.Drawing;
[TestFixture]
public class EllipseTests
internal class EllipseTests
{
[Test]
public void Area_ShouldBePiRadiusRadius_GivenUnitEllipse()

View File

@ -1,4 +1,4 @@
using System.Drawing;
using System.Drawing;
using System.Numerics;
using NUnit.Framework;
using X10D.Drawing;
@ -6,7 +6,7 @@ using X10D.Drawing;
namespace X10D.Tests.Drawing;
[TestFixture]
public class Line3DTests
internal class Line3DTests
{
[Test]
public void CompareTo_ShouldBeNegativeOne_GivenEmptyAndOne()

View File

@ -1,11 +1,11 @@
using System.Drawing;
using System.Drawing;
using NUnit.Framework;
using X10D.Drawing;
namespace X10D.Tests.Drawing;
[TestFixture]
public class LineFTests
internal class LineFTests
{
[Test]
public void CompareTo_ShouldBeNegativeOne_GivenEmptyAndOne()

View File

@ -1,10 +1,10 @@
using NUnit.Framework;
using NUnit.Framework;
using X10D.Drawing;
namespace X10D.Tests.Drawing;
[TestFixture]
public class LineTests
internal class LineTests
{
[Test]
public void CompareTo_ShouldBeNegativeOne_GivenEmptyAndOne()

View File

@ -1,4 +1,4 @@
using System.Drawing;
using System.Drawing;
using NUnit.Framework;
#if !NET6_0_OR_GREATER
using X10D.Core;
@ -8,7 +8,7 @@ using X10D.Drawing;
namespace X10D.Tests.Drawing;
[TestFixture]
public class PointFTests
internal class PointFTests
{
[Test]
public void IsOnLine_ShouldReturnTrue_GivenPointOnLine()

View File

@ -1,11 +1,11 @@
using System.Drawing;
using System.Drawing;
using NUnit.Framework;
using X10D.Drawing;
namespace X10D.Tests.Drawing;
[TestFixture]
public class PointTests
internal class PointTests
{
[Test]
public void IsOnLine_ShouldReturnTrue_GivenPointOnLine()

View File

@ -1,4 +1,4 @@
using System.Drawing;
using System.Drawing;
using System.Numerics;
using NUnit.Framework;
using X10D.Drawing;
@ -6,7 +6,7 @@ using X10D.Drawing;
namespace X10D.Tests.Drawing;
[TestFixture]
public class PolygonFTests
internal class PolygonFTests
{
[Test]
public void AddVertices_ShouldAddVertices()

View File

@ -1,11 +1,11 @@
using System.Drawing;
using System.Drawing;
using NUnit.Framework;
using X10D.Drawing;
namespace X10D.Tests.Drawing;
[TestFixture]
public class PolygonTests
internal class PolygonTests
{
[Test]
public void AddVertices_ShouldAddVertices()

View File

@ -1,11 +1,11 @@
using System.Numerics;
using System.Numerics;
using NUnit.Framework;
using X10D.Drawing;
namespace X10D.Tests.Drawing;
[TestFixture]
public class PolyhedronTests
internal class PolyhedronTests
{
[Test]
public void AddVertices_ShouldAddVertices()

View File

@ -1,11 +1,11 @@
using System.Drawing;
using System.Drawing;
using NUnit.Framework;
using X10D.Drawing;
namespace X10D.Tests.Drawing;
[TestFixture]
public class RandomTests
internal class RandomTests
{
[Test]
public void NextColorArgb_ShouldReturn331515e5_GivenSeed1234()

View File

@ -1,11 +1,11 @@
using System.Drawing;
using System.Drawing;
using NUnit.Framework;
using X10D.Drawing;
namespace X10D.Tests.Drawing;
[TestFixture]
public class SizeTests
internal class SizeTests
{
[Test]
public void ToPoint_ShouldReturnPoint_WithEquivalentMembers()

View File

@ -1,10 +1,10 @@
using NUnit.Framework;
using NUnit.Framework;
using X10D.Drawing;
namespace X10D.Tests.Drawing;
[TestFixture]
public class SphereTests
internal class SphereTests
{
[Test]
public void Circumference_ShouldBe2PiRadius_GivenUnitCircle()

View File

@ -1,4 +1,4 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using NUnit.Framework;
using X10D.Hosting.DependencyInjection;
@ -6,7 +6,7 @@ using X10D.Hosting.DependencyInjection;
namespace X10D.Tests.Hosting;
[TestFixture]
public class ServiceCollectionTests
internal class ServiceCollectionTests
{
[Test]
public void AddHostedSingleton_ShouldRegisterServiceAsSingletonAndAsHostedService()

View File

@ -1,10 +1,10 @@
using NUnit.Framework;
using NUnit.Framework;
using X10D.IO;
namespace X10D.Tests.IO;
[TestFixture]
public class BooleanTests
internal class BooleanTests
{
[Test]
public void GetBytes_ReturnsArrayContaining1()

View File

@ -4,7 +4,7 @@ using X10D.IO;
namespace X10D.Tests.IO;
[TestFixture]
public class ByteTests
internal class ByteTests
{
[Test]
public void GetBytes_ReturnsArrayContainingItself()

View File

@ -0,0 +1,72 @@
using NUnit.Framework;
using X10D.IO;
namespace X10D.Tests.IO;
[TestFixture]
internal class DecimalTests
{
[Test]
public void GetBigEndianBytes_ShouldReturnBytes_InBigEndian()
{
const decimal value = 1234m;
byte[] expected = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 210];
byte[] bytes = value.GetBigEndianBytes();
CollectionAssert.AreEqual(expected, bytes);
}
[Test]
public void GetLittleEndianBytes_ShouldReturnBytes_InLittleEndian()
{
const decimal value = 1234m;
byte[] expected = [210, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
byte[] bytes = value.GetLittleEndianBytes();
CollectionAssert.AreEqual(expected, bytes);
}
[Test]
public void TryWriteBigEndianBytes_ShouldWriteBytes_InBigEndian()
{
const decimal value = 1234m;
byte[] expected = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 210];
Span<byte> bytes = stackalloc byte[16];
Assert.That(value.TryWriteBigEndianBytes(bytes));
CollectionAssert.AreEqual(expected, bytes.ToArray());
}
[Test]
public void TryWriteLittleEndianBytes_ShouldWriteBytes_InLittleEndian()
{
const decimal value = 1234m;
byte[] expected = [210, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
Span<byte> bytes = stackalloc byte[16];
Assert.That(value.TryWriteLittleEndianBytes(bytes));
CollectionAssert.AreEqual(expected, bytes.ToArray());
}
[Test]
public void TryWriteBigEndianBytes_ShouldReturnFalse_GivenSmallSpan()
{
const decimal value = 1234m;
Span<byte> bytes = Span<byte>.Empty;
Assert.That(value.TryWriteBigEndianBytes(bytes), Is.False);
}
[Test]
public void TryWriteLittleEndianBytes_ShouldReturnFalse_GivenSmallSpan()
{
const decimal value = 1234m;
Span<byte> bytes = Span<byte>.Empty;
Assert.That(value.TryWriteLittleEndianBytes(bytes), Is.False);
}
}

View File

@ -4,7 +4,7 @@ using X10D.IO;
namespace X10D.Tests.IO;
[TestFixture]
public class DirectoryInfoTests
internal class DirectoryInfoTests
{
[Test]
public void Clear_ShouldClear_GivenValidDirectory()

View File

@ -4,63 +4,63 @@ using X10D.IO;
namespace X10D.Tests.IO;
[TestFixture]
public class DoubleTests
internal class DoubleTests
{
[Test]
public void GetBytes_ReturnsCorrectValue()
public void GetBigEndianBytes_ReturnsCorrectValue()
{
const double value = 42.5;
byte[] bytes = BitConverter.IsLittleEndian
? new byte[] {0, 0, 0, 0, 0, 0x40, 0x45, 0x40}
: new byte[] {0x40, 0x45, 0x40, 0, 0, 0, 0, 0};
CollectionAssert.AreEqual(bytes, value.GetBytes());
var expected = new byte[] { 0x40, 0x45, 0x40, 0, 0, 0, 0, 0 };
byte[] actual = value.GetBigEndianBytes();
CollectionAssert.AreEqual(expected, actual);
}
[Test]
public void GetBytes_ReturnsCorrectValue_WithEndianness()
public void GetLittleEndianBytes_ReturnsCorrectValue()
{
const double value = 42.5;
byte[] littleEndian = {0, 0, 0, 0, 0, 0x40, 0x45, 0x40};
byte[] bigEndian = {0x40, 0x45, 0x40, 0, 0, 0, 0, 0};
CollectionAssert.AreEqual(littleEndian, value.GetBytes(Endianness.LittleEndian));
CollectionAssert.AreEqual(bigEndian, value.GetBytes(Endianness.BigEndian));
var expected = new byte[] { 0, 0, 0, 0, 0, 0x40, 0x45, 0x40 };
byte[] actual = value.GetLittleEndianBytes();
CollectionAssert.AreEqual(expected, actual);
}
[Test]
public void TryWriteBytes_ReturnsTrue_FillsSpanCorrectly_GivenLargeEnoughSpan()
public void TryWriteBigEndian_ReturnsTrue_FillsSpanCorrectly()
{
const double value = 42.5;
byte[] bytes = BitConverter.IsLittleEndian
? new byte[] {0, 0, 0, 0, 0, 0x40, 0x45, 0x40}
: new byte[] {0x40, 0x45, 0x40, 0, 0, 0, 0, 0};
Span<byte> buffer = stackalloc byte[8];
Assert.That(value.TryWriteBytes(buffer));
CollectionAssert.AreEqual(bytes, buffer.ToArray());
var expected = new byte[] { 0x40, 0x45, 0x40, 0, 0, 0, 0, 0 };
Span<byte> actual = stackalloc byte[8];
Assert.That(value.TryWriteBigEndianBytes(actual));
CollectionAssert.AreEqual(expected, actual.ToArray());
}
[Test]
public void TryWriteBytes_ReturnsTrue_FillsSpanCorrectly_GivenLargeEnoughSpan_WithEndianness()
public void TryWriteLittleEndian_ReturnsTrue_FillsSpanCorrectly()
{
const double value = 42.5;
byte[] littleEndian = {0, 0, 0, 0, 0, 0x40, 0x45, 0x40};
byte[] bigEndian = {0x40, 0x45, 0x40, 0, 0, 0, 0, 0};
Span<byte> buffer = stackalloc byte[8];
Assert.That(value.TryWriteBytes(buffer, Endianness.LittleEndian));
CollectionAssert.AreEqual(littleEndian, buffer.ToArray());
Assert.That(value.TryWriteBytes(buffer, Endianness.BigEndian));
CollectionAssert.AreEqual(bigEndian, buffer.ToArray());
var expected = new byte[] { 0, 0, 0, 0, 0, 0x40, 0x45, 0x40 };
Span<byte> actual = stackalloc byte[8];
Assert.That(value.TryWriteLittleEndianBytes(actual));
CollectionAssert.AreEqual(expected, actual.ToArray());
}
[Test]
public void TryWriteBytes_ReturnsFalse_GivenSmallSpan()
public void TryWriteBigEndian_ReturnsFalse_GivenSmallSpan()
{
const double value = 42.5;
Span<byte> buffer = stackalloc byte[0];
Assert.That(value.TryWriteBytes(buffer), Is.False);
Assert.That(value.TryWriteBigEndianBytes(buffer), Is.False);
}
[Test]
public void TryWriteLittleEndian_RReturnsFalse_GivenSmallSpan()
{
const double value = 42.5;
Span<byte> buffer = stackalloc byte[0];
Assert.That(value.TryWriteLittleEndianBytes(buffer), Is.False);
}
}

View File

@ -5,7 +5,7 @@ using X10D.IO;
namespace X10D.Tests.IO;
[TestFixture]
public class FileInfoTests
internal class FileInfoTests
{
[Test]
public void GetHashSha1ShouldBeCorrect()

View File

@ -4,59 +4,63 @@ using X10D.IO;
namespace X10D.Tests.IO;
[TestFixture]
public class Int16Tests
internal class Int16Tests
{
[Test]
public void GetBytes_ReturnsCorrectValue()
public void GetLittleEndianBytes_ReturnsCorrectValue()
{
const short value = 0x0F;
byte[] bytes = BitConverter.IsLittleEndian ? new byte[] {0x0F, 0} : new byte[] {0, 0x0F};
CollectionAssert.AreEqual(bytes, value.GetBytes());
byte[] expected = { 0x0F, 0 };
byte[] actual = value.GetLittleEndianBytes();
CollectionAssert.AreEqual(expected, actual);
}
[Test]
public void GetBytes_ReturnsCorrectValue_WithEndianness()
public void GetBigEndianBytes_ReturnsCorrectValue()
{
const short value = 0x0F;
byte[] littleEndian = {0x0F, 0};
byte[] bigEndian = {0, 0x0F};
CollectionAssert.AreEqual(littleEndian, value.GetBytes(Endianness.LittleEndian));
CollectionAssert.AreEqual(bigEndian, value.GetBytes(Endianness.BigEndian));
byte[] expected = { 0, 0x0F };
byte[] actual = value.GetBigEndianBytes();
CollectionAssert.AreEqual(expected, actual);
}
[Test]
public void TryWriteBytes_ReturnsTrue_FillsSpanCorrectly_GivenLargeEnoughSpan()
public void TryWriteLittleEndian_ReturnsTrue_FillsSpanCorrectly()
{
const short value = 0x0F;
byte[] bytes = BitConverter.IsLittleEndian ? new byte[] {0x0F, 0} : new byte[] {0, 0x0F};
Span<byte> buffer = stackalloc byte[2];
Assert.That(value.TryWriteBytes(buffer));
CollectionAssert.AreEqual(bytes, buffer.ToArray());
byte[] expected = { 0x0F, 0 };
Span<byte> actual = stackalloc byte[2];
Assert.That(value.TryWriteLittleEndianBytes(actual));
CollectionAssert.AreEqual(expected, actual.ToArray());
}
[Test]
public void TryWriteBytes_ReturnsTrue_FillsSpanCorrectly_GivenLargeEnoughSpan_WithEndianness()
public void TryWriteBigEndian_ReturnsTrue_FillsSpanCorrectly()
{
const short value = 0x0F;
byte[] littleEndian = {0x0F, 0};
byte[] bigEndian = {0, 0x0F};
Span<byte> buffer = stackalloc byte[2];
Assert.That(value.TryWriteBytes(buffer, Endianness.LittleEndian));
CollectionAssert.AreEqual(littleEndian, buffer.ToArray());
Assert.That(value.TryWriteBytes(buffer, Endianness.BigEndian));
CollectionAssert.AreEqual(bigEndian, buffer.ToArray());
byte[] expected = { 0, 0x0F };
Span<byte> actual = stackalloc byte[2];
Assert.That(value.TryWriteBigEndianBytes(actual));
CollectionAssert.AreEqual(expected, actual.ToArray());
}
[Test]
public void TryWriteBytes_ReturnsFalse_GivenSmallSpan()
public void TryWriteLittleEndian_RReturnsFalse_GivenSmallSpan()
{
const short value = 0x0F;
Span<byte> buffer = stackalloc byte[0];
Assert.That(value.TryWriteBytes(buffer), Is.False);
Assert.That(value.TryWriteLittleEndianBytes(buffer), Is.False);
}
[Test]
public void TryWriteBigEndian_ReturnsFalse_GivenSmallSpan()
{
const short value = 0x0F;
Span<byte> buffer = stackalloc byte[0];
Assert.That(value.TryWriteBigEndianBytes(buffer), Is.False);
}
}

View File

@ -4,59 +4,63 @@ using X10D.IO;
namespace X10D.Tests.IO;
[TestFixture]
public class Int32Tests
internal class Int32Tests
{
[Test]
public void GetBytes_ReturnsCorrectValue()
public void GetBigEndianBytes_ReturnsCorrectValue()
{
const int value = 0x0F;
byte[] bytes = BitConverter.IsLittleEndian ? new byte[] {0x0F, 0, 0, 0} : new byte[] {0, 0, 0, 0x0F};
CollectionAssert.AreEqual(bytes, value.GetBytes());
var expected = new byte[] { 0, 0, 0, 0x0F };
byte[] actual = value.GetBigEndianBytes();
CollectionAssert.AreEqual(expected, actual);
}
[Test]
public void GetBytes_ReturnsCorrectValue_WithEndianness()
public void GetLittleEndianBytes_ReturnsCorrectValue()
{
const int value = 0x0F;
byte[] littleEndian = {0x0F, 0, 0, 0};
byte[] bigEndian = {0, 0, 0, 0x0F};
CollectionAssert.AreEqual(littleEndian, value.GetBytes(Endianness.LittleEndian));
CollectionAssert.AreEqual(bigEndian, value.GetBytes(Endianness.BigEndian));
var expected = new byte[] { 0x0F, 0, 0, 0 };
byte[] actual = value.GetLittleEndianBytes();
CollectionAssert.AreEqual(expected, actual);
}
[Test]
public void TryWriteBytes_ReturnsTrue_FillsSpanCorrectly_GivenLargeEnoughSpan()
public void TryWriteBigEndian_ReturnsTrue_FillsSpanCorrectly()
{
const int value = 0x0F;
byte[] bytes = BitConverter.IsLittleEndian ? new byte[] {0x0F, 0, 0, 0} : new byte[] {0, 0, 0, 0x0F};
Span<byte> buffer = stackalloc byte[4];
Assert.That(value.TryWriteBytes(buffer));
CollectionAssert.AreEqual(bytes, buffer.ToArray());
var expected = new byte[] { 0, 0, 0, 0x0F };
Span<byte> actual = stackalloc byte[4];
Assert.That(value.TryWriteBigEndianBytes(actual));
CollectionAssert.AreEqual(expected, actual.ToArray());
}
[Test]
public void TryWriteBytes_ReturnsTrue_FillsSpanCorrectly_GivenLargeEnoughSpan_WithEndianness()
public void TryWriteLittleEndian_ReturnsTrue_FillsSpanCorrectly()
{
const int value = 0x0F;
byte[] littleEndian = {0x0F, 0, 0, 0};
byte[] bigEndian = {0, 0, 0, 0x0F};
Span<byte> buffer = stackalloc byte[4];
Assert.That(value.TryWriteBytes(buffer, Endianness.LittleEndian));
CollectionAssert.AreEqual(littleEndian, buffer.ToArray());
Assert.That(value.TryWriteBytes(buffer, Endianness.BigEndian));
CollectionAssert.AreEqual(bigEndian, buffer.ToArray());
var expected = new byte[] { 0x0F, 0, 0, 0 };
Span<byte> actual = stackalloc byte[4];
Assert.That(value.TryWriteLittleEndianBytes(actual));
CollectionAssert.AreEqual(expected, actual.ToArray());
}
[Test]
public void TryWriteBytes_ReturnsFalse_GivenSmallSpan()
public void TryWriteBigEndian_ReturnsFalse_GivenSmallSpan()
{
const int value = 0x0F;
Span<byte> buffer = stackalloc byte[0];
Assert.That(value.TryWriteBytes(buffer), Is.False);
Assert.That(value.TryWriteBigEndianBytes(buffer), Is.False);
}
[Test]
public void TryWriteLittleEndian_RReturnsFalse_GivenSmallSpan()
{
const int value = 0x0F;
Span<byte> buffer = stackalloc byte[0];
Assert.That(value.TryWriteLittleEndianBytes(buffer), Is.False);
}
}

View File

@ -4,63 +4,63 @@ using X10D.IO;
namespace X10D.Tests.IO;
[TestFixture]
public class Int64Tests
internal class Int64Tests
{
[Test]
public void GetBytes_ReturnsCorrectValue()
public void GetLittleEndianBytes_ReturnsCorrectValue()
{
const long value = 0x0F;
byte[] bytes = BitConverter.IsLittleEndian
? new byte[] {0x0F, 0, 0, 0, 0, 0, 0, 0}
: new byte[] {0, 0, 0, 0, 0, 0, 0, 0x0F};
CollectionAssert.AreEqual(bytes, value.GetBytes());
byte[] expected = { 0x0F, 0, 0, 0, 0, 0, 0, 0 };
byte[] actual = value.GetLittleEndianBytes();
CollectionAssert.AreEqual(expected, actual);
}
[Test]
public void GetBytes_ReturnsCorrectValue_WithEndianness()
public void GetBigEndianBytes_ReturnsCorrectValue()
{
const long value = 0x0F;
byte[] littleEndian = {0x0F, 0, 0, 0, 0, 0, 0, 0};
byte[] bigEndian = {0, 0, 0, 0, 0, 0, 0, 0x0F};
CollectionAssert.AreEqual(littleEndian, value.GetBytes(Endianness.LittleEndian));
CollectionAssert.AreEqual(bigEndian, value.GetBytes(Endianness.BigEndian));
byte[] expected = { 0, 0, 0, 0, 0, 0, 0, 0x0F };
byte[] actual = value.GetBigEndianBytes();
CollectionAssert.AreEqual(expected, actual);
}
[Test]
public void TryWriteBytes_ReturnsTrue_FillsSpanCorrectly_GivenLargeEnoughSpan()
public void TryWriteLittleEndian_ReturnsTrue_FillsSpanCorrectly()
{
const long value = 0x0F;
byte[] bytes = BitConverter.IsLittleEndian
? new byte[] {0x0F, 0, 0, 0, 0, 0, 0, 0}
: new byte[] {0, 0, 0, 0, 0, 0, 0, 0x0F};
Span<byte> buffer = stackalloc byte[8];
Assert.That(value.TryWriteBytes(buffer));
CollectionAssert.AreEqual(bytes, buffer.ToArray());
byte[] expected = { 0x0F, 0, 0, 0, 0, 0, 0, 0 };
Span<byte> actual = stackalloc byte[8];
Assert.That(value.TryWriteLittleEndianBytes(actual));
CollectionAssert.AreEqual(expected, actual.ToArray());
}
[Test]
public void TryWriteBytes_ReturnsTrue_FillsSpanCorrectly_GivenLargeEnoughSpan_WithEndianness()
public void TryWriteBigEndian_ReturnsTrue_FillsSpanCorrectly()
{
const long value = 0x0F;
byte[] littleEndian = {0x0F, 0, 0, 0, 0, 0, 0, 0};
byte[] bigEndian = {0, 0, 0, 0, 0, 0, 0, 0x0F};
Span<byte> buffer = stackalloc byte[8];
Assert.That(value.TryWriteBytes(buffer, Endianness.LittleEndian));
CollectionAssert.AreEqual(littleEndian, buffer.ToArray());
Assert.That(value.TryWriteBytes(buffer, Endianness.BigEndian));
CollectionAssert.AreEqual(bigEndian, buffer.ToArray());
byte[] expected = { 0, 0, 0, 0, 0, 0, 0, 0x0F };
Span<byte> actual = stackalloc byte[8];
Assert.That(value.TryWriteBigEndianBytes(actual));
CollectionAssert.AreEqual(expected, actual.ToArray());
}
[Test]
public void TryWriteBytes_ReturnsFalse_GivenSmallSpan()
public void TryWriteLittleEndian_RReturnsFalse_GivenSmallSpan()
{
const long value = 0x0F;
Span<byte> buffer = stackalloc byte[0];
Assert.That(value.TryWriteBytes(buffer), Is.False);
Assert.That(value.TryWriteLittleEndianBytes(buffer), Is.False);
}
[Test]
public void TryWriteBigEndian_ReturnsFalse_GivenSmallSpan()
{
const long value = 0x0F;
Span<byte> buffer = stackalloc byte[0];
Assert.That(value.TryWriteBigEndianBytes(buffer), Is.False);
}
}

View File

@ -5,7 +5,7 @@ using X10D.IO;
namespace X10D.Tests.IO;
[TestFixture]
public class ListOfByteTests
internal class ListOfByteTests
{
[Test]
public void AsString_ShouldReturnBytes_GivenBytes()

View File

@ -4,8 +4,7 @@ using X10D.IO;
namespace X10D.Tests.IO;
[TestFixture]
[CLSCompliant(false)]
public class SByteTests
internal class SByteTests
{
[Test]
public void GetBytes_ReturnsArrayContainingItself()

View File

@ -4,63 +4,63 @@ using X10D.IO;
namespace X10D.Tests.IO;
[TestFixture]
public class SingleTests
internal class SingleTests
{
[Test]
public void GetBytes_ReturnsCorrectValue()
public void GetBigEndianBytes_ReturnsCorrectValue()
{
const float value = 42.5f;
byte[] bytes = BitConverter.IsLittleEndian
? new byte[] {0, 0, 0x2A, 0x42}
: new byte[] {0x42, 0x2A, 0, 0};
CollectionAssert.AreEqual(bytes, value.GetBytes());
var expected = new byte[] { 0x42, 0x2A, 0, 0 };
byte[] actual = value.GetBigEndianBytes();
CollectionAssert.AreEqual(expected, actual);
}
[Test]
public void GetBytes_ReturnsCorrectValue_WithEndianness()
public void GetLittleEndianBytes_ReturnsCorrectValue()
{
const float value = 42.5f;
byte[] littleEndian = {0, 0, 0x2A, 0x42};
byte[] bigEndian = {0x42, 0x2A, 0, 0};
CollectionAssert.AreEqual(littleEndian, value.GetBytes(Endianness.LittleEndian));
CollectionAssert.AreEqual(bigEndian, value.GetBytes(Endianness.BigEndian));
var expected = new byte[] { 0, 0, 0x2A, 0x42 };
byte[] actual = value.GetLittleEndianBytes();
CollectionAssert.AreEqual(expected, actual);
}
[Test]
public void TryWriteBytes_ReturnsTrue_FillsSpanCorrectly_GivenLargeEnoughSpan()
public void TryWriteBigEndian_ReturnsTrue_FillsSpanCorrectly()
{
const float value = 42.5f;
byte[] bytes = BitConverter.IsLittleEndian
? new byte[] {0, 0, 0x2A, 0x42}
: new byte[] {0x42, 0x2A, 0, 0};
Span<byte> buffer = stackalloc byte[4];
Assert.That(value.TryWriteBytes(buffer));
CollectionAssert.AreEqual(bytes, buffer.ToArray());
var expected = new byte[] { 0x42, 0x2A, 0, 0 };
Span<byte> actual = stackalloc byte[4];
Assert.That(value.TryWriteBigEndianBytes(actual));
CollectionAssert.AreEqual(expected, actual.ToArray());
}
[Test]
public void TryWriteBytes_ReturnsTrue_FillsSpanCorrectly_GivenLargeEnoughSpan_WithEndianness()
public void TryWriteLittleEndian_ReturnsTrue_FillsSpanCorrectly()
{
const float value = 42.5f;
byte[] littleEndian = {0, 0, 0x2A, 0x42};
byte[] bigEndian = {0x42, 0x2A, 0, 0};
Span<byte> buffer = stackalloc byte[4];
Assert.That(value.TryWriteBytes(buffer, Endianness.LittleEndian));
CollectionAssert.AreEqual(littleEndian, buffer.ToArray());
Assert.That(value.TryWriteBytes(buffer, Endianness.BigEndian));
CollectionAssert.AreEqual(bigEndian, buffer.ToArray());
var expected = new byte[] { 0, 0, 0x2A, 0x42 };
Span<byte> actual = stackalloc byte[4];
Assert.That(value.TryWriteLittleEndianBytes(actual));
CollectionAssert.AreEqual(expected, actual.ToArray());
}
[Test]
public void TryWriteBytes_ReturnsFalse_GivenSmallSpan()
public void TryWriteBigEndian_ReturnsFalse_GivenSmallSpan()
{
const float value = 42.5f;
Span<byte> buffer = stackalloc byte[0];
Assert.That(value.TryWriteBytes(buffer), Is.False);
Assert.That(value.TryWriteBigEndianBytes(buffer), Is.False);
}
[Test]
public void TryWriteLittleEndian_RReturnsFalse_GivenSmallSpan()
{
const float value = 42.5f;
Span<byte> buffer = stackalloc byte[0];
Assert.That(value.TryWriteLittleEndianBytes(buffer), Is.False);
}
}

View File

@ -1,42 +1,43 @@
using NUnit.Framework;
using System.Diagnostics.CodeAnalysis;
using NUnit.Framework;
using X10D.IO;
namespace X10D.Tests.IO;
public partial class StreamTests
internal partial class StreamTests
{
[Test]
public void ReadDecimal_ShouldThrowArgumentException_GivenNonReadableStream()
{
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.ReadDecimal());
Assert.Throws<ArgumentException>(() => stream.ReadDecimal(Endianness.LittleEndian));
Assert.Throws<ArgumentException>(() => stream.ReadDecimal(Endianness.BigEndian));
}
[Test]
public void ReadDecimal_ShouldThrowArgumentNullException_GivenNullStream()
public void ReadDecimalBigEndian_ShouldThrowArgumentNullException_GivenNullStream()
{
Stream stream = null!;
Assert.Throws<ArgumentNullException>(() => stream.ReadDecimal());
Assert.Throws<ArgumentNullException>(() => stream.ReadDecimal(Endianness.LittleEndian));
Assert.Throws<ArgumentNullException>(() => stream.ReadDecimal(Endianness.BigEndian));
Assert.Throws<ArgumentNullException>(() => stream.ReadDecimalBigEndian());
}
[Test]
public void ReadDecimal_ShouldThrowArgumentOutOfRangeException_GivenInvalidEndiannessValue()
public void ReadDecimalLittleEndian_ShouldThrowArgumentNullException_GivenNullStream()
{
// we don't need to enclose this stream in a using declaration, since disposing a
// null stream is meaningless. NullStream.Dispose actually does nothing, anyway.
// that - coupled with the fact that encapsulating the stream in a using declaration causes the
// analyser to trip up and think the stream is disposed by the time the local is captured in
// assertion lambda - means this line is fine as it is. please do not change.
Stream stream = Stream.Null;
Assert.Throws<ArgumentOutOfRangeException>(() => stream.ReadDecimal((Endianness)(-1)));
Stream stream = null!;
Assert.Throws<ArgumentNullException>(() => stream.ReadDecimalLittleEndian());
}
[Test]
public void ReadDecimal_ShouldReadBigEndian_GivenBigEndian()
[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope")]
public void ReadDecimalBigEndian_ShouldThrowArgumentException_GivenNonReadableStream()
{
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.ReadDecimalBigEndian());
}
[Test]
[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope")]
public void ReadDecimalLittleEndian_ShouldThrowArgumentException_GivenNonReadableStream()
{
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.ReadDecimalLittleEndian());
}
[Test]
public void ReadDecimalBigEndian_ShouldReadBigEndian()
{
using var stream = new MemoryStream();
ReadOnlySpan<byte> bytes = stackalloc byte[]
@ -47,7 +48,7 @@ public partial class StreamTests
stream.Position = 0;
const decimal expected = 420.0m;
decimal actual = stream.ReadDecimal(Endianness.BigEndian);
decimal actual = stream.ReadDecimalBigEndian();
Assert.Multiple(() =>
{
@ -57,7 +58,7 @@ public partial class StreamTests
}
[Test]
public void ReadDecimal_ShouldWriteLittleEndian_GivenLittleEndian()
public void ReadDecimalLittleEndian_ShouldWriteLittleEndian()
{
using var stream = new MemoryStream();
ReadOnlySpan<byte> bytes = stackalloc byte[]
@ -68,7 +69,7 @@ public partial class StreamTests
stream.Position = 0;
const decimal expected = 420.0m;
decimal actual = stream.ReadDecimal(Endianness.LittleEndian);
decimal actual = stream.ReadDecimalLittleEndian();
Assert.Multiple(() =>
{

View File

@ -1,65 +1,66 @@
using NUnit.Framework;
using System.Diagnostics.CodeAnalysis;
using NUnit.Framework;
using X10D.IO;
namespace X10D.Tests.IO;
public partial class StreamTests
internal partial class StreamTests
{
[Test]
public void ReadDouble_ShouldThrowArgumentException_GivenNonReadableStream()
{
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.ReadDouble());
Assert.Throws<ArgumentException>(() => stream.ReadDouble(Endianness.LittleEndian));
Assert.Throws<ArgumentException>(() => stream.ReadDouble(Endianness.BigEndian));
}
[Test]
public void ReadDouble_ShouldThrowArgumentNullException_GivenNullStream()
public void ReadDoubleBigEndian_ShouldThrowArgumentNullException_GivenNullStream()
{
Stream stream = null!;
Assert.Throws<ArgumentNullException>(() => stream.ReadDouble());
Assert.Throws<ArgumentNullException>(() => stream.ReadDouble(Endianness.LittleEndian));
Assert.Throws<ArgumentNullException>(() => stream.ReadDouble(Endianness.BigEndian));
Assert.Throws<ArgumentNullException>(() => stream.ReadDoubleBigEndian());
}
[Test]
public void ReadDouble_ShouldThrowArgumentOutOfRangeException_GivenInvalidEndiannessValue()
public void ReadDoubleLittleEndian_ShouldThrowArgumentNullException_GivenNullStream()
{
// we don't need to enclose this stream in a using declaration, since disposing a
// null stream is meaningless. NullStream.Dispose actually does nothing, anyway.
// that - coupled with the fact that encapsulating the stream in a using declaration causes the
// analyser to trip up and think the stream is disposed by the time the local is captured in
// assertion lambda - means this line is fine as it is. please do not change.
Stream stream = Stream.Null;
Assert.Throws<ArgumentOutOfRangeException>(() => stream.ReadDouble((Endianness)(-1)));
Stream stream = null!;
Assert.Throws<ArgumentNullException>(() => stream.ReadDoubleLittleEndian());
}
[Test]
public void ReadDouble_ShouldReadBigEndian_GivenBigEndian()
[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope")]
public void ReadDoubleBigEndian_ShouldThrowArgumentException_GivenNonReadableStream()
{
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.ReadDoubleBigEndian());
}
[Test]
[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope")]
public void ReadDoubleLittleEndian_ShouldThrowArgumentException_GivenNonReadableStream()
{
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.ReadDoubleLittleEndian());
}
[Test]
public void ReadDoubleBigEndian_ShouldReadBigEndian()
{
using var stream = new MemoryStream();
ReadOnlySpan<byte> bytes = stackalloc byte[] {0x40, 0x7A, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00};
ReadOnlySpan<byte> bytes = stackalloc byte[] { 0x40, 0x7A, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00 };
stream.Write(bytes);
stream.Position = 0;
const double expected = 420.0;
double actual = stream.ReadDouble(Endianness.BigEndian);
double actual = stream.ReadDoubleBigEndian();
Assert.That(stream.Position, Is.EqualTo(8));
Assert.That(actual, Is.EqualTo(expected));
}
[Test]
public void ReadDouble_ShouldWriteLittleEndian_GivenLittleEndian()
public void ReadDoubleLittleEndian_ShouldWriteLittleEndian()
{
using var stream = new MemoryStream();
ReadOnlySpan<byte> bytes = stackalloc byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7A, 0x40};
ReadOnlySpan<byte> bytes = stackalloc byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7A, 0x40 };
stream.Write(bytes);
stream.Position = 0;
const double expected = 420.0;
double actual = stream.ReadDouble(Endianness.LittleEndian);
double actual = stream.ReadDoubleLittleEndian();
Assert.That(stream.Position, Is.EqualTo(8));
Assert.That(actual, Is.EqualTo(expected));

View File

@ -1,65 +1,66 @@
using NUnit.Framework;
using System.Diagnostics.CodeAnalysis;
using NUnit.Framework;
using X10D.IO;
namespace X10D.Tests.IO;
public partial class StreamTests
internal partial class StreamTests
{
[Test]
public void ReadInt16_ShouldThrowArgumentException_GivenNonReadableStream()
{
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.ReadInt16());
Assert.Throws<ArgumentException>(() => stream.ReadInt16(Endianness.LittleEndian));
Assert.Throws<ArgumentException>(() => stream.ReadInt16(Endianness.BigEndian));
}
[Test]
public void ReadInt16_ShouldThrowArgumentNullException_GivenNullStream()
public void ReadInt16BigEndian_ShouldThrowArgumentNullException_GivenNullStream()
{
Stream stream = null!;
Assert.Throws<ArgumentNullException>(() => stream.ReadInt16());
Assert.Throws<ArgumentNullException>(() => stream.ReadInt16(Endianness.LittleEndian));
Assert.Throws<ArgumentNullException>(() => stream.ReadInt16(Endianness.BigEndian));
Assert.Throws<ArgumentNullException>(() => stream.ReadInt16BigEndian());
}
[Test]
public void ReadInt16_ShouldThrowArgumentOutOfRangeException_GivenInvalidEndiannessValue()
public void ReadInt16LittleEndian_ShouldThrowArgumentNullException_GivenNullStream()
{
// we don't need to enclose this stream in a using declaration, since disposing a
// null stream is meaningless. NullStream.Dispose actually does nothing, anyway.
// that - coupled with the fact that encapsulating the stream in a using declaration causes the
// analyser to trip up and think the stream is disposed by the time the local is captured in
// assertion lambda - means this line is fine as it is. please do not change.
Stream stream = Stream.Null;
Assert.Throws<ArgumentOutOfRangeException>(() => stream.ReadInt16((Endianness)(-1)));
Stream stream = null!;
Assert.Throws<ArgumentNullException>(() => stream.ReadInt16LittleEndian());
}
[Test]
public void ReadInt16_ShouldReadBigEndian_GivenBigEndian()
[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope")]
public void ReadInt16BigEndian_ShouldThrowArgumentException_GivenNonReadableStream()
{
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.ReadInt16BigEndian());
}
[Test]
[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope")]
public void ReadInt16LittleEndian_ShouldThrowArgumentException_GivenNonReadableStream()
{
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.ReadInt16LittleEndian());
}
[Test]
public void ReadInt16BigEndian_ShouldReadBigEndian()
{
using var stream = new MemoryStream();
ReadOnlySpan<byte> bytes = stackalloc byte[] {0x01, 0xA4};
ReadOnlySpan<byte> bytes = stackalloc byte[] { 0x01, 0xA4 };
stream.Write(bytes);
stream.Position = 0;
const short expected = 420;
short actual = stream.ReadInt16(Endianness.BigEndian);
short actual = stream.ReadInt16BigEndian();
Assert.That(stream.Position, Is.EqualTo(2));
Assert.That(actual, Is.EqualTo(expected));
}
[Test]
public void ReadInt16_ShouldReadLittleEndian_GivenLittleEndian()
public void ReadInt16LittleEndian_ShouldReadLittleEndian()
{
using var stream = new MemoryStream();
ReadOnlySpan<byte> bytes = stackalloc byte[] {0xA4, 0x01};
ReadOnlySpan<byte> bytes = stackalloc byte[] { 0xA4, 0x01 };
stream.Write(bytes);
stream.Position = 0;
const short expected = 420;
short actual = stream.ReadInt16(Endianness.LittleEndian);
short actual = stream.ReadInt16LittleEndian();
Assert.That(stream.Position, Is.EqualTo(2));
Assert.That(actual, Is.EqualTo(expected));

View File

@ -1,65 +1,66 @@
using NUnit.Framework;
using System.Diagnostics.CodeAnalysis;
using NUnit.Framework;
using X10D.IO;
namespace X10D.Tests.IO;
public partial class StreamTests
internal partial class StreamTests
{
[Test]
public void ReadInt32_ShouldThrowArgumentException_GivenNonReadableStream()
{
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.ReadInt32());
Assert.Throws<ArgumentException>(() => stream.ReadInt32(Endianness.LittleEndian));
Assert.Throws<ArgumentException>(() => stream.ReadInt32(Endianness.BigEndian));
}
[Test]
public void ReadInt32_ShouldThrowArgumentNullException_GivenNullStream()
public void ReadInt32BigEndian_ShouldThrowArgumentNullException_GivenNullStream()
{
Stream stream = null!;
Assert.Throws<ArgumentNullException>(() => stream.ReadInt32());
Assert.Throws<ArgumentNullException>(() => stream.ReadInt32(Endianness.LittleEndian));
Assert.Throws<ArgumentNullException>(() => stream.ReadInt32(Endianness.BigEndian));
Assert.Throws<ArgumentNullException>(() => stream.ReadInt32BigEndian());
}
[Test]
public void ReadInt32_ShouldThrowArgumentOutOfRangeException_GivenInvalidEndiannessValue()
public void ReadInt32LittleEndian_ShouldThrowArgumentNullException_GivenNullStream()
{
// we don't need to enclose this stream in a using declaration, since disposing a
// null stream is meaningless. NullStream.Dispose actually does nothing, anyway.
// that - coupled with the fact that encapsulating the stream in a using declaration causes the
// analyser to trip up and think the stream is disposed by the time the local is captured in
// assertion lambda - means this line is fine as it is. please do not change.
Stream stream = Stream.Null;
Assert.Throws<ArgumentOutOfRangeException>(() => stream.ReadInt32((Endianness)(-1)));
Stream stream = null!;
Assert.Throws<ArgumentNullException>(() => stream.ReadInt32LittleEndian());
}
[Test]
public void ReadInt32_ShouldReadBigEndian_GivenBigEndian()
[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope")]
public void ReadInt32BigEndian_ShouldThrowArgumentException_GivenNonReadableStream()
{
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.ReadInt32BigEndian());
}
[Test]
[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope")]
public void ReadInt32LittleEndian_ShouldThrowArgumentException_GivenNonReadableStream()
{
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.ReadInt32LittleEndian());
}
[Test]
public void ReadInt32BigEndian_ShouldReadBigEndian()
{
using var stream = new MemoryStream();
ReadOnlySpan<byte> bytes = stackalloc byte[] {0x00, 0x00, 0x01, 0xA4};
ReadOnlySpan<byte> bytes = stackalloc byte[] { 0x00, 0x00, 0x01, 0xA4 };
stream.Write(bytes);
stream.Position = 0;
const int expected = 420;
int actual = stream.ReadInt32(Endianness.BigEndian);
int actual = stream.ReadInt32BigEndian();
Assert.That(stream.Position, Is.EqualTo(4));
Assert.That(actual, Is.EqualTo(expected));
}
[Test]
public void ReadInt32_ShouldReadLittleEndian_GivenLittleEndian()
public void ReadInt32LittleEndian_ShouldReadLittleEndian()
{
using var stream = new MemoryStream();
ReadOnlySpan<byte> bytes = stackalloc byte[] {0xA4, 0x01, 0x00, 0x00};
ReadOnlySpan<byte> bytes = stackalloc byte[] { 0xA4, 0x01, 0x00, 0x00 };
stream.Write(bytes);
stream.Position = 0;
const int expected = 420;
int actual = stream.ReadInt32(Endianness.LittleEndian);
int actual = stream.ReadInt32LittleEndian();
Assert.That(stream.Position, Is.EqualTo(4));
Assert.That(actual, Is.EqualTo(expected));

View File

@ -3,63 +3,61 @@ using X10D.IO;
namespace X10D.Tests.IO;
public partial class StreamTests
internal partial class StreamTests
{
[Test]
public void ReadInt64_ShouldThrowArgumentException_GivenNonReadableStream()
{
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.ReadInt64());
Assert.Throws<ArgumentException>(() => stream.ReadInt64(Endianness.LittleEndian));
Assert.Throws<ArgumentException>(() => stream.ReadInt64(Endianness.BigEndian));
}
[Test]
public void ReadInt64_ShouldThrowArgumentNullException_GivenNullStream()
public void ReadInt64BigEndian_ShouldThrowArgumentNullException_GivenNullStream()
{
Stream stream = null!;
Assert.Throws<ArgumentNullException>(() => stream.ReadInt64());
Assert.Throws<ArgumentNullException>(() => stream.ReadInt64(Endianness.LittleEndian));
Assert.Throws<ArgumentNullException>(() => stream.ReadInt64(Endianness.BigEndian));
Assert.Throws<ArgumentNullException>(() => stream.ReadInt64BigEndian());
}
[Test]
public void ReadInt64_ShouldThrowArgumentOutOfRangeException_GivenInvalidEndiannessValue()
public void ReadInt64LittleEndian_ShouldThrowArgumentNullException_GivenNullStream()
{
// we don't need to enclose this stream in a using declaration, since disposing a
// null stream is meaningless. NullStream.Dispose actually does nothing, anyway.
// that - coupled with the fact that encapsulating the stream in a using declaration causes the
// analyser to trip up and think the stream is disposed by the time the local is captured in
// assertion lambda - means this line is fine as it is. please do not change.
Stream stream = Stream.Null;
Assert.Throws<ArgumentOutOfRangeException>(() => stream.ReadInt64((Endianness)(-1)));
Stream stream = null!;
Assert.Throws<ArgumentNullException>(() => stream.ReadInt64LittleEndian());
}
[Test]
public void ReadInt64_ShouldReadBigEndian_GivenBigEndian()
public void ReadInt64BigEndian_ShouldThrowArgumentException_GivenNonReadableStream()
{
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.ReadInt64BigEndian());
}
[Test]
public void ReadInt64LittleEndian_ShouldThrowArgumentException_GivenNonReadableStream()
{
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.ReadInt64LittleEndian());
}
[Test]
public void ReadInt64BigEndian_ShouldReadBigEndian()
{
using var stream = new MemoryStream();
ReadOnlySpan<byte> bytes = stackalloc byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA4};
ReadOnlySpan<byte> bytes = stackalloc byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA4 };
stream.Write(bytes);
stream.Position = 0;
const long expected = 420;
long actual = stream.ReadInt64(Endianness.BigEndian);
long actual = stream.ReadInt64BigEndian();
Assert.That(stream.Position, Is.EqualTo(8));
Assert.That(actual, Is.EqualTo(expected));
}
[Test]
public void ReadInt64_ShouldWriteLittleEndian_GivenLittleEndian()
public void ReadInt64LittleEndian_ShouldWriteLittleEndian()
{
using var stream = new MemoryStream();
ReadOnlySpan<byte> bytes = stackalloc byte[] {0xA4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
ReadOnlySpan<byte> bytes = stackalloc byte[] { 0xA4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
stream.Write(bytes);
stream.Position = 0;
const long expected = 420;
long actual = stream.ReadInt64(Endianness.LittleEndian);
long actual = stream.ReadInt64LittleEndian();
Assert.That(stream.Position, Is.EqualTo(8));
Assert.That(actual, Is.EqualTo(expected));

View File

@ -1,65 +1,66 @@
using NUnit.Framework;
using System.Diagnostics.CodeAnalysis;
using NUnit.Framework;
using X10D.IO;
namespace X10D.Tests.IO;
public partial class StreamTests
internal partial class StreamTests
{
[Test]
public void ReadSingle_ShouldThrowArgumentException_GivenNonReadableStream()
{
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.ReadSingle());
Assert.Throws<ArgumentException>(() => stream.ReadSingle(Endianness.LittleEndian));
Assert.Throws<ArgumentException>(() => stream.ReadSingle(Endianness.BigEndian));
}
[Test]
public void ReadSingle_ShouldThrowArgumentNullException_GivenNullStream()
public void ReadSingleBigEndian_ShouldThrowArgumentNullException_GivenNullStream()
{
Stream stream = null!;
Assert.Throws<ArgumentNullException>(() => stream.ReadSingle());
Assert.Throws<ArgumentNullException>(() => stream.ReadSingle(Endianness.LittleEndian));
Assert.Throws<ArgumentNullException>(() => stream.ReadSingle(Endianness.BigEndian));
Assert.Throws<ArgumentNullException>(() => stream.ReadSingleBigEndian());
}
[Test]
public void ReadSingle_ShouldThrowArgumentOutOfRangeException_GivenInvalidEndiannessValue()
public void ReadSingleLittleEndian_ShouldThrowArgumentNullException_GivenNullStream()
{
// we don't need to enclose this stream in a using declaration, since disposing a
// null stream is meaningless. NullStream.Dispose actually does nothing, anyway.
// that - coupled with the fact that encapsulating the stream in a using declaration causes the
// analyser to trip up and think the stream is disposed by the time the local is captured in
// assertion lambda - means this line is fine as it is. please do not change.
Stream stream = Stream.Null;
Assert.Throws<ArgumentOutOfRangeException>(() => stream.ReadSingle((Endianness)(-1)));
Stream stream = null!;
Assert.Throws<ArgumentNullException>(() => stream.ReadSingleLittleEndian());
}
[Test]
public void ReadSingle_ShouldReadBigEndian_GivenBigEndian()
[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope")]
public void ReadSingleBigEndian_ShouldThrowArgumentException_GivenNonReadableStream()
{
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.ReadSingleBigEndian());
}
[Test]
[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope")]
public void ReadSingleLittleEndian_ShouldThrowArgumentException_GivenNonReadableStream()
{
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.ReadSingleLittleEndian());
}
[Test]
public void ReadSingleBigEndian_ShouldReadBigEndian()
{
using var stream = new MemoryStream();
ReadOnlySpan<byte> bytes = stackalloc byte[] {0x43, 0xD2, 0x00, 0x00};
ReadOnlySpan<byte> bytes = stackalloc byte[] { 0x43, 0xD2, 0x00, 0x00 };
stream.Write(bytes);
stream.Position = 0;
const float expected = 420.0f;
float actual = stream.ReadSingle(Endianness.BigEndian);
float actual = stream.ReadSingleBigEndian();
Assert.That(stream.Position, Is.EqualTo(4));
Assert.That(actual, Is.EqualTo(expected));
}
[Test]
public void ReadSingle_ShouldReadLittleEndian_GivenLittleEndian()
public void ReadSingleLittleEndian_ShouldReadLittleEndian()
{
using var stream = new MemoryStream();
ReadOnlySpan<byte> bytes = stackalloc byte[] {0x00, 0x00, 0xD2, 0x43};
ReadOnlySpan<byte> bytes = stackalloc byte[] { 0x00, 0x00, 0xD2, 0x43 };
stream.Write(bytes);
stream.Position = 0;
const float expected = 420.0f;
float actual = stream.ReadSingle(Endianness.LittleEndian);
float actual = stream.ReadSingleLittleEndian();
Assert.That(stream.Position, Is.EqualTo(4));
Assert.That(actual, Is.EqualTo(expected));

View File

@ -1,70 +1,66 @@
using NUnit.Framework;
using System.Diagnostics.CodeAnalysis;
using NUnit.Framework;
using X10D.IO;
namespace X10D.Tests.IO;
public partial class StreamTests
internal partial class StreamTests
{
[Test]
[CLSCompliant(false)]
public void ReadUInt16_ShouldThrowArgumentException_GivenNonReadableStream()
{
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.ReadUInt16());
Assert.Throws<ArgumentException>(() => stream.ReadUInt16(Endianness.LittleEndian));
Assert.Throws<ArgumentException>(() => stream.ReadUInt16(Endianness.BigEndian));
}
[Test]
[CLSCompliant(false)]
public void ReadUInt16_ShouldThrowArgumentNullException_GivenNullStream()
public void ReadUInt16BigEndian_ShouldThrowArgumentNullException_GivenNullStream()
{
Stream stream = null!;
Assert.Throws<ArgumentNullException>(() => stream.ReadUInt16());
Assert.Throws<ArgumentNullException>(() => stream.ReadUInt16(Endianness.LittleEndian));
Assert.Throws<ArgumentNullException>(() => stream.ReadUInt16(Endianness.BigEndian));
Assert.Throws<ArgumentNullException>(() => stream.ReadUInt16BigEndian());
}
[Test]
[CLSCompliant(false)]
public void ReadUInt16_ShouldThrowArgumentOutOfRangeException_GivenInvalidEndiannessValue()
public void ReadUInt16LittleEndian_ShouldThrowArgumentNullException_GivenNullStream()
{
// we don't need to enclose this stream in a using declaration, since disposing a
// null stream is meaningless. NullStream.Dispose actually does nothing, anyway.
// that - coupled with the fact that encapsulating the stream in a using declaration causes the
// analyser to trip up and think the stream is disposed by the time the local is captured in
// assertion lambda - means this line is fine as it is. please do not change.
Stream stream = Stream.Null;
Assert.Throws<ArgumentOutOfRangeException>(() => stream.ReadUInt16((Endianness)(-1)));
Stream stream = null!;
Assert.Throws<ArgumentNullException>(() => stream.ReadUInt16LittleEndian());
}
[Test]
[CLSCompliant(false)]
public void ReadUInt16_ShouldReadBigEndian_GivenBigEndian()
[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope")]
public void ReadUInt16BigEndian_ShouldThrowArgumentException_GivenNonReadableStream()
{
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.ReadUInt16BigEndian());
}
[Test]
[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope")]
public void ReadUInt16LittleEndian_ShouldThrowArgumentException_GivenNonReadableStream()
{
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.ReadUInt16LittleEndian());
}
[Test]
public void ReadUInt16BigEndian_ShouldReadBigEndian()
{
using var stream = new MemoryStream();
ReadOnlySpan<byte> bytes = stackalloc byte[] {0x01, 0xA4};
ReadOnlySpan<byte> bytes = stackalloc byte[] { 0x01, 0xA4 };
stream.Write(bytes);
stream.Position = 0;
const ushort expected = 420;
ushort actual = stream.ReadUInt16(Endianness.BigEndian);
ushort actual = stream.ReadUInt16BigEndian();
Assert.That(stream.Position, Is.EqualTo(2));
Assert.That(actual, Is.EqualTo(expected));
}
[Test]
[CLSCompliant(false)]
public void ReadUInt16_ShouldReadLittleEndian_GivenLittleEndian()
public void ReadUInt16LittleEndian_ShouldReadLittleEndian()
{
using var stream = new MemoryStream();
ReadOnlySpan<byte> bytes = stackalloc byte[] {0xA4, 0x01};
ReadOnlySpan<byte> bytes = stackalloc byte[] { 0xA4, 0x01 };
stream.Write(bytes);
stream.Position = 0;
const ushort expected = 420;
ushort actual = stream.ReadUInt16(Endianness.LittleEndian);
ushort actual = stream.ReadUInt16LittleEndian();
Assert.That(stream.Position, Is.EqualTo(2));
Assert.That(actual, Is.EqualTo(expected));

View File

@ -1,70 +1,66 @@
using NUnit.Framework;
using System.Diagnostics.CodeAnalysis;
using NUnit.Framework;
using X10D.IO;
namespace X10D.Tests.IO;
public partial class StreamTests
internal partial class StreamTests
{
[Test]
[CLSCompliant(false)]
public void ReadUInt32_ShouldThrowArgumentException_GivenNonReadableStream()
{
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.ReadUInt32());
Assert.Throws<ArgumentException>(() => stream.ReadUInt32(Endianness.LittleEndian));
Assert.Throws<ArgumentException>(() => stream.ReadUInt32(Endianness.BigEndian));
}
[Test]
[CLSCompliant(false)]
public void ReadUInt32_ShouldThrowArgumentNullException_GivenNullStream()
public void ReadUInt32BigEndian_ShouldThrowArgumentNullException_GivenNullStream()
{
Stream stream = null!;
Assert.Throws<ArgumentNullException>(() => stream.ReadUInt32());
Assert.Throws<ArgumentNullException>(() => stream.ReadUInt32(Endianness.LittleEndian));
Assert.Throws<ArgumentNullException>(() => stream.ReadUInt32(Endianness.BigEndian));
Assert.Throws<ArgumentNullException>(() => stream.ReadUInt32BigEndian());
}
[Test]
[CLSCompliant(false)]
public void ReadUInt32_ShouldThrowArgumentOutOfRangeException_GivenInvalidEndiannessValue()
public void ReadUInt32LittleEndian_ShouldThrowArgumentNullException_GivenNullStream()
{
// we don't need to enclose this stream in a using declaration, since disposing a
// null stream is meaningless. NullStream.Dispose actually does nothing, anyway.
// that - coupled with the fact that encapsulating the stream in a using declaration causes the
// analyser to trip up and think the stream is disposed by the time the local is captured in
// assertion lambda - means this line is fine as it is. please do not change.
Stream stream = Stream.Null;
Assert.Throws<ArgumentOutOfRangeException>(() => stream.ReadUInt32((Endianness)(-1)));
Stream stream = null!;
Assert.Throws<ArgumentNullException>(() => stream.ReadUInt32LittleEndian());
}
[Test]
[CLSCompliant(false)]
public void ReadUInt32_ShouldReadBigEndian_GivenBigEndian()
[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope")]
public void ReadUInt32BigEndian_ShouldThrowArgumentException_GivenNonReadableStream()
{
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.ReadUInt32BigEndian());
}
[Test]
[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope")]
public void ReadUInt32LittleEndian_ShouldThrowArgumentException_GivenNonReadableStream()
{
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.ReadUInt32LittleEndian());
}
[Test]
public void ReadUInt32BigEndian_ShouldReadBigEndian()
{
using var stream = new MemoryStream();
ReadOnlySpan<byte> bytes = stackalloc byte[] {0x00, 0x00, 0x01, 0xA4};
ReadOnlySpan<byte> bytes = stackalloc byte[] { 0x00, 0x00, 0x01, 0xA4 };
stream.Write(bytes);
stream.Position = 0;
const uint expected = 420;
uint actual = stream.ReadUInt32(Endianness.BigEndian);
uint actual = stream.ReadUInt32BigEndian();
Assert.That(stream.Position, Is.EqualTo(4));
Assert.That(actual, Is.EqualTo(expected));
}
[Test]
[CLSCompliant(false)]
public void ReadUInt32_ShouldReadLittleEndian_GivenLittleEndian()
public void ReadUInt32LittleEndian_ShouldReadLittleEndian()
{
using var stream = new MemoryStream();
ReadOnlySpan<byte> bytes = stackalloc byte[] {0xA4, 0x01, 0x00, 0x00};
ReadOnlySpan<byte> bytes = stackalloc byte[] { 0xA4, 0x01, 0x00, 0x00 };
stream.Write(bytes);
stream.Position = 0;
const uint expected = 420;
uint actual = stream.ReadUInt32(Endianness.LittleEndian);
uint actual = stream.ReadUInt32LittleEndian();
Assert.That(stream.Position, Is.EqualTo(4));
Assert.That(actual, Is.EqualTo(expected));

View File

@ -1,70 +1,66 @@
using NUnit.Framework;
using System.Diagnostics.CodeAnalysis;
using NUnit.Framework;
using X10D.IO;
namespace X10D.Tests.IO;
public partial class StreamTests
internal partial class StreamTests
{
[Test]
[CLSCompliant(false)]
public void ReadUInt64_ShouldThrowArgumentException_GivenNonReadableStream()
{
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.ReadUInt64());
Assert.Throws<ArgumentException>(() => stream.ReadUInt64(Endianness.LittleEndian));
Assert.Throws<ArgumentException>(() => stream.ReadUInt64(Endianness.BigEndian));
}
[Test]
[CLSCompliant(false)]
public void ReadUInt64_ShouldThrowArgumentNullException_GivenNullStream()
public void ReadUInt64BigEndian_ShouldThrowArgumentNullException_GivenNullStream()
{
Stream stream = null!;
Assert.Throws<ArgumentNullException>(() => stream.ReadUInt64());
Assert.Throws<ArgumentNullException>(() => stream.ReadUInt64(Endianness.LittleEndian));
Assert.Throws<ArgumentNullException>(() => stream.ReadUInt64(Endianness.BigEndian));
Assert.Throws<ArgumentNullException>(() => stream.ReadUInt64BigEndian());
}
[Test]
[CLSCompliant(false)]
public void ReadUInt64_ShouldThrowArgumentOutOfRangeException_GivenInvalidEndiannessValue()
public void ReadUInt64LittleEndian_ShouldThrowArgumentNullException_GivenNullStream()
{
// we don't need to enclose this stream in a using declaration, since disposing a
// null stream is meaningless. NullStream.Dispose actually does nothing, anyway.
// that - coupled with the fact that encapsulating the stream in a using declaration causes the
// analyser to trip up and think the stream is disposed by the time the local is captured in
// assertion lambda - means this line is fine as it is. please do not change.
Stream stream = Stream.Null;
Assert.Throws<ArgumentOutOfRangeException>(() => stream.ReadUInt64((Endianness)(-1)));
Stream stream = null!;
Assert.Throws<ArgumentNullException>(() => stream.ReadUInt64LittleEndian());
}
[Test]
[CLSCompliant(false)]
public void ReadUInt64_ShouldReadBigEndian_GivenBigEndian()
[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope")]
public void ReadUInt64BigEndian_ShouldThrowArgumentException_GivenNonReadableStream()
{
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.ReadUInt64BigEndian());
}
[Test]
[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope")]
public void ReadUInt64LittleEndian_ShouldThrowArgumentException_GivenNonReadableStream()
{
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.ReadUInt64LittleEndian());
}
[Test]
public void ReadUInt64BigEndian_ShouldReadBigEndian()
{
using var stream = new MemoryStream();
ReadOnlySpan<byte> bytes = stackalloc byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA4};
ReadOnlySpan<byte> bytes = stackalloc byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA4 };
stream.Write(bytes);
stream.Position = 0;
const ulong expected = 420;
ulong actual = stream.ReadUInt64(Endianness.BigEndian);
ulong actual = stream.ReadUInt64BigEndian();
Assert.That(stream.Position, Is.EqualTo(8));
Assert.That(actual, Is.EqualTo(expected));
}
[Test]
[CLSCompliant(false)]
public void ReadUInt64_ShouldWriteLittleEndian_GivenLittleEndian()
public void ReadUInt64LittleEndian_ShouldWriteLittleEndian()
{
using var stream = new MemoryStream();
ReadOnlySpan<byte> bytes = stackalloc byte[] {0xA4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
ReadOnlySpan<byte> bytes = stackalloc byte[] { 0xA4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
stream.Write(bytes);
stream.Position = 0;
const ulong expected = 420;
ulong actual = stream.ReadUInt64(Endianness.LittleEndian);
ulong actual = stream.ReadUInt64LittleEndian();
Assert.That(stream.Position, Is.EqualTo(8));
Assert.That(actual, Is.EqualTo(expected));

View File

@ -1,45 +1,47 @@
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using NUnit.Framework;
using X10D.IO;
namespace X10D.Tests.IO;
public partial class StreamTests
internal partial class StreamTests
{
[Test]
public void WriteDecimal_ShouldThrowArgumentException_GivenNonWriteableStream()
{
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.Write(420.0m, Endianness.LittleEndian));
Assert.Throws<ArgumentException>(() => stream.Write(420.0m, Endianness.BigEndian));
}
[Test]
public void WriteDecimal_ShouldThrowArgumentNullException_GivenNullStream()
public void WriteBigEndian_ShouldThrowArgumentNullException_GivenNullStream_AndDecimalArgument()
{
Stream stream = null!;
Assert.Throws<ArgumentNullException>(() => stream.Write(420.0m, Endianness.LittleEndian));
Assert.Throws<ArgumentNullException>(() => stream.Write(420.0m, Endianness.BigEndian));
Assert.Throws<ArgumentNullException>(() => stream.WriteBigEndian(420.0m));
}
[Test]
public void WriteDecimal_ShouldThrowArgumentOutOfRangeException_GivenInvalidEndiannessValue()
[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope")]
public void WriteBigEndian_ShouldThrowArgumentException_GivenNonWritableStream_AndDecimalArgument()
{
// we don't need to enclose this stream in a using declaration, since disposing a
// null stream is meaningless. NullStream.Dispose actually does nothing, anyway.
// that - coupled with the fact that encapsulating the stream in a using declaration causes the
// analyser to trip up and think the stream is disposed by the time the local is captured in
// assertion lambda - means this line is fine as it is. please do not change.
Stream stream = Stream.Null;
Assert.Throws<ArgumentOutOfRangeException>(() => stream.Write(420.0m, (Endianness)(-1)));
Assert.Throws<ArgumentOutOfRangeException>(() => stream.Write(420.0m, (Endianness)(-1)));
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.WriteBigEndian(420.0m));
}
[Test]
public void WriteDecimal_ShouldWriteBigEndian_GivenBigEndian()
public void WriteLittleEndian_ShouldThrowArgumentNullException_GivenNullStream_AndDecimalArgument()
{
Stream stream = null!;
Assert.Throws<ArgumentNullException>(() => stream.WriteLittleEndian(420.0m));
}
[Test]
[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope")]
public void WriteLittleEndian_ShouldThrowArgumentException_GivenNonWritableStream_AndDecimalArgument()
{
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.WriteLittleEndian(420.0m));
}
[Test]
public void WriteBigEndian_ShouldWriteBigEndian_GivenDecimalArgument()
{
using var stream = new MemoryStream();
stream.Write(420.0m, Endianness.BigEndian);
stream.WriteBigEndian(420.0m);
Assert.That(stream.Position, Is.EqualTo(16));
stream.Position = 0;
@ -49,16 +51,17 @@ public partial class StreamTests
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x68
};
int read = stream.Read(actual);
Trace.WriteLine(string.Join(' ', actual.ToArray()));
Assert.That(read, Is.EqualTo(16));
CollectionAssert.AreEqual(expected.ToArray(), actual.ToArray());
}
[Test]
public void WriteDecimal_ShouldWriteLittleEndian_GivenLittleEndian()
public void WriteLittleEndian_ShouldWriteLittleEndian_GivenDecimalArgument()
{
using var stream = new MemoryStream();
stream.Write(420.0m, Endianness.LittleEndian);
stream.WriteLittleEndian(420.0m);
Assert.That(stream.Position, Is.EqualTo(16));
stream.Position = 0;

View File

@ -1,49 +1,51 @@
using NUnit.Framework;
using System.Diagnostics.CodeAnalysis;
using NUnit.Framework;
using X10D.IO;
namespace X10D.Tests.IO;
public partial class StreamTests
internal partial class StreamTests
{
[Test]
public void WriteDouble_ShouldThrowArgumentException_GivenNonWriteableStream()
{
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.Write(420.0, Endianness.LittleEndian));
Assert.Throws<ArgumentException>(() => stream.Write(420.0, Endianness.BigEndian));
}
[Test]
public void WriteDouble_ShouldThrowArgumentNullException_GivenNullStream()
public void WriteBigEndian_ShouldThrowArgumentNullException_GivenNullStream_AndDoubleArgument()
{
Stream stream = null!;
Assert.Throws<ArgumentNullException>(() => stream.Write(420.0, Endianness.LittleEndian));
Assert.Throws<ArgumentNullException>(() => stream.Write(420.0, Endianness.BigEndian));
Assert.Throws<ArgumentNullException>(() => stream.WriteBigEndian(420.0));
}
[Test]
public void WriteDouble_ShouldThrowArgumentOutOfRangeException_GivenInvalidEndiannessValue()
[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope")]
public void WriteBigEndian_ShouldThrowArgumentException_GivenNonWritableStream_AndDoubleArgument()
{
// we don't need to enclose this stream in a using declaration, since disposing a
// null stream is meaningless. NullStream.Dispose actually does nothing, anyway.
// that - coupled with the fact that encapsulating the stream in a using declaration causes the
// analyser to trip up and think the stream is disposed by the time the local is captured in
// assertion lambda - means this line is fine as it is. please do not change.
Stream stream = Stream.Null;
Assert.Throws<ArgumentOutOfRangeException>(() => stream.Write(420.0, (Endianness)(-1)));
Assert.Throws<ArgumentOutOfRangeException>(() => stream.Write(420.0, (Endianness)(-1)));
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.WriteBigEndian(420.0));
}
[Test]
public void WriteDouble_ShouldWriteBigEndian_GivenBigEndian()
public void WriteLittleEndian_ShouldThrowArgumentNullException_GivenNullStream_AndDoubleArgument()
{
Stream stream = null!;
Assert.Throws<ArgumentNullException>(() => stream.WriteLittleEndian(420.0));
}
[Test]
[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope")]
public void WriteLittleEndian_ShouldThrowArgumentException_GivenNonWritableStream_AndDoubleArgument()
{
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.WriteLittleEndian(420.0));
}
[Test]
public void WriteBigEndian_ShouldWriteBigEndian_GivenDoubleArgument()
{
using var stream = new MemoryStream();
stream.Write(420.0, Endianness.BigEndian);
stream.WriteBigEndian(420.0);
Assert.That(stream.Position, Is.EqualTo(8));
stream.Position = 0;
Span<byte> actual = stackalloc byte[8];
ReadOnlySpan<byte> expected = stackalloc byte[] {0x40, 0x7A, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00};
ReadOnlySpan<byte> expected = stackalloc byte[] { 0x40, 0x7A, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00 };
int read = stream.Read(actual);
Assert.That(read, Is.EqualTo(8));
@ -51,15 +53,15 @@ public partial class StreamTests
}
[Test]
public void WriteDouble_ShouldWriteLittleEndian_GivenLittleEndian()
public void WriteLittleEndian_ShouldWriteLittleEndian_GivenDoubleArgument()
{
using var stream = new MemoryStream();
stream.Write(420.0, Endianness.LittleEndian);
stream.WriteLittleEndian(420.0);
Assert.That(stream.Position, Is.EqualTo(8));
stream.Position = 0;
Span<byte> actual = stackalloc byte[8];
ReadOnlySpan<byte> expected = stackalloc byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7A, 0x40};
ReadOnlySpan<byte> expected = stackalloc byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7A, 0x40 };
int read = stream.Read(actual);
Assert.That(read, Is.EqualTo(8));

View File

@ -1,49 +1,51 @@
using NUnit.Framework;
using System.Diagnostics.CodeAnalysis;
using NUnit.Framework;
using X10D.IO;
namespace X10D.Tests.IO;
public partial class StreamTests
internal partial class StreamTests
{
[Test]
public void WriteInt16_ShouldThrowArgumentException_GivenNonWriteableStream()
{
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.Write((short)420, Endianness.LittleEndian));
Assert.Throws<ArgumentException>(() => stream.Write((short)420, Endianness.BigEndian));
}
[Test]
public void WriteInt16_ShouldThrowArgumentNullException_GivenNullStream()
public void WriteBigEndian_ShouldThrowArgumentNullException_GivenNullStream_AndInt16Argument()
{
Stream stream = null!;
Assert.Throws<ArgumentNullException>(() => stream.Write((short)420, Endianness.LittleEndian));
Assert.Throws<ArgumentNullException>(() => stream.Write((short)420, Endianness.BigEndian));
Assert.Throws<ArgumentNullException>(() => stream.WriteBigEndian((short)420));
}
[Test]
public void WriteInt16_ShouldThrowArgumentOutOfRangeException_GivenInvalidEndiannessValue()
[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope")]
public void WriteBigEndian_ShouldThrowArgumentException_GivenNonWritableStream_AndInt16Argument()
{
// we don't need to enclose this stream in a using declaration, since disposing a
// null stream is meaningless. NullStream.Dispose actually does nothing, anyway.
// that - coupled with the fact that encapsulating the stream in a using declaration causes the
// analyser to trip up and think the stream is disposed by the time the local is captured in
// assertion lambda - means this line is fine as it is. please do not change.
Stream stream = Stream.Null;
Assert.Throws<ArgumentOutOfRangeException>(() => stream.Write((short)420, (Endianness)(-1)));
Assert.Throws<ArgumentOutOfRangeException>(() => stream.Write((short)420, (Endianness)(-1)));
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.WriteBigEndian((short)420));
}
[Test]
public void WriteInt16_ShouldWriteBigEndian_GivenBigEndian()
public void WriteLittleEndian_ShouldThrowArgumentNullException_GivenNullStream_AndInt16Argument()
{
Stream stream = null!;
Assert.Throws<ArgumentNullException>(() => stream.WriteLittleEndian((short)420));
}
[Test]
[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope")]
public void WriteLittleEndian_ShouldThrowArgumentException_GivenNonWritableStream_AndInt16Argument()
{
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.WriteLittleEndian((short)420));
}
[Test]
public void WriteBigEndian_ShouldWriteBigEndian_GivenInt16Argument()
{
using var stream = new MemoryStream();
stream.Write((short)420, Endianness.BigEndian);
stream.WriteBigEndian((short)420);
Assert.That(stream.Position, Is.EqualTo(2));
stream.Position = 0;
Span<byte> actual = stackalloc byte[2];
ReadOnlySpan<byte> expected = stackalloc byte[] {0x01, 0xA4};
ReadOnlySpan<byte> expected = stackalloc byte[] { 0x01, 0xA4 };
int read = stream.Read(actual);
Assert.That(read, Is.EqualTo(2));
@ -51,15 +53,15 @@ public partial class StreamTests
}
[Test]
public void WriteInt16_ShouldWriteLittleEndian_GivenLittleEndian()
public void WriteLittleEndian_ShouldWriteLittleEndian_GivenInt16Argument()
{
using var stream = new MemoryStream();
stream.Write((short)420, Endianness.LittleEndian);
stream.WriteLittleEndian((short)420);
Assert.That(stream.Position, Is.EqualTo(2));
stream.Position = 0;
Span<byte> actual = stackalloc byte[2];
ReadOnlySpan<byte> expected = stackalloc byte[] {0xA4, 0x01};
ReadOnlySpan<byte> expected = stackalloc byte[] { 0xA4, 0x01 };
int read = stream.Read(actual);
Assert.That(read, Is.EqualTo(2));

View File

@ -1,49 +1,51 @@
using NUnit.Framework;
using System.Diagnostics.CodeAnalysis;
using NUnit.Framework;
using X10D.IO;
namespace X10D.Tests.IO;
public partial class StreamTests
internal partial class StreamTests
{
[Test]
public void WriteInt32_ShouldThrowArgumentException_GivenNonWriteableStream()
{
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.Write(420, Endianness.LittleEndian));
Assert.Throws<ArgumentException>(() => stream.Write(420, Endianness.BigEndian));
}
[Test]
public void WriteInt32_ShouldThrowArgumentNullException_GivenNullStream()
public void WriteBigEndian_ShouldThrowArgumentNullException_GivenNullStream_AndInt32Argument()
{
Stream stream = null!;
Assert.Throws<ArgumentNullException>(() => stream.Write(420, Endianness.LittleEndian));
Assert.Throws<ArgumentNullException>(() => stream.Write(420, Endianness.BigEndian));
Assert.Throws<ArgumentNullException>(() => stream.WriteBigEndian(420));
}
[Test]
public void WriteInt32_ShouldThrowArgumentOutOfRangeException_GivenInvalidEndiannessValue()
[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope")]
public void WriteBigEndian_ShouldThrowArgumentException_GivenNonWritableStream_AndInt32Argument()
{
// we don't need to enclose this stream in a using declaration, since disposing a
// null stream is meaningless. NullStream.Dispose actually does nothing, anyway.
// that - coupled with the fact that encapsulating the stream in a using declaration causes the
// analyser to trip up and think the stream is disposed by the time the local is captured in
// assertion lambda - means this line is fine as it is. please do not change.
Stream stream = Stream.Null;
Assert.Throws<ArgumentOutOfRangeException>(() => stream.Write(420, (Endianness)(-1)));
Assert.Throws<ArgumentOutOfRangeException>(() => stream.Write(420, (Endianness)(-1)));
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.WriteBigEndian(420));
}
[Test]
public void WriteInt32_ShouldWriteBigEndian_GivenBigEndian()
public void WriteLittleEndian_ShouldThrowArgumentNullException_GivenNullStream_AndInt32Argument()
{
Stream stream = null!;
Assert.Throws<ArgumentNullException>(() => stream.WriteLittleEndian(420));
}
[Test]
[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope")]
public void WriteLittleEndian_ShouldThrowArgumentException_GivenNonWritableStream_AndInt32Argument()
{
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.WriteLittleEndian(420));
}
[Test]
public void WriteBigEndian_ShouldWriteBigEndian_GivenInt32Argument()
{
using var stream = new MemoryStream();
stream.Write(420, Endianness.BigEndian);
stream.WriteBigEndian(420);
Assert.That(stream.Position, Is.EqualTo(4));
stream.Position = 0;
Span<byte> actual = stackalloc byte[4];
ReadOnlySpan<byte> expected = stackalloc byte[] {0x00, 0x00, 0x01, 0xA4};
ReadOnlySpan<byte> expected = stackalloc byte[] { 0x00, 0x00, 0x01, 0xA4 };
int read = stream.Read(actual);
Assert.That(read, Is.EqualTo(4));
@ -51,15 +53,15 @@ public partial class StreamTests
}
[Test]
public void WriteInt32_ShouldWriteLittleEndian_GivenLittleEndian()
public void WriteLittleEndian_ShouldWriteLittleEndian_GivenInt32Argument()
{
using var stream = new MemoryStream();
stream.Write(420, Endianness.LittleEndian);
stream.WriteLittleEndian(420);
Assert.That(stream.Position, Is.EqualTo(4));
stream.Position = 0;
Span<byte> actual = stackalloc byte[4];
ReadOnlySpan<byte> expected = stackalloc byte[] {0xA4, 0x01, 0x00, 0x00};
ReadOnlySpan<byte> expected = stackalloc byte[] { 0xA4, 0x01, 0x00, 0x00 };
int read = stream.Read(actual);
Assert.That(read, Is.EqualTo(4));

View File

@ -1,49 +1,51 @@
using NUnit.Framework;
using System.Diagnostics.CodeAnalysis;
using NUnit.Framework;
using X10D.IO;
namespace X10D.Tests.IO;
public partial class StreamTests
internal partial class StreamTests
{
[Test]
public void WriteInt64_ShouldThrowArgumentException_GivenNonWriteableStream()
{
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.Write(420L, Endianness.LittleEndian));
Assert.Throws<ArgumentException>(() => stream.Write(420L, Endianness.BigEndian));
}
[Test]
public void WriteInt64_ShouldThrowArgumentNullException_GivenNullStream()
public void WriteBigEndian_ShouldThrowArgumentNullException_GivenNullStream_AndInt64Argument()
{
Stream stream = null!;
Assert.Throws<ArgumentNullException>(() => stream.Write(420L, Endianness.LittleEndian));
Assert.Throws<ArgumentNullException>(() => stream.Write(420L, Endianness.BigEndian));
Assert.Throws<ArgumentNullException>(() => stream.WriteBigEndian(420L));
}
[Test]
public void WriteInt64_ShouldThrowArgumentOutOfRangeException_GivenInvalidEndiannessValue()
[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope")]
public void WriteBigEndian_ShouldThrowArgumentException_GivenNonWritableStream_AndInt64Argument()
{
// we don't need to enclose this stream in a using declaration, since disposing a
// null stream is meaningless. NullStream.Dispose actually does nothing, anyway.
// that - coupled with the fact that encapsulating the stream in a using declaration causes the
// analyser to trip up and think the stream is disposed by the time the local is captured in
// assertion lambda - means this line is fine as it is. please do not change.
Stream stream = Stream.Null;
Assert.Throws<ArgumentOutOfRangeException>(() => stream.Write(420L, (Endianness)(-1)));
Assert.Throws<ArgumentOutOfRangeException>(() => stream.Write(420L, (Endianness)(-1)));
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.WriteBigEndian(420L));
}
[Test]
public void WriteInt64_ShouldWriteBigEndian_GivenBigEndian()
public void WriteLittleEndian_ShouldThrowArgumentNullException_GivenNullStream_AndInt64Argument()
{
Stream stream = null!;
Assert.Throws<ArgumentNullException>(() => stream.WriteLittleEndian(420L));
}
[Test]
[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope")]
public void WriteLittleEndian_ShouldThrowArgumentException_GivenNonWritableStream_AndInt64Argument()
{
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.WriteLittleEndian(420L));
}
[Test]
public void WriteBigEndian_ShouldWriteBigEndian_GivenInt64Argument()
{
using var stream = new MemoryStream();
stream.Write(420L, Endianness.BigEndian);
stream.WriteBigEndian(420L);
Assert.That(stream.Position, Is.EqualTo(8));
stream.Position = 0;
Span<byte> actual = stackalloc byte[8];
ReadOnlySpan<byte> expected = stackalloc byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA4};
ReadOnlySpan<byte> expected = stackalloc byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA4 };
int read = stream.Read(actual);
Assert.That(read, Is.EqualTo(8));
@ -51,15 +53,15 @@ public partial class StreamTests
}
[Test]
public void WriteInt64_ShouldWriteLittleEndian_GivenLittleEndian()
public void WriteLittleEndian_ShouldWriteLittleEndian_GivenLittleEndian()
{
using var stream = new MemoryStream();
stream.Write(420L, Endianness.LittleEndian);
stream.WriteLittleEndian(420L);
Assert.That(stream.Position, Is.EqualTo(8));
stream.Position = 0;
Span<byte> actual = stackalloc byte[8];
ReadOnlySpan<byte> expected = stackalloc byte[] {0xA4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
ReadOnlySpan<byte> expected = stackalloc byte[] { 0xA4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
int read = stream.Read(actual);
Assert.That(read, Is.EqualTo(8));

View File

@ -1,49 +1,51 @@
using NUnit.Framework;
using System.Diagnostics.CodeAnalysis;
using NUnit.Framework;
using X10D.IO;
namespace X10D.Tests.IO;
public partial class StreamTests
internal partial class StreamTests
{
[Test]
public void WriteSingle_ShouldThrowArgumentException_GivenNonWriteableStream()
{
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.Write(420.0f, Endianness.LittleEndian));
Assert.Throws<ArgumentException>(() => stream.Write(420.0f, Endianness.BigEndian));
}
[Test]
public void WriteSingle_ShouldThrowArgumentNullException_GivenNullStream()
public void WriteBigEndian_ShouldThrowArgumentNullException_GivenNullStream_AndSingleArgument()
{
Stream stream = null!;
Assert.Throws<ArgumentNullException>(() => stream.Write(420.0f, Endianness.LittleEndian));
Assert.Throws<ArgumentNullException>(() => stream.Write(420.0f, Endianness.BigEndian));
Assert.Throws<ArgumentNullException>(() => stream.WriteBigEndian(420.0f));
}
[Test]
public void WriteSingle_ShouldThrowArgumentOutOfRangeException_GivenInvalidEndiannessValue()
[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope")]
public void WriteBigEndian_ShouldThrowArgumentException_GivenNonWritableStream_AndSingleArgument()
{
// we don't need to enclose this stream in a using declaration, since disposing a
// null stream is meaningless. NullStream.Dispose actually does nothing, anyway.
// that - coupled with the fact that encapsulating the stream in a using declaration causes the
// analyser to trip up and think the stream is disposed by the time the local is captured in
// assertion lambda - means this line is fine as it is. please do not change.
Stream stream = Stream.Null;
Assert.Throws<ArgumentOutOfRangeException>(() => stream.Write(420.0f, (Endianness)(-1)));
Assert.Throws<ArgumentOutOfRangeException>(() => stream.Write(420.0f, (Endianness)(-1)));
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.WriteBigEndian(420.0f));
}
[Test]
public void WriteSingle_ShouldWriteBigEndian_GivenBigEndian()
public void WriteLittleEndian_ShouldThrowArgumentNullException_GivenNullStream_AndSingleArgument()
{
Stream stream = null!;
Assert.Throws<ArgumentNullException>(() => stream.WriteLittleEndian(420.0f));
}
[Test]
[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope")]
public void WriteLittleEndian_ShouldThrowArgumentException_GivenNonWritableStream_AndSingleArgument()
{
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.WriteLittleEndian(420.0f));
}
[Test]
public void WriteBigEndian_ShouldWriteBigEndian_GivenSingleArgument()
{
using var stream = new MemoryStream();
stream.Write(420.0f, Endianness.BigEndian);
stream.WriteBigEndian(420.0f);
Assert.That(stream.Position, Is.EqualTo(4));
stream.Position = 0;
Span<byte> actual = stackalloc byte[4];
ReadOnlySpan<byte> expected = stackalloc byte[] {0x43, 0xD2, 0x00, 0x00};
ReadOnlySpan<byte> expected = stackalloc byte[] { 0x43, 0xD2, 0x00, 0x00 };
int read = stream.Read(actual);
Assert.That(read, Is.EqualTo(4));
@ -51,15 +53,15 @@ public partial class StreamTests
}
[Test]
public void WriteSingle_ShouldWriteLittleEndian_GivenLittleEndian()
public void WriteLittleEndian_ShouldWriteLittleEndian_GivenSingleArgument()
{
using var stream = new MemoryStream();
stream.Write(420.0f, Endianness.LittleEndian);
stream.WriteLittleEndian(420.0f);
Assert.That(stream.Position, Is.EqualTo(4));
stream.Position = 0;
Span<byte> actual = stackalloc byte[4];
ReadOnlySpan<byte> expected = stackalloc byte[] {0x00, 0x00, 0xD2, 0x43};
ReadOnlySpan<byte> expected = stackalloc byte[] { 0x00, 0x00, 0xD2, 0x43 };
int read = stream.Read(actual);
Assert.That(read, Is.EqualTo(4));

View File

@ -1,53 +1,51 @@
using NUnit.Framework;
using System.Diagnostics.CodeAnalysis;
using NUnit.Framework;
using X10D.IO;
namespace X10D.Tests.IO;
public partial class StreamTests
internal partial class StreamTests
{
[Test]
[CLSCompliant(false)]
public void WriteUInt16_ShouldThrowArgumentException_GivenNonWriteableStream()
{
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.Write((ushort)420, Endianness.LittleEndian));
Assert.Throws<ArgumentException>(() => stream.Write((ushort)420, Endianness.BigEndian));
}
[Test]
[CLSCompliant(false)]
public void WriteUInt16_ShouldThrowArgumentNullException_GivenNullStream()
public void WriteBigEndian_ShouldThrowArgumentNullException_GivenNullStream_AndUInt16Argument()
{
Stream stream = null!;
Assert.Throws<ArgumentNullException>(() => stream.Write((ushort)420, Endianness.LittleEndian));
Assert.Throws<ArgumentNullException>(() => stream.Write((ushort)420, Endianness.BigEndian));
Assert.Throws<ArgumentNullException>(() => stream.WriteBigEndian((ushort)420));
}
[Test]
[CLSCompliant(false)]
public void WriteUInt16_ShouldThrowArgumentOutOfRangeException_GivenInvalidEndiannessValue()
[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope")]
public void WriteBigEndian_ShouldThrowArgumentException_GivenNonWritableStream_AndUInt16Argument()
{
// we don't need to enclose this stream in a using declaration, since disposing a
// null stream is meaningless. NullStream.Dispose actually does nothing, anyway.
// that - coupled with the fact that encapsulating the stream in a using declaration causes the
// analyser to trip up and think the stream is disposed by the time the local is captured in
// assertion lambda - means this line is fine as it is. please do not change.
Stream stream = Stream.Null;
Assert.Throws<ArgumentOutOfRangeException>(() => stream.Write((ushort)420, (Endianness)(-1)));
Assert.Throws<ArgumentOutOfRangeException>(() => stream.Write((ushort)420, (Endianness)(-1)));
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.WriteBigEndian((ushort)420));
}
[Test]
[CLSCompliant(false)]
public void WriteUInt16_ShouldWriteBigEndian_GivenBigEndian()
public void WriteLittleEndian_ShouldThrowArgumentNullException_GivenNullStream_AndUInt16Argument()
{
Stream stream = null!;
Assert.Throws<ArgumentNullException>(() => stream.WriteLittleEndian((ushort)420));
}
[Test]
[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope")]
public void WriteLittleEndian_ShouldThrowArgumentException_GivenNonWritableStream_AndUInt16Argument()
{
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.WriteLittleEndian((ushort)420));
}
[Test]
public void WriteBigEndian_ShouldWriteBigEndian_GivenUInt16Endian()
{
using var stream = new MemoryStream();
stream.Write((ushort)420, Endianness.BigEndian);
stream.WriteBigEndian((ushort)420);
Assert.That(stream.Position, Is.EqualTo(2));
stream.Position = 0;
Span<byte> actual = stackalloc byte[2];
ReadOnlySpan<byte> expected = stackalloc byte[] {0x01, 0xA4};
ReadOnlySpan<byte> expected = stackalloc byte[] { 0x01, 0xA4 };
int read = stream.Read(actual);
Assert.That(read, Is.EqualTo(2));
@ -55,16 +53,15 @@ public partial class StreamTests
}
[Test]
[CLSCompliant(false)]
public void WriteUInt16_ShouldWriteLittleEndian_GivenLittleEndian()
public void WriteLittleEndian_ShouldWriteLittleEndian_GivenUInt16tleEndian()
{
using var stream = new MemoryStream();
stream.Write((ushort)420, Endianness.LittleEndian);
stream.WriteLittleEndian((ushort)420);
Assert.That(stream.Position, Is.EqualTo(2));
stream.Position = 0;
Span<byte> actual = stackalloc byte[2];
ReadOnlySpan<byte> expected = stackalloc byte[] {0xA4, 0x01};
ReadOnlySpan<byte> expected = stackalloc byte[] { 0xA4, 0x01 };
int read = stream.Read(actual);
Assert.That(read, Is.EqualTo(2));

View File

@ -1,53 +1,51 @@
using NUnit.Framework;
using System.Diagnostics.CodeAnalysis;
using NUnit.Framework;
using X10D.IO;
namespace X10D.Tests.IO;
public partial class StreamTests
internal partial class StreamTests
{
[Test]
[CLSCompliant(false)]
public void WriteUInt32_ShouldThrowArgumentException_GivenNonWriteableStream()
{
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.Write(420U, Endianness.LittleEndian));
Assert.Throws<ArgumentException>(() => stream.Write(420U, Endianness.BigEndian));
}
[Test]
[CLSCompliant(false)]
public void WriteUInt32_ShouldThrowArgumentNullException_GivenNullStream()
public void WriteBigEndian_ShouldThrowArgumentNullException_GivenNullStream_AndUInt32Argument()
{
Stream stream = null!;
Assert.Throws<ArgumentNullException>(() => stream.Write(420U, Endianness.LittleEndian));
Assert.Throws<ArgumentNullException>(() => stream.Write(420U, Endianness.BigEndian));
Assert.Throws<ArgumentNullException>(() => stream.WriteBigEndian(420U));
}
[Test]
[CLSCompliant(false)]
public void WriteUInt32_ShouldThrowArgumentOutOfRangeException_GivenInvalidEndiannessValue()
[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope")]
public void WriteBigEndian_ShouldThrowArgumentException_GivenNonWritableStream_AndUInt32Argument()
{
// we don't need to enclose this stream in a using declaration, since disposing a
// null stream is meaningless. NullStream.Dispose actually does nothing, anyway.
// that - coupled with the fact that encapsulating the stream in a using declaration causes the
// analyser to trip up and think the stream is disposed by the time the local is captured in
// assertion lambda - means this line is fine as it is. please do not change.
Stream stream = Stream.Null;
Assert.Throws<ArgumentOutOfRangeException>(() => stream.Write(420U, (Endianness)(-1)));
Assert.Throws<ArgumentOutOfRangeException>(() => stream.Write(420U, (Endianness)(-1)));
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.WriteBigEndian(420U));
}
[Test]
[CLSCompliant(false)]
public void WriteUInt32_ShouldWriteBigEndian_GivenBigEndian()
public void WriteLittleEndian_ShouldThrowArgumentNullException_GivenNullStream_AndUInt32Argument()
{
Stream stream = null!;
Assert.Throws<ArgumentNullException>(() => stream.WriteLittleEndian(420U));
}
[Test]
[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope")]
public void WriteLittleEndian_ShouldThrowArgumentException_GivenNonWritableStream_AndUInt32Argument()
{
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.WriteLittleEndian(420U));
}
[Test]
public void WriteBigEndian_ShouldWriteBigEndian_GivenUInt32Argument()
{
using var stream = new MemoryStream();
stream.Write(420U, Endianness.BigEndian);
stream.WriteBigEndian(420U);
Assert.That(stream.Position, Is.EqualTo(4));
stream.Position = 0;
Span<byte> actual = stackalloc byte[4];
ReadOnlySpan<byte> expected = stackalloc byte[] {0x00, 0x00, 0x01, 0xA4};
ReadOnlySpan<byte> expected = stackalloc byte[] { 0x00, 0x00, 0x01, 0xA4 };
int read = stream.Read(actual);
Assert.That(read, Is.EqualTo(4));
@ -55,16 +53,15 @@ public partial class StreamTests
}
[Test]
[CLSCompliant(false)]
public void WriteUInt32_ShouldWriteLittleEndian_GivenLittleEndian()
public void WriteLittleEndian_ShouldWriteLittleEndian_GivenUInt32Argument()
{
using var stream = new MemoryStream();
stream.Write(420U, Endianness.LittleEndian);
stream.WriteLittleEndian(420U);
Assert.That(stream.Position, Is.EqualTo(4));
stream.Position = 0;
Span<byte> actual = stackalloc byte[4];
ReadOnlySpan<byte> expected = stackalloc byte[] {0xA4, 0x01, 0x00, 0x00};
ReadOnlySpan<byte> expected = stackalloc byte[] { 0xA4, 0x01, 0x00, 0x00 };
int read = stream.Read(actual);
Assert.That(read, Is.EqualTo(4));

View File

@ -1,53 +1,51 @@
using NUnit.Framework;
using System.Diagnostics.CodeAnalysis;
using NUnit.Framework;
using X10D.IO;
namespace X10D.Tests.IO;
public partial class StreamTests
internal partial class StreamTests
{
[Test]
[CLSCompliant(false)]
public void WriteUInt64_ShouldThrowArgumentException_GivenNonWriteableStream()
{
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.Write(420UL, Endianness.LittleEndian));
Assert.Throws<ArgumentException>(() => stream.Write(420UL, Endianness.BigEndian));
}
[Test]
[CLSCompliant(false)]
public void WriteUInt64_ShouldThrowArgumentNullException_GivenNullStream()
public void WriteBigEndian_ShouldThrowArgumentNullException_GivenNullStream_AndUInt64Argument()
{
Stream stream = null!;
Assert.Throws<ArgumentNullException>(() => stream.Write(420UL, Endianness.LittleEndian));
Assert.Throws<ArgumentNullException>(() => stream.Write(420UL, Endianness.BigEndian));
Assert.Throws<ArgumentNullException>(() => stream.WriteBigEndian(420UL));
}
[Test]
[CLSCompliant(false)]
public void WriteUInt64_ShouldThrowArgumentOutOfRangeException_GivenInvalidEndiannessValue()
[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope")]
public void WriteBigEndian_ShouldThrowArgumentException_GivenNonWritableStream_AndUInt64Argument()
{
// we don't need to enclose this stream in a using declaration, since disposing a
// null stream is meaningless. NullStream.Dispose actually does nothing, anyway.
// that - coupled with the fact that encapsulating the stream in a using declaration causes the
// analyser to trip up and think the stream is disposed by the time the local is captured in
// assertion lambda - means this line is fine as it is. please do not change.
Stream stream = Stream.Null;
Assert.Throws<ArgumentOutOfRangeException>(() => stream.Write(420UL, (Endianness)(-1)));
Assert.Throws<ArgumentOutOfRangeException>(() => stream.Write(420UL, (Endianness)(-1)));
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.WriteBigEndian(420UL));
}
[Test]
[CLSCompliant(false)]
public void WriteUInt64_ShouldWriteBigEndian_GivenBigEndian()
public void WriteLittleEndian_ShouldThrowArgumentNullException_GivenNullStream_AndUInt64Argument()
{
Stream stream = null!;
Assert.Throws<ArgumentNullException>(() => stream.WriteLittleEndian(420UL));
}
[Test]
[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope")]
public void WriteLittleEndian_ShouldThrowArgumentException_GivenNonWritableStream_AndUInt64Argument()
{
Stream stream = new DummyStream();
Assert.Throws<ArgumentException>(() => stream.WriteLittleEndian(420UL));
}
[Test]
public void WriteBigEndian_ShouldWriteBigEndian_GivenUInt64Argument()
{
using var stream = new MemoryStream();
stream.Write(420UL, Endianness.BigEndian);
stream.WriteBigEndian(420UL);
Assert.That(stream.Position, Is.EqualTo(8));
stream.Position = 0;
Span<byte> actual = stackalloc byte[8];
ReadOnlySpan<byte> expected = stackalloc byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA4};
ReadOnlySpan<byte> expected = stackalloc byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA4 };
int read = stream.Read(actual);
Assert.That(read, Is.EqualTo(8));
@ -55,16 +53,15 @@ public partial class StreamTests
}
[Test]
[CLSCompliant(false)]
public void WriteUInt64_ShouldWriteLittleEndian_GivenLittleEndian()
public void WriteLittleEndian_ShouldWriteLittleEndian_GivenUInt64Argument()
{
using var stream = new MemoryStream();
stream.Write(420UL, Endianness.LittleEndian);
stream.WriteLittleEndian(420UL);
Assert.That(stream.Position, Is.EqualTo(8));
stream.Position = 0;
Span<byte> actual = stackalloc byte[8];
ReadOnlySpan<byte> expected = stackalloc byte[] {0xA4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
ReadOnlySpan<byte> expected = stackalloc byte[] { 0xA4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
int read = stream.Read(actual);
Assert.That(read, Is.EqualTo(8));

View File

@ -7,7 +7,7 @@ using X10D.IO;
namespace X10D.Tests.IO;
[TestFixture]
public partial class StreamTests
internal partial class StreamTests
{
[Test]
public void GetHashSha1ShouldBeCorrect()
@ -86,16 +86,15 @@ public partial class StreamTests
[Test]
public void NullCreateMethodShouldThrow()
{
Assert.Throws<TypeInitializationException>(() => Stream.Null.GetHash<HashAlgorithmTestClass>());
Assert.Throws<TypeInitializationException>(() =>
Stream.Null.TryWriteHash<HashAlgorithmTestClass>(Span<byte>.Empty, out _));
Assert.Throws<ArgumentException>(() => Stream.Null.GetHash<HashAlgorithmTestClass>());
Assert.Throws<ArgumentException>(() => Stream.Null.TryWriteHash<HashAlgorithmTestClass>(Span<byte>.Empty, out _));
}
[Test]
public void NoCreateMethodShouldThrow()
{
Assert.Throws<TypeInitializationException>(() => Stream.Null.GetHash<HashAlgorithmTestClassNoCreateMethod>());
Assert.Throws<TypeInitializationException>(() =>
Assert.Throws<ArgumentException>(() => Stream.Null.GetHash<HashAlgorithmTestClassNoCreateMethod>());
Assert.Throws<ArgumentException>(() =>
Stream.Null.TryWriteHash<HashAlgorithmTestClassNoCreateMethod>(Span<byte>.Empty, out _));
}

View File

@ -1,11 +1,11 @@
using System.Text;
using System.Text;
using NUnit.Framework;
using X10D.IO;
namespace X10D.Tests.IO;
[TestFixture]
public class TextReaderTests
internal class TextReaderTests
{
[Test]
public void EnumerateLines_ShouldYield10Lines_Given10LineString()

Some files were not shown because too many files have changed in this diff Show More