Compare commits

...

146 Commits

Author SHA1 Message Date
Oliver Booth 6020a6e602
Merge pull request #85 from oliverbooth/release/4.0.0
4.0.0 major release
2024-06-12 14:11:23 +01:00
Oliver Booth 62cb9a36fe
feat: add EnqueueAll/DequeueAll, PushAll/PopAll for Queue and Stack 2024-06-12 14:06:54 +01:00
Oliver Booth b627d21b59
[ci skip] docs: update changelog to reflect #84 2024-06-12 13:44:11 +01:00
Oliver Booth b8a067130c
Merge pull request #84 from oliverbooth/feature/generic_math
Add support for generic math
2024-06-12 13:41:40 +01:00
Oliver Booth 7f9277287b
test: add 100% coverage for DigitalRoot
remove partial coverage by checking for 9
2024-06-12 13:38:52 +01:00
Oliver Booth db96c9e6fb
refactor(test): exclude platform-specific Unpack impl
can't have coverage on SSE3/AVX2 instructions if CPU doesn't support it.
2024-06-12 13:27:14 +01:00
Oliver Booth d022a71ce6
test: add tests for INumber<T>.Sign 2024-06-12 13:15:54 +01:00
Oliver Booth e51296d285
Merge branch 'release/4.0.0' into feature/generic_math 2024-06-12 12:10:27 +01:00
Oliver Booth 8eaa01b505
test: TryWriteBytes should return false for smol span 2024-06-12 11:59:47 +01:00
Oliver Booth 68197ef5c7
fix: fix order of bytes in decimal write bytes methods 2024-06-12 11:57:27 +01:00
Oliver Booth e5e27c0afd
[ci skip] test: remove NOSONAR markers 2024-06-12 11:52:31 +01:00
Oliver Booth c338f4263e
chore: favour use of c# 12 2024-06-12 11:50:48 +01:00
Oliver Booth d2924d7ac0
refactor!: remove extensions for Progress<T> 2024-06-12 04:00:25 +01:00
Oliver Booth 77dd144321
ci: ignore compile-generated file from coverage 2024-06-12 03:54:22 +01:00
Oliver Booth 69157b9517
ci: drop net7.0 target for tests 2024-06-12 03:46:46 +01:00
Oliver Booth 4a80c93cc2
chore!: drop net7.0 target (#90) 2024-06-12 03:45:51 +01:00
Oliver Booth f389731703
style: remove trailing whitespace on line 10 2024-06-12 03:42:21 +01:00
Oliver Booth 195e25e0e3
feat: add range-based foreach 2024-06-12 03:40:34 +01:00
Oliver Booth 19c467d88b
refactor!: move IsEven/IsOdd to NumberExtensions for .net>=7.0 2024-02-17 18:23:55 +00:00
Oliver Booth 3e0853d102
refactor!: move GCF to BinaryIntegerExtensions for .net>=7 2024-02-17 18:17:12 +00:00
Oliver Booth 30f158e861
refactor!: move Factorial to BinaryIntegerExtensions for .net>=7 2024-02-17 18:13:45 +00:00
Oliver Booth bd1b12da71
docs: update 3.x.x migration docs 2024-02-17 17:54:06 +00:00
Oliver Booth 8d2b4b011b
Merge branch 'main' into release/4.0.0 2024-02-17 17:28:53 +00:00
Oliver Booth eb46257b75
Merge branch 'release/4.0.0' into feature/generic_math 2024-02-17 17:27:56 +00:00
Oliver Booth 8459d8fc83
ci(test): use coverage from coverlet 2024-02-17 17:23:27 +00:00
Oliver Booth fdf1465730
test: coverlet output xml 2024-02-17 17:23:02 +00:00
Oliver Booth 69f0fa7b80
Merge branch 'release/4.0.0' into feature/generic_math 2024-02-17 16:12:39 +00:00
Oliver Booth 6501162857
fix(ci): convert coverage report to codecov supported format 2024-02-17 16:12:00 +00:00
Oliver Booth 39773a56c3
ci: output DetailedXML from dotcover 2024-02-17 16:08:40 +00:00
Oliver Booth 8cdbfcfe0d
Merge branch 'release/4.0.0' into feature/generic_math 2024-02-17 15:31:02 +00:00
Oliver Booth 29cd725b66
Merge branch 'main' into release/4.0.0 2024-02-17 15:30:41 +00:00
Oliver Booth 89de426d9a
ci: search for files with codecov 2024-02-17 03:04:19 +00:00
Oliver Booth 43128c4c64
Merge branch 'main' into release/4.0.0 2024-02-17 00:29:14 +00:00
Oliver Booth 1c09081240
Merge branch 'main' into release/4.0.0 2024-02-12 15:09:35 +00:00
Oliver Booth 447323f4d1
Merge branch 'main' into release/4.0.0 2024-02-12 14:45:56 +00:00
Oliver Booth 485501cfc0
ci(test): add dotCover output to codecov upload 2024-02-12 14:42:11 +00:00
Oliver Booth 22aaa96c23
Merge branch 'main' into release/4.0.0 2024-02-12 10:23:15 +00:00
Oliver Booth 6472c0fc84
Merge branch 'main' into release/4.0.0 2024-02-12 10:21:06 +00:00
Oliver Booth 99e0bef64d
Merge branch 'release/4.0.0' into feature/generic_math 2024-02-12 09:38:46 +00:00
Oliver Booth db3a80b6da
Merge branch 'main' into release/4.0.0 2024-02-12 09:34:35 +00:00
Oliver Booth f679ec294e
fix(tests): add test to fix coverage on DateOnly.Deconstruct 2024-02-12 02:35:17 +00:00
Oliver Booth 6750f0e3db
Merge branch 'main' into release/4.0.0 2024-02-12 01:50:34 +00:00
Oliver Booth 2b5c13300a
Merge branch 'main' into release/4.0.0 2024-02-12 01:47:17 +00:00
Oliver Booth cc94905930
Merge branch 'release/4.0.0' into feature/generic_math 2024-01-06 17:12:01 +00:00
Oliver Booth 7d911b9124
fix(tests): assert correct exception for IList<T>.RemoveRange 2024-01-06 17:11:47 +00:00
Oliver Booth 458ab03be0
style: remove double blank line 2024-01-06 17:03:19 +00:00
Oliver Booth be44b9d549
Merge branch 'release/4.0.0' into feature/generic_math 2024-01-06 17:01:42 +00:00
Oliver Booth ceb7989d2d
fix: revert changes by merge conflict from #89 2024-01-06 14:31:47 +00:00
Oliver Booth 2a89c8e6fe
Merge pull request #89 from RealityProgrammer/main
AdvSimd intrinsic obsoletion
2024-01-06 14:28:57 +00:00
Oliver Booth 87f5b39f3b
Merge branch 'release/4.0.0' into main 2024-01-06 14:27:05 +00:00
NN Huy Hoang 790b31a635 Remove trailing whitespace 2023-11-22 22:47:56 +07:00
NN Huy Hoang fa0ece667e Obsolete AdvSimd intrinsic implementations, minor improvements in certain areas 2023-11-22 22:29:46 +07:00
Oliver Booth d5c63feb5c
fix(tests): remove ambiguous call to Span<T>.Count (#88) 2023-11-14 16:57:25 +00:00
Oliver Booth ba451a0144
chore: update dependencies
* Microsoft.Extensions.Hosting 8.0.0
* Microsoft.NET.Test.Sdk 17.8.0
* NSubstitute 5.1.0
* NUnit 3.14.0
* NUnit3Analyzers 3.9.0
* NUnit.Analyzers 3.9.0
* coverlet.collector 6.0.0
* System.Reactive 6.0.0
2023-11-14 16:56:40 +00:00
Oliver Booth e2327b5235
refactor!: remove Span<T>.Replace for .NET 8 (#88) 2023-11-14 16:55:12 +00:00
Oliver Booth b6b90bf1fd
build: target .NET 8 (#88) 2023-11-14 16:49:53 +00:00
Oliver Booth b18e3ac97b
chore: add global.json to sln 2023-11-14 16:48:48 +00:00
Oliver Booth 4c91ec436f
fix(ci): drop netcoreapp3.1 from dotnet workflow (#87) 2023-09-13 00:52:19 +01:00
Oliver Booth c9955b53fc
fix: remove netcoreapp3.1 target from Benchmarks tool (#87) 2023-09-13 00:48:51 +01:00
Oliver Booth 85685c15a0
docs: mention target loss in changelog 2023-09-13 00:47:56 +01:00
Oliver Booth 8f9fc6ef7a
refactor: remove target-conditional branches (#87) 2023-09-13 00:46:12 +01:00
Oliver Booth 89f8ceb474
chore!: remove netstandard2.1/netcoreapp3.1 target (#87) 2023-09-13 00:33:07 +01:00
Oliver Booth b84d9c734a
refactor!: remove X10D.Unity + associated projects/workflows (#86) 2023-09-13 00:25:04 +01:00
Oliver Booth 0a2eb5edda
docs: give background and info 2023-08-28 13:41:19 +01:00
Oliver Booth 21f9a92491
docs: add more documentation pages 2023-08-28 13:41:03 +01:00
Oliver Booth b7d9a255e5
refactor!: add Bytes suffix to IO methods 2023-08-28 13:15:19 +01:00
Oliver Booth fc334d164c
chore: ignore Libraries folder 2023-08-28 13:05:01 +01:00
Oliver Booth 60c739f661
chore: don't share TargetFrameworks in build props 2023-08-28 13:04:16 +01:00
Oliver Booth f3023dbd9f
tests: add IsTestProject:true to csproj 2023-08-28 12:50:26 +01:00
Oliver Booth ea97616d57
chore: update X10D.Unity.Tests to 2021.3.29f1
The following packages have been upgraded:
- com.unity.collab-proxy 2.0.5
- com.ide.rider 3.0.24
- com.unity.ide.visualstudio 2.0.18
- com.unity.test-framework 1.1.33
- com.unity.timeline 1.6.5

The following packages have been added:
- com.unity.toolchain.win-x86_64-linux-x86_64 2.0.6
2023-08-28 12:50:02 +01:00
Oliver Booth 964d105f92
fix(chore): don't pull CHANGELOG.md contents in PackageReleaseNotes 2023-08-27 14:03:36 +01:00
Oliver Booth ff6b8d5465
feat: add Span overloads to complement char.Repeat/string.Repeat 2023-08-27 13:58:15 +01:00
Oliver Booth 56c3f117c7
style: discard pure return of Randomize 2023-08-27 13:45:24 +01:00
Oliver Booth 5220f386aa
style: amend 2fb91d5175 2023-08-27 13:45:07 +01:00
Oliver Booth dfa0bd4e11
style: add braces around parent for loop 2023-08-27 13:39:20 +01:00
Oliver Booth 20f81c5c97
test: use more meaningful test names 2023-08-27 13:38:58 +01:00
Oliver Booth 0d02c88ef6
test: use fluent Has.Length 2023-08-27 13:38:45 +01:00
Oliver Booth e115a8fa0e
style: format document 2023-08-27 13:38:31 +01:00
Oliver Booth 2fb91d5175
test: suppress CA1307 and add StringComparison overload calls 2023-08-27 13:38:14 +01:00
Oliver Booth 43d2e8feea
test: add tests for MDLink 2023-08-27 13:29:09 +01:00
Oliver Booth 2445e36cfd
fix(ci): install dotCover global tool for sonarcloud workflow 2023-08-27 13:13:13 +01:00
Oliver Booth 74f957f0c2
ci: update sonarcloud to Java 17
Also changes sonar.login option to sonar.token
2023-08-27 04:33:24 +01:00
Oliver Booth 1c58acd0a5
ci: rename sonarcloud workflow 2023-08-27 04:21:53 +01:00
Oliver Booth 579a1d8c89
style(docs): one-line <returns> element 2023-08-27 04:13:53 +01:00
Oliver Booth da08d23aee
style(tests): use more meaningful test names 2023-08-27 03:48:56 +01:00
Oliver Booth dc0b6abdc4
style(tests): use Has.Length for length assertion 2023-08-27 03:48:41 +01:00
Oliver Booth 45ffd08dda
tests: wrap multiple asserts in Assert.Multiple 2023-08-27 03:48:22 +01:00
Oliver Booth fbd3e951c4
fix: discard Repeat return value 2023-08-27 03:47:58 +01:00
Oliver Booth c6dbc4cebe
style: cap lines to 130 in length 2023-08-27 03:45:12 +01:00
Oliver Booth 41ba8b5aad
fix: include WriteBits to !NET5_0_OR_GREATER 2023-08-27 03:39:53 +01:00
Oliver Booth 5d936b5385
feat: add markdown formatting methods 2023-08-27 03:37:01 +01:00
Oliver Booth bd823ba818
perf: stackalloc single char span, instead of using ToString, for .NET 7
This removes the allocations caused by ToString(). Unfortunately, the ReadOnlySpan<char> overload is only available from .NET 7, and so this is a conditional performance gain. Shame.
2023-08-27 01:26:37 +01:00
Oliver Booth cfe70a7923
refactor: discard GetBits return 2023-08-26 18:50:49 +01:00
Oliver Booth 799e635577
style: mark WriteBits conditional 2023-08-26 18:50:37 +01:00
Oliver Booth b843d155f6
[ci skip] style: cap line length at 130 2023-08-26 18:40:23 +01:00
Oliver Booth 68968c1b0b
style: remove UTF8 BOM 2023-08-26 18:15:04 +01:00
Oliver Booth 9caa0acb7b
style: remove UTF8 BOM 2023-08-26 18:11:29 +01:00
Oliver Booth bb2f67e9b6
style: remove UTF8 BOM 2023-08-26 18:08:14 +01:00
Oliver Booth 2da8c7db7a
refactor: rename TNumber as TInteger 2023-08-25 02:53:06 +01:00
Oliver Booth b8f85e4270
refactor: CountDigits is Pure. also honour methodimpl 2023-08-25 02:50:15 +01:00
Oliver Booth 39dfea7622
[ci skip] fix: define CountDigits in the correct file
I'm an idiot.
2023-08-25 02:42:51 +01:00
Oliver Booth 423fb90cc4
feat: add IBinaryInteger<T>.CountDigits 2023-08-25 02:34:55 +01:00
Oliver Booth 8bc7372ba4
Merge branch 'release/4.0.0' into feature/generic_math 2023-08-25 02:27:08 +01:00
Oliver Booth 129cbfb51f
refactor: revert 50d9cad2f3 2023-08-24 02:29:59 +01:00
Oliver Booth f238d420f4
Merge branch 'main' into release/4.0.0 2023-08-24 01:54:42 +01:00
Oliver Booth 71b0bec85c
style(test): format span tests 2023-08-24 01:53:24 +01:00
Oliver Booth 50d9cad2f3
perf: optimise subsequent GetHash and TryWriteHash calls 2023-08-23 17:06:44 +01:00
Oliver Booth 1157e36eff
refactor: separate stream Read/Write methods to partials 2023-08-23 17:00:55 +01:00
Oliver Booth 30b7a465a7
fix: fix marshal of decimal for netstandard 2.1 2023-08-23 16:54:20 +01:00
Oliver Booth caa0070458
fix: fix incorrect endian swap 2023-08-23 16:43:33 +01:00
Oliver Booth ed46bcd0d8
Merge branch 'main' into release/4.0.0 2023-08-23 16:15:21 +01:00
Oliver Booth d90e949212
fix(ci): build on subdir branch push 2023-08-23 16:14:56 +01:00
Oliver Booth 28d7bee262
fix(tests): add support for trace logging during tests 2023-08-23 14:18:04 +01:00
Oliver Booth 0bf89bb82a
refactor!: change exception thrown by GetHash and TryWriteHash
The methods no longer throw TypeInitializationException, and instead now throw ArgumentException.
2023-08-23 14:17:42 +01:00
Oliver Booth 5c21c86a52
refactor!: replace Endianness enum with explicit Big/Little methods 2023-08-23 14:15:52 +01:00
Oliver Booth 15107ea90f
docs: fix xmldoc for Line3D 2023-08-22 23:53:13 +01:00
Oliver Booth fa375e7758
refactor: conditionally import System.Runtime.Intrinsics.X86 2023-08-22 23:38:18 +01:00
Oliver Booth b4ae55caaa
Merge branch 'main' into release/4.0.0 2023-08-22 23:27:35 +01:00
Oliver Booth c5f5ba9bb6
Merge branch 'main' into release/4.0.0 2023-08-22 23:25:33 +01:00
Oliver Booth 0868b698c5
[ci skip] docs: fix README branding header in X10D.Unity 2023-08-22 22:42:07 +01:00
Oliver Booth 9c5ed12cad
chore: enable NRT for tools 2023-08-22 22:40:59 +01:00
Oliver Booth 5b2c83e2eb
chore: define TargetFrameworks in shared props 2023-08-22 22:40:49 +01:00
Oliver Booth 1e71029f38
refactor: remove X10D.DSharpPlus 2023-08-22 17:52:49 +01:00
Oliver Booth 27e0ec54be
chore: extract shared build props 2023-08-22 17:46:44 +01:00
Oliver Booth 1b71d94084
chore: remove redundant shared props 2023-08-22 17:44:29 +01:00
Oliver Booth 4593a21065
fix(tools): clear Package property groups 2023-08-22 17:43:16 +01:00
Oliver Booth d17d94a8c1
chore: suppress NU1701 (#77) 2023-08-22 17:39:45 +01:00
Oliver Booth 24a7de7e8c
refactor: define test fixtures as internal 2023-08-22 17:32:47 +01:00
Oliver Booth e8a331ff96
chore: use shared Build.props for all projects 2023-08-22 17:11:20 +01:00
Oliver Booth a14fe4ca64
Merge branch 'main' into release/4.0.0 2023-08-21 17:41:05 +01:00
Oliver Booth 4c6ea59e2f
Merge branch 'main' into release/4.0.0 2023-08-21 17:28:32 +01:00
Oliver Booth 9b995524dd
feat: add service/impl register for AddHostedSingleton 2023-08-21 17:21:58 +01:00
Oliver Booth b977b7a4ec
Merge branch 'main' into release/4.0.0 2023-08-09 15:24:33 +01:00
Oliver Booth 8d7ca6ea0a
fix(tests): remove outdated tests
This should have been part of d8be858359
2023-05-14 16:31:57 +01:00
Oliver Booth d8be858359
refactor: remove IEnumerable.ConcatOne 2023-05-14 16:27:42 +01:00
Oliver Booth 23dee3d2b8
feat: add value-passthru overloads for ConcatIf 2023-04-14 14:17:33 +01:00
Oliver Booth 6f3a667e37
feat: add string.ConcatIf 2023-04-14 13:55:52 +01:00
Oliver Booth 63e2f7b69e
Merge branch 'main' into release/4.0.0 2023-04-13 23:27:53 +01:00
Oliver Booth 21907aef83
Merge branch 'main' into release/4.0.0 2023-04-13 23:15:16 +01:00
Oliver Booth dbc63b9b26
[ci skip] docs: bump version in README 2023-04-13 23:14:32 +01:00
Oliver Booth ccef1cd269
Merge pull request #81 from oliverbooth/dev/remove_throwhelpers
Remove throw helpers (resolves #80)
2023-04-13 23:12:04 +01:00
Oliver Booth bb3659c047
refactor: remove throw helpers (#80) 2023-04-13 22:52:46 +01:00
Oliver Booth 3b5fb7b2be
refactor: remove throw helpers in X10D.DSharpPlus (#80) 2023-04-13 22:35:43 +01:00
Oliver Booth 21271314af
feat: add generic math where possible in MathUtility 2023-04-05 17:36:49 +01:00
Oliver Booth b91aad6305
feat: convert DigitalRoot and Mod to generic math 2023-04-05 15:35:25 +01:00
Oliver Booth 87a85b82d9
feat: add Unpack for IBinaryInteger<T>
This introduces an experiment, to add support for generic math in X10D. So far, build and tests remain passing - this is a good sign. There is potential here.

This API is subject to change and may be removed without warning.
2023-04-05 15:11:43 +01:00
524 changed files with 5611 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,63 @@ 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 `Queue<T>.EnqueueAll` and `Queue<T>.DequeueAll`.
- X10D: Added `Stack<T>.PushAll` and `Stack<T>.PopAll`.
- 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

@ -0,0 +1,68 @@
using NUnit.Framework;
using X10D.Collections;
namespace X10D.Tests.Collections;
[TestFixture]
internal class QueueTests
{
[Test]
public void EnqueueAll_ShouldThrowArgumentNullException_GivenNullQueue()
{
Queue<int> queue = null!;
Assert.Throws<ArgumentNullException>(() => queue.EnqueueAll([]));
}
[Test]
public void EnqueueAll_ShouldThrowArgumentNullException_GivenNullElements()
{
var queue = new Queue<int>();
Assert.Throws<ArgumentNullException>(() => queue.EnqueueAll(null!));
}
[Test]
public void DequeueAll_ShouldThrowArgumentNullException_GivenNullQueue()
{
Queue<int> queue = null!;
Assert.Throws<ArgumentNullException>(() => _ = queue.DequeueAll().ToArray());
}
[Test]
public void EnqueueAll_ShouldAddElementsToQueue_GivenValidEnumerable()
{
var queue = new Queue<int>();
int[] elements = [1, 2, 3, 4, 5];
Assert.That(queue, Is.Empty);
queue.EnqueueAll(elements);
Assert.That(queue, Is.Not.Empty);
Assert.That(queue, Has.Count.EqualTo(5));
var index = 0;
foreach (int i in queue)
{
Assert.That(i, Is.EqualTo(elements[index]));
index++;
}
}
[Test]
public void DequeueAll_ShouldRemoveElementsFromQueue()
{
var queue = new Queue<int>([1, 2, 3, 4, 5]);
Assert.That(queue, Is.Not.Empty);
Assert.That(queue, Has.Count.EqualTo(5));
var index = 1;
foreach (int i in queue.DequeueAll())
{
Assert.That(i, Is.EqualTo(index));
index++;
}
Assert.That(queue, Is.Empty);
}
}

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

@ -0,0 +1,68 @@
using NUnit.Framework;
using X10D.Collections;
namespace X10D.Tests.Collections;
[TestFixture]
internal class StackTests
{
[Test]
public void PushAll_ShouldThrowArgumentNullException_GivenNullStack()
{
Stack<int> stack = null!;
Assert.Throws<ArgumentNullException>(() => stack.PushAll([]));
}
[Test]
public void PushAll_ShouldThrowArgumentNullException_GivenNullElements()
{
var stack = new Stack<int>();
Assert.Throws<ArgumentNullException>(() => stack.PushAll(null!));
}
[Test]
public void PopAll_ShouldThrowArgumentNullException_GivenNullStack()
{
Stack<int> stack = null!;
Assert.Throws<ArgumentNullException>(() => _ = stack.PopAll().ToArray());
}
[Test]
public void PushAll_ShouldAddElementsToStack_GivenValidEnumerable()
{
var stack = new Stack<int>();
int[] elements = [1, 2, 3, 4, 5];
Assert.That(stack, Is.Empty);
stack.PushAll(elements);
Assert.That(stack, Is.Not.Empty);
Assert.That(stack, Has.Count.EqualTo(5));
var index = 4;
foreach (int i in stack)
{
Assert.That(i, Is.EqualTo(elements[index]));
index--;
}
}
[Test]
public void PopAll_ShouldRemoveElementsFromStack()
{
var stack = new Stack<int>([1, 2, 3, 4, 5]);
Assert.That(stack, Is.Not.Empty);
Assert.That(stack, Has.Count.EqualTo(5));
var index = 5;
foreach (int i in stack.PopAll())
{
Assert.That(i, Is.EqualTo(index));
index--;
}
Assert.That(stack, Is.Empty);
}
}

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));

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