mirror of
https://github.com/oliverbooth/X10D
synced 2024-10-18 10:06:09 +00:00
3.0.0 Update (#43)
For a full list of changes, see [CHANGELOG.md](CHANGELOG.md)
This commit is contained in:
parent
32cd57dfb4
commit
b16e5a9de9
12
.config/dotnet-tools.json
Normal file
12
.config/dotnet-tools.json
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"isRoot": true,
|
||||||
|
"tools": {
|
||||||
|
"dotnet-stryker": {
|
||||||
|
"version": "1.3.1",
|
||||||
|
"commands": [
|
||||||
|
"dotnet-stryker"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -23,10 +23,10 @@ dotnet_separate_import_directive_groups=false
|
|||||||
dotnet_sort_system_directives_first=true
|
dotnet_sort_system_directives_first=true
|
||||||
|
|
||||||
# this. and Me. preferences
|
# this. and Me. preferences
|
||||||
dotnet_style_qualification_for_event=true:suggestion
|
dotnet_style_qualification_for_event=false:warning
|
||||||
dotnet_style_qualification_for_field=true:suggestion
|
dotnet_style_qualification_for_field=false:warning
|
||||||
dotnet_style_qualification_for_method=true:suggestion
|
dotnet_style_qualification_for_method=false:warning
|
||||||
dotnet_style_qualification_for_property=true:suggestion
|
dotnet_style_qualification_for_property=false:warning
|
||||||
|
|
||||||
# Language keywords vs BCL types preferences
|
# Language keywords vs BCL types preferences
|
||||||
dotnet_style_predefined_type_for_locals_parameters_members=true:warning
|
dotnet_style_predefined_type_for_locals_parameters_members=true:warning
|
||||||
@ -65,9 +65,7 @@ dotnet_code_quality_unused_parameters=all:suggestion
|
|||||||
#### C# Coding Conventions ####
|
#### C# Coding Conventions ####
|
||||||
|
|
||||||
# var preferences
|
# var preferences
|
||||||
csharp_style_var_elsewhere=true:warning
|
|
||||||
csharp_style_var_when_type_is_apparent=true:warning
|
csharp_style_var_when_type_is_apparent=true:warning
|
||||||
csharp_style_var_for_built_in_types=true:warning
|
|
||||||
|
|
||||||
# Expression-bodied members
|
# Expression-bodied members
|
||||||
csharp_style_expression_bodied_accessors=true:suggestion
|
csharp_style_expression_bodied_accessors=true:suggestion
|
||||||
@ -107,7 +105,7 @@ csharp_style_unused_value_assignment_preference=discard_variable:suggestion
|
|||||||
csharp_style_unused_value_expression_statement_preference=discard_variable:silent
|
csharp_style_unused_value_expression_statement_preference=discard_variable:silent
|
||||||
|
|
||||||
# 'using' directive preferences
|
# 'using' directive preferences
|
||||||
csharp_using_directive_placement=inside_namespace:suggestion
|
csharp_using_directive_placement=outside_namespace:error
|
||||||
|
|
||||||
#### C# Formatting Rules ####
|
#### C# Formatting Rules ####
|
||||||
|
|
||||||
|
33
.github/workflows/dotnet.yml
vendored
Normal file
33
.github/workflows/dotnet.yml
vendored
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
name: .NET
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ master ]
|
||||||
|
pull_request:
|
||||||
|
branches: [ master ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
name: "Build & Test"
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Setup .NET
|
||||||
|
uses: actions/setup-dotnet@v2
|
||||||
|
with:
|
||||||
|
dotnet-version: 6.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"
|
||||||
|
|
||||||
|
- name: Restore dependencies
|
||||||
|
run: dotnet restore
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: dotnet build --no-restore --configuration Release
|
||||||
|
|
||||||
|
- name: Test
|
||||||
|
run: dotnet test --no-build --verbosity normal --configuration Release
|
25
.github/workflows/dotnetcore.yml
vendored
25
.github/workflows/dotnetcore.yml
vendored
@ -1,25 +0,0 @@
|
|||||||
name: .NET Core
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ master ]
|
|
||||||
pull_request:
|
|
||||||
branches: [ master ]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Setup .NET Core
|
|
||||||
uses: actions/setup-dotnet@v1
|
|
||||||
with:
|
|
||||||
dotnet-version: 3.1.101
|
|
||||||
- name: Install dependencies
|
|
||||||
run: dotnet restore
|
|
||||||
- name: Build
|
|
||||||
run: dotnet build --configuration Release --no-restore
|
|
||||||
- name: Test
|
|
||||||
run: dotnet test --no-restore --verbosity normal
|
|
41
.github/workflows/nightly.yml
vendored
Normal file
41
.github/workflows/nightly.yml
vendored
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
name: Publish Nightly
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
- develop
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
nightly:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: "!contains(format('{0} {1}', github.event.head_commit.message, github.event.pull_request.title), '[ci-skip]')"
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Setup .NET
|
||||||
|
uses: actions/setup-dotnet@v2
|
||||||
|
with:
|
||||||
|
dotnet-version: 6.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 Debug
|
||||||
|
|
||||||
|
- name: Build NuGet package
|
||||||
|
run: |
|
||||||
|
mkdir build
|
||||||
|
dotnet pack X10D -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
|
||||||
|
|
||||||
|
- name: Push NuGet Package to nuget.org
|
||||||
|
run: dotnet nuget push "build/*" --source https://api.nuget.org/v3/index.json --api-key ${{ secrets.NUGET_API_KEY }} --skip-duplicate
|
46
.github/workflows/prerelease.yml
vendored
Normal file
46
.github/workflows/prerelease.yml
vendored
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
name: Tagged Pre-Release
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- "v[0-9]+.[0-9]+.[0-9]+-*"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
prerelease:
|
||||||
|
name: "Tagged Pre-Release"
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Setup .NET
|
||||||
|
uses: actions/setup-dotnet@v2
|
||||||
|
with:
|
||||||
|
dotnet-version: 6.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: Publish
|
||||||
|
run: dotnet publish -c Release -r linux-x64 --self-contained true
|
||||||
|
|
||||||
|
- name: Build NuGet package
|
||||||
|
run: |
|
||||||
|
mkdir build
|
||||||
|
dotnet pack X10D -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
|
||||||
|
|
||||||
|
- name: Push NuGet Package to nuget.org
|
||||||
|
run: dotnet nuget push "build/*" --source https://api.nuget.org/v3/index.json --api-key ${{ secrets.NUGET_API_KEY }} --skip-duplicate
|
||||||
|
|
||||||
|
- name: Create Release
|
||||||
|
uses: "marvinpinto/action-automatic-releases@latest"
|
||||||
|
with:
|
||||||
|
repo_token: "${{ secrets.GITHUB_TOKEN }}"
|
||||||
|
prerelease: true
|
46
.github/workflows/release.yml
vendored
Normal file
46
.github/workflows/release.yml
vendored
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
name: Tagged Release
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- "v[0-9]+.[0-9]+.[0-9]+"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
release:
|
||||||
|
name: "Tagged Release"
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Setup .NET
|
||||||
|
uses: actions/setup-dotnet@v2
|
||||||
|
with:
|
||||||
|
dotnet-version: 6.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: Publish
|
||||||
|
run: dotnet publish -c Release -r linux-x64 --self-contained true
|
||||||
|
|
||||||
|
- name: Build NuGet package
|
||||||
|
run: |
|
||||||
|
mkdir build
|
||||||
|
dotnet pack X10D -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
|
||||||
|
|
||||||
|
- name: Push NuGet Package to nuget.org
|
||||||
|
run: dotnet nuget push "build/*" --source https://api.nuget.org/v3/index.json --api-key ${{ secrets.NUGET_API_KEY }} --skip-duplicate
|
||||||
|
|
||||||
|
- name: Create Release
|
||||||
|
uses: "marvinpinto/action-automatic-releases@latest"
|
||||||
|
with:
|
||||||
|
repo_token: "${{ secrets.GITHUB_TOKEN }}"
|
||||||
|
prerelease: false
|
36
.github/workflows/source_validator.yml
vendored
Normal file
36
.github/workflows/source_validator.yml
vendored
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
name: Source Validator
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
- develop
|
||||||
|
pull_request:
|
||||||
|
types: [opened, synchronize, reopened]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
source_validator:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: "!contains(format('{0} {1}', github.event.head_commit.message, github.event.pull_request.title), '[ci-skip]')"
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Setup .NET
|
||||||
|
uses: actions/setup-dotnet@v2
|
||||||
|
with:
|
||||||
|
dotnet-version: 6.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 Debug
|
||||||
|
|
||||||
|
- name: Run Source Validation
|
||||||
|
run: dotnet run --project X10D.SourceValidator ./X10D/src
|
||||||
|
|
349
.gitignore
vendored
349
.gitignore
vendored
@ -1,22 +1,22 @@
|
|||||||
## Ignore Visual Studio temporary files, build results, and
|
*.swp
|
||||||
## files generated by popular Visual Studio add-ons.
|
*.*~
|
||||||
##
|
project.lock.json
|
||||||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
.DS_Store
|
||||||
|
*.pyc
|
||||||
|
nupkg/
|
||||||
|
|
||||||
|
# Visual Studio Code
|
||||||
|
.vscode
|
||||||
|
|
||||||
|
# Rider
|
||||||
|
.idea
|
||||||
|
|
||||||
# User-specific files
|
# User-specific files
|
||||||
*.idea
|
|
||||||
*.rsuser
|
|
||||||
*.suo
|
*.suo
|
||||||
*.user
|
*.user
|
||||||
*.userosscache
|
*.userosscache
|
||||||
*.sln.docstates
|
*.sln.docstates
|
||||||
|
|
||||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
|
||||||
*.userprefs
|
|
||||||
|
|
||||||
# Mono auto generated files
|
|
||||||
mono_crash.*
|
|
||||||
|
|
||||||
# Build results
|
# Build results
|
||||||
[Dd]ebug/
|
[Dd]ebug/
|
||||||
[Dd]ebugPublic/
|
[Dd]ebugPublic/
|
||||||
@ -24,327 +24,14 @@ mono_crash.*
|
|||||||
[Rr]eleases/
|
[Rr]eleases/
|
||||||
x64/
|
x64/
|
||||||
x86/
|
x86/
|
||||||
[Aa][Rr][Mm]/
|
build/
|
||||||
[Aa][Rr][Mm]64/
|
|
||||||
bld/
|
bld/
|
||||||
[Bb]in/
|
[Bb]in/
|
||||||
[Oo]bj/
|
[Oo]bj/
|
||||||
[Ll]og/
|
[Oo]ut/
|
||||||
|
msbuild.log
|
||||||
|
msbuild.err
|
||||||
|
msbuild.wrn
|
||||||
|
|
||||||
# Visual Studio 2015/2017 cache/options directory
|
# Visual Studio 2015
|
||||||
.vs/
|
.vs/
|
||||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
|
||||||
#wwwroot/
|
|
||||||
|
|
||||||
# Visual Studio 2017 auto generated files
|
|
||||||
Generated\ Files/
|
|
||||||
|
|
||||||
# MSTest test Results
|
|
||||||
[Tt]est[Rr]esult*/
|
|
||||||
[Bb]uild[Ll]og.*
|
|
||||||
|
|
||||||
# NUnit
|
|
||||||
*.VisualState.xml
|
|
||||||
TestResult.xml
|
|
||||||
nunit-*.xml
|
|
||||||
|
|
||||||
# Build Results of an ATL Project
|
|
||||||
[Dd]ebugPS/
|
|
||||||
[Rr]eleasePS/
|
|
||||||
dlldata.c
|
|
||||||
|
|
||||||
# Benchmark Results
|
|
||||||
BenchmarkDotNet.Artifacts/
|
|
||||||
|
|
||||||
# .NET Core
|
|
||||||
project.lock.json
|
|
||||||
project.fragment.lock.json
|
|
||||||
artifacts/
|
|
||||||
|
|
||||||
# StyleCop
|
|
||||||
StyleCopReport.xml
|
|
||||||
|
|
||||||
# Files built by Visual Studio
|
|
||||||
*_i.c
|
|
||||||
*_p.c
|
|
||||||
*_h.h
|
|
||||||
*.ilk
|
|
||||||
*.meta
|
|
||||||
*.obj
|
|
||||||
*.iobj
|
|
||||||
*.pch
|
|
||||||
*.pdb
|
|
||||||
*.ipdb
|
|
||||||
*.pgc
|
|
||||||
*.pgd
|
|
||||||
*.rsp
|
|
||||||
*.sbr
|
|
||||||
*.tlb
|
|
||||||
*.tli
|
|
||||||
*.tlh
|
|
||||||
*.tmp
|
|
||||||
*.tmp_proj
|
|
||||||
*_wpftmp.csproj
|
|
||||||
*.log
|
|
||||||
*.vspscc
|
|
||||||
*.vssscc
|
|
||||||
.builds
|
|
||||||
*.pidb
|
|
||||||
*.svclog
|
|
||||||
*.scc
|
|
||||||
|
|
||||||
# Chutzpah Test files
|
|
||||||
_Chutzpah*
|
|
||||||
|
|
||||||
# Visual C++ cache files
|
|
||||||
ipch/
|
|
||||||
*.aps
|
|
||||||
*.ncb
|
|
||||||
*.opendb
|
|
||||||
*.opensdf
|
|
||||||
*.sdf
|
|
||||||
*.cachefile
|
|
||||||
*.VC.db
|
|
||||||
*.VC.VC.opendb
|
|
||||||
|
|
||||||
# Visual Studio profiler
|
|
||||||
*.psess
|
|
||||||
*.vsp
|
|
||||||
*.vspx
|
|
||||||
*.sap
|
|
||||||
|
|
||||||
# Visual Studio Trace Files
|
|
||||||
*.e2e
|
|
||||||
|
|
||||||
# TFS 2012 Local Workspace
|
|
||||||
$tf/
|
|
||||||
|
|
||||||
# Guidance Automation Toolkit
|
|
||||||
*.gpState
|
|
||||||
|
|
||||||
# ReSharper is a .NET coding add-in
|
|
||||||
_ReSharper*/
|
|
||||||
*.[Rr]e[Ss]harper
|
|
||||||
*.DotSettings.user
|
|
||||||
|
|
||||||
# JustCode is a .NET coding add-in
|
|
||||||
.JustCode
|
|
||||||
|
|
||||||
# TeamCity is a build add-in
|
|
||||||
_TeamCity*
|
|
||||||
|
|
||||||
# DotCover is a Code Coverage Tool
|
|
||||||
*.dotCover
|
|
||||||
|
|
||||||
# AxoCover is a Code Coverage Tool
|
|
||||||
.axoCover/*
|
|
||||||
!.axoCover/settings.json
|
|
||||||
|
|
||||||
# Visual Studio code coverage results
|
|
||||||
*.coverage
|
|
||||||
*.coveragexml
|
|
||||||
|
|
||||||
# NCrunch
|
|
||||||
_NCrunch_*
|
|
||||||
.*crunch*.local.xml
|
|
||||||
nCrunchTemp_*
|
|
||||||
|
|
||||||
# MightyMoose
|
|
||||||
*.mm.*
|
|
||||||
AutoTest.Net/
|
|
||||||
|
|
||||||
# Web workbench (sass)
|
|
||||||
.sass-cache/
|
|
||||||
|
|
||||||
# Installshield output folder
|
|
||||||
[Ee]xpress/
|
|
||||||
|
|
||||||
# DocProject is a documentation generator add-in
|
|
||||||
DocProject/buildhelp/
|
|
||||||
DocProject/Help/*.HxT
|
|
||||||
DocProject/Help/*.HxC
|
|
||||||
DocProject/Help/*.hhc
|
|
||||||
DocProject/Help/*.hhk
|
|
||||||
DocProject/Help/*.hhp
|
|
||||||
DocProject/Help/Html2
|
|
||||||
DocProject/Help/html
|
|
||||||
|
|
||||||
# Click-Once directory
|
|
||||||
publish/
|
|
||||||
|
|
||||||
# Publish Web Output
|
|
||||||
*.[Pp]ublish.xml
|
|
||||||
*.azurePubxml
|
|
||||||
# Note: Comment the next line if you want to checkin your web deploy settings,
|
|
||||||
# but database connection strings (with potential passwords) will be unencrypted
|
|
||||||
*.pubxml
|
|
||||||
*.publishproj
|
|
||||||
|
|
||||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
|
||||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
|
||||||
# in these scripts will be unencrypted
|
|
||||||
PublishScripts/
|
|
||||||
|
|
||||||
# NuGet Packages
|
|
||||||
*.nupkg
|
|
||||||
# NuGet Symbol Packages
|
|
||||||
*.snupkg
|
|
||||||
# The packages folder can be ignored because of Package Restore
|
|
||||||
**/[Pp]ackages/*
|
|
||||||
# except build/, which is used as an MSBuild target.
|
|
||||||
!**/[Pp]ackages/build/
|
|
||||||
# Uncomment if necessary however generally it will be regenerated when needed
|
|
||||||
#!**/[Pp]ackages/repositories.config
|
|
||||||
# NuGet v3's project.json files produces more ignorable files
|
|
||||||
*.nuget.props
|
|
||||||
*.nuget.targets
|
|
||||||
|
|
||||||
# Microsoft Azure Build Output
|
|
||||||
csx/
|
|
||||||
*.build.csdef
|
|
||||||
|
|
||||||
# Microsoft Azure Emulator
|
|
||||||
ecf/
|
|
||||||
rcf/
|
|
||||||
|
|
||||||
# Windows Store app package directories and files
|
|
||||||
AppPackages/
|
|
||||||
BundleArtifacts/
|
|
||||||
Package.StoreAssociation.xml
|
|
||||||
_pkginfo.txt
|
|
||||||
*.appx
|
|
||||||
*.appxbundle
|
|
||||||
*.appxupload
|
|
||||||
|
|
||||||
# Visual Studio cache files
|
|
||||||
# files ending in .cache can be ignored
|
|
||||||
*.[Cc]ache
|
|
||||||
# but keep track of directories ending in .cache
|
|
||||||
!?*.[Cc]ache/
|
|
||||||
|
|
||||||
# Others
|
|
||||||
ClientBin/
|
|
||||||
~$*
|
|
||||||
*~
|
|
||||||
*.dbmdl
|
|
||||||
*.dbproj.schemaview
|
|
||||||
*.jfm
|
|
||||||
*.pfx
|
|
||||||
*.publishsettings
|
|
||||||
orleans.codegen.cs
|
|
||||||
|
|
||||||
# Including strong name files can present a security risk
|
|
||||||
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
|
||||||
#*.snk
|
|
||||||
|
|
||||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
|
||||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
|
||||||
#bower_components/
|
|
||||||
|
|
||||||
# RIA/Silverlight projects
|
|
||||||
Generated_Code/
|
|
||||||
|
|
||||||
# Backup & report files from converting an old project file
|
|
||||||
# to a newer Visual Studio version. Backup files are not needed,
|
|
||||||
# because we have git ;-)
|
|
||||||
_UpgradeReport_Files/
|
|
||||||
Backup*/
|
|
||||||
UpgradeLog*.XML
|
|
||||||
UpgradeLog*.htm
|
|
||||||
ServiceFabricBackup/
|
|
||||||
*.rptproj.bak
|
|
||||||
|
|
||||||
# SQL Server files
|
|
||||||
*.mdf
|
|
||||||
*.ldf
|
|
||||||
*.ndf
|
|
||||||
|
|
||||||
# Business Intelligence projects
|
|
||||||
*.rdl.data
|
|
||||||
*.bim.layout
|
|
||||||
*.bim_*.settings
|
|
||||||
*.rptproj.rsuser
|
|
||||||
*- [Bb]ackup.rdl
|
|
||||||
*- [Bb]ackup ([0-9]).rdl
|
|
||||||
*- [Bb]ackup ([0-9][0-9]).rdl
|
|
||||||
|
|
||||||
# Microsoft Fakes
|
|
||||||
FakesAssemblies/
|
|
||||||
|
|
||||||
# GhostDoc plugin setting file
|
|
||||||
*.GhostDoc.xml
|
|
||||||
|
|
||||||
# Node.js Tools for Visual Studio
|
|
||||||
.ntvs_analysis.dat
|
|
||||||
node_modules/
|
|
||||||
|
|
||||||
# Visual Studio 6 build log
|
|
||||||
*.plg
|
|
||||||
|
|
||||||
# Visual Studio 6 workspace options file
|
|
||||||
*.opt
|
|
||||||
|
|
||||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
|
||||||
*.vbw
|
|
||||||
|
|
||||||
# Visual Studio LightSwitch build output
|
|
||||||
**/*.HTMLClient/GeneratedArtifacts
|
|
||||||
**/*.DesktopClient/GeneratedArtifacts
|
|
||||||
**/*.DesktopClient/ModelManifest.xml
|
|
||||||
**/*.Server/GeneratedArtifacts
|
|
||||||
**/*.Server/ModelManifest.xml
|
|
||||||
_Pvt_Extensions
|
|
||||||
|
|
||||||
# Paket dependency manager
|
|
||||||
.paket/paket.exe
|
|
||||||
paket-files/
|
|
||||||
|
|
||||||
# FAKE - F# Make
|
|
||||||
.fake/
|
|
||||||
|
|
||||||
# CodeRush personal settings
|
|
||||||
.cr/personal
|
|
||||||
|
|
||||||
# Python Tools for Visual Studio (PTVS)
|
|
||||||
__pycache__/
|
|
||||||
*.pyc
|
|
||||||
|
|
||||||
# Cake - Uncomment if you are using it
|
|
||||||
# tools/**
|
|
||||||
# !tools/packages.config
|
|
||||||
|
|
||||||
# Tabs Studio
|
|
||||||
*.tss
|
|
||||||
|
|
||||||
# Telerik's JustMock configuration file
|
|
||||||
*.jmconfig
|
|
||||||
|
|
||||||
# BizTalk build output
|
|
||||||
*.btp.cs
|
|
||||||
*.btm.cs
|
|
||||||
*.odx.cs
|
|
||||||
*.xsd.cs
|
|
||||||
|
|
||||||
# OpenCover UI analysis results
|
|
||||||
OpenCover/
|
|
||||||
|
|
||||||
# Azure Stream Analytics local run output
|
|
||||||
ASALocalRun/
|
|
||||||
|
|
||||||
# MSBuild Binary and Structured Log
|
|
||||||
*.binlog
|
|
||||||
|
|
||||||
# NVidia Nsight GPU debugger configuration file
|
|
||||||
*.nvuser
|
|
||||||
|
|
||||||
# MFractors (Xamarin productivity tool) working folder
|
|
||||||
.mfractor/
|
|
||||||
|
|
||||||
# Local History for Visual Studio
|
|
||||||
.localhistory/
|
|
||||||
|
|
||||||
# BeatPulse healthcheck temp database
|
|
||||||
healthchecksdb
|
|
||||||
|
|
||||||
# Backup folder for Package Reference Convert tool in Visual Studio 2017
|
|
||||||
MigrationBackup/
|
|
191
CHANGELOG.md
191
CHANGELOG.md
@ -1,7 +1,170 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## [3.0.0]
|
||||||
|
|
||||||
|
In the midst of writing these release notes, I may have missed some important changes. If you notice an API change that is not documented here,
|
||||||
|
please [open an issue](https://github.com/oliverbooth/X10D/issues)!
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Added `T.AsArrayValue()`
|
||||||
|
- Added `T.AsEnumerableValue()`
|
||||||
|
- Added `T.RepeatValue(int)`
|
||||||
|
- Added `T.ToJson([JsonSerializerOptions])`
|
||||||
|
- Added `string.FromJson([JsonSerializerOptions])`
|
||||||
|
- Added `T[].AsReadOnly()`
|
||||||
|
- Added `T[].Clear([Range])` and `T[].Clear(int, int)`
|
||||||
|
- Added `DateTime.IsLeapYear()`
|
||||||
|
- Added `DateTimeOffset.IsLeapYear()`
|
||||||
|
- Added `Endianness` enum
|
||||||
|
- Added `FileInfo.GetHash<T>()`
|
||||||
|
- Added `FileInfo.TryWriteHash<T>(Span<byte>, out int)`
|
||||||
|
- Added `IComparable<T>.Clamp(T, T)` - this supersedes `Clamp` defined for hard-coded numeric types (#24)
|
||||||
|
- Added `IComparable<T1>.GreaterThan(T2)` (#22)
|
||||||
|
- Added `IComparable<T1>.GreaterThanOrEqualTo(T2)` (#22)
|
||||||
|
- Added `IComparable<T1>.LessThan(T2)` (#22)
|
||||||
|
- Added `IComparable<T1>.LessThanOrEqualTo(T2)` (#22)
|
||||||
|
- Added `IComparable<T1>.Max(T)` (#23)
|
||||||
|
- Added `IComparable<T1>.Min(T)` (#23)
|
||||||
|
- Added `IDictionary<TKey, TValue>.AddOrUpdate()`
|
||||||
|
- Added `IEnumerable<TSource>.Product()` and `IEnumerable<TSource>.Product<TResult>(Func<TSource>, TResult)` for all built-in numeric types, computing the product of all (optionally transformed) elements
|
||||||
|
- Added `IList<T>.Fill(T)` and `IList<T>.Fill(T, int, int)`
|
||||||
|
- Added `IPAddress.IsIPv4()` and `IPAddress.IsIPv6()`
|
||||||
|
- Added `IReadOnlyList<byte>.Pack8Bit()`
|
||||||
|
- Added `IReadOnlyList<byte>.Pack16Bit()`
|
||||||
|
- Added `IReadOnlyList<byte>.Pack32Bit()`
|
||||||
|
- Added `IReadOnlyList<byte>.Pack64Bit()`
|
||||||
|
- Added `MemberInfo.HasCustomAttribute<T>()` and `MemberInfo.HasCustomAttribute(Type)`
|
||||||
|
- Added `defaultValue` overload for `MemberInfo.SelectFromCustomAttribute<TAttr, TReturn>()`
|
||||||
|
- Added `Random.Next<T>()` (returns a random field from a specified enum type)
|
||||||
|
- Added `Random.NextByte([byte[, byte]])`
|
||||||
|
- Added `Random.NextColorArgb()`, returning a random color in RGB space, including random alpha
|
||||||
|
- Added `Random.NextColorRgb()`, returning a random color in RGB space with alpha 255
|
||||||
|
- Added `Random.NextDouble(double[, double])`
|
||||||
|
- Added `Random.NextInt16([short[, short]])`
|
||||||
|
- Added `Random.NextSingle(float[, float])` (#34)
|
||||||
|
- Added `Random.NextUnitVector2()`
|
||||||
|
- Added `Random.NextUnitVector3()`
|
||||||
|
- Added `Random.NextRotation()`
|
||||||
|
- Added `Rune.Repeat(int)`
|
||||||
|
- Added `byte.IsEven()`
|
||||||
|
- Added `byte.IsOdd()`
|
||||||
|
- Added `byte.IsPrime()`
|
||||||
|
- Added `byte.UnpackBits()`
|
||||||
|
- Added `byte.RangeTo(byte)`, `byte.RangeTo(short)`, `byte.RangeTo(int)`, and `byte.RangeTo(long)`
|
||||||
|
- Added `int.Mod(int)`
|
||||||
|
- Added `int.RangeTo(int)`, and `int.RangeTo(long)`
|
||||||
|
- Added `int.UnpackBits()`
|
||||||
|
- Added `long.Mod(long)`
|
||||||
|
- Added `long.RangeTo(long)`
|
||||||
|
- Added `long.UnpackBits()`
|
||||||
|
- Added `sbyte.IsEven()`
|
||||||
|
- Added `sbyte.IsOdd()`
|
||||||
|
- Added `sbyte.IsPrime()`
|
||||||
|
- Added `sbyte.Mod(sbyte)`
|
||||||
|
- Added `short.IsEven()`
|
||||||
|
- Added `short.IsOdd()`
|
||||||
|
- Added `short.Mod(short)`
|
||||||
|
- Added `short.RangeTo(short)`, `short.RangeTo(int)`, and `short.RangeTo(long)`
|
||||||
|
- Added `short.UnpackBits()`
|
||||||
|
- Added `string.IsPalindrome()`
|
||||||
|
- Added `Stream.GetHash<T>()`
|
||||||
|
- Added `Stream.TryWriteHash<T>(Span<byte>, out int)`
|
||||||
|
- Added `Stream.ReadInt16([Endian])`
|
||||||
|
- Added `Stream.ReadInt32([Endian])`
|
||||||
|
- Added `Stream.ReadInt64([Endian])`
|
||||||
|
- Added `Stream.ReadUInt16([Endian])`
|
||||||
|
- Added `Stream.ReadUInt32([Endian])`
|
||||||
|
- Added `Stream.ReadUInt64([Endian])`
|
||||||
|
- Added `Stream.Write(short, [Endian])`
|
||||||
|
- Added `Stream.Write(int, [Endian])`
|
||||||
|
- Added `Stream.Write(long, [Endian])`
|
||||||
|
- Added `Stream.Write(ushort, [Endian])`
|
||||||
|
- Added `Stream.Write(uint, [Endian])`
|
||||||
|
- Added `Stream.Write(ulong, [Endian])`
|
||||||
|
- Added `TimeSpan.Ago()`
|
||||||
|
- Added `TimeSpan.FromNow()`
|
||||||
|
- Added `TimeSpanParser.TryParse` which supersedes `TimeSpanParser.Parse`
|
||||||
|
- Added `Sqrt()` and `ComplexSqrt()` for all built-in decimal types
|
||||||
|
- Added `All()` and `Any()` for `Span<T>` and `ReadOnlySpan<T>`, mimicking the corresponding methods in `System.Linq`
|
||||||
|
- Added `Sign()` for built-in numeric types. For unsigned types, this never returns -1
|
||||||
|
- Added `Type.Implements<T>()` and `Type.Implements(Type)` (#25)
|
||||||
|
- Added `Type.Inherits<T>()` and `Type.Inherits(Type)` (#25)
|
||||||
|
- Added `DigitalRoot` function for built-in integer types
|
||||||
|
- Added `Factorial` function for built-in integer types
|
||||||
|
- Added `HostToNetworkOrder` and `NetworkToHostOrder` for `short`, `int`, and `long`
|
||||||
|
- Added `IsLeapYear` function for `DateTime` and `DateTimeOffset`, as well as built-in numeric types
|
||||||
|
- Added `MultiplicativePersistence` function for built-in integer types
|
||||||
|
- Added `RotateLeft` and `RotateRight` for built-in integer types
|
||||||
|
- Added trigonometric functions for built-in numeric types, including `Acos()`, `Asin()`, `Atan()`, `Atan2()`, `Cos()`, `Sin()`, `Tan()` (#49)
|
||||||
|
- Added time-related extension methods for built-in numeric types, including `Milliseconds()`, `Seconds()`, `Minutes()`, `Hours()`, `Days()`, and `Weeks()`. `Ticks()` is also available, but only for integers; not floating point
|
||||||
|
- Added `StringBuilderReader` (inheriting `TextReader`) which allows reading from a `StringBuilder` without consuming the underlying string
|
||||||
|
- Added extension methods for `System.Decimal`
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Updated to .NET 6 (#45)
|
||||||
|
- Methods defined to accept `byte[]` have been changed accept `IReadOnlyList<byte>`
|
||||||
|
- Extension methods are now defined in appropriate child namespaces to reduce the risk of name collisions (#7)
|
||||||
|
- `char[].Random(int)`, `char[].Random(int, int)`, `IEnumerable<char>.Random(int)`, and `IEnumerable<char>.Random(int, int)` have been redefined as `Random.NextString(IReadOnlyList<char>, int)`
|
||||||
|
- `IComparable<T>.Between(T, T)` has been redefined as `IComparable<T1>.Between(T2, T3, [InclusiveOptions])` to allow comparison of disparate yet comparable types, and also offers inclusivity options
|
||||||
|
- `DateTime` extensions now wrap `DateTimeOffset` extensions
|
||||||
|
- `DateTime.ToUnixTimestamp([bool])` has been redefined as `DateTime.ToUnixTimeMilliseconds()` and `DateTime.ToUnixTimeSeconds()`
|
||||||
|
- `Dictionary<T1, T2>.ToGetParameters()`, `IDictionary<T1, T2>.ToGetParameters()`, and `IReadOnlyDictionary<T1, T2>.ToGetParameters()`, has been redefined as `IEnumerable<KeyValuePair<T1, T2>>.ToGetParameters()`
|
||||||
|
- `Dictionary<T1, T2>.ToConnectionString()`, `IDictionary<T1, T2>.ToConnectionString()`, and `IReadOnlyDictionary<T1, T2>.ToConnectionString()`, has been redefined as `IEnumerable<KeyValuePair<T1, T2>>.ToConnectionString()`
|
||||||
|
- `IList<T>.OneOf([Random])` and `IEnumerable<T>.OneOf([Random])` have been redefined as `Random.NextFrom<T>(IEnumerable<T>)` to fall in line with the naming convention of `System.Random` (#21)
|
||||||
|
- `IList<T>.Shuffle([Random])` now uses a Fisher-Yates shuffle implementation
|
||||||
|
- `IList<T>.Shuffle([Random])` has been repurposed to shuffle the list in place, rather than returning a new enumerable
|
||||||
|
- `IEnumerable<T>.Shuffle([Random])` has been renamed to `IEnumerable<T>.Shuffled([Random])` to avoid confusion with `IList<T>.Shuffle([Random])`
|
||||||
|
- `Random.CoinToss()` has been redefined as `Random.NextBoolean()` to fall in line with the naming convention of `System.Random`
|
||||||
|
- `Random.OneOf<T>(T[])` and `Random.OneOf<T>(IList<T>)` have been redefined as `Random.NextFrom<T>(IEnumerable<T>)` to fall in line with the naming convention of `System.Random`
|
||||||
|
- `Enum.Next([bool])` and `Enum.Previous([bool])` have been redefined as `Enum.Next()`, `Enum.Previous()`, `Enum.NextUnchecked()`, `Enum.PreviousUnchecked()`. The `Unchecked` variants of these methods do not perform index validation, and will throw `IndexOutOfRangeException` when attempting to access an invalid index. The checked variants will perform a modulo to wrap the index
|
||||||
|
- Seperated `string.WithAlternative(string, [bool])` to `string.WithEmptyAlternative(string)` and `string.WithWhiteSpaceAlternative(string)`
|
||||||
|
- `string.AsNullIfEmpty()` and `string.AsNullIfWhiteSpace()` now accept a nullable `string`
|
||||||
|
- `IEnumerable<byte>.GetString([Encoding])` has been renamed to `IReadOnlyList<byte>.ToString` and its `Encoding` parameter has
|
||||||
|
been made non-optional
|
||||||
|
- Fixed a bug where `IEnumerable<KeyValuePair<K,V>>.ToConnectionString()` would not sanitize types with custom `ToString()`
|
||||||
|
implementation (#20)
|
||||||
|
Renamed `string.Random(int[, Random])` to `string.Randomize(int[, Random])`
|
||||||
|
- Redefined `char[].Random(int)`, `char[].Random(int, Random)`, `IEnumerable<char>.Random(int)`, and `IEnumerable<char>.Random(int, Random)`, as `Random.NextString(IReadOnlyList<char>, int)`
|
||||||
|
- Improved performance for:
|
||||||
|
- `string.IsLower()`
|
||||||
|
- `string.IsUpper()`
|
||||||
|
- `string.Reverse()`
|
||||||
|
- `TimeSpanParser`
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
- Indefinitely suspended Unity support, until such a time that Unity can be updated to a newer version of .NET. See: https://forum.unity.com/threads/unity-future-net-development-status.1092205/
|
||||||
|
- Removed `bool.And(bool)`
|
||||||
|
- Removed `bool.NAnd(bool)`
|
||||||
|
- Removed `bool.NOr(bool)`
|
||||||
|
- Removed `bool.Not(bool)`
|
||||||
|
- Removed `bool.Or(bool)`
|
||||||
|
- Removed `bool.ToByte()`
|
||||||
|
- Removed `bool.ToInt16()`
|
||||||
|
- Removed `bool.ToInt64()`
|
||||||
|
- Removed `bool.XNOr()`
|
||||||
|
- Removed `bool.XOr()`
|
||||||
|
- Removed `IConvertible.To<T>([IFormatProvider])` (#13)
|
||||||
|
- Removed `IConvertible.ToOrDefault<T>([IFormatProvider])` (#13)
|
||||||
|
- Removed `IConvertible.ToOrDefault<T>(out T, [IFormatProvider])` (#13)
|
||||||
|
- Removed `IConvertible.ToOrNull<T>([IFormatProvider])` (#13)
|
||||||
|
- Removed `IConvertible.ToOrNull<T>(out T, [IFormatProvider])` (#13)
|
||||||
|
- Removed `IConvertible.ToOrOther<T>(T, [IFormatProvider])` (#13)
|
||||||
|
- Removed `IConvertible.ToOrOther<T>(out T, T, [IFormatProvider])` (#13)
|
||||||
|
- Removed `IEnumerable<T>.Split(int)` - this functionality is now provided by .NET in the form of the `Chunk` method. See: https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.chunk?view=net-6.0
|
||||||
|
- Removed `MemberInfo.GetDefaultValue()` (use `SelectFromCustomAttribute()` instead)
|
||||||
|
- Removed `MemberInfo.GetDescription()` (use `SelectFromCustomAttribute()` instead)
|
||||||
|
- Removed `int.ToBoolean()`
|
||||||
|
- Removed `long.ToBoolean()`
|
||||||
|
- Removed `short.ToBoolean()`
|
||||||
|
- Removed `uint.ToBoolean()`
|
||||||
|
- Removed `ushort.ToBoolean()`
|
||||||
|
- Removed `ulong.ToBoolean()`
|
||||||
|
- Removed `WaitHandle.WaitOneAsync()`. For suspensions of execution during asynchronous operations, favour `TaskCompletionSource` or `TaskCompletionSource<T>`. See: https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.taskcompletionsource?view=net-6.0 and https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.taskcompletionsource-1?view=net-6.0
|
||||||
|
|
||||||
## [2.6.0] - 2020-10-20
|
## [2.6.0] - 2020-10-20
|
||||||
# Added
|
|
||||||
|
### Added
|
||||||
|
|
||||||
- Add `string.AsNullIfEmpty()`
|
- Add `string.AsNullIfEmpty()`
|
||||||
- Returns the current string, or `null` if the current string is null or empty.
|
- Returns the current string, or `null` if the current string is null or empty.
|
||||||
- Add `string.AsNullIfWhiteSpace()`
|
- Add `string.AsNullIfWhiteSpace()`
|
||||||
@ -9,16 +172,21 @@
|
|||||||
- Add `string.Reverse()`
|
- Add `string.Reverse()`
|
||||||
- Reverses the current string
|
- Reverses the current string
|
||||||
- Add `string.WithAlternative()`
|
- Add `string.WithAlternative()`
|
||||||
- Returns the current string, or an alternative value if the current string is null or empty, or optionally if the current string consists of only whitespace.
|
- Returns the current string, or an alternative value if the current string is null or empty, or optionally if the current
|
||||||
|
string consists of only whitespace.
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- n/a
|
- n/a
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
|
||||||
- n/a
|
- n/a
|
||||||
|
|
||||||
## [2.5.0] - 2020-07-15
|
## [2.5.0] - 2020-07-15
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- `WaitHandle.WaitOneAsync()`
|
- `WaitHandle.WaitOneAsync()`
|
||||||
- Wraps `WaitHandle.WaitOne` as a `Task`
|
- Wraps `WaitHandle.WaitOne` as a `Task`
|
||||||
- Add support for Unity 2019.4.3f1
|
- Add support for Unity 2019.4.3f1
|
||||||
@ -45,13 +213,17 @@
|
|||||||
- Add `BetterBehavior` (experimental wrapper over `MonoBehaviour`)
|
- Add `BetterBehavior` (experimental wrapper over `MonoBehaviour`)
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- n/a
|
- n/a
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
|
||||||
- n/a
|
- n/a
|
||||||
|
|
||||||
## [2.2.0] - 2020-04-21
|
## [2.2.0] - 2020-04-21
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Add `string.ChangeEncoding(Encoding, Encoding)`
|
- Add `string.ChangeEncoding(Encoding, Encoding)`
|
||||||
- Converts this string from one encoding to another
|
- Converts this string from one encoding to another
|
||||||
- Add `string.IsLower()`
|
- Add `string.IsLower()`
|
||||||
@ -62,16 +234,21 @@
|
|||||||
- Various extension methods with regards to reflection:
|
- Various extension methods with regards to reflection:
|
||||||
- `GetDefaultValue` and `GetDefaultValue<T>` - gets the value stored in the member's `DefaultValue` attribute
|
- `GetDefaultValue` and `GetDefaultValue<T>` - gets the value stored in the member's `DefaultValue` attribute
|
||||||
- `GetDescription`- gets the value stored in the member's `Description` attribute
|
- `GetDescription`- gets the value stored in the member's `Description` attribute
|
||||||
- `SelectFromCustomAttribute<T1, T2>` - Internally calls `GetCustomAttribute<T1>` and passes it to a `Func<T1, T2>` so that specific members may be selected
|
- `SelectFromCustomAttribute<T1, T2>` - Internally calls `GetCustomAttribute<T1>` and passes it to a `Func<T1, T2>` so that
|
||||||
|
specific members may be selected
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- n/a
|
- n/a
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
|
||||||
- n/a
|
- n/a
|
||||||
|
|
||||||
## [2.1.0] - 2020-04-18
|
## [2.1.0] - 2020-04-18
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Add `bool bool.And(bool)`
|
- Add `bool bool.And(bool)`
|
||||||
- Performs logical AND
|
- Performs logical AND
|
||||||
- Add `bool bool.Or(bool)`
|
- Add `bool bool.Or(bool)`
|
||||||
@ -94,29 +271,35 @@
|
|||||||
- 1 if `true`, 0 otherwise
|
- 1 if `true`, 0 otherwise
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- n/a
|
- n/a
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
|
||||||
- n/a
|
- n/a
|
||||||
|
|
||||||
## [2.0.0] - 2020-04-18
|
## [2.0.0] - 2020-04-18
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Add `IEnumerable<T>.Split(int)`
|
- Add `IEnumerable<T>.Split(int)`
|
||||||
- Performs the same operation as the previously defined `IEnumerable<byte>.Chunkify(int)`, except now accepts any type `T`
|
- Performs the same operation as the previously defined `IEnumerable<byte>.Chunkify(int)`, except now accepts any type `T`
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Fix `DateTime.Last(DayOfWeek)` implementation
|
- Fix `DateTime.Last(DayOfWeek)` implementation
|
||||||
- Now returns the correct date/time for a given day of the week
|
- Now returns the correct date/time for a given day of the week
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
|
||||||
- Remove `IEnumerable<byte>.Chunkify(int)`
|
- Remove `IEnumerable<byte>.Chunkify(int)`
|
||||||
- Replaced by a method of the same behaviour `IEnumerable<T>.Split(int)`
|
- Replaced by a method of the same behaviour `IEnumerable<T>.Split(int)`
|
||||||
|
|
||||||
## Earlier versions
|
## Earlier versions
|
||||||
|
|
||||||
### ***Not documented***
|
### ***Not documented***
|
||||||
|
|
||||||
[Unreleased]: https://github.com/oliverbooth/X10D/tree/HEAD
|
[3.0.0]: https://github.com/oliverbooth/X10D/releases/tag/3.0.0
|
||||||
[2.6.0]: https://github.com/oliverbooth/X10D/releases/tag/2.6.0
|
[2.6.0]: https://github.com/oliverbooth/X10D/releases/tag/2.6.0
|
||||||
[2.5.0]: https://github.com/oliverbooth/X10D/releases/tag/2.5.0
|
[2.5.0]: https://github.com/oliverbooth/X10D/releases/tag/2.5.0
|
||||||
[2.2.0]: https://github.com/oliverbooth/X10D/releases/tag/2.2.0
|
[2.2.0]: https://github.com/oliverbooth/X10D/releases/tag/2.2.0
|
||||||
|
@ -2,25 +2,25 @@
|
|||||||
Contributions to this project are always welcome. If you spot a bug, or want to request a new extension method, open a new issue or submit a pull request.
|
Contributions to this project are always welcome. If you spot a bug, or want to request a new extension method, open a new issue or submit a pull request.
|
||||||
|
|
||||||
### Pull request guidelines
|
### Pull request guidelines
|
||||||
This project uses C# 8.0 language features, and adheres to the following analyzers:
|
This project uses C# 9.0 language features, and adheres to the FxCop analyzer.
|
||||||
|
There is an `.editorconfig` included in this repository. For quick and painless pull requests, ensure that the analyzer does not throw warnings.
|
||||||
- Rozlynator
|
|
||||||
- FxCop
|
|
||||||
- StyleCop
|
|
||||||
|
|
||||||
There is an `.editorconfig` and an analyzer `ruleset` file included in this repository. For quick and painless pull requests, ensure that these analyzers do not throw warnings.
|
|
||||||
|
|
||||||
### Code style
|
### Code style
|
||||||
Below are a few pointers to which you may refer, but keep in mind this is not an exhaustive list:
|
Below are a few pointers to which you may refer, but keep in mind this is not an exhaustive list:
|
||||||
|
|
||||||
- Use C# 8.0 features where possible
|
- Use C# 9.0 features where possible
|
||||||
- Try to ensure code is CLS-compliant
|
- Try to ensure code is CLS-compliant. Where this is not possible, decorate methods with `CLSCompliantAttribute` and pass `false`
|
||||||
- Follow all .NET guidelines for naming conventions
|
- Follow all .NET guidelines for naming conventions
|
||||||
- Make full use of XMLDoc and be thorough - but concise - with all documentation.
|
- Make full use of XMLDoc and be thorough - but concise - with all documentation
|
||||||
- Ensure that no line exceeds 120 characters in length
|
- Ensure that no line exceeds 130 characters in length
|
||||||
- Do NOT include file headers in any form
|
- Do NOT include file headers in any form
|
||||||
- Declare `using` directives within namespace scope
|
- Declare `using` directives outside of namespace scope
|
||||||
- Try to avoid using exceptions for flow control
|
- Avoid using exceptions for flow control where possible
|
||||||
|
- Use braces, even for single-statement bodies
|
||||||
|
- Use implicit type when the type is apparent or not important
|
||||||
|
- Use U.S. English throughout the codebase and documentation
|
||||||
|
|
||||||
|
When in doubt, follow .NET guidelines for styling.
|
||||||
|
|
||||||
### Tests
|
### Tests
|
||||||
When introducing a new extension method, you must ensure that you have also defined a unit test that asserts its correct behavior. The code style guidelines and code-analysis rules apply to the `X10D.Tests` equally as much as `X10D`, although documentation may be briefer. Refer to existing tests as a guideline.
|
When introducing a new extension method, you must ensure that you have also defined a unit test that asserts its correct behavior. The code style guidelines and code-analysis rules apply to the `X10D.Tests` equally as much as `X10D`, although documentation may be briefer. Refer to existing tests as a guideline.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2019 Oliver Booth
|
Copyright (c) 2019-2022 Oliver Booth
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
267
README.md
267
README.md
@ -1,259 +1,46 @@
|
|||||||
# X10D
|
<h1 align="center"><img src="https://raw.githubusercontent.com/oliverbooth/X10D/develop/banner.png"></h1>
|
||||||
## Extension methods on crack
|
<p align="center">
|
||||||
|
<a href="https://github.com/oliverbooth/X10D/actions?query=workflow%3A%22.NET+Core%22"><img src="https://img.shields.io/github/workflow/status/oliverbooth/X10D/.NET%20Core" alt="GitHub Workflow Status" title="GitHub Workflow Status"></a>
|
||||||
[<img src="https://img.shields.io/github/workflow/status/oliverbooth/X10D/.NET%20Core">](https://github.com/oliverbooth/X10D/actions?query=workflow%3A%22.NET+Core%22)
|
<a href="https://github.com/oliverbooth/X10D/issues"><img src="https://img.shields.io/github/issues/oliverbooth/X10D" alt="GitHub Issues" title="GitHub Issues"></a>
|
||||||
[<img src="https://img.shields.io/github/issues/oliverbooth/X10D">](https://github.com/oliverbooth/X10D/issues)
|
<a href="https://sonarcloud.io/dashboard?id=oliverbooth_X10D"><img src="https://img.shields.io/sonar/coverage/oliverbooth_X10D?server=https%3A%2F%2Fsonarcloud.io" alt="Coverage"></a>
|
||||||
[<img src="https://img.shields.io/nuget/v/X10D">](https://www.nuget.org/packages/X10D/)
|
<a href="https://www.nuget.org/packages/X10D/"><img src="https://img.shields.io/nuget/dt/X10D" alt="NuGet Downloads" title="NuGet Downloads"></a>
|
||||||
[<img src="https://img.shields.io/github/license/oliverbooth/X10D">](https://github.com/oliverbooth/X10D/blob/master/LICENSE.md)
|
<a href="https://www.nuget.org/packages/X10D/"><img src="https://img.shields.io/nuget/v/X10D?label=stable" alt="Stable Version" title="Stable Version"></a>
|
||||||
|
<a href="https://www.nuget.org/packages/X10D/"><img src="https://img.shields.io/nuget/vpre/X10D?label=nightly" alt="Nightly Version" title="Nightly Version"></a>
|
||||||
|
<a href="https://github.com/oliverbooth/X10D/blob/master/LICENSE.md"><img src="https://img.shields.io/github/license/oliverbooth/X10D" alt="MIT License" title="MIT License"></a>
|
||||||
|
</p>
|
||||||
|
|
||||||
### About
|
### About
|
||||||
X10D (pronounced *extend*), is a class library that provides extension methods for numerous .NET 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.
|
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.)*
|
*(I'm also [dogfooding](https://www.pcmag.com/encyclopedia/term/dogfooding) this library, so there's that.)*
|
||||||
|
|
||||||
### Table of contents
|
### Table of contents
|
||||||
- [Install](#install)
|
- [Installation](#installation)
|
||||||
|
- [Unity installation](#unity-installation)
|
||||||
|
- [NuGet installation](#nuget-installation)
|
||||||
- [Features](#features)
|
- [Features](#features)
|
||||||
- [Numeric](#numeric)
|
|
||||||
- [String](#string)
|
|
||||||
- [DateTime](#datetime)
|
|
||||||
- [Enumerable](#enumerable)
|
|
||||||
- [Enum](#enum)
|
|
||||||
- [Conversion](#conversion)
|
|
||||||
- [Random](#random)
|
|
||||||
- [Contributing](#contributing)
|
- [Contributing](#contributing)
|
||||||
- [License](#license)
|
- [License](#license)
|
||||||
|
|
||||||
You can find the list of classes that have extension methods by viewing the `README.md` file in any of the respective library folders.
|
You can find the list of classes that have extension methods by viewing the `README.md` file in any of the respective library folders.
|
||||||
|
|
||||||
## Install
|
## Installation
|
||||||
Install X10D with NuGet via the following command:
|
### NuGet installation
|
||||||
```ps
|
```ps
|
||||||
Install-Package X10D -Version 2.6.0
|
Install-Package X10D -Version 3.0.0
|
||||||
```
|
```
|
||||||
or by downloading the [latest release](https://github.com/oliverbooth/X10D/releases/latest) from this repository.
|
|
||||||
|
### 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.
|
||||||
|
|
||||||
|
### What happened to X10D.Unity?
|
||||||
|
I decided it was time for X10D to be migrated to .NET 6. Unity currently supports .NET Framework 4.x / .NET Standard 2.1, and as such is not compatible with X10D at this time.
|
||||||
|
Unity have announced official support for .NET 6 in the future (see [this forum post](https://forum.unity.com/threads/unity-future-net-development-status.1092205/) for more details),
|
||||||
|
but until such a time that Unity supports .NET 6, X10D.Unity will not be maintained or innovated upon.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
### Numeric extensions
|
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.
|
||||||
> 👍 ProTip: *Most* of the extensions available for `int` will also exist for `short`, `long`, and their unsigned counterparts!
|
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.**
|
||||||
|
|
||||||
#### `bool` <-> `int`
|
|
||||||
Convert a `bool` to an `int` by using `ToInt32`. The value returned is 1 if the input is `true`, and 0 if it's `false`.
|
|
||||||
```cs
|
|
||||||
bool b = true;
|
|
||||||
|
|
||||||
int i = b.ToInt32(); // 1
|
|
||||||
```
|
|
||||||
The same also works in reverse. Using `ToBoolean` on an `int` will return `false` if the input is 0, and `true`if the input is anything else.
|
|
||||||
```cs
|
|
||||||
int zero = 0;
|
|
||||||
long nonZero = 1;
|
|
||||||
|
|
||||||
bool b1 = zero.ToBoolean(); // false
|
|
||||||
bool b2 = nonZero.ToBoolean(); // true
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Between
|
|
||||||
Determine if a value is between other values using `Between` like so:
|
|
||||||
```cs
|
|
||||||
int i = 3;
|
|
||||||
|
|
||||||
if (i.Between(2, 4))
|
|
||||||
{
|
|
||||||
// i is between 2 and 4!
|
|
||||||
}
|
|
||||||
```
|
|
||||||
Since the signature of this method is defined with a generic constraint of `IComparable<T>`, this will also work for any object that is `IComparable<T>` - not just numeric types!
|
|
||||||
```cs
|
|
||||||
bool Between<T>(this T actual, T lower, T upper) where T : IComparable<T>
|
|
||||||
```
|
|
||||||
|
|
||||||
#### IsEven (*and IsOdd*)
|
|
||||||
As the names suggest, this method determines if the input value is evenly divisible by 2.
|
|
||||||
```cs
|
|
||||||
int i = 5;
|
|
||||||
bool b = i.IsEven(); // false
|
|
||||||
```
|
|
||||||
There is also an `IsOdd` extension method, which will return the opposite of that returned by `IsEven`.
|
|
||||||
|
|
||||||
#### IsPrime
|
|
||||||
Determine if an integral is a prime number by using `IsPrime`.
|
|
||||||
```cs
|
|
||||||
bool b = 43.IsPrime(); // true
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Clamp
|
|
||||||
Clamp a value between an upper and lower bound
|
|
||||||
```cs
|
|
||||||
int i = 5.Clamp(0, 3); // 3
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Convert degrees <-> radians
|
|
||||||
Easily convert between radians and degrees
|
|
||||||
```cs
|
|
||||||
double rad = 2 * Math.PI;
|
|
||||||
double deg = rad.RadiansToDegrees(); // 360
|
|
||||||
|
|
||||||
rad = deg.DegreesToRadians(); // back to 2*pi
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Round
|
|
||||||
Round a value to the nearest whole number:
|
|
||||||
```cs
|
|
||||||
var d = 2.75;
|
|
||||||
var rounded = d.Round(); // 3
|
|
||||||
```
|
|
||||||
Or specify a value to have it round to the nearest multiple of `x`:
|
|
||||||
```cs
|
|
||||||
double a = 8.0.Round(10); // 10
|
|
||||||
double b = 2.0.Round(10); // 0
|
|
||||||
```
|
|
||||||
|
|
||||||
### String
|
|
||||||
#### Repeat value
|
|
||||||
Repeat a string or a char a specific number of times using `Repeat`
|
|
||||||
```cs
|
|
||||||
var c = '-';
|
|
||||||
var str = "foo";
|
|
||||||
|
|
||||||
string repeatedC = c.Repeat(10); // ----------
|
|
||||||
string repeatedStr = str.Repeat(5); // foofoofoofoofoo
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Base-64 encode/decode
|
|
||||||
```cs
|
|
||||||
var base64 = "Hello World".Base64Encode(); // SGVsbG8gV29ybGQ=
|
|
||||||
var str = "SGVsbG8gV29ybGQ=".Base64Decode(); // Hello World
|
|
||||||
```
|
|
||||||
|
|
||||||
### DateTime
|
|
||||||
|
|
||||||
#### Age
|
|
||||||
Get a rounded integer representing the number of years since a given date. i.e. easily calculate someone's age:
|
|
||||||
```cs
|
|
||||||
var dateOfBirth = new DateTime(1960, 7, 16);
|
|
||||||
int age = dateOfBirth.Age(); // the age as of today
|
|
||||||
```
|
|
||||||
You can also specify a date at which to stop counting the years, by passing an `asOf` date:
|
|
||||||
```cs
|
|
||||||
var dateOfBirth = new DateTime(1960, 7, 16);
|
|
||||||
int age = dateOfBirth.Age(new DateTime(1970, 7, 16)); // 10, the age as of 1970
|
|
||||||
```
|
|
||||||
|
|
||||||
#### To/From Unix Timestamp
|
|
||||||
Convert to/from a Unix timestamp represented in seconds using `FromUnixTimestamp` on a numeric type, and `ToUnixTimestamp` on a `DateTime`.
|
|
||||||
```cs
|
|
||||||
long sec = 1587223415;
|
|
||||||
DateTime time = sec.FromUnixTimestamp(); // 2020-04-18 15:23:35
|
|
||||||
long unix = time.ToUnixTimestamp();
|
|
||||||
```
|
|
||||||
or represent it with milliseconds by passing `true` for the `isMillis` argument:
|
|
||||||
```cs
|
|
||||||
long millis = 1587223415500;
|
|
||||||
DateTime time = millis.FromUnixTimestamp(true); // 2020-04-18 15:23:35.50
|
|
||||||
long unix = time.ToUnixTimestamp(true);
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Get first/last day of month
|
|
||||||
Get the first or last day of the month by using `FirstDayOfMonth` and `LastDayOfMonth`
|
|
||||||
```cs
|
|
||||||
var dt = new DateTime(2016, 2, 4);
|
|
||||||
|
|
||||||
DateTime first = dt.FirstDayOfMonth(); // 2016-02-01
|
|
||||||
DateTime last = dt.LastDayOfMonth(); // 2016-02-29 (2016 is a leap year)
|
|
||||||
```
|
|
||||||
You can also use `First` or `Last` to get the first or final occurrence of a specific day of the week in a given month:
|
|
||||||
```cs
|
|
||||||
var dt = new DateTime(2019, 4, 14);
|
|
||||||
|
|
||||||
DateTime theLastFriday = dt.Last(DayOfWeek.Friday); // 2019-04-24
|
|
||||||
DateTime theLastThursday = dt.Last(DayOfWeek.Thursday); // 2019-04-40
|
|
||||||
```
|
|
||||||
|
|
||||||
### Enumerable
|
|
||||||
#### Split into chunks
|
|
||||||
Split an `IEnumerable<T>` into an `IEnumerable<IEnumerable<T>>`, essentially "chunking" the original IEnumerable into a specific size
|
|
||||||
```cs
|
|
||||||
var arr = new int[] { 1, 2, 3, 4, 5, 6, 7, 8 };
|
|
||||||
var chunks = arr.Split(2); // split into chunks of 2
|
|
||||||
|
|
||||||
foreach (var chunk in chunks)
|
|
||||||
{
|
|
||||||
Console.WriteLine(string.Join(", ", chunk));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Output:
|
|
||||||
// 1, 2
|
|
||||||
// 3, 4
|
|
||||||
// 5, 6
|
|
||||||
// 7, 8
|
|
||||||
```
|
|
||||||
This also works for `string`:
|
|
||||||
```cs
|
|
||||||
var str = "Hello World";
|
|
||||||
var chunks = str.Split(2); // split string into chunks of 2
|
|
||||||
|
|
||||||
foreach (var chunk in chunks)
|
|
||||||
{
|
|
||||||
Console.WriteLine(string.Join(string.Empty, chunk));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Output:
|
|
||||||
// He
|
|
||||||
// ll
|
|
||||||
// o <-- space is included
|
|
||||||
// Wo
|
|
||||||
// rl
|
|
||||||
// d <-- no space! end of string
|
|
||||||
```
|
|
||||||
|
|
||||||
### Enum
|
|
||||||
#### Parse string into enum
|
|
||||||
You can use the `EnumParse` method to convert a string into a value from an enum, while optionally ignoring case:
|
|
||||||
```cs
|
|
||||||
enum Number
|
|
||||||
{
|
|
||||||
Zero,
|
|
||||||
One,
|
|
||||||
Two,
|
|
||||||
Three,
|
|
||||||
}
|
|
||||||
|
|
||||||
Number num = "two".EnumParse<Number>(true); // num == Number.Two
|
|
||||||
```
|
|
||||||
|
|
||||||
#### `Next` / `Previous` enum cycling
|
|
||||||
Cycle through the values in an enum with `Next` and `Previous`:
|
|
||||||
```cs
|
|
||||||
Number two = Number.Two;
|
|
||||||
|
|
||||||
Number one = two.Previous();
|
|
||||||
Number three = two.Next();
|
|
||||||
```
|
|
||||||
|
|
||||||
### Conversion
|
|
||||||
Easily convert between types using `To`, `ToOrNull`, `ToOrDefault`, or `ToOrOther`, thereby shortening the call to `Convert.ChangeType` or `Convert.ToX`:
|
|
||||||
```CS
|
|
||||||
int i = "43".To<int>();
|
|
||||||
int j = "a".ToOrDefault<int>(); // 0
|
|
||||||
int k = "a".ToOrOther<int>(100); // 100
|
|
||||||
```
|
|
||||||
|
|
||||||
### Random
|
|
||||||
Do more with Random including flip a coin, randomly select an element in an array, or shuffle the array entirely.
|
|
||||||
```cs
|
|
||||||
var random = new Random();
|
|
||||||
|
|
||||||
// flip a coin
|
|
||||||
bool heads = random.CoinToss();
|
|
||||||
|
|
||||||
// randomly choose an item
|
|
||||||
var arr = new int[] { 1, 2, 3, 4 };
|
|
||||||
var item = random.OneOf(arr);
|
|
||||||
|
|
||||||
// shuffle an array or list
|
|
||||||
var shuffled = arr.Shuffle(random);
|
|
||||||
```
|
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
Contributions are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md).
|
Contributions are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md).
|
||||||
|
64
X10D.SourceValidator/Program.cs
Normal file
64
X10D.SourceValidator/Program.cs
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
using System.Text;
|
||||||
|
|
||||||
|
var directories = new Stack<string>(Directory.GetDirectories(args[0]));
|
||||||
|
var problems = 0;
|
||||||
|
var files = 0;
|
||||||
|
|
||||||
|
while (directories.Count > 0)
|
||||||
|
{
|
||||||
|
string path = Path.GetFullPath(directories.Pop());
|
||||||
|
|
||||||
|
foreach (string directory in Directory.EnumerateDirectories(path))
|
||||||
|
{
|
||||||
|
directories.Push(directory);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (string file in Directory.EnumerateFiles(path, "*.cs"))
|
||||||
|
{
|
||||||
|
files++;
|
||||||
|
await using var stream = File.OpenRead(file);
|
||||||
|
using var reader = new StreamReader(stream, Encoding.UTF8);
|
||||||
|
var blankLine = false;
|
||||||
|
|
||||||
|
var lineNumber = 1;
|
||||||
|
while (await reader.ReadLineAsync() is { } line)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(line))
|
||||||
|
{
|
||||||
|
if (blankLine)
|
||||||
|
{
|
||||||
|
Console.ForegroundColor = ConsoleColor.Red;
|
||||||
|
Console.Out.WriteLine($"{file}({lineNumber}): Double blank line");
|
||||||
|
Console.ResetColor();
|
||||||
|
problems++;
|
||||||
|
}
|
||||||
|
|
||||||
|
blankLine = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
blankLine = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line.Length > 130)
|
||||||
|
{
|
||||||
|
Console.ForegroundColor = ConsoleColor.Red;
|
||||||
|
Console.Out.WriteLine($"{file}({lineNumber}): Line is too long ({line.Length})");
|
||||||
|
Console.ResetColor();
|
||||||
|
problems++;
|
||||||
|
}
|
||||||
|
else if (line.Length > 0 && char.IsWhiteSpace(line[^1]))
|
||||||
|
{
|
||||||
|
Console.ForegroundColor = ConsoleColor.Red;
|
||||||
|
Console.Out.WriteLine($"{file}({lineNumber}): Line contains trailing whitespace");
|
||||||
|
Console.ResetColor();
|
||||||
|
problems++;
|
||||||
|
}
|
||||||
|
|
||||||
|
lineNumber++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.Out.WriteLine($"Finished scanning {files} files, {problems} problems encountered.");
|
||||||
|
return problems;
|
14
X10D.SourceValidator/X10D.SourceValidator.csproj
Normal file
14
X10D.SourceValidator/X10D.SourceValidator.csproj
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\X10D\X10D.csproj"/>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
1000
X10D.Tests/1000primes.txt
Normal file
1000
X10D.Tests/1000primes.txt
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,35 +1,29 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
<IsPackable>false</IsPackable>
|
<IsPackable>false</IsPackable>
|
||||||
<CodeAnalysisRuleSet>..\X10D.ruleset</CodeAnalysisRuleSet>
|
<Nullable>enable</Nullable>
|
||||||
<CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>
|
<ImplicitUsings>true</ImplicitUsings>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.8">
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0"/>
|
||||||
|
<PackageReference Include="MSTest.TestAdapter" Version="2.2.10"/>
|
||||||
|
<PackageReference Include="MSTest.TestFramework" Version="2.2.10"/>
|
||||||
|
<PackageReference Include="coverlet.collector" Version="3.1.2">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
|
|
||||||
<PackageReference Include="MSTest.TestAdapter" Version="2.0.0" />
|
|
||||||
<PackageReference Include="MSTest.TestFramework" Version="2.0.0" />
|
|
||||||
<PackageReference Include="coverlet.collector" Version="1.0.1" />
|
|
||||||
<PackageReference Include="Roslynator.Analyzers" Version="2.3.0">
|
|
||||||
<PrivateAssets>all</PrivateAssets>
|
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
|
||||||
</PackageReference>
|
|
||||||
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.164">
|
|
||||||
<PrivateAssets>all</PrivateAssets>
|
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
|
||||||
</PackageReference>
|
|
||||||
<PackageReference Include="Unity3D.SDK" Version="2019.4.3.1" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\X10D.Unity\X10D.Unity.csproj" />
|
|
||||||
<ProjectReference Include="..\X10D\X10D.csproj"/>
|
<ProjectReference Include="..\X10D\X10D.csproj"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Remove="1000primes.txt"/>
|
||||||
|
<EmbeddedResource Include="1000primes.txt"/>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
@ -1,3 +1 @@
|
|||||||
using System;
|
[assembly: CLSCompliant(true)]
|
||||||
|
|
||||||
[assembly: CLSCompliant(true)]
|
|
||||||
|
48
X10D.Tests/src/Collections/ArrayTests.cs
Normal file
48
X10D.Tests/src/Collections/ArrayTests.cs
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Collections;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Collections;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class ArrayTests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void AsReadOnlyShouldBeReadOnly()
|
||||||
|
{
|
||||||
|
var array = new object[] {1, "f", true};
|
||||||
|
var readOnly = array.AsReadOnly();
|
||||||
|
Assert.IsNotNull(readOnly);
|
||||||
|
Assert.IsTrue(readOnly.Count == 3);
|
||||||
|
|
||||||
|
// ReSharper disable once ConvertTypeCheckToNullCheck
|
||||||
|
Assert.IsTrue(readOnly is IReadOnlyCollection<object>);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void AsReadOnlyNullShouldThrow()
|
||||||
|
{
|
||||||
|
object[]? array = null;
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(array!.AsReadOnly);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
[DataRow]
|
||||||
|
[DataRow(1)]
|
||||||
|
[DataRow(1, 2, 3)]
|
||||||
|
[DataRow(1, 2, 3, 4, 5)]
|
||||||
|
public void ClearShouldFillDefault(params int[] args)
|
||||||
|
{
|
||||||
|
args.Clear();
|
||||||
|
|
||||||
|
int[] clearedArray = Enumerable.Repeat(0, args.Length).ToArray();
|
||||||
|
CollectionAssert.AreEqual(clearedArray, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ClearNullShouldThrow()
|
||||||
|
{
|
||||||
|
int[]? array = null;
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(array!.Clear);
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => array!.Clear(0, 0));
|
||||||
|
}
|
||||||
|
}
|
56
X10D.Tests/src/Collections/BoolListTests.cs
Normal file
56
X10D.Tests/src/Collections/BoolListTests.cs
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Collections;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Collections;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class BoolListTests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void Pack8Bit_Should_Pack_Correctly()
|
||||||
|
{
|
||||||
|
var array = new[] {true, false, true, false, true, false, true, false};
|
||||||
|
Assert.AreEqual(85, array.PackByte()); // 01010101
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Pack16Bit_Should_Pack_Correctly()
|
||||||
|
{
|
||||||
|
var array = new[] {true, false, true, false, true, false, true, false, true, true, false, true};
|
||||||
|
Assert.AreEqual(2901, array.PackInt16()); // 101101010101
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Pack32Bit_Should_Pack_Correctly()
|
||||||
|
{
|
||||||
|
var array = new[] {true, false, true, false, true, false, true, false, true, true, false, true};
|
||||||
|
Assert.AreEqual(2901, array.PackInt32()); // 101101010101
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Pack64Bit_Should_Pack_Correctly()
|
||||||
|
{
|
||||||
|
var array = new[] {true, false, true, false, true, false, true, false, true, true, false, true};
|
||||||
|
Assert.AreEqual(2901, array.PackInt64()); // 101101010101
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Pack_ShouldThrow_GivenLargeArray()
|
||||||
|
{
|
||||||
|
bool[] array = Enumerable.Repeat(false, 65).ToArray();
|
||||||
|
Assert.ThrowsException<ArgumentException>(() => array.PackByte());
|
||||||
|
Assert.ThrowsException<ArgumentException>(() => array.PackInt16());
|
||||||
|
Assert.ThrowsException<ArgumentException>(() => array.PackInt32());
|
||||||
|
Assert.ThrowsException<ArgumentException>(() => array.PackInt64());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Pack_ShouldThrow_GivenNull()
|
||||||
|
{
|
||||||
|
bool[]? array = null;
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => array!.PackByte());
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => array!.PackInt16());
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => array!.PackInt32());
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => array!.PackInt64());
|
||||||
|
}
|
||||||
|
}
|
57
X10D.Tests/src/Collections/ByteTests.cs
Normal file
57
X10D.Tests/src/Collections/ByteTests.cs
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Collections;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Collections;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class ByteTests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void UnpackBits_ShouldUnpackToArrayCorrectly()
|
||||||
|
{
|
||||||
|
bool[] bits = ((byte)0b11010100).Unpack();
|
||||||
|
|
||||||
|
Assert.AreEqual(8, bits.Length);
|
||||||
|
|
||||||
|
Assert.IsFalse(bits[0]);
|
||||||
|
Assert.IsFalse(bits[1]);
|
||||||
|
Assert.IsTrue(bits[2]);
|
||||||
|
Assert.IsFalse(bits[3]);
|
||||||
|
Assert.IsTrue(bits[4]);
|
||||||
|
Assert.IsFalse(bits[5]);
|
||||||
|
Assert.IsTrue(bits[6]);
|
||||||
|
Assert.IsTrue(bits[7]);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void UnpackBits_ShouldUnpackToSpanCorrectly()
|
||||||
|
{
|
||||||
|
Span<bool> bits = stackalloc bool[8];
|
||||||
|
((byte)0b11010100).Unpack(bits);
|
||||||
|
|
||||||
|
Assert.IsFalse(bits[0]);
|
||||||
|
Assert.IsFalse(bits[1]);
|
||||||
|
Assert.IsTrue(bits[2]);
|
||||||
|
Assert.IsFalse(bits[3]);
|
||||||
|
Assert.IsTrue(bits[4]);
|
||||||
|
Assert.IsFalse(bits[5]);
|
||||||
|
Assert.IsTrue(bits[6]);
|
||||||
|
Assert.IsTrue(bits[7]);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void UnpackBits_ShouldRepackEqually()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(0b11010100, ((byte)0b11010100).Unpack().PackByte());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void UnpackBits_ShouldThrow_GivenTooSmallSpan()
|
||||||
|
{
|
||||||
|
Assert.ThrowsException<ArgumentException>(() =>
|
||||||
|
{
|
||||||
|
Span<bool> bits = stackalloc bool[0];
|
||||||
|
((byte)0b11010100).Unpack(bits);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
189
X10D.Tests/src/Collections/DictionaryTests.cs
Normal file
189
X10D.Tests/src/Collections/DictionaryTests.cs
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Collections;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Collections;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class DictionaryTests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void AddOrUpdate_ShouldAddNewKey_IfNotExists()
|
||||||
|
{
|
||||||
|
var dictionary = new Dictionary<int, string>();
|
||||||
|
Assert.IsFalse(dictionary.ContainsKey(1));
|
||||||
|
|
||||||
|
dictionary.AddOrUpdate(1, "one", (_, _) => string.Empty);
|
||||||
|
Assert.IsTrue(dictionary.ContainsKey(1));
|
||||||
|
Assert.AreEqual("one", dictionary[1]);
|
||||||
|
|
||||||
|
dictionary.Clear();
|
||||||
|
Assert.IsFalse(dictionary.ContainsKey(1));
|
||||||
|
|
||||||
|
dictionary.AddOrUpdate(1, _ => "one", (_, _) => string.Empty);
|
||||||
|
Assert.IsTrue(dictionary.ContainsKey(1));
|
||||||
|
Assert.AreEqual("one", dictionary[1]);
|
||||||
|
|
||||||
|
dictionary.Clear();
|
||||||
|
Assert.IsFalse(dictionary.ContainsKey(1));
|
||||||
|
|
||||||
|
dictionary.AddOrUpdate(1, (_, _) => "one", (_, _, _) => string.Empty, 0);
|
||||||
|
Assert.IsTrue(dictionary.ContainsKey(1));
|
||||||
|
Assert.AreEqual("one", dictionary[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void AddOrUpdate_ShouldUpdateKey_IfExists()
|
||||||
|
{
|
||||||
|
var dictionary = new Dictionary<int, string> {[1] = "one"};
|
||||||
|
Assert.IsTrue(dictionary.ContainsKey(1));
|
||||||
|
Assert.AreEqual("one", dictionary[1]);
|
||||||
|
|
||||||
|
dictionary.AddOrUpdate(1, string.Empty, (_, _) => "two");
|
||||||
|
Assert.IsTrue(dictionary.ContainsKey(1));
|
||||||
|
Assert.AreEqual("two", dictionary[1]);
|
||||||
|
|
||||||
|
dictionary.Clear();
|
||||||
|
Assert.IsFalse(dictionary.ContainsKey(1));
|
||||||
|
dictionary[1] = "one";
|
||||||
|
|
||||||
|
dictionary.AddOrUpdate(1, _ => string.Empty, (_, _) => "two");
|
||||||
|
Assert.IsTrue(dictionary.ContainsKey(1));
|
||||||
|
Assert.AreEqual("two", dictionary[1]);
|
||||||
|
|
||||||
|
dictionary.Clear();
|
||||||
|
Assert.IsFalse(dictionary.ContainsKey(1));
|
||||||
|
dictionary[1] = "one";
|
||||||
|
|
||||||
|
dictionary.AddOrUpdate(1, (_, _) => string.Empty, (_, _, _) => "two", 0);
|
||||||
|
Assert.IsTrue(dictionary.ContainsKey(1));
|
||||||
|
Assert.AreEqual("two", dictionary[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void AddOrUpdate_ShouldThrow_GivenNullDictionary()
|
||||||
|
{
|
||||||
|
Dictionary<int, string>? dictionary = null;
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => dictionary!.AddOrUpdate(1, string.Empty, (_, _) => string.Empty));
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() =>
|
||||||
|
dictionary!.AddOrUpdate(1, _ => string.Empty, (_, _) => string.Empty));
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() =>
|
||||||
|
dictionary!.AddOrUpdate(1, (_, _) => string.Empty, (_, _, _) => string.Empty, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void AddOrUpdate_ShouldThrow_GivenNullUpdateValueFactory()
|
||||||
|
{
|
||||||
|
var dictionary = new Dictionary<int, string>();
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => dictionary.AddOrUpdate(1, string.Empty, null!));
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => dictionary.AddOrUpdate(1, _ => string.Empty, null!));
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => dictionary.AddOrUpdate(1, (_, _) => string.Empty, null!, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void AddOrUpdate_ShouldThrow_GivenNullAddValueFactory()
|
||||||
|
{
|
||||||
|
var dictionary = new Dictionary<int, string>();
|
||||||
|
Func<int, string>? addValueFactory = null;
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => dictionary.AddOrUpdate(1, addValueFactory!, (_, _) => "one"));
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => dictionary.AddOrUpdate(1, null!, (_, _, _) => "one", 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ToConnectionString_ShouldReturnConnectionString()
|
||||||
|
{
|
||||||
|
var dictionary = new Dictionary<string, string?>
|
||||||
|
{
|
||||||
|
["Data Source"] = "localhost", ["Initial Catalog"] = "test", ["Integrated Security"] = "True", ["Foobar"] = null
|
||||||
|
};
|
||||||
|
|
||||||
|
string connectionString = dictionary.ToConnectionString();
|
||||||
|
Assert.AreEqual("Data Source=localhost;Initial Catalog=test;Integrated Security=True;Foobar=", connectionString);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ToConnectionString_ShouldReturnTransformedValueConnectionString()
|
||||||
|
{
|
||||||
|
var dictionary = new Dictionary<string, string?>
|
||||||
|
{
|
||||||
|
["Data Source"] = "localhost", ["Initial Catalog"] = "test", ["Integrated Security"] = "True", ["Foobar"] = null
|
||||||
|
};
|
||||||
|
|
||||||
|
string connectionString = dictionary.ToConnectionString(v => v?.ToUpperInvariant());
|
||||||
|
Assert.AreEqual("Data Source=LOCALHOST;Initial Catalog=TEST;Integrated Security=TRUE;Foobar=", connectionString);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ToConnectionString_ShouldReturnTransformedKeyValueConnectionString()
|
||||||
|
{
|
||||||
|
var dictionary = new Dictionary<string, string?>
|
||||||
|
{
|
||||||
|
["Data Source"] = "localhost", ["Initial Catalog"] = "test", ["Integrated Security"] = "True", ["Foobar"] = null
|
||||||
|
};
|
||||||
|
|
||||||
|
string connectionString = dictionary.ToConnectionString(k => k.ToUpper(), v => v?.ToUpperInvariant());
|
||||||
|
Assert.AreEqual("DATA SOURCE=LOCALHOST;INITIAL CATALOG=TEST;INTEGRATED SECURITY=TRUE;FOOBAR=", connectionString);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ToConnectionString_ShouldThrow_GivenNullSource()
|
||||||
|
{
|
||||||
|
Dictionary<string, string>? dictionary = null;
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => dictionary!.ToConnectionString());
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => dictionary!.ToConnectionString(null!));
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => dictionary!.ToConnectionString(null!, null!));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ToConnectionString_ShouldThrow_GivenNullSelector()
|
||||||
|
{
|
||||||
|
var dictionary = new Dictionary<string, string>();
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => dictionary.ToConnectionString(null!));
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => dictionary.ToConnectionString(null!, _ => _));
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => dictionary.ToConnectionString(_ => _, null!));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ToGetParameters_ShouldReturnParameters()
|
||||||
|
{
|
||||||
|
var dictionary = new Dictionary<string, string> {["id"] = "1", ["user"] = "hello world", ["foo"] = "bar"};
|
||||||
|
|
||||||
|
string queryString = dictionary.ToGetParameters();
|
||||||
|
Assert.AreEqual("id=1&user=hello+world&foo=bar", queryString);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ToGetParameters_ShouldReturnTransformedValueParameters()
|
||||||
|
{
|
||||||
|
var dictionary = new Dictionary<string, string?> {["id"] = "1", ["user"] = "hello world", ["foo"] = null};
|
||||||
|
|
||||||
|
string queryString = dictionary.ToGetParameters(v => v?.ToUpper());
|
||||||
|
Assert.AreEqual("id=1&user=HELLO+WORLD&foo=", queryString);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ToGetParameters_ShouldReturnTransformedKeyValueParameters()
|
||||||
|
{
|
||||||
|
var dictionary = new Dictionary<string, string?> {["id"] = "1", ["user"] = "hello world", ["foo"] = null};
|
||||||
|
|
||||||
|
string queryString = dictionary.ToGetParameters(k => k.ToUpper(), v => v?.ToUpper());
|
||||||
|
Assert.AreEqual("ID=1&USER=HELLO+WORLD&FOO=", queryString);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ToGetParameters_ShouldThrow_GivenNullSource()
|
||||||
|
{
|
||||||
|
Dictionary<string, string>? dictionary = null;
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => dictionary!.ToGetParameters());
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => dictionary!.ToGetParameters(null!));
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => dictionary!.ToGetParameters(null!, null!));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ToGetParameters_ShouldThrow_GivenNullSelector()
|
||||||
|
{
|
||||||
|
var dictionary = new Dictionary<string, string>();
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => dictionary.ToGetParameters(null!));
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => dictionary.ToGetParameters(null!, _ => _));
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => dictionary.ToGetParameters(_ => _, null!));
|
||||||
|
}
|
||||||
|
}
|
26
X10D.Tests/src/Collections/EnumerableTests.cs
Normal file
26
X10D.Tests/src/Collections/EnumerableTests.cs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Collections;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Collections;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class EnumerableTests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void Shuffled_ShouldThrow_GivenNull()
|
||||||
|
{
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => ((List<int>?)null)!.Shuffled());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Shuffled_ShouldReorder_GivenNotNull()
|
||||||
|
{
|
||||||
|
int[] array = Enumerable.Range(1, 52).ToArray(); // 52! chance of being shuffled to the same order
|
||||||
|
int[] shuffled = array[..];
|
||||||
|
|
||||||
|
CollectionAssert.AreEqual(array, shuffled);
|
||||||
|
|
||||||
|
shuffled = array.Shuffled().ToArray();
|
||||||
|
CollectionAssert.AreNotEqual(array, shuffled);
|
||||||
|
}
|
||||||
|
}
|
67
X10D.Tests/src/Collections/Int16Tests.cs
Normal file
67
X10D.Tests/src/Collections/Int16Tests.cs
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Collections;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Collections;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class Int16Tests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void UnpackBits_ShouldUnpackToArrayCorrectly()
|
||||||
|
{
|
||||||
|
bool[] bits = ((short)0b11010100).Unpack();
|
||||||
|
|
||||||
|
Assert.AreEqual(16, bits.Length);
|
||||||
|
|
||||||
|
Assert.IsFalse(bits[0]);
|
||||||
|
Assert.IsFalse(bits[1]);
|
||||||
|
Assert.IsTrue(bits[2]);
|
||||||
|
Assert.IsFalse(bits[3]);
|
||||||
|
Assert.IsTrue(bits[4]);
|
||||||
|
Assert.IsFalse(bits[5]);
|
||||||
|
Assert.IsTrue(bits[6]);
|
||||||
|
Assert.IsTrue(bits[7]);
|
||||||
|
|
||||||
|
for (var index = 8; index < 16; index++)
|
||||||
|
{
|
||||||
|
Assert.IsFalse(bits[index]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void UnpackBits_ShouldUnpackToSpanCorrectly()
|
||||||
|
{
|
||||||
|
Span<bool> bits = stackalloc bool[16];
|
||||||
|
((short)0b11010100).Unpack(bits);
|
||||||
|
|
||||||
|
Assert.IsFalse(bits[0]);
|
||||||
|
Assert.IsFalse(bits[1]);
|
||||||
|
Assert.IsTrue(bits[2]);
|
||||||
|
Assert.IsFalse(bits[3]);
|
||||||
|
Assert.IsTrue(bits[4]);
|
||||||
|
Assert.IsFalse(bits[5]);
|
||||||
|
Assert.IsTrue(bits[6]);
|
||||||
|
Assert.IsTrue(bits[7]);
|
||||||
|
|
||||||
|
for (var index = 8; index < 16; index++)
|
||||||
|
{
|
||||||
|
Assert.IsFalse(bits[index]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void UnpackBits_ShouldRepackEqually()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(0b11010100, ((short)0b11010100).Unpack().PackInt16());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void UnpackBits_ShouldThrow_GivenTooSmallSpan()
|
||||||
|
{
|
||||||
|
Assert.ThrowsException<ArgumentException>(() =>
|
||||||
|
{
|
||||||
|
Span<bool> bits = stackalloc bool[0];
|
||||||
|
((short)0b11010100).Unpack(bits);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
67
X10D.Tests/src/Collections/Int32Tests.cs
Normal file
67
X10D.Tests/src/Collections/Int32Tests.cs
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Collections;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Collections;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class Int32Tests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void UnpackBits_ShouldUnpackToArrayCorrectly()
|
||||||
|
{
|
||||||
|
bool[] bits = 0b11010100.Unpack();
|
||||||
|
|
||||||
|
Assert.AreEqual(32, bits.Length);
|
||||||
|
|
||||||
|
Assert.IsFalse(bits[0]);
|
||||||
|
Assert.IsFalse(bits[1]);
|
||||||
|
Assert.IsTrue(bits[2]);
|
||||||
|
Assert.IsFalse(bits[3]);
|
||||||
|
Assert.IsTrue(bits[4]);
|
||||||
|
Assert.IsFalse(bits[5]);
|
||||||
|
Assert.IsTrue(bits[6]);
|
||||||
|
Assert.IsTrue(bits[7]);
|
||||||
|
|
||||||
|
for (var index = 8; index < 32; index++)
|
||||||
|
{
|
||||||
|
Assert.IsFalse(bits[index]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void UnpackBits_ShouldUnpackToSpanCorrectly()
|
||||||
|
{
|
||||||
|
Span<bool> bits = stackalloc bool[32];
|
||||||
|
0b11010100.Unpack(bits);
|
||||||
|
|
||||||
|
Assert.IsFalse(bits[0]);
|
||||||
|
Assert.IsFalse(bits[1]);
|
||||||
|
Assert.IsTrue(bits[2]);
|
||||||
|
Assert.IsFalse(bits[3]);
|
||||||
|
Assert.IsTrue(bits[4]);
|
||||||
|
Assert.IsFalse(bits[5]);
|
||||||
|
Assert.IsTrue(bits[6]);
|
||||||
|
Assert.IsTrue(bits[7]);
|
||||||
|
|
||||||
|
for (var index = 8; index < 32; index++)
|
||||||
|
{
|
||||||
|
Assert.IsFalse(bits[index]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void UnpackBits_ShouldRepackEqually()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(0b11010100, 0b11010100.Unpack().PackInt32());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void UnpackBits_ShouldThrow_GivenTooSmallSpan()
|
||||||
|
{
|
||||||
|
Assert.ThrowsException<ArgumentException>(() =>
|
||||||
|
{
|
||||||
|
Span<bool> bits = stackalloc bool[0];
|
||||||
|
0b11010100.Unpack(bits);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
71
X10D.Tests/src/Collections/Int64Tests.cs
Normal file
71
X10D.Tests/src/Collections/Int64Tests.cs
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
using System.Diagnostics;
|
||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Collections;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Collections;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class Int64Tests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void UnpackBits_ShouldUnpackToArrayCorrectly()
|
||||||
|
{
|
||||||
|
bool[] bits = 0b11010100L.Unpack();
|
||||||
|
|
||||||
|
Assert.AreEqual(64, bits.Length);
|
||||||
|
|
||||||
|
Trace.WriteLine(Convert.ToString(0b11010100L, 2));
|
||||||
|
Trace.WriteLine(string.Join("", bits.Select(b => b ? "1" : "0")));
|
||||||
|
|
||||||
|
Assert.IsFalse(bits[0]);
|
||||||
|
Assert.IsFalse(bits[1]);
|
||||||
|
Assert.IsTrue(bits[2]);
|
||||||
|
Assert.IsFalse(bits[3]);
|
||||||
|
Assert.IsTrue(bits[4]);
|
||||||
|
Assert.IsFalse(bits[5]);
|
||||||
|
Assert.IsTrue(bits[6]);
|
||||||
|
Assert.IsTrue(bits[7]);
|
||||||
|
|
||||||
|
for (var index = 8; index < 64; index++)
|
||||||
|
{
|
||||||
|
Assert.IsFalse(bits[index], index.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void UnpackBits_ShouldUnpackToSpanCorrectly()
|
||||||
|
{
|
||||||
|
Span<bool> bits = stackalloc bool[64];
|
||||||
|
0b11010100L.Unpack(bits);
|
||||||
|
|
||||||
|
Assert.IsFalse(bits[0]);
|
||||||
|
Assert.IsFalse(bits[1]);
|
||||||
|
Assert.IsTrue(bits[2]);
|
||||||
|
Assert.IsFalse(bits[3]);
|
||||||
|
Assert.IsTrue(bits[4]);
|
||||||
|
Assert.IsFalse(bits[5]);
|
||||||
|
Assert.IsTrue(bits[6]);
|
||||||
|
Assert.IsTrue(bits[7]);
|
||||||
|
|
||||||
|
for (var index = 8; index < 64; index++)
|
||||||
|
{
|
||||||
|
Assert.IsFalse(bits[index], index.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void UnpackBits_ShouldRepackEqually()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(0b11010100L, 0b11010100L.Unpack().PackInt64());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void UnpackBits_ShouldThrow_GivenTooSmallSpan()
|
||||||
|
{
|
||||||
|
Assert.ThrowsException<ArgumentException>(() =>
|
||||||
|
{
|
||||||
|
Span<bool> bits = stackalloc bool[0];
|
||||||
|
0b11010100L.Unpack(bits);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
113
X10D.Tests/src/Collections/ListTests.cs
Normal file
113
X10D.Tests/src/Collections/ListTests.cs
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Collections;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Collections;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class ListTests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
[DataRow(1)]
|
||||||
|
[DataRow(1, 2, 3)]
|
||||||
|
[DataRow(1, 2, 3, 4, 5)]
|
||||||
|
public void Fill_ShouldGiveHomogenousList_GivenValue(params int[] args)
|
||||||
|
{
|
||||||
|
int[] all42 = Enumerable.Repeat(42, args.Length).ToArray();
|
||||||
|
var list = new List<int>(args);
|
||||||
|
|
||||||
|
CollectionAssert.AreEqual(args, list);
|
||||||
|
|
||||||
|
args.Fill(42);
|
||||||
|
list.Fill(42);
|
||||||
|
|
||||||
|
CollectionAssert.AreEqual(args, list);
|
||||||
|
CollectionAssert.AreEqual(all42, args);
|
||||||
|
CollectionAssert.AreEqual(all42, list);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
[DataRow(1)]
|
||||||
|
[DataRow(1, 2, 3)]
|
||||||
|
[DataRow(1, 2, 3, 4, 5)]
|
||||||
|
public void SlicedFill_ShouldLeaveFirstElement_GivenStartIndex1(params int[] args)
|
||||||
|
{
|
||||||
|
int first = args[0];
|
||||||
|
args.Fill(1, 1, args.Length - 1);
|
||||||
|
|
||||||
|
int[] comparison = Enumerable.Repeat(1, args.Length - 1).ToArray();
|
||||||
|
Assert.AreEqual(first, args[0]);
|
||||||
|
CollectionAssert.AreEqual(comparison, args[1..]);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Fill_ShouldThrow_GivenExceededCount()
|
||||||
|
{
|
||||||
|
int[] array = Array.Empty<int>();
|
||||||
|
var list = new List<int>();
|
||||||
|
Assert.ThrowsException<ArgumentOutOfRangeException>(() => array.Fill(0, 0, 1));
|
||||||
|
Assert.ThrowsException<ArgumentOutOfRangeException>(() => list.Fill(0, 0, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Fill_ShouldThrow_GivenNegativeCount()
|
||||||
|
{
|
||||||
|
int[] array = Array.Empty<int>();
|
||||||
|
var list = new List<int>();
|
||||||
|
Assert.ThrowsException<ArgumentOutOfRangeException>(() => array.Fill(0, 0, -1));
|
||||||
|
Assert.ThrowsException<ArgumentOutOfRangeException>(() => list.Fill(0, 0, -1));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Fill_ShouldThrow_GivenNegativeStartIndex()
|
||||||
|
{
|
||||||
|
int[] array = Array.Empty<int>();
|
||||||
|
var list = new List<int>();
|
||||||
|
Assert.ThrowsException<ArgumentOutOfRangeException>(() => array.Fill(0, -1, 0));
|
||||||
|
Assert.ThrowsException<ArgumentOutOfRangeException>(() => list.Fill(0, -1, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Fill_ShouldThrow_GivenNull()
|
||||||
|
{
|
||||||
|
int[]? array = null;
|
||||||
|
List<int>? list = null;
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => array!.Fill(0));
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => list!.Fill(0));
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => array!.Fill(0, 0, 0));
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => list!.Fill(0, 0, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Shuffle_ShouldReorder_GivenNotNull()
|
||||||
|
{
|
||||||
|
var list = new List<int>(Enumerable.Range(1, 52)); // 52! chance of being shuffled to the same order
|
||||||
|
var shuffled = new List<int>(list);
|
||||||
|
|
||||||
|
CollectionAssert.AreEqual(list, shuffled);
|
||||||
|
|
||||||
|
shuffled.Shuffle();
|
||||||
|
|
||||||
|
CollectionAssert.AreNotEqual(list, shuffled);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Shuffle_ShouldThrow_GivenNull()
|
||||||
|
{
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => ((List<int>?)null)!.Shuffle());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Random_ShouldReturnContainedObject_GivenNotNull()
|
||||||
|
{
|
||||||
|
var list = new List<int>(Enumerable.Range(1, 52)); // 52! chance of being shuffled to the same order
|
||||||
|
int random = list.Random();
|
||||||
|
|
||||||
|
Assert.IsTrue(list.Contains(random));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Random_ShouldThrow_GivenNull()
|
||||||
|
{
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => ((List<int>?)null)!.Random());
|
||||||
|
}
|
||||||
|
}
|
@ -1,214 +0,0 @@
|
|||||||
namespace X10D.Tests.Core
|
|
||||||
{
|
|
||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="BooleanExtensions" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestClass]
|
|
||||||
public class BooleanTests
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="BooleanExtensions.And" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void And()
|
|
||||||
{
|
|
||||||
const bool a = true;
|
|
||||||
const bool b = true;
|
|
||||||
const bool c = false;
|
|
||||||
const bool d = false;
|
|
||||||
|
|
||||||
Assert.IsTrue(a);
|
|
||||||
Assert.IsTrue(b);
|
|
||||||
Assert.IsFalse(c);
|
|
||||||
Assert.IsFalse(d);
|
|
||||||
|
|
||||||
Assert.IsTrue(a.And(b));
|
|
||||||
Assert.IsFalse(b.And(c));
|
|
||||||
Assert.IsFalse(c.And(d));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="BooleanExtensions.NAnd" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void NAnd()
|
|
||||||
{
|
|
||||||
const bool a = true;
|
|
||||||
const bool b = true;
|
|
||||||
const bool c = false;
|
|
||||||
const bool d = false;
|
|
||||||
|
|
||||||
Assert.IsTrue(a);
|
|
||||||
Assert.IsTrue(b);
|
|
||||||
Assert.IsFalse(c);
|
|
||||||
Assert.IsFalse(d);
|
|
||||||
|
|
||||||
Assert.IsFalse(a.NAnd(b));
|
|
||||||
Assert.IsTrue(b.NAnd(c));
|
|
||||||
Assert.IsTrue(c.NAnd(d));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="BooleanExtensions.NOr" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void NOr()
|
|
||||||
{
|
|
||||||
const bool a = true;
|
|
||||||
const bool b = true;
|
|
||||||
const bool c = false;
|
|
||||||
const bool d = false;
|
|
||||||
|
|
||||||
Assert.IsTrue(a);
|
|
||||||
Assert.IsTrue(b);
|
|
||||||
Assert.IsFalse(c);
|
|
||||||
Assert.IsFalse(d);
|
|
||||||
|
|
||||||
Assert.IsFalse(a.NOr(b));
|
|
||||||
Assert.IsFalse(b.NOr(c));
|
|
||||||
Assert.IsTrue(c.NOr(d));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="BooleanExtensions.Not" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void Not()
|
|
||||||
{
|
|
||||||
const bool a = true;
|
|
||||||
const bool b = false;
|
|
||||||
|
|
||||||
Assert.IsTrue(a);
|
|
||||||
Assert.IsFalse(b);
|
|
||||||
Assert.IsFalse(a.Not());
|
|
||||||
Assert.IsTrue(b.Not());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="BooleanExtensions.Or" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void Or()
|
|
||||||
{
|
|
||||||
const bool a = true;
|
|
||||||
const bool b = true;
|
|
||||||
const bool c = false;
|
|
||||||
const bool d = false;
|
|
||||||
|
|
||||||
Assert.IsTrue(a);
|
|
||||||
Assert.IsTrue(b);
|
|
||||||
Assert.IsFalse(c);
|
|
||||||
Assert.IsFalse(d);
|
|
||||||
|
|
||||||
Assert.IsTrue(a.Or(b));
|
|
||||||
Assert.IsTrue(b.Or(c));
|
|
||||||
Assert.IsFalse(c.Or(d));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="BooleanExtensions.ToByte" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void ToByte()
|
|
||||||
{
|
|
||||||
const bool a = true;
|
|
||||||
const bool b = false;
|
|
||||||
const byte c = 1;
|
|
||||||
const byte d = 0;
|
|
||||||
|
|
||||||
Assert.IsTrue(a);
|
|
||||||
Assert.IsFalse(b);
|
|
||||||
Assert.AreEqual(c, a.ToByte());
|
|
||||||
Assert.AreEqual(d, b.ToByte());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="BooleanExtensions.ToInt16" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void ToInt16()
|
|
||||||
{
|
|
||||||
const bool a = true;
|
|
||||||
const bool b = false;
|
|
||||||
|
|
||||||
Assert.IsTrue(a);
|
|
||||||
Assert.IsFalse(b);
|
|
||||||
Assert.AreEqual(1, a.ToInt16());
|
|
||||||
Assert.AreEqual(0, b.ToInt16());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="BooleanExtensions.ToInt32" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void ToInt32()
|
|
||||||
{
|
|
||||||
const bool a = true;
|
|
||||||
const bool b = false;
|
|
||||||
|
|
||||||
Assert.IsTrue(a);
|
|
||||||
Assert.IsFalse(b);
|
|
||||||
Assert.AreEqual(1, a.ToInt32());
|
|
||||||
Assert.AreEqual(0, b.ToInt32());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="BooleanExtensions.ToInt64" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void ToInt64()
|
|
||||||
{
|
|
||||||
const bool a = true;
|
|
||||||
const bool b = false;
|
|
||||||
|
|
||||||
Assert.IsTrue(a);
|
|
||||||
Assert.IsFalse(b);
|
|
||||||
Assert.AreEqual(1L, a.ToInt64());
|
|
||||||
Assert.AreEqual(0L, b.ToInt64());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="BooleanExtensions.XNOr" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void XNOr()
|
|
||||||
{
|
|
||||||
const bool a = true;
|
|
||||||
const bool b = true;
|
|
||||||
const bool c = false;
|
|
||||||
const bool d = false;
|
|
||||||
|
|
||||||
Assert.IsTrue(a);
|
|
||||||
Assert.IsTrue(b);
|
|
||||||
Assert.IsFalse(c);
|
|
||||||
Assert.IsFalse(d);
|
|
||||||
|
|
||||||
Assert.IsTrue(a.XNOr(b));
|
|
||||||
Assert.IsFalse(b.XNOr(c));
|
|
||||||
Assert.IsTrue(c.XNOr(d));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="BooleanExtensions.XOr" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void XOr()
|
|
||||||
{
|
|
||||||
const bool a = true;
|
|
||||||
const bool b = true;
|
|
||||||
const bool c = false;
|
|
||||||
const bool d = false;
|
|
||||||
|
|
||||||
Assert.IsTrue(a);
|
|
||||||
Assert.IsTrue(b);
|
|
||||||
Assert.IsFalse(c);
|
|
||||||
Assert.IsFalse(d);
|
|
||||||
|
|
||||||
Assert.IsFalse(a.XOr(b));
|
|
||||||
Assert.IsTrue(b.XOr(c));
|
|
||||||
Assert.IsFalse(c.XOr(d));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,103 +0,0 @@
|
|||||||
namespace X10D.Tests.Core
|
|
||||||
{
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="ByteExtensions" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestClass]
|
|
||||||
public class ByteTests
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="ByteExtensions.AsString" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void AsString()
|
|
||||||
{
|
|
||||||
byte[] a = { 0x00, 0x73, 0xc6, 0xff };
|
|
||||||
Assert.AreEqual("00-73-C6-FF", a.AsString());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="ByteExtensions.GetInt16" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void GetInt16()
|
|
||||||
{
|
|
||||||
byte[] a = { 0xF3, 0x3F };
|
|
||||||
Assert.AreEqual(16371, a.GetInt16());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="ByteExtensions.GetInt32" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void GetInt32()
|
|
||||||
{
|
|
||||||
byte[] a = { 0xB0, 0x0B, 0x13, 0x5F };
|
|
||||||
Assert.AreEqual(1595083696, a.GetInt32());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="ByteExtensions.GetInt64" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void GetInt64()
|
|
||||||
{
|
|
||||||
byte[] a = { 0xB0, 0x0B, 0x13, 0x50, 0x05, 0x31, 0xB0, 0x0B };
|
|
||||||
Assert.AreEqual(842227029206305712L, a.GetInt64());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="ByteExtensions.GetString(IEnumerable{byte})" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void GetString()
|
|
||||||
{
|
|
||||||
byte[] a = { 0x48, 0xc3, 0xa9, 0x6c, 0x6c, 0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64 };
|
|
||||||
Assert.AreEqual("H\u00e9llo World", a.GetString());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="ByteExtensions.GetString(IEnumerable{byte}, Encoding)" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void GetStringAscii()
|
|
||||||
{
|
|
||||||
byte[] a = { 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64 };
|
|
||||||
Assert.AreEqual("Hello World", a.GetString(Encoding.ASCII));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="ByteExtensions.GetUInt16" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void GetUInt16()
|
|
||||||
{
|
|
||||||
byte[] a = { 0xF3, 0x3F };
|
|
||||||
Assert.AreEqual(16371, a.GetUInt16());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="ByteExtensions.GetUInt32" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void GetUInt32()
|
|
||||||
{
|
|
||||||
byte[] a = { 0xB0, 0x0B, 0x13, 0x5F };
|
|
||||||
Assert.AreEqual(1595083696U, a.GetUInt32());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="ByteExtensions.GetUInt64" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void GetUInt64()
|
|
||||||
{
|
|
||||||
byte[] a = { 0xB0, 0x0B, 0x13, 0x50, 0x05, 0x31, 0xB0, 0x0B };
|
|
||||||
Assert.AreEqual(842227029206305712UL, a.GetUInt64());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,35 +0,0 @@
|
|||||||
namespace X10D.Tests.Core
|
|
||||||
{
|
|
||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="CharExtensions" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestClass]
|
|
||||||
public class CharTests
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="CharExtensions.Repeat" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void Random()
|
|
||||||
{
|
|
||||||
var set = "abcdefghijklmnopqrstuvwxyz".ToCharArray();
|
|
||||||
var random = set.Random(20);
|
|
||||||
|
|
||||||
Assert.IsTrue(random.All(c => Array.IndexOf(set, c) >= 0));
|
|
||||||
Assert.IsFalse(random.Any(c => Array.IndexOf(set, c) < -1));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="CharExtensions.Repeat" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void Repeat()
|
|
||||||
{
|
|
||||||
Assert.AreEqual("aaaaaaaaaa", 'a'.Repeat(10));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
namespace X10D.Tests.Core
|
|
||||||
{
|
|
||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="ComparableExtensions" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestClass]
|
|
||||||
public class ComparableTests
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="ComparableExtensions.Between{T}" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void Between()
|
|
||||||
{
|
|
||||||
Assert.IsTrue(5.Between(2, 7));
|
|
||||||
Assert.IsTrue(10.Between(9, 11));
|
|
||||||
Assert.IsFalse(100.Between(80, 99));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,58 +0,0 @@
|
|||||||
namespace X10D.Tests.Core
|
|
||||||
{
|
|
||||||
using System;
|
|
||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="ConvertibleExtensions" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestClass]
|
|
||||||
public class ConvertibleTests
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="ConvertibleExtensions.To{T}" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void To()
|
|
||||||
{
|
|
||||||
Assert.AreEqual(2, "2".To<int>());
|
|
||||||
Assert.AreEqual("12.5", 12.50.To<string>());
|
|
||||||
Assert.IsTrue("True".To<bool>());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="ConvertibleExtensions.ToOrDefault{T}(System.IConvertible, System.IFormatProvider)" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void ToOrDefault()
|
|
||||||
{
|
|
||||||
Assert.AreEqual(2, "2".ToOrDefault<int>());
|
|
||||||
Assert.AreEqual("12.5", 12.50.ToOrDefault<string>());
|
|
||||||
Assert.IsTrue("True".ToOrDefault<bool>());
|
|
||||||
Assert.ThrowsException<FormatException>(() => "Foo".ToOrDefault<double>());
|
|
||||||
Assert.IsTrue("1.5".ToOrDefault(out float f));
|
|
||||||
Assert.AreEqual(1.5f, f);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="ConvertibleExtensions.ToOrNull{T}(System.IConvertible, System.IFormatProvider)" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void ToOrNull()
|
|
||||||
{
|
|
||||||
Assert.IsFalse("foo".ToOrNull(out ConvertibleTests t));
|
|
||||||
Assert.IsNull(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="ConvertibleExtensions.ToOrOther{T}(System.IConvertible, T, System.IFormatProvider)" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void ToOrOther()
|
|
||||||
{
|
|
||||||
Assert.AreEqual(2.0, "Foo".ToOrOther(2.0));
|
|
||||||
Assert.IsFalse("Foo".ToOrOther(out var d, 2.0));
|
|
||||||
Assert.AreEqual(2.0, d);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
76
X10D.Tests/src/Core/CoreTests.cs
Normal file
76
X10D.Tests/src/Core/CoreTests.cs
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Core;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Core;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class CoreTests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
[DataRow(1)]
|
||||||
|
[DataRow("f")]
|
||||||
|
[DataRow(true)]
|
||||||
|
public void AsArrayValue_ShouldBeLength1_GivenValue(object o)
|
||||||
|
{
|
||||||
|
object[] array = o.AsArrayValue()!;
|
||||||
|
Assert.IsNotNull(array);
|
||||||
|
Assert.IsTrue(array.Length == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
[DataRow(1)]
|
||||||
|
[DataRow("f")]
|
||||||
|
[DataRow(true)]
|
||||||
|
public void AsArrayValue_ShouldContainValue_Given_Value(object o)
|
||||||
|
{
|
||||||
|
object[] array = o.AsArrayValue()!;
|
||||||
|
Assert.IsNotNull(array);
|
||||||
|
Assert.AreEqual(o, array[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
[DataRow(1)]
|
||||||
|
[DataRow("f")]
|
||||||
|
[DataRow(true)]
|
||||||
|
public void AsEnumerableValue_ShouldBeLength1_GivenValue(object o)
|
||||||
|
{
|
||||||
|
IEnumerable<object> enumerable = o.AsEnumerableValue()!;
|
||||||
|
Assert.IsNotNull(enumerable);
|
||||||
|
Assert.IsTrue(enumerable.Count() == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
[DataRow(1)]
|
||||||
|
[DataRow("f")]
|
||||||
|
[DataRow(true)]
|
||||||
|
public void AsEnumerableValue_ShouldContainValue_Given_Value(object o)
|
||||||
|
{
|
||||||
|
IEnumerable<object> enumerable = o.AsEnumerableValue()!;
|
||||||
|
Assert.IsNotNull(enumerable);
|
||||||
|
Assert.AreEqual(o, enumerable.ElementAt(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
[DataRow(1)]
|
||||||
|
[DataRow("f")]
|
||||||
|
[DataRow(true)]
|
||||||
|
public void RepeatValue_ShouldContainRepeatedValue_GivenValue(object o)
|
||||||
|
{
|
||||||
|
IEnumerable<object> enumerable = o.RepeatValue(10);
|
||||||
|
Assert.IsNotNull(enumerable);
|
||||||
|
|
||||||
|
object[] array = enumerable.ToArray();
|
||||||
|
Assert.AreEqual(10, array.Length);
|
||||||
|
CollectionAssert.AreEqual(new[] {o, o, o, o, o, o, o, o, o, o}, array);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
[DataRow(1)]
|
||||||
|
[DataRow("f")]
|
||||||
|
[DataRow(true)]
|
||||||
|
public void RepeatValue_ShouldThrow_GivenNegativeCount(object o)
|
||||||
|
{
|
||||||
|
// we must force enumeration via ToArray() to ensure the exception is thrown
|
||||||
|
Assert.ThrowsException<ArgumentOutOfRangeException>(() => o.RepeatValue(-1).ToArray());
|
||||||
|
}
|
||||||
|
}
|
@ -1,107 +0,0 @@
|
|||||||
namespace X10D.Tests.Core
|
|
||||||
{
|
|
||||||
using System;
|
|
||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="DateTimeExtensions" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestClass]
|
|
||||||
public class DateTimeTests
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="DateTimeExtensions.Age(DateTime)" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void Age()
|
|
||||||
{
|
|
||||||
// no choice but to create dynamic based on today's date.
|
|
||||||
// age varies with time
|
|
||||||
var now = DateTime.Now;
|
|
||||||
var dt = new DateTime(now.Year - 18, 1, 1);
|
|
||||||
|
|
||||||
Assert.AreEqual(18, dt.Age());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="DateTimeExtensions.First" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void First()
|
|
||||||
{
|
|
||||||
var dt = new DateTime(2018, 6, 20);
|
|
||||||
|
|
||||||
Assert.AreEqual(4, dt.First(DayOfWeek.Monday).Day);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="DateTimeExtensions.FirstDayOfMonth" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void FirstDayOfMonth()
|
|
||||||
{
|
|
||||||
var dt = new DateTime(2018, 6, 20);
|
|
||||||
var first = dt.FirstDayOfMonth();
|
|
||||||
|
|
||||||
Assert.AreEqual(dt.Year, first.Year);
|
|
||||||
Assert.AreEqual(dt.Month, first.Month);
|
|
||||||
Assert.AreEqual(1, first.Day);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="DateTimeExtensions.Last" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void Last()
|
|
||||||
{
|
|
||||||
{
|
|
||||||
var dt = new DateTime(2019, 12, 1);
|
|
||||||
var last = dt.Last(DayOfWeek.Wednesday);
|
|
||||||
|
|
||||||
Assert.AreEqual(dt.Year, last.Year);
|
|
||||||
Assert.AreEqual(dt.Month, last.Month);
|
|
||||||
Assert.AreEqual(25, last.Day);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
var dt = new DateTime(2020, 4, 14);
|
|
||||||
var last = dt.Last(DayOfWeek.Friday);
|
|
||||||
|
|
||||||
Assert.AreEqual(dt.Year, last.Year);
|
|
||||||
Assert.AreEqual(dt.Month, last.Month);
|
|
||||||
Assert.AreEqual(24, last.Day);
|
|
||||||
|
|
||||||
last = dt.Last(DayOfWeek.Thursday);
|
|
||||||
Assert.AreEqual(dt.Year, last.Year);
|
|
||||||
Assert.AreEqual(dt.Month, last.Month);
|
|
||||||
Assert.AreEqual(30, last.Day);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="DateTimeExtensions.LastDayOfMonth" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void LastDayOfMonth()
|
|
||||||
{
|
|
||||||
var dt = new DateTime(2016, 2, 4);
|
|
||||||
var last = dt.LastDayOfMonth();
|
|
||||||
|
|
||||||
Assert.AreEqual(dt.Year, last.Year);
|
|
||||||
Assert.AreEqual(dt.Month, last.Month);
|
|
||||||
Assert.AreEqual(29, last.Day); // 2016 is a leap year
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="DateTimeExtensions.ToUnixTimeStamp" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void ToUnixTimestamp()
|
|
||||||
{
|
|
||||||
var dt = new DateTime(2015, 10, 21, 1, 0, 0, DateTimeKind.Utc);
|
|
||||||
var unix = dt.ToUnixTimeStamp();
|
|
||||||
|
|
||||||
Assert.AreEqual(1445389200L, unix);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,42 +0,0 @@
|
|||||||
namespace X10D.Tests.Core
|
|
||||||
{
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="DictionaryExtensions" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestClass]
|
|
||||||
public class DictionaryTests
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="DictionaryExtensions.ToConnectionString{T1,T2}(IDictionary{T1,T2})" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void ToConnectionString()
|
|
||||||
{
|
|
||||||
var dictionary = new Dictionary<string, object>
|
|
||||||
{
|
|
||||||
{ "username", "Foo" }, { "password", "Foo Bar" }, { "port", 3306 },
|
|
||||||
};
|
|
||||||
|
|
||||||
var connectionString = dictionary.ToConnectionString();
|
|
||||||
Assert.AreEqual("username=Foo;password=\"Foo Bar\";port=3306", connectionString);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="DictionaryExtensions.ToGetParameters{T1,T2}(IDictionary{T1,T2})" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void ToGetParameters()
|
|
||||||
{
|
|
||||||
var dictionary = new Dictionary<string, object>
|
|
||||||
{
|
|
||||||
{ "username", "Foo" }, { "password", "Foo Bar" }, { "port", 3306 },
|
|
||||||
};
|
|
||||||
|
|
||||||
var getParameterString = dictionary.ToGetParameters();
|
|
||||||
Assert.AreEqual("username=Foo&password=Foo+Bar&port=3306", getParameterString);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,84 +0,0 @@
|
|||||||
namespace X10D.Tests.Core
|
|
||||||
{
|
|
||||||
using System;
|
|
||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="DoubleExtensions" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestClass]
|
|
||||||
public class DoubleTests
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="DoubleExtensions.Clamp" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void Clamp()
|
|
||||||
{
|
|
||||||
Assert.AreEqual(2.0, 3.0.Clamp(1.0, 2.0));
|
|
||||||
Assert.AreEqual(1.0, (-3.0).Clamp(1.0, 2.0));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="DoubleExtensions.DegreesToRadians" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void DegreesToRadians()
|
|
||||||
{
|
|
||||||
Assert.AreEqual(Math.PI, 180.0.DegreesToRadians());
|
|
||||||
Assert.AreEqual(Math.PI * 1.5, 270.0.DegreesToRadians());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="DoubleExtensions.GetBytes" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void GetBytes()
|
|
||||||
{
|
|
||||||
CollectionAssert.AreEqual(
|
|
||||||
new byte[] { 0x18, 0x2D, 0x44, 0x54, 0xFB, 0x21, 0x09, 0x40 },
|
|
||||||
Math.PI.GetBytes());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="DoubleExtensions.IsEven" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void IsEven()
|
|
||||||
{
|
|
||||||
Assert.IsTrue(2.0.IsEven());
|
|
||||||
Assert.IsFalse(1.0.IsEven());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="DoubleExtensions.IsOdd" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void IsOdd()
|
|
||||||
{
|
|
||||||
Assert.IsFalse(2.0.IsOdd());
|
|
||||||
Assert.IsTrue(1.0.IsOdd());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="DoubleExtensions.RadiansToDegrees" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void RadiansToDegrees()
|
|
||||||
{
|
|
||||||
Assert.AreEqual(180.0, Math.PI.RadiansToDegrees());
|
|
||||||
Assert.AreEqual(360.0, (2.0 * Math.PI).RadiansToDegrees());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="DoubleExtensions.Round" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void Round()
|
|
||||||
{
|
|
||||||
Assert.AreEqual(5.0, 3.5.Round(5));
|
|
||||||
Assert.AreEqual(5.0, 7.0.Round(5));
|
|
||||||
Assert.AreEqual(10.0, 7.5.Round(5));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
62
X10D.Tests/src/Core/EnumTests.cs
Normal file
62
X10D.Tests/src/Core/EnumTests.cs
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Core;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Core;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public 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.
|
||||||
|
// it's clearly Monday as defined by ISO 8601.
|
||||||
|
// but Microsoft can't fix this without breaking compatibility.
|
||||||
|
// I have feelings...
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Next()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(DayOfWeek.Monday, DayOfWeek.Sunday.Next());
|
||||||
|
Assert.AreEqual(DayOfWeek.Tuesday, DayOfWeek.Monday.Next());
|
||||||
|
Assert.AreEqual(DayOfWeek.Wednesday, DayOfWeek.Tuesday.Next());
|
||||||
|
Assert.AreEqual(DayOfWeek.Thursday, DayOfWeek.Wednesday.Next());
|
||||||
|
Assert.AreEqual(DayOfWeek.Friday, DayOfWeek.Thursday.Next());
|
||||||
|
Assert.AreEqual(DayOfWeek.Saturday, DayOfWeek.Friday.Next());
|
||||||
|
Assert.AreEqual(DayOfWeek.Sunday, DayOfWeek.Saturday.Next()); // Saturday is the "last" day. wrap to "first"
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NextUnchecked()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(DayOfWeek.Monday, DayOfWeek.Sunday.NextUnchecked());
|
||||||
|
Assert.AreEqual(DayOfWeek.Tuesday, DayOfWeek.Monday.NextUnchecked());
|
||||||
|
Assert.AreEqual(DayOfWeek.Wednesday, DayOfWeek.Tuesday.NextUnchecked());
|
||||||
|
Assert.AreEqual(DayOfWeek.Thursday, DayOfWeek.Wednesday.NextUnchecked());
|
||||||
|
Assert.AreEqual(DayOfWeek.Friday, DayOfWeek.Thursday.NextUnchecked());
|
||||||
|
Assert.AreEqual(DayOfWeek.Saturday, DayOfWeek.Friday.NextUnchecked());
|
||||||
|
Assert.ThrowsException<IndexOutOfRangeException>(() => DayOfWeek.Saturday.NextUnchecked());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Previous()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(DayOfWeek.Saturday, DayOfWeek.Sunday.Previous()); // Sunday is the "first" day. wrap to "last"
|
||||||
|
Assert.AreEqual(DayOfWeek.Sunday, DayOfWeek.Monday.Previous());
|
||||||
|
Assert.AreEqual(DayOfWeek.Monday, DayOfWeek.Tuesday.Previous());
|
||||||
|
Assert.AreEqual(DayOfWeek.Tuesday, DayOfWeek.Wednesday.Previous());
|
||||||
|
Assert.AreEqual(DayOfWeek.Wednesday, DayOfWeek.Thursday.Previous());
|
||||||
|
Assert.AreEqual(DayOfWeek.Thursday, DayOfWeek.Friday.Previous());
|
||||||
|
Assert.AreEqual(DayOfWeek.Friday, DayOfWeek.Saturday.Previous());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void PreviousUnchecked()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(DayOfWeek.Sunday, DayOfWeek.Monday.PreviousUnchecked());
|
||||||
|
Assert.AreEqual(DayOfWeek.Monday, DayOfWeek.Tuesday.PreviousUnchecked());
|
||||||
|
Assert.AreEqual(DayOfWeek.Tuesday, DayOfWeek.Wednesday.PreviousUnchecked());
|
||||||
|
Assert.AreEqual(DayOfWeek.Wednesday, DayOfWeek.Thursday.PreviousUnchecked());
|
||||||
|
Assert.AreEqual(DayOfWeek.Thursday, DayOfWeek.Friday.PreviousUnchecked());
|
||||||
|
Assert.AreEqual(DayOfWeek.Friday, DayOfWeek.Saturday.PreviousUnchecked());
|
||||||
|
Assert.ThrowsException<IndexOutOfRangeException>(() => DayOfWeek.Sunday.PreviousUnchecked());
|
||||||
|
}
|
||||||
|
}
|
@ -1,55 +1,20 @@
|
|||||||
namespace X10D.Tests.Core
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
{
|
using X10D.Core;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
namespace X10D.Tests.Core;
|
||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="EnumerableExtensions" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestClass]
|
[TestClass]
|
||||||
public class EnumerableTests
|
public class EnumerableTests
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="EnumerableExtensions.Split{T}" /> using an array of <see cref="byte" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void SplitByte()
|
[DataRow(1)]
|
||||||
|
[DataRow("f")]
|
||||||
|
[DataRow(true)]
|
||||||
|
public void AsEnumerable_ShouldWrapElement_GivenValue(object o)
|
||||||
{
|
{
|
||||||
byte[] foo = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
|
IEnumerable<object?> array = o.AsEnumerableValue().ToArray(); // prevent multiple enumeration of IEnumerable
|
||||||
IEnumerable<IEnumerable<byte>> chunks = foo.Split(2).ToArray();
|
Assert.IsNotNull(array);
|
||||||
|
Assert.IsTrue(array.Count() == 1);
|
||||||
Assert.AreEqual(4, chunks.Count());
|
Assert.AreEqual(o, array.ElementAt(0));
|
||||||
CollectionAssert.AreEqual(new byte[] { 0x01, 0x02 }, chunks.ElementAt(0).ToList());
|
|
||||||
CollectionAssert.AreEqual(new byte[] { 0x03, 0x04 }, chunks.ElementAt(1).ToList());
|
|
||||||
CollectionAssert.AreEqual(new byte[] { 0x05, 0x06 }, chunks.ElementAt(2).ToList());
|
|
||||||
CollectionAssert.AreEqual(new byte[] { 0x07, 0x08 }, chunks.ElementAt(3).ToList());
|
|
||||||
|
|
||||||
// test exceeding chunk size
|
|
||||||
chunks = foo.Split(foo.Length + 10).ToArray();
|
|
||||||
Assert.AreEqual(1, chunks.Count());
|
|
||||||
CollectionAssert.AreEqual(foo, chunks.SelectMany(c => c).ToList());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="EnumerableExtensions.Split{T}" /> using an array of <see cref="int" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void SplitInt32()
|
|
||||||
{
|
|
||||||
int[] foo = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
|
|
||||||
IEnumerable<IEnumerable<int>> chunks = foo.Split(2).ToArray();
|
|
||||||
|
|
||||||
Assert.AreEqual(4, chunks.Count());
|
|
||||||
CollectionAssert.AreEqual(new[] { 0x01, 0x02 }, chunks.ElementAt(0).ToList());
|
|
||||||
CollectionAssert.AreEqual(new[] { 0x03, 0x04 }, chunks.ElementAt(1).ToList());
|
|
||||||
CollectionAssert.AreEqual(new[] { 0x05, 0x06 }, chunks.ElementAt(2).ToList());
|
|
||||||
CollectionAssert.AreEqual(new[] { 0x07, 0x08 }, chunks.ElementAt(3).ToList());
|
|
||||||
|
|
||||||
// test exceeding chunk size
|
|
||||||
chunks = foo.Split(foo.Length + 10).ToArray();
|
|
||||||
Assert.AreEqual(1, chunks.Count());
|
|
||||||
CollectionAssert.AreEqual(foo, chunks.SelectMany(c => c).ToList());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
245
X10D.Tests/src/Core/RandomTests.cs
Normal file
245
X10D.Tests/src/Core/RandomTests.cs
Normal file
@ -0,0 +1,245 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Core;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Core;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class RandomTests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void NextBoolean_ShouldBeFalse_GivenSeed1234()
|
||||||
|
{
|
||||||
|
var random = new Random(1234);
|
||||||
|
Assert.IsFalse(random.NextBoolean());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NextBoolean_ShouldThrow_GivenNull()
|
||||||
|
{
|
||||||
|
Random? random = null;
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => random!.NextBoolean());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NextByte_ShouldBe101_GivenSeed1234()
|
||||||
|
{
|
||||||
|
var random = new Random(1234);
|
||||||
|
Assert.AreEqual(101, random.NextByte());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NextByte_WithMax10_ShouldBe3_GivenSeed1234()
|
||||||
|
{
|
||||||
|
var random = new Random(1234);
|
||||||
|
Assert.AreEqual(3, random.NextByte(10));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NextByte_WithMin0Max10_ShouldBe3_GivenSeed1234()
|
||||||
|
{
|
||||||
|
var random = new Random(1234);
|
||||||
|
Assert.AreEqual(3, random.NextByte(0, 10));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NextByte_ShouldThrow_GivenNull()
|
||||||
|
{
|
||||||
|
Random? random = null;
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => random!.NextByte());
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => random!.NextByte(10));
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => random!.NextByte(0, 10));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NextDouble_WithMax10_ShouldBe3point9908097935797695_GivenSeed1234()
|
||||||
|
{
|
||||||
|
var random = new Random(1234);
|
||||||
|
Assert.AreEqual(3.9908097935797695, random.NextDouble(10));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NextDouble_WithMin0Max10_ShouldBe3point9908097935797695_GivenSeed1234()
|
||||||
|
{
|
||||||
|
var random = new Random(1234);
|
||||||
|
Assert.AreEqual(3.9908097935797695, random.NextDouble(0, 10));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NextDouble_ShouldThrow_GivenNull()
|
||||||
|
{
|
||||||
|
Random? random = null;
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => random!.NextDouble(10));
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => random!.NextDouble(0, 10));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NextDouble_ShouldThrow_GivenMaxLessThan0()
|
||||||
|
{
|
||||||
|
var random = new Random(1234);
|
||||||
|
Assert.ThrowsException<ArgumentOutOfRangeException>(() => random.NextDouble(-1));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NextDouble_ShouldThrow_GivenMaxLessThanMin()
|
||||||
|
{
|
||||||
|
var random = new Random(1234);
|
||||||
|
Assert.ThrowsException<ArgumentException>(() => random.NextDouble(0, -1));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NextEnum_ShouldBeTuesday_GivenSeed1234()
|
||||||
|
{
|
||||||
|
var random = new Random(1234);
|
||||||
|
Assert.AreEqual(DayOfWeek.Tuesday, random.Next<DayOfWeek>());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NextEnum_ShouldThrow_GivenNull()
|
||||||
|
{
|
||||||
|
Random? random = null;
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => random!.Next<DayOfWeek>());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NextFrom_ShouldThrow_GivenNullRandom()
|
||||||
|
{
|
||||||
|
Random? random = null;
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => random!.NextFrom(""));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NextFrom_ShouldThrow_GivenNullSource()
|
||||||
|
{
|
||||||
|
var random = new Random(1234);
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => random.NextFrom((string?)null!));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NextFrom_ShouldEnumerate_GivenNonList()
|
||||||
|
{
|
||||||
|
IEnumerable<int> Source()
|
||||||
|
{
|
||||||
|
yield return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
var random = new Random(1234);
|
||||||
|
Assert.AreEqual(0, random.NextFrom(Source()));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NextInt16_ShouldBe13076_GivenSeed1234()
|
||||||
|
{
|
||||||
|
var random = new Random(1234);
|
||||||
|
Assert.AreEqual(13076, random.NextInt16());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NextInt16_WithMax10_ShouldBe3_GivenSeed1234()
|
||||||
|
{
|
||||||
|
var random = new Random(1234);
|
||||||
|
Assert.AreEqual(3, random.NextInt16(10));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NextInt16_WithMin0Max10_ShouldBe3_GivenSeed1234()
|
||||||
|
{
|
||||||
|
var random = new Random(1234);
|
||||||
|
Assert.AreEqual(3, random.NextInt16(0, 10));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NextInt16_ShouldThrow_GivenMaxLessThan0()
|
||||||
|
{
|
||||||
|
var random = new Random(1234);
|
||||||
|
Assert.ThrowsException<ArgumentOutOfRangeException>(() => random.NextInt16(-1));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NextInt16_ShouldThrow_GivenNull()
|
||||||
|
{
|
||||||
|
Random? random = null;
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => random!.NextInt16());
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => random!.NextInt16(10));
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => random!.NextInt16(0, 10));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NextSingle_WithMax10_ShouldBe3point99081_GivenSeed1234()
|
||||||
|
{
|
||||||
|
var random = new Random(1234);
|
||||||
|
Assert.AreEqual(3.99081f, random.NextSingle(10));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NextSingle_WithMin0Max10_ShouldBe3point99081_GivenSeed1234()
|
||||||
|
{
|
||||||
|
var random = new Random(1234);
|
||||||
|
Assert.AreEqual(3.99081f, random.NextSingle(0, 10));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NextSingle_ShouldThrow_GivenNull()
|
||||||
|
{
|
||||||
|
Random? random = null;
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => random!.NextSingle(10));
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => random!.NextSingle(0, 10));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NextSingle_ShouldThrow_GivenMaxLessThan0()
|
||||||
|
{
|
||||||
|
var random = new Random(1234);
|
||||||
|
Assert.ThrowsException<ArgumentOutOfRangeException>(() => random.NextSingle(-1));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NextSingle_ShouldThrow_GivenMaxLessThanMin()
|
||||||
|
{
|
||||||
|
var random = new Random(1234);
|
||||||
|
Assert.ThrowsException<ArgumentException>(() => random.NextSingle(0, -1));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NextString_ShouldBe_kxiyiyvnqi_GivenSeed1234()
|
||||||
|
{
|
||||||
|
const string alphabet = "abcdefghijklmnopqrstuvwxyz";
|
||||||
|
|
||||||
|
var random = new Random(1234);
|
||||||
|
Assert.AreEqual("kxiyiyvnqi", random.NextString(alphabet.ToCharArray(), 10));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NextString_ShouldBeEmpty_GivenLength0()
|
||||||
|
{
|
||||||
|
var random = new Random(1234);
|
||||||
|
Assert.AreEqual(string.Empty, random.NextString(ArraySegment<char>.Empty, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NextString_ShouldBeLength1_GivenLength1()
|
||||||
|
{
|
||||||
|
var random = new Random(1234);
|
||||||
|
Assert.AreEqual(1, random.NextString("hello world".ToCharArray(), 1).Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NextString_ShouldThrow_GivenNullRandom()
|
||||||
|
{
|
||||||
|
Random? random = null;
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => random!.NextString(ArraySegment<char>.Empty, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NextString_ShouldThrow_GivenNullSource()
|
||||||
|
{
|
||||||
|
var random = new Random(1234);
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => random.NextString(null!, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NextString_ShouldThrow_GivenNegativeLength()
|
||||||
|
{
|
||||||
|
var random = new Random(1234);
|
||||||
|
Assert.ThrowsException<ArgumentOutOfRangeException>(() => random.NextString(ArraySegment<char>.Empty, -1));
|
||||||
|
}
|
||||||
|
}
|
@ -1,70 +0,0 @@
|
|||||||
namespace X10D.Tests.Core
|
|
||||||
{
|
|
||||||
using System;
|
|
||||||
using System.ComponentModel;
|
|
||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="ReflectionExtensions" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestClass]
|
|
||||||
public class ReflectionTests
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Test for <see cref="ReflectionExtensions.GetDefaultValue{T}(System.Reflection.MemberInfo)" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void GetDefaultValue()
|
|
||||||
{
|
|
||||||
var klass = new TestClass();
|
|
||||||
|
|
||||||
foreach (var property in klass.GetType().GetProperties())
|
|
||||||
{
|
|
||||||
Assert.AreEqual("Foo", property.GetDefaultValue<string>());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Test for <see cref="ReflectionExtensions.GetDescription(System.Reflection.MemberInfo)" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void GetDescription()
|
|
||||||
{
|
|
||||||
var klass = new TestClass();
|
|
||||||
|
|
||||||
foreach (var property in klass.GetType().GetProperties())
|
|
||||||
{
|
|
||||||
Assert.AreEqual("Test description", property.GetDescription());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Test for <see cref="ReflectionExtensions.GetDescription(System.Reflection.MemberInfo)" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void SelectFromCustomAttribute()
|
|
||||||
{
|
|
||||||
var klass = new TestClass();
|
|
||||||
|
|
||||||
foreach (var property in klass.GetType().GetProperties())
|
|
||||||
{
|
|
||||||
var value = property.SelectFromCustomAttribute<TestAttribute, string>(a => a.TestValue);
|
|
||||||
Assert.AreEqual("Bar", value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Property)]
|
|
||||||
private sealed class TestAttribute : Attribute
|
|
||||||
{
|
|
||||||
public string TestValue { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
private sealed class TestClass
|
|
||||||
{
|
|
||||||
[System.ComponentModel.Description("Test description")]
|
|
||||||
[DefaultValue("Foo")]
|
|
||||||
[Test(TestValue = "Bar")]
|
|
||||||
public string TestProperty { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,81 +0,0 @@
|
|||||||
namespace X10D.Tests.Core
|
|
||||||
{
|
|
||||||
using System.Linq;
|
|
||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="StringExtensions" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestClass]
|
|
||||||
public class StringTests
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="StringExtensions.AsNullIfEmpty" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void AsNullIfEmpty()
|
|
||||||
{
|
|
||||||
Assert.AreEqual(null, string.Empty.AsNullIfEmpty());
|
|
||||||
Assert.AreEqual(null, ((string)null).AsNullIfEmpty());
|
|
||||||
Assert.AreEqual(" ", " ".AsNullIfEmpty());
|
|
||||||
Assert.AreEqual("foo", "foo".AsNullIfEmpty());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="StringExtensions.AsNullIfWhiteSpace" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void AsNullIfWhiteSpace()
|
|
||||||
{
|
|
||||||
Assert.AreEqual(null, string.Empty.AsNullIfWhiteSpace());
|
|
||||||
Assert.AreEqual(null, ((string)null).AsNullIfWhiteSpace());
|
|
||||||
Assert.AreEqual(null, " ".AsNullIfWhiteSpace());
|
|
||||||
Assert.AreEqual("foo", "foo".AsNullIfWhiteSpace());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="StringExtensions.Repeat" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void Repeat()
|
|
||||||
{
|
|
||||||
Assert.AreEqual("foofoofoofoofoo", "foo".Repeat(5));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="StringExtensions.Reverse" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void Reverse()
|
|
||||||
{
|
|
||||||
Assert.AreEqual("dlroW olleH", StringExtensions.Reverse("Hello World"));
|
|
||||||
Assert.AreEqual("Foobar", StringExtensions.Reverse("rabooF"));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="StringExtensions.Split" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void Split()
|
|
||||||
{
|
|
||||||
const string str = "Hello World";
|
|
||||||
|
|
||||||
// ReSharper disable once SuggestVarOrType_Elsewhere
|
|
||||||
var arr = str.Split(2).ToArray();
|
|
||||||
CollectionAssert.AreEqual(new[] { "He", "ll", "o ", "Wo", "rl", "d" }, arr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="StringExtensions.WithAlternative" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void WithAlternative()
|
|
||||||
{
|
|
||||||
Assert.AreEqual("Hello", "Hello".WithAlternative("Discarded"));
|
|
||||||
Assert.AreEqual("Alternative", string.Empty.WithAlternative("Alternative"));
|
|
||||||
Assert.AreEqual(" ", " ".WithAlternative("Discarded"));
|
|
||||||
Assert.AreEqual("Alternative", " ".WithAlternative("Alternative", true));
|
|
||||||
Assert.AreEqual("Alternative", ((string)null).WithAlternative("Alternative"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
namespace X10D.Tests.Core
|
|
||||||
{
|
|
||||||
using System;
|
|
||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="TimeSpanParser" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestClass]
|
|
||||||
public class TimeSpanParserTests
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Tests for <see cref="TimeSpanParser.Parse" />.
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void TestParser()
|
|
||||||
{
|
|
||||||
Assert.AreEqual(TimeSpan.FromHours(3), "3h".ToTimeSpan());
|
|
||||||
Assert.AreEqual(TimeSpan.FromMinutes(2.5), "2.5m".ToTimeSpan());
|
|
||||||
Assert.AreEqual(TimeSpan.FromHours(1), "60m".ToTimeSpan());
|
|
||||||
Assert.AreEqual(TimeSpan.FromDays(1), "1d".ToTimeSpan());
|
|
||||||
Assert.AreEqual(TimeSpan.FromDays(8), "1w 1d".ToTimeSpan());
|
|
||||||
Assert.AreEqual(TimeSpan.FromDays(8), "1w1d".ToTimeSpan());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
37
X10D.Tests/src/Drawing/RandomTests.cs
Normal file
37
X10D.Tests/src/Drawing/RandomTests.cs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
using System.Drawing;
|
||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Drawing;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Drawing;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class RandomTests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void NextColorArgb_ShouldReturn331515e5_GivenSeed1234()
|
||||||
|
{
|
||||||
|
var random = new Random(1234);
|
||||||
|
Assert.AreEqual(Color.FromArgb(51, 21, 21, 229), random.NextColorArgb());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NextColorArgb_ShouldThrow_GivenNull()
|
||||||
|
{
|
||||||
|
Random? random = null;
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => random!.NextColorArgb());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NextColorRgb_ShouldReturn1515e5_GivenSeed1234()
|
||||||
|
{
|
||||||
|
var random = new Random(1234);
|
||||||
|
Assert.AreEqual(Color.FromArgb(255, 21, 21, 229), random.NextColorRgb());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NextColorRgb_ShouldThrow_GivenNull()
|
||||||
|
{
|
||||||
|
Random? random = null;
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => random!.NextColorRgb());
|
||||||
|
}
|
||||||
|
}
|
32
X10D.Tests/src/IO/BooleanTests.cs
Normal file
32
X10D.Tests/src/IO/BooleanTests.cs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.IO;
|
||||||
|
|
||||||
|
namespace X10D.Tests.IO;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class BooleanTests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void GetBytes_ReturnsArrayContaining1()
|
||||||
|
{
|
||||||
|
const bool value = true;
|
||||||
|
CollectionAssert.AreEqual(new byte[] {1}, value.GetBytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void TryWriteBytes_ReturnsTrue_FillsSpanContaining1_GivenLargeEnoughSpan()
|
||||||
|
{
|
||||||
|
const bool value = true;
|
||||||
|
Span<byte> buffer = stackalloc byte[1];
|
||||||
|
Assert.IsTrue(value.TryWriteBytes(buffer));
|
||||||
|
CollectionAssert.AreEqual(new byte[] {1}, buffer.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void TryWriteBytes_ReturnsFalse_GivenSmallSpan()
|
||||||
|
{
|
||||||
|
const bool value = true;
|
||||||
|
Span<byte> buffer = stackalloc byte[0];
|
||||||
|
Assert.IsFalse(value.TryWriteBytes(buffer));
|
||||||
|
}
|
||||||
|
}
|
32
X10D.Tests/src/IO/ByteTests.cs
Normal file
32
X10D.Tests/src/IO/ByteTests.cs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.IO;
|
||||||
|
|
||||||
|
namespace X10D.Tests.IO;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class ByteTests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void GetBytes_ReturnsArrayContainingItself()
|
||||||
|
{
|
||||||
|
const byte value = 0xFF;
|
||||||
|
CollectionAssert.AreEqual(new[] {value}, value.GetBytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void TryWriteBytes_ReturnsTrue_FillsSpanContainingItself_GivenLargeEnoughSpan()
|
||||||
|
{
|
||||||
|
const byte value = 0xFF;
|
||||||
|
Span<byte> buffer = stackalloc byte[1];
|
||||||
|
Assert.IsTrue(value.TryWriteBytes(buffer));
|
||||||
|
CollectionAssert.AreEqual(new[] {value}, buffer.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void TryWriteBytes_ReturnsFalse_GivenSmallSpan()
|
||||||
|
{
|
||||||
|
const byte value = 0x0F;
|
||||||
|
Span<byte> buffer = stackalloc byte[0];
|
||||||
|
Assert.IsFalse(value.TryWriteBytes(buffer));
|
||||||
|
}
|
||||||
|
}
|
66
X10D.Tests/src/IO/DoubleTests.cs
Normal file
66
X10D.Tests/src/IO/DoubleTests.cs
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.IO;
|
||||||
|
|
||||||
|
namespace X10D.Tests.IO;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class DoubleTests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void GetBytes_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());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void GetBytes_ReturnsCorrectValue_WithEndianness()
|
||||||
|
{
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void TryWriteBytes_ReturnsTrue_FillsSpanCorrectly_GivenLargeEnoughSpan()
|
||||||
|
{
|
||||||
|
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.IsTrue(value.TryWriteBytes(buffer));
|
||||||
|
CollectionAssert.AreEqual(bytes, buffer.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void TryWriteBytes_ReturnsTrue_FillsSpanCorrectly_GivenLargeEnoughSpan_WithEndianness()
|
||||||
|
{
|
||||||
|
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.IsTrue(value.TryWriteBytes(buffer, Endianness.LittleEndian));
|
||||||
|
CollectionAssert.AreEqual(littleEndian, buffer.ToArray());
|
||||||
|
|
||||||
|
Assert.IsTrue(value.TryWriteBytes(buffer, Endianness.BigEndian));
|
||||||
|
CollectionAssert.AreEqual(bigEndian, buffer.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void TryWriteBytes_ReturnsFalse_GivenSmallSpan()
|
||||||
|
{
|
||||||
|
const double value = 42.5;
|
||||||
|
Span<byte> buffer = stackalloc byte[0];
|
||||||
|
Assert.IsFalse(value.TryWriteBytes(buffer));
|
||||||
|
}
|
||||||
|
}
|
93
X10D.Tests/src/IO/FileInfoTests.cs
Normal file
93
X10D.Tests/src/IO/FileInfoTests.cs
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
using System.Security.Cryptography;
|
||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.IO;
|
||||||
|
|
||||||
|
namespace X10D.Tests.IO;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class FileInfoTests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void GetHashSha1ShouldBeCorrect()
|
||||||
|
{
|
||||||
|
string fileName = $"temp.{DateTimeOffset.Now.ToUnixTimeSeconds()}.bin";
|
||||||
|
if (File.Exists(fileName))
|
||||||
|
{
|
||||||
|
Assert.Fail("Temporary file already exists");
|
||||||
|
}
|
||||||
|
|
||||||
|
File.WriteAllText(fileName, "Hello World");
|
||||||
|
Assert.IsTrue(File.Exists(fileName));
|
||||||
|
|
||||||
|
// SHA-1
|
||||||
|
byte[] expectedHash =
|
||||||
|
{
|
||||||
|
0x0A, 0x4D, 0x55, 0xA8, 0xD7, 0x78, 0xE5, 0x02, 0x2F, 0xAB, 0x70, 0x19, 0x77, 0xC5, 0xD8, 0x40, 0xBB, 0xC4, 0x86,
|
||||||
|
0xD0
|
||||||
|
};
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
byte[] hash = new FileInfo(fileName).GetHash<SHA1>();
|
||||||
|
CollectionAssert.AreEqual(expectedHash, hash);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
File.Delete(fileName); // cleanup is important
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void TryWriteHashSha1ShouldBeCorrect()
|
||||||
|
{
|
||||||
|
string fileName = $"temp.{DateTimeOffset.Now.ToUnixTimeSeconds()}.bin";
|
||||||
|
if (File.Exists(fileName))
|
||||||
|
{
|
||||||
|
Assert.Fail("Temporary file already exists");
|
||||||
|
}
|
||||||
|
|
||||||
|
File.WriteAllText(fileName, "Hello World");
|
||||||
|
Assert.IsTrue(File.Exists(fileName));
|
||||||
|
|
||||||
|
// SHA-1
|
||||||
|
byte[] expectedHash =
|
||||||
|
{
|
||||||
|
0x0A, 0x4D, 0x55, 0xA8, 0xD7, 0x78, 0xE5, 0x02, 0x2F, 0xAB, 0x70, 0x19, 0x77, 0xC5, 0xD8, 0x40, 0xBB, 0xC4, 0x86,
|
||||||
|
0xD0
|
||||||
|
};
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Span<byte> hash = stackalloc byte[20];
|
||||||
|
new FileInfo(fileName).TryWriteHash<SHA1>(hash, out int bytesWritten);
|
||||||
|
Assert.AreEqual(expectedHash.Length, bytesWritten);
|
||||||
|
CollectionAssert.AreEqual(expectedHash, hash.ToArray());
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
File.Delete(fileName); // cleanup is important
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void GetHashNullShouldThrow()
|
||||||
|
{
|
||||||
|
// any HashAlgorithm will do, but SHA1 is used above. so to remain consistent, we use it here
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => ((FileInfo?)null)!.GetHash<SHA1>());
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => ((FileInfo?)null)!.TryWriteHash<SHA1>(Span<byte>.Empty, out _));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void GetHashInvalidFileShouldThrow()
|
||||||
|
{
|
||||||
|
string fileName = $"temp.{DateTimeOffset.Now.ToUnixTimeSeconds()}.bin";
|
||||||
|
if (File.Exists(fileName))
|
||||||
|
{
|
||||||
|
Assert.Fail("Temporary file already exists");
|
||||||
|
}
|
||||||
|
|
||||||
|
// any HashAlgorithm will do, but SHA1 is used above. so to remain consistent, we use it here
|
||||||
|
Assert.ThrowsException<FileNotFoundException>(() => new FileInfo(fileName).GetHash<SHA1>());
|
||||||
|
Assert.ThrowsException<FileNotFoundException>(() => new FileInfo(fileName).TryWriteHash<SHA1>(Span<byte>.Empty, out _));
|
||||||
|
}
|
||||||
|
}
|
62
X10D.Tests/src/IO/Int16Tests.cs
Normal file
62
X10D.Tests/src/IO/Int16Tests.cs
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.IO;
|
||||||
|
|
||||||
|
namespace X10D.Tests.IO;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class Int16Tests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void GetBytes_ReturnsCorrectValue()
|
||||||
|
{
|
||||||
|
const short value = 0x0F;
|
||||||
|
byte[] bytes = BitConverter.IsLittleEndian ? new byte[] {0x0F, 0} : new byte[] {0, 0x0F};
|
||||||
|
CollectionAssert.AreEqual(bytes, value.GetBytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void GetBytes_ReturnsCorrectValue_WithEndianness()
|
||||||
|
{
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void TryWriteBytes_ReturnsTrue_FillsSpanCorrectly_GivenLargeEnoughSpan()
|
||||||
|
{
|
||||||
|
const short value = 0x0F;
|
||||||
|
byte[] bytes = BitConverter.IsLittleEndian ? new byte[] {0x0F, 0} : new byte[] {0, 0x0F};
|
||||||
|
|
||||||
|
Span<byte> buffer = stackalloc byte[2];
|
||||||
|
Assert.IsTrue(value.TryWriteBytes(buffer));
|
||||||
|
CollectionAssert.AreEqual(bytes, buffer.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void TryWriteBytes_ReturnsTrue_FillsSpanCorrectly_GivenLargeEnoughSpan_WithEndianness()
|
||||||
|
{
|
||||||
|
const short value = 0x0F;
|
||||||
|
byte[] littleEndian = {0x0F, 0};
|
||||||
|
byte[] bigEndian = {0, 0x0F};
|
||||||
|
|
||||||
|
Span<byte> buffer = stackalloc byte[2];
|
||||||
|
|
||||||
|
Assert.IsTrue(value.TryWriteBytes(buffer, Endianness.LittleEndian));
|
||||||
|
CollectionAssert.AreEqual(littleEndian, buffer.ToArray());
|
||||||
|
|
||||||
|
Assert.IsTrue(value.TryWriteBytes(buffer, Endianness.BigEndian));
|
||||||
|
CollectionAssert.AreEqual(bigEndian, buffer.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void TryWriteBytes_ReturnsFalse_GivenSmallSpan()
|
||||||
|
{
|
||||||
|
const short value = 0x0F;
|
||||||
|
Span<byte> buffer = stackalloc byte[0];
|
||||||
|
Assert.IsFalse(value.TryWriteBytes(buffer));
|
||||||
|
}
|
||||||
|
}
|
62
X10D.Tests/src/IO/Int32Tests.cs
Normal file
62
X10D.Tests/src/IO/Int32Tests.cs
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.IO;
|
||||||
|
|
||||||
|
namespace X10D.Tests.IO;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class Int32Tests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void GetBytes_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());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void GetBytes_ReturnsCorrectValue_WithEndianness()
|
||||||
|
{
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void TryWriteBytes_ReturnsTrue_FillsSpanCorrectly_GivenLargeEnoughSpan()
|
||||||
|
{
|
||||||
|
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.IsTrue(value.TryWriteBytes(buffer));
|
||||||
|
CollectionAssert.AreEqual(bytes, buffer.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void TryWriteBytes_ReturnsTrue_FillsSpanCorrectly_GivenLargeEnoughSpan_WithEndianness()
|
||||||
|
{
|
||||||
|
const int value = 0x0F;
|
||||||
|
byte[] littleEndian = {0x0F, 0, 0, 0};
|
||||||
|
byte[] bigEndian = {0, 0, 0, 0x0F};
|
||||||
|
|
||||||
|
Span<byte> buffer = stackalloc byte[4];
|
||||||
|
|
||||||
|
Assert.IsTrue(value.TryWriteBytes(buffer, Endianness.LittleEndian));
|
||||||
|
CollectionAssert.AreEqual(littleEndian, buffer.ToArray());
|
||||||
|
|
||||||
|
Assert.IsTrue(value.TryWriteBytes(buffer, Endianness.BigEndian));
|
||||||
|
CollectionAssert.AreEqual(bigEndian, buffer.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void TryWriteBytes_ReturnsFalse_GivenSmallSpan()
|
||||||
|
{
|
||||||
|
const int value = 0x0F;
|
||||||
|
Span<byte> buffer = stackalloc byte[0];
|
||||||
|
Assert.IsFalse(value.TryWriteBytes(buffer));
|
||||||
|
}
|
||||||
|
}
|
66
X10D.Tests/src/IO/Int64Tests.cs
Normal file
66
X10D.Tests/src/IO/Int64Tests.cs
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.IO;
|
||||||
|
|
||||||
|
namespace X10D.Tests.IO;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class Int64Tests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void GetBytes_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());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void GetBytes_ReturnsCorrectValue_WithEndianness()
|
||||||
|
{
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void TryWriteBytes_ReturnsTrue_FillsSpanCorrectly_GivenLargeEnoughSpan()
|
||||||
|
{
|
||||||
|
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.IsTrue(value.TryWriteBytes(buffer));
|
||||||
|
CollectionAssert.AreEqual(bytes, buffer.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void TryWriteBytes_ReturnsTrue_FillsSpanCorrectly_GivenLargeEnoughSpan_WithEndianness()
|
||||||
|
{
|
||||||
|
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.IsTrue(value.TryWriteBytes(buffer, Endianness.LittleEndian));
|
||||||
|
CollectionAssert.AreEqual(littleEndian, buffer.ToArray());
|
||||||
|
|
||||||
|
Assert.IsTrue(value.TryWriteBytes(buffer, Endianness.BigEndian));
|
||||||
|
CollectionAssert.AreEqual(bigEndian, buffer.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void TryWriteBytes_ReturnsFalse_GivenSmallSpan()
|
||||||
|
{
|
||||||
|
const long value = 0x0F;
|
||||||
|
Span<byte> buffer = stackalloc byte[0];
|
||||||
|
Assert.IsFalse(value.TryWriteBytes(buffer));
|
||||||
|
}
|
||||||
|
}
|
168
X10D.Tests/src/IO/ListOfByteTests.cs
Normal file
168
X10D.Tests/src/IO/ListOfByteTests.cs
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
using System.Text;
|
||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.IO;
|
||||||
|
|
||||||
|
namespace X10D.Tests.IO;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class ListOfByteTests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void AsString_ShouldReturnBytes_GivenBytes()
|
||||||
|
{
|
||||||
|
var bytes = new byte[] {0x01, 0x02, 0x03, 0x04, 0x05};
|
||||||
|
Assert.AreEqual("01-02-03-04-05", bytes.AsString());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void AsString_ShouldThrow_GivenNullArray()
|
||||||
|
{
|
||||||
|
byte[]? bytes = null;
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => bytes!.AsString());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ToDouble_ShouldReturnDouble_GivenBytes()
|
||||||
|
{
|
||||||
|
var bytes = new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7A, 0x40};
|
||||||
|
|
||||||
|
if (!BitConverter.IsLittleEndian)
|
||||||
|
{
|
||||||
|
Array.Reverse(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.AreEqual(420.0, bytes.ToDouble(), 1e-6);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ToDouble_ShouldThrow_GivenNullArray()
|
||||||
|
{
|
||||||
|
byte[]? bytes = null;
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => bytes!.ToDouble());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ToInt16_ShouldReturnInt16_GivenBytes()
|
||||||
|
{
|
||||||
|
var bytes = new byte[] {0xA4, 0x01};
|
||||||
|
Assert.AreEqual(420, bytes.ToInt16());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ToInt16_ShouldThrow_GivenNullArray()
|
||||||
|
{
|
||||||
|
byte[]? bytes = null;
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => bytes!.ToInt16());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ToInt32_ShouldReturnInt32_GivenBytes()
|
||||||
|
{
|
||||||
|
var bytes = new byte[] {0xA4, 0x01, 0x00, 0x00};
|
||||||
|
Assert.AreEqual(420, bytes.ToInt32());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ToInt32_ShouldThrow_GivenNullArray()
|
||||||
|
{
|
||||||
|
byte[]? bytes = null;
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => bytes!.ToInt32());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ToInt64_ShouldReturnInt32_GivenBytes()
|
||||||
|
{
|
||||||
|
var bytes = new byte[] {0xA4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||||
|
Assert.AreEqual(420L, bytes.ToInt64());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ToInt64_ShouldThrow_GivenNullArray()
|
||||||
|
{
|
||||||
|
byte[]? bytes = null;
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => bytes!.ToInt64());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ToSingle_ShouldReturnDouble_GivenBytes()
|
||||||
|
{
|
||||||
|
var bytes = new byte[] {0x00, 0x00, 0xD2, 0x43};
|
||||||
|
|
||||||
|
if (!BitConverter.IsLittleEndian)
|
||||||
|
{
|
||||||
|
Array.Reverse(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.AreEqual(420.0, bytes.ToSingle(), 1e-6);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ToSingle_ShouldThrow_GivenNullArray()
|
||||||
|
{
|
||||||
|
byte[]? bytes = null;
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => bytes!.ToSingle());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ToString_ShouldReturnHelloWorld_GivenUTF8()
|
||||||
|
{
|
||||||
|
var bytes = new byte[] {0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x57, 0x6F, 0x72, 0x6C, 0x64};
|
||||||
|
Assert.AreEqual("Hello World", bytes.ToString(Encoding.UTF8));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ToString_ShouldThrow_GivenNullArray()
|
||||||
|
{
|
||||||
|
byte[]? bytes = null;
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => bytes!.ToString(Encoding.UTF8));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ToString_ShouldThrow_GivenNullEncoding()
|
||||||
|
{
|
||||||
|
var bytes = new byte[] {0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x57, 0x6F, 0x72, 0x6C, 0x64};
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => bytes.ToString(null!));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ToUInt16_ShouldReturnInt16_GivenBytes()
|
||||||
|
{
|
||||||
|
var bytes = new byte[] {0xA4, 0x01};
|
||||||
|
Assert.AreEqual((ushort)420, bytes.ToUInt16());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ToUInt16_ShouldThrow_GivenNullArray()
|
||||||
|
{
|
||||||
|
byte[]? bytes = null;
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => bytes!.ToUInt16());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ToUInt32_ShouldReturnInt32_GivenBytes()
|
||||||
|
{
|
||||||
|
var bytes = new byte[] {0xA4, 0x01, 0x00, 0x00};
|
||||||
|
Assert.AreEqual(420U, bytes.ToUInt32());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ToUInt32_ShouldThrow_GivenNullArray()
|
||||||
|
{
|
||||||
|
byte[]? bytes = null;
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => bytes!.ToUInt32());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ToUInt64_ShouldReturnInt32_GivenBytes()
|
||||||
|
{
|
||||||
|
var bytes = new byte[] {0xA4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||||
|
Assert.AreEqual(420UL, bytes.ToUInt64());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ToUInt64_ShouldThrow_GivenNullArray()
|
||||||
|
{
|
||||||
|
byte[]? bytes = null;
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => bytes!.ToUInt64());
|
||||||
|
}
|
||||||
|
}
|
33
X10D.Tests/src/IO/SByteTests.cs
Normal file
33
X10D.Tests/src/IO/SByteTests.cs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.IO;
|
||||||
|
|
||||||
|
namespace X10D.Tests.IO;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
[CLSCompliant(false)]
|
||||||
|
public class SByteTests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void GetBytes_ReturnsArrayContainingItself()
|
||||||
|
{
|
||||||
|
const sbyte value = 0x0F;
|
||||||
|
CollectionAssert.AreEqual(new[] {(byte)value}, value.GetBytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void TryWriteBytes_ReturnsTrue_FillsSpanContainingItself_GivenLargeEnoughSpan()
|
||||||
|
{
|
||||||
|
const sbyte value = 0x0F;
|
||||||
|
Span<byte> buffer = stackalloc byte[1];
|
||||||
|
Assert.IsTrue(value.TryWriteBytes(buffer));
|
||||||
|
CollectionAssert.AreEqual(new[] {(byte)value}, buffer.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void TryWriteBytes_ReturnsFalse_GivenSmallSpan()
|
||||||
|
{
|
||||||
|
const sbyte value = 0x0F;
|
||||||
|
Span<byte> buffer = stackalloc byte[0];
|
||||||
|
Assert.IsFalse(value.TryWriteBytes(buffer));
|
||||||
|
}
|
||||||
|
}
|
66
X10D.Tests/src/IO/SingleTests.cs
Normal file
66
X10D.Tests/src/IO/SingleTests.cs
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.IO;
|
||||||
|
|
||||||
|
namespace X10D.Tests.IO;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class SingleTests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void GetBytes_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());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void GetBytes_ReturnsCorrectValue_WithEndianness()
|
||||||
|
{
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void TryWriteBytes_ReturnsTrue_FillsSpanCorrectly_GivenLargeEnoughSpan()
|
||||||
|
{
|
||||||
|
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.IsTrue(value.TryWriteBytes(buffer));
|
||||||
|
CollectionAssert.AreEqual(bytes, buffer.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void TryWriteBytes_ReturnsTrue_FillsSpanCorrectly_GivenLargeEnoughSpan_WithEndianness()
|
||||||
|
{
|
||||||
|
const float value = 42.5f;
|
||||||
|
byte[] littleEndian = {0, 0, 0x2A, 0x42};
|
||||||
|
byte[] bigEndian = {0x42, 0x2A, 0, 0};
|
||||||
|
|
||||||
|
Span<byte> buffer = stackalloc byte[4];
|
||||||
|
|
||||||
|
Assert.IsTrue(value.TryWriteBytes(buffer, Endianness.LittleEndian));
|
||||||
|
CollectionAssert.AreEqual(littleEndian, buffer.ToArray());
|
||||||
|
|
||||||
|
Assert.IsTrue(value.TryWriteBytes(buffer, Endianness.BigEndian));
|
||||||
|
CollectionAssert.AreEqual(bigEndian, buffer.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void TryWriteBytes_ReturnsFalse_GivenSmallSpan()
|
||||||
|
{
|
||||||
|
const float value = 42.5f;
|
||||||
|
Span<byte> buffer = stackalloc byte[0];
|
||||||
|
Assert.IsFalse(value.TryWriteBytes(buffer));
|
||||||
|
}
|
||||||
|
}
|
526
X10D.Tests/src/IO/StreamTests.cs
Normal file
526
X10D.Tests/src/IO/StreamTests.cs
Normal file
@ -0,0 +1,526 @@
|
|||||||
|
using System.Diagnostics;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.IO;
|
||||||
|
|
||||||
|
namespace X10D.Tests.IO;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class StreamTests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void GetHashSha1ShouldBeCorrect()
|
||||||
|
{
|
||||||
|
// SHA-1
|
||||||
|
byte[] expectedHash =
|
||||||
|
{
|
||||||
|
0x0A, 0x4D, 0x55, 0xA8, 0xD7, 0x78, 0xE5, 0x02, 0x2F, 0xAB, 0x70, 0x19, 0x77, 0xC5, 0xD8, 0x40, 0xBB, 0xC4, 0x86,
|
||||||
|
0xD0
|
||||||
|
};
|
||||||
|
|
||||||
|
using var stream = new MemoryStream();
|
||||||
|
stream.Write(Encoding.UTF8.GetBytes("Hello World"));
|
||||||
|
stream.Position = 0;
|
||||||
|
|
||||||
|
byte[] hash = stream.GetHash<SHA1>();
|
||||||
|
Trace.WriteLine($"Hash: {BitConverter.ToString(hash)}");
|
||||||
|
Trace.WriteLine($"Expected: {BitConverter.ToString(expectedHash)}");
|
||||||
|
CollectionAssert.AreEqual(expectedHash, hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void GetHashNullShouldThrow()
|
||||||
|
{
|
||||||
|
// any HashAlgorithm will do, but SHA1 is used above. so to remain consistent, we use it here
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => ((Stream?)null)!.GetHash<SHA1>());
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => ((Stream?)null)!.TryWriteHash<SHA1>(Span<byte>.Empty, out _));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void TryWriteHashSha1_ShouldBeCorrect()
|
||||||
|
{
|
||||||
|
// SHA-1
|
||||||
|
byte[] expectedHash =
|
||||||
|
{
|
||||||
|
0x0A, 0x4D, 0x55, 0xA8, 0xD7, 0x78, 0xE5, 0x02, 0x2F, 0xAB, 0x70, 0x19, 0x77, 0xC5, 0xD8, 0x40, 0xBB, 0xC4, 0x86,
|
||||||
|
0xD0
|
||||||
|
};
|
||||||
|
|
||||||
|
using var stream = new MemoryStream();
|
||||||
|
stream.Write(Encoding.UTF8.GetBytes("Hello World"));
|
||||||
|
stream.Position = 0;
|
||||||
|
|
||||||
|
Span<byte> hash = stackalloc byte[20];
|
||||||
|
stream.TryWriteHash<SHA1>(hash, out int bytesWritten);
|
||||||
|
Assert.AreEqual(expectedHash.Length, bytesWritten);
|
||||||
|
CollectionAssert.AreEqual(expectedHash, hash.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void GetHash_TryWriteHash_ShouldThrow_GivenNonReadableStream()
|
||||||
|
{
|
||||||
|
Assert.ThrowsException<IOException>(() =>
|
||||||
|
{
|
||||||
|
using var stream = new DummyStream();
|
||||||
|
stream.GetHash<SHA1>();
|
||||||
|
});
|
||||||
|
|
||||||
|
Assert.ThrowsException<IOException>(() =>
|
||||||
|
{
|
||||||
|
using var stream = new DummyStream();
|
||||||
|
stream.TryWriteHash<SHA1>(Span<byte>.Empty, out _);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void LargeStreamShouldThrow()
|
||||||
|
{
|
||||||
|
Assert.ThrowsException<ArgumentException>(() =>
|
||||||
|
{
|
||||||
|
using var stream = new DummyStream(true);
|
||||||
|
stream.TryWriteHash<SHA1>(Span<byte>.Empty, out _);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NullCreateMethodShouldThrow()
|
||||||
|
{
|
||||||
|
Assert.ThrowsException<TypeInitializationException>(() => Stream.Null.GetHash<HashAlgorithmTestClass>());
|
||||||
|
Assert.ThrowsException<TypeInitializationException>(() =>
|
||||||
|
Stream.Null.TryWriteHash<HashAlgorithmTestClass>(Span<byte>.Empty, out _));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NoCreateMethodShouldThrow()
|
||||||
|
{
|
||||||
|
Assert.ThrowsException<TypeInitializationException>(() => Stream.Null.GetHash<HashAlgorithmTestClassNoCreateMethod>());
|
||||||
|
Assert.ThrowsException<TypeInitializationException>(() =>
|
||||||
|
Stream.Null.TryWriteHash<HashAlgorithmTestClassNoCreateMethod>(Span<byte>.Empty, out _));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Write_ShouldThrow_GivenUndefinedEndianness()
|
||||||
|
{
|
||||||
|
Assert.ThrowsException<ArgumentOutOfRangeException>(() =>
|
||||||
|
{
|
||||||
|
using var stream = new MemoryStream();
|
||||||
|
return stream.Write(0.0f, (Endianness)(-1));
|
||||||
|
});
|
||||||
|
Assert.ThrowsException<ArgumentOutOfRangeException>(() =>
|
||||||
|
{
|
||||||
|
using var stream = new MemoryStream();
|
||||||
|
return stream.Write(0.0, (Endianness)(-1));
|
||||||
|
});
|
||||||
|
Assert.ThrowsException<ArgumentOutOfRangeException>(() =>
|
||||||
|
{
|
||||||
|
using var stream = new MemoryStream();
|
||||||
|
return stream.Write(0.0m, (Endianness)(-1));
|
||||||
|
});
|
||||||
|
|
||||||
|
Assert.ThrowsException<ArgumentOutOfRangeException>(() =>
|
||||||
|
{
|
||||||
|
using var stream = new MemoryStream();
|
||||||
|
return stream.Write((short)0, (Endianness)(-1));
|
||||||
|
});
|
||||||
|
Assert.ThrowsException<ArgumentOutOfRangeException>(() =>
|
||||||
|
{
|
||||||
|
using var stream = new MemoryStream();
|
||||||
|
return stream.Write(0, (Endianness)(-1));
|
||||||
|
});
|
||||||
|
Assert.ThrowsException<ArgumentOutOfRangeException>(() =>
|
||||||
|
{
|
||||||
|
using var stream = new MemoryStream();
|
||||||
|
return stream.Write(0L, (Endianness)(-1));
|
||||||
|
});
|
||||||
|
|
||||||
|
Assert.ThrowsException<ArgumentOutOfRangeException>(() =>
|
||||||
|
{
|
||||||
|
using var stream = new MemoryStream();
|
||||||
|
return stream.Write((ushort)0, (Endianness)(-1));
|
||||||
|
});
|
||||||
|
Assert.ThrowsException<ArgumentOutOfRangeException>(() =>
|
||||||
|
{
|
||||||
|
using var stream = new MemoryStream();
|
||||||
|
return stream.Write(0U, (Endianness)(-1));
|
||||||
|
});
|
||||||
|
Assert.ThrowsException<ArgumentOutOfRangeException>(() =>
|
||||||
|
{
|
||||||
|
using var stream = new MemoryStream();
|
||||||
|
return stream.Write(0UL, (Endianness)(-1));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Read_ShouldThrow_GivenNullStream()
|
||||||
|
{
|
||||||
|
Stream? stream = null;
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => stream!.ReadSingle());
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => stream!.ReadDouble());
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => stream!.ReadDecimal());
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => stream!.ReadInt16());
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => stream!.ReadInt32());
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => stream!.ReadInt64());
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => stream!.ReadUInt16());
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => stream!.ReadUInt32());
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => stream!.ReadUInt64());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Write_ShouldThrow_GivenNullStream()
|
||||||
|
{
|
||||||
|
Stream? stream = null;
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => stream!.Write(0.0f, Endianness.LittleEndian));
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => stream!.Write(0.0, Endianness.LittleEndian));
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => stream!.Write(0.0m, Endianness.LittleEndian));
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => stream!.Write((short)0));
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => stream!.Write(0));
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => stream!.Write(0L));
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => stream!.Write((ushort)0));
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => stream!.Write(0U));
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => stream!.Write(0UL));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Read_ShouldThrow_GivenUndefinedEndianness()
|
||||||
|
{
|
||||||
|
Assert.ThrowsException<ArgumentOutOfRangeException>(() =>
|
||||||
|
{
|
||||||
|
using var stream = new MemoryStream();
|
||||||
|
return stream.ReadSingle((Endianness)(-1));
|
||||||
|
});
|
||||||
|
Assert.ThrowsException<ArgumentOutOfRangeException>(() =>
|
||||||
|
{
|
||||||
|
using var stream = new MemoryStream();
|
||||||
|
return stream.ReadDouble((Endianness)(-1));
|
||||||
|
});
|
||||||
|
Assert.ThrowsException<ArgumentOutOfRangeException>(() =>
|
||||||
|
{
|
||||||
|
using var stream = new MemoryStream();
|
||||||
|
return stream.ReadDecimal((Endianness)(-1));
|
||||||
|
});
|
||||||
|
|
||||||
|
Assert.ThrowsException<ArgumentOutOfRangeException>(() =>
|
||||||
|
{
|
||||||
|
using var stream = new MemoryStream();
|
||||||
|
return stream.ReadInt16((Endianness)(-1));
|
||||||
|
});
|
||||||
|
Assert.ThrowsException<ArgumentOutOfRangeException>(() =>
|
||||||
|
{
|
||||||
|
using var stream = new MemoryStream();
|
||||||
|
return stream.ReadInt32((Endianness)(-1));
|
||||||
|
});
|
||||||
|
Assert.ThrowsException<ArgumentOutOfRangeException>(() =>
|
||||||
|
{
|
||||||
|
using var stream = new MemoryStream();
|
||||||
|
return stream.ReadInt64((Endianness)(-1));
|
||||||
|
});
|
||||||
|
|
||||||
|
Assert.ThrowsException<ArgumentOutOfRangeException>(() =>
|
||||||
|
{
|
||||||
|
using var stream = new MemoryStream();
|
||||||
|
return stream.ReadUInt16((Endianness)(-1));
|
||||||
|
});
|
||||||
|
Assert.ThrowsException<ArgumentOutOfRangeException>(() =>
|
||||||
|
{
|
||||||
|
using var stream = new MemoryStream();
|
||||||
|
return stream.ReadUInt32((Endianness)(-1));
|
||||||
|
});
|
||||||
|
Assert.ThrowsException<ArgumentOutOfRangeException>(() =>
|
||||||
|
{
|
||||||
|
using var stream = new MemoryStream();
|
||||||
|
return stream.ReadUInt64((Endianness)(-1));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ReadDouble_WriteDouble_ShouldBeSymmetric()
|
||||||
|
{
|
||||||
|
using var stream = new MemoryStream();
|
||||||
|
stream.Write(420.0, BitConverter.IsLittleEndian ? Endianness.LittleEndian : Endianness.BigEndian);
|
||||||
|
|
||||||
|
stream.Position = 0;
|
||||||
|
Assert.AreEqual(420.0, stream.ReadDouble(), 1e-6);
|
||||||
|
|
||||||
|
stream.Position = 0;
|
||||||
|
stream.Write(420.0, Endianness.LittleEndian);
|
||||||
|
|
||||||
|
stream.Position = 0;
|
||||||
|
Assert.AreEqual(420.0, stream.ReadDouble(Endianness.LittleEndian), 1e-6);
|
||||||
|
|
||||||
|
stream.Position = 0;
|
||||||
|
stream.Write(420.0, Endianness.BigEndian);
|
||||||
|
|
||||||
|
stream.Position = 0;
|
||||||
|
Assert.AreEqual(420.0, stream.ReadDouble(Endianness.BigEndian), 1e-6);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ReadDecimal_WriteSingle_ShouldBeSymmetric()
|
||||||
|
{
|
||||||
|
using var stream = new MemoryStream();
|
||||||
|
stream.Write(420.0m, BitConverter.IsLittleEndian ? Endianness.LittleEndian : Endianness.BigEndian);
|
||||||
|
|
||||||
|
stream.Position = 0;
|
||||||
|
Assert.AreEqual(420.0m, stream.ReadDecimal());
|
||||||
|
|
||||||
|
stream.Position = 0;
|
||||||
|
stream.Write(420.0m, Endianness.LittleEndian);
|
||||||
|
|
||||||
|
stream.Position = 0;
|
||||||
|
Assert.AreEqual(420.0m, stream.ReadDecimal(Endianness.LittleEndian));
|
||||||
|
|
||||||
|
stream.Position = 0;
|
||||||
|
stream.Write(420.0m, Endianness.BigEndian);
|
||||||
|
|
||||||
|
stream.Position = 0;
|
||||||
|
Assert.AreEqual(420.0m, stream.ReadDecimal(Endianness.BigEndian));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ReadSingle_WriteSingle_ShouldBeSymmetric()
|
||||||
|
{
|
||||||
|
using var stream = new MemoryStream();
|
||||||
|
stream.Write(420.0f, BitConverter.IsLittleEndian ? Endianness.LittleEndian : Endianness.BigEndian);
|
||||||
|
|
||||||
|
stream.Position = 0;
|
||||||
|
Assert.AreEqual(420.0f, stream.ReadSingle(), 1e-6f);
|
||||||
|
|
||||||
|
stream.Position = 0;
|
||||||
|
stream.Write(420.0f, Endianness.LittleEndian);
|
||||||
|
|
||||||
|
stream.Position = 0;
|
||||||
|
Assert.AreEqual(420.0f, stream.ReadSingle(Endianness.LittleEndian), 1e-6f);
|
||||||
|
|
||||||
|
stream.Position = 0;
|
||||||
|
stream.Write(420.0f, Endianness.BigEndian);
|
||||||
|
|
||||||
|
stream.Position = 0;
|
||||||
|
Assert.AreEqual(420.0f, stream.ReadSingle(Endianness.BigEndian), 1e-6f);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ReadInt16_WriteInt16_ShouldBeSymmetric()
|
||||||
|
{
|
||||||
|
using var stream = new MemoryStream();
|
||||||
|
stream.Write((short)420);
|
||||||
|
|
||||||
|
stream.Position = 0;
|
||||||
|
Assert.AreEqual(420, stream.ReadInt16());
|
||||||
|
|
||||||
|
stream.Position = 0;
|
||||||
|
stream.Write((short)420, Endianness.LittleEndian);
|
||||||
|
|
||||||
|
stream.Position = 0;
|
||||||
|
Assert.AreEqual(420, stream.ReadInt16(Endianness.LittleEndian));
|
||||||
|
|
||||||
|
stream.Position = 0;
|
||||||
|
stream.Write((short)420, Endianness.BigEndian);
|
||||||
|
|
||||||
|
stream.Position = 0;
|
||||||
|
Assert.AreEqual(420, stream.ReadInt16(Endianness.BigEndian));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ReadInt32_WriteInt32_ShouldBeSymmetric()
|
||||||
|
{
|
||||||
|
using var stream = new MemoryStream();
|
||||||
|
stream.Write(420);
|
||||||
|
|
||||||
|
stream.Position = 0;
|
||||||
|
Assert.AreEqual(420, stream.ReadInt32());
|
||||||
|
|
||||||
|
stream.Position = 0;
|
||||||
|
stream.Write(420, Endianness.LittleEndian);
|
||||||
|
|
||||||
|
stream.Position = 0;
|
||||||
|
Assert.AreEqual(420, stream.ReadInt32(Endianness.LittleEndian));
|
||||||
|
|
||||||
|
stream.Position = 0;
|
||||||
|
stream.Write(420, Endianness.BigEndian);
|
||||||
|
|
||||||
|
stream.Position = 0;
|
||||||
|
Assert.AreEqual(420, stream.ReadInt32(Endianness.BigEndian));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ReadInt64_WriteInt64_ShouldBeSymmetric()
|
||||||
|
{
|
||||||
|
using var stream = new MemoryStream();
|
||||||
|
stream.Write(420L);
|
||||||
|
|
||||||
|
stream.Position = 0;
|
||||||
|
Assert.AreEqual(420L, stream.ReadInt64());
|
||||||
|
|
||||||
|
stream.Position = 0;
|
||||||
|
stream.Write(420L, Endianness.LittleEndian);
|
||||||
|
|
||||||
|
stream.Position = 0;
|
||||||
|
Assert.AreEqual(420L, stream.ReadInt64(Endianness.LittleEndian));
|
||||||
|
|
||||||
|
stream.Position = 0;
|
||||||
|
stream.Write(420L, Endianness.BigEndian);
|
||||||
|
|
||||||
|
stream.Position = 0;
|
||||||
|
Assert.AreEqual(420L, stream.ReadInt64(Endianness.BigEndian));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
[CLSCompliant(false)]
|
||||||
|
public void ReadUInt16_WriteUInt16_ShouldBeSymmetric()
|
||||||
|
{
|
||||||
|
using var stream = new MemoryStream();
|
||||||
|
stream.Write((ushort)420);
|
||||||
|
|
||||||
|
stream.Position = 0;
|
||||||
|
Assert.AreEqual((ushort)420, stream.ReadUInt16());
|
||||||
|
|
||||||
|
stream.Position = 0;
|
||||||
|
stream.Write((ushort)420, Endianness.LittleEndian);
|
||||||
|
|
||||||
|
stream.Position = 0;
|
||||||
|
Assert.AreEqual((ushort)420, stream.ReadUInt16(Endianness.LittleEndian));
|
||||||
|
|
||||||
|
stream.Position = 0;
|
||||||
|
stream.Write((ushort)420, Endianness.BigEndian);
|
||||||
|
|
||||||
|
stream.Position = 0;
|
||||||
|
Assert.AreEqual((ushort)420, stream.ReadUInt16(Endianness.BigEndian));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
[CLSCompliant(false)]
|
||||||
|
public void ReadUInt32_WriteUInt32_ShouldBeSymmetric()
|
||||||
|
{
|
||||||
|
using var stream = new MemoryStream();
|
||||||
|
stream.Write(420U);
|
||||||
|
|
||||||
|
stream.Position = 0;
|
||||||
|
Assert.AreEqual(420U, stream.ReadUInt32());
|
||||||
|
|
||||||
|
stream.Position = 0;
|
||||||
|
stream.Write(420U, Endianness.LittleEndian);
|
||||||
|
|
||||||
|
stream.Position = 0;
|
||||||
|
Assert.AreEqual(420U, stream.ReadUInt32(Endianness.LittleEndian));
|
||||||
|
|
||||||
|
stream.Position = 0;
|
||||||
|
stream.Write(420U, Endianness.BigEndian);
|
||||||
|
|
||||||
|
stream.Position = 0;
|
||||||
|
Assert.AreEqual(420U, stream.ReadUInt32(Endianness.BigEndian));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
[CLSCompliant(false)]
|
||||||
|
public void ReadUInt64_WriteUInt64_ShouldBeSymmetric()
|
||||||
|
{
|
||||||
|
using var stream = new MemoryStream();
|
||||||
|
stream.Write(420UL);
|
||||||
|
|
||||||
|
stream.Position = 0;
|
||||||
|
Assert.AreEqual(420UL, stream.ReadUInt64());
|
||||||
|
|
||||||
|
stream.Position = 0;
|
||||||
|
stream.Write(420UL, Endianness.LittleEndian);
|
||||||
|
|
||||||
|
stream.Position = 0;
|
||||||
|
Assert.AreEqual(420UL, stream.ReadUInt64(Endianness.LittleEndian));
|
||||||
|
|
||||||
|
stream.Position = 0;
|
||||||
|
stream.Write(420UL, Endianness.BigEndian);
|
||||||
|
|
||||||
|
stream.Position = 0;
|
||||||
|
Assert.AreEqual(420UL, stream.ReadUInt64(Endianness.BigEndian));
|
||||||
|
}
|
||||||
|
|
||||||
|
private class DummyStream : Stream
|
||||||
|
{
|
||||||
|
public DummyStream(bool readable = false)
|
||||||
|
{
|
||||||
|
CanRead = readable;
|
||||||
|
CanSeek = readable;
|
||||||
|
CanWrite = readable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Flush()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int Read(byte[] buffer, int offset, int count)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override long Seek(long offset, SeekOrigin origin)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SetLength(long value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Write(byte[] buffer, int offset, int count)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool CanRead { get; }
|
||||||
|
|
||||||
|
public override bool CanSeek { get; }
|
||||||
|
|
||||||
|
public override bool CanWrite { get; }
|
||||||
|
|
||||||
|
public override long Length
|
||||||
|
{
|
||||||
|
get => long.MaxValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override long Position
|
||||||
|
{
|
||||||
|
get => 0;
|
||||||
|
set { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class HashAlgorithmTestClass : HashAlgorithm
|
||||||
|
{
|
||||||
|
public static new HashAlgorithmTestClass? Create()
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void HashCore(byte[] array, int ibStart, int cbSize)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override byte[] HashFinal()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class HashAlgorithmTestClassNoCreateMethod : HashAlgorithm
|
||||||
|
{
|
||||||
|
protected override void HashCore(byte[] array, int ibStart, int cbSize)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override byte[] HashFinal()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
63
X10D.Tests/src/IO/UInt16Tests.cs
Normal file
63
X10D.Tests/src/IO/UInt16Tests.cs
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.IO;
|
||||||
|
|
||||||
|
namespace X10D.Tests.IO;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
[CLSCompliant(false)]
|
||||||
|
public class UInt16Tests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void GetBytes_ReturnsCorrectValue()
|
||||||
|
{
|
||||||
|
const ushort value = 0x0F;
|
||||||
|
byte[] bytes = BitConverter.IsLittleEndian ? new byte[] {0x0F, 0} : new byte[] {0, 0x0F};
|
||||||
|
CollectionAssert.AreEqual(bytes, value.GetBytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void GetBytes_ReturnsCorrectValue_WithEndianness()
|
||||||
|
{
|
||||||
|
const ushort value = 0x0F;
|
||||||
|
byte[] littleEndian = {0x0F, 0};
|
||||||
|
byte[] bigEndian = {0, 0x0F};
|
||||||
|
|
||||||
|
CollectionAssert.AreEqual(littleEndian, value.GetBytes(Endianness.LittleEndian));
|
||||||
|
CollectionAssert.AreEqual(bigEndian, value.GetBytes(Endianness.BigEndian));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void TryWriteBytes_ReturnsTrue_FillsSpanCorrectly_GivenLargeEnoughSpan()
|
||||||
|
{
|
||||||
|
const ushort value = 0x0F;
|
||||||
|
byte[] bytes = BitConverter.IsLittleEndian ? new byte[] {0x0F, 0} : new byte[] {0, 0x0F};
|
||||||
|
|
||||||
|
Span<byte> buffer = stackalloc byte[2];
|
||||||
|
Assert.IsTrue(value.TryWriteBytes(buffer));
|
||||||
|
CollectionAssert.AreEqual(bytes, buffer.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void TryWriteBytes_ReturnsTrue_FillsSpanCorrectly_GivenLargeEnoughSpan_WithEndianness()
|
||||||
|
{
|
||||||
|
const ushort value = 0x0F;
|
||||||
|
byte[] littleEndian = {0x0F, 0};
|
||||||
|
byte[] bigEndian = {0, 0x0F};
|
||||||
|
|
||||||
|
Span<byte> buffer = stackalloc byte[2];
|
||||||
|
|
||||||
|
Assert.IsTrue(value.TryWriteBytes(buffer, Endianness.LittleEndian));
|
||||||
|
CollectionAssert.AreEqual(littleEndian, buffer.ToArray());
|
||||||
|
|
||||||
|
Assert.IsTrue(value.TryWriteBytes(buffer, Endianness.BigEndian));
|
||||||
|
CollectionAssert.AreEqual(bigEndian, buffer.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void TryWriteBytes_ReturnsFalse_GivenSmallSpan()
|
||||||
|
{
|
||||||
|
const ushort value = 0x0F;
|
||||||
|
Span<byte> buffer = stackalloc byte[0];
|
||||||
|
Assert.IsFalse(value.TryWriteBytes(buffer));
|
||||||
|
}
|
||||||
|
}
|
63
X10D.Tests/src/IO/UInt32Tests.cs
Normal file
63
X10D.Tests/src/IO/UInt32Tests.cs
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.IO;
|
||||||
|
|
||||||
|
namespace X10D.Tests.IO;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
[CLSCompliant(false)]
|
||||||
|
public class UInt32Tests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void GetBytes_ReturnsCorrectValue()
|
||||||
|
{
|
||||||
|
const uint value = 0x0F;
|
||||||
|
byte[] bytes = BitConverter.IsLittleEndian ? new byte[] {0x0F, 0, 0, 0} : new byte[] {0, 0, 0, 0x0F};
|
||||||
|
CollectionAssert.AreEqual(bytes, value.GetBytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void GetBytes_ReturnsCorrectValue_WithEndianness()
|
||||||
|
{
|
||||||
|
const uint 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));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void TryWriteBytes_ReturnsTrue_FillsSpanCorrectly_GivenLargeEnoughSpan()
|
||||||
|
{
|
||||||
|
const uint 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.IsTrue(value.TryWriteBytes(buffer));
|
||||||
|
CollectionAssert.AreEqual(bytes, buffer.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void TryWriteBytes_ReturnsTrue_FillsSpanCorrectly_GivenLargeEnoughSpan_WithEndianness()
|
||||||
|
{
|
||||||
|
const uint value = 0x0F;
|
||||||
|
byte[] littleEndian = {0x0F, 0, 0, 0};
|
||||||
|
byte[] bigEndian = {0, 0, 0, 0x0F};
|
||||||
|
|
||||||
|
Span<byte> buffer = stackalloc byte[4];
|
||||||
|
|
||||||
|
Assert.IsTrue(value.TryWriteBytes(buffer, Endianness.LittleEndian));
|
||||||
|
CollectionAssert.AreEqual(littleEndian, buffer.ToArray());
|
||||||
|
|
||||||
|
Assert.IsTrue(value.TryWriteBytes(buffer, Endianness.BigEndian));
|
||||||
|
CollectionAssert.AreEqual(bigEndian, buffer.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void TryWriteBytes_ReturnsFalse_GivenSmallSpan()
|
||||||
|
{
|
||||||
|
const uint value = 0x0F;
|
||||||
|
Span<byte> buffer = stackalloc byte[0];
|
||||||
|
Assert.IsFalse(value.TryWriteBytes(buffer));
|
||||||
|
}
|
||||||
|
}
|
67
X10D.Tests/src/IO/UInt64Tests.cs
Normal file
67
X10D.Tests/src/IO/UInt64Tests.cs
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.IO;
|
||||||
|
|
||||||
|
namespace X10D.Tests.IO;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
[CLSCompliant(false)]
|
||||||
|
public class UInt64Tests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void GetBytes_ReturnsCorrectValue()
|
||||||
|
{
|
||||||
|
const ulong 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());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void GetBytes_ReturnsCorrectValue_WithEndianness()
|
||||||
|
{
|
||||||
|
const ulong 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));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void TryWriteBytes_ReturnsTrue_FillsSpanCorrectly_GivenLargeEnoughSpan()
|
||||||
|
{
|
||||||
|
const ulong 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.IsTrue(value.TryWriteBytes(buffer));
|
||||||
|
CollectionAssert.AreEqual(bytes, buffer.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void TryWriteBytes_ReturnsTrue_FillsSpanCorrectly_GivenLargeEnoughSpan_WithEndianness()
|
||||||
|
{
|
||||||
|
const ulong 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.IsTrue(value.TryWriteBytes(buffer, Endianness.LittleEndian));
|
||||||
|
CollectionAssert.AreEqual(littleEndian, buffer.ToArray());
|
||||||
|
|
||||||
|
Assert.IsTrue(value.TryWriteBytes(buffer, Endianness.BigEndian));
|
||||||
|
CollectionAssert.AreEqual(bigEndian, buffer.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void TryWriteBytes_ReturnsFalse_GivenSmallSpan()
|
||||||
|
{
|
||||||
|
const ulong value = 0x0F;
|
||||||
|
Span<byte> buffer = stackalloc byte[0];
|
||||||
|
Assert.IsFalse(value.TryWriteBytes(buffer));
|
||||||
|
}
|
||||||
|
}
|
96
X10D.Tests/src/Linq/ByteTests.cs
Normal file
96
X10D.Tests/src/Linq/ByteTests.cs
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Linq;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Linq;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class ByteTests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void ProductShouldBeCorrect()
|
||||||
|
{
|
||||||
|
byte Cast(int i) => (byte)i;
|
||||||
|
|
||||||
|
Assert.AreEqual(0, Enumerable.Range(0, 10).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(1, Enumerable.Range(1, 1).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(2, Enumerable.Range(1, 2).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(6, Enumerable.Range(1, 3).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(24, Enumerable.Range(1, 4).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(120, Enumerable.Range(1, 5).Select(Cast).Product());
|
||||||
|
|
||||||
|
// 6! will overflow for byte
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ProductOfDoublesShouldBeCorrect()
|
||||||
|
{
|
||||||
|
byte Double(int i) => (byte)(i * 2);
|
||||||
|
|
||||||
|
Assert.AreEqual(0, Enumerable.Range(0, 10).Product(Double));
|
||||||
|
Assert.AreEqual(2, Enumerable.Range(1, 1).Product(Double));
|
||||||
|
Assert.AreEqual(8, Enumerable.Range(1, 2).Product(Double));
|
||||||
|
Assert.AreEqual(48, Enumerable.Range(1, 3).Product(Double));
|
||||||
|
|
||||||
|
// Π_(i=1)^n (2i) will overflow at i=4 for byte
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void RangeTo_Byte_ShouldYieldCorrectValues()
|
||||||
|
{
|
||||||
|
const byte start = 1;
|
||||||
|
const byte end = 10;
|
||||||
|
|
||||||
|
byte current = 1;
|
||||||
|
foreach (byte value in start.RangeTo(end))
|
||||||
|
{
|
||||||
|
Assert.AreEqual(current++, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.AreEqual(current, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void RangeTo_Int16_ShouldYieldCorrectValues()
|
||||||
|
{
|
||||||
|
const byte start = 1;
|
||||||
|
const short end = 10;
|
||||||
|
|
||||||
|
short current = 1;
|
||||||
|
foreach (short value in start.RangeTo(end))
|
||||||
|
{
|
||||||
|
Assert.AreEqual(current++, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.AreEqual(current, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void RangeTo_Int32_ShouldYieldCorrectValues()
|
||||||
|
{
|
||||||
|
const byte start = 1;
|
||||||
|
const int end = 10;
|
||||||
|
|
||||||
|
int current = 1;
|
||||||
|
foreach (int value in start.RangeTo(end))
|
||||||
|
{
|
||||||
|
Assert.AreEqual(current++, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.AreEqual(current, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void RangeTo_Int64_ShouldYieldCorrectValues()
|
||||||
|
{
|
||||||
|
const byte start = 1;
|
||||||
|
const long end = 10;
|
||||||
|
|
||||||
|
long current = 1;
|
||||||
|
foreach (long value in start.RangeTo(end))
|
||||||
|
{
|
||||||
|
Assert.AreEqual(current++, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.AreEqual(current, end);
|
||||||
|
}
|
||||||
|
}
|
44
X10D.Tests/src/Linq/DecimalTests.cs
Normal file
44
X10D.Tests/src/Linq/DecimalTests.cs
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Linq;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Linq;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class DecimalTests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void ProductShouldBeCorrect()
|
||||||
|
{
|
||||||
|
decimal Cast(int i) => i;
|
||||||
|
|
||||||
|
Assert.AreEqual(0m, Enumerable.Range(0, 10).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(1m, Enumerable.Range(1, 1).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(2m, Enumerable.Range(1, 2).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(6m, Enumerable.Range(1, 3).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(24m, Enumerable.Range(1, 4).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(120m, Enumerable.Range(1, 5).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(720m, Enumerable.Range(1, 6).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(5040m, Enumerable.Range(1, 7).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(40320m, Enumerable.Range(1, 8).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(362880m, Enumerable.Range(1, 9).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(3628800m, Enumerable.Range(1, 10).Select(Cast).Product());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ProductOfDoublesShouldBeCorrect()
|
||||||
|
{
|
||||||
|
decimal Double(int i) => i * 2m;
|
||||||
|
|
||||||
|
Assert.AreEqual(0m, Enumerable.Range(0, 10).Product(Double));
|
||||||
|
Assert.AreEqual(2m, Enumerable.Range(1, 1).Product(Double));
|
||||||
|
Assert.AreEqual(8m, Enumerable.Range(1, 2).Product(Double));
|
||||||
|
Assert.AreEqual(48m, Enumerable.Range(1, 3).Product(Double));
|
||||||
|
Assert.AreEqual(384m, Enumerable.Range(1, 4).Product(Double));
|
||||||
|
Assert.AreEqual(3840m, Enumerable.Range(1, 5).Product(Double));
|
||||||
|
Assert.AreEqual(46080m, Enumerable.Range(1, 6).Product(Double));
|
||||||
|
Assert.AreEqual(645120m, Enumerable.Range(1, 7).Product(Double));
|
||||||
|
Assert.AreEqual(10321920m, Enumerable.Range(1, 8).Product(Double));
|
||||||
|
Assert.AreEqual(185794560m, Enumerable.Range(1, 9).Product(Double));
|
||||||
|
Assert.AreEqual(3715891200m, Enumerable.Range(1, 10).Product(Double));
|
||||||
|
}
|
||||||
|
}
|
44
X10D.Tests/src/Linq/DoubleTests.cs
Normal file
44
X10D.Tests/src/Linq/DoubleTests.cs
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Linq;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Linq;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class DoubleTests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void ProductShouldBeCorrect()
|
||||||
|
{
|
||||||
|
double Cast(int i) => i;
|
||||||
|
|
||||||
|
Assert.AreEqual(0.0, Enumerable.Range(0, 10).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(1.0, Enumerable.Range(1, 1).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(2.0, Enumerable.Range(1, 2).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(6.0, Enumerable.Range(1, 3).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(24.0, Enumerable.Range(1, 4).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(120.0, Enumerable.Range(1, 5).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(720.0, Enumerable.Range(1, 6).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(5040.0, Enumerable.Range(1, 7).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(40320.0, Enumerable.Range(1, 8).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(362880.0, Enumerable.Range(1, 9).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(3628800.0, Enumerable.Range(1, 10).Select(Cast).Product());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ProductOfDoublesShouldBeCorrect()
|
||||||
|
{
|
||||||
|
double Double(int i) => i * 2.0;
|
||||||
|
|
||||||
|
Assert.AreEqual(0.0, Enumerable.Range(0, 10).Product(Double));
|
||||||
|
Assert.AreEqual(2.0, Enumerable.Range(1, 1).Product(Double));
|
||||||
|
Assert.AreEqual(8.0, Enumerable.Range(1, 2).Product(Double));
|
||||||
|
Assert.AreEqual(48.0, Enumerable.Range(1, 3).Product(Double));
|
||||||
|
Assert.AreEqual(384.0, Enumerable.Range(1, 4).Product(Double));
|
||||||
|
Assert.AreEqual(3840.0, Enumerable.Range(1, 5).Product(Double));
|
||||||
|
Assert.AreEqual(46080.0, Enumerable.Range(1, 6).Product(Double));
|
||||||
|
Assert.AreEqual(645120.0, Enumerable.Range(1, 7).Product(Double));
|
||||||
|
Assert.AreEqual(10321920.0, Enumerable.Range(1, 8).Product(Double));
|
||||||
|
Assert.AreEqual(185794560.0, Enumerable.Range(1, 9).Product(Double));
|
||||||
|
Assert.AreEqual(3715891200.0, Enumerable.Range(1, 10).Product(Double));
|
||||||
|
}
|
||||||
|
}
|
85
X10D.Tests/src/Linq/Int16Tests.cs
Normal file
85
X10D.Tests/src/Linq/Int16Tests.cs
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Linq;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Linq;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class Int16Tests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void ProductShouldBeCorrect()
|
||||||
|
{
|
||||||
|
short Cast(int i) => (short)i;
|
||||||
|
|
||||||
|
Assert.AreEqual(0, Enumerable.Range(0, 10).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(1, Enumerable.Range(1, 1).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(2, Enumerable.Range(1, 2).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(6, Enumerable.Range(1, 3).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(24, Enumerable.Range(1, 4).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(120, Enumerable.Range(1, 5).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(720, Enumerable.Range(1, 6).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(5040, Enumerable.Range(1, 7).Select(Cast).Product());
|
||||||
|
|
||||||
|
// 8! will overflow for short
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ProductOfDoublesShouldBeCorrect()
|
||||||
|
{
|
||||||
|
short Double(int i) => (short)(i * 2);
|
||||||
|
|
||||||
|
Assert.AreEqual(0, Enumerable.Range(0, 10).Product(Double));
|
||||||
|
Assert.AreEqual(2, Enumerable.Range(1, 1).Product(Double));
|
||||||
|
Assert.AreEqual(8, Enumerable.Range(1, 2).Product(Double));
|
||||||
|
Assert.AreEqual(48, Enumerable.Range(1, 3).Product(Double));
|
||||||
|
Assert.AreEqual(384, Enumerable.Range(1, 4).Product(Double));
|
||||||
|
Assert.AreEqual(3840, Enumerable.Range(1, 5).Product(Double));
|
||||||
|
|
||||||
|
// Π_(i=1)^n (2i) will overflow at i=6 for short
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void RangeTo_Int16_ShouldYieldCorrectValues()
|
||||||
|
{
|
||||||
|
const short start = 1;
|
||||||
|
const short end = 10;
|
||||||
|
|
||||||
|
short current = 1;
|
||||||
|
foreach (short value in start.RangeTo(end))
|
||||||
|
{
|
||||||
|
Assert.AreEqual(current++, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.AreEqual(current, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void RangeTo_Int32_ShouldYieldCorrectValues()
|
||||||
|
{
|
||||||
|
const short start = 1;
|
||||||
|
const int end = 10;
|
||||||
|
|
||||||
|
int current = 1;
|
||||||
|
foreach (int value in start.RangeTo(end))
|
||||||
|
{
|
||||||
|
Assert.AreEqual(current++, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.AreEqual(current, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void RangeTo_Int64_ShouldYieldCorrectValues()
|
||||||
|
{
|
||||||
|
const short start = 1;
|
||||||
|
const long end = 10;
|
||||||
|
|
||||||
|
long current = 1;
|
||||||
|
foreach (long value in start.RangeTo(end))
|
||||||
|
{
|
||||||
|
Assert.AreEqual(current++, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.AreEqual(current, end);
|
||||||
|
}
|
||||||
|
}
|
73
X10D.Tests/src/Linq/Int32Tests.cs
Normal file
73
X10D.Tests/src/Linq/Int32Tests.cs
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Linq;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Linq;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class Int32Tests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void ProductShouldBeCorrect()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(0, Enumerable.Range(0, 10).Product());
|
||||||
|
Assert.AreEqual(1, Enumerable.Range(1, 1).Product());
|
||||||
|
Assert.AreEqual(2, Enumerable.Range(1, 2).Product());
|
||||||
|
Assert.AreEqual(6, Enumerable.Range(1, 3).Product());
|
||||||
|
Assert.AreEqual(24, Enumerable.Range(1, 4).Product());
|
||||||
|
Assert.AreEqual(120, Enumerable.Range(1, 5).Product());
|
||||||
|
Assert.AreEqual(720, Enumerable.Range(1, 6).Product());
|
||||||
|
Assert.AreEqual(5040, Enumerable.Range(1, 7).Product());
|
||||||
|
Assert.AreEqual(40320, Enumerable.Range(1, 8).Product());
|
||||||
|
Assert.AreEqual(362880, Enumerable.Range(1, 9).Product());
|
||||||
|
Assert.AreEqual(3628800, Enumerable.Range(1, 10).Product());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ProductOfDoublesShouldBeCorrect()
|
||||||
|
{
|
||||||
|
int Double(int i) => i * 2;
|
||||||
|
|
||||||
|
Assert.AreEqual(0, Enumerable.Range(0, 10).Product(Double));
|
||||||
|
Assert.AreEqual(2, Enumerable.Range(1, 1).Product(Double));
|
||||||
|
Assert.AreEqual(8, Enumerable.Range(1, 2).Product(Double));
|
||||||
|
Assert.AreEqual(48, Enumerable.Range(1, 3).Product(Double));
|
||||||
|
Assert.AreEqual(384, Enumerable.Range(1, 4).Product(Double));
|
||||||
|
Assert.AreEqual(3840, Enumerable.Range(1, 5).Product(Double));
|
||||||
|
Assert.AreEqual(46080, Enumerable.Range(1, 6).Product(Double));
|
||||||
|
Assert.AreEqual(645120, Enumerable.Range(1, 7).Product(Double));
|
||||||
|
Assert.AreEqual(10321920, Enumerable.Range(1, 8).Product(Double));
|
||||||
|
Assert.AreEqual(185794560, Enumerable.Range(1, 9).Product(Double));
|
||||||
|
|
||||||
|
// Π_(i=1)^n (2i) will overflow at i=10 for int
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void RangeTo_Int32_ShouldYieldCorrectValues()
|
||||||
|
{
|
||||||
|
const int start = 1;
|
||||||
|
const int end = 10;
|
||||||
|
|
||||||
|
int current = 1;
|
||||||
|
foreach (int value in start.RangeTo(end))
|
||||||
|
{
|
||||||
|
Assert.AreEqual(current++, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.AreEqual(current, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void RangeTo_Int64_ShouldYieldCorrectValues()
|
||||||
|
{
|
||||||
|
const int start = 1;
|
||||||
|
const long end = 10;
|
||||||
|
|
||||||
|
long current = 1;
|
||||||
|
foreach (long value in start.RangeTo(end))
|
||||||
|
{
|
||||||
|
Assert.AreEqual(current++, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.AreEqual(current, end);
|
||||||
|
}
|
||||||
|
}
|
59
X10D.Tests/src/Linq/Int64Tests.cs
Normal file
59
X10D.Tests/src/Linq/Int64Tests.cs
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Linq;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Linq;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class Int64Tests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void ProductShouldBeCorrect()
|
||||||
|
{
|
||||||
|
long Cast(int i) => i;
|
||||||
|
|
||||||
|
Assert.AreEqual(0, Enumerable.Range(0, 10).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(1, Enumerable.Range(1, 1).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(2, Enumerable.Range(1, 2).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(6, Enumerable.Range(1, 3).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(24, Enumerable.Range(1, 4).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(120, Enumerable.Range(1, 5).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(720, Enumerable.Range(1, 6).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(5040, Enumerable.Range(1, 7).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(40320, Enumerable.Range(1, 8).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(362880, Enumerable.Range(1, 9).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(3628800, Enumerable.Range(1, 10).Select(Cast).Product());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ProductOfDoublesShouldBeCorrect()
|
||||||
|
{
|
||||||
|
long Double(int i) => i * 2;
|
||||||
|
|
||||||
|
Assert.AreEqual(0, Enumerable.Range(0, 10).Product(Double));
|
||||||
|
Assert.AreEqual(2, Enumerable.Range(1, 1).Product(Double));
|
||||||
|
Assert.AreEqual(8, Enumerable.Range(1, 2).Product(Double));
|
||||||
|
Assert.AreEqual(48, Enumerable.Range(1, 3).Product(Double));
|
||||||
|
Assert.AreEqual(384, Enumerable.Range(1, 4).Product(Double));
|
||||||
|
Assert.AreEqual(3840, Enumerable.Range(1, 5).Product(Double));
|
||||||
|
Assert.AreEqual(46080, Enumerable.Range(1, 6).Product(Double));
|
||||||
|
Assert.AreEqual(645120, Enumerable.Range(1, 7).Product(Double));
|
||||||
|
Assert.AreEqual(10321920, Enumerable.Range(1, 8).Product(Double));
|
||||||
|
Assert.AreEqual(185794560, Enumerable.Range(1, 9).Product(Double));
|
||||||
|
Assert.AreEqual(3715891200, Enumerable.Range(1, 10).Product(Double));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void RangeTo_Int64_ShouldYieldCorrectValues()
|
||||||
|
{
|
||||||
|
const long start = 1;
|
||||||
|
const long end = 10;
|
||||||
|
|
||||||
|
long current = 1;
|
||||||
|
foreach (long value in start.RangeTo(end))
|
||||||
|
{
|
||||||
|
Assert.AreEqual(current++, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.AreEqual(current, end);
|
||||||
|
}
|
||||||
|
}
|
58
X10D.Tests/src/Linq/ReadOnlySpanTests.cs
Normal file
58
X10D.Tests/src/Linq/ReadOnlySpanTests.cs
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Linq;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Linq;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class ReadOnlySpanTests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void AllShouldReturnTrueForEmptySpan()
|
||||||
|
{
|
||||||
|
var span = new ReadOnlySpan<int>();
|
||||||
|
Assert.IsTrue(span.All(x => x > 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void AllShouldBeCorrect()
|
||||||
|
{
|
||||||
|
var span = new ReadOnlySpan<int>(new[] {2, 4, 6, 8, 10});
|
||||||
|
Assert.IsTrue(span.All(x => x % 2 == 0));
|
||||||
|
Assert.IsFalse(span.All(x => x % 2 == 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void AnyShouldReturnFalseForEmptySpan()
|
||||||
|
{
|
||||||
|
var span = new ReadOnlySpan<int>();
|
||||||
|
Assert.IsFalse(span.Any(x => x > 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void AnyShouldBeCorrect()
|
||||||
|
{
|
||||||
|
var span = new ReadOnlySpan<int>(new[] {2, 4, 6, 8, 10});
|
||||||
|
Assert.IsTrue(span.Any(x => x % 2 == 0));
|
||||||
|
Assert.IsFalse(span.Any(x => x % 2 == 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void AllNullPredicateShouldThrow()
|
||||||
|
{
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() =>
|
||||||
|
{
|
||||||
|
var span = new ReadOnlySpan<int>();
|
||||||
|
return span.All(null!);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void AnyNullPredicateShouldThrow()
|
||||||
|
{
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() =>
|
||||||
|
{
|
||||||
|
var span = new ReadOnlySpan<int>();
|
||||||
|
return span.Any(null!);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
37
X10D.Tests/src/Linq/SByteExtensions.cs
Normal file
37
X10D.Tests/src/Linq/SByteExtensions.cs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Linq;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Linq;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
[CLSCompliant(false)]
|
||||||
|
public class SByteTests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void ProductShouldBeCorrect()
|
||||||
|
{
|
||||||
|
sbyte Cast(int i) => (sbyte)i;
|
||||||
|
|
||||||
|
Assert.AreEqual(0, Enumerable.Range(0, 10).Product());
|
||||||
|
Assert.AreEqual(1, Enumerable.Range(1, 1).Product());
|
||||||
|
Assert.AreEqual(2, Enumerable.Range(1, 2).Product());
|
||||||
|
Assert.AreEqual(6, Enumerable.Range(1, 3).Product());
|
||||||
|
Assert.AreEqual(24, Enumerable.Range(1, 4).Product());
|
||||||
|
Assert.AreEqual(120, Enumerable.Range(1, 5).Product());
|
||||||
|
|
||||||
|
// 6! will overflow for sbyte
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ProductOfDoublesShouldBeCorrect()
|
||||||
|
{
|
||||||
|
sbyte Double(int i) => (sbyte)(i * 2);
|
||||||
|
|
||||||
|
Assert.AreEqual(0, Enumerable.Range(0, 10).Product(Double));
|
||||||
|
Assert.AreEqual(2, Enumerable.Range(1, 1).Product(Double));
|
||||||
|
Assert.AreEqual(8, Enumerable.Range(1, 2).Product(Double));
|
||||||
|
Assert.AreEqual(48, Enumerable.Range(1, 3).Product(Double));
|
||||||
|
|
||||||
|
// Π_(i=1)^(n(i*2)) will overflow at i=4 for sbyte
|
||||||
|
}
|
||||||
|
}
|
44
X10D.Tests/src/Linq/SingleTests.cs
Normal file
44
X10D.Tests/src/Linq/SingleTests.cs
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Linq;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Linq;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class SingleTests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void ProductShouldBeCorrect()
|
||||||
|
{
|
||||||
|
float Cast(int i) => i;
|
||||||
|
|
||||||
|
Assert.AreEqual(0f, Enumerable.Range(0, 10).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(1f, Enumerable.Range(1, 1).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(2f, Enumerable.Range(1, 2).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(6f, Enumerable.Range(1, 3).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(24f, Enumerable.Range(1, 4).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(120f, Enumerable.Range(1, 5).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(720f, Enumerable.Range(1, 6).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(5040f, Enumerable.Range(1, 7).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(40320f, Enumerable.Range(1, 8).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(362880f, Enumerable.Range(1, 9).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(3628800f, Enumerable.Range(1, 10).Select(Cast).Product());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ProductOfDoublesShouldBeCorrect()
|
||||||
|
{
|
||||||
|
float Double(int i) => i * 2f;
|
||||||
|
|
||||||
|
Assert.AreEqual(0f, Enumerable.Range(0, 10).Product(Double));
|
||||||
|
Assert.AreEqual(2f, Enumerable.Range(1, 1).Product(Double));
|
||||||
|
Assert.AreEqual(8f, Enumerable.Range(1, 2).Product(Double));
|
||||||
|
Assert.AreEqual(48f, Enumerable.Range(1, 3).Product(Double));
|
||||||
|
Assert.AreEqual(384f, Enumerable.Range(1, 4).Product(Double));
|
||||||
|
Assert.AreEqual(3840f, Enumerable.Range(1, 5).Product(Double));
|
||||||
|
Assert.AreEqual(46080f, Enumerable.Range(1, 6).Product(Double));
|
||||||
|
Assert.AreEqual(645120f, Enumerable.Range(1, 7).Product(Double));
|
||||||
|
Assert.AreEqual(10321920f, Enumerable.Range(1, 8).Product(Double));
|
||||||
|
Assert.AreEqual(185794560f, Enumerable.Range(1, 9).Product(Double));
|
||||||
|
Assert.AreEqual(3715891200f, Enumerable.Range(1, 10).Product(Double));
|
||||||
|
}
|
||||||
|
}
|
58
X10D.Tests/src/Linq/SpanTests.cs
Normal file
58
X10D.Tests/src/Linq/SpanTests.cs
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Linq;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Linq;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class SpanTests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void AllShouldReturnTrueForEmptySpan()
|
||||||
|
{
|
||||||
|
var span = new Span<int>();
|
||||||
|
Assert.IsTrue(span.All(x => x > 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void AllShouldBeCorrect()
|
||||||
|
{
|
||||||
|
var span = new Span<int>(new[] {2, 4, 6, 8, 10});
|
||||||
|
Assert.IsTrue(span.All(x => x % 2 == 0));
|
||||||
|
Assert.IsFalse(span.All(x => x % 2 == 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void AnyShouldReturnFalseForEmptySpan()
|
||||||
|
{
|
||||||
|
var span = new Span<int>();
|
||||||
|
Assert.IsFalse(span.Any(x => x > 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void AnyShouldBeCorrect()
|
||||||
|
{
|
||||||
|
var span = new Span<int>(new[] {2, 4, 6, 8, 10});
|
||||||
|
Assert.IsTrue(span.Any(x => x % 2 == 0));
|
||||||
|
Assert.IsFalse(span.Any(x => x % 2 == 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void AllNullPredicateShouldThrow()
|
||||||
|
{
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() =>
|
||||||
|
{
|
||||||
|
var span = new Span<int>();
|
||||||
|
return span.All(null!);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void AnyNullPredicateShouldThrow()
|
||||||
|
{
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() =>
|
||||||
|
{
|
||||||
|
var span = new Span<int>();
|
||||||
|
return span.Any(null!);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
43
X10D.Tests/src/Linq/UInt16Tests.cs
Normal file
43
X10D.Tests/src/Linq/UInt16Tests.cs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Linq;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Linq;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
[CLSCompliant(false)]
|
||||||
|
public class UInt16Tests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void ProductShouldBeCorrect()
|
||||||
|
{
|
||||||
|
ushort Cast(int i) => (ushort)i;
|
||||||
|
|
||||||
|
Assert.AreEqual(0U, Enumerable.Range(0, 10).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(1U, Enumerable.Range(1, 1).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(2U, Enumerable.Range(1, 2).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(6U, Enumerable.Range(1, 3).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(24U, Enumerable.Range(1, 4).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(120U, Enumerable.Range(1, 5).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(720U, Enumerable.Range(1, 6).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(5040U, Enumerable.Range(1, 7).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(40320U, Enumerable.Range(1, 8).Select(Cast).Product());
|
||||||
|
|
||||||
|
// 9! will overflow for ushort
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ProductOfDoublesShouldBeCorrect()
|
||||||
|
{
|
||||||
|
ushort Double(int i) => (ushort)(i * 2);
|
||||||
|
|
||||||
|
Assert.AreEqual(0U, Enumerable.Range(0, 10).Product(Double));
|
||||||
|
Assert.AreEqual(2U, Enumerable.Range(1, 1).Product(Double));
|
||||||
|
Assert.AreEqual(8U, Enumerable.Range(1, 2).Product(Double));
|
||||||
|
Assert.AreEqual(48U, Enumerable.Range(1, 3).Product(Double));
|
||||||
|
Assert.AreEqual(384U, Enumerable.Range(1, 4).Product(Double));
|
||||||
|
Assert.AreEqual(3840U, Enumerable.Range(1, 5).Product(Double));
|
||||||
|
Assert.AreEqual(46080U, Enumerable.Range(1, 6).Product(Double));
|
||||||
|
|
||||||
|
// Π_(i=1)^n (2i) will overflow at i=7 for ushort
|
||||||
|
}
|
||||||
|
}
|
45
X10D.Tests/src/Linq/UInt32Tests.cs
Normal file
45
X10D.Tests/src/Linq/UInt32Tests.cs
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Linq;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Linq;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
[CLSCompliant(false)]
|
||||||
|
public class UInt32Tests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void ProductShouldBeCorrect()
|
||||||
|
{
|
||||||
|
ulong Cast(int i) => (ulong)i;
|
||||||
|
|
||||||
|
Assert.AreEqual(0U, Enumerable.Range(0, 10).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(1U, Enumerable.Range(1, 1).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(2U, Enumerable.Range(1, 2).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(6U, Enumerable.Range(1, 3).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(24U, Enumerable.Range(1, 4).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(120U, Enumerable.Range(1, 5).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(720U, Enumerable.Range(1, 6).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(5040U, Enumerable.Range(1, 7).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(40320U, Enumerable.Range(1, 8).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(362880U, Enumerable.Range(1, 9).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(3628800U, Enumerable.Range(1, 10).Select(Cast).Product());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ProductOfDoublesShouldBeCorrect()
|
||||||
|
{
|
||||||
|
uint Double(int i) => (uint)i * 2;
|
||||||
|
|
||||||
|
Assert.AreEqual(0U, Enumerable.Range(0, 10).Product(Double));
|
||||||
|
Assert.AreEqual(2U, Enumerable.Range(1, 1).Product(Double));
|
||||||
|
Assert.AreEqual(8U, Enumerable.Range(1, 2).Product(Double));
|
||||||
|
Assert.AreEqual(48U, Enumerable.Range(1, 3).Product(Double));
|
||||||
|
Assert.AreEqual(384U, Enumerable.Range(1, 4).Product(Double));
|
||||||
|
Assert.AreEqual(3840U, Enumerable.Range(1, 5).Product(Double));
|
||||||
|
Assert.AreEqual(46080U, Enumerable.Range(1, 6).Product(Double));
|
||||||
|
Assert.AreEqual(645120U, Enumerable.Range(1, 7).Product(Double));
|
||||||
|
Assert.AreEqual(10321920U, Enumerable.Range(1, 8).Product(Double));
|
||||||
|
Assert.AreEqual(185794560U, Enumerable.Range(1, 9).Product(Double));
|
||||||
|
Assert.AreEqual(3715891200U, Enumerable.Range(1, 10).Product(Double));
|
||||||
|
}
|
||||||
|
}
|
45
X10D.Tests/src/Linq/UInt64Tests.cs
Normal file
45
X10D.Tests/src/Linq/UInt64Tests.cs
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Linq;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Linq;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
[CLSCompliant(false)]
|
||||||
|
public class UInt64Tests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void ProductShouldBeCorrect()
|
||||||
|
{
|
||||||
|
ulong Cast(int i) => (ulong)i;
|
||||||
|
|
||||||
|
Assert.AreEqual(0UL, Enumerable.Range(0, 10).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(1UL, Enumerable.Range(1, 1).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(2UL, Enumerable.Range(1, 2).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(6UL, Enumerable.Range(1, 3).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(24UL, Enumerable.Range(1, 4).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(120UL, Enumerable.Range(1, 5).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(720UL, Enumerable.Range(1, 6).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(5040UL, Enumerable.Range(1, 7).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(40320UL, Enumerable.Range(1, 8).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(362880UL, Enumerable.Range(1, 9).Select(Cast).Product());
|
||||||
|
Assert.AreEqual(3628800UL, Enumerable.Range(1, 10).Select(Cast).Product());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ProductOfDoublesShouldBeCorrect()
|
||||||
|
{
|
||||||
|
ulong Double(int i) => (ulong)i * 2;
|
||||||
|
|
||||||
|
Assert.AreEqual(0UL, Enumerable.Range(0, 10).Product(Double));
|
||||||
|
Assert.AreEqual(2UL, Enumerable.Range(1, 1).Product(Double));
|
||||||
|
Assert.AreEqual(8UL, Enumerable.Range(1, 2).Product(Double));
|
||||||
|
Assert.AreEqual(48UL, Enumerable.Range(1, 3).Product(Double));
|
||||||
|
Assert.AreEqual(384UL, Enumerable.Range(1, 4).Product(Double));
|
||||||
|
Assert.AreEqual(3840UL, Enumerable.Range(1, 5).Product(Double));
|
||||||
|
Assert.AreEqual(46080UL, Enumerable.Range(1, 6).Product(Double));
|
||||||
|
Assert.AreEqual(645120UL, Enumerable.Range(1, 7).Product(Double));
|
||||||
|
Assert.AreEqual(10321920UL, Enumerable.Range(1, 8).Product(Double));
|
||||||
|
Assert.AreEqual(185794560UL, Enumerable.Range(1, 9).Product(Double));
|
||||||
|
Assert.AreEqual(3715891200UL, Enumerable.Range(1, 10).Product(Double));
|
||||||
|
}
|
||||||
|
}
|
62
X10D.Tests/src/Math/ByteTests.cs
Normal file
62
X10D.Tests/src/Math/ByteTests.cs
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Math;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Math;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class ByteTests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void DigitalRootShouldBeCorrect()
|
||||||
|
{
|
||||||
|
const byte value = 238;
|
||||||
|
Assert.AreEqual(4, value.DigitalRoot());
|
||||||
|
Assert.AreEqual(4, (-value).DigitalRoot());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void FactorialShouldBeCorrect()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(1L, ((byte)0).Factorial());
|
||||||
|
Assert.AreEqual(1L, ((byte)1).Factorial());
|
||||||
|
Assert.AreEqual(2L, ((byte)2).Factorial());
|
||||||
|
Assert.AreEqual(6L, ((byte)3).Factorial());
|
||||||
|
Assert.AreEqual(24L, ((byte)4).Factorial());
|
||||||
|
Assert.AreEqual(120L, ((byte)5).Factorial());
|
||||||
|
Assert.AreEqual(720L, ((byte)6).Factorial());
|
||||||
|
Assert.AreEqual(5040L, ((byte)7).Factorial());
|
||||||
|
Assert.AreEqual(40320L, ((byte)8).Factorial());
|
||||||
|
Assert.AreEqual(362880L, ((byte)9).Factorial());
|
||||||
|
Assert.AreEqual(3628800L, ((byte)10).Factorial());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void IsEvenShouldBeCorrect()
|
||||||
|
{
|
||||||
|
const byte one = 1;
|
||||||
|
const byte two = 2;
|
||||||
|
|
||||||
|
Assert.IsFalse(one.IsEven());
|
||||||
|
Assert.IsTrue(two.IsEven());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void IsOddShouldBeCorrect()
|
||||||
|
{
|
||||||
|
const byte one = 1;
|
||||||
|
const byte two = 2;
|
||||||
|
|
||||||
|
Assert.IsTrue(one.IsOdd());
|
||||||
|
Assert.IsFalse(two.IsOdd());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void MultiplicativePersistence_ShouldBeCorrect_ForRecordHolders()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(0, ((byte)0).MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(1, ((byte)10).MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(2, ((byte)25).MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(3, ((byte)39).MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(4, ((byte)77).MultiplicativePersistence());
|
||||||
|
}
|
||||||
|
}
|
201
X10D.Tests/src/Math/ComparableTests.cs
Normal file
201
X10D.Tests/src/Math/ComparableTests.cs
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Math;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Math;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class ComparableTests
|
||||||
|
{
|
||||||
|
private class ComparableTestClass : IComparable<ComparableTestClass>
|
||||||
|
{
|
||||||
|
public int CompareTo(ComparableTestClass? other)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly int _lower = 1;
|
||||||
|
private readonly int _upper = 10;
|
||||||
|
private readonly int _value = 5;
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Between_5_1_10_ShouldBeTrue()
|
||||||
|
{
|
||||||
|
Assert.IsTrue(_value.Between(_lower, _upper));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Between_1_1_10_ShouldBeFalse()
|
||||||
|
{
|
||||||
|
// default option is exclusive
|
||||||
|
Assert.IsFalse(_lower.Between(_lower, _upper));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Between_1_1_10_Inclusive_ShouldBeTrue()
|
||||||
|
{
|
||||||
|
Assert.IsTrue(_lower.Between(_lower, _upper, InclusiveOptions.Inclusive));
|
||||||
|
Assert.IsTrue(_lower.Between(_lower, _upper, InclusiveOptions.LowerInclusive));
|
||||||
|
Assert.IsFalse(_lower.Between(_lower, _upper, InclusiveOptions.UpperInclusive));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Between_10_1_10_ShouldBeFalse()
|
||||||
|
{
|
||||||
|
// default option is exclusive
|
||||||
|
Assert.IsFalse(_upper.Between(_lower, _upper));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Between_10_1_10_Inclusive_ShouldBeTrue()
|
||||||
|
{
|
||||||
|
Assert.IsTrue(_upper.Between(_lower, _upper, InclusiveOptions.Inclusive));
|
||||||
|
Assert.IsTrue(_upper.Between(_lower, _upper, InclusiveOptions.UpperInclusive));
|
||||||
|
Assert.IsFalse(_upper.Between(_lower, _upper, InclusiveOptions.LowerInclusive));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Between_1_10_5_ShouldThrow()
|
||||||
|
{
|
||||||
|
Assert.ThrowsException<ArgumentException>(() => _lower.Between(_upper, _value));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Between_Null_ShouldThrow()
|
||||||
|
{
|
||||||
|
ComparableTestClass? nullPointer = null;
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => ((ComparableTestClass?)null)!.Between(nullPointer!, nullPointer!));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Clamp_3_1_5_ShouldBe3()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(3, 3.Clamp(1, 5));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Clamp_10_1_5_ShouldBe5()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(5, 10.Clamp(1, 5));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Clamp_n_6_5_ShouldThrow()
|
||||||
|
{
|
||||||
|
Assert.ThrowsException<ArgumentException>(() => 0.Clamp(6, 5));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void GreaterThan_5_6_ShouldBeFalse()
|
||||||
|
{
|
||||||
|
Assert.IsFalse(5.GreaterThan(6));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void GreaterThan_6_5_ShouldBeTrue()
|
||||||
|
{
|
||||||
|
Assert.IsTrue(6.GreaterThan(5));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void GreaterThan_5_5_ShouldBeFalse()
|
||||||
|
{
|
||||||
|
Assert.IsFalse(5.LessThan(5));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void GreaterThan_Null_ShouldThrow()
|
||||||
|
{
|
||||||
|
ComparableTestClass? nullPointer = null;
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => nullPointer!.GreaterThan(nullPointer!));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void GreaterThanOrEqualTo_5_5_ShouldBeTrue()
|
||||||
|
{
|
||||||
|
Assert.IsTrue(5.GreaterThanOrEqualTo(5));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void GreaterThanOrEqualTo_6_5_ShouldBeTrue()
|
||||||
|
{
|
||||||
|
Assert.IsTrue(6.GreaterThanOrEqualTo(5));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void GreaterThanOrEqualTo_5_6_ShouldBeFalse()
|
||||||
|
{
|
||||||
|
Assert.IsFalse(5.GreaterThanOrEqualTo(6));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void GreaterThanOrEqualTo_Null_ShouldThrow()
|
||||||
|
{
|
||||||
|
ComparableTestClass? nullPointer = null;
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => nullPointer!.GreaterThanOrEqualTo(nullPointer!));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void LessThan_Null_ShouldThrow()
|
||||||
|
{
|
||||||
|
ComparableTestClass? nullPointer = null;
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => nullPointer!.LessThan(nullPointer!));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void LessThan_6_5_ShouldBeFalse()
|
||||||
|
{
|
||||||
|
Assert.IsFalse(6.LessThan(5));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void LessThan_5_6_ShouldBeTrue()
|
||||||
|
{
|
||||||
|
Assert.IsTrue(5.LessThan(6));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void LessThan_5_5_ShouldBeFalse()
|
||||||
|
{
|
||||||
|
Assert.IsFalse(5.LessThan(5));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void LessThanOrEqualTo_5_5_ShouldBeTrue()
|
||||||
|
{
|
||||||
|
Assert.IsTrue(5.LessThanOrEqualTo(5));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void LessThanOrEqualTo_5_6_ShouldBeTrue()
|
||||||
|
{
|
||||||
|
Assert.IsTrue(5.LessThanOrEqualTo(6));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void LessThanOrEqualTo_6_5_ShouldBeFalse()
|
||||||
|
{
|
||||||
|
Assert.IsFalse(6.LessThanOrEqualTo(5));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void LessThanOrEqualTo_Null_ShouldThrow()
|
||||||
|
{
|
||||||
|
ComparableTestClass? nullPointer = null;
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => nullPointer!.LessThanOrEqualTo(nullPointer!));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Max_Null_ShouldThrow()
|
||||||
|
{
|
||||||
|
ComparableTestClass? nullPointer = null;
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => nullPointer!.Max(nullPointer!));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Min_Null_ShouldThrow()
|
||||||
|
{
|
||||||
|
ComparableTestClass? nullPointer = null;
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => nullPointer!.Min(nullPointer!));
|
||||||
|
}
|
||||||
|
}
|
122
X10D.Tests/src/Math/DecimalTests.cs
Normal file
122
X10D.Tests/src/Math/DecimalTests.cs
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
using System.Numerics;
|
||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Math;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Math;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class DecimalTests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void ComplexSqrt_ShouldBeCorrect_GivenReal()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(0.0, 0.0m.ComplexSqrt());
|
||||||
|
Assert.AreEqual(1.4142135623730951, 2.0m.ComplexSqrt());
|
||||||
|
Assert.AreEqual(3.0, 9.0m.ComplexSqrt());
|
||||||
|
Assert.AreEqual(4.0, 16.0m.ComplexSqrt());
|
||||||
|
Assert.AreEqual(100.0, 10000.0m.ComplexSqrt());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ComplexSqrt_ShouldBeImaginary_GivenNegativeValue()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(new Complex(0, 1), (-1.0m).ComplexSqrt());
|
||||||
|
Assert.AreEqual(new Complex(0, 1.4142135623730951), (-2.0m).ComplexSqrt());
|
||||||
|
Assert.AreEqual(new Complex(0, 3.0), (-9.0m).ComplexSqrt());
|
||||||
|
Assert.AreEqual(new Complex(0, 4.0), (-16.0m).ComplexSqrt());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void IsEven_ShouldBeFalse_GivenOddNumber()
|
||||||
|
{
|
||||||
|
Assert.IsFalse((-3.0m).IsEven());
|
||||||
|
Assert.IsFalse((-1.0m).IsEven());
|
||||||
|
Assert.IsFalse(1.0m.IsEven());
|
||||||
|
Assert.IsFalse(3.0m.IsEven());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void IsEven_ShouldBeTrue_GivenOddNumber()
|
||||||
|
{
|
||||||
|
Assert.IsTrue((-4.0m).IsEven());
|
||||||
|
Assert.IsTrue((-2.0m).IsEven());
|
||||||
|
Assert.IsTrue(0.0m.IsEven());
|
||||||
|
Assert.IsTrue(2.0m.IsEven());
|
||||||
|
Assert.IsTrue(4.0m.IsEven());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void IsOdd_ShouldBeFalse_GivenEvenNumber()
|
||||||
|
{
|
||||||
|
Assert.IsFalse((-4.0m).IsOdd());
|
||||||
|
Assert.IsFalse((-2.0m).IsOdd());
|
||||||
|
Assert.IsFalse(0.0m.IsOdd());
|
||||||
|
Assert.IsFalse(2.0m.IsOdd());
|
||||||
|
Assert.IsFalse(4.0m.IsOdd());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void IsOdd_ShouldBeTrue_GivenOddNumber()
|
||||||
|
{
|
||||||
|
Assert.IsTrue((-3.0m).IsOdd());
|
||||||
|
Assert.IsTrue((-1.0m).IsOdd());
|
||||||
|
Assert.IsTrue(1.0m.IsOdd());
|
||||||
|
Assert.IsTrue(3.0m.IsOdd());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Round_ShouldRoundToNearestInteger()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(4.0m, 3.5m.Round());
|
||||||
|
Assert.AreEqual(7.0m, 6.8m.Round());
|
||||||
|
Assert.AreEqual(7.0m, 7.2m.Round());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Round_ShouldRoundToNearestMultiple()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(5.0m, 3.5m.Round(5));
|
||||||
|
Assert.AreEqual(5.0m, 7.0m.Round(5));
|
||||||
|
Assert.AreEqual(10.0m, 7.5m.Round(5));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Sign_ShouldBeMinus1_GivenNegative()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(-1, -1.0m.Sign());
|
||||||
|
Assert.AreEqual(-1, -2.0m.Sign());
|
||||||
|
Assert.AreEqual(-1, -3.0m.Sign());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Sign_ShouldBe0_Given0()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(0, 0.0m.Sign());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Sign_ShouldBe1_GivenPositive()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(1, 1.0m.Sign());
|
||||||
|
Assert.AreEqual(1, 2.0m.Sign());
|
||||||
|
Assert.AreEqual(1, 3.0m.Sign());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Sqrt_ShouldBeCorrect_GivenValue()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(0.0m, 0.0m.Sqrt());
|
||||||
|
Assert.AreEqual(1.4142135623730950488016887242m, 2.0m.Sqrt());
|
||||||
|
Assert.AreEqual(3.0m, 9.0m.Sqrt());
|
||||||
|
Assert.AreEqual(4.0m, 16.0m.Sqrt());
|
||||||
|
Assert.AreEqual(100.0m, 10000.0m.Sqrt());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Sqrt_ShouldThrow_GivenNegativeValue()
|
||||||
|
{
|
||||||
|
Assert.ThrowsException<ArgumentException>(() => (-1.0m).Sqrt());
|
||||||
|
Assert.ThrowsException<ArgumentException>(() => (-2.0m).Sqrt());
|
||||||
|
Assert.ThrowsException<ArgumentException>(() => (-3.0m).Sqrt());
|
||||||
|
}
|
||||||
|
}
|
242
X10D.Tests/src/Math/DoubleTests.cs
Normal file
242
X10D.Tests/src/Math/DoubleTests.cs
Normal file
@ -0,0 +1,242 @@
|
|||||||
|
using System.Numerics;
|
||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Math;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Math;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class DoubleTests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void DegreesToRadians_ShouldBeCorrect()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(System.Math.PI, 180.0.DegreesToRadians(), 1e-6);
|
||||||
|
Assert.AreEqual(System.Math.PI * 1.5, 270.0.DegreesToRadians(), 1e-6);
|
||||||
|
Assert.AreEqual(0.0, 0.0.DegreesToRadians(), 1e-6);
|
||||||
|
Assert.AreEqual(0.017453292519943295, 1.0.DegreesToRadians(), 1e-6);
|
||||||
|
Assert.AreEqual(0.10471975511965978, 6.0.DegreesToRadians(), 1e-6);
|
||||||
|
Assert.AreEqual(0.20943951023931956, 12.0.DegreesToRadians(), 1e-6);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void RadiansToDegrees_ShouldBeCorrect()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(180.0, System.Math.PI.RadiansToDegrees(), 1e-6);
|
||||||
|
Assert.AreEqual(360.0, (2.0 * System.Math.PI).RadiansToDegrees(), 1e-6);
|
||||||
|
Assert.AreEqual(0.0, 0.0.RadiansToDegrees(), 1e-6);
|
||||||
|
Assert.AreEqual(1.0, 0.017453292519943295.RadiansToDegrees(), 1e-6);
|
||||||
|
Assert.AreEqual(6.000000000000001, 0.10471975511965978.RadiansToDegrees(), 1e-6); // rounding errors are fun
|
||||||
|
Assert.AreEqual(12.0, 0.20943951023931953.RadiansToDegrees(), 1e-6);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ComplexSqrt_ShouldBeCorrect_GivenReal()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(0.0, 0.0.ComplexSqrt());
|
||||||
|
Assert.AreEqual(1.4142135623730951, 2.0.ComplexSqrt());
|
||||||
|
Assert.AreEqual(3.0, 9.0.ComplexSqrt());
|
||||||
|
Assert.AreEqual(4.0, 16.0.ComplexSqrt());
|
||||||
|
Assert.AreEqual(100.0, 10000.0.ComplexSqrt());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ComplexSqrt_ShouldBeImaginary_GivenNegativeValue()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(new Complex(0, 1), (-1.0).ComplexSqrt());
|
||||||
|
Assert.AreEqual(new Complex(0, 1.4142135623730951), (-2.0).ComplexSqrt());
|
||||||
|
Assert.AreEqual(new Complex(0, 3.0), (-9.0).ComplexSqrt());
|
||||||
|
Assert.AreEqual(new Complex(0, 4.0), (-16.0).ComplexSqrt());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ComplexSqrt_ShouldBeComplexInfinity_GivenInfinity()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(Complex.Infinity, double.NegativeInfinity.ComplexSqrt());
|
||||||
|
Assert.AreEqual(Complex.Infinity, double.PositiveInfinity.ComplexSqrt());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ComplexSqrt_ShouldBeNaN_GivenNaN()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(Complex.NaN, double.NaN.ComplexSqrt());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void IsEven_ShouldBeFalse_GivenOddNumber()
|
||||||
|
{
|
||||||
|
Assert.IsFalse((-3.0).IsEven());
|
||||||
|
Assert.IsFalse((-1.0).IsEven());
|
||||||
|
Assert.IsFalse(1.0.IsEven());
|
||||||
|
Assert.IsFalse(3.0.IsEven());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void IsEven_ShouldBeTrue_GivenOddNumber()
|
||||||
|
{
|
||||||
|
Assert.IsTrue((-4.0).IsEven());
|
||||||
|
Assert.IsTrue((-2.0).IsEven());
|
||||||
|
Assert.IsTrue(0.0.IsEven());
|
||||||
|
Assert.IsTrue(2.0.IsEven());
|
||||||
|
Assert.IsTrue(4.0.IsEven());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void IsOdd_ShouldBeFalse_GivenEvenNumber()
|
||||||
|
{
|
||||||
|
Assert.IsFalse((-4.0).IsOdd());
|
||||||
|
Assert.IsFalse((-2.0).IsOdd());
|
||||||
|
Assert.IsFalse(0.0.IsOdd());
|
||||||
|
Assert.IsFalse(2.0.IsOdd());
|
||||||
|
Assert.IsFalse(4.0.IsOdd());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void IsOdd_ShouldBeTrue_GivenOddNumber()
|
||||||
|
{
|
||||||
|
Assert.IsTrue((-3.0).IsOdd());
|
||||||
|
Assert.IsTrue((-1.0).IsOdd());
|
||||||
|
Assert.IsTrue(1.0.IsOdd());
|
||||||
|
Assert.IsTrue(3.0.IsOdd());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Round_ShouldRoundToNearestInteger()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(4.0, 3.5.Round(), 1e-6);
|
||||||
|
Assert.AreEqual(7.0, 6.8.Round(), 1e-6);
|
||||||
|
Assert.AreEqual(7.0, 7.2.Round(), 1e-6);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Round_ShouldRoundToNearestMultiple()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(5.0, 3.5.Round(5), 1e-6);
|
||||||
|
Assert.AreEqual(5.0, 7.0.Round(5), 1e-6);
|
||||||
|
Assert.AreEqual(10.0, 7.5.Round(5), 1e-6);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Sign_ShouldBeMinus1_GivenNegative()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(-1, -1.0.Sign());
|
||||||
|
Assert.AreEqual(-1, -2.0.Sign());
|
||||||
|
Assert.AreEqual(-1, -3.0.Sign());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Sign_ShouldBe0_Given0()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(0, 0.0.Sign());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Sign_ShouldBe1_GivenPositive()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(1, 1.0.Sign());
|
||||||
|
Assert.AreEqual(1, 2.0.Sign());
|
||||||
|
Assert.AreEqual(1, 3.0.Sign());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Sqrt_ShouldBeCorrect_GivenValue()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(0.0, 0.0.Sqrt(), 1e-6);
|
||||||
|
Assert.AreEqual(1.414213562373095, 2.0.Sqrt(), 1e-6);
|
||||||
|
Assert.AreEqual(3.0, 9.0.Sqrt(), 1e-6);
|
||||||
|
Assert.AreEqual(4.0, 16.0.Sqrt(), 1e-6);
|
||||||
|
Assert.AreEqual(100.0, 10000.0.Sqrt(), 1e-6);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Sqrt_ShouldBeNaN_GivenNaN()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(double.NaN, double.NaN.Sqrt());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Sqrt_ShouldBeNaN_GivenNegativeValue()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(double.NaN, (-1.0).Sqrt());
|
||||||
|
Assert.AreEqual(double.NaN, (-2.0).Sqrt());
|
||||||
|
Assert.AreEqual(double.NaN, (-3.0).Sqrt());
|
||||||
|
Assert.AreEqual(double.NaN, double.NegativeInfinity.Sqrt());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Sqrt_ShouldBePositiveInfinity_GivenPositiveInfinity()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(double.PositiveInfinity, double.PositiveInfinity.Sqrt());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Acos_ShouldBeCorrect()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(1.0471975511965979, 0.5.Acos(), 1e-6);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Acosh_ShouldBeCorrect()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(0.9624236501192069, 1.5.Acosh(), 1e-6);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Asin_ShouldBeCorrect()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(0.5235987755982989, 0.5.Asin(), 1e-6);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Asinh_ShouldBeCorrect()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(1.1947632172871094, 1.5.Asinh(), 1e-6);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Atan_ShouldBeCorrect()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(0.4636476090008061, 0.5.Atan(), 1e-6);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Atanh_ShouldBeCorrect()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(0.5493061443340549, 0.5.Atanh(), 1e-6);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Cos_ShouldBeCorrect()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(0.8775825618903728, 0.5.Cos(), 1e-6);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Cosh_ShouldBeCorrect()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(2.352409615243247, 1.5.Cosh(), 1e-6);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Sin_ShouldBeCorrect()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(0.479425538604203, 0.5.Sin(), 1e-6);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Sinh_ShouldBeCorrect()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(2.1292794550948173, 1.5.Sinh(), 1e-6);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Tan_ShouldBeCorrect()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(0.5463024898437905, 0.5.Tan(), 1e-6);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Tanh_ShouldBeCorrect()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(0.46211715726000974, 0.5.Tanh(), 1e-6);
|
||||||
|
}
|
||||||
|
}
|
80
X10D.Tests/src/Math/Int16Tests.cs
Normal file
80
X10D.Tests/src/Math/Int16Tests.cs
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Math;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Math;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class Int16Tests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void DigitalRootShouldBeCorrect()
|
||||||
|
{
|
||||||
|
const short value = 238;
|
||||||
|
Assert.AreEqual(4, value.DigitalRoot());
|
||||||
|
Assert.AreEqual(4, (-value).DigitalRoot());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void FactorialShouldBeCorrect()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(1L, ((short)0).Factorial());
|
||||||
|
Assert.AreEqual(1L, ((short)1).Factorial());
|
||||||
|
Assert.AreEqual(2L, ((short)2).Factorial());
|
||||||
|
Assert.AreEqual(6L, ((short)3).Factorial());
|
||||||
|
Assert.AreEqual(24L, ((short)4).Factorial());
|
||||||
|
Assert.AreEqual(120L, ((short)5).Factorial());
|
||||||
|
Assert.AreEqual(720L, ((short)6).Factorial());
|
||||||
|
Assert.AreEqual(5040L, ((short)7).Factorial());
|
||||||
|
Assert.AreEqual(40320L, ((short)8).Factorial());
|
||||||
|
Assert.AreEqual(362880L, ((short)9).Factorial());
|
||||||
|
Assert.AreEqual(3628800L, ((short)10).Factorial());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void IsEvenShouldBeCorrect()
|
||||||
|
{
|
||||||
|
const short one = 1;
|
||||||
|
const short two = 2;
|
||||||
|
|
||||||
|
Assert.IsFalse(one.IsEven());
|
||||||
|
Assert.IsTrue(two.IsEven());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void IsOddShouldBeCorrect()
|
||||||
|
{
|
||||||
|
const short one = 1;
|
||||||
|
const short two = 2;
|
||||||
|
|
||||||
|
Assert.IsTrue(one.IsOdd());
|
||||||
|
Assert.IsFalse(two.IsOdd());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void MultiplicativePersistence_ShouldBeCorrect_ForRecordHolders()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(0, ((short)0).MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(1, ((short)10).MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(2, ((short)25).MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(3, ((short)39).MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(4, ((short)77).MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(5, ((short)679).MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(6, ((short)6788).MultiplicativePersistence());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NegativeFactorialShouldThrow()
|
||||||
|
{
|
||||||
|
Assert.ThrowsException<ArithmeticException>(() => ((short)-1).Factorial());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void SignShouldBeCorrect()
|
||||||
|
{
|
||||||
|
const short one = 1;
|
||||||
|
const short zero = 0;
|
||||||
|
Assert.AreEqual(one, one.Sign());
|
||||||
|
Assert.AreEqual(zero, zero.Sign());
|
||||||
|
Assert.AreEqual(-one, (-one).Sign());
|
||||||
|
}
|
||||||
|
}
|
83
X10D.Tests/src/Math/Int32Tests.cs
Normal file
83
X10D.Tests/src/Math/Int32Tests.cs
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Math;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Math;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class Int32Tests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void DigitalRootShouldBeCorrect()
|
||||||
|
{
|
||||||
|
const int value = 238;
|
||||||
|
Assert.AreEqual(4, value.DigitalRoot());
|
||||||
|
Assert.AreEqual(4, (-value).DigitalRoot());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void FactorialShouldBeCorrect()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(1L, 0.Factorial());
|
||||||
|
Assert.AreEqual(1L, 1.Factorial());
|
||||||
|
Assert.AreEqual(2L, 2.Factorial());
|
||||||
|
Assert.AreEqual(6L, 3.Factorial());
|
||||||
|
Assert.AreEqual(24L, 4.Factorial());
|
||||||
|
Assert.AreEqual(120L, 5.Factorial());
|
||||||
|
Assert.AreEqual(720L, 6.Factorial());
|
||||||
|
Assert.AreEqual(5040L, 7.Factorial());
|
||||||
|
Assert.AreEqual(40320L, 8.Factorial());
|
||||||
|
Assert.AreEqual(362880L, 9.Factorial());
|
||||||
|
Assert.AreEqual(3628800L, 10.Factorial());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void IsEvenShouldBeCorrect()
|
||||||
|
{
|
||||||
|
const int one = 1;
|
||||||
|
const int two = 2;
|
||||||
|
|
||||||
|
Assert.IsFalse(one.IsEven());
|
||||||
|
Assert.IsTrue(two.IsEven());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void IsOddShouldBeCorrect()
|
||||||
|
{
|
||||||
|
const int one = 1;
|
||||||
|
const int two = 2;
|
||||||
|
|
||||||
|
Assert.IsTrue(one.IsOdd());
|
||||||
|
Assert.IsFalse(two.IsOdd());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void MultiplicativePersistence_ShouldBeCorrect_ForRecordHolders()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(0, 0.MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(1, 10.MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(2, 25.MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(3, 39.MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(4, 77.MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(5, 679.MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(6, 6788.MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(7, 68889.MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(8, 2677889.MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(9, 26888999.MultiplicativePersistence());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NegativeFactorialShouldThrow()
|
||||||
|
{
|
||||||
|
Assert.ThrowsException<ArithmeticException>(() => (-1).Factorial());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void SignShouldBeCorrect()
|
||||||
|
{
|
||||||
|
const int one = 1;
|
||||||
|
const int zero = 0;
|
||||||
|
Assert.AreEqual(one, one.Sign());
|
||||||
|
Assert.AreEqual(zero, zero.Sign());
|
||||||
|
Assert.AreEqual(-one, (-one).Sign());
|
||||||
|
}
|
||||||
|
}
|
85
X10D.Tests/src/Math/Int64Tests.cs
Normal file
85
X10D.Tests/src/Math/Int64Tests.cs
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Math;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Math;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class Int64Tests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void DigitalRootShouldBeCorrect()
|
||||||
|
{
|
||||||
|
const long value = 238;
|
||||||
|
Assert.AreEqual(4, value.DigitalRoot());
|
||||||
|
Assert.AreEqual(4, (-value).DigitalRoot());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void FactorialShouldBeCorrect()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(1L, 0L.Factorial());
|
||||||
|
Assert.AreEqual(1L, 1L.Factorial());
|
||||||
|
Assert.AreEqual(2L, 2L.Factorial());
|
||||||
|
Assert.AreEqual(6L, 3L.Factorial());
|
||||||
|
Assert.AreEqual(24L, 4L.Factorial());
|
||||||
|
Assert.AreEqual(120L, 5L.Factorial());
|
||||||
|
Assert.AreEqual(720L, 6L.Factorial());
|
||||||
|
Assert.AreEqual(5040L, 7L.Factorial());
|
||||||
|
Assert.AreEqual(40320L, 8L.Factorial());
|
||||||
|
Assert.AreEqual(362880L, 9L.Factorial());
|
||||||
|
Assert.AreEqual(3628800L, 10L.Factorial());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void IsEvenShouldBeCorrect()
|
||||||
|
{
|
||||||
|
const long one = 1;
|
||||||
|
const long two = 2;
|
||||||
|
|
||||||
|
Assert.IsFalse(one.IsEven());
|
||||||
|
Assert.IsTrue(two.IsEven());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void IsOddShouldBeCorrect()
|
||||||
|
{
|
||||||
|
const long one = 1;
|
||||||
|
const long two = 2;
|
||||||
|
|
||||||
|
Assert.IsTrue(one.IsOdd());
|
||||||
|
Assert.IsFalse(two.IsOdd());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void MultiplicativePersistence_ShouldBeCorrect_ForRecordHolders()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(0, 0L.MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(1, 10L.MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(2, 25L.MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(3, 39L.MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(4, 77L.MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(5, 679L.MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(6, 6788L.MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(7, 68889L.MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(8, 2677889L.MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(9, 26888999L.MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(10, 3778888999L.MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(11, 277777788888899L.MultiplicativePersistence());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NegativeFactorialShouldThrow()
|
||||||
|
{
|
||||||
|
Assert.ThrowsException<ArithmeticException>(() => (-1L).Factorial());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void SignShouldBeCorrect()
|
||||||
|
{
|
||||||
|
const long one = 1;
|
||||||
|
const long zero = 0;
|
||||||
|
Assert.AreEqual(one, one.Sign());
|
||||||
|
Assert.AreEqual(zero, zero.Sign());
|
||||||
|
Assert.AreEqual(-one, (-one).Sign());
|
||||||
|
}
|
||||||
|
}
|
154
X10D.Tests/src/Math/IsPrimeTests.cs
Normal file
154
X10D.Tests/src/Math/IsPrimeTests.cs
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Math;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Math;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class IsPrimeTests
|
||||||
|
{
|
||||||
|
private IReadOnlyList<int> _primeNumbers = ArraySegment<int>.Empty;
|
||||||
|
|
||||||
|
[TestInitialize]
|
||||||
|
public void Initialize()
|
||||||
|
{
|
||||||
|
_primeNumbers = LoadPrimes();
|
||||||
|
Assert.AreEqual(1000, _primeNumbers.Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void First1000Primes()
|
||||||
|
{
|
||||||
|
for (var index = 0; index < _primeNumbers.Count; index++)
|
||||||
|
{
|
||||||
|
int value = _primeNumbers[index];
|
||||||
|
|
||||||
|
Assert.IsTrue(value.IsPrime());
|
||||||
|
Assert.IsTrue(((long)value).IsPrime());
|
||||||
|
|
||||||
|
if (value is >= byte.MinValue and <= byte.MaxValue)
|
||||||
|
{
|
||||||
|
Assert.IsTrue(((byte)value).IsPrime());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value is >= short.MinValue and <= short.MaxValue)
|
||||||
|
{
|
||||||
|
Assert.IsTrue(((short)value).IsPrime());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value is >= byte.MinValue and <= byte.MaxValue)
|
||||||
|
{
|
||||||
|
Assert.IsTrue(((byte)value).IsPrime());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value is >= ushort.MinValue and <= ushort.MaxValue)
|
||||||
|
{
|
||||||
|
Assert.IsTrue(((ushort)value).IsPrime());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value is >= sbyte.MinValue and <= sbyte.MaxValue)
|
||||||
|
{
|
||||||
|
Assert.IsTrue(((sbyte)value).IsPrime());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value >= 0)
|
||||||
|
{
|
||||||
|
Assert.IsTrue(((uint)value).IsPrime());
|
||||||
|
Assert.IsTrue(((ulong)value).IsPrime());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Negatives()
|
||||||
|
{
|
||||||
|
for (var value = short.MinValue; value < 0; value++)
|
||||||
|
{
|
||||||
|
Assert.IsFalse(value.IsPrime());
|
||||||
|
Assert.IsFalse(((int)value).IsPrime());
|
||||||
|
Assert.IsFalse(((long)value).IsPrime());
|
||||||
|
|
||||||
|
if (value is >= sbyte.MinValue and <= sbyte.MaxValue)
|
||||||
|
{
|
||||||
|
Assert.IsFalse(((sbyte)value).IsPrime());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void LessThan2()
|
||||||
|
{
|
||||||
|
for (var value = 0; value < 2; value++)
|
||||||
|
{
|
||||||
|
Assert.IsFalse(value.IsPrime());
|
||||||
|
Assert.IsFalse(((byte)value).IsPrime());
|
||||||
|
Assert.IsFalse(((short)value).IsPrime());
|
||||||
|
Assert.IsFalse(((long)value).IsPrime());
|
||||||
|
|
||||||
|
Assert.IsFalse(((sbyte)value).IsPrime());
|
||||||
|
Assert.IsFalse(((ushort)value).IsPrime());
|
||||||
|
Assert.IsFalse(((uint)value).IsPrime());
|
||||||
|
Assert.IsFalse(((ulong)value).IsPrime());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ZeroTo7919()
|
||||||
|
{
|
||||||
|
for (var value = 0; value < 7920; value++)
|
||||||
|
{
|
||||||
|
bool expected = _primeNumbers.Contains(value);
|
||||||
|
|
||||||
|
Assert.AreEqual(expected, ((short)value).IsPrime());
|
||||||
|
Assert.AreEqual(expected, value.IsPrime());
|
||||||
|
Assert.AreEqual(expected, ((long)value).IsPrime());
|
||||||
|
|
||||||
|
Assert.AreEqual(expected, ((ushort)value).IsPrime());
|
||||||
|
Assert.AreEqual(expected, ((uint)value).IsPrime());
|
||||||
|
Assert.AreEqual(expected, ((ulong)value).IsPrime());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ZeroToByteMaxValue()
|
||||||
|
{
|
||||||
|
for (byte value = 0; value < byte.MaxValue; value++)
|
||||||
|
{
|
||||||
|
bool expected = _primeNumbers.Contains(value);
|
||||||
|
|
||||||
|
Assert.AreEqual(expected, value.IsPrime());
|
||||||
|
Assert.AreEqual(expected, ((short)value).IsPrime());
|
||||||
|
Assert.AreEqual(expected, ((int)value).IsPrime());
|
||||||
|
Assert.AreEqual(expected, ((long)value).IsPrime());
|
||||||
|
|
||||||
|
Assert.AreEqual(expected, ((ushort)value).IsPrime());
|
||||||
|
Assert.AreEqual(expected, ((uint)value).IsPrime());
|
||||||
|
Assert.AreEqual(expected, ((ulong)value).IsPrime());
|
||||||
|
|
||||||
|
if (value < sbyte.MaxValue)
|
||||||
|
{
|
||||||
|
Assert.AreEqual(expected, ((sbyte)value).IsPrime());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IReadOnlyList<int> LoadPrimes()
|
||||||
|
{
|
||||||
|
using var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("X10D.Tests.1000primes.txt");
|
||||||
|
Assert.IsNotNull(stream);
|
||||||
|
|
||||||
|
using var reader = new StreamReader(stream, Encoding.UTF8);
|
||||||
|
var primes = new List<int>();
|
||||||
|
|
||||||
|
while (reader.ReadLine() is { } line)
|
||||||
|
{
|
||||||
|
if (int.TryParse(line, out int prime))
|
||||||
|
{
|
||||||
|
primes.Add(prime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return primes.AsReadOnly();
|
||||||
|
}
|
||||||
|
}
|
79
X10D.Tests/src/Math/SByteTests.cs
Normal file
79
X10D.Tests/src/Math/SByteTests.cs
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Math;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Math;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
[CLSCompliant(false)]
|
||||||
|
public class SByteTests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void DigitalRootShouldBeCorrect()
|
||||||
|
{
|
||||||
|
const sbyte value = 127; // sbyte.MaxValue. can't use 238 like the other tests
|
||||||
|
Assert.AreEqual(1, value.DigitalRoot());
|
||||||
|
Assert.AreEqual(1, (-value).DigitalRoot());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void FactorialShouldBeCorrect()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(1L, ((sbyte)0).Factorial());
|
||||||
|
Assert.AreEqual(1L, ((sbyte)1).Factorial());
|
||||||
|
Assert.AreEqual(2L, ((sbyte)2).Factorial());
|
||||||
|
Assert.AreEqual(6L, ((sbyte)3).Factorial());
|
||||||
|
Assert.AreEqual(24L, ((sbyte)4).Factorial());
|
||||||
|
Assert.AreEqual(120L, ((sbyte)5).Factorial());
|
||||||
|
Assert.AreEqual(720L, ((sbyte)6).Factorial());
|
||||||
|
Assert.AreEqual(5040L, ((sbyte)7).Factorial());
|
||||||
|
Assert.AreEqual(40320L, ((sbyte)8).Factorial());
|
||||||
|
Assert.AreEqual(362880L, ((sbyte)9).Factorial());
|
||||||
|
Assert.AreEqual(3628800L, ((sbyte)10).Factorial());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void IsEvenShouldBeCorrect()
|
||||||
|
{
|
||||||
|
const sbyte one = 1;
|
||||||
|
const sbyte two = 2;
|
||||||
|
|
||||||
|
Assert.IsFalse(one.IsEven());
|
||||||
|
Assert.IsTrue(two.IsEven());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void IsOddShouldBeCorrect()
|
||||||
|
{
|
||||||
|
const sbyte one = 1;
|
||||||
|
const sbyte two = 2;
|
||||||
|
|
||||||
|
Assert.IsTrue(one.IsOdd());
|
||||||
|
Assert.IsFalse(two.IsOdd());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void MultiplicativePersistence_ShouldBeCorrect_ForRecordHolders()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(0, ((sbyte)0).MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(1, ((sbyte)10).MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(2, ((sbyte)25).MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(3, ((sbyte)39).MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(4, ((sbyte)77).MultiplicativePersistence());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NegativeFactorialShouldThrow()
|
||||||
|
{
|
||||||
|
Assert.ThrowsException<ArithmeticException>(() => ((sbyte)-1).Factorial());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void SignShouldBeCorrect()
|
||||||
|
{
|
||||||
|
const sbyte one = 1;
|
||||||
|
const sbyte zero = 0;
|
||||||
|
Assert.AreEqual(one, one.Sign());
|
||||||
|
Assert.AreEqual(zero, zero.Sign());
|
||||||
|
Assert.AreEqual(-one, (-one).Sign());
|
||||||
|
}
|
||||||
|
}
|
242
X10D.Tests/src/Math/SingleTests.cs
Normal file
242
X10D.Tests/src/Math/SingleTests.cs
Normal file
@ -0,0 +1,242 @@
|
|||||||
|
using System.Numerics;
|
||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Math;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Math;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class SingleTests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void DegreesToRadians_ShouldBeCorrect()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(MathF.PI, 180.0f.DegreesToRadians(), 1e-6f);
|
||||||
|
Assert.AreEqual(MathF.PI * 1.5f, 270.0f.DegreesToRadians(), 1e-6f);
|
||||||
|
Assert.AreEqual(0.0f, 0.0f.DegreesToRadians(), 1e-6f);
|
||||||
|
Assert.AreEqual(0.017453292f, 1.0f.DegreesToRadians(), 1e-6f);
|
||||||
|
Assert.AreEqual(0.10471976f, 6.0f.DegreesToRadians(), 1e-6f);
|
||||||
|
Assert.AreEqual(0.20943952f, 12.0f.DegreesToRadians(), 1e-6f);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void RadiansToDegrees_ShouldBeCorrect()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(180.0f, MathF.PI.RadiansToDegrees(), 1e-6f);
|
||||||
|
Assert.AreEqual(270.0f, (MathF.PI * 1.5f).RadiansToDegrees(), 1e-6f);
|
||||||
|
Assert.AreEqual(0.0, 0.0f.RadiansToDegrees(), 1e-6f);
|
||||||
|
Assert.AreEqual(0.99999994f, 0.017453292f.RadiansToDegrees(), 1e-6f); // rounding errors are fun
|
||||||
|
Assert.AreEqual(6.0f, 0.10471976f.RadiansToDegrees(), 1e-6f);
|
||||||
|
Assert.AreEqual(12.0f, 0.20943952f.RadiansToDegrees(), 1e-6f);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ComplexSqrt_ShouldBeCorrect_GivenReal()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(0.0f, 0.0f.ComplexSqrt());
|
||||||
|
Assert.AreEqual(1.4142135f, 2.0f.ComplexSqrt());
|
||||||
|
Assert.AreEqual(3.0f, 9.0f.ComplexSqrt());
|
||||||
|
Assert.AreEqual(4.0f, 16.0f.ComplexSqrt());
|
||||||
|
Assert.AreEqual(100.0f, 10000.0f.ComplexSqrt());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ComplexSqrt_ShouldBeImaginary_GivenNegativeValue()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(new Complex(0, 1), (-1.0f).ComplexSqrt());
|
||||||
|
Assert.AreEqual(new Complex(0, 1.4142135f), (-2.0f).ComplexSqrt());
|
||||||
|
Assert.AreEqual(new Complex(0, 3.0f), (-9.0f).ComplexSqrt());
|
||||||
|
Assert.AreEqual(new Complex(0, 4.0f), (-16.0f).ComplexSqrt());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ComplexSqrt_ShouldBeComplexInfinity_GivenInfinity()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(Complex.Infinity, float.NegativeInfinity.ComplexSqrt());
|
||||||
|
Assert.AreEqual(Complex.Infinity, float.PositiveInfinity.ComplexSqrt());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void ComplexSqrt_ShouldBeNaN_GivenNaN()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(Complex.NaN, float.NaN.ComplexSqrt());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void IsEven_ShouldBeFalse_GivenOddNumber()
|
||||||
|
{
|
||||||
|
Assert.IsFalse((-3.0f).IsEven());
|
||||||
|
Assert.IsFalse((-1.0f).IsEven());
|
||||||
|
Assert.IsFalse(1.0f.IsEven());
|
||||||
|
Assert.IsFalse(3.0f.IsEven());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void IsEven_ShouldBeTrue_GivenOddNumber()
|
||||||
|
{
|
||||||
|
Assert.IsTrue((-4.0f).IsEven());
|
||||||
|
Assert.IsTrue((-2.0f).IsEven());
|
||||||
|
Assert.IsTrue(0.0f.IsEven());
|
||||||
|
Assert.IsTrue(2.0f.IsEven());
|
||||||
|
Assert.IsTrue(4.0f.IsEven());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void IsOdd_ShouldBeFalse_GivenEvenNumber()
|
||||||
|
{
|
||||||
|
Assert.IsFalse((-4.0f).IsOdd());
|
||||||
|
Assert.IsFalse((-2.0f).IsOdd());
|
||||||
|
Assert.IsFalse(0.0f.IsOdd());
|
||||||
|
Assert.IsFalse(2.0f.IsOdd());
|
||||||
|
Assert.IsFalse(4.0f.IsOdd());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void IsOdd_ShouldBeTrue_GivenOddNumber()
|
||||||
|
{
|
||||||
|
Assert.IsTrue((-3.0f).IsOdd());
|
||||||
|
Assert.IsTrue((-1.0f).IsOdd());
|
||||||
|
Assert.IsTrue(1.0f.IsOdd());
|
||||||
|
Assert.IsTrue(3.0f.IsOdd());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Round_ShouldRoundToNearestInteger()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(4.0f, 3.5f.Round(), 1e-6f);
|
||||||
|
Assert.AreEqual(7.0f, 6.8f.Round(), 1e-6f);
|
||||||
|
Assert.AreEqual(7.0f, 7.2f.Round(), 1e-6f);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Round_ShouldRoundToNearestMultiple()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(5.0f, 3.5f.Round(5), 1e-6f);
|
||||||
|
Assert.AreEqual(5.0f, 7.0f.Round(5), 1e-6f);
|
||||||
|
Assert.AreEqual(10.0f, 7.5f.Round(5), 1e-6f);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Sign_ShouldBeMinus1_GivenNegative()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(-1, -1.0f.Sign());
|
||||||
|
Assert.AreEqual(-1, -2.0f.Sign());
|
||||||
|
Assert.AreEqual(-1, -3.0f.Sign());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Sign_ShouldBe0_Given0()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(0, 0.0f.Sign());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Sign_ShouldBe1_GivenPositive()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(1, 1.0f.Sign());
|
||||||
|
Assert.AreEqual(1, 2.0f.Sign());
|
||||||
|
Assert.AreEqual(1, 3.0f.Sign());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Sqrt_ShouldBeCorrect_GivenValue()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(0.0f, 0.0f.Sqrt(), 1e-6f);
|
||||||
|
Assert.AreEqual(1.4142135f, 2.0f.Sqrt(), 1e-6f);
|
||||||
|
Assert.AreEqual(3.0f, 9.0f.Sqrt(), 1e-6f);
|
||||||
|
Assert.AreEqual(4.0f, 16.0f.Sqrt(), 1e-6f);
|
||||||
|
Assert.AreEqual(100.0f, 10000.0f.Sqrt(), 1e-6f);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Sqrt_ShouldBeNaN_GivenNaN()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(float.NaN, float.NaN.Sqrt());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Sqrt_ShouldBeNaN_GivenNegativeValue()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(float.NaN, (-1.0f).Sqrt());
|
||||||
|
Assert.AreEqual(float.NaN, (-2.0f).Sqrt());
|
||||||
|
Assert.AreEqual(float.NaN, (-3.0f).Sqrt());
|
||||||
|
Assert.AreEqual(float.NaN, float.NegativeInfinity.Sqrt());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Sqrt_ShouldBePositiveInfinity_GivenPositiveInfinity()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(float.PositiveInfinity, float.PositiveInfinity.Sqrt());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Acos_ShouldBeCorrect()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(1.0471975803375244f, 0.5f.Acos(), 1e-6f);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Acosh_ShouldBeCorrect()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(0.9624236822128296f, 1.5f.Acosh(), 1e-6f);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Asin_ShouldBeCorrect()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(0.5235987901687622f, 0.5f.Asin(), 1e-6f);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Asinh_ShouldBeCorrect()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(1.19476318359375f, 1.5f.Asinh(), 1e-6f);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Atan_ShouldBeCorrect()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(0.46364760398864746, 0.5f.Atan(), 1e-6f);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Atanh_ShouldBeCorrect()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(0.5493061542510986f, 0.5f.Atanh(), 1e-6f);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Cos_ShouldBeCorrect()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(0.8775825500488281f, 0.5f.Cos(), 1e-6f);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Cosh_ShouldBeCorrect()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(2.352409601211548f, 1.5f.Cosh(), 1e-6f);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Sin_ShouldBeCorrect()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(0.4794255495071411, 0.5f.Sin(), 1e-6f);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Sinh_ShouldBeCorrect()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(2.129279375076294f, 1.5f.Sinh(), 1e-6f);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Tan_ShouldBeCorrect()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(0.4794255495071411f, 0.5f.Tan(), 1e-6f);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Tanh_ShouldBeCorrect()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(0.46211716532707214f, 0.5f.Tanh(), 1e-6f);
|
||||||
|
}
|
||||||
|
}
|
65
X10D.Tests/src/Math/UInt16Tests.cs
Normal file
65
X10D.Tests/src/Math/UInt16Tests.cs
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Math;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Math;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
[CLSCompliant(false)]
|
||||||
|
public class UInt16Tests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void DigitalRootShouldBeCorrect()
|
||||||
|
{
|
||||||
|
const ushort value = 238;
|
||||||
|
Assert.AreEqual(4, value.DigitalRoot());
|
||||||
|
Assert.AreEqual(4, (-value).DigitalRoot());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void FactorialShouldBeCorrect()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(1UL, ((ushort)0).Factorial());
|
||||||
|
Assert.AreEqual(1UL, ((ushort)1).Factorial());
|
||||||
|
Assert.AreEqual(2UL, ((ushort)2).Factorial());
|
||||||
|
Assert.AreEqual(6UL, ((ushort)3).Factorial());
|
||||||
|
Assert.AreEqual(24UL, ((ushort)4).Factorial());
|
||||||
|
Assert.AreEqual(120UL, ((ushort)5).Factorial());
|
||||||
|
Assert.AreEqual(720UL, ((ushort)6).Factorial());
|
||||||
|
Assert.AreEqual(5040UL, ((ushort)7).Factorial());
|
||||||
|
Assert.AreEqual(40320UL, ((ushort)8).Factorial());
|
||||||
|
Assert.AreEqual(362880UL, ((ushort)9).Factorial());
|
||||||
|
Assert.AreEqual(3628800UL, ((ushort)10).Factorial());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void IsEvenShouldBeCorrect()
|
||||||
|
{
|
||||||
|
const ushort one = 1;
|
||||||
|
const ushort two = 2;
|
||||||
|
|
||||||
|
Assert.IsFalse(one.IsEven());
|
||||||
|
Assert.IsTrue(two.IsEven());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void IsOddShouldBeCorrect()
|
||||||
|
{
|
||||||
|
const ushort one = 1;
|
||||||
|
const ushort two = 2;
|
||||||
|
|
||||||
|
Assert.IsTrue(one.IsOdd());
|
||||||
|
Assert.IsFalse(two.IsOdd());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void MultiplicativePersistence_ShouldBeCorrect_ForRecordHolders()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(0, ((ushort)0).MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(1, ((ushort)10).MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(2, ((ushort)25).MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(3, ((ushort)39).MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(4, ((ushort)77).MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(5, ((ushort)679).MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(6, ((ushort)6788).MultiplicativePersistence());
|
||||||
|
}
|
||||||
|
}
|
69
X10D.Tests/src/Math/UInt32Tests.cs
Normal file
69
X10D.Tests/src/Math/UInt32Tests.cs
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Math;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Math;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
[CLSCompliant(false)]
|
||||||
|
public class UInt32Tests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void DigitalRootShouldBeCorrect()
|
||||||
|
{
|
||||||
|
const uint value = 238;
|
||||||
|
Assert.AreEqual(4U, value.DigitalRoot());
|
||||||
|
Assert.AreEqual(4U, (-value).DigitalRoot());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void FactorialShouldBeCorrect()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(1UL, 0U.Factorial());
|
||||||
|
Assert.AreEqual(1UL, 1U.Factorial());
|
||||||
|
Assert.AreEqual(2UL, 2U.Factorial());
|
||||||
|
Assert.AreEqual(6UL, 3U.Factorial());
|
||||||
|
Assert.AreEqual(24UL, 4U.Factorial());
|
||||||
|
Assert.AreEqual(120UL, 5U.Factorial());
|
||||||
|
Assert.AreEqual(720UL, 6U.Factorial());
|
||||||
|
Assert.AreEqual(5040UL, 7U.Factorial());
|
||||||
|
Assert.AreEqual(40320UL, 8U.Factorial());
|
||||||
|
Assert.AreEqual(362880UL, 9U.Factorial());
|
||||||
|
Assert.AreEqual(3628800UL, 10U.Factorial());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void IsEvenShouldBeCorrect()
|
||||||
|
{
|
||||||
|
const uint one = 1;
|
||||||
|
const uint two = 2;
|
||||||
|
|
||||||
|
Assert.IsFalse(one.IsEven());
|
||||||
|
Assert.IsTrue(two.IsEven());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void IsOddShouldBeCorrect()
|
||||||
|
{
|
||||||
|
const uint one = 1;
|
||||||
|
const uint two = 2;
|
||||||
|
|
||||||
|
Assert.IsTrue(one.IsOdd());
|
||||||
|
Assert.IsFalse(two.IsOdd());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void MultiplicativePersistence_ShouldBeCorrect_ForRecordHolders()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(0, 0U.MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(1, 10U.MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(2, 25U.MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(3, 39U.MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(4, 77U.MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(5, 679U.MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(6, 6788U.MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(7, 68889U.MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(8, 2677889U.MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(9, 26888999U.MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(10, 3778888999U.MultiplicativePersistence());
|
||||||
|
}
|
||||||
|
}
|
74
X10D.Tests/src/Math/UInt64Tests.cs
Normal file
74
X10D.Tests/src/Math/UInt64Tests.cs
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Math;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Math;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
[CLSCompliant(false)]
|
||||||
|
public class UInt64Tests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void DigitalRootShouldBeCorrect()
|
||||||
|
{
|
||||||
|
const ulong value = 238;
|
||||||
|
Assert.AreEqual(4U, value.DigitalRoot());
|
||||||
|
|
||||||
|
// -ulong operator not defined because it might exceed long.MinValue,
|
||||||
|
// so instead, cast to long and then negate.
|
||||||
|
// HAX.
|
||||||
|
Assert.AreEqual(4U, (-(long)value).DigitalRoot());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void FactorialShouldBeCorrect()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(1UL, 0UL.Factorial());
|
||||||
|
Assert.AreEqual(1UL, 1UL.Factorial());
|
||||||
|
Assert.AreEqual(2UL, 2UL.Factorial());
|
||||||
|
Assert.AreEqual(6UL, 3UL.Factorial());
|
||||||
|
Assert.AreEqual(24UL, 4UL.Factorial());
|
||||||
|
Assert.AreEqual(120UL, 5UL.Factorial());
|
||||||
|
Assert.AreEqual(720UL, 6UL.Factorial());
|
||||||
|
Assert.AreEqual(5040UL, 7UL.Factorial());
|
||||||
|
Assert.AreEqual(40320UL, 8UL.Factorial());
|
||||||
|
Assert.AreEqual(362880UL, 9UL.Factorial());
|
||||||
|
Assert.AreEqual(3628800UL, 10UL.Factorial());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void IsEvenShouldBeCorrect()
|
||||||
|
{
|
||||||
|
const ulong one = 1;
|
||||||
|
const ulong two = 2;
|
||||||
|
|
||||||
|
Assert.IsFalse(one.IsEven());
|
||||||
|
Assert.IsTrue(two.IsEven());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void IsOddShouldBeCorrect()
|
||||||
|
{
|
||||||
|
const ulong one = 1;
|
||||||
|
const ulong two = 2;
|
||||||
|
|
||||||
|
Assert.IsTrue(one.IsOdd());
|
||||||
|
Assert.IsFalse(two.IsOdd());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void MultiplicativePersistence_ShouldBeCorrect_ForRecordHolders()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(0, 0UL.MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(1, 10UL.MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(2, 25UL.MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(3, 39UL.MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(4, 77UL.MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(5, 679UL.MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(6, 6788UL.MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(7, 68889UL.MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(8, 2677889UL.MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(9, 26888999UL.MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(10, 3778888999UL.MultiplicativePersistence());
|
||||||
|
Assert.AreEqual(11, 277777788888899UL.MultiplicativePersistence());
|
||||||
|
}
|
||||||
|
}
|
76
X10D.Tests/src/Net/EndPointTests.cs
Normal file
76
X10D.Tests/src/Net/EndPointTests.cs
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
using System.Net;
|
||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Net;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Net;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class EndPointTests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void GetHost_ShouldBeLocalhost_GivenLocalhostDnsEndPoint()
|
||||||
|
{
|
||||||
|
var endPoint = new DnsEndPoint("localhost", 1234);
|
||||||
|
Assert.AreEqual("localhost", endPoint.GetHost());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void GetHost_ShouldBe127001_GivenLoopbackIPEndPoint()
|
||||||
|
{
|
||||||
|
var endPoint = new IPEndPoint(IPAddress.Loopback, 1234);
|
||||||
|
Assert.AreEqual("127.0.0.1", endPoint.GetHost());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void GetHost_ShouldBeColonColon1_GivenIPv6LoopBackIPEndPoint()
|
||||||
|
{
|
||||||
|
var endPoint = new IPEndPoint(IPAddress.IPv6Loopback, 1234);
|
||||||
|
Assert.AreEqual("::1", endPoint.GetHost());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void GetHost_ShouldThrow_GivenNull()
|
||||||
|
{
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => ((IPEndPoint?)null)!.GetHost());
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => ((DnsEndPoint?)null)!.GetHost());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void GetPort_ShouldBe1234_Given1234IPEndPoint()
|
||||||
|
{
|
||||||
|
var endPoint = new IPEndPoint(IPAddress.Loopback, 1234);
|
||||||
|
Assert.AreEqual(1234, endPoint.GetPort());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void GetPort_ShouldBe1234_Given1234DnsEndPoint()
|
||||||
|
{
|
||||||
|
var endPoint = new DnsEndPoint("localhost", 1234);
|
||||||
|
Assert.AreEqual(1234, endPoint.GetPort());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void GetPort_ShouldThrow_GivenNull()
|
||||||
|
{
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => ((IPEndPoint?)null)!.GetPort());
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => ((DnsEndPoint?)null)!.GetPort());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void GetHost_ShouldBeEmpty_GivenInvalidEndPoint()
|
||||||
|
{
|
||||||
|
var endPoint = new DummyEndPoint();
|
||||||
|
Assert.AreEqual(string.Empty, endPoint.GetHost());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void GetPort_ShouldBe0_GivenInvalidEndPoint()
|
||||||
|
{
|
||||||
|
var endPoint = new DummyEndPoint();
|
||||||
|
Assert.AreEqual(0, endPoint.GetPort());
|
||||||
|
}
|
||||||
|
|
||||||
|
private class DummyEndPoint : EndPoint
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
43
X10D.Tests/src/Net/IPAddressTests.cs
Normal file
43
X10D.Tests/src/Net/IPAddressTests.cs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
using System.Net;
|
||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Net;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Net;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class IPAddressTests
|
||||||
|
{
|
||||||
|
private IPAddress _ipv4Address = null!;
|
||||||
|
private IPAddress _ipv6Address = null!;
|
||||||
|
|
||||||
|
[TestInitialize]
|
||||||
|
public void Initialize()
|
||||||
|
{
|
||||||
|
_ipv4Address = IPAddress.Parse("127.0.0.1");
|
||||||
|
_ipv6Address = IPAddress.Parse("::1");
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void IsIPv4_ShouldBeTrue_GivenIPv4()
|
||||||
|
{
|
||||||
|
Assert.IsTrue(_ipv4Address.IsIPv4());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void IsIPv4_ShouldBeFalse_GivenIPv6()
|
||||||
|
{
|
||||||
|
Assert.IsFalse(_ipv6Address.IsIPv4());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void IsIPv6_ShouldBeFalse_GivenIPv4()
|
||||||
|
{
|
||||||
|
Assert.IsFalse(_ipv4Address.IsIPv6());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void IsIPv6_ShouldBeTrue_GivenIPv6()
|
||||||
|
{
|
||||||
|
Assert.IsTrue(_ipv6Address.IsIPv6());
|
||||||
|
}
|
||||||
|
}
|
26
X10D.Tests/src/Net/Int16Tests.cs
Normal file
26
X10D.Tests/src/Net/Int16Tests.cs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Net;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Net;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class Int16Tests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void HostToNetworkOrder_ReturnsCorrectValue()
|
||||||
|
{
|
||||||
|
const short hostOrder = 0x0102;
|
||||||
|
const short networkOrder = 0x0201;
|
||||||
|
|
||||||
|
Assert.AreEqual(BitConverter.IsLittleEndian ? networkOrder : hostOrder, hostOrder.HostToNetworkOrder());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NetworkToHostOrder_ReturnsCorrectValue()
|
||||||
|
{
|
||||||
|
const short hostOrder = 0x0102;
|
||||||
|
const short networkOrder = 0x0201;
|
||||||
|
|
||||||
|
Assert.AreEqual(BitConverter.IsLittleEndian ? hostOrder : networkOrder, networkOrder.NetworkToHostOrder());
|
||||||
|
}
|
||||||
|
}
|
26
X10D.Tests/src/Net/Int32Tests.cs
Normal file
26
X10D.Tests/src/Net/Int32Tests.cs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Net;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Net;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class Int32Tests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void HostToNetworkOrder_ReturnsCorrectValue()
|
||||||
|
{
|
||||||
|
const int hostOrder = 0x01020304;
|
||||||
|
const int networkOrder = 0x04030201;
|
||||||
|
|
||||||
|
Assert.AreEqual(BitConverter.IsLittleEndian ? networkOrder : hostOrder, hostOrder.HostToNetworkOrder());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NetworkToHostOrder_ReturnsCorrectValue()
|
||||||
|
{
|
||||||
|
const int hostOrder = 0x01020304;
|
||||||
|
const int networkOrder = 0x04030201;
|
||||||
|
|
||||||
|
Assert.AreEqual(BitConverter.IsLittleEndian ? hostOrder : networkOrder, networkOrder.NetworkToHostOrder());
|
||||||
|
}
|
||||||
|
}
|
26
X10D.Tests/src/Net/Int64Tests.cs
Normal file
26
X10D.Tests/src/Net/Int64Tests.cs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Net;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Net;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class Int64Tests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void HostToNetworkOrder_ReturnsCorrectValue()
|
||||||
|
{
|
||||||
|
const long hostOrder = 0x0102030405060708;
|
||||||
|
const long networkOrder = 0x0807060504030201;
|
||||||
|
|
||||||
|
Assert.AreEqual(BitConverter.IsLittleEndian ? networkOrder : hostOrder, hostOrder.HostToNetworkOrder());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NetworkToHostOrder_ReturnsCorrectValue()
|
||||||
|
{
|
||||||
|
const long hostOrder = 0x0102030405060708;
|
||||||
|
const long networkOrder = 0x0807060504030201;
|
||||||
|
|
||||||
|
Assert.AreEqual(BitConverter.IsLittleEndian ? hostOrder : networkOrder, networkOrder.NetworkToHostOrder());
|
||||||
|
}
|
||||||
|
}
|
42
X10D.Tests/src/Numerics/ByteTests.cs
Normal file
42
X10D.Tests/src/Numerics/ByteTests.cs
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Numerics;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Numerics;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class ByteTests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void RotateLeft_ShouldRotateCorrectly()
|
||||||
|
{
|
||||||
|
const byte value = 181; // 10110101
|
||||||
|
const byte expected = 91; // 01011011
|
||||||
|
|
||||||
|
Assert.AreEqual(value, value.RotateLeft(0));
|
||||||
|
Assert.AreEqual(expected, value.RotateLeft(4));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void RotateLeft_ShouldModForLargeCount()
|
||||||
|
{
|
||||||
|
const byte value = 181; // 10110101
|
||||||
|
Assert.AreEqual(value, value.RotateLeft(8));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void RotateRight_ShouldRotateCorrectly()
|
||||||
|
{
|
||||||
|
const byte value = 181; // 10110101
|
||||||
|
const byte expected = 91; // 01011011
|
||||||
|
|
||||||
|
Assert.AreEqual(value, value.RotateRight(0));
|
||||||
|
Assert.AreEqual(expected, value.RotateRight(4));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void RotateRight_ShouldModForLargeCount()
|
||||||
|
{
|
||||||
|
const byte value = 181; // 10110101
|
||||||
|
Assert.AreEqual(value, value.RotateRight(8));
|
||||||
|
}
|
||||||
|
}
|
44
X10D.Tests/src/Numerics/Int16Tests.cs
Normal file
44
X10D.Tests/src/Numerics/Int16Tests.cs
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Numerics;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Numerics;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class Int16Tests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void RotateLeft_ShouldRotateCorrectly()
|
||||||
|
{
|
||||||
|
const short value = 2896; // 00001011 01010000
|
||||||
|
const short expected = 27137; // 01101010 00000001
|
||||||
|
|
||||||
|
Assert.AreEqual(value, value.RotateLeft(0));
|
||||||
|
Assert.AreEqual(expected, value.RotateLeft(5));
|
||||||
|
Assert.AreEqual(value, value.RotateLeft(16));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void RotateLeft_ShouldModForLargeCount()
|
||||||
|
{
|
||||||
|
const short value = 2896; // 00001011 01010000
|
||||||
|
Assert.AreEqual(value, value.RotateLeft(16));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void RotateRight_ShouldRotateCorrectly()
|
||||||
|
{
|
||||||
|
const short value = 2896; // 00001011 01010000
|
||||||
|
const short expected = -32678; // 01111111 10100110
|
||||||
|
|
||||||
|
Assert.AreEqual(value, value.RotateRight(0));
|
||||||
|
Assert.AreEqual(expected, value.RotateRight(5));
|
||||||
|
Assert.AreEqual(value, value.RotateRight(16));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void RotateRight_ShouldModForLargeCount()
|
||||||
|
{
|
||||||
|
const short value = 2896; // 00001011 01010000
|
||||||
|
Assert.AreEqual(value, value.RotateRight(16));
|
||||||
|
}
|
||||||
|
}
|
42
X10D.Tests/src/Numerics/Int32Tests.cs
Normal file
42
X10D.Tests/src/Numerics/Int32Tests.cs
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Numerics;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Numerics;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class Int32Tests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void RotateLeft_ShouldRotateCorrectly()
|
||||||
|
{
|
||||||
|
const int value = 284719; // 00000000 00000100 01011000 00101111
|
||||||
|
const int expected = -1336016888; // 10110000 01011110 00000000 00001000
|
||||||
|
|
||||||
|
Assert.AreEqual(value, value.RotateLeft(0));
|
||||||
|
Assert.AreEqual(expected, value.RotateLeft(17));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void RotateLeft_ShouldModForLargeCount()
|
||||||
|
{
|
||||||
|
const int value = 284719; // 00000000 00000100 01011000 00101111
|
||||||
|
Assert.AreEqual(value, value.RotateLeft(32));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void RotateRight_ShouldRotateCorrectly()
|
||||||
|
{
|
||||||
|
const int value = 284719; // 00000000 00000100 01011000 00101111
|
||||||
|
const int expected = 739737602; // 00101100 00010111 10000000 00000010
|
||||||
|
|
||||||
|
Assert.AreEqual(value, value.RotateRight(0));
|
||||||
|
Assert.AreEqual(expected, value.RotateRight(17));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void RotateRight_ShouldModForLargeCount()
|
||||||
|
{
|
||||||
|
const int value = 284719; // 00000000 00000100 01011000 00101111
|
||||||
|
Assert.AreEqual(value, value.RotateRight(32));
|
||||||
|
}
|
||||||
|
}
|
42
X10D.Tests/src/Numerics/Int64Tests.cs
Normal file
42
X10D.Tests/src/Numerics/Int64Tests.cs
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Numerics;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Numerics;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class Int64Tests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void RotateLeft_ShouldRotateCorrectly()
|
||||||
|
{
|
||||||
|
const long value = 5972019251303316844; // 01010010 11100000 11011111 11011110 00110001 10111010 01111101 01101100
|
||||||
|
const long expected = -1588168355691398970; // 11101001 11110101 10110001 01001011 10000011 01111111 01111000 11000110
|
||||||
|
|
||||||
|
Assert.AreEqual(value, value.RotateLeft(0));
|
||||||
|
Assert.AreEqual(expected, value.RotateLeft(42));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void RotateLeft_ShouldModForLargeCount()
|
||||||
|
{
|
||||||
|
const long value = 5972019251303316844; // 01010010 11100000 11011111 11011110 00110001 10111010 01111101 01101100
|
||||||
|
Assert.AreEqual(value, value.RotateLeft(64));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void RotateRight_ShouldRotateCorrectly()
|
||||||
|
{
|
||||||
|
const long value = 5972019251303316844; // 01010010 11100000 11011111 11011110 00110001 10111010 01111101 01101100
|
||||||
|
const long expected = -608990218894919625; // 11110111 10001100 01101110 10011111 01011011 00010100 10111000 00110111
|
||||||
|
|
||||||
|
Assert.AreEqual(value, value.RotateRight(0));
|
||||||
|
Assert.AreEqual(expected, value.RotateRight(42));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void RotateRight_ShouldModForLargeCount()
|
||||||
|
{
|
||||||
|
const long value = 5972019251303316844; // 01010010 11100000 11011111 11011110 00110001 10111010 01111101 01101100
|
||||||
|
Assert.AreEqual(value, value.RotateRight(64));
|
||||||
|
}
|
||||||
|
}
|
68
X10D.Tests/src/Numerics/RandomTests.cs
Normal file
68
X10D.Tests/src/Numerics/RandomTests.cs
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Numerics;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Numerics;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class RandomTests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void NextUnitVector2_ShouldReturnVector_WithMagnitude1()
|
||||||
|
{
|
||||||
|
var random = new Random();
|
||||||
|
var vector = random.NextUnitVector2();
|
||||||
|
Assert.AreEqual(1, vector.Length(), 1e-6);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NextUnitVector2_ShouldThrow_GivenNullRandom()
|
||||||
|
{
|
||||||
|
Random? random = null;
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => random!.NextUnitVector2());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NextUnitVector3_ShouldReturnVector_WithMagnitude1()
|
||||||
|
{
|
||||||
|
var random = new Random();
|
||||||
|
var vector = random.NextUnitVector3();
|
||||||
|
Assert.AreEqual(1, vector.Length(), 1e-6);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NextUnitVector3_ShouldThrow_GivenNullRandom()
|
||||||
|
{
|
||||||
|
Random? random = null;
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => random!.NextUnitVector3());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NextRotation_ShouldReturnQuaternion_WithMagnitude1()
|
||||||
|
{
|
||||||
|
var random = new Random();
|
||||||
|
var rotation = random.NextRotation();
|
||||||
|
Assert.AreEqual(1, rotation.Length(), 1e-6);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NextRotation_ShouldThrow_GivenNullRandom()
|
||||||
|
{
|
||||||
|
Random? random = null;
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => random!.NextRotation());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NextRotationUniform_ShouldReturnQuaternion_WithMagnitude1()
|
||||||
|
{
|
||||||
|
var random = new Random();
|
||||||
|
var rotation = random.NextRotationUniform();
|
||||||
|
Assert.AreEqual(1, rotation.Length(), 1e-6);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NextRotationUniform_ShouldThrow_GivenNullRandom()
|
||||||
|
{
|
||||||
|
Random? random = null;
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => random!.NextRotationUniform());
|
||||||
|
}
|
||||||
|
}
|
43
X10D.Tests/src/Numerics/SByteTests.cs
Normal file
43
X10D.Tests/src/Numerics/SByteTests.cs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Numerics;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Numerics;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
[CLSCompliant(false)]
|
||||||
|
public class SByteTests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void RotateLeft_ShouldRotateCorrectly()
|
||||||
|
{
|
||||||
|
const sbyte value = 117; // 01110101
|
||||||
|
const sbyte expected = 87; // 01010111
|
||||||
|
|
||||||
|
Assert.AreEqual(value, value.RotateLeft(0));
|
||||||
|
Assert.AreEqual(expected, value.RotateLeft(4));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void RotateLeft_ShouldModForLargeCount()
|
||||||
|
{
|
||||||
|
const sbyte value = 117; // 01110101
|
||||||
|
Assert.AreEqual(value, value.RotateLeft(8));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void RotateRight_ShouldRotateCorrectly()
|
||||||
|
{
|
||||||
|
const sbyte value = 117; // 01110101
|
||||||
|
const sbyte expected = 87; // 01010111
|
||||||
|
|
||||||
|
Assert.AreEqual(value, value.RotateRight(0));
|
||||||
|
Assert.AreEqual(expected, value.RotateRight(4));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void RotateRight_ShouldModForLargeCount()
|
||||||
|
{
|
||||||
|
const sbyte value = 117; // 01110101
|
||||||
|
Assert.AreEqual(value, value.RotateRight(8));
|
||||||
|
}
|
||||||
|
}
|
45
X10D.Tests/src/Numerics/UInt16Tests.cs
Normal file
45
X10D.Tests/src/Numerics/UInt16Tests.cs
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Numerics;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Numerics;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
[CLSCompliant(false)]
|
||||||
|
public class UInt16Tests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void RotateLeft_ShouldRotateCorrectly()
|
||||||
|
{
|
||||||
|
const ushort value = 2896; // 00001011 01010000
|
||||||
|
const ushort expected = 27137; // 01101010 00000001
|
||||||
|
|
||||||
|
Assert.AreEqual(value, value.RotateLeft(0));
|
||||||
|
Assert.AreEqual(expected, value.RotateLeft(5));
|
||||||
|
Assert.AreEqual(value, value.RotateLeft(16));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void RotateLeft_ShouldModForLargeCount()
|
||||||
|
{
|
||||||
|
const ushort value = 2896; // 00001011 01010000
|
||||||
|
Assert.AreEqual(value, value.RotateLeft(16));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void RotateRight_ShouldRotateCorrectly()
|
||||||
|
{
|
||||||
|
const ushort value = 2896; // 00001011 01010000
|
||||||
|
const ushort expected = 32858; // 10000000 01011010
|
||||||
|
|
||||||
|
Assert.AreEqual(value, value.RotateRight(0));
|
||||||
|
Assert.AreEqual(expected, value.RotateRight(5));
|
||||||
|
Assert.AreEqual(value, value.RotateRight(16));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void RotateRight_ShouldModForLargeCount()
|
||||||
|
{
|
||||||
|
const ushort value = 2896; // 00001011 01010000
|
||||||
|
Assert.AreEqual(value, value.RotateRight(16));
|
||||||
|
}
|
||||||
|
}
|
43
X10D.Tests/src/Numerics/UInt32Tests.cs
Normal file
43
X10D.Tests/src/Numerics/UInt32Tests.cs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Numerics;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Numerics;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
[CLSCompliant(false)]
|
||||||
|
public class UInt32Tests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void RotateLeft_ShouldRotateCorrectly()
|
||||||
|
{
|
||||||
|
const uint value = 284719; // 00000000 00000100 01011000 00101111
|
||||||
|
const uint expected = 2958950408; // 10110000 01011110 00000000 00001000
|
||||||
|
|
||||||
|
Assert.AreEqual(value, value.RotateLeft(0));
|
||||||
|
Assert.AreEqual(expected, value.RotateLeft(17));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void RotateLeft_ShouldModForLargeCount()
|
||||||
|
{
|
||||||
|
const uint value = 284719; // 00000000 00000100 01011000 00101111
|
||||||
|
Assert.AreEqual(value, value.RotateLeft(32));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void RotateRight_ShouldRotateCorrectly()
|
||||||
|
{
|
||||||
|
const uint value = 284719; // 00000000 00000100 01011000 00101111
|
||||||
|
const uint expected = 739737602; // 00101100 00010111 10000000 00000010
|
||||||
|
|
||||||
|
Assert.AreEqual(value, value.RotateRight(0));
|
||||||
|
Assert.AreEqual(expected, value.RotateRight(17));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void RotateRight_ShouldModForLargeCount()
|
||||||
|
{
|
||||||
|
const uint value = 284719; // 00000000 00000100 01011000 00101111
|
||||||
|
Assert.AreEqual(value, value.RotateRight(32));
|
||||||
|
}
|
||||||
|
}
|
43
X10D.Tests/src/Numerics/UInt64Tests.cs
Normal file
43
X10D.Tests/src/Numerics/UInt64Tests.cs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Numerics;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Numerics;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
[CLSCompliant(false)]
|
||||||
|
public class UInt64Tests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void RotateLeft_ShouldRotateCorrectly()
|
||||||
|
{
|
||||||
|
const ulong value = 5972019251303316844; // 01010010 11100000 11011111 11011110 00110001 10111010 01111101 01101100
|
||||||
|
const ulong expected = 16858575718018152646; // 11101001 11110101 10110001 01001011 10000011 01111111 01111000 11000110
|
||||||
|
|
||||||
|
Assert.AreEqual(value, value.RotateLeft(0));
|
||||||
|
Assert.AreEqual(expected, value.RotateLeft(42));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void RotateLeft_ShouldModForLargeCount()
|
||||||
|
{
|
||||||
|
const ulong value = 5972019251303316844; // 01010010 11100000 11011111 11011110 00110001 10111010 01111101 01101100
|
||||||
|
Assert.AreEqual(value, value.RotateLeft(64));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void RotateRight_ShouldRotateCorrectly()
|
||||||
|
{
|
||||||
|
const ulong value = 5972019251303316844; // 01010010 11100000 11011111 11011110 00110001 10111010 01111101 01101100
|
||||||
|
const ulong expected = 17837753854814631991; // 11110111 10001100 01101110 10011111 01011011 00010100 10111000 00110111
|
||||||
|
|
||||||
|
Assert.AreEqual(value, value.RotateRight(0));
|
||||||
|
Assert.AreEqual(expected, value.RotateRight(42));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void RotateRight_ShouldModForLargeCount()
|
||||||
|
{
|
||||||
|
const ulong value = 5972019251303316844; // 01010010 11100000 11011111 11011110 00110001 10111010 01111101 01101100
|
||||||
|
Assert.AreEqual(value, value.RotateRight(64));
|
||||||
|
}
|
||||||
|
}
|
78
X10D.Tests/src/Reflection/MemberInfoTests.cs
Normal file
78
X10D.Tests/src/Reflection/MemberInfoTests.cs
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Reflection;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Reflection;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class MemberInfoTests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void HasCustomAttribute_ShouldBeTrue_GivenCLSCompliantAttributeOnUnsignedTypes()
|
||||||
|
{
|
||||||
|
Assert.IsTrue(typeof(sbyte).HasCustomAttribute(typeof(CLSCompliantAttribute))); // okay, sbyte is signed. I know.
|
||||||
|
Assert.IsTrue(typeof(ushort).HasCustomAttribute(typeof(CLSCompliantAttribute)));
|
||||||
|
Assert.IsTrue(typeof(uint).HasCustomAttribute(typeof(CLSCompliantAttribute)));
|
||||||
|
Assert.IsTrue(typeof(ulong).HasCustomAttribute(typeof(CLSCompliantAttribute)));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void HasCustomAttribute_ShouldBeTrue_GivenCLSCompliantAttributeOnUnsignedTypes_Generic()
|
||||||
|
{
|
||||||
|
Assert.IsTrue(typeof(sbyte).HasCustomAttribute<CLSCompliantAttribute>()); // okay, sbyte is signed. I know.
|
||||||
|
Assert.IsTrue(typeof(ushort).HasCustomAttribute<CLSCompliantAttribute>());
|
||||||
|
Assert.IsTrue(typeof(uint).HasCustomAttribute<CLSCompliantAttribute>());
|
||||||
|
Assert.IsTrue(typeof(ulong).HasCustomAttribute<CLSCompliantAttribute>());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void HasCustomAttribute_ShouldThrow_GivenNull()
|
||||||
|
{
|
||||||
|
Type? type = null;
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => type!.HasCustomAttribute<CLSCompliantAttribute>());
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => type!.HasCustomAttribute(typeof(CLSCompliantAttribute)));
|
||||||
|
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => typeof(object).HasCustomAttribute(null!));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void HasCustomAttribute_ShouldThrow_GivenNonAttribute()
|
||||||
|
{
|
||||||
|
Assert.ThrowsException<ArgumentException>(() => typeof(object).HasCustomAttribute(typeof(object)));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void SelectFromCustomAttribute_ShouldBeFalse_GivenCLSCompliantAttributeOnUnsignedTypes()
|
||||||
|
{
|
||||||
|
Assert.IsFalse(typeof(sbyte).SelectFromCustomAttribute((CLSCompliantAttribute attribute) => attribute.IsCompliant));
|
||||||
|
Assert.IsFalse(typeof(ushort).SelectFromCustomAttribute((CLSCompliantAttribute attribute) => attribute.IsCompliant));
|
||||||
|
Assert.IsFalse(typeof(uint).SelectFromCustomAttribute((CLSCompliantAttribute attribute) => attribute.IsCompliant));
|
||||||
|
Assert.IsFalse(typeof(ulong).SelectFromCustomAttribute((CLSCompliantAttribute attribute) => attribute.IsCompliant));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void SelectFromCustomAttribute_ShouldBeTrue_GivenCLSCompliantAttributeOnSignedTypes()
|
||||||
|
{
|
||||||
|
Assert.IsTrue(typeof(byte).SelectFromCustomAttribute((CLSCompliantAttribute attribute) => attribute.IsCompliant, true));
|
||||||
|
Assert.IsTrue(typeof(short).SelectFromCustomAttribute((CLSCompliantAttribute attribute) => attribute.IsCompliant, true));
|
||||||
|
Assert.IsTrue(typeof(int).SelectFromCustomAttribute((CLSCompliantAttribute attribute) => attribute.IsCompliant, true));
|
||||||
|
Assert.IsTrue(typeof(long).SelectFromCustomAttribute((CLSCompliantAttribute attribute) => attribute.IsCompliant, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void SelectFromCustomAttribute_ShouldThrow_GivenNull()
|
||||||
|
{
|
||||||
|
Type? type = null;
|
||||||
|
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() =>
|
||||||
|
(type!.SelectFromCustomAttribute((CLSCompliantAttribute attribute) => attribute.IsCompliant)));
|
||||||
|
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() =>
|
||||||
|
(type!.SelectFromCustomAttribute((CLSCompliantAttribute attribute) => attribute.IsCompliant, true)));
|
||||||
|
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() =>
|
||||||
|
{
|
||||||
|
Func<CLSCompliantAttribute, bool>? selector = null;
|
||||||
|
typeof(int).SelectFromCustomAttribute(selector!);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
59
X10D.Tests/src/Reflection/TypeTests.cs
Normal file
59
X10D.Tests/src/Reflection/TypeTests.cs
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Reflection;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Reflection;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class TypeTests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void Inherits_ShouldBeTrue_GivenStringInheritsObject()
|
||||||
|
{
|
||||||
|
Assert.IsTrue(typeof(string).Inherits(typeof(object)));
|
||||||
|
Assert.IsTrue(typeof(string).Inherits<object>());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Inherits_ShouldBeFalse_GivenObjectInheritsString()
|
||||||
|
{
|
||||||
|
Assert.IsFalse(typeof(object).Inherits(typeof(string)));
|
||||||
|
Assert.IsFalse(typeof(object).Inherits<string>());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Inherits_ShouldThrow_GivenValueType()
|
||||||
|
{
|
||||||
|
Assert.ThrowsException<ArgumentException>(() => typeof(int).Inherits(typeof(object)));
|
||||||
|
Assert.ThrowsException<ArgumentException>(() => typeof(object).Inherits(typeof(int)));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Inherits_ShouldThrow_GivenNull()
|
||||||
|
{
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => typeof(object).Inherits(null!));
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => ((Type?)null)!.Inherits(typeof(object)));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Implements_ShouldBeTrue_GivenInt32ImplementsIComparable()
|
||||||
|
{
|
||||||
|
Assert.IsTrue(typeof(int).Implements<IComparable>());
|
||||||
|
Assert.IsTrue(typeof(int).Implements<IComparable<int>>());
|
||||||
|
Assert.IsTrue(typeof(int).Implements(typeof(IComparable)));
|
||||||
|
Assert.IsTrue(typeof(int).Implements(typeof(IComparable<int>)));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Implements_ShouldThrow_GivenNull()
|
||||||
|
{
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => typeof(object).Implements(null!));
|
||||||
|
Assert.ThrowsException<ArgumentNullException>(() => ((Type?)null)!.Implements(typeof(object)));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Implements_ShouldThrow_GivenNonInterface()
|
||||||
|
{
|
||||||
|
Assert.ThrowsException<ArgumentException>(() => typeof(string).Implements<object>());
|
||||||
|
Assert.ThrowsException<ArgumentException>(() => typeof(string).Implements(typeof(object)));
|
||||||
|
}
|
||||||
|
}
|
37
X10D.Tests/src/Text/CharTests.cs
Normal file
37
X10D.Tests/src/Text/CharTests.cs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using X10D.Text;
|
||||||
|
|
||||||
|
namespace X10D.Tests.Text;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class CharTests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void RepeatShouldBeCorrect()
|
||||||
|
{
|
||||||
|
const string expected = "aaaaaaaaaa";
|
||||||
|
string actual = 'a'.Repeat(10);
|
||||||
|
|
||||||
|
Assert.AreEqual(expected, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void RepeatOneCountShouldBeLength1String()
|
||||||
|
{
|
||||||
|
string repeated = 'a'.Repeat(1);
|
||||||
|
Assert.AreEqual(1, repeated.Length);
|
||||||
|
Assert.AreEqual("a", repeated);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void RepeatZeroCountShouldBeEmpty()
|
||||||
|
{
|
||||||
|
Assert.AreEqual(string.Empty, 'a'.Repeat(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void RepeatNegativeCountShouldThrow()
|
||||||
|
{
|
||||||
|
Assert.ThrowsException<ArgumentOutOfRangeException>(() => 'a'.Repeat(-1));
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user