Compare commits

..

No commits in common. "master" and "2.0.0-preview1" have entirely different histories.

489 changed files with 7918 additions and 65582 deletions

114
.circleci/config.yml Normal file
View File

@ -0,0 +1,114 @@
version: 2.1
executors:
unity:
# https://hub.docker.com/r/gableroux/unity3d/tags
parameters:
version: {type: string}
docker:
- image: gableroux/unity3d:<< parameters.version >>
go:
docker:
- image: circleci/golang
commands:
unity_activate:
parameters:
unity_version: {type: string}
unity_license: {type: string}
steps:
# get activation file, if fail to activate unity, use this key and activate from https://license.unity3d.com/manual
- run: apt update && apt install libunwind8 -y
- run: /opt/Unity/Editor/Unity -quit -batchmode -nographics -logFile -createManualActivationFile || exit 0
- run: cat Unity_v<< parameters.unity_version >>.alf
# get from UNITY_LICENSE envvar(base64 encoded(cat foo.ulf | base64 )), this file is generated from above manual activation
- run: echo << parameters.unity_license >> | base64 -di >> .circleci/Unity.ulf
- run: /opt/Unity/Editor/Unity -quit -batchmode -nographics -silent-crashes -logFile -manualLicenseFile .circleci/Unity.ulf || exit 0
jobs:
build-and-test:
parameters:
unity_version: {type: string}
unity_license: {type: string}
executor:
name: unity
version: << parameters.unity_version >>
steps:
- checkout
- unity_activate:
unity_version: << parameters.unity_version >>
unity_license: << parameters.unity_license >>
- run:
name: Build Linux(Mono)
command: /opt/Unity/Editor/Unity -quit -batchmode -nographics -silent-crashes -logFile -projectPath . -executeMethod UnitTestBuilder.BuildUnitTest /headless /ScriptBackend Mono2x /BuildTarget StandaloneLinux64
working_directory: .
# TODO:check unity version and packages...
# - run: ./bin/UnitTest/StandaloneLinux64_Mono2x/test
build-and-create-package:
parameters:
unity_version: {type: string}
unity_license: {type: string}
executor:
name: unity
version: << parameters.unity_version >>
steps:
- checkout
- unity_activate:
unity_version: << parameters.unity_version >>
unity_license: << parameters.unity_license >>
- run:
name: Export unitypackage
command: /opt/Unity/Editor/Unity -quit -batchmode -nographics -silent-crashes -logFile -projectPath . -executeMethod PackageExporter.Export
working_directory: .
- store_artifacts:
path: ./UniRx.Async.unitypackage
destination: /UniRx.Async.unitypackage
# upload to github by ghr
upload-github:
executor: go
steps:
- attach_workspace:
at: .
- run: go get github.com/tcnksm/ghr
- run: ghr -t ${GITHUB_TOKEN} -u ${CIRCLE_PROJECT_USERNAME} -r ${CIRCLE_PROJECT_REPONAME} ${CIRCLE_TAG} .
- store_artifacts:
path: UniRx.Async.unitypackage
destination: UniRx.Async.unitypackage
workflows:
version: 2
build-unity:
jobs:
# does not exists yet.
# - build-and-test:
# unity_version: 2019.3.0a2
# unity_license: ${UNITY_LICENSE_2019_3}
# - build-and-test:
# unity_version: 2019.2.0b2
# unity_license: ${UNITY_LICENSE_2019_2}
- build-and-test:
unity_version: 2019.1.2f1
unity_license: ${UNITY_LICENSE_2019_1}
filters:
tags:
only: /.*/
# test asmdef will not found.
# - build-and-test:
# unity_version: 2018.4.0f1
# unity_license: ${UNITY_LICENSE_2018_4}
# # UniTask minimum support version is 2018.3(C# 7.x)
# - build-and-test:
# unity_version: 2018.3.12f1
# unity_license: ${UNITY_LICENSE_2018_3}
- build-and-create-package:
unity_version: 2019.1.2f1
unity_license: ${UNITY_LICENSE_2019_1}
filters:
tags:
only: /^\d\.\d\.\d.*/
branches:
ignore: /.*/
- upload-github:
requires:
- build-and-create-package
filters:
tags:
only: /^\d\.\d\.\d.*/
branches:
ignore: /.*/

View File

@ -1,41 +0,0 @@
# top-most EditorConfig file
root = true
[*]
charset = utf-8
end_of_line = lf
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true
# Visual Studio Spell checker configs (https://learn.microsoft.com/en-us/visualstudio/ide/text-spell-checker?view=vs-2022#how-to-customize-the-spell-checker)
spelling_exclusion_path = ./exclusion.dic
[*.cs]
indent_size = 4
charset = utf-8-bom
end_of_line = unset
# Solution files
[*.{sln,slnx}]
end_of_line = unset
# MSBuild project files
[*.{csproj,props,targets}]
end_of_line = unset
# Xml config files
[*.{ruleset,config,nuspec,resx,runsettings,DotSettings}]
end_of_line = unset
[*{_AssemblyInfo.cs,.notsupported.cs}]
generated_code = true
# C# code style settings
[*.{cs}]
dotnet_diagnostic.IDE0044.severity = none # IDE0044: Make field readonly
# https://stackoverflow.com/questions/79195382/how-to-disable-fading-unused-methods-in-visual-studio-2022-17-12-0
dotnet_diagnostic.IDE0051.severity = none # IDE0051: Remove unused private member
dotnet_diagnostic.IDE0130.severity = none # IDE0130: Namespace does not match folder structure

1
.github/FUNDING.yml vendored
View File

@ -1 +0,0 @@
github: [neuecc]

View File

@ -1,12 +0,0 @@
# ref: https://docs.github.com/en/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly" # Check for updates to GitHub Actions every week
ignore:
# I just want update action when major/minor version is updated. patch updates are too noisy.
- dependency-name: '*'
update-types:
- version-update:semver-patch

View File

@ -1,92 +0,0 @@
name: Build-Debug
on:
push:
branches:
- "master"
pull_request:
branches:
- "master"
jobs:
build-dotnet:
permissions:
contents: read
runs-on: ubuntu-24.04
timeout-minutes: 10
steps:
- uses: Cysharp/Actions/.github/actions/checkout@main
- uses: Cysharp/Actions/.github/actions/setup-dotnet@main
- run: dotnet build -c Debug
- run: dotnet test -c Debug
build-unity:
if: ${{ ((github.event_name == 'push' && github.repository_owner == 'Cysharp') || startsWith(github.event.pull_request.head.label, 'Cysharp:')) && github.triggering_actor != 'dependabot[bot]' }}
strategy:
fail-fast: false
max-parallel: 2
matrix:
unity: ["2022.3.39f1", "6000.0.12f1"] # Test with LTS
permissions:
contents: read
runs-on: ubuntu-24.04
timeout-minutes: 30 # Unity build takes more than 20min.
steps:
- name: Load secrets
id: op-load-secret
uses: 1password/load-secrets-action@581a835fb51b8e7ec56b71cf2ffddd7e68bb25e0 # v2.0.0
with:
export-env: false
env:
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN_PUBLIC }}
UNITY_EMAIL: "op://${{ vars.OP_VAULT_ACTIONS_PUBLIC }}/UNITY_LICENSE/username"
UNITY_PASSWORD: "op://${{ vars.OP_VAULT_ACTIONS_PUBLIC }}/UNITY_LICENSE/credential"
UNITY_SERIAL: "op://${{ vars.OP_VAULT_ACTIONS_PUBLIC }}/UNITY_LICENSE/serial"
- uses: Cysharp/Actions/.github/actions/checkout@main
# Execute scripts: Export Package
# /opt/Unity/Editor/Unity -quit -batchmode -nographics -silent-crashes -logFile -projectPath . -executeMethod PackageExporter.Export
- name: Build Unity (.unitypacakge)
if: ${{ startsWith(matrix.unity, '2022') }} # only execute once
uses: Cysharp/Actions/.github/actions/unity-builder@main
env:
UNITY_EMAIL: ${{ steps.op-load-secret.outputs.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ steps.op-load-secret.outputs.UNITY_PASSWORD }}
UNITY_SERIAL: ${{ steps.op-load-secret.outputs.UNITY_SERIAL }}
with:
projectPath: src/UniTask
unityVersion: ${{ matrix.unity }}
targetPlatform: StandaloneLinux64
buildMethod: PackageExporter.Export
# Execute UnitTest
# /opt/Unity/Editor/Unity -quit -batchmode -nographics -silent-crashes -logFile -projectPath . -executeMethod UnitTestBuilder.BuildUnitTest /headless /ScriptBackend IL2CPP /BuildTarget StandaloneLinux64
- name: Build UnitTest (IL2CPP)
uses: Cysharp/Actions/.github/actions/unity-builder@main
env:
UNITY_EMAIL: ${{ steps.op-load-secret.outputs.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ steps.op-load-secret.outputs.UNITY_PASSWORD }}
UNITY_SERIAL: ${{ steps.op-load-secret.outputs.UNITY_SERIAL }}
with:
projectPath: src/UniTask
unityVersion: ${{ matrix.unity }}
targetPlatform: StandaloneLinux64
buildMethod: UnitTestBuilder.BuildUnitTest
customParameters: "/headless /ScriptBackend IL2CPP"
- name: Check UnitTest file is generated
run: ls -lR ./src/UniTask/bin/UnitTest
- name: Execute UnitTest
run: ./src/UniTask/bin/UnitTest/StandaloneLinux64_IL2CPP/test
- uses: Cysharp/Actions/.github/actions/check-metas@main # check meta files
with:
directory: src/UniTask
# Store artifacts.
- uses: Cysharp/Actions/.github/actions/upload-artifact@main
if: ${{ startsWith(matrix.unity, '2021') }} # only execute 2021
with:
name: UniTask.unitypackage-${{ matrix.unity }}.zip
path: ./src/UniTask/*.unitypackage
retention-days: 1

View File

@ -1,34 +0,0 @@
name: build-docs
on:
push:
branches:
- master
- feature/docs
jobs:
run-docfx:
permissions:
contents: write
pages: write
runs-on: ubuntu-24.04
timeout-minutes: 10
steps:
- uses: Cysharp/Actions/.github/actions/checkout@main
- uses: Cysharp/Actions/.github/actions/checkout@main
with:
repository: Cysharp/DocfxTemplate
path: docs/_DocfxTemplate
- uses: Kirbyrawr/docfx-action@db9a22c8fe1e8693a2a21be54cb0b87dfaa72cc4
name: Docfx metadata
with:
args: metadata docs/docfx.json
- uses: Kirbyrawr/docfx-action@db9a22c8fe1e8693a2a21be54cb0b87dfaa72cc4
name: Docfx build
with:
args: build docs/docfx.json
- name: Publish to GitHub Pages
uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: docs/_site

View File

@ -1,121 +0,0 @@
name: build-release
on:
workflow_dispatch:
inputs:
tag:
description: "tag: git tag you want create. (sample 1.0.0)"
required: true
dry-run:
description: "dry-run: true will never create relase/nuget."
required: true
default: false
type: boolean
jobs:
update-packagejson:
permissions:
actions: read
contents: write
uses: Cysharp/Actions/.github/workflows/update-packagejson.yaml@main
with:
file-path: ./src/UniTask/Assets/Plugins/UniTask/package.json
tag: ${{ inputs.tag }}
dry-run: ${{ inputs.dry-run }}
build-dotnet:
needs: [update-packagejson]
permissions:
contents: read
runs-on: ubuntu-24.04
timeout-minutes: 10
steps:
- run: echo ${{ needs.update-packagejson.outputs.sha }}
- uses: Cysharp/Actions/.github/actions/checkout@main
with:
ref: ${{ needs.update-packagejson.outputs.sha }}
- uses: Cysharp/Actions/.github/actions/setup-dotnet@main
# build and pack
- run: dotnet build -c Release -p:Version=${{ inputs.tag }}
- run: dotnet test -c Release --no-build
- run: dotnet pack ./src/UniTask.NetCore/UniTask.NetCore.csproj -c Release --no-build -p:Version=${{ inputs.tag }} -o ./publish
# Store artifacts.
- uses: Cysharp/Actions/.github/actions/upload-artifact@main
with:
name: nuget
path: ./publish/
retention-days: 1
build-unity:
needs: [update-packagejson]
strategy:
matrix:
unity: ["2022.3.39f1"]
permissions:
contents: read
runs-on: ubuntu-24.04
timeout-minutes: 15
steps:
- name: Load secrets
id: op-load-secret
uses: 1password/load-secrets-action@581a835fb51b8e7ec56b71cf2ffddd7e68bb25e0 # v2.0.0
with:
export-env: false
env:
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN_PUBLIC }}
UNITY_EMAIL: "op://${{ vars.OP_VAULT_ACTIONS_PUBLIC }}/UNITY_LICENSE/username"
UNITY_PASSWORD: "op://${{ vars.OP_VAULT_ACTIONS_PUBLIC }}/UNITY_LICENSE/credential"
UNITY_SERIAL: "op://${{ vars.OP_VAULT_ACTIONS_PUBLIC }}/UNITY_LICENSE/serial"
- run: echo ${{ needs.update-packagejson.outputs.sha }}
- uses: Cysharp/Actions/.github/actions/checkout@main
with:
ref: ${{ needs.update-packagejson.outputs.sha }}
# Execute scripts: Export Package
# /opt/Unity/Editor/Unity -quit -batchmode -nographics -silent-crashes -logFile -projectPath . -executeMethod PackageExporter.Export
- name: Build Unity (.unitypacakge)
uses: Cysharp/Actions/.github/actions/unity-builder@main
env:
UNITY_EMAIL: ${{ steps.op-load-secret.outputs.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ steps.op-load-secret.outputs.UNITY_PASSWORD }}
UNITY_SERIAL: ${{ steps.op-load-secret.outputs.UNITY_SERIAL }}
with:
projectPath: src/UniTask
unityVersion: ${{ matrix.unity }}
targetPlatform: StandaloneLinux64
buildMethod: PackageExporter.Export
- uses: Cysharp/Actions/.github/actions/check-metas@main # check meta files
with:
directory: src/UniTask
# Store artifacts.
- uses: Cysharp/Actions/.github/actions/upload-artifact@main
with:
name: UniTask.${{ inputs.tag }}.unitypackage
path: ./src/UniTask/UniTask.${{ inputs.tag }}.unitypackage
retention-days: 1
# release
create-release:
needs: [update-packagejson, build-dotnet, build-unity]
permissions:
contents: write
uses: Cysharp/Actions/.github/workflows/create-release.yaml@main
with:
commit-id: ${{ needs.update-packagejson.outputs.sha }}
dry-run: ${{ inputs.dry-run }}
tag: ${{ inputs.tag }}
nuget-push: true
release-upload: true
release-asset-path: ./UniTask.${{ inputs.tag }}.unitypackage/UniTask.${{ inputs.tag }}.unitypackage
secrets: inherit
cleanup:
if: ${{ needs.update-packagejson.outputs.is-branch-created == 'true' }}
needs: [update-packagejson, build-dotnet, build-unity]
permissions:
contents: write
uses: Cysharp/Actions/.github/workflows/clean-packagejson-branch.yaml@main
with:
branch: ${{ needs.update-packagejson.outputs.branch-name }}

View File

@ -1,12 +0,0 @@
name: Prevent github change
on:
pull_request:
paths:
- ".github/**/*.yaml"
- ".github/**/*.yml"
jobs:
detect:
permissions:
contents: read
uses: Cysharp/Actions/.github/workflows/prevent-github-change.yaml@main

View File

@ -1,14 +0,0 @@
name: "Close stale issues"
on:
workflow_dispatch:
schedule:
- cron: "0 0 * * *"
jobs:
stale:
permissions:
contents: read
pull-requests: write
issues: write
uses: Cysharp/Actions/.github/workflows/stale-issue.yaml@main

View File

@ -1,15 +0,0 @@
name: TOC Generator
on:
push:
paths:
- 'README.md'
jobs:
toc:
permissions:
contents: write
uses: Cysharp/Actions/.github/workflows/toc-generator.yaml@main
with:
TOC_TITLE: "## Table of Contents"
secrets: inherit

35
.gitignore vendored
View File

@ -130,15 +130,28 @@ UpgradeLog*.XML
Assets/WSATestCertificate.pfx
.vs/
# Unity
Assembly-CSharp\.csproj
# Unity
.vsconfig
src/UniTask/Library/*
src/UniTask/Temp/*
src/UniTask/Logs/*
src/UniTask/[Uu]ser[Ss]ettings/
src/UniTask/*.sln
src/UniTask/*.csproj
src/UniTask/*.unitypackage
!src/UniTask/Packages/
UniRx\.Async\.csproj
UniRx\.Async\.Editor\.csproj
UniRx\.Async\.Tests\.csproj
UniTask\.sln
RuntimeUnitTestToolkit\.csproj
Assembly-CSharp-Editor\.csproj
UniRx\.Async\.unitypackage
UniRx.Async.Tests.Editor.csproj
src/UniTask/UniTask.csproj
src/UniTask/UniTask.Editor.csproj
src/UniTask/UniTask.Tests.csproj
src/UniTask/UniTask.Tests.Editor.csproj

1040
README.md

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,15 +1,13 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31606.5
# Visual Studio Version 16
VisualStudioVersion = 16.0.29613.14
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UniTask.NetCoreTests", "src\UniTask.NetCoreTests\UniTask.NetCoreTests.csproj", "{B3E311A4-70D8-4131-9965-C073A99D201A}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UniTask.NetCoreTests", "src\UniTask.NetCoreTests\UniTask.NetCoreTests.csproj", "{B3E311A4-70D8-4131-9965-C073A99D201A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UniTask.NetCore", "src\UniTask.NetCore\UniTask.NetCore.csproj", "{16EE20D0-7FB1-483A-8467-A5EEDBF1F5BF}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UniTask.NetCoreSandbox", "src\UniTask.NetCoreSandbox\UniTask.NetCoreSandbox.csproj", "{3915E72E-33E0-4A14-A6D8-872702200E58}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UniTask.Analyzer", "src\UniTask.Analyzer\UniTask.Analyzer.csproj", "{0AC6F052-A255-4EE3-9E05-1C02D49AB1C2}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UniTask.NetCoreSandbox", "src\UniTask.NetCoreSandbox\UniTask.NetCoreSandbox.csproj", "{3915E72E-33E0-4A14-A6D8-872702200E58}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -29,10 +27,6 @@ Global
{3915E72E-33E0-4A14-A6D8-872702200E58}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3915E72E-33E0-4A14-A6D8-872702200E58}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3915E72E-33E0-4A14-A6D8-872702200E58}.Release|Any CPU.Build.0 = Release|Any CPU
{0AC6F052-A255-4EE3-9E05-1C02D49AB1C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0AC6F052-A255-4EE3-9E05-1C02D49AB1C2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0AC6F052-A255-4EE3-9E05-1C02D49AB1C2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0AC6F052-A255-4EE3-9E05-1C02D49AB1C2}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

10
docs/.gitignore vendored
View File

@ -1,10 +0,0 @@
###############
# folder #
###############
/**/DROP/
/**/TEMP/
/**/packages/
/**/bin/
/**/obj/
_site
_DocfxTemplate

5
docs/api/.gitignore vendored
View File

@ -1,5 +0,0 @@
###############
# temp file #
###############
*.yml
.manifest

View File

@ -1,70 +0,0 @@
{
"metadata": [
{
"src": [
{
"files": [
"UniTask/Assets/Plugins/UniTask/Runtime/**/*.cs"
],
"src": "../src"
}
],
"dest": "api",
"disableGitFeatures": false,
"disableDefaultFilter": false
}
],
"build": {
"globalMetadata": {
"_disableContribution": true,
"_appTitle": "UniTask"
},
"content": [
{
"files": [
"api/**.yml",
"api/index.md"
]
},
{
"files": [
"articles/**.md",
"articles/**/toc.yml",
"toc.yml",
"*.md"
]
}
],
"resource": [
{
"files": [
"images/**"
]
}
],
"overwrite": [
{
"files": [
"apidoc/**.md"
],
"exclude": [
"obj/**",
"_site/**"
]
}
],
"dest": "_site",
"globalMetadataFiles": [],
"fileMetadataFiles": [],
"template": [
"_DocfxTemplate/templates/default-v2.5.2",
"_DocfxTemplate/templates/cysharp"
],
"postProcessors": [],
"markdownEngineName": "markdig",
"noLangKeyword": false,
"keepFileLink": false,
"cleanupCacheHistory": false
}
}

View File

@ -1,8 +0,0 @@
---
title: Home
---
# UniTask
Provides an efficient async/await integration to Unity.
https://github.com/Cysharp/UniTask

View File

@ -1,11 +0,0 @@
- name: API Documentation
href: api/
homepage: api/Cysharp.Threading.Tasks.html
- name: Repository
href: https://github.com/Cysharp/UniTask
homepage: https://github.com/Cysharp/UniTask
- name: Releases
href: https://github.com/Cysharp/UniTask/releases
homepage: https://github.com/Cysharp/UniTask/releases

View File

@ -1,8 +0,0 @@
{
"profiles": {
"UniTask.Analyzer": {
"commandName": "DebugRoslynComponent",
"targetProject": "..\\UniTask.NetCoreSandbox\\UniTask.NetCoreSandbox.csproj"
}
}
}

View File

@ -1,29 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>library</OutputType>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<IsRoslynComponent>true</IsRoslynComponent>
<TargetsForTfmSpecificContentInPackage>$(TargetsForTfmSpecificContentInPackage);PackBuildOutputs</TargetsForTfmSpecificContentInPackage>
<IncludeBuildOutput>false</IncludeBuildOutput>
<IncludeSymbols>false</IncludeSymbols>
<SuppressDependenciesWhenPacking>true</SuppressDependenciesWhenPacking>
<DevelopmentDependency>true</DevelopmentDependency>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.8.0" />
</ItemGroup>
<Target Name="PackBuildOutputs" DependsOnTargets="SatelliteDllsProjectOutputGroup;DebugSymbolsProjectOutputGroup">
<ItemGroup>
<TfmSpecificPackageFile Include="$(TargetDir)\*.dll" PackagePath="analyzers\dotnet\cs" />
<TfmSpecificPackageFile Include="@(SatelliteDllsProjectOutputGroupOutput->'%(FinalOutputPath)')" PackagePath="analyzers\dotnet\cs\%(SatelliteDllsProjectOutputGroupOutput.Culture)\" />
</ItemGroup>
</Target>
</Project>

View File

@ -1,54 +0,0 @@
#pragma warning disable RS2008
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Operations;
using System.Collections.Immutable;
using System.Threading;
namespace UniTask.Analyzer
{
[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class UniTaskAnalyzer : DiagnosticAnalyzer
{
private static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor(
id: "UNITASK001",
title: "UniTaskAnalyzer001: Must pass CancellationToken",
messageFormat: "Must pass CancellationToken",
category: "Usage",
defaultSeverity: DiagnosticSeverity.Error,
isEnabledByDefault: true,
description: "Pass CancellationToken or CancellationToken.None.");
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get { return ImmutableArray.Create(Rule); } }
public override void Initialize(AnalysisContext context)
{
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
context.EnableConcurrentExecution();
context.RegisterOperationAction(AnalyzeOperation, OperationKind.Invocation);
}
private static void AnalyzeOperation(OperationAnalysisContext context)
{
var token = context.Compilation.GetTypeByMetadataName(typeof(CancellationToken).FullName);
if (token == null) return;
if (context.Operation is IInvocationOperation invocation)
{
foreach (var arg in invocation.Arguments)
{
if (arg.ArgumentKind == ArgumentKind.DefaultValue)
{
if (SymbolEqualityComparer.Default.Equals(arg.Parameter.Type, token))
{
var diagnostic = Diagnostic.Create(Rule, arg.Syntax.GetLocation());
context.ReportDiagnostic(diagnostic);
}
}
}
}
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

View File

@ -1,101 +0,0 @@
#if !NETSTANDARD2_0
#pragma warning disable 0649
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using System.Threading.Tasks.Sources;
namespace Cysharp.Threading.Tasks
{
public static class AsyncEnumerableExtensions
{
public static IUniTaskAsyncEnumerable<T> AsUniTaskAsyncEnumerable<T>(this IAsyncEnumerable<T> source)
{
return new AsyncEnumerableToUniTaskAsyncEnumerable<T>(source);
}
public static IAsyncEnumerable<T> AsAsyncEnumerable<T>(this IUniTaskAsyncEnumerable<T> source)
{
return new UniTaskAsyncEnumerableToAsyncEnumerable<T>(source);
}
sealed class AsyncEnumerableToUniTaskAsyncEnumerable<T> : IUniTaskAsyncEnumerable<T>
{
readonly IAsyncEnumerable<T> source;
public AsyncEnumerableToUniTaskAsyncEnumerable(IAsyncEnumerable<T> source)
{
this.source = source;
}
public IUniTaskAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken cancellationToken = default)
{
return new Enumerator(source.GetAsyncEnumerator(cancellationToken));
}
sealed class Enumerator : IUniTaskAsyncEnumerator<T>
{
readonly IAsyncEnumerator<T> enumerator;
public Enumerator(IAsyncEnumerator<T> enumerator)
{
this.enumerator = enumerator;
}
public T Current => enumerator.Current;
public async UniTask DisposeAsync()
{
await enumerator.DisposeAsync();
}
public async UniTask<bool> MoveNextAsync()
{
return await enumerator.MoveNextAsync();
}
}
}
sealed class UniTaskAsyncEnumerableToAsyncEnumerable<T> : IAsyncEnumerable<T>
{
readonly IUniTaskAsyncEnumerable<T> source;
public UniTaskAsyncEnumerableToAsyncEnumerable(IUniTaskAsyncEnumerable<T> source)
{
this.source = source;
}
public IAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken cancellationToken = default)
{
return new Enumerator(source.GetAsyncEnumerator(cancellationToken));
}
sealed class Enumerator : IAsyncEnumerator<T>
{
readonly IUniTaskAsyncEnumerator<T> enumerator;
public Enumerator(IUniTaskAsyncEnumerator<T> enumerator)
{
this.enumerator = enumerator;
}
public T Current => enumerator.Current;
public ValueTask DisposeAsync()
{
return enumerator.DisposeAsync();
}
public ValueTask<bool> MoveNextAsync()
{
return enumerator.MoveNextAsync();
}
}
}
}
}
#endif

View File

@ -1,39 +0,0 @@
//using Cysharp.Threading.Tasks.Internal;
//using System;
//using System.Collections.Concurrent;
//using System.Runtime.CompilerServices;
//using System.Threading;
//namespace Cysharp.Threading.Tasks
//{
// public partial struct UniTask
// {
// public static UniTask Delay()
// {
// return default;
// }
// sealed class DelayPromise : IUniTaskSource
// {
// public void GetResult(short token)
// {
// throw new NotImplementedException();
// }
// public UniTaskStatus GetStatus(short token)
// {
// throw new NotImplementedException();
// }
// public void OnCompleted(Action<object> continuation, object state, short token)
// {
// throw new NotImplementedException();
// }
// public UniTaskStatus UnsafeGetStatus()
// {
// throw new NotImplementedException();
// }
// }
// }
//}

View File

@ -1,103 +0,0 @@
using Cysharp.Threading.Tasks.Internal;
using System;
using System.Collections.Concurrent;
using System.Runtime.CompilerServices;
using System.Threading;
namespace Cysharp.Threading.Tasks
{
public partial struct UniTask
{
public static UniTask.YieldAwaitable Yield()
{
return default;
}
public readonly struct YieldAwaitable
{
public Awaiter GetAwaiter()
{
return default;
}
public readonly struct Awaiter : ICriticalNotifyCompletion
{
static readonly SendOrPostCallback SendOrPostCallbackDelegate = Continuation;
static readonly WaitCallback WaitCallbackDelegate = Continuation;
public bool IsCompleted => false;
public void GetResult() { }
public void OnCompleted(Action continuation)
{
UnsafeOnCompleted(continuation);
}
public void UnsafeOnCompleted(Action continuation)
{
var syncContext = SynchronizationContext.Current;
if (syncContext != null)
{
syncContext.Post(SendOrPostCallbackDelegate, continuation);
}
else
{
#if NETCOREAPP3_1
ThreadPool.UnsafeQueueUserWorkItem(ThreadPoolWorkItem.Create(continuation), false);
#else
ThreadPool.UnsafeQueueUserWorkItem(WaitCallbackDelegate, continuation);
#endif
}
}
static void Continuation(object state)
{
((Action)state).Invoke();
}
}
#if NETCOREAPP3_1
sealed class ThreadPoolWorkItem : IThreadPoolWorkItem, ITaskPoolNode<ThreadPoolWorkItem>
{
static TaskPool<ThreadPoolWorkItem> pool;
ThreadPoolWorkItem nextNode;
public ref ThreadPoolWorkItem NextNode => ref nextNode;
static ThreadPoolWorkItem()
{
TaskPool.RegisterSizeGetter(typeof(ThreadPoolWorkItem), () => pool.Size);
}
Action continuation;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ThreadPoolWorkItem Create(Action continuation)
{
if (!pool.TryPop(out var item))
{
item = new ThreadPoolWorkItem();
}
item.continuation = continuation;
return item;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Execute()
{
var call = continuation;
continuation = null;
if (call != null)
{
pool.TryPush(this);
call.Invoke();
}
}
}
#endif
}
}
}

View File

@ -1,43 +1,31 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net6.0;net7.0;netstandard2.1;netstandard2.0</TargetFrameworks>
<AssemblyName>UniTask</AssemblyName>
<LangVersion>8.0</LangVersion>
<RootNamespace>Cysharp.Threading.Tasks</RootNamespace>
<DefineConstants>UNITASK_NETCORE</DefineConstants>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<AssemblyName>UniTask</AssemblyName>
<RootNamespace>Cysharp.Threading.Tasks</RootNamespace>
</PropertyGroup>
<!-- NuGet Packaging -->
<Id>UniTask</Id>
<PackageVersion>$(Version)</PackageVersion>
<Company>Cysharp</Company>
<Authors>Cysharp</Authors>
<Copyright>© Cysharp, Inc.</Copyright>
<PackageTags>task;async</PackageTags>
<Description>Provides an efficient async/await integration to Unity and .NET Core.</Description>
<PackageProjectUrl>https://github.com/Cysharp/UniTask</PackageProjectUrl>
<RepositoryUrl>$(PackageProjectUrl)</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageIcon>Icon.png</PackageIcon>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>opensource.snk</AssemblyOriginatorKeyFile>
<IsPackable>true</IsPackable>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\UniTask\Assets\Plugins\UniTask\**\*.cs"
Exclude="..\UniTask\Assets\Plugins\UniTask\Triggers\*.cs;
..\UniTask\Assets\Plugins\UniTask\Editor\*.cs;
<ItemGroup>
<None Include="Icon.png" Pack="true" PackagePath="/" />
</ItemGroup>
..\UniTask\Assets\Plugins\UniTask\Internal\UnityEqualityComparer.cs;
..\UniTask\Assets\Plugins\UniTask\Internal\DiagnosticsExtensions.cs;
..\UniTask\Assets\Plugins\UniTask\Internal\PlayerLoopRunner.cs;
<ItemGroup>
<Compile Include="..\UniTask\Assets\Plugins\UniTask\Runtime\**\*.cs" Exclude="&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Editor\*.cs;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\Triggers\*.cs;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\Linq\UnityExtensions\*.cs;&#xD;&#xA; &#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\Internal\UnityEqualityComparer.cs;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\Internal\DiagnosticsExtensions.cs;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\Internal\PlayerLoopRunner.cs;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\Internal\ContinuationQueue.cs;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\Internal\UnityWebRequestExtensions.cs;&#xD;&#xA; &#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\UniTaskSynchronizationContext.cs;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\CancellationTokenSourceExtensions.cs;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\EnumeratorAsyncExtensions.cs;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\TimeoutController.cs;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\PlayerLoopHelper.cs;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\PlayerLoopTimer.cs;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\UniTask.Delay.cs;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\UniTask.Run.cs;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\UniTask.Bridge.cs;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\UniTask.WaitUntil.cs;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\UnityAsyncExtensions.*;&#xD;&#xA;..\UniTask\Assets\Plugins\UniTask\Runtime\UnityBindingExtensions.cs;&#xD;&#xA;" />
<Compile Remove="..\UniTask\Assets\Plugins\UniTask\Runtime\_InternalVisibleTo.cs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.Threading.Tasks.Extensions" Version="4.5.4" />
</ItemGroup>
..\UniTask\Assets\Plugins\UniTask\CancellationTokenSourceExtensions.cs;
..\UniTask\Assets\Plugins\UniTask\EnumeratorAsyncExtensions.cs;
..\UniTask\Assets\Plugins\UniTask\PlayerLoopHelper.cs;
..\UniTask\Assets\Plugins\UniTask\UniTask.Delay.cs;
..\UniTask\Assets\Plugins\UniTask\UniTask.Run.cs;
..\UniTask\Assets\Plugins\UniTask\UniTask.Bridge.cs;
..\UniTask\Assets\Plugins\UniTask\UniTask.WaitUntil.cs;
..\UniTask\Assets\Plugins\UniTask\UnityAsyncExtensions.cs;
..\UniTask\Assets\Plugins\UniTask\UnityAsyncExtensions.uGUI.cs;
..\UniTask\Assets\Plugins\UniTask\UnityAsyncExtensions.MonoBehaviour.cs;
"/>
</ItemGroup>
</Project>

Binary file not shown.

View File

@ -1,50 +1,38 @@
#pragma warning disable CS1998
using Cysharp.Threading.Tasks;
using System.Linq;
using Cysharp.Threading.Tasks;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using System.Collections;
using System.Text;
using System.Text.RegularExpressions;
using System.Runtime.CompilerServices;
using Cysharp.Threading.Tasks.Linq;
using System.Reactive.Linq;
using System.Reactive.Concurrency;
namespace NetCoreSandbox
{
public class Program
class Program
{
static async Task Main(string[] args)
{
var cts = new CancellationTokenSource();
// OK.
await FooAsync(10, cts.Token);
// NG(Compiler Error)
// await FooAsync(10);
Console.WriteLine("Foo");
var v = await outer().AsTask();
Console.WriteLine("Bar:" + v);
}
static async UniTask FooAsync(int x, CancellationToken cancellationToken = default)
static async UniTask<int> outer()
{
await UniTask.Yield();
var v = await DoAsync();
return v;
}
}
static async UniTask<int> DoAsync()
{
var tcs = new UniTaskCompletionSource<int>();
tcs.TrySetResult(100);
var v = await tcs.Task;
return v;
}
}
}

View File

@ -2,26 +2,12 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
<RootNamespace>NetCoreSandbox</RootNamespace>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.12.1" />
<PackageReference Include="PooledAwait" Version="1.0.49" />
<PackageReference Include="System.Interactive.Async" Version="4.1.1" />
<PackageReference Include="System.Reactive" Version="4.4.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\UniTask.NetCore\UniTask.NetCore.csproj" />
<ProjectReference Include="..\UniTask.Analyzer\UniTask.Analyzer.csproj">
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
<OutputItemType>Analyzer</OutputItemType>
</ProjectReference>
</ItemGroup>
</Project>

View File

@ -1,167 +0,0 @@
using Cysharp.Threading.Tasks;
using FluentAssertions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Channels;
using Cysharp.Threading.Tasks.Linq;
using System.Threading.Tasks;
using Xunit;
namespace NetCoreTests
{
public class AsyncLazyTest
{
[Fact]
public async Task LazyLazy()
{
{
var l = UniTask.Lazy(() => After());
var a = AwaitAwait(l.Task);
var b = AwaitAwait(l.Task);
var c = AwaitAwait(l.Task);
await a;
await b;
await c;
}
{
var l = UniTask.Lazy(() => AfterException());
var a = AwaitAwait(l.Task);
var b = AwaitAwait(l.Task);
var c = AwaitAwait(l.Task);
await Assert.ThrowsAsync<TaskTestException>(async () => await a);
await Assert.ThrowsAsync<TaskTestException>(async () => await b);
await Assert.ThrowsAsync<TaskTestException>(async () => await c);
}
}
[Fact]
public async Task LazyImmediate()
{
{
var l = UniTask.Lazy(() => UniTask.FromResult(1).AsUniTask());
var a = AwaitAwait(l.Task);
var b = AwaitAwait(l.Task);
var c = AwaitAwait(l.Task);
await a;
await b;
await c;
}
{
var l = UniTask.Lazy(() => UniTask.FromException(new TaskTestException()));
var a = AwaitAwait(l.Task);
var b = AwaitAwait(l.Task);
var c = AwaitAwait(l.Task);
await Assert.ThrowsAsync<TaskTestException>(async () => await a);
await Assert.ThrowsAsync<TaskTestException>(async () => await b);
await Assert.ThrowsAsync<TaskTestException>(async () => await c);
}
}
static async UniTask AwaitAwait(UniTask t)
{
await t;
}
async UniTask After()
{
await UniTask.Yield();
Thread.Sleep(TimeSpan.FromSeconds(1));
await UniTask.Yield();
await UniTask.Yield();
}
async UniTask AfterException()
{
await UniTask.Yield();
Thread.Sleep(TimeSpan.FromSeconds(1));
await UniTask.Yield();
throw new TaskTestException();
}
}
public class AsyncLazyTest2
{
[Fact]
public async Task LazyLazy()
{
{
var l = UniTask.Lazy(() => After());
var a = AwaitAwait(l.Task);
var b = AwaitAwait(l.Task);
var c = AwaitAwait(l.Task);
var a2 = await a;
var b2 = await b;
var c2 = await c;
(a2, b2, c2).Should().Be((10, 10, 10));
}
{
var l = UniTask.Lazy(() => AfterException());
var a = AwaitAwait(l.Task);
var b = AwaitAwait(l.Task);
var c = AwaitAwait(l.Task);
await Assert.ThrowsAsync<TaskTestException>(async () => await a);
await Assert.ThrowsAsync<TaskTestException>(async () => await b);
await Assert.ThrowsAsync<TaskTestException>(async () => await c);
}
}
[Fact]
public async Task LazyImmediate()
{
{
var l = UniTask.Lazy(() => UniTask.FromResult(1));
var a = AwaitAwait(l.Task);
var b = AwaitAwait(l.Task);
var c = AwaitAwait(l.Task);
var a2 = await a;
var b2 = await b;
var c2 = await c;
(a2, b2, c2).Should().Be((1, 1, 1));
}
{
var l = UniTask.Lazy(() => UniTask.FromException<int>(new TaskTestException()));
var a = AwaitAwait(l.Task);
var b = AwaitAwait(l.Task);
var c = AwaitAwait(l.Task);
await Assert.ThrowsAsync<TaskTestException>(async () => await a);
await Assert.ThrowsAsync<TaskTestException>(async () => await b);
await Assert.ThrowsAsync<TaskTestException>(async () => await c);
}
}
static async UniTask<int> AwaitAwait(UniTask<int> t)
{
return await t;
}
async UniTask<int> After()
{
await UniTask.Yield();
Thread.Sleep(TimeSpan.FromSeconds(1));
await UniTask.Yield();
await UniTask.Yield();
return 10;
}
async UniTask<int> AfterException()
{
await UniTask.Yield();
Thread.Sleep(TimeSpan.FromSeconds(1));
await UniTask.Yield();
throw new TaskTestException();
}
}
}

View File

@ -1,197 +0,0 @@
using Cysharp.Threading.Tasks;
using FluentAssertions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Channels;
using Cysharp.Threading.Tasks.Linq;
using System.Threading.Tasks;
using Xunit;
namespace NetCoreTests
{
public class AsyncReactivePropertyTest
{
[Fact]
public async Task Iteration()
{
var rp = new AsyncReactiveProperty<int>(99);
var f = await rp.FirstAsync();
f.Should().Be(99);
var array = rp.Take(5).ToArrayAsync();
rp.Value = 100;
rp.Value = 100;
rp.Value = 100;
rp.Value = 131;
var ar = await array;
ar.Should().Equal(new[] { 99, 100, 100, 100, 131 });
}
[Fact]
public async Task WithoutCurrent()
{
var rp = new AsyncReactiveProperty<int>(99);
var array = rp.WithoutCurrent().Take(5).ToArrayAsync();
rp.Value = 100;
rp.Value = 100;
rp.Value = 100;
rp.Value = 131;
rp.Value = 191;
var ar = await array;
ar.Should().Equal(new[] { 100, 100, 100, 131, 191 });
}
//[Fact]
//public async Task StateIteration()
//{
// var rp = new ReadOnlyAsyncReactiveProperty<int>(99);
// var setter = rp.GetSetter();
// var f = await rp.FirstAsync();
// f.Should().Be(99);
// var array = rp.Take(5).ToArrayAsync();
// setter(100);
// setter(100);
// setter(100);
// setter(131);
// var ar = await array;
// ar.Should().Equal(new[] { 99, 100, 100, 100, 131 });
//}
//[Fact]
//public async Task StateWithoutCurrent()
//{
// var rp = new ReadOnlyAsyncReactiveProperty<int>(99);
// var setter = rp.GetSetter();
// var array = rp.WithoutCurrent().Take(5).ToArrayAsync();
// setter(100);
// setter(100);
// setter(100);
// setter(131);
// setter(191);
// var ar = await array;
// ar.Should().Equal(new[] { 100, 100, 100, 131, 191 });
//}
[Fact]
public void StateFromEnumeration()
{
var rp = new AsyncReactiveProperty<int>(10);
var state = rp.ToReadOnlyAsyncReactiveProperty(CancellationToken.None);
rp.Value = 10;
state.Value.Should().Be(10);
rp.Value = 20;
state.Value.Should().Be(20);
state.Dispose();
rp.Value = 30;
state.Value.Should().Be(20);
}
[Fact]
public async Task WaitAsyncTest()
{
var rp = new AsyncReactiveProperty<int>(128);
var f = await rp.FirstAsync();
f.Should().Be(128);
{
var t = rp.WaitAsync();
rp.Value = 99;
rp.Value = 100;
var v = await t;
v.Should().Be(99);
}
{
var t = rp.WaitAsync();
rp.Value = 99;
rp.Value = 100;
var v = await t;
v.Should().Be(99);
}
}
[Fact]
public async Task WaitAsyncCancellationTest()
{
var cts = new CancellationTokenSource();
var rp = new AsyncReactiveProperty<int>(128);
var t = rp.WaitAsync(cts.Token);
cts.Cancel();
rp.Value = 99;
rp.Value = 100;
await Assert.ThrowsAsync<OperationCanceledException>(async () => { await t; });
}
[Fact]
public async Task ReadOnlyWaitAsyncTest()
{
var rp = new AsyncReactiveProperty<int>(128);
var rrp = rp.ToReadOnlyAsyncReactiveProperty(CancellationToken.None);
var t = rrp.WaitAsync();
rp.Value = 99;
rp.Value = 100;
var v = await t;
v.Should().Be(99);
}
[Fact]
public async Task ReadOnlyWaitAsyncCancellationTest()
{
var cts = new CancellationTokenSource();
var rp = new AsyncReactiveProperty<int>(128);
var rrp = rp.ToReadOnlyAsyncReactiveProperty(CancellationToken.None);
var t = rrp.WaitAsync(cts.Token);
cts.Cancel();
rp.Value = 99;
rp.Value = 100;
await Assert.ThrowsAsync<OperationCanceledException>(async () => { await t; });
}
}
}

View File

@ -1,51 +0,0 @@
using Cysharp.Threading.Tasks;
using FluentAssertions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Channels;
using Cysharp.Threading.Tasks.Linq;
using System.Threading.Tasks;
using Xunit;
namespace NetCoreTests
{
public class CancellationTokenTest
{
[Fact]
public async Task WaitUntilCanceled()
{
var cts = new CancellationTokenSource();
cts.CancelAfter(TimeSpan.FromSeconds(1.5));
var now = DateTime.UtcNow;
await cts.Token.WaitUntilCanceled();
var elapsed = DateTime.UtcNow - now;
elapsed.Should().BeGreaterThan(TimeSpan.FromSeconds(1));
}
[Fact]
public void AlreadyCanceled()
{
var cts = new CancellationTokenSource();
cts.Cancel();
cts.Token.WaitUntilCanceled().GetAwaiter().IsCompleted.Should().BeTrue();
}
[Fact]
public void None()
{
CancellationToken.None.WaitUntilCanceled().GetAwaiter().IsCompleted.Should().BeTrue();
}
}
}

View File

@ -1,370 +0,0 @@
using Cysharp.Threading.Tasks;
using FluentAssertions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Channels;
using Cysharp.Threading.Tasks.Linq;
using System.Threading.Tasks;
using Xunit;
namespace NetCoreTests
{
public class ChannelTest
{
(System.Threading.Channels.Channel<int>, Cysharp.Threading.Tasks.Channel<int>) CreateChannel()
{
var reference = System.Threading.Channels.Channel.CreateUnbounded<int>(new UnboundedChannelOptions
{
AllowSynchronousContinuations = true,
SingleReader = true,
SingleWriter = false
});
var channel = Cysharp.Threading.Tasks.Channel.CreateSingleConsumerUnbounded<int>();
return (reference, channel);
}
[Fact]
public async Task SingleWriteSingleRead()
{
var (reference, channel) = CreateChannel();
foreach (var item in new[] { 10, 20, 30 })
{
var t1 = reference.Reader.WaitToReadAsync();
var t2 = channel.Reader.WaitToReadAsync();
t1.IsCompleted.Should().BeFalse();
t2.Status.IsCompleted().Should().BeFalse();
reference.Writer.TryWrite(item);
channel.Writer.TryWrite(item);
(await t1).Should().BeTrue();
(await t2).Should().BeTrue();
reference.Reader.TryRead(out var refitem).Should().BeTrue();
channel.Reader.TryRead(out var chanitem).Should().BeTrue();
refitem.Should().Be(item);
chanitem.Should().Be(item);
}
}
[Fact]
public async Task MultiWrite()
{
var (reference, channel) = CreateChannel();
foreach (var item in new[] { 10, 20, 30 })
{
var t1 = reference.Reader.WaitToReadAsync();
var t2 = channel.Reader.WaitToReadAsync();
t1.IsCompleted.Should().BeFalse();
t2.Status.IsCompleted().Should().BeFalse();
foreach (var i in Enumerable.Range(1, 3))
{
reference.Writer.TryWrite(item * i);
channel.Writer.TryWrite(item * i);
}
(await t1).Should().BeTrue();
(await t2).Should().BeTrue();
foreach (var i in Enumerable.Range(1, 3))
{
(await reference.Reader.WaitToReadAsync()).Should().BeTrue();
(await channel.Reader.WaitToReadAsync()).Should().BeTrue();
reference.Reader.TryRead(out var refitem).Should().BeTrue();
channel.Reader.TryRead(out var chanitem).Should().BeTrue();
refitem.Should().Be(item * i);
chanitem.Should().Be(item * i);
}
}
}
[Fact]
public async Task CompleteOnEmpty()
{
var (reference, channel) = CreateChannel();
foreach (var item in new[] { 10, 20, 30 })
{
reference.Writer.TryWrite(item);
channel.Writer.TryWrite(item);
reference.Reader.TryRead(out var refitem);
channel.Reader.TryRead(out var chanitem);
}
// Empty.
var completion1 = reference.Reader.Completion;
var wait1 = reference.Reader.WaitToReadAsync();
var completion2 = channel.Reader.Completion;
var wait2 = channel.Reader.WaitToReadAsync();
reference.Writer.TryComplete();
channel.Writer.TryComplete();
completion1.Status.Should().Be(TaskStatus.RanToCompletion);
completion2.Status.Should().Be(UniTaskStatus.Succeeded);
(await wait1).Should().BeFalse();
(await wait2).Should().BeFalse();
}
[Fact]
public async Task CompleteErrorOnEmpty()
{
var (reference, channel) = CreateChannel();
foreach (var item in new[] { 10, 20, 30 })
{
reference.Writer.TryWrite(item);
channel.Writer.TryWrite(item);
reference.Reader.TryRead(out var refitem);
channel.Reader.TryRead(out var chanitem);
}
// Empty.
var completion1 = reference.Reader.Completion;
var wait1 = reference.Reader.WaitToReadAsync();
var completion2 = channel.Reader.Completion;
var wait2 = channel.Reader.WaitToReadAsync();
var ex = new Exception();
reference.Writer.TryComplete(ex);
channel.Writer.TryComplete(ex);
completion1.Status.Should().Be(TaskStatus.Faulted);
completion2.Status.Should().Be(UniTaskStatus.Faulted);
(await Assert.ThrowsAsync<Exception>(async () => await wait1)).Should().Be(ex);
(await Assert.ThrowsAsync<Exception>(async () => await wait2)).Should().Be(ex);
}
[Fact]
public async Task CompleteWithRest()
{
var (reference, channel) = CreateChannel();
foreach (var item in new[] { 10, 20, 30 })
{
reference.Writer.TryWrite(item);
channel.Writer.TryWrite(item);
}
// Three Item2.
var completion1 = reference.Reader.Completion;
var wait1 = reference.Reader.WaitToReadAsync();
var completion2 = channel.Reader.Completion;
var wait2 = channel.Reader.WaitToReadAsync();
reference.Writer.TryComplete();
channel.Writer.TryComplete();
// completion1.Status.Should().Be(TaskStatus.WaitingForActivation);
completion2.Status.Should().Be(UniTaskStatus.Pending);
(await wait1).Should().BeTrue();
(await wait2).Should().BeTrue();
foreach (var item in new[] { 10, 20, 30 })
{
reference.Reader.TryRead(out var i1).Should().BeTrue();
channel.Reader.TryRead(out var i2).Should().BeTrue();
i1.Should().Be(item);
i2.Should().Be(item);
}
(await reference.Reader.WaitToReadAsync()).Should().BeFalse();
(await channel.Reader.WaitToReadAsync()).Should().BeFalse();
completion1.Status.Should().Be(TaskStatus.RanToCompletion);
completion2.Status.Should().Be(UniTaskStatus.Succeeded);
}
[Fact]
public async Task CompleteErrorWithRest()
{
var (reference, channel) = CreateChannel();
foreach (var item in new[] { 10, 20, 30 })
{
reference.Writer.TryWrite(item);
channel.Writer.TryWrite(item);
}
// Three Item2.
var completion1 = reference.Reader.Completion;
var wait1 = reference.Reader.WaitToReadAsync();
var completion2 = channel.Reader.Completion;
var wait2 = channel.Reader.WaitToReadAsync();
var ex = new Exception();
reference.Writer.TryComplete(ex);
channel.Writer.TryComplete(ex);
// completion1.Status.Should().Be(TaskStatus.WaitingForActivation);
completion2.Status.Should().Be(UniTaskStatus.Pending);
(await wait1).Should().BeTrue();
(await wait2).Should().BeTrue();
foreach (var item in new[] { 10, 20, 30 })
{
reference.Reader.TryRead(out var i1).Should().BeTrue();
channel.Reader.TryRead(out var i2).Should().BeTrue();
i1.Should().Be(item);
i2.Should().Be(item);
}
wait1 = reference.Reader.WaitToReadAsync();
wait2 = channel.Reader.WaitToReadAsync();
(await Assert.ThrowsAsync<Exception>(async () => await wait1)).Should().Be(ex);
(await Assert.ThrowsAsync<Exception>(async () => await wait2)).Should().Be(ex);
completion1.Status.Should().Be(TaskStatus.Faulted);
completion2.Status.Should().Be(UniTaskStatus.Faulted);
}
[Fact]
public async Task Cancellation()
{
var (reference, channel) = CreateChannel();
var cts = new CancellationTokenSource();
var wait1 = reference.Reader.WaitToReadAsync(cts.Token);
var wait2 = channel.Reader.WaitToReadAsync(cts.Token);
cts.Cancel();
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await wait1)).CancellationToken.Should().Be(cts.Token);
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await wait2)).CancellationToken.Should().Be(cts.Token);
}
[Fact]
public async Task AsyncEnumerator()
{
var (reference, channel) = CreateChannel();
var ta1 = reference.Reader.ReadAllAsync().ToArrayAsync();
var ta2 = channel.Reader.ReadAllAsync().ToArrayAsync();
foreach (var item in new[] { 10, 20, 30 })
{
reference.Writer.TryWrite(item);
channel.Writer.TryWrite(item);
}
reference.Writer.TryComplete();
channel.Writer.TryComplete();
(await ta1).Should().Equal(new[] { 10, 20, 30 });
(await ta2).Should().Equal(new[] { 10, 20, 30 });
}
[Fact]
public async Task AsyncEnumeratorCancellation()
{
// Token1, Token2 and Cancel1
{
var cts1 = new CancellationTokenSource();
var cts2 = new CancellationTokenSource();
var (reference, channel) = CreateChannel();
var ta1 = reference.Reader.ReadAllAsync(cts1.Token).ToArrayAsync(cts2.Token);
var ta2 = channel.Reader.ReadAllAsync(cts1.Token).ToArrayAsync(cts2.Token);
foreach (var item in new[] { 10, 20, 30 })
{
reference.Writer.TryWrite(item);
channel.Writer.TryWrite(item);
}
cts1.Cancel();
await Assert.ThrowsAsync<OperationCanceledException>(async () => await ta1);
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await ta2)).CancellationToken.Should().Be(cts1.Token);
}
// Token1, Token2 and Cancel2
{
var cts1 = new CancellationTokenSource();
var cts2 = new CancellationTokenSource();
var (reference, channel) = CreateChannel();
var ta1 = reference.Reader.ReadAllAsync(cts1.Token).ToArrayAsync(cts2.Token);
var ta2 = channel.Reader.ReadAllAsync(cts1.Token).ToArrayAsync(cts2.Token);
foreach (var item in new[] { 10, 20, 30 })
{
reference.Writer.TryWrite(item);
channel.Writer.TryWrite(item);
}
cts2.Cancel();
await Assert.ThrowsAsync<OperationCanceledException>(async () => await ta1);
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await ta2)).CancellationToken.Should().Be(cts2.Token);
}
// Token1 and Cancel1
{
var cts1 = new CancellationTokenSource();
var (reference, channel) = CreateChannel();
var ta1 = reference.Reader.ReadAllAsync(cts1.Token).ToArrayAsync();
var ta2 = channel.Reader.ReadAllAsync(cts1.Token).ToArrayAsync();
foreach (var item in new[] { 10, 20, 30 })
{
reference.Writer.TryWrite(item);
channel.Writer.TryWrite(item);
}
cts1.Cancel();
await Assert.ThrowsAsync<OperationCanceledException>(async () => await ta1);
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await ta2)).CancellationToken.Should().Be(cts1.Token);
}
// Token2 and Cancel2
{
var cts2 = new CancellationTokenSource();
var (reference, channel) = CreateChannel();
var ta1 = reference.Reader.ReadAllAsync().ToArrayAsync(cts2.Token);
var ta2 = channel.Reader.ReadAllAsync().ToArrayAsync(cts2.Token);
foreach (var item in new[] { 10, 20, 30 })
{
reference.Writer.TryWrite(item);
channel.Writer.TryWrite(item);
}
cts2.Cancel();
await Assert.ThrowsAsync<OperationCanceledException>(async () => await ta1);
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await ta2)).CancellationToken.Should().Be(cts2.Token);
}
}
}
}

View File

@ -1,590 +0,0 @@
using Cysharp.Threading.Tasks;
using FluentAssertions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Channels;
using Cysharp.Threading.Tasks.Linq;
using System.Threading.Tasks;
using Xunit;
namespace NetCoreTests
{
public class CompletionSourceTest
{
[Fact]
public async Task SetFirst()
{
{
var tcs = new UniTaskCompletionSource();
tcs.TrySetResult();
await tcs.Task; // ok.
await tcs.Task; // ok.
tcs.Task.Status.Should().Be(UniTaskStatus.Succeeded);
}
{
var tcs = new UniTaskCompletionSource();
tcs.TrySetException(new TestException());
await Assert.ThrowsAsync<TestException>(async () => await tcs.Task);
await Assert.ThrowsAsync<TestException>(async () => await tcs.Task);
tcs.Task.Status.Should().Be(UniTaskStatus.Faulted);
}
var cts = new CancellationTokenSource();
{
var tcs = new UniTaskCompletionSource();
tcs.TrySetException(new OperationCanceledException(cts.Token));
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await tcs.Task)).CancellationToken.Should().Be(cts.Token);
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await tcs.Task)).CancellationToken.Should().Be(cts.Token);
tcs.Task.Status.Should().Be(UniTaskStatus.Canceled);
}
{
var tcs = new UniTaskCompletionSource();
tcs.TrySetCanceled(cts.Token);
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await tcs.Task)).CancellationToken.Should().Be(cts.Token);
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await tcs.Task)).CancellationToken.Should().Be(cts.Token);
tcs.Task.Status.Should().Be(UniTaskStatus.Canceled);
}
}
[Fact]
public async Task SingleOnFirst()
{
{
var tcs = new UniTaskCompletionSource();
async UniTask Await()
{
await tcs.Task;
}
var a = Await();
tcs.TrySetResult();
await a;
await tcs.Task; // ok.
tcs.Task.Status.Should().Be(UniTaskStatus.Succeeded);
}
{
var tcs = new UniTaskCompletionSource();
async UniTask Await()
{
await tcs.Task;
}
var a = Await();
tcs.TrySetException(new TestException());
await Assert.ThrowsAsync<TestException>(async () => await a);
await Assert.ThrowsAsync<TestException>(async () => await tcs.Task);
tcs.Task.Status.Should().Be(UniTaskStatus.Faulted);
}
var cts = new CancellationTokenSource();
{
var tcs = new UniTaskCompletionSource();
async UniTask Await()
{
await tcs.Task;
}
var a = Await();
tcs.TrySetException(new OperationCanceledException(cts.Token));
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await a)).CancellationToken.Should().Be(cts.Token);
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await tcs.Task)).CancellationToken.Should().Be(cts.Token);
tcs.Task.Status.Should().Be(UniTaskStatus.Canceled);
}
{
var tcs = new UniTaskCompletionSource();
async UniTask Await()
{
await tcs.Task;
}
var a = Await();
tcs.TrySetCanceled(cts.Token);
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await a)).CancellationToken.Should().Be(cts.Token);
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await tcs.Task)).CancellationToken.Should().Be(cts.Token);
tcs.Task.Status.Should().Be(UniTaskStatus.Canceled);
}
}
[Fact]
public async Task MultiOne()
{
{
var tcs = new UniTaskCompletionSource();
async UniTask Await()
{
await tcs.Task;
}
var a = Await();
var b = Await();
tcs.TrySetResult();
await a;
await b;
await tcs.Task; // ok.
tcs.Task.Status.Should().Be(UniTaskStatus.Succeeded);
}
{
var tcs = new UniTaskCompletionSource();
async UniTask Await()
{
await tcs.Task;
}
var a = Await();
var b = Await();
tcs.TrySetException(new TestException());
await Assert.ThrowsAsync<TestException>(async () => await a);
await Assert.ThrowsAsync<TestException>(async () => await b);
await Assert.ThrowsAsync<TestException>(async () => await tcs.Task);
tcs.Task.Status.Should().Be(UniTaskStatus.Faulted);
}
var cts = new CancellationTokenSource();
{
var tcs = new UniTaskCompletionSource();
async UniTask Await()
{
await tcs.Task;
}
var a = Await();
var b = Await();
tcs.TrySetException(new OperationCanceledException(cts.Token));
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await a)).CancellationToken.Should().Be(cts.Token);
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await b)).CancellationToken.Should().Be(cts.Token);
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await tcs.Task)).CancellationToken.Should().Be(cts.Token);
tcs.Task.Status.Should().Be(UniTaskStatus.Canceled);
}
{
var tcs = new UniTaskCompletionSource();
async UniTask Await()
{
await tcs.Task;
}
var a = Await();
var b = Await();
tcs.TrySetCanceled(cts.Token);
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await a)).CancellationToken.Should().Be(cts.Token);
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await b)).CancellationToken.Should().Be(cts.Token);
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await tcs.Task)).CancellationToken.Should().Be(cts.Token);
tcs.Task.Status.Should().Be(UniTaskStatus.Canceled);
}
}
[Fact]
public async Task MultiTwo()
{
{
var tcs = new UniTaskCompletionSource();
async UniTask Await()
{
await tcs.Task;
}
var a = Await();
var b = Await();
var c = Await();
tcs.TrySetResult();
await a;
await b;
await c;
await tcs.Task; // ok.
tcs.Task.Status.Should().Be(UniTaskStatus.Succeeded);
}
{
var tcs = new UniTaskCompletionSource();
async UniTask Await()
{
await tcs.Task;
}
var a = Await();
var b = Await();
var c = Await();
tcs.TrySetException(new TestException());
await Assert.ThrowsAsync<TestException>(async () => await a);
await Assert.ThrowsAsync<TestException>(async () => await b);
await Assert.ThrowsAsync<TestException>(async () => await c);
await Assert.ThrowsAsync<TestException>(async () => await tcs.Task);
tcs.Task.Status.Should().Be(UniTaskStatus.Faulted);
}
var cts = new CancellationTokenSource();
{
var tcs = new UniTaskCompletionSource();
async UniTask Await()
{
await tcs.Task;
}
var a = Await();
var b = Await();
var c = Await();
tcs.TrySetException(new OperationCanceledException(cts.Token));
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await a)).CancellationToken.Should().Be(cts.Token);
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await b)).CancellationToken.Should().Be(cts.Token);
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await c)).CancellationToken.Should().Be(cts.Token);
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await tcs.Task)).CancellationToken.Should().Be(cts.Token);
tcs.Task.Status.Should().Be(UniTaskStatus.Canceled);
}
{
var tcs = new UniTaskCompletionSource();
async UniTask Await()
{
await tcs.Task;
}
var a = Await();
var b = Await();
var c = Await();
tcs.TrySetCanceled(cts.Token);
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await a)).CancellationToken.Should().Be(cts.Token);
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await b)).CancellationToken.Should().Be(cts.Token);
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await c)).CancellationToken.Should().Be(cts.Token);
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await tcs.Task)).CancellationToken.Should().Be(cts.Token);
tcs.Task.Status.Should().Be(UniTaskStatus.Canceled);
}
}
class TestException : Exception
{
}
}
public class CompletionSourceTest2
{
[Fact]
public async Task SetFirst()
{
{
var tcs = new UniTaskCompletionSource<int>();
tcs.TrySetResult(10);
var a = await tcs.Task; // ok.
var b = await tcs.Task; // ok.
a.Should().Be(10);
b.Should().Be(10);
tcs.Task.Status.Should().Be(UniTaskStatus.Succeeded);
}
{
var tcs = new UniTaskCompletionSource<int>();
tcs.TrySetException(new TestException());
await Assert.ThrowsAsync<TestException>(async () => await tcs.Task);
await Assert.ThrowsAsync<TestException>(async () => await tcs.Task);
tcs.Task.Status.Should().Be(UniTaskStatus.Faulted);
}
var cts = new CancellationTokenSource();
{
var tcs = new UniTaskCompletionSource<int>();
tcs.TrySetException(new OperationCanceledException(cts.Token));
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await tcs.Task)).CancellationToken.Should().Be(cts.Token);
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await tcs.Task)).CancellationToken.Should().Be(cts.Token);
tcs.Task.Status.Should().Be(UniTaskStatus.Canceled);
}
{
var tcs = new UniTaskCompletionSource<int>();
tcs.TrySetCanceled(cts.Token);
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await tcs.Task)).CancellationToken.Should().Be(cts.Token);
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await tcs.Task)).CancellationToken.Should().Be(cts.Token);
tcs.Task.Status.Should().Be(UniTaskStatus.Canceled);
}
}
[Fact]
public async Task SingleOnFirst()
{
{
var tcs = new UniTaskCompletionSource<int>();
async UniTask<int> Await()
{
return await tcs.Task;
}
var a = Await();
tcs.TrySetResult(10);
var r1 = await a;
var r2 = await tcs.Task; // ok.
r1.Should().Be(10);
r2.Should().Be(10);
tcs.Task.Status.Should().Be(UniTaskStatus.Succeeded);
}
{
var tcs = new UniTaskCompletionSource<int>();
async UniTask<int> Await()
{
return await tcs.Task;
}
var a = Await();
tcs.TrySetException(new TestException());
await Assert.ThrowsAsync<TestException>(async () => await a);
await Assert.ThrowsAsync<TestException>(async () => await tcs.Task);
tcs.Task.Status.Should().Be(UniTaskStatus.Faulted);
}
var cts = new CancellationTokenSource();
{
var tcs = new UniTaskCompletionSource<int>();
async UniTask<int> Await()
{
return await tcs.Task;
}
var a = Await();
tcs.TrySetException(new OperationCanceledException(cts.Token));
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await a)).CancellationToken.Should().Be(cts.Token);
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await tcs.Task)).CancellationToken.Should().Be(cts.Token);
tcs.Task.Status.Should().Be(UniTaskStatus.Canceled);
}
{
var tcs = new UniTaskCompletionSource<int>();
async UniTask<int> Await()
{
return await tcs.Task;
}
var a = Await();
tcs.TrySetCanceled(cts.Token);
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await a)).CancellationToken.Should().Be(cts.Token);
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await tcs.Task)).CancellationToken.Should().Be(cts.Token);
tcs.Task.Status.Should().Be(UniTaskStatus.Canceled);
}
}
[Fact]
public async Task MultiOne()
{
{
var tcs = new UniTaskCompletionSource<int>();
async UniTask<int> Await()
{
return await tcs.Task;
}
var a = Await();
var b = Await();
tcs.TrySetResult(10);
var r1 = await a;
var r2 = await b;
var r3 = await tcs.Task; // ok.
(r1, r2, r3).Should().Be((10, 10, 10));
tcs.Task.Status.Should().Be(UniTaskStatus.Succeeded);
}
{
var tcs = new UniTaskCompletionSource<int>();
async UniTask<int> Await()
{
return await tcs.Task;
}
var a = Await();
var b = Await();
tcs.TrySetException(new TestException());
await Assert.ThrowsAsync<TestException>(async () => await a);
await Assert.ThrowsAsync<TestException>(async () => await b);
await Assert.ThrowsAsync<TestException>(async () => await tcs.Task);
tcs.Task.Status.Should().Be(UniTaskStatus.Faulted);
}
var cts = new CancellationTokenSource();
{
var tcs = new UniTaskCompletionSource<int>();
async UniTask<int> Await()
{
return await tcs.Task;
}
var a = Await();
var b = Await();
tcs.TrySetException(new OperationCanceledException(cts.Token));
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await a)).CancellationToken.Should().Be(cts.Token);
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await b)).CancellationToken.Should().Be(cts.Token);
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await tcs.Task)).CancellationToken.Should().Be(cts.Token);
tcs.Task.Status.Should().Be(UniTaskStatus.Canceled);
}
{
var tcs = new UniTaskCompletionSource<int>();
async UniTask<int> Await()
{
return await tcs.Task;
}
var a = Await();
var b = Await();
tcs.TrySetCanceled(cts.Token);
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await a)).CancellationToken.Should().Be(cts.Token);
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await b)).CancellationToken.Should().Be(cts.Token);
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await tcs.Task)).CancellationToken.Should().Be(cts.Token);
tcs.Task.Status.Should().Be(UniTaskStatus.Canceled);
}
}
[Fact]
public async Task MultiTwo()
{
{
var tcs = new UniTaskCompletionSource<int>();
async UniTask<int> Await()
{
return await tcs.Task;
}
var a = Await();
var b = Await();
var c = Await();
tcs.TrySetResult(10);
var r1 = await a;
var r2 = await b;
var r3 = await c;
var r4 = await tcs.Task; // ok.
(r1, r2, r3, r4).Should().Be((10, 10, 10, 10));
tcs.Task.Status.Should().Be(UniTaskStatus.Succeeded);
}
{
var tcs = new UniTaskCompletionSource<int>();
async UniTask<int> Await()
{
return await tcs.Task;
}
var a = Await();
var b = Await();
var c = Await();
tcs.TrySetException(new TestException());
await Assert.ThrowsAsync<TestException>(async () => await a);
await Assert.ThrowsAsync<TestException>(async () => await b);
await Assert.ThrowsAsync<TestException>(async () => await c);
await Assert.ThrowsAsync<TestException>(async () => await tcs.Task);
tcs.Task.Status.Should().Be(UniTaskStatus.Faulted);
}
var cts = new CancellationTokenSource();
{
var tcs = new UniTaskCompletionSource<int>();
async UniTask<int> Await()
{
return await tcs.Task;
}
var a = Await();
var b = Await();
var c = Await();
tcs.TrySetException(new OperationCanceledException(cts.Token));
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await a)).CancellationToken.Should().Be(cts.Token);
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await b)).CancellationToken.Should().Be(cts.Token);
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await c)).CancellationToken.Should().Be(cts.Token);
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await tcs.Task)).CancellationToken.Should().Be(cts.Token);
tcs.Task.Status.Should().Be(UniTaskStatus.Canceled);
}
{
var tcs = new UniTaskCompletionSource<int>();
async UniTask<int> Await()
{
return await tcs.Task;
}
var a = Await();
var b = Await();
var c = Await();
tcs.TrySetCanceled(cts.Token);
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await a)).CancellationToken.Should().Be(cts.Token);
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await b)).CancellationToken.Should().Be(cts.Token);
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await c)).CancellationToken.Should().Be(cts.Token);
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await tcs.Task)).CancellationToken.Should().Be(cts.Token);
tcs.Task.Status.Should().Be(UniTaskStatus.Canceled);
}
}
class TestException : Exception
{
}
}
}

View File

@ -1,47 +0,0 @@
using Cysharp.Threading.Tasks;
using FluentAssertions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Channels;
using Cysharp.Threading.Tasks.Linq;
using System.Threading.Tasks;
using Xunit;
namespace NetCoreTests
{
public class DeferTest
{
[Fact]
public async Task D()
{
var created = false;
var v = UniTask.Defer(() => { created = true; return UniTask.Run(() => 10); });
created.Should().BeFalse();
var t = await v;
created.Should().BeTrue();
t.Should().Be(10);
}
[Fact]
public async Task D2()
{
var created = false;
var v = UniTask.Defer(() => { created = true; return UniTask.Run(() => 10).AsUniTask(); });
created.Should().BeFalse();
await v;
created.Should().BeTrue();
}
}
}

View File

@ -1,496 +0,0 @@
using Cysharp.Threading.Tasks;
using Cysharp.Threading.Tasks.Linq;
using FluentAssertions;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading.Tasks;
using Xunit;
namespace NetCoreTests.Linq
{
public class Aggregate
{
[Theory]
[InlineData(0, 10)]
[InlineData(0, 1)]
[InlineData(10, 0)]
[InlineData(1, 11)]
public async Task Sum(int start, int count)
{
{
var xs = await UniTaskAsyncEnumerable.Range(start, count).SumAsync();
var ys = Enumerable.Range(start, count).Sum();
xs.Should().Be(ys);
}
{
var xs = await UniTaskAsyncEnumerable.Range(start, count).SumAsync(x => x * 2);
var ys = Enumerable.Range(start, count).Sum(x => x * 2);
xs.Should().Be(ys);
}
{
var xs = await UniTaskAsyncEnumerable.Range(start, count).SumAwaitAsync(x => UniTask.Run(() => x));
var ys = Enumerable.Range(start, count).Sum(x => x);
xs.Should().Be(ys);
}
{
var xs = await UniTaskAsyncEnumerable.Range(start, count).SumAwaitWithCancellationAsync((x, _) => UniTask.Run(() => x));
var ys = Enumerable.Range(start, count).Sum(x => x);
xs.Should().Be(ys);
}
}
public static IEnumerable<object[]> array1 = new object[][]
{
new object[]{new int[] { 1, 10, 100 } },
new object[]{new int?[] { 1, null, 100 } },
new object[]{new float[] { 1, 10, 100 } },
new object[]{new float?[] { 1, null, 100 } },
new object[]{new double[] { 1, 10, 100 } },
new object[]{new double?[] { 1, null, 100 } },
new object[]{new decimal[] { 1, 10, 100 } },
new object[]{new decimal?[] { 1, null, 100 } },
};
[Theory]
[MemberData(nameof(array1))]
public async Task Average<T>(T arr)
{
switch (arr)
{
case int[] array:
{
var xs = await array.ToUniTaskAsyncEnumerable().AverageAsync();
var ys = array.Average();
xs.Should().Be(ys);
}
break;
case int?[] array:
{
var xs = await array.ToUniTaskAsyncEnumerable().AverageAsync();
var ys = array.Average();
xs.Should().Be(ys);
}
break;
case float[] array:
{
var xs = await array.ToUniTaskAsyncEnumerable().AverageAsync();
var ys = array.Average();
xs.Should().Be(ys);
}
break;
case float?[] array:
{
var xs = await array.ToUniTaskAsyncEnumerable().AverageAsync();
var ys = array.Average();
xs.Should().Be(ys);
}
break;
case double[] array:
{
var xs = await array.ToUniTaskAsyncEnumerable().AverageAsync();
var ys = array.Average();
xs.Should().Be(ys);
}
break;
case double?[] array:
{
var xs = await array.ToUniTaskAsyncEnumerable().AverageAsync();
var ys = array.Average();
xs.Should().Be(ys);
}
break;
case decimal[] array:
{
var xs = await array.ToUniTaskAsyncEnumerable().AverageAsync();
var ys = array.Average();
xs.Should().Be(ys);
}
break;
case decimal?[] array:
{
var xs = await array.ToUniTaskAsyncEnumerable().AverageAsync();
var ys = array.Average();
xs.Should().Be(ys);
}
break;
default:
break;
}
}
public static IEnumerable<object[]> array2 = new object[][]
{
new object[]{new int[] { } },
new object[]{new int[] { 5 } },
new object[]{new int[] { 5, 10, 100 } },
new object[]{new int[] { 10, 5,100 } },
new object[]{new int[] { 100, 10, 5 } },
new object[]{new int?[] { } },
new object[]{new int?[] { 5 } },
new object[]{new int?[] { null, null, null } },
new object[]{new int?[] { null, 5, 10, 100 } },
new object[]{new int?[] { 10, 5,100, null } },
new object[]{new int?[] { 100, 10, 5 } },
new object[]{new X[] { } },
new object[]{new X[] { new X(5) } },
new object[]{new X[] { new X(5), new X(10), new X(100) } },
new object[]{new X[] { new X(10),new X( 5),new X(100) } },
new object[]{new X[] { new X(100), new X(10),new X(5) } },
new object[]{new XX[] { } },
new object[]{new XX[] { new XX(new X(5)) } },
new object[]{new XX[] { new XX(new X(5)), new XX(new X(10)), new XX(new X(100)) } },
new object[]{new XX[] { new XX(new X(10)),new XX(new X( 5)),new XX(new X(100)) } },
new object[]{new XX[] { new XX(new X(100)), new XX(new X(10)),new XX(new X(5)) } },
};
[Theory]
[MemberData(nameof(array2))]
public async Task Min<T>(T arr)
{
switch (arr)
{
case int[] array:
{
{
if (array.Length == 0)
{
await Assert.ThrowsAsync<InvalidOperationException>(async () => await array.ToUniTaskAsyncEnumerable().MinAsync());
Assert.Throws<InvalidOperationException>(() => array.Min());
}
else
{
var xs = await array.ToUniTaskAsyncEnumerable().MinAsync();
var ys = array.Min();
xs.Should().Be(ys);
}
}
{
if (array.Length == 0)
{
await Assert.ThrowsAsync<InvalidOperationException>(async () => await array.ToUniTaskAsyncEnumerable().MinAsync(x => x * 2));
Assert.Throws<InvalidOperationException>(() => array.Min(x => x * 2));
}
else
{
var xs = await array.ToUniTaskAsyncEnumerable().MinAsync(x => x * 2);
var ys = array.Min(x => x * 2);
xs.Should().Be(ys);
}
}
}
break;
case int?[] array:
{
{
var xs = await array.ToUniTaskAsyncEnumerable().MinAsync();
var ys = array.Min();
xs.Should().Be(ys);
}
{
var xs = await array.ToUniTaskAsyncEnumerable().MinAsync(x => x);
var ys = array.Min(x => x);
xs.Should().Be(ys);
}
}
break;
case X[] array:
{
{
var xs = await array.ToUniTaskAsyncEnumerable().MinAsync();
var ys = array.Min();
xs.Should().Be(ys);
}
{
if (array.Length == 0)
{
await Assert.ThrowsAsync<InvalidOperationException>(async () => await array.ToUniTaskAsyncEnumerable().MinAsync(x => x.Value));
Assert.Throws<InvalidOperationException>(() => array.Min(x => x.Value));
}
else
{
var xs = await array.ToUniTaskAsyncEnumerable().MinAsync(x => x.Value);
var ys = array.Min(x => x.Value);
xs.Should().Be(ys);
}
}
}
break;
case XX[] array:
{
var xs = await array.ToUniTaskAsyncEnumerable().MinAsync(x => x.Value);
var ys = array.Min(x => x.Value);
xs.Should().Be(ys);
}
break;
default:
break;
}
}
[Theory]
[MemberData(nameof(array2))]
public async Task Max<T>(T arr)
{
switch (arr)
{
case int[] array:
{
{
if (array.Length == 0)
{
await Assert.ThrowsAsync<InvalidOperationException>(async () => await array.ToUniTaskAsyncEnumerable().MaxAsync());
Assert.Throws<InvalidOperationException>(() => array.Max());
}
else
{
var xs = await array.ToUniTaskAsyncEnumerable().MaxAsync();
var ys = array.Max();
xs.Should().Be(ys);
}
}
{
if (array.Length == 0)
{
await Assert.ThrowsAsync<InvalidOperationException>(async () => await array.ToUniTaskAsyncEnumerable().MaxAsync(x => x * 2));
Assert.Throws<InvalidOperationException>(() => array.Max(x => x * 2));
}
else
{
var xs = await array.ToUniTaskAsyncEnumerable().MaxAsync(x => x * 2);
var ys = array.Max(x => x * 2);
xs.Should().Be(ys);
}
}
}
break;
case int?[] array:
{
{
var xs = await array.ToUniTaskAsyncEnumerable().MaxAsync();
var ys = array.Max();
xs.Should().Be(ys);
}
{
var xs = await array.ToUniTaskAsyncEnumerable().MaxAsync(x => x);
var ys = array.Max(x => x);
xs.Should().Be(ys);
}
}
break;
case X[] array:
{
{
var xs = await array.ToUniTaskAsyncEnumerable().MaxAsync();
var ys = array.Max();
xs.Should().Be(ys);
}
{
if (array.Length == 0)
{
await Assert.ThrowsAsync<InvalidOperationException>(async () => await array.ToUniTaskAsyncEnumerable().MaxAsync(x => x.Value));
Assert.Throws<InvalidOperationException>(() => array.Max(x => x.Value));
}
else
{
var xs = await array.ToUniTaskAsyncEnumerable().MaxAsync(x => x.Value);
var ys = array.Max(x => x.Value);
xs.Should().Be(ys);
}
}
}
break;
case XX[] array:
{
var xs = await array.ToUniTaskAsyncEnumerable().MaxAsync(x => x.Value);
var ys = array.Max(x => x.Value);
xs.Should().Be(ys);
}
break;
default:
break;
}
}
public class XX
{
public readonly X Value;
public XX(X value)
{
this.Value = value;
}
}
public class X : IComparable<X>
{
public readonly int Value;
public X(int value)
{
Value = value;
}
public int CompareTo([AllowNull] X other)
{
return Comparer<int>.Default.Compare(Value, other.Value);
}
}
[Theory]
[InlineData(0, 10)]
[InlineData(0, 1)]
[InlineData(10, 0)]
[InlineData(1, 11)]
public async Task Count(int start, int count)
{
{
var xs = await UniTaskAsyncEnumerable.Range(start, count).CountAsync();
var ys = Enumerable.Range(start, count).Count();
xs.Should().Be(ys);
}
{
var xs = await UniTaskAsyncEnumerable.Range(start, count).CountAsync(x => x % 2 == 0);
var ys = Enumerable.Range(start, count).Count(x => x % 2 == 0);
xs.Should().Be(ys);
}
{
var xs = await UniTaskAsyncEnumerable.Range(start, count).LongCountAsync();
var ys = Enumerable.Range(start, count).LongCount();
xs.Should().Be(ys);
}
{
var xs = await UniTaskAsyncEnumerable.Range(start, count).LongCountAsync(x => x % 2 == 0);
var ys = Enumerable.Range(start, count).LongCount(x => x % 2 == 0);
xs.Should().Be(ys);
}
}
[Fact]
public async Task AggregateTest1()
{
// 0
await Assert.ThrowsAsync<InvalidOperationException>(async () => await new int[] { }.ToUniTaskAsyncEnumerable().AggregateAsync((x, y) => x + y));
Assert.Throws<InvalidOperationException>(() => new int[] { }.Aggregate((x, y) => x + y));
// 1
{
var a = await Enumerable.Range(1, 1).ToUniTaskAsyncEnumerable().AggregateAsync((x, y) => x + y);
var b = Enumerable.Range(1, 1).Aggregate((x, y) => x + y);
a.Should().Be(b);
}
// 2
{
var a = await Enumerable.Range(1, 2).ToUniTaskAsyncEnumerable().AggregateAsync((x, y) => x + y);
var b = Enumerable.Range(1, 2).Aggregate((x, y) => x + y);
a.Should().Be(b);
}
// 10
{
var a = await Enumerable.Range(1, 10).ToUniTaskAsyncEnumerable().AggregateAsync((x, y) => x + y);
var b = Enumerable.Range(1, 10).Aggregate((x, y) => x + y);
a.Should().Be(b);
}
}
[Fact]
public async Task AggregateTest2()
{
// 0
{
var a = await Enumerable.Range(1, 1).ToUniTaskAsyncEnumerable().AggregateAsync(1000, (x, y) => x + y);
var b = Enumerable.Range(1, 1).Aggregate(1000, (x, y) => x + y);
a.Should().Be(b);
}
// 1
{
var a = await Enumerable.Range(1, 1).ToUniTaskAsyncEnumerable().AggregateAsync(1000, (x, y) => x + y);
var b = Enumerable.Range(1, 1).Aggregate(1000, (x, y) => x + y);
a.Should().Be(b);
}
// 2
{
var a = await Enumerable.Range(1, 2).ToUniTaskAsyncEnumerable().AggregateAsync(1000, (x, y) => x + y);
var b = Enumerable.Range(1, 2).Aggregate(1000, (x, y) => x + y);
a.Should().Be(b);
}
// 10
{
var a = await Enumerable.Range(1, 10).ToUniTaskAsyncEnumerable().AggregateAsync(1000, (x, y) => x + y);
var b = Enumerable.Range(1, 10).Aggregate(1000, (x, y) => x + y);
a.Should().Be(b);
}
}
[Fact]
public async Task AggregateTest3()
{
// 0
{
var a = await Enumerable.Range(1, 1).ToUniTaskAsyncEnumerable().AggregateAsync(1000, (x, y) => x + y, x => (x * 99).ToString());
var b = Enumerable.Range(1, 1).Aggregate(1000, (x, y) => x + y, x => (x * 99).ToString());
a.Should().Be(b);
}
// 1
{
var a = await Enumerable.Range(1, 1).ToUniTaskAsyncEnumerable().AggregateAsync(1000, (x, y) => x + y, x => (x * 99).ToString());
var b = Enumerable.Range(1, 1).Aggregate(1000, (x, y) => x + y, x => (x * 99).ToString());
a.Should().Be(b);
}
// 2
{
var a = await Enumerable.Range(1, 2).ToUniTaskAsyncEnumerable().AggregateAsync(1000, (x, y) => x + y, x => (x * 99).ToString());
var b = Enumerable.Range(1, 2).Aggregate(1000, (x, y) => x + y, x => (x * 99).ToString());
a.Should().Be(b);
}
// 10
{
var a = await Enumerable.Range(1, 10).ToUniTaskAsyncEnumerable().AggregateAsync(1000, (x, y) => x + y, x => (x * 99).ToString());
var b = Enumerable.Range(1, 10).Aggregate(1000, (x, y) => x + y, x => (x * 99).ToString());
a.Should().Be(b);
}
}
[Fact]
public async Task ForEach()
{
var list = new List<int>();
await Enumerable.Range(1, 10).ToUniTaskAsyncEnumerable().ForEachAsync(x =>
{
list.Add(x);
});
list.Should().Equal(Enumerable.Range(1, 10));
var list2 = new List<(int, int)>();
await Enumerable.Range(5, 10).ToUniTaskAsyncEnumerable().ForEachAsync((index, x) =>
{
list2.Add((index, x));
});
var list3 = Enumerable.Range(5, 10).Select((index, x) => (index, x)).ToArray();
list2.Should().Equal(list3);
}
}
}

View File

@ -1,112 +0,0 @@
using Cysharp.Threading.Tasks;
using Cysharp.Threading.Tasks.Linq;
using FluentAssertions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Concurrency;
using System.Reactive.Linq;
using System.Threading.Tasks;
using Xunit;
namespace NetCoreTests.Linq
{
public class AllAny
{
[Theory]
[InlineData(0, 0)]
[InlineData(1, 1)]
[InlineData(1, 2)]
[InlineData(1, 3)]
[InlineData(0, 10)]
[InlineData(0, 11)]
public async Task AllTest(int start, int count)
{
var range = Enumerable.Range(start, count);
var x = await range.ToUniTaskAsyncEnumerable().AllAsync(x => x % 2 == 0);
var y = range.All(x => x % 2 == 0);
x.Should().Be(y);
}
[Theory]
[InlineData(0, 0)]
[InlineData(1, 1)]
[InlineData(1, 2)]
[InlineData(1, 3)]
[InlineData(0, 10)]
[InlineData(0, 11)]
public async Task AnyTest(int start, int count)
{
var range = Enumerable.Range(start, count);
{
var x = await range.ToUniTaskAsyncEnumerable().AnyAsync();
var y = range.Any();
x.Should().Be(y);
}
{
var x = await range.ToUniTaskAsyncEnumerable().AnyAsync(x => x % 2 == 0);
var y = range.Any(x => x % 2 == 0);
x.Should().Be(y);
}
}
[Theory]
[InlineData(0, 0)]
[InlineData(1, 1)]
[InlineData(1, 2)]
[InlineData(1, 3)]
[InlineData(0, 10)]
[InlineData(0, 11)]
public async Task ContainsTest(int start, int count)
{
var range = Enumerable.Range(start, count);
foreach (var c in Enumerable.Range(0, 15))
{
var x = await range.ToUniTaskAsyncEnumerable().ContainsAsync(c);
var y = range.Contains(c);
x.Should().Be(y);
}
}
[Fact]
public async Task SequenceEqual()
{
// empty and empty
(await new int[0].ToUniTaskAsyncEnumerable().SequenceEqualAsync(new int[0].ToUniTaskAsyncEnumerable())).Should().BeTrue();
(new int[0].SequenceEqual(new int[0])).Should().BeTrue();
// empty and exists
(await new int[0].ToUniTaskAsyncEnumerable().SequenceEqualAsync(new int[] { 1 }.ToUniTaskAsyncEnumerable())).Should().BeFalse();
(new int[0].SequenceEqual(new int[] { 1 })).Should().BeFalse();
// exists and empty
(await new int[] { 1 }.ToUniTaskAsyncEnumerable().SequenceEqualAsync(new int[0].ToUniTaskAsyncEnumerable())).Should().BeFalse();
(new int[] { 1 }.SequenceEqual(new int[] { })).Should().BeFalse();
// samelength same value
(await new int[] { 1, 2, 3 }.ToUniTaskAsyncEnumerable().SequenceEqualAsync(new int[] { 1, 2, 3 }.ToUniTaskAsyncEnumerable())).Should().BeTrue();
(new int[] { 1, 2, 3 }.SequenceEqual(new int[] { 1, 2, 3 })).Should().BeTrue();
// samelength different value(first)
(await new int[] { 5, 2, 3 }.ToUniTaskAsyncEnumerable().SequenceEqualAsync(new int[] { 1, 2, 3 }.ToUniTaskAsyncEnumerable())).Should().BeFalse();
// samelength different value(middle)
(await new int[] { 1, 2, 3 }.ToUniTaskAsyncEnumerable().SequenceEqualAsync(new int[] { 1, 5, 3 }.ToUniTaskAsyncEnumerable())).Should().BeFalse();
// samelength different value(last)
(await new int[] { 1, 2, 3 }.ToUniTaskAsyncEnumerable().SequenceEqualAsync(new int[] { 1, 2, 5 }.ToUniTaskAsyncEnumerable())).Should().BeFalse();
// left is long
(await new int[] { 1, 2, 3, 4 }.ToUniTaskAsyncEnumerable().SequenceEqualAsync(new int[] { 1, 2, 3 }.ToUniTaskAsyncEnumerable())).Should().BeFalse();
(new int[] { 1, 2, 3, 4 }.SequenceEqual(new int[] { 1, 2, 3 })).Should().BeFalse();
// right is long
(await new int[] { 1, 2, 3 }.ToUniTaskAsyncEnumerable().SequenceEqualAsync(new int[] { 1, 2, 3, 4 }.ToUniTaskAsyncEnumerable())).Should().BeFalse();
(new int[] { 1, 2, 3 }.SequenceEqual(new int[] { 1, 2, 3, 4 })).Should().BeFalse();
}
}
}

View File

@ -1,144 +0,0 @@
using Cysharp.Threading.Tasks;
using Cysharp.Threading.Tasks.Linq;
using FluentAssertions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Concurrency;
using System.Reactive.Linq;
using System.Threading.Tasks;
using Xunit;
namespace NetCoreTests.Linq
{
public class Concat
{
[Theory]
[InlineData(0, 0)]
[InlineData(0, 1)]
[InlineData(0, 2)]
[InlineData(0, 10)]
public async Task Append(int start, int count)
{
var xs = await Enumerable.Range(start, count).ToUniTaskAsyncEnumerable().Append(99).ToArrayAsync();
var ys = Enumerable.Range(start, count).Append(99).ToArray();
xs.Should().Equal(ys);
}
[Fact]
public async Task AppendThrow()
{
var xs = UniTaskTestException.ThrowImmediate().Append(99).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
var ys = UniTaskTestException.ThrowAfter().Append(99).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await ys);
var zs = UniTaskTestException.ThrowInMoveNext().Append(99).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await zs);
}
[Theory]
[InlineData(0, 0)]
[InlineData(0, 1)]
[InlineData(0, 2)]
[InlineData(0, 10)]
public async Task Prepend(int start, int count)
{
var xs = await Enumerable.Range(start, count).ToUniTaskAsyncEnumerable().Prepend(99).ToArrayAsync();
var ys = Enumerable.Range(start, count).Prepend(99).ToArray();
xs.Should().Equal(ys);
}
[Fact]
public async Task PrependThrow()
{
var xs = UniTaskTestException.ThrowImmediate().Prepend(99).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
var ys = UniTaskTestException.ThrowAfter().Prepend(99).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await ys);
var zs = UniTaskTestException.ThrowInMoveNext().Prepend(99).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await zs);
}
public static IEnumerable<object[]> array1 = new object[][]
{
new object[] { (0, 0), (0, 0) }, // empty + empty
new object[] { (0, 1), (0, 0) }, // 1 + empty
new object[] { (0, 0), (0, 1) }, // empty + 1
new object[] { (0, 5), (0, 0) }, // 5 + empty
new object[] { (0, 0), (0, 5) }, // empty + 5
new object[] { (0, 5), (0, 5) }, // 5 + 5
};
[Theory]
[MemberData(nameof(array1))]
public async Task ConcatTest((int, int) left, (int, int) right)
{
var l = Enumerable.Range(left.Item1, left.Item2);
var r = Enumerable.Range(right.Item1, right.Item2);
var xs = await l.ToUniTaskAsyncEnumerable().Concat(r.ToUniTaskAsyncEnumerable()).ToArrayAsync();
var ys = l.Concat(r).ToArray();
xs.Should().Equal(ys);
}
[Fact]
public async Task ConcatThrow()
{
{
var xs = UniTaskTestException.ThrowImmediate().Concat(UniTaskAsyncEnumerable.Range(1, 10)).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
var ys = UniTaskTestException.ThrowAfter().Concat(UniTaskAsyncEnumerable.Range(1, 10)).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await ys);
var zs = UniTaskTestException.ThrowInMoveNext().Concat(UniTaskAsyncEnumerable.Range(1, 10)).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await zs);
}
{
var xs = UniTaskAsyncEnumerable.Range(1, 10).Concat(UniTaskTestException.ThrowImmediate()).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
var ys = UniTaskAsyncEnumerable.Range(1, 10).Concat(UniTaskTestException.ThrowAfter()).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await ys);
var zs = UniTaskAsyncEnumerable.Range(1, 10).Concat(UniTaskTestException.ThrowInMoveNext()).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await zs);
}
}
[Fact]
public async Task DefaultIfEmpty()
{
{
var xs = await Enumerable.Range(1, 0).ToUniTaskAsyncEnumerable().DefaultIfEmpty(99).ToArrayAsync();
var ys = Enumerable.Range(1, 0).DefaultIfEmpty(99).ToArray();
xs.Should().Equal(ys);
}
{
var xs = await Enumerable.Range(1, 1).ToUniTaskAsyncEnumerable().DefaultIfEmpty(99).ToArrayAsync();
var ys = Enumerable.Range(1, 1).DefaultIfEmpty(99).ToArray();
xs.Should().Equal(ys);
}
{
var xs = await Enumerable.Range(1, 10).ToUniTaskAsyncEnumerable().DefaultIfEmpty(99).ToArrayAsync();
var ys = Enumerable.Range(1, 10).DefaultIfEmpty(99).ToArray();
xs.Should().Equal(ys);
}
// Throw
{
foreach (var item in UniTaskTestException.Throws())
{
var xs = item.DefaultIfEmpty().ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
}
}
}
}

View File

@ -1,196 +0,0 @@
using Cysharp.Threading.Tasks;
using Cysharp.Threading.Tasks.Linq;
using FluentAssertions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Concurrency;
using System.Reactive.Linq;
using System.Threading.Tasks;
using Xunit;
namespace NetCoreTests.Linq
{
public class Convert
{
[Fact]
public async Task ToAsyncEnumerable()
{
{
var xs = await Enumerable.Range(1, 100).ToUniTaskAsyncEnumerable().ToArrayAsync();
xs.Length.Should().Be(100);
}
{
var xs = await Enumerable.Empty<int>().ToUniTaskAsyncEnumerable().ToArrayAsync();
xs.Length.Should().Be(0);
}
}
[Fact]
public async Task ToObservable()
{
{
var xs = await UniTaskAsyncEnumerable.Range(1, 10).ToObservable().ToArray();
xs.Should().Equal(Enumerable.Range(1, 10));
}
{
var xs = await UniTaskAsyncEnumerable.Range(1, 0).ToObservable().ToArray();
xs.Should().Equal(Enumerable.Range(1, 0));
}
}
[Fact]
public async Task ToAsyncEnumerableTask()
{
var t = Task.FromResult(100);
var xs = await t.ToUniTaskAsyncEnumerable().ToArrayAsync();
xs.Length.Should().Be(1);
xs[0].Should().Be(100);
}
[Fact]
public async Task ToAsyncEnumerableUniTask()
{
var t = UniTask.FromResult(100);
var xs = await t.ToUniTaskAsyncEnumerable().ToArrayAsync();
xs.Length.Should().Be(1);
xs[0].Should().Be(100);
}
[Fact]
public async Task ToAsyncEnumerableObservable()
{
{
var xs = await Observable.Range(1, 100).ToUniTaskAsyncEnumerable().ToArrayAsync();
var ys = await Observable.Range(1, 100).ToArray();
xs.Should().Equal(ys);
}
{
var xs = await Observable.Range(1, 100, ThreadPoolScheduler.Instance).ToUniTaskAsyncEnumerable().ToArrayAsync();
var ys = await Observable.Range(1, 100, ThreadPoolScheduler.Instance).ToArray();
xs.Should().Equal(ys);
}
{
var xs = await Observable.Empty<int>(ThreadPoolScheduler.Instance).ToUniTaskAsyncEnumerable().ToArrayAsync();
var ys = await Observable.Empty<int>(ThreadPoolScheduler.Instance).ToArray();
xs.Should().Equal(ys);
}
}
[Fact]
public async Task ToDictionary()
{
{
var xs = await Enumerable.Range(1, 100).ToUniTaskAsyncEnumerable().ToDictionaryAsync(x => x);
var ys = Enumerable.Range(1, 100).ToDictionary(x => x);
xs.OrderBy(x => x.Key).Should().Equal(ys.OrderBy(x => x.Key));
}
{
var xs = await Enumerable.Range(1, 0).ToUniTaskAsyncEnumerable().ToDictionaryAsync(x => x);
var ys = Enumerable.Range(1, 0).ToDictionary(x => x);
xs.OrderBy(x => x.Key).Should().Equal(ys.OrderBy(x => x.Key));
}
{
var xs = await Enumerable.Range(1, 100).ToUniTaskAsyncEnumerable().ToDictionaryAsync(x => x, x => x * 2);
var ys = Enumerable.Range(1, 100).ToDictionary(x => x, x => x * 2);
xs.OrderBy(x => x.Key).Should().Equal(ys.OrderBy(x => x.Key));
}
{
var xs = await Enumerable.Range(1, 0).ToUniTaskAsyncEnumerable().ToDictionaryAsync(x => x, x => x * 2);
var ys = Enumerable.Range(1, 0).ToDictionary(x => x, x => x * 2);
xs.OrderBy(x => x.Key).Should().Equal(ys.OrderBy(x => x.Key));
}
}
[Fact]
public async Task ToLookup()
{
var arr = new[] { 1, 4, 10, 10, 4, 5, 10, 9 };
{
var xs = await arr.ToUniTaskAsyncEnumerable().ToLookupAsync(x => x);
var ys = arr.ToLookup(x => x);
xs.Count.Should().Be(ys.Count);
xs.Should().BeEquivalentTo(ys);
foreach (var key in xs.Select(x => x.Key))
{
xs[key].Should().Equal(ys[key]);
}
}
{
var xs = await Enumerable.Range(1, 0).ToUniTaskAsyncEnumerable().ToLookupAsync(x => x);
var ys = Enumerable.Range(1, 0).ToLookup(x => x);
xs.Should().BeEquivalentTo(ys);
}
{
var xs = await arr.ToUniTaskAsyncEnumerable().ToLookupAsync(x => x, x => x * 2);
var ys = arr.ToLookup(x => x, x => x * 2);
xs.Count.Should().Be(ys.Count);
xs.Should().BeEquivalentTo(ys);
foreach (var key in xs.Select(x => x.Key))
{
xs[key].Should().Equal(ys[key]);
}
}
{
var xs = await Enumerable.Range(1, 0).ToUniTaskAsyncEnumerable().ToLookupAsync(x => x, x => x * 2);
var ys = Enumerable.Range(1, 0).ToLookup(x => x, x => x * 2);
xs.Should().BeEquivalentTo(ys);
}
}
[Fact]
public async Task ToList()
{
{
var xs = await Enumerable.Range(1, 100).ToUniTaskAsyncEnumerable().ToListAsync();
var ys = Enumerable.Range(1, 100).ToList();
xs.Should().Equal(ys);
}
{
var xs = await Enumerable.Empty<int>().ToUniTaskAsyncEnumerable().ToListAsync();
var ys = Enumerable.Empty<int>().ToList();
xs.Should().Equal(ys);
}
}
[Fact]
public async Task ToHashSet()
{
{
var xs = await new[] { 1, 20, 4, 5, 20, 4, 6 }.ToUniTaskAsyncEnumerable().ToHashSetAsync();
var ys = new[] { 1, 20, 4, 5, 20, 4, 6 }.ToHashSet();
xs.OrderBy(x => x).Should().Equal(ys.OrderBy(x => x));
}
{
var xs = await Enumerable.Empty<int>().ToUniTaskAsyncEnumerable().ToHashSetAsync();
var ys = Enumerable.Empty<int>().ToHashSet();
xs.Should().Equal(ys);
}
}
}
}

View File

@ -1,194 +0,0 @@
#pragma warning disable CS1998
#pragma warning disable CS0162
using Cysharp.Threading.Tasks;
using Cysharp.Threading.Tasks.Linq;
using FluentAssertions;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Xunit;
namespace NetCoreTests.Linq
{
public class CreateTest
{
[Fact]
public async Task SyncCreation()
{
var from = 10;
var count = 100;
var xs = await UniTaskAsyncEnumerable.Create<int>(async (writer, token) =>
{
for (int i = 0; i < count; i++)
{
await writer.YieldAsync(from + i);
}
}).ToArrayAsync();
var ys = await Range(from, count).AsUniTaskAsyncEnumerable().ToArrayAsync();
xs.Should().Equal(ys);
}
[Fact]
public async Task SyncManually()
{
var list = new List<int>();
var xs = UniTaskAsyncEnumerable.Create<int>(async (writer, token) =>
{
list.Add(100);
await writer.YieldAsync(10);
list.Add(200);
await writer.YieldAsync(20);
list.Add(300);
await writer.YieldAsync(30);
list.Add(400);
});
list.Should().BeEmpty();
var e = xs.GetAsyncEnumerator();
list.Should().BeEmpty();
await e.MoveNextAsync();
list.Should().Equal(100);
e.Current.Should().Be(10);
await e.MoveNextAsync();
list.Should().Equal(100, 200);
e.Current.Should().Be(20);
await e.MoveNextAsync();
list.Should().Equal(100, 200, 300);
e.Current.Should().Be(30);
(await e.MoveNextAsync()).Should().BeFalse();
list.Should().Equal(100, 200, 300, 400);
}
[Fact]
public async Task SyncExceptionFirst()
{
var from = 10;
var count = 100;
var xs = UniTaskAsyncEnumerable.Create<int>(async (writer, token) =>
{
for (int i = 0; i < count; i++)
{
throw new UniTaskTestException();
await writer.YieldAsync(from + i);
}
});
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs.ToArrayAsync());
}
[Fact]
public async Task SyncException()
{
var from = 10;
var count = 100;
var xs = UniTaskAsyncEnumerable.Create<int>(async (writer, token) =>
{
for (int i = 0; i < count; i++)
{
await writer.YieldAsync(from + i);
if (i == 15)
{
throw new UniTaskTestException();
}
}
});
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs.ToArrayAsync());
}
[Fact]
public async Task ASyncManually()
{
var list = new List<int>();
var xs = UniTaskAsyncEnumerable.Create<int>(async (writer, token) =>
{
await UniTask.Yield();
list.Add(100);
await writer.YieldAsync(10);
await UniTask.Yield();
list.Add(200);
await writer.YieldAsync(20);
await UniTask.Yield();
list.Add(300);
await UniTask.Yield();
await writer.YieldAsync(30);
await UniTask.Yield();
list.Add(400);
});
list.Should().BeEmpty();
var e = xs.GetAsyncEnumerator();
list.Should().BeEmpty();
await e.MoveNextAsync();
list.Should().Equal(100);
e.Current.Should().Be(10);
await e.MoveNextAsync();
list.Should().Equal(100, 200);
e.Current.Should().Be(20);
await e.MoveNextAsync();
list.Should().Equal(100, 200, 300);
e.Current.Should().Be(30);
(await e.MoveNextAsync()).Should().BeFalse();
list.Should().Equal(100, 200, 300, 400);
}
[Fact]
public async Task AwaitForeachBreak()
{
var finallyCalled = false;
var enumerable = UniTaskAsyncEnumerable.Create<int>(async (writer, _) =>
{
try
{
await writer.YieldAsync(1);
}
finally
{
finallyCalled = true;
}
});
await foreach (var x in enumerable)
{
x.Should().Be(1);
break;
}
finallyCalled.Should().BeTrue();
}
async IAsyncEnumerable<int> Range(int from, int count)
{
for (int i = 0; i < count; i++)
{
yield return from + i;
}
}
}
}

View File

@ -1,66 +0,0 @@
using Cysharp.Threading.Tasks.Linq;
using FluentAssertions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Xunit;
namespace NetCoreTests.Linq
{
public class Factory
{
[Theory]
[InlineData(0, 10)]
[InlineData(0, 0)]
[InlineData(1, 5)]
[InlineData(1, 0)]
[InlineData(0, 11)]
[InlineData(1, 11)]
public async Task RangeTest(int start, int count)
{
var xs = await UniTaskAsyncEnumerable.Range(start, count).ToArrayAsync();
var ys = Enumerable.Range(start, count).ToArray();
xs.Should().Equal(ys);
}
[Theory]
[InlineData("foo", 0)]
[InlineData("bar", 1)]
[InlineData("baz", 3)]
[InlineData("foobar", 10)]
[InlineData("foobarbaz", 11)]
public async Task RepeatTest(string value, int count)
{
var xs = await UniTaskAsyncEnumerable.Repeat(value, count).ToArrayAsync();
var ys = Enumerable.Repeat(value, count).ToArray();
xs.Should().Equal(ys);
}
[Fact]
public async Task EmptyTest()
{
var xs = await UniTaskAsyncEnumerable.Empty<int>().ToArrayAsync();
var ys = Enumerable.Empty<int>().ToArray();
xs.Should().Equal(ys);
}
[Theory]
[InlineData(100)]
[InlineData((string)null)]
[InlineData("foo")]
public async Task ReturnTest<T>(T value)
{
var xs = await UniTaskAsyncEnumerable.Return(value).ToArrayAsync();
xs.Length.Should().Be(1);
xs[0].Should().Be(value);
}
}
}

View File

@ -1,118 +0,0 @@
using Cysharp.Threading.Tasks;
using Cysharp.Threading.Tasks.Linq;
using FluentAssertions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Concurrency;
using System.Reactive.Linq;
using System.Threading.Tasks;
using Xunit;
namespace NetCoreTests.Linq
{
public class Filtering
{
[Fact]
public async Task Where()
{
var range = Enumerable.Range(1, 10);
var src = range.ToUniTaskAsyncEnumerable();
{
var a = await src.Where(x => x % 2 == 0).ToArrayAsync();
var expected = range.Where(x => x % 2 == 0).ToArray();
a.Should().Equal(expected);
}
{
var a = await src.Where((x, i) => (x + i) % 2 == 0).ToArrayAsync();
var expected = range.Where((x, i) => (x + i) % 2 == 0).ToArray();
a.Should().Equal(expected);
}
{
var a = await src.WhereAwait(x => UniTask.Run(() => x % 2 == 0)).ToArrayAsync();
var b = await src.WhereAwait(x => UniTask.FromResult(x % 2 == 0)).ToArrayAsync();
var expected = range.Where(x => x % 2 == 0).ToArray();
a.Should().Equal(expected);
b.Should().Equal(expected);
}
{
var a = await src.WhereAwait((x, i) => UniTask.Run(() => (x + i) % 2 == 0)).ToArrayAsync();
var b = await src.WhereAwait((x, i) => UniTask.FromResult((x + i) % 2 == 0)).ToArrayAsync();
var expected = range.Where((x, i) => (x + i) % 2 == 0).ToArray();
a.Should().Equal(expected);
b.Should().Equal(expected);
}
}
[Fact]
public async Task WhereException()
{
foreach (var item in UniTaskTestException.Throws())
{
{
var xs = item.Where(x => x % 2 == 0).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
{
var xs = item.Where((x, i) => x % 2 == 0).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
{
var xs = item.WhereAwait(x => UniTask.FromResult(x % 2 == 0)).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
{
var xs = item.WhereAwait((x, i) => UniTask.FromResult(x % 2 == 0)).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
}
}
[Fact]
public async Task OfType()
{
var data = new object[] { 0, null, 10, 30, null, "foo", 99 };
var a = await data.ToUniTaskAsyncEnumerable().OfType<int>().ToArrayAsync();
var b = data.OfType<int>().ToArray();
a.Should().Equal(b);
}
[Fact]
public async Task OfTypeException()
{
foreach (var item in UniTaskTestException.Throws())
{
var xs = item.Select(x => (object)x).OfType<int>().ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
}
[Fact]
public async Task Cast()
{
var data = new object[] { 0, 10, 30, 99 };
var a = await data.ToUniTaskAsyncEnumerable().Cast<int>().ToArrayAsync();
var b = data.Cast<int>().ToArray();
a.Should().Equal(b);
}
[Fact]
public async Task CastException()
{
foreach (var item in UniTaskTestException.Throws())
{
var xs = item.Select(x => (object)x).Cast<int>().ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
}
}
}

View File

@ -1,258 +0,0 @@
using Cysharp.Threading.Tasks;
using Cysharp.Threading.Tasks.Linq;
using FluentAssertions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Concurrency;
using System.Reactive.Linq;
using System.Threading.Tasks;
using Xunit;
namespace NetCoreTests.Linq
{
public class FirstLast
{
[Fact]
public async Task FirstTest()
{
{
await Assert.ThrowsAsync<InvalidOperationException>(async () => await Enumerable.Empty<int>().ToUniTaskAsyncEnumerable().FirstAsync());
Assert.Throws<InvalidOperationException>(() => Enumerable.Empty<int>().First());
var x = await new[] { 99 }.ToUniTaskAsyncEnumerable().FirstAsync();
var y = new[] { 99 }.First();
x.Should().Be(y);
}
{
var array = new[] { 99, 11, 135, 10, 144, 800 };
await Assert.ThrowsAsync<InvalidOperationException>(async () => await array.ToUniTaskAsyncEnumerable().FirstAsync(x => x % 98 == 0));
Assert.Throws<InvalidOperationException>(() => array.First(x => x % 98 == 0));
var x = await array.ToUniTaskAsyncEnumerable().FirstAsync(x => x % 2 == 0);
var y = array.First(x => x % 2 == 0);
x.Should().Be(y);
}
{
var x = await Enumerable.Empty<int>().ToUniTaskAsyncEnumerable().FirstOrDefaultAsync();
var y = Enumerable.Empty<int>().FirstOrDefault();
x.Should().Be(y);
}
{
var x = await new[] { 99 }.ToUniTaskAsyncEnumerable().FirstOrDefaultAsync();
var y = new[] { 99 }.FirstOrDefault();
x.Should().Be(y);
}
{
var array = new[] { 99, 11, 135, 10, 144, 800 };
var x = await array.ToUniTaskAsyncEnumerable().FirstOrDefaultAsync(x => x % 98 == 0);
var y = array.FirstOrDefault(x => x % 98 == 0);
x.Should().Be(y);
}
{
var array = new[] { 99, 11, 135, 10, 144, 800 };
var x = await array.ToUniTaskAsyncEnumerable().FirstAsync(x => x % 2 == 0);
var y = array.FirstOrDefault(x => x % 2 == 0);
x.Should().Be(y);
}
}
[Fact]
public async Task LastTest()
{
{
await Assert.ThrowsAsync<InvalidOperationException>(async () => await Enumerable.Empty<int>().ToUniTaskAsyncEnumerable().LastAsync());
Assert.Throws<InvalidOperationException>(() => Enumerable.Empty<int>().Last());
var x = await new[] { 99 }.ToUniTaskAsyncEnumerable().LastAsync();
var y = new[] { 99 }.Last();
x.Should().Be(y);
}
{
var array = new[] { 99, 11, 135, 10, 144, 800 };
await Assert.ThrowsAsync<InvalidOperationException>(async () => await array.ToUniTaskAsyncEnumerable().LastAsync(x => x % 98 == 0));
Assert.Throws<InvalidOperationException>(() => array.Last(x => x % 98 == 0));
var x = await array.ToUniTaskAsyncEnumerable().LastAsync(x => x % 2 == 0);
var y = array.Last(x => x % 2 == 0);
x.Should().Be(y);
}
{
var x = await Enumerable.Empty<int>().ToUniTaskAsyncEnumerable().LastOrDefaultAsync();
var y = Enumerable.Empty<int>().LastOrDefault();
x.Should().Be(y);
}
{
var x = await new[] { 99 }.ToUniTaskAsyncEnumerable().LastOrDefaultAsync();
var y = new[] { 99 }.LastOrDefault();
x.Should().Be(y);
}
{
var array = new[] { 99, 11, 135, 10, 144, 800 };
var x = await array.ToUniTaskAsyncEnumerable().LastOrDefaultAsync(x => x % 98 == 0);
var y = array.LastOrDefault(x => x % 98 == 0);
x.Should().Be(y);
}
{
var array = new[] { 99, 11, 135, 10, 144, 800 };
var x = await array.ToUniTaskAsyncEnumerable().LastOrDefaultAsync(x => x % 2 == 0);
var y = array.LastOrDefault(x => x % 2 == 0);
x.Should().Be(y);
}
}
[Fact]
public async Task SingleTest()
{
{
await Assert.ThrowsAsync<InvalidOperationException>(async () => await Enumerable.Empty<int>().ToUniTaskAsyncEnumerable().SingleAsync());
Assert.Throws<InvalidOperationException>(() => Enumerable.Empty<int>().Single());
var x = await new[] { 99 }.ToUniTaskAsyncEnumerable().SingleAsync();
var y = new[] { 99 }.Single();
x.Should().Be(y);
var array = new[] { 99, 11, 135, 10, 144, 800 };
await Assert.ThrowsAsync<InvalidOperationException>(async () => await array.ToUniTaskAsyncEnumerable().SingleAsync());
Assert.Throws<InvalidOperationException>(() => array.Single());
}
{
var array = new[] { 99, 11, 135, 10, 144, 800 };
// not found
await Assert.ThrowsAsync<InvalidOperationException>(async () => await array.ToUniTaskAsyncEnumerable().SingleAsync(x => x % 999 == 0));
Assert.Throws<InvalidOperationException>(() => array.Single(x => x % 999 == 0));
// found multi
await Assert.ThrowsAsync<InvalidOperationException>(async () => await array.ToUniTaskAsyncEnumerable().SingleAsync(x => x % 2 == 0));
Assert.Throws<InvalidOperationException>(() => array.Single(x => x % 2 == 0));
{
var x = await array.ToUniTaskAsyncEnumerable().SingleAsync(x => x % 144 == 0);
var y = array.Single(x => x % 144 == 0);
x.Should().Be(y);
}
{
var x = await array.ToUniTaskAsyncEnumerable().SingleAsync(x => x % 800 == 0);
var y = array.Single(x => x % 800 == 0);
x.Should().Be(y);
}
}
{
{
var x = await Enumerable.Empty<int>().ToUniTaskAsyncEnumerable().SingleOrDefaultAsync();
var y = Enumerable.Empty<int>().SingleOrDefault();
x.Should().Be(y);
}
{
var x = await new[] { 99 }.ToUniTaskAsyncEnumerable().SingleOrDefaultAsync();
var y = new[] { 99 }.SingleOrDefault();
x.Should().Be(y);
var array = new[] { 99, 11, 135, 10, 144, 800 };
await Assert.ThrowsAsync<InvalidOperationException>(async () => await array.ToUniTaskAsyncEnumerable().SingleOrDefaultAsync());
Assert.Throws<InvalidOperationException>(() => array.SingleOrDefault());
}
{
var array = new[] { 99, 11, 135, 10, 144, 800 };
// not found
{
var x = await array.ToUniTaskAsyncEnumerable().SingleOrDefaultAsync(x => x % 999 == 0);
var y = array.SingleOrDefault(x => x % 999 == 0);
x.Should().Be(y);
}
// found multi
await Assert.ThrowsAsync<InvalidOperationException>(async () => await array.ToUniTaskAsyncEnumerable().SingleOrDefaultAsync(x => x % 2 == 0));
Assert.Throws<InvalidOperationException>(() => array.SingleOrDefault(x => x % 2 == 0));
// normal
{
var x = await array.ToUniTaskAsyncEnumerable().SingleOrDefaultAsync(x => x % 144 == 0);
var y = array.SingleOrDefault(x => x % 144 == 0);
x.Should().Be(y);
}
{
var x = await array.ToUniTaskAsyncEnumerable().SingleOrDefaultAsync(x => x % 800 == 0);
var y = array.SingleOrDefault(x => x % 800 == 0);
x.Should().Be(y);
}
}
}
}
[Fact]
public async Task ElementAtTest()
{
{
await Assert.ThrowsAsync<ArgumentOutOfRangeException>(async () => await Enumerable.Empty<int>().ToUniTaskAsyncEnumerable().ElementAtAsync(0));
Assert.Throws<ArgumentOutOfRangeException>(() => Enumerable.Empty<int>().ElementAt(0));
var x = await new[] { 99 }.ToUniTaskAsyncEnumerable().ElementAtAsync(0);
var y = new[] { 99 }.ElementAt(0);
x.Should().Be(y);
}
{
var array = new[] { 99, 11, 135, 10, 144, 800 };
await Assert.ThrowsAsync<ArgumentOutOfRangeException>(async () => await array.ToUniTaskAsyncEnumerable().ElementAtAsync(10));
Assert.Throws<ArgumentOutOfRangeException>(() => array.ElementAt(10));
{
var x = await array.ToUniTaskAsyncEnumerable().ElementAtAsync(0);
var y = array.ElementAt(0);
x.Should().Be(y);
}
{
var x = await array.ToUniTaskAsyncEnumerable().ElementAtAsync(3);
var y = array.ElementAt(3);
x.Should().Be(y);
}
{
var x = await array.ToUniTaskAsyncEnumerable().ElementAtAsync(5);
var y = array.ElementAt(5);
x.Should().Be(y);
}
}
{
{
var x = await Enumerable.Empty<int>().ToUniTaskAsyncEnumerable().ElementAtOrDefaultAsync(0);
var y = Enumerable.Empty<int>().ElementAtOrDefault(0);
x.Should().Be(y);
}
{
var x = await new[] { 99 }.ToUniTaskAsyncEnumerable().ElementAtOrDefaultAsync(0);
var y = new[] { 99 }.ElementAtOrDefault(0);
x.Should().Be(y);
}
}
{
var array = new[] { 99, 11, 135, 10, 144, 800 };
{
var x = await array.ToUniTaskAsyncEnumerable().ElementAtOrDefaultAsync(10);
var y = array.ElementAtOrDefault(10);
x.Should().Be(y);
}
{
var x = await array.ToUniTaskAsyncEnumerable().ElementAtOrDefaultAsync(0);
var y = array.ElementAtOrDefault(0);
x.Should().Be(y);
}
{
var x = await array.ToUniTaskAsyncEnumerable().ElementAtOrDefaultAsync(3);
var y = array.ElementAtOrDefault(3);
x.Should().Be(y);
}
{
var x = await array.ToUniTaskAsyncEnumerable().ElementAtOrDefaultAsync(5);
var y = array.ElementAtOrDefault(5);
x.Should().Be(y);
}
}
}
}
}

View File

@ -1,253 +0,0 @@
using Cysharp.Threading.Tasks;
using Cysharp.Threading.Tasks.Linq;
using FluentAssertions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Concurrency;
using System.Reactive.Linq;
using System.Threading;
using System.Threading.Tasks;
using Xunit;
namespace NetCoreTests.Linq
{
public class Joins
{
static int rd;
static UniTask<T> RandomRun<T>(T value)
{
if (Interlocked.Increment(ref rd) % 2 == 0)
{
return UniTask.Run(() => value);
}
else
{
return UniTask.FromResult(value);
}
}
[Fact]
public async Task Join()
{
var outer = new[] { 1, 2, 4, 5, 8, 10, 14, 4, 8, 1, 2, 10 };
var inner = new[] { 1, 2, 1, 2, 1, 14, 2 };
var xs = await outer.ToUniTaskAsyncEnumerable().Join(inner.ToUniTaskAsyncEnumerable(), x => x, x => x, (x, y) => (x, y)).ToArrayAsync();
var ys = outer.Join(inner, x => x, x => x, (x, y) => (x, y)).ToArray();
xs.Should().Equal(ys);
}
[Fact]
public async Task JoinThrow()
{
var outer = new[] { 1, 2, 4, 5, 8, 10, 14, 4, 8, 1, 2, 10 };
var inner = new[] { 1, 2, 1, 2, 1, 14, 2 };
foreach (var item in UniTaskTestException.Throws())
{
var xs = outer.ToUniTaskAsyncEnumerable().Join(item, x => x, x => x, (x, y) => x + y).ToArrayAsync();
var ys = item.Join(inner.ToUniTaskAsyncEnumerable(), x => x, x => x, (x, y) => x + y).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
await Assert.ThrowsAsync<UniTaskTestException>(async () => await ys);
}
}
[Fact]
public async Task JoinAwait()
{
var outer = new[] { 1, 2, 4, 5, 8, 10, 14, 4, 8, 1, 2, 10 };
var inner = new[] { 1, 2, 1, 2, 1, 14, 2 };
var xs = await outer.ToUniTaskAsyncEnumerable().JoinAwait(inner.ToUniTaskAsyncEnumerable(), x => RandomRun(x), x => RandomRun(x), (x, y) => RandomRun((x, y))).ToArrayAsync();
var ys = outer.Join(inner, x => x, x => x, (x, y) => (x, y)).ToArray();
xs.Should().Equal(ys);
}
[Fact]
public async Task JoinAwaitThrow()
{
var outer = new[] { 1, 2, 4, 5, 8, 10, 14, 4, 8, 1, 2, 10 };
var inner = new[] { 1, 2, 1, 2, 1, 14, 2 };
foreach (var item in UniTaskTestException.Throws())
{
var xs = outer.ToUniTaskAsyncEnumerable().JoinAwait(item, x => RandomRun(x), x => RandomRun(x), (x, y) => RandomRun(x + y)).ToArrayAsync();
var ys = item.Join(inner.ToUniTaskAsyncEnumerable(), x => x, x => x, (x, y) => x + y).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
await Assert.ThrowsAsync<UniTaskTestException>(async () => await ys);
}
}
[Fact]
public async Task JoinAwaitCt()
{
var outer = new[] { 1, 2, 4, 5, 8, 10, 14, 4, 8, 1, 2, 10 };
var inner = new[] { 1, 2, 1, 2, 1, 14, 2 };
var xs = await outer.ToUniTaskAsyncEnumerable().JoinAwaitWithCancellation(inner.ToUniTaskAsyncEnumerable(), (x, _) => RandomRun(x), (x, _) => RandomRun(x), (x, y, _) => RandomRun((x, y))).ToArrayAsync();
var ys = outer.Join(inner, x => x, x => x, (x, y) => (x, y)).ToArray();
xs.Should().Equal(ys);
}
[Fact]
public async Task JoinAwaitCtThrow()
{
var outer = new[] { 1, 2, 4, 5, 8, 10, 14, 4, 8, 1, 2, 10 };
var inner = new[] { 1, 2, 1, 2, 1, 14, 2 };
foreach (var item in UniTaskTestException.Throws())
{
var xs = outer.ToUniTaskAsyncEnumerable().JoinAwaitWithCancellation(item, (x, _) => RandomRun(x), (x, _) => RandomRun(x), (x, y, _) => RandomRun(x + y)).ToArrayAsync();
var ys = item.JoinAwaitWithCancellation(inner.ToUniTaskAsyncEnumerable(), (x, _) => RandomRun(x), (x, _) => RandomRun(x), (x, y, _) => RandomRun(x + y)).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
await Assert.ThrowsAsync<UniTaskTestException>(async () => await ys);
}
}
[Fact]
public async Task GroupBy()
{
var arr = new[] { 1, 4, 10, 10, 4, 5, 10, 9 };
{
var xs = await arr.ToUniTaskAsyncEnumerable().GroupBy(x => x).ToArrayAsync();
var ys = arr.GroupBy(x => x).ToArray();
xs.Length.Should().Be(ys.Length);
xs.Should().BeEquivalentTo(ys);
}
{
var xs = await arr.ToUniTaskAsyncEnumerable().GroupBy(x => x, (key, xs) => (key, xs.ToArray())).ToArrayAsync();
var ys = arr.GroupBy(x => x, (key, xs) => (key, xs.ToArray())).ToArray();
xs.Length.Should().Be(ys.Length);
xs.OrderBy(x => x.key).SelectMany(x => x.Item2).Should().Equal(ys.OrderBy(x => x.key).SelectMany(x => x.Item2));
}
{
var xs = await arr.ToUniTaskAsyncEnumerable().GroupByAwait(x => RandomRun(x)).ToArrayAsync();
var ys = arr.GroupBy(x => x).ToArray();
xs.Length.Should().Be(ys.Length);
xs.Should().BeEquivalentTo(ys);
}
{
var xs = await arr.ToUniTaskAsyncEnumerable().GroupByAwait(x => RandomRun(x), (key, xs) => RandomRun((key, xs.ToArray()))).ToArrayAsync();
var ys = arr.GroupBy(x => x, (key, xs) => (key, xs.ToArray())).ToArray();
xs.Length.Should().Be(ys.Length);
xs.OrderBy(x => x.key).SelectMany(x => x.Item2).Should().Equal(ys.OrderBy(x => x.key).SelectMany(x => x.Item2));
}
{
var xs = await arr.ToUniTaskAsyncEnumerable().GroupByAwaitWithCancellation((x, _) => RandomRun(x)).ToArrayAsync();
var ys = arr.GroupBy(x => x).ToArray();
xs.Length.Should().Be(ys.Length);
xs.Should().BeEquivalentTo(ys);
}
{
var xs = await arr.ToUniTaskAsyncEnumerable().GroupByAwaitWithCancellation((x, _) => RandomRun(x), (key, xs, _) => RandomRun((key, xs.ToArray()))).ToArrayAsync();
var ys = arr.GroupBy(x => x, (key, xs) => (key, xs.ToArray())).ToArray();
xs.Length.Should().Be(ys.Length);
xs.OrderBy(x => x.key).SelectMany(x => x.Item2).Should().Equal(ys.OrderBy(x => x.key).SelectMany(x => x.Item2));
}
}
[Fact]
public async Task GroupByThrow()
{
var arr = new[] { 1, 4, 10, 10, 4, 5, 10, 9 };
foreach (var item in UniTaskTestException.Throws())
{
var xs = item.GroupBy(x => x).ToArrayAsync();
var ys = item.GroupByAwait(x => RandomRun(x)).ToArrayAsync();
var zs = item.GroupByAwaitWithCancellation((x, _) => RandomRun(x)).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
await Assert.ThrowsAsync<UniTaskTestException>(async () => await ys);
await Assert.ThrowsAsync<UniTaskTestException>(async () => await zs);
}
}
[Fact]
public async Task GroupJoin()
{
var outer = new[] { 1, 2, 4, 5, 8, 10, 14, 4, 8, 1, 2, 10 };
var inner = new[] { 1, 2, 1, 2, 1, 14, 2 };
{
var xs = await outer.ToUniTaskAsyncEnumerable().GroupJoin(inner.ToUniTaskAsyncEnumerable(), x => x, x => x, (x, y) => (x, string.Join(", ", y))).ToArrayAsync();
var ys = outer.GroupJoin(inner, x => x, x => x, (x, y) => (x, string.Join(", ", y))).ToArray();
xs.Length.Should().Be(ys.Length);
xs.Should().Equal(ys);
}
{
var xs = await outer.ToUniTaskAsyncEnumerable().GroupJoinAwait(inner.ToUniTaskAsyncEnumerable(), x => RandomRun(x), x => RandomRun(x), (x, y) => RandomRun((x, string.Join(", ", y)))).ToArrayAsync();
var ys = outer.GroupJoin(inner, x => x, x => x, (x, y) => (x, string.Join(", ", y))).ToArray();
xs.Length.Should().Be(ys.Length);
xs.Should().Equal(ys);
}
{
var xs = await outer.ToUniTaskAsyncEnumerable().GroupJoinAwaitWithCancellation(inner.ToUniTaskAsyncEnumerable(), (x, _) => RandomRun(x), (x, _) => RandomRun(x), (x, y, _) => RandomRun((x, string.Join(", ", y)))).ToArrayAsync();
var ys = outer.GroupJoin(inner, x => x, x => x, (x, y) => (x, string.Join(", ", y))).ToArray();
xs.Length.Should().Be(ys.Length);
xs.Should().Equal(ys);
}
}
[Fact]
public async Task GroupJoinThrow()
{
var outer = new[] { 1, 2, 4, 5, 8, 10, 14, 4, 8, 1, 2, 10 }.ToUniTaskAsyncEnumerable();
var inner = new[] { 1, 2, 1, 2, 1, 14, 2 }.ToUniTaskAsyncEnumerable();
foreach (var item in UniTaskTestException.Throws())
{
{
var xs = item.GroupJoin(outer, x => x, x => x, (x, y) => x).ToArrayAsync();
var ys = inner.GroupJoin(item, x => x, x => x, (x, y) => x).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
await Assert.ThrowsAsync<UniTaskTestException>(async () => await ys);
}
{
var xs = item.GroupJoinAwait(outer, x => RandomRun(x), x => RandomRun(x), (x, y) => RandomRun(x)).ToArrayAsync();
var ys = inner.GroupJoinAwait(item, x => RandomRun(x), x => RandomRun(x), (x, y) => RandomRun(x)).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
await Assert.ThrowsAsync<UniTaskTestException>(async () => await ys);
}
{
var xs = item.GroupJoinAwaitWithCancellation(outer, (x, _) => RandomRun(x), (x, _) => RandomRun(x), (x, y, _) => RandomRun(x)).ToArrayAsync();
var ys = inner.GroupJoinAwaitWithCancellation(item, (x, _) => RandomRun(x), (x, _) => RandomRun(x), (x, y, _) => RandomRun(x)).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
await Assert.ThrowsAsync<UniTaskTestException>(async () => await ys);
}
}
}
}
}

View File

@ -1,139 +0,0 @@
#pragma warning disable CS1998
using System;
using System.Threading;
using System.Threading.Tasks;
using Cysharp.Threading.Tasks;
using Cysharp.Threading.Tasks.Linq;
using FluentAssertions;
using Xunit;
namespace NetCoreTests.Linq
{
public class MergeTest
{
[Fact]
public async Task TwoSource()
{
var semaphore = new SemaphoreSlim(1, 1);
var a = UniTaskAsyncEnumerable.Create<string>(async (writer, _) =>
{
await UniTask.SwitchToThreadPool();
await semaphore.WaitAsync();
await writer.YieldAsync("A1");
semaphore.Release();
await semaphore.WaitAsync();
await writer.YieldAsync("A2");
semaphore.Release();
});
var b = UniTaskAsyncEnumerable.Create<string>(async (writer, _) =>
{
await UniTask.SwitchToThreadPool();
await semaphore.WaitAsync();
await writer.YieldAsync("B1");
await writer.YieldAsync("B2");
semaphore.Release();
await semaphore.WaitAsync();
await writer.YieldAsync("B3");
semaphore.Release();
});
var result = await a.Merge(b).ToArrayAsync();
result.Should().Equal("A1", "B1", "B2", "A2", "B3");
}
[Fact]
public async Task ThreeSource()
{
var semaphore = new SemaphoreSlim(0, 1);
var a = UniTaskAsyncEnumerable.Create<string>(async (writer, _) =>
{
await UniTask.SwitchToThreadPool();
await semaphore.WaitAsync();
await writer.YieldAsync("A1");
semaphore.Release();
await semaphore.WaitAsync();
await writer.YieldAsync("A2");
semaphore.Release();
});
var b = UniTaskAsyncEnumerable.Create<string>(async (writer, _) =>
{
await UniTask.SwitchToThreadPool();
await semaphore.WaitAsync();
await writer.YieldAsync("B1");
await writer.YieldAsync("B2");
semaphore.Release();
await semaphore.WaitAsync();
await writer.YieldAsync("B3");
semaphore.Release();
});
var c = UniTaskAsyncEnumerable.Create<string>(async (writer, _) =>
{
await UniTask.SwitchToThreadPool();
await writer.YieldAsync("C1");
semaphore.Release();
});
var result = await a.Merge(b, c).ToArrayAsync();
result.Should().Equal("C1", "A1", "B1", "B2", "A2", "B3");
}
[Fact]
public async Task Throw()
{
var a = UniTaskAsyncEnumerable.Create<string>(async (writer, _) =>
{
await writer.YieldAsync("A1");
});
var b = UniTaskAsyncEnumerable.Create<string>(async (writer, _) =>
{
throw new UniTaskTestException();
});
var enumerator = a.Merge(b).GetAsyncEnumerator();
(await enumerator.MoveNextAsync()).Should().Be(true);
enumerator.Current.Should().Be("A1");
await Assert.ThrowsAsync<UniTaskTestException>(async () => await enumerator.MoveNextAsync());
}
[Fact]
public async Task Cancel()
{
var cts = new CancellationTokenSource();
var a = UniTaskAsyncEnumerable.Create<string>(async (writer, _) =>
{
await writer.YieldAsync("A1");
});
var b = UniTaskAsyncEnumerable.Create<string>(async (writer, _) =>
{
await writer.YieldAsync("B1");
});
var enumerator = a.Merge(b).GetAsyncEnumerator(cts.Token);
(await enumerator.MoveNextAsync()).Should().Be(true);
enumerator.Current.Should().Be("A1");
cts.Cancel();
await Assert.ThrowsAsync<OperationCanceledException>(async () => await enumerator.MoveNextAsync());
}
}
}

View File

@ -1,285 +0,0 @@
using Cysharp.Threading.Tasks;
using Cysharp.Threading.Tasks.Linq;
using FluentAssertions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Concurrency;
using System.Reactive.Linq;
using System.Threading.Tasks;
using Xunit;
namespace NetCoreTests.Linq
{
public class Paging
{
[Theory]
[InlineData(0, 0)]
[InlineData(0, 1)]
[InlineData(9, 0)]
[InlineData(9, 1)]
[InlineData(9, 5)]
[InlineData(9, 9)]
[InlineData(9, 15)]
public async Task Skip(int collection, int skipCount)
{
var xs = await UniTaskAsyncEnumerable.Range(1, collection).Skip(skipCount).ToArrayAsync();
var ys = Enumerable.Range(1, collection).Skip(skipCount).ToArray();
xs.Should().Equal(ys);
}
[Fact]
public async Task SkipException()
{
foreach (var item in UniTaskTestException.Throws())
{
var xs = item.Skip(5).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
}
[Theory]
[InlineData(0, 0)]
[InlineData(0, 1)]
[InlineData(9, 0)]
[InlineData(9, 1)]
[InlineData(9, 5)]
[InlineData(9, 9)]
[InlineData(9, 15)]
public async Task SkipLast(int collection, int skipCount)
{
var xs = await UniTaskAsyncEnumerable.Range(1, collection).SkipLast(skipCount).ToArrayAsync();
var ys = Enumerable.Range(1, collection).SkipLast(skipCount).ToArray();
xs.Should().Equal(ys);
}
[Fact]
public async Task SkipLastException()
{
foreach (var item in UniTaskTestException.Throws())
{
var xs = item.SkipLast(5).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
}
[Theory]
[InlineData(0, 0)]
[InlineData(0, 1)]
[InlineData(9, 0)]
[InlineData(9, 1)]
[InlineData(9, 5)]
[InlineData(9, 9)]
[InlineData(9, 15)]
public async Task TakeLast(int collection, int takeCount)
{
var xs = await UniTaskAsyncEnumerable.Range(1, collection).TakeLast(takeCount).ToArrayAsync();
var ys = Enumerable.Range(1, collection).TakeLast(takeCount).ToArray();
xs.Should().Equal(ys);
}
[Fact]
public async Task TakeLastException()
{
foreach (var item in UniTaskTestException.Throws())
{
var xs = item.TakeLast(5).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
}
[Theory]
[InlineData(0, 0)]
[InlineData(0, 1)]
[InlineData(9, 0)]
[InlineData(9, 1)]
[InlineData(9, 5)]
[InlineData(9, 9)]
[InlineData(9, 15)]
public async Task Take(int collection, int takeCount)
{
var xs = await UniTaskAsyncEnumerable.Range(1, collection).Take(takeCount).ToArrayAsync();
var ys = Enumerable.Range(1, collection).Take(takeCount).ToArray();
xs.Should().Equal(ys);
}
[Fact]
public async Task TakeException()
{
foreach (var item in UniTaskTestException.Throws())
{
var xs = item.Take(5).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
}
[Theory]
[InlineData(0, 0)]
[InlineData(0, 1)]
[InlineData(9, 0)]
[InlineData(9, 1)]
[InlineData(9, 5)]
[InlineData(9, 9)]
[InlineData(9, 15)]
public async Task SkipWhile(int collection, int skipCount)
{
{
var xs = await UniTaskAsyncEnumerable.Range(1, collection).SkipWhile(x => x < skipCount).ToArrayAsync();
var ys = Enumerable.Range(1, collection).SkipWhile(x => x < skipCount).ToArray();
xs.Should().Equal(ys);
}
{
var xs = await UniTaskAsyncEnumerable.Range(1, collection).SkipWhile((x, i) => x < (skipCount - i)).ToArrayAsync();
var ys = Enumerable.Range(1, collection).SkipWhile((x, i) => x < (skipCount - i)).ToArray();
xs.Should().Equal(ys);
}
{
var xs = await UniTaskAsyncEnumerable.Range(1, collection).SkipWhileAwait(x => UniTask.Run(() => x < skipCount)).ToArrayAsync();
var ys = Enumerable.Range(1, collection).SkipWhile(x => x < skipCount).ToArray();
xs.Should().Equal(ys);
}
{
var xs = await UniTaskAsyncEnumerable.Range(1, collection).SkipWhileAwait((x, i) => UniTask.Run(() => x < (skipCount - i))).ToArrayAsync();
var ys = Enumerable.Range(1, collection).SkipWhile((x, i) => x < (skipCount - i)).ToArray();
xs.Should().Equal(ys);
}
{
var xs = await UniTaskAsyncEnumerable.Range(1, collection).SkipWhileAwaitWithCancellation((x, _) => UniTask.Run(() => x < skipCount)).ToArrayAsync();
var ys = Enumerable.Range(1, collection).SkipWhile(x => x < skipCount).ToArray();
xs.Should().Equal(ys);
}
{
var xs = await UniTaskAsyncEnumerable.Range(1, collection).SkipWhileAwaitWithCancellation((x, i, _) => UniTask.Run(() => x < (skipCount - i))).ToArrayAsync();
var ys = Enumerable.Range(1, collection).SkipWhile((x, i) => x < (skipCount - i)).ToArray();
xs.Should().Equal(ys);
}
}
[Fact]
public async Task SkipWhileException()
{
foreach (var item in UniTaskTestException.Throws())
{
var xs = item.SkipWhile(x => x < 2).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
foreach (var item in UniTaskTestException.Throws())
{
var xs = item.SkipWhile((x, i) => x < 2).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
foreach (var item in UniTaskTestException.Throws())
{
var xs = item.SkipWhileAwait((x) => UniTask.Run(() => x < 2)).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
foreach (var item in UniTaskTestException.Throws())
{
var xs = item.SkipWhileAwait((x, i) => UniTask.Run(() => x < 2)).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
foreach (var item in UniTaskTestException.Throws())
{
var xs = item.SkipWhileAwaitWithCancellation((x, _) => UniTask.Run(() => x < 2)).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
foreach (var item in UniTaskTestException.Throws())
{
var xs = item.SkipWhileAwaitWithCancellation((x, i, _) => UniTask.Run(() => x < 2)).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
}
[Theory]
[InlineData(0, 0)]
[InlineData(0, 1)]
[InlineData(9, 0)]
[InlineData(9, 1)]
[InlineData(9, 5)]
[InlineData(9, 9)]
[InlineData(9, 15)]
public async Task TakeWhile(int collection, int skipCount)
{
{
var xs = await UniTaskAsyncEnumerable.Range(1, collection).TakeWhile(x => x < skipCount).ToArrayAsync();
var ys = Enumerable.Range(1, collection).TakeWhile(x => x < skipCount).ToArray();
xs.Should().Equal(ys);
}
{
var xs = await UniTaskAsyncEnumerable.Range(1, collection).TakeWhile((x, i) => x < (skipCount - i)).ToArrayAsync();
var ys = Enumerable.Range(1, collection).TakeWhile((x, i) => x < (skipCount - i)).ToArray();
xs.Should().Equal(ys);
}
{
var xs = await UniTaskAsyncEnumerable.Range(1, collection).TakeWhileAwait(x => UniTask.Run(() => x < skipCount)).ToArrayAsync();
var ys = Enumerable.Range(1, collection).TakeWhile(x => x < skipCount).ToArray();
xs.Should().Equal(ys);
}
{
var xs = await UniTaskAsyncEnumerable.Range(1, collection).TakeWhileAwait((x, i) => UniTask.Run(() => x < (skipCount - i))).ToArrayAsync();
var ys = Enumerable.Range(1, collection).TakeWhile((x, i) => x < (skipCount - i)).ToArray();
xs.Should().Equal(ys);
}
{
var xs = await UniTaskAsyncEnumerable.Range(1, collection).TakeWhileAwaitWithCancellation((x, _) => UniTask.Run(() => x < skipCount)).ToArrayAsync();
var ys = Enumerable.Range(1, collection).TakeWhile(x => x < skipCount).ToArray();
xs.Should().Equal(ys);
}
{
var xs = await UniTaskAsyncEnumerable.Range(1, collection).TakeWhileAwaitWithCancellation((x, i, _) => UniTask.Run(() => x < (skipCount - i))).ToArrayAsync();
var ys = Enumerable.Range(1, collection).TakeWhile((x, i) => x < (skipCount - i)).ToArray();
xs.Should().Equal(ys);
}
}
[Fact]
public async Task TakeWhileException()
{
foreach (var item in UniTaskTestException.Throws())
{
var xs = item.TakeWhile(x => x < 5).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
foreach (var item in UniTaskTestException.Throws())
{
var xs = item.TakeWhile((x, i) => x < 5).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
foreach (var item in UniTaskTestException.Throws())
{
var xs = item.TakeWhileAwait((x) => UniTask.Run(() => x < 5)).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
foreach (var item in UniTaskTestException.Throws())
{
var xs = item.TakeWhileAwait((x, i) => UniTask.Run(() => x < 5)).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
foreach (var item in UniTaskTestException.Throws())
{
var xs = item.TakeWhileAwaitWithCancellation((x, _) => UniTask.Run(() => x < 5)).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
foreach (var item in UniTaskTestException.Throws())
{
var xs = item.TakeWhileAwaitWithCancellation((x, i, _) => UniTask.Run(() => x < 5)).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
}
}
}

View File

@ -1,437 +0,0 @@
using Cysharp.Threading.Tasks;
using Cysharp.Threading.Tasks.Linq;
using FluentAssertions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Concurrency;
using System.Reactive.Linq;
using System.Threading.Tasks;
using Xunit;
namespace NetCoreTests.Linq
{
public class Projection
{
[Theory]
[InlineData(0, 0)]
[InlineData(0, 1)]
[InlineData(0, 2)]
[InlineData(0, 10)]
public async Task Reverse(int start, int count)
{
var xs = await Enumerable.Range(start, count).ToUniTaskAsyncEnumerable().Reverse().ToArrayAsync();
var ys = Enumerable.Range(start, count).Reverse().ToArray();
xs.Should().Equal(ys);
}
[Fact]
public async Task ReverseException()
{
foreach (var item in UniTaskTestException.Throws())
{
var xs = item.Reverse().ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
}
[Theory]
[InlineData(0)]
[InlineData(1)]
[InlineData(9)]
public async Task Select(int count)
{
{
var xs = await UniTaskAsyncEnumerable.Range(1, count).Select(x => x * x).ToArrayAsync();
var ys = Enumerable.Range(1, count).Select(x => x * x).ToArray();
xs.Should().Equal(ys);
var zs = await UniTaskAsyncEnumerable.Range(1, count).SelectAwait((x) => UniTask.Run(() => x * x)).ToArrayAsync();
zs.Should().Equal(ys);
}
{
var xs = await UniTaskAsyncEnumerable.Range(1, count).Select((x, i) => x * x * i).ToArrayAsync();
var ys = Enumerable.Range(1, count).Select((x, i) => x * x * i).ToArray();
xs.Should().Equal(ys);
var zs = await UniTaskAsyncEnumerable.Range(1, count).SelectAwait((x, i) => UniTask.Run(() => x * x * i)).ToArrayAsync();
zs.Should().Equal(ys);
}
}
[Fact]
public async Task SelectException()
{
foreach (var item in UniTaskTestException.Throws())
{
var xs = item.Select(x => UniTaskAsyncEnumerable.Range(0, 1)).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
// await
foreach (var item in UniTaskTestException.Throws())
{
var xs = item.SelectAwait(x => UniTask.Run(() => UniTaskAsyncEnumerable.Range(0, 1))).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
// cancel
foreach (var item in UniTaskTestException.Throws())
{
var xs = item.SelectAwaitWithCancellation((x, _) => UniTask.Run(() => UniTaskAsyncEnumerable.Range(0, 1))).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
}
[Theory]
[InlineData(0, 9)] // empty + exists
[InlineData(9, 0)] // exists + empty
[InlineData(9, 9)] // exists + exists
public async Task SelectMany(int leftCount, int rightCount)
{
{
var xs = await UniTaskAsyncEnumerable.Range(1, leftCount).SelectMany(x => UniTaskAsyncEnumerable.Range(99, rightCount * x)).ToArrayAsync();
var ys = Enumerable.Range(1, leftCount).SelectMany(x => Enumerable.Range(99, rightCount * x)).ToArray();
xs.Should().Equal(ys);
}
{
var xs = await UniTaskAsyncEnumerable.Range(1, leftCount).SelectMany((i, x) => UniTaskAsyncEnumerable.Range(99 * i, rightCount * x)).ToArrayAsync();
var ys = Enumerable.Range(1, leftCount).SelectMany((i, x) => Enumerable.Range(99 * i, rightCount * x)).ToArray();
xs.Should().Equal(ys);
}
{
var xs = await UniTaskAsyncEnumerable.Range(1, leftCount).SelectMany(x => UniTaskAsyncEnumerable.Range(99, rightCount * x), (x, y) => x * y).ToArrayAsync();
var ys = Enumerable.Range(1, leftCount).SelectMany(x => Enumerable.Range(99, rightCount * x), (x, y) => x * y).ToArray();
xs.Should().Equal(ys);
}
{
var xs = await UniTaskAsyncEnumerable.Range(1, leftCount).SelectMany((i, x) => UniTaskAsyncEnumerable.Range(99 * i, rightCount * x), (x, y) => x * y).ToArrayAsync();
var ys = Enumerable.Range(1, leftCount).SelectMany((i, x) => Enumerable.Range(99 * i, rightCount * x), (x, y) => x * y).ToArray();
xs.Should().Equal(ys);
}
// await
{
var xs = await UniTaskAsyncEnumerable.Range(1, leftCount).SelectManyAwait(x => UniTask.Run(() => UniTaskAsyncEnumerable.Range(99, rightCount * x))).ToArrayAsync();
var ys = Enumerable.Range(1, leftCount).SelectMany(x => Enumerable.Range(99, rightCount * x)).ToArray();
xs.Should().Equal(ys);
}
{
var xs = await UniTaskAsyncEnumerable.Range(1, leftCount).SelectManyAwait((i, x) => UniTask.Run(() => UniTaskAsyncEnumerable.Range(99 * i, rightCount * x))).ToArrayAsync();
var ys = Enumerable.Range(1, leftCount).SelectMany((i, x) => Enumerable.Range(99 * i, rightCount * x)).ToArray();
xs.Should().Equal(ys);
}
{
var xs = await UniTaskAsyncEnumerable.Range(1, leftCount).SelectManyAwait(x => UniTask.Run(() => UniTaskAsyncEnumerable.Range(99, rightCount * x)), (x, y) => UniTask.Run(() => x * y)).ToArrayAsync();
var ys = Enumerable.Range(1, leftCount).SelectMany(x => Enumerable.Range(99, rightCount * x), (x, y) => x * y).ToArray();
xs.Should().Equal(ys);
}
{
var xs = await UniTaskAsyncEnumerable.Range(1, leftCount).SelectManyAwait((i, x) => UniTask.Run(() => UniTaskAsyncEnumerable.Range(99 * i, rightCount * x)), (x, y) => UniTask.Run(() => x * y)).ToArrayAsync();
var ys = Enumerable.Range(1, leftCount).SelectMany((i, x) => Enumerable.Range(99 * i, rightCount * x), (x, y) => x * y).ToArray();
xs.Should().Equal(ys);
}
// with cancel
{
var xs = await UniTaskAsyncEnumerable.Range(1, leftCount).SelectManyAwaitWithCancellation((x, _) => UniTask.Run(() => UniTaskAsyncEnumerable.Range(99, rightCount * x))).ToArrayAsync();
var ys = Enumerable.Range(1, leftCount).SelectMany(x => Enumerable.Range(99, rightCount * x)).ToArray();
xs.Should().Equal(ys);
}
{
var xs = await UniTaskAsyncEnumerable.Range(1, leftCount).SelectManyAwaitWithCancellation((i, x, _) => UniTask.Run(() => UniTaskAsyncEnumerable.Range(99 * i, rightCount * x))).ToArrayAsync();
var ys = Enumerable.Range(1, leftCount).SelectMany((i, x) => Enumerable.Range(99 * i, rightCount * x)).ToArray();
xs.Should().Equal(ys);
}
{
var xs = await UniTaskAsyncEnumerable.Range(1, leftCount).SelectManyAwaitWithCancellation((x, _) => UniTask.Run(() => UniTaskAsyncEnumerable.Range(99, rightCount * x)), (x, y, _) => UniTask.Run(() => x * y)).ToArrayAsync();
var ys = Enumerable.Range(1, leftCount).SelectMany(x => Enumerable.Range(99, rightCount * x), (x, y) => x * y).ToArray();
xs.Should().Equal(ys);
}
{
var xs = await UniTaskAsyncEnumerable.Range(1, leftCount).SelectManyAwaitWithCancellation((i, x, _) => UniTask.Run(() => UniTaskAsyncEnumerable.Range(99 * i, rightCount * x)), (x, y, _) => UniTask.Run(() => x * y)).ToArrayAsync();
var ys = Enumerable.Range(1, leftCount).SelectMany((i, x) => Enumerable.Range(99 * i, rightCount * x), (x, y) => x * y).ToArray();
xs.Should().Equal(ys);
}
}
[Fact]
public async Task SelectManyException()
{
// error + exists
// exists + error
foreach (var item in UniTaskTestException.Throws())
{
var xs = item.SelectMany(x => UniTaskAsyncEnumerable.Range(0, 1)).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
foreach (var item in UniTaskTestException.Throws())
{
var xs = UniTaskAsyncEnumerable.Range(0, 1).SelectMany(x => item).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
// await
foreach (var item in UniTaskTestException.Throws())
{
var xs = item.SelectManyAwait(x => UniTask.Run(() => UniTaskAsyncEnumerable.Range(0, 1))).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
foreach (var item in UniTaskTestException.Throws())
{
var xs = UniTaskAsyncEnumerable.Range(0, 1).SelectManyAwait(x => UniTask.Run(() => item)).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
// with c
foreach (var item in UniTaskTestException.Throws())
{
var xs = item.SelectManyAwaitWithCancellation((x, _) => UniTask.Run(() => UniTaskAsyncEnumerable.Range(0, 1))).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
foreach (var item in UniTaskTestException.Throws())
{
var xs = UniTaskAsyncEnumerable.Range(0, 1).SelectManyAwaitWithCancellation((x, _) => UniTask.Run(() => item)).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
}
[Theory]
[InlineData(0, 9)] // empty + exists
[InlineData(9, 0)] // exists + empty
[InlineData(9, 9)] // same
[InlineData(9, 4)] // leftlong
[InlineData(4, 9)] // rightlong
public async Task Zip(int leftCount, int rightCount)
{
{
var xs = await UniTaskAsyncEnumerable.Range(1, leftCount).Zip(UniTaskAsyncEnumerable.Range(99, rightCount)).ToArrayAsync();
var ys = Enumerable.Range(1, leftCount).Zip(Enumerable.Range(99, rightCount)).ToArray();
xs.Should().Equal(ys);
}
{
var xs = await UniTaskAsyncEnumerable.Range(1, leftCount).ZipAwait(UniTaskAsyncEnumerable.Range(99, rightCount), (x, y) => UniTask.Run(() => (x, y))).ToArrayAsync();
var ys = Enumerable.Range(1, leftCount).Zip(Enumerable.Range(99, rightCount)).ToArray();
xs.Should().Equal(ys);
}
{
var xs = await UniTaskAsyncEnumerable.Range(1, leftCount).ZipAwaitWithCancellation(UniTaskAsyncEnumerable.Range(99, rightCount), (x, y, _) => UniTask.Run(() => (x, y))).ToArrayAsync();
var ys = Enumerable.Range(1, leftCount).Zip(Enumerable.Range(99, rightCount)).ToArray();
xs.Should().Equal(ys);
}
}
[Fact]
public async Task ZipException()
{
foreach (var item in UniTaskTestException.Throws())
{
var xs = item.Zip(UniTaskAsyncEnumerable.Range(1, 10)).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
foreach (var item in UniTaskTestException.Throws())
{
var xs = UniTaskAsyncEnumerable.Range(1, 10).Zip(item).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
// a
foreach (var item in UniTaskTestException.Throws())
{
var xs = item.ZipAwait(UniTaskAsyncEnumerable.Range(1, 10), (x, y) => UniTask.Run(() => (x, y))).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
foreach (var item in UniTaskTestException.Throws())
{
var xs = UniTaskAsyncEnumerable.Range(1, 10).ZipAwait(item, (x, y) => UniTask.Run(() => (x, y))).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
// c
foreach (var item in UniTaskTestException.Throws())
{
var xs = item.ZipAwaitWithCancellation(UniTaskAsyncEnumerable.Range(1, 10), (x, y, c) => UniTask.Run(() => (x, y))).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
foreach (var item in UniTaskTestException.Throws())
{
var xs = UniTaskAsyncEnumerable.Range(1, 10).ZipAwaitWithCancellation(item, (x, y, c) => UniTask.Run(() => (x, y))).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
}
[Theory]
// [InlineData(0, 0)]
[InlineData(0, 3)]
[InlineData(9, 1)]
[InlineData(9, 2)]
[InlineData(9, 3)]
[InlineData(17, 3)]
[InlineData(17, 16)]
[InlineData(17, 17)]
[InlineData(17, 27)]
public async Task Buffer(int rangeCount, int bufferCount)
{
var xs = await UniTaskAsyncEnumerable.Range(0, rangeCount).Buffer(bufferCount).Select(x => string.Join(",", x)).ToArrayAsync();
var ys = await AsyncEnumerable.Range(0, rangeCount).Buffer(bufferCount).Select(x => string.Join(",", x)).ToArrayAsync();
xs.Should().Equal(ys);
}
[Theory]
// [InlineData(0, 0)]
[InlineData(0, 3, 2)]
[InlineData(9, 1, 1)]
[InlineData(9, 2, 3)]
[InlineData(9, 3, 4)]
[InlineData(17, 3, 3)]
[InlineData(17, 16, 5)]
[InlineData(17, 17, 19)]
public async Task BufferSkip(int rangeCount, int bufferCount, int skipCount)
{
var xs = await UniTaskAsyncEnumerable.Range(0, rangeCount).Buffer(bufferCount, skipCount).Select(x => string.Join(",", x)).ToArrayAsync();
var ys = await AsyncEnumerable.Range(0, rangeCount).Buffer(bufferCount, skipCount).Select(x => string.Join(",", x)).ToArrayAsync();
xs.Should().Equal(ys);
}
[Fact]
public async Task BufferError()
{
foreach (var item in UniTaskTestException.Throws())
{
var xs = item.Buffer(3).ToArrayAsync();
var ys = item.Buffer(3, 2).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
await Assert.ThrowsAsync<UniTaskTestException>(async () => await ys);
}
}
[Fact]
public async Task CombineLatestOK()
{
var a = new AsyncReactiveProperty<int>(0);
var b = new AsyncReactiveProperty<int>(0);
var list = new List<(int, int)>();
var complete = a.WithoutCurrent().CombineLatest(b.WithoutCurrent(), (x, y) => (x, y)).ForEachAsync(x => list.Add(x));
list.Count.Should().Be(0);
a.Value = 10;
list.Count.Should().Be(0);
a.Value = 20;
list.Count.Should().Be(0);
b.Value = 1;
list.Count.Should().Be(1);
list[0].Should().Be((20, 1));
a.Value = 30;
list.Last().Should().Be((30, 1));
b.Value = 2;
list.Last().Should().Be((30, 2));
a.Dispose();
b.Value = 3;
list.Last().Should().Be((30, 3));
b.Dispose();
await complete;
}
[Fact]
public async Task CombineLatestLong()
{
var a = UniTaskAsyncEnumerable.Range(1, 100000);
var b = new AsyncReactiveProperty<int>(0);
var list = new List<(int, int)>();
var complete = a.CombineLatest(b.WithoutCurrent(), (x, y) => (x, y)).ForEachAsync(x => list.Add(x));
b.Value = 1;
list[0].Should().Be((100000, 1));
b.Dispose();
await complete;
}
[Fact]
public async Task CombineLatestError()
{
var a = new AsyncReactiveProperty<int>(0);
var b = new AsyncReactiveProperty<int>(0);
var list = new List<(int, int)>();
var complete = a.WithoutCurrent()
.Select(x => { if (x == 0) { throw new MyException(); } return x; })
.CombineLatest(b.WithoutCurrent(), (x, y) => (x, y)).ForEachAsync(x => list.Add(x));
a.Value = 10;
b.Value = 1;
list.Last().Should().Be((10, 1));
a.Value = 0;
await Assert.ThrowsAsync<MyException>(async () => await complete);
}
[Fact]
public async Task PariwiseImmediate()
{
var xs = await UniTaskAsyncEnumerable.Range(1, 5).Pairwise().ToArrayAsync();
xs.Should().Equal((1, 2), (2, 3), (3, 4), (4, 5));
}
[Fact]
public async Task Pariwise()
{
var a = new AsyncReactiveProperty<int>(0);
var list = new List<(int, int)>();
var complete = a.WithoutCurrent().Pairwise().ForEachAsync(x => list.Add(x));
list.Count.Should().Be(0);
a.Value = 10;
list.Count.Should().Be(0);
a.Value = 20;
list.Count.Should().Be(1);
a.Value = 30;
a.Value = 40;
a.Value = 50;
a.Dispose();
await complete;
list.Should().Equal((10, 20), (20, 30), (30, 40), (40, 50));
}
class MyException : Exception
{
}
}
}

View File

@ -1,78 +0,0 @@
using Cysharp.Threading.Tasks;
using Cysharp.Threading.Tasks.Linq;
using FluentAssertions;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Xunit;
namespace NetCoreTests.Linq
{
public class PublishTest
{
[Fact]
public async Task Normal()
{
var rp = new AsyncReactiveProperty<int>(1);
var multicast = rp.Publish();
var a = multicast.ToArrayAsync();
var b = multicast.Take(2).ToArrayAsync();
var disp = multicast.Connect();
rp.Value = 2;
(await b).Should().Equal(1, 2);
var c = multicast.ToArrayAsync();
rp.Value = 3;
rp.Value = 4;
rp.Value = 5;
rp.Dispose();
(await a).Should().Equal(1, 2, 3, 4, 5);
(await c).Should().Equal(3, 4, 5);
disp.Dispose();
}
[Fact]
public async Task Cancel()
{
var rp = new AsyncReactiveProperty<int>(1);
var multicast = rp.Publish();
var a = multicast.ToArrayAsync();
var b = multicast.Take(2).ToArrayAsync();
var disp = multicast.Connect();
rp.Value = 2;
(await b).Should().Equal(1, 2);
var c = multicast.ToArrayAsync();
rp.Value = 3;
disp.Dispose();
rp.Value = 4;
rp.Value = 5;
rp.Dispose();
await Assert.ThrowsAsync<OperationCanceledException>(async () => await a);
await Assert.ThrowsAsync<OperationCanceledException>(async () => await c);
}
}
}

View File

@ -1,29 +0,0 @@
using Cysharp.Threading.Tasks;
using Cysharp.Threading.Tasks.Linq;
using FluentAssertions;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Xunit;
namespace NetCoreTests.Linq
{
public class QueueTest
{
[Fact]
public async Task Q()
{
var rp = new AsyncReactiveProperty<int>(100);
var l = new List<int>();
await rp.Take(10).Queue().ForEachAsync(x =>
{
rp.Value += 10;
l.Add(x);
});
l.Should().Equal(100, 110, 120, 130, 140, 150, 160, 170, 180, 190);
}
}
}

View File

@ -1,193 +0,0 @@
using Cysharp.Threading.Tasks;
using Cysharp.Threading.Tasks.Linq;
using FluentAssertions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Concurrency;
using System.Reactive.Linq;
using System.Threading.Tasks;
using Xunit;
namespace NetCoreTests.Linq
{
public class Sets
{
public static IEnumerable<object[]> array1 = new object[][]
{
new object[] { new int[] { } }, // empty
new object[] { new int[] { 1, 2, 3 } }, // no dup
new object[] { new int[] { 1, 2, 3, 3, 4, 5, 2 } }, // dup
};
public static IEnumerable<object[]> array2 = new object[][]
{
new object[] { new int[] { } }, // empty
new object[] { new int[] { 1, 2 } },
new object[] { new int[] { 1, 2, 4, 5, 9 } }, // dup
};
[Theory]
[MemberData(nameof(array1))]
public async Task Distinct(int[] array)
{
var ys = array.Distinct().ToArray();
{
(await array.ToUniTaskAsyncEnumerable().Distinct().ToArrayAsync()).Should().Equal(ys);
(await array.ToUniTaskAsyncEnumerable().Distinct(x => x).ToArrayAsync()).Should().Equal(ys);
(await array.ToUniTaskAsyncEnumerable().DistinctAwait(x => UniTask.Run(() => x)).ToArrayAsync()).Should().Equal(ys);
(await array.ToUniTaskAsyncEnumerable().DistinctAwaitWithCancellation((x, _) => UniTask.Run(() => x)).ToArrayAsync()).Should().Equal(ys);
}
}
[Fact]
public async Task DistinctThrow()
{
foreach (var item in UniTaskTestException.Throws())
{
{
var xs = item.Distinct().ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
{
var xs = item.Distinct(x => x).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
{
var xs = item.DistinctAwait(x => UniTask.Run(() => x)).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
{
var xs = item.DistinctAwaitWithCancellation((x, _) => UniTask.Run(() => x)).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
}
}
[Theory]
[MemberData(nameof(array1))]
public async Task DistinctUntilChanged(int[] array)
{
var ys = await array.ToAsyncEnumerable().DistinctUntilChanged().ToArrayAsync();
{
(await array.ToUniTaskAsyncEnumerable().DistinctUntilChanged().ToArrayAsync()).Should().Equal(ys);
(await array.ToUniTaskAsyncEnumerable().DistinctUntilChanged(x => x).ToArrayAsync()).Should().Equal(ys);
(await array.ToUniTaskAsyncEnumerable().DistinctUntilChangedAwait(x => UniTask.Run(() => x)).ToArrayAsync()).Should().Equal(ys);
(await array.ToUniTaskAsyncEnumerable().DistinctUntilChangedAwaitWithCancellation((x, _) => UniTask.Run(() => x)).ToArrayAsync()).Should().Equal(ys);
}
}
[Fact]
public async Task DistinctUntilChangedThrow()
{
foreach (var item in UniTaskTestException.Throws())
{
{
var xs = item.DistinctUntilChanged().ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
{
var xs = item.DistinctUntilChanged(x => x).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
{
var xs = item.DistinctUntilChangedAwait(x => UniTask.Run(() => x)).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
{
var xs = item.DistinctUntilChangedAwaitWithCancellation((x, _) => UniTask.Run(() => x)).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
}
}
[Fact]
public async Task Except()
{
foreach (var a1 in array1.First().Cast<int[]>())
{
foreach (var a2 in array2.First().Cast<int[]>())
{
var xs = await a1.ToUniTaskAsyncEnumerable().Except(a2.ToUniTaskAsyncEnumerable()).ToArrayAsync();
var ys = a1.Except(a2).ToArray();
xs.Should().Equal(ys);
}
}
}
[Fact]
public async Task ExceptThrow()
{
foreach (var item in UniTaskTestException.Throws())
{
var xs = item.Except(UniTaskAsyncEnumerable.Return(10)).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
foreach (var item in UniTaskTestException.Throws())
{
var xs = UniTaskAsyncEnumerable.Return(10).Except(item).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
}
[Fact]
public async Task Intersect()
{
foreach (var a1 in array1.First().Cast<int[]>())
{
foreach (var a2 in array2.First().Cast<int[]>())
{
var xs = await a1.ToUniTaskAsyncEnumerable().Intersect(a2.ToUniTaskAsyncEnumerable()).ToArrayAsync();
var ys = a1.Intersect(a2).ToArray();
xs.Should().Equal(ys);
}
}
}
[Fact]
public async Task IntersectThrow()
{
foreach (var item in UniTaskTestException.Throws())
{
var xs = item.Intersect(UniTaskAsyncEnumerable.Return(10)).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
foreach (var item in UniTaskTestException.Throws())
{
var xs = UniTaskAsyncEnumerable.Return(10).Intersect(item).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
}
[Fact]
public async Task Union()
{
foreach (var a1 in array1.First().Cast<int[]>())
{
foreach (var a2 in array2.First().Cast<int[]>())
{
var xs = await a1.ToUniTaskAsyncEnumerable().Union(a2.ToUniTaskAsyncEnumerable()).ToArrayAsync();
var ys = a1.Union(a2).ToArray();
xs.Should().Equal(ys);
}
}
}
[Fact]
public async Task UnionThrow()
{
foreach (var item in UniTaskTestException.Throws())
{
var xs = item.Union(UniTaskAsyncEnumerable.Return(10)).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
foreach (var item in UniTaskTestException.Throws())
{
var xs = UniTaskAsyncEnumerable.Return(10).Union(item).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await xs);
}
}
}
}

View File

@ -1,221 +0,0 @@
using Cysharp.Threading.Tasks;
using Cysharp.Threading.Tasks.Linq;
using FluentAssertions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Concurrency;
using System.Reactive.Linq;
using System.Threading;
using System.Threading.Tasks;
using Xunit;
namespace NetCoreTests.Linq
{
public class SortCheck
{
public int Age { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public override string ToString()
{
return (Age, FirstName, LastName).ToString();
}
}
public class Sort
{
static int rd;
static UniTask<T> RandomRun<T>(T value)
{
if (Interlocked.Increment(ref rd) % 2 == 0)
{
return UniTask.Run(() => value);
}
else
{
return UniTask.FromResult(value);
}
}
static UniTask<T> RandomRun<T>(T value, CancellationToken ct)
{
if (Interlocked.Increment(ref rd) % 2 == 0)
{
return UniTask.Run(() => value);
}
else
{
return UniTask.FromResult(value);
}
}
[Fact]
public async Task OrderBy()
{
var array = new[] { 1, 99, 32, 4, 536, 7, 8 };
{
var xs = await array.ToUniTaskAsyncEnumerable().OrderBy(x => x).ToArrayAsync();
var ys = array.OrderBy(x => x).ToArray();
xs.Should().Equal(ys);
}
{
var xs = await array.ToUniTaskAsyncEnumerable().OrderByDescending(x => x).ToArrayAsync();
var ys = array.OrderByDescending(x => x).ToArray();
xs.Should().Equal(ys);
}
{
var xs = await array.ToUniTaskAsyncEnumerable().OrderByAwait(RandomRun).ToArrayAsync();
var ys = array.OrderBy(x => x).ToArray();
xs.Should().Equal(ys);
}
{
var xs = await array.ToUniTaskAsyncEnumerable().OrderByDescendingAwait(RandomRun).ToArrayAsync();
var ys = array.OrderByDescending(x => x).ToArray();
xs.Should().Equal(ys);
}
{
var xs = await array.ToUniTaskAsyncEnumerable().OrderByAwaitWithCancellation(RandomRun).ToArrayAsync();
var ys = array.OrderBy(x => x).ToArray();
xs.Should().Equal(ys);
}
{
var xs = await array.ToUniTaskAsyncEnumerable().OrderByDescendingAwaitWithCancellation(RandomRun).ToArrayAsync();
var ys = array.OrderByDescending(x => x).ToArray();
xs.Should().Equal(ys);
}
}
[Fact]
public async Task ThenBy()
{
var array = new[]
{
new SortCheck { Age = 99, FirstName = "ABC", LastName = "DEF" },
new SortCheck { Age = 49, FirstName = "ABC", LastName = "DEF" },
new SortCheck { Age = 49, FirstName = "ABC", LastName = "ZKH" },
new SortCheck { Age = 12, FirstName = "ABC", LastName = "DEF" },
new SortCheck { Age = 49, FirstName = "ABC", LastName = "MEF" },
new SortCheck { Age = 12, FirstName = "QQQ", LastName = "DEF" },
new SortCheck { Age = 19, FirstName = "ZKN", LastName = "DEF" },
new SortCheck { Age = 39, FirstName = "APO", LastName = "REF" },
new SortCheck { Age = 59, FirstName = "ABC", LastName = "DEF" },
new SortCheck { Age = 99, FirstName = "DBC", LastName = "DEF" },
new SortCheck { Age = 99, FirstName = "DBC", LastName = "MEF" },
};
{
var a = array.OrderBy(x => x.Age).ThenBy(x => x.FirstName).ThenBy(x => x.LastName).ToArray();
var b = array.OrderBy(x => x.Age).ThenBy(x => x.FirstName).ThenByDescending(x => x.LastName).ToArray();
var c = array.OrderBy(x => x.Age).ThenByDescending(x => x.FirstName).ThenBy(x => x.LastName).ToArray();
var d = array.OrderBy(x => x.Age).ThenByDescending(x => x.FirstName).ThenByDescending(x => x.LastName).ToArray();
var e = array.OrderByDescending(x => x.Age).ThenBy(x => x.FirstName).ThenBy(x => x.LastName).ToArray();
var f = array.OrderByDescending(x => x.Age).ThenBy(x => x.FirstName).ThenByDescending(x => x.LastName).ToArray();
var g = array.OrderByDescending(x => x.Age).ThenByDescending(x => x.FirstName).ThenBy(x => x.LastName).ToArray();
var h = array.OrderByDescending(x => x.Age).ThenByDescending(x => x.FirstName).ThenByDescending(x => x.LastName).ToArray();
{
var a2 = await array.ToUniTaskAsyncEnumerable().OrderBy(x => x.Age).ThenBy(x => x.FirstName).ThenBy(x => x.LastName).ToArrayAsync();
var b2 = await array.ToUniTaskAsyncEnumerable().OrderBy(x => x.Age).ThenBy(x => x.FirstName).ThenByDescending(x => x.LastName).ToArrayAsync();
var c2 = await array.ToUniTaskAsyncEnumerable().OrderBy(x => x.Age).ThenByDescending(x => x.FirstName).ThenBy(x => x.LastName).ToArrayAsync();
var d2 = await array.ToUniTaskAsyncEnumerable().OrderBy(x => x.Age).ThenByDescending(x => x.FirstName).ThenByDescending(x => x.LastName).ToArrayAsync();
var e2 = await array.ToUniTaskAsyncEnumerable().OrderByDescending(x => x.Age).ThenBy(x => x.FirstName).ThenBy(x => x.LastName).ToArrayAsync();
var f2 = await array.ToUniTaskAsyncEnumerable().OrderByDescending(x => x.Age).ThenBy(x => x.FirstName).ThenByDescending(x => x.LastName).ToArrayAsync();
var g2 = await array.ToUniTaskAsyncEnumerable().OrderByDescending(x => x.Age).ThenByDescending(x => x.FirstName).ThenBy(x => x.LastName).ToArrayAsync();
var h2 = await array.ToUniTaskAsyncEnumerable().OrderByDescending(x => x.Age).ThenByDescending(x => x.FirstName).ThenByDescending(x => x.LastName).ToArrayAsync();
a.Should().Equal(a2);
b.Should().Equal(b2);
c.Should().Equal(c2);
d.Should().Equal(d2);
e.Should().Equal(e2);
f.Should().Equal(f2);
g.Should().Equal(g2);
h.Should().Equal(h2);
}
{
var a2 = await array.ToUniTaskAsyncEnumerable().OrderByAwait(x => RandomRun(x.Age)).ThenByAwait(x => RandomRun(x.FirstName)).ThenByAwait(x => RandomRun(x.LastName)).ToArrayAsync();
var b2 = await array.ToUniTaskAsyncEnumerable().OrderByAwait(x => RandomRun(x.Age)).ThenByAwait(x => RandomRun(x.FirstName)).ThenByDescendingAwait(x => RandomRun(x.LastName)).ToArrayAsync();
var c2 = await array.ToUniTaskAsyncEnumerable().OrderByAwait(x => RandomRun(x.Age)).ThenByDescendingAwait(x => RandomRun(x.FirstName)).ThenByAwait(x => RandomRun(x.LastName)).ToArrayAsync();
var d2 = await array.ToUniTaskAsyncEnumerable().OrderByAwait(x => RandomRun(x.Age)).ThenByDescendingAwait(x => RandomRun(x.FirstName)).ThenByDescendingAwait(x => RandomRun(x.LastName)).ToArrayAsync();
var e2 = await array.ToUniTaskAsyncEnumerable().OrderByDescendingAwait(x => RandomRun(x.Age)).ThenByAwait(x => RandomRun(x.FirstName)).ThenByAwait(x => RandomRun(x.LastName)).ToArrayAsync();
var f2 = await array.ToUniTaskAsyncEnumerable().OrderByDescendingAwait(x => RandomRun(x.Age)).ThenByAwait(x => RandomRun(x.FirstName)).ThenByDescendingAwait(x => RandomRun(x.LastName)).ToArrayAsync();
var g2 = await array.ToUniTaskAsyncEnumerable().OrderByDescendingAwait(x => RandomRun(x.Age)).ThenByDescendingAwait(x => RandomRun(x.FirstName)).ThenByAwait(x => RandomRun(x.LastName)).ToArrayAsync();
var h2 = await array.ToUniTaskAsyncEnumerable().OrderByDescendingAwait(x => RandomRun(x.Age)).ThenByDescendingAwait(x => RandomRun(x.FirstName)).ThenByDescendingAwait(x => RandomRun(x.LastName)).ToArrayAsync();
a.Should().Equal(a2);
b.Should().Equal(b2);
c.Should().Equal(c2);
d.Should().Equal(d2);
e.Should().Equal(e2);
f.Should().Equal(f2);
g.Should().Equal(g2);
h.Should().Equal(h2);
}
{
var a2 = await array.ToUniTaskAsyncEnumerable().OrderByAwaitWithCancellation((x, ct) => RandomRun(x.Age)).ThenByAwaitWithCancellation((x, ct) => RandomRun(x.FirstName)).ThenByAwaitWithCancellation((x, ct) => RandomRun(x.LastName)).ToArrayAsync();
var b2 = await array.ToUniTaskAsyncEnumerable().OrderByAwaitWithCancellation((x, ct) => RandomRun(x.Age)).ThenByAwaitWithCancellation((x, ct) => RandomRun(x.FirstName)).ThenByDescendingAwaitWithCancellation((x, ct) => RandomRun(x.LastName)).ToArrayAsync();
var c2 = await array.ToUniTaskAsyncEnumerable().OrderByAwaitWithCancellation((x, ct) => RandomRun(x.Age)).ThenByDescendingAwaitWithCancellation((x, ct) => RandomRun(x.FirstName)).ThenByAwaitWithCancellation((x, ct) => RandomRun(x.LastName)).ToArrayAsync();
var d2 = await array.ToUniTaskAsyncEnumerable().OrderByAwaitWithCancellation((x, ct) => RandomRun(x.Age)).ThenByDescendingAwaitWithCancellation((x, ct) => RandomRun(x.FirstName)).ThenByDescendingAwaitWithCancellation((x, ct) => RandomRun(x.LastName)).ToArrayAsync();
var e2 = await array.ToUniTaskAsyncEnumerable().OrderByDescendingAwaitWithCancellation((x, ct) => RandomRun(x.Age)).ThenByAwaitWithCancellation((x, ct) => RandomRun(x.FirstName)).ThenByAwaitWithCancellation((x, ct) => RandomRun(x.LastName)).ToArrayAsync();
var f2 = await array.ToUniTaskAsyncEnumerable().OrderByDescendingAwaitWithCancellation((x, ct) => RandomRun(x.Age)).ThenByAwaitWithCancellation((x, ct) => RandomRun(x.FirstName)).ThenByDescendingAwaitWithCancellation((x, ct) => RandomRun(x.LastName)).ToArrayAsync();
var g2 = await array.ToUniTaskAsyncEnumerable().OrderByDescendingAwaitWithCancellation((x, ct) => RandomRun(x.Age)).ThenByDescendingAwaitWithCancellation((x, ct) => RandomRun(x.FirstName)).ThenByAwaitWithCancellation((x, ct) => RandomRun(x.LastName)).ToArrayAsync();
var h2 = await array.ToUniTaskAsyncEnumerable().OrderByDescendingAwaitWithCancellation((x, ct) => RandomRun(x.Age)).ThenByDescendingAwaitWithCancellation((x, ct) => RandomRun(x.FirstName)).ThenByDescendingAwaitWithCancellation((x, ct) => RandomRun(x.LastName)).ToArrayAsync();
a.Should().Equal(a2);
b.Should().Equal(b2);
c.Should().Equal(c2);
d.Should().Equal(d2);
e.Should().Equal(e2);
f.Should().Equal(f2);
g.Should().Equal(g2);
h.Should().Equal(h2);
}
}
}
[Fact]
public async Task Throws()
{
foreach (var item in UniTaskTestException.Throws())
{
{
var a = item.OrderBy(x => x).ToArrayAsync();
var b = item.OrderByDescending(x => x).ToArrayAsync();
var c = item.OrderBy(x => x).ThenBy(x => x).ToArrayAsync();
var d = item.OrderBy(x => x).ThenByDescending(x => x).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await a);
await Assert.ThrowsAsync<UniTaskTestException>(async () => await b);
await Assert.ThrowsAsync<UniTaskTestException>(async () => await c);
await Assert.ThrowsAsync<UniTaskTestException>(async () => await d);
}
{
var a = item.OrderByAwait(RandomRun).ToArrayAsync();
var b = item.OrderByDescendingAwait(RandomRun).ToArrayAsync();
var c = item.OrderByAwait(RandomRun).ThenByAwait(RandomRun).ToArrayAsync();
var d = item.OrderByAwait(RandomRun).ThenByDescendingAwait(RandomRun).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await a);
await Assert.ThrowsAsync<UniTaskTestException>(async () => await b);
await Assert.ThrowsAsync<UniTaskTestException>(async () => await c);
await Assert.ThrowsAsync<UniTaskTestException>(async () => await d);
}
{
var a = item.OrderByAwaitWithCancellation(RandomRun).ToArrayAsync();
var b = item.OrderByDescendingAwaitWithCancellation(RandomRun).ToArrayAsync();
var c = item.OrderByAwaitWithCancellation(RandomRun).ThenByAwaitWithCancellation(RandomRun).ToArrayAsync();
var d = item.OrderByAwaitWithCancellation(RandomRun).ThenByDescendingAwaitWithCancellation(RandomRun).ToArrayAsync();
await Assert.ThrowsAsync<UniTaskTestException>(async () => await a);
await Assert.ThrowsAsync<UniTaskTestException>(async () => await b);
await Assert.ThrowsAsync<UniTaskTestException>(async () => await c);
await Assert.ThrowsAsync<UniTaskTestException>(async () => await d);
}
}
}
}
}

View File

@ -1,165 +0,0 @@
using Cysharp.Threading.Tasks;
using Cysharp.Threading.Tasks.Linq;
using FluentAssertions;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Xunit;
namespace NetCoreTests.Linq
{
public class TakeInfinityTest
{
[Fact]
public async Task Take()
{
var rp = new AsyncReactiveProperty<int>(1);
var xs = rp.Take(5).ToArrayAsync();
rp.Value = 2;
rp.Value = 3;
rp.Value = 4;
rp.Value = 5;
(await xs).Should().Equal(1, 2, 3, 4, 5);
}
[Fact]
public async Task TakeWhile()
{
var rp = new AsyncReactiveProperty<int>(1);
var xs = rp.TakeWhile(x => x != 5).ToArrayAsync();
rp.Value = 2;
rp.Value = 3;
rp.Value = 4;
rp.Value = 5;
(await xs).Should().Equal(1, 2, 3, 4);
}
[Fact]
public async Task TakeUntilCanceled()
{
var cts = new CancellationTokenSource();
var rp = new AsyncReactiveProperty<int>(1);
var xs = rp.TakeUntilCanceled(cts.Token).ToArrayAsync();
var c = CancelAsync();
await c;
var foo = await xs;
foo.Should().Equal(new[] { 1, 10, 20 });
async Task CancelAsync()
{
rp.Value = 10;
await Task.Yield();
rp.Value = 20;
await Task.Yield();
cts.Cancel();
rp.Value = 30;
await Task.Yield();
rp.Value = 40;
}
}
[Fact]
public async Task SkipUntilCanceled()
{
var cts = new CancellationTokenSource();
var rp = new AsyncReactiveProperty<int>(1);
var xs = rp.SkipUntilCanceled(cts.Token).ToArrayAsync();
var c = CancelAsync();
await c;
var foo = await xs;
foo.Should().Equal(new[] { 20, 30, 40 });
async Task CancelAsync()
{
rp.Value = 10;
await Task.Yield();
rp.Value = 20;
await Task.Yield();
cts.Cancel();
rp.Value = 30;
await Task.Yield();
rp.Value = 40;
rp.Dispose(); // complete.
}
}
[Fact]
public async Task TakeUntil()
{
var cts = new AsyncReactiveProperty<int>(0);
var rp = new AsyncReactiveProperty<int>(1);
var xs = rp.TakeUntil(cts.WaitAsync()).ToArrayAsync();
var c = CancelAsync();
await c;
var foo = await xs;
foo.Should().Equal(new[] { 1, 10, 20 });
async Task CancelAsync()
{
rp.Value = 10;
await Task.Yield();
rp.Value = 20;
await Task.Yield();
cts.Value = 9999;
rp.Value = 30;
await Task.Yield();
rp.Value = 40;
}
}
[Fact]
public async Task SkipUntil()
{
var cts = new AsyncReactiveProperty<int>(0);
var rp = new AsyncReactiveProperty<int>(1);
var xs = rp.SkipUntil(cts.WaitAsync()).ToArrayAsync();
var c = CancelAsync();
await c;
var foo = await xs;
foo.Should().Equal(new[] { 20, 30, 40 });
async Task CancelAsync()
{
rp.Value = 10;
await Task.Yield();
rp.Value = 20;
await Task.Yield();
cts.Value = 9999;
rp.Value = 30;
await Task.Yield();
rp.Value = 40;
rp.Dispose(); // complete.
}
}
}
}

View File

@ -1,126 +0,0 @@
using Cysharp.Threading.Tasks;
using Cysharp.Threading.Tasks.Linq;
using System;
using System.Collections.Generic;
using System.Runtime.ExceptionServices;
using System.Threading;
namespace NetCoreTests.Linq
{
public class UniTaskTestException : Exception
{
public static IUniTaskAsyncEnumerable<int> ThrowImmediate()
{
return UniTaskAsyncEnumerable.Throw<int>(new UniTaskTestException());
}
public static IUniTaskAsyncEnumerable<int> ThrowAfter()
{
return new ThrowAfter<int>(new UniTaskTestException());
}
public static IUniTaskAsyncEnumerable<int> ThrowInMoveNext()
{
return new ThrowIn<int>(new UniTaskTestException());
}
public static IEnumerable<IUniTaskAsyncEnumerable<int>> Throws(int count = 3)
{
yield return ThrowImmediate();
yield return ThrowAfter();
yield return ThrowInMoveNext();
yield return UniTaskAsyncEnumerable.Range(1, count).Concat(ThrowImmediate());
yield return UniTaskAsyncEnumerable.Range(1, count).Concat(ThrowAfter());
yield return UniTaskAsyncEnumerable.Range(1, count).Concat(ThrowInMoveNext());
}
}
internal class ThrowIn<TValue> : IUniTaskAsyncEnumerable<TValue>
{
readonly Exception exception;
public ThrowIn(Exception exception)
{
this.exception = exception;
}
public IUniTaskAsyncEnumerator<TValue> GetAsyncEnumerator(CancellationToken cancellationToken = default)
{
return new Enumerator(exception, cancellationToken);
}
class Enumerator : IUniTaskAsyncEnumerator<TValue>
{
readonly Exception exception;
CancellationToken cancellationToken;
public Enumerator(Exception exception, CancellationToken cancellationToken)
{
this.exception = exception;
this.cancellationToken = cancellationToken;
}
public TValue Current => default;
public UniTask<bool> MoveNextAsync()
{
ExceptionDispatchInfo.Capture(exception).Throw();
return new UniTask<bool>(false);
}
public UniTask DisposeAsync()
{
return default;
}
}
}
internal class ThrowAfter<TValue> : IUniTaskAsyncEnumerable<TValue>
{
readonly Exception exception;
public ThrowAfter(Exception exception)
{
this.exception = exception;
}
public IUniTaskAsyncEnumerator<TValue> GetAsyncEnumerator(CancellationToken cancellationToken = default)
{
return new Enumerator(exception, cancellationToken);
}
class Enumerator : IUniTaskAsyncEnumerator<TValue>
{
readonly Exception exception;
CancellationToken cancellationToken;
public Enumerator(Exception exception, CancellationToken cancellationToken)
{
this.exception = exception;
this.cancellationToken = cancellationToken;
}
public TValue Current => default;
public UniTask<bool> MoveNextAsync()
{
cancellationToken.ThrowIfCancellationRequested();
var tcs = new UniTaskCompletionSource<bool>();
var awaiter = UniTask.Yield().GetAwaiter();
awaiter.UnsafeOnCompleted(() =>
{
Thread.Sleep(1);
tcs.TrySetException(exception);
});
return tcs.Task;
}
public UniTask DisposeAsync()
{
return default;
}
}
}
}

View File

@ -1,301 +0,0 @@
#pragma warning disable CS1998
using Cysharp.Threading.Tasks;
using FluentAssertions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Channels;
using Cysharp.Threading.Tasks.Linq;
using System.Threading.Tasks;
using Xunit;
using System.Runtime.CompilerServices;
namespace NetCoreTests
{
public class UniTaskBuilderTest
{
[Fact]
public async Task Empty()
{
await Core();
static async UniTask Core()
{
}
}
[Fact]
public async Task EmptyThrow()
{
await Assert.ThrowsAsync<TaskTestException>(async () => await Core());
static async UniTask Core()
{
throw new TaskTestException();
}
}
[Fact]
public async Task Task_Done()
{
await Core();
static async UniTask Core()
{
await new TestAwaiter(true, UniTaskStatus.Succeeded);
}
}
[Fact]
public async Task Task_Fail()
{
await Assert.ThrowsAsync<TaskTestException>(async () => await Core());
static async UniTask Core()
{
await new TestAwaiter(true, UniTaskStatus.Faulted);
}
}
[Fact]
public async Task Task_Cancel()
{
await Assert.ThrowsAsync<OperationCanceledException>(async () => await Core());
static async UniTask Core()
{
await new TestAwaiter(true, UniTaskStatus.Canceled);
}
}
[Fact]
public async Task AwaitUnsafeOnCompletedCall_Task_SetResult()
{
await Core();
static async UniTask Core()
{
await new TestAwaiter(false, UniTaskStatus.Succeeded);
await new TestAwaiter(false, UniTaskStatus.Succeeded);
await new TestAwaiter(false, UniTaskStatus.Succeeded);
}
}
[Fact]
public async Task AwaitUnsafeOnCompletedCall_Task_SetException()
{
await Assert.ThrowsAsync<TaskTestException>(async () => await Core());
static async UniTask Core()
{
await new TestAwaiter(false, UniTaskStatus.Succeeded);
await new TestAwaiter(false, UniTaskStatus.Faulted);
throw new InvalidOperationException();
}
}
[Fact]
public async Task AwaitUnsafeOnCompletedCall_Task_SetCancelException()
{
await Assert.ThrowsAsync<OperationCanceledException>(async () => await Core());
static async UniTask Core()
{
await new TestAwaiter(false, UniTaskStatus.Succeeded);
await new TestAwaiter(false, UniTaskStatus.Canceled);
throw new InvalidOperationException();
}
}
}
public class UniTask_T_BuilderTest
{
[Fact]
public async Task Empty()
{
(await Core()).Should().Be(10);
static async UniTask<int> Core()
{
return 10;
}
}
[Fact]
public async Task EmptyThrow()
{
await Assert.ThrowsAsync<TaskTestException>(async () => await Core());
static async UniTask<int> Core()
{
throw new TaskTestException();
}
}
[Fact]
public async Task Task_Done()
{
(await Core()).Should().Be(10);
static async UniTask<int> Core()
{
return await new TestAwaiter<int>(true, UniTaskStatus.Succeeded, 10);
}
}
[Fact]
public async Task Task_Fail()
{
await Assert.ThrowsAsync<TaskTestException>(async () => await Core());
static async UniTask<int> Core()
{
return await new TestAwaiter<int>(true, UniTaskStatus.Faulted, 10);
}
}
[Fact]
public async Task Task_Cancel()
{
await Assert.ThrowsAsync<OperationCanceledException>(async () => await Core());
static async UniTask<int> Core()
{
return await new TestAwaiter<int>(true, UniTaskStatus.Canceled, 10);
}
}
[Fact]
public async Task AwaitUnsafeOnCompletedCall_Task_SetResult()
{
(await Core()).Should().Be(6);
static async UniTask<int> Core()
{
var sum = 0;
sum += await new TestAwaiter<int>(false, UniTaskStatus.Succeeded, 1);
sum += await new TestAwaiter<int>(false, UniTaskStatus.Succeeded, 2);
sum += await new TestAwaiter<int>(false, UniTaskStatus.Succeeded, 3);
return sum;
}
}
[Fact]
public async Task AwaitUnsafeOnCompletedCall_Task_SetException()
{
await Assert.ThrowsAsync<TaskTestException>(async () => await Core());
static async UniTask<int> Core()
{
await new TestAwaiter<int>(false, UniTaskStatus.Succeeded, 10);
await new TestAwaiter<int>(false, UniTaskStatus.Faulted, 10);
throw new InvalidOperationException();
}
}
[Fact]
public async Task AwaitUnsafeOnCompletedCall_Task_SetCancelException()
{
await Assert.ThrowsAsync<OperationCanceledException>(async () => await Core());
static async UniTask<int> Core()
{
await new TestAwaiter<int>(false, UniTaskStatus.Succeeded, 10);
await new TestAwaiter<int>(false, UniTaskStatus.Canceled, 10);
throw new InvalidOperationException();
}
}
}
public class TaskTestException : Exception
{
}
public struct TestAwaiter : ICriticalNotifyCompletion
{
readonly UniTaskStatus status;
readonly bool isCompleted;
public TestAwaiter(bool isCompleted, UniTaskStatus status)
{
this.isCompleted = isCompleted;
this.status = status;
}
public TestAwaiter GetAwaiter() => this;
public bool IsCompleted => isCompleted;
public void GetResult()
{
switch (status)
{
case UniTaskStatus.Faulted:
throw new TaskTestException();
case UniTaskStatus.Canceled:
throw new OperationCanceledException();
case UniTaskStatus.Pending:
case UniTaskStatus.Succeeded:
default:
break;
}
}
public void OnCompleted(Action continuation)
{
ThreadPool.QueueUserWorkItem(_ => continuation(), null);
}
public void UnsafeOnCompleted(Action continuation)
{
ThreadPool.UnsafeQueueUserWorkItem(_ => continuation(), null);
}
}
public struct TestAwaiter<T> : ICriticalNotifyCompletion
{
readonly UniTaskStatus status;
readonly bool isCompleted;
readonly T value;
public TestAwaiter(bool isCompleted, UniTaskStatus status, T value)
{
this.isCompleted = isCompleted;
this.status = status;
this.value = value;
}
public TestAwaiter<T> GetAwaiter() => this;
public bool IsCompleted => isCompleted;
public T GetResult()
{
switch (status)
{
case UniTaskStatus.Faulted:
throw new TaskTestException();
case UniTaskStatus.Canceled:
throw new OperationCanceledException();
case UniTaskStatus.Pending:
case UniTaskStatus.Succeeded:
default:
return value;
}
}
public void OnCompleted(Action continuation)
{
ThreadPool.QueueUserWorkItem(_ => continuation(), null);
}
public void UnsafeOnCompleted(Action continuation)
{
ThreadPool.UnsafeQueueUserWorkItem(_ => continuation(), null);
}
}
}

View File

@ -1,45 +0,0 @@
#pragma warning disable CS1998
using System;
using System.Threading.Tasks;
using Cysharp.Threading.Tasks;
using Xunit;
namespace NetCoreTests
{
public class TaskExtensionsTest
{
[Fact]
public async Task PropagateException()
{
await Assert.ThrowsAsync<InvalidOperationException>(async () =>
{
await ThrowAsync().AsUniTask();
});
await Assert.ThrowsAsync<InvalidOperationException>(async () =>
{
await ThrowOrValueAsync().AsUniTask();
});
}
[Fact]
public async Task PropagateExceptionWhenAll()
{
await Assert.ThrowsAsync<InvalidOperationException>(async () =>
{
await Task.WhenAll(ThrowAsync(), ThrowAsync()).AsUniTask();
});
}
async Task ThrowAsync()
{
throw new InvalidOperationException();
}
async Task<int> ThrowOrValueAsync()
{
throw new InvalidOperationException();
}
}
}

View File

@ -1,637 +0,0 @@
using Cysharp.Threading.Tasks;
using FluentAssertions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Channels;
using Cysharp.Threading.Tasks.Linq;
using System.Threading.Tasks;
using Xunit;
namespace NetCoreTests
{
public class TriggerEventTest
{
[Fact]
public void SimpleAdd()
{
var ev = new TriggerEvent<int>();
// do nothing
ev.SetResult(0);
ev.SetError(null);
ev.SetCompleted();
ev.SetCanceled(default);
{
var one = new TestEvent(1);
ev.Add(one);
ev.SetResult(10);
ev.SetResult(20);
ev.SetResult(30);
one.NextCalled.Should().Equal(10, 20, 30);
ev.SetCompleted();
one.CompletedCalled.Count.Should().Be(1);
// do nothing
ev.SetResult(0);
ev.SetError(null);
ev.SetCompleted();
ev.SetCanceled(default);
one.NextCalled.Should().Equal(10, 20, 30);
one.CompletedCalled.Count.Should().Be(1);
}
// after removed, onemore
{
var one = new TestEvent(1);
ev.Add(one);
ev.SetResult(10);
ev.SetResult(20);
ev.SetResult(30);
one.NextCalled.Should().Equal(10, 20, 30);
ev.SetCompleted();
one.CompletedCalled.Count.Should().Be(1);
// do nothing
ev.SetResult(0);
ev.SetError(null);
ev.SetCompleted();
ev.SetCanceled(default);
one.NextCalled.Should().Equal(10, 20, 30);
one.CompletedCalled.Count.Should().Be(1);
}
}
[Fact]
public void AddFour()
{
var ev = new TriggerEvent<int>();
// do nothing
ev.SetResult(0);
ev.SetError(null);
ev.SetCompleted();
ev.SetCanceled(default);
{
var one = new TestEvent(1);
var two = new TestEvent(2);
var three = new TestEvent(3);
var four = new TestEvent(4);
ev.Add(one);
ev.Add(two);
ev.Add(three);
ev.Add(four);
ev.SetResult(10);
ev.SetResult(20);
ev.SetResult(30);
one.NextCalled.Should().Equal(10, 20, 30);
two.NextCalled.Should().Equal(10, 20, 30);
three.NextCalled.Should().Equal(10, 20, 30);
four.NextCalled.Should().Equal(10, 20, 30);
ev.SetCompleted();
one.CompletedCalled.Count.Should().Be(1);
two.CompletedCalled.Count.Should().Be(1);
three.CompletedCalled.Count.Should().Be(1);
// do nothing
ev.SetResult(0);
ev.SetError(null);
ev.SetCompleted();
ev.SetCanceled(default);
one.NextCalled.Should().Equal(10, 20, 30);
one.CompletedCalled.Count.Should().Be(1);
two.NextCalled.Should().Equal(10, 20, 30);
three.CompletedCalled.Count.Should().Be(1);
two.NextCalled.Should().Equal(10, 20, 30);
three.CompletedCalled.Count.Should().Be(1);
}
// after removed, onemore.
{
var one = new TestEvent(1);
var two = new TestEvent(2);
var three = new TestEvent(3);
var four = new TestEvent(4);
ev.Add(one);
ev.Add(two);
ev.Add(three);
ev.Add(four);
ev.SetResult(10);
ev.SetResult(20);
ev.SetResult(30);
ev.Add(four);
one.NextCalled.Should().Equal(10, 20, 30);
two.NextCalled.Should().Equal(10, 20, 30);
three.NextCalled.Should().Equal(10, 20, 30);
four.NextCalled.Should().Equal(10, 20, 30);
ev.SetCompleted();
one.CompletedCalled.Count.Should().Be(1);
two.CompletedCalled.Count.Should().Be(1);
three.CompletedCalled.Count.Should().Be(1);
// do nothing
ev.SetResult(0);
ev.SetError(null);
ev.SetCompleted();
ev.SetCanceled(default);
one.NextCalled.Should().Equal(10, 20, 30);
one.CompletedCalled.Count.Should().Be(1);
two.NextCalled.Should().Equal(10, 20, 30);
three.CompletedCalled.Count.Should().Be(1);
two.NextCalled.Should().Equal(10, 20, 30);
three.CompletedCalled.Count.Should().Be(1);
}
}
[Fact]
public void OneRemove()
{
var ev = new TriggerEvent<int>();
{
var one = new TestEvent(1);
var two = new TestEvent(2);
var three = new TestEvent(3);
ev.Add(one);
ev.Add(two);
ev.Add(three);
ev.SetResult(10);
ev.SetResult(20);
ev.SetResult(30);
one.NextCalled.Should().Equal(10, 20, 30);
two.NextCalled.Should().Equal(10, 20, 30);
three.NextCalled.Should().Equal(10, 20, 30);
ev.Remove(one);
ev.SetResult(40);
ev.SetResult(50);
ev.SetResult(60);
one.NextCalled.Should().Equal(10, 20, 30);
two.NextCalled.Should().Equal(10, 20, 30, 40, 50, 60);
three.NextCalled.Should().Equal(10, 20, 30, 40, 50, 60);
}
}
[Fact]
public void TwoRemove()
{
var ev = new TriggerEvent<int>();
{
var one = new TestEvent(1);
var two = new TestEvent(2);
var three = new TestEvent(3);
ev.Add(one);
ev.Add(two);
ev.Add(three);
ev.SetResult(10);
ev.SetResult(20);
ev.SetResult(30);
one.NextCalled.Should().Equal(10, 20, 30);
two.NextCalled.Should().Equal(10, 20, 30);
three.NextCalled.Should().Equal(10, 20, 30);
ev.Remove(two);
ev.SetResult(40);
ev.SetResult(50);
ev.SetResult(60);
one.NextCalled.Should().Equal(10, 20, 30, 40, 50, 60);
two.NextCalled.Should().Equal(10, 20, 30);
three.NextCalled.Should().Equal(10, 20, 30, 40, 50, 60);
}
}
[Fact]
public void ThreeRemove()
{
var ev = new TriggerEvent<int>();
{
var one = new TestEvent(1);
var two = new TestEvent(2);
var three = new TestEvent(3);
ev.Add(one);
ev.Add(two);
ev.Add(three);
ev.SetResult(10);
ev.SetResult(20);
ev.SetResult(30);
one.NextCalled.Should().Equal(10, 20, 30);
two.NextCalled.Should().Equal(10, 20, 30);
three.NextCalled.Should().Equal(10, 20, 30);
ev.Remove(three);
ev.SetResult(40);
ev.SetResult(50);
ev.SetResult(60);
one.NextCalled.Should().Equal(10, 20, 30, 40, 50, 60);
two.NextCalled.Should().Equal(10, 20, 30, 40, 50, 60);
three.NextCalled.Should().Equal(10, 20, 30);
}
}
[Fact]
public void RemoveSelf()
{
new RemoveMe().Run1();
new RemoveMe().Run2();
new RemoveMe().Run3();
}
[Fact]
public void RemoveNextInIterating()
{
new RemoveNext().Run1();
new RemoveNext().Run2();
new RemoveNext().Run3();
}
[Fact]
public void RemoveNextNextTest()
{
new RemoveNextNext().Run1();
new RemoveNextNext().Run2();
}
[Fact]
public void AddTest()
{
new AddMe().Run1();
new AddMe().Run2();
}
public class RemoveMe
{
TriggerEvent<int> ev;
public void Run1()
{
TestEvent one = default;
one = new TestEvent(1, () => ev.Remove(one));
var two = new TestEvent(2);
var three = new TestEvent(3);
ev.Add(one);
ev.Add(two);
ev.Add(three);
ev.SetResult(10);
ev.SetResult(20);
ev.SetResult(30);
one.NextCalled.Should().Equal(10);
two.NextCalled.Should().Equal(10, 20, 30);
three.NextCalled.Should().Equal(10, 20, 30);
}
public void Run2()
{
TestEvent one = default;
one = new TestEvent(1, () => ev.Remove(one));
var two = new TestEvent(2);
var three = new TestEvent(3);
ev.Add(two);
ev.Add(one); // add second.
ev.Add(three);
ev.SetResult(10);
ev.SetResult(20);
ev.SetResult(30);
one.NextCalled.Should().Equal(10);
two.NextCalled.Should().Equal(10, 20, 30);
three.NextCalled.Should().Equal(10, 20, 30);
}
public void Run3()
{
TestEvent one = default;
one = new TestEvent(1, () => ev.Remove(one));
var two = new TestEvent(2);
var three = new TestEvent(3);
ev.Add(two);
ev.Add(three);
ev.Add(one); // add thired.
ev.SetResult(10);
ev.SetResult(20);
ev.SetResult(30);
one.NextCalled.Should().Equal(10);
two.NextCalled.Should().Equal(10, 20, 30);
three.NextCalled.Should().Equal(10, 20, 30);
}
}
public class RemoveNext
{
TriggerEvent<int> ev;
public void Run1()
{
TestEvent one = default;
TestEvent two = default;
TestEvent three = default;
one = new TestEvent(1, () => ev.Remove(two));
two = new TestEvent(2);
three = new TestEvent(3);
ev.Add(one);
ev.Add(two);
ev.Add(three);
ev.SetResult(10);
ev.SetResult(20);
ev.SetResult(30);
one.NextCalled.Should().Equal(10, 20, 30);
two.NextCalled.Count.Should().Be(0);
three.NextCalled.Should().Equal(10, 20, 30);
}
public void Run2()
{
TestEvent one = default;
TestEvent two = default;
TestEvent three = default;
one = new TestEvent(1, () => ev.Remove(two));
two = new TestEvent(2);
three = new TestEvent(3);
ev.Add(two);
ev.Add(one); // add second
ev.Add(three);
ev.SetResult(10);
ev.SetResult(20);
ev.SetResult(30);
one.NextCalled.Should().Equal(10, 20, 30);
two.NextCalled.Should().Equal(10);
three.NextCalled.Should().Equal(10, 20, 30);
}
public void Run3()
{
TestEvent one = default;
TestEvent two = default;
TestEvent three = default;
one = new TestEvent(1, () => ev.Remove(two));
two = new TestEvent(2);
three = new TestEvent(3);
ev.Add(two);
ev.Add(three);
ev.Add(one); // add thired.
ev.SetResult(10);
ev.SetResult(20);
ev.SetResult(30);
one.NextCalled.Should().Equal(10, 20, 30);
two.NextCalled.Should().Equal(10);
three.NextCalled.Should().Equal(10, 20, 30);
}
}
public class RemoveNextNext
{
TriggerEvent<int> ev;
public void Run1()
{
TestEvent one = default;
TestEvent two = default;
TestEvent three = default;
TestEvent four = default;
one = new TestEvent(1, () => { ev.Remove(two); ev.Remove(three); });
two = new TestEvent(2);
three = new TestEvent(3);
four = new TestEvent(4);
ev.Add(one);
ev.Add(two);
ev.Add(three);
ev.Add(four);
ev.SetResult(10);
ev.SetResult(20);
ev.SetResult(30);
one.NextCalled.Should().Equal(10, 20, 30);
two.NextCalled.Count.Should().Be(0);
three.NextCalled.Count.Should().Be(0);
four.NextCalled.Should().Equal(10, 20, 30);
}
public void Run2()
{
TestEvent one = default;
TestEvent two = default;
TestEvent three = default;
TestEvent four = default;
one = new TestEvent(1, () => { ev.Remove(one); ev.Remove(two); ev.Remove(three); });
two = new TestEvent(2);
three = new TestEvent(3);
four = new TestEvent(4);
ev.Add(one);
ev.Add(two);
ev.Add(three);
ev.Add(four);
ev.SetResult(10);
ev.SetResult(20);
ev.SetResult(30);
one.NextCalled.Should().Equal(10);
two.NextCalled.Count.Should().Be(0);
three.NextCalled.Count.Should().Be(0);
four.NextCalled.Should().Equal(10, 20, 30);
}
}
public class AddMe
{
TriggerEvent<int> ev;
public void Run1()
{
TestEvent one = default;
TestEvent two = default;
TestEvent three = default;
TestEvent four = default;
one = new TestEvent(1, () =>
{
if (two == null)
{
ev.Add(two = new TestEvent(2));
}
else if (three == null)
{
ev.Add(three = new TestEvent(3));
}
else if (four == null)
{
ev.Add(four = new TestEvent(4));
}
});
ev.Add(one);
ev.SetResult(10);
ev.SetResult(20);
ev.SetResult(30);
ev.SetResult(40);
one.NextCalled.Should().Equal(10, 20, 30, 40);
two.NextCalled.Should().Equal(20, 30, 40);
three.NextCalled.Should().Equal(30, 40);
four.NextCalled.Should().Equal(40);
}
public void Run2()
{
TestEvent one = default;
TestEvent two = default;
TestEvent three = default;
TestEvent four = default;
one = new TestEvent(1, () =>
{
if (two == null)
{
ev.Add(two = new TestEvent(2, () =>
{
if (three == null)
{
ev.Add(three = new TestEvent(3, () =>
{
if (four == null)
{
ev.Add(four = new TestEvent(4));
}
}));
}
}));
}
});
ev.Add(one);
ev.SetResult(10);
ev.SetResult(20);
ev.SetResult(30);
ev.SetResult(40);
one.NextCalled.Should().Equal(10, 20, 30, 40);
two.NextCalled.Should().Equal(20, 30, 40);
three.NextCalled.Should().Equal(30, 40);
four.NextCalled.Should().Equal(40);
}
}
}
public class TestEvent : ITriggerHandler<int>
{
public readonly int Id;
readonly Action iteratingEvent;
public TestEvent(int id)
{
this.Id = id;
}
public TestEvent(int id, Action iteratingEvent)
{
this.Id = id;
this.iteratingEvent = iteratingEvent;
}
public List<int> NextCalled = new List<int>();
public List<Exception> ErrorCalled = new List<Exception>();
public List<object> CompletedCalled = new List<object>();
public List<CancellationToken> CancelCalled = new List<CancellationToken>();
public ITriggerHandler<int> Prev { get; set; }
public ITriggerHandler<int> Next { get; set; }
public void OnCanceled(CancellationToken cancellationToken)
{
CancelCalled.Add(cancellationToken);
}
public void OnCompleted()
{
CompletedCalled.Add(new object());
}
public void OnError(Exception ex)
{
ErrorCalled.Add(ex);
}
public void OnNext(int value)
{
NextCalled.Add(value);
iteratingEvent?.Invoke();
}
public override string ToString()
{
return Id.ToString();
}
}
}

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
<IsPackable>false</IsPackable>
@ -9,20 +9,10 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="FluentAssertions" Version="5.10.3" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.1" />
<PackageReference Include="System.Interactive.Async" Version="4.1.1" />
<PackageReference Include="System.Linq.Async" Version="4.1.1" />
<PackageReference Include="System.Reactive" Version="4.4.1" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\UniTask.NetCore\UniTask.NetCore.csproj" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
<PackageReference Include="xunit" Version="2.4.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
<PackageReference Include="coverlet.collector" Version="1.0.1" />
</ItemGroup>
</Project>

View File

@ -1,80 +0,0 @@
using System.Threading.Tasks;
using Cysharp.Threading.Tasks;
using FluentAssertions;
using NetCoreTests.Linq;
using Xunit;
namespace NetCoreTests
{
public class AutoResetUniTaskCompletionSourceTest
{
[Fact]
public async Task SetResultAfterReturn()
{
var source1 = AutoResetUniTaskCompletionSource.Create();
source1.TrySetResult();
await source1.Task;
source1.TrySetResult().Should().BeFalse();
var source2 = AutoResetUniTaskCompletionSource.Create();
source2.TrySetResult();
await source2.Task;
source2.TrySetResult().Should().BeFalse();
}
[Fact]
public async Task SetCancelAfterReturn()
{
var source = AutoResetUniTaskCompletionSource.Create();
source.TrySetResult();
await source.Task;
source.TrySetCanceled().Should().BeFalse();
}
[Fact]
public async Task SetExceptionAfterReturn()
{
var source = AutoResetUniTaskCompletionSource.Create();
source.TrySetResult();
await source.Task;
source.TrySetException(new UniTaskTestException()).Should().BeFalse();
}
[Fact]
public async Task SetResultWithValueAfterReturn()
{
var source1 = AutoResetUniTaskCompletionSource<int>.Create();
source1.TrySetResult(100);
(await source1.Task).Should().Be(100);
source1.TrySetResult(100).Should().BeFalse();
var source2 = AutoResetUniTaskCompletionSource.Create();
source2.TrySetResult();
await source2.Task;
source2.TrySetResult().Should().BeFalse();
}
[Fact]
public async Task SetCancelWithValueAfterReturn()
{
var source = AutoResetUniTaskCompletionSource<int>.Create();
source.TrySetResult(100);
(await source.Task).Should().Be(100);
source.TrySetCanceled().Should().BeFalse();
}
[Fact]
public async Task SetExceptionWithValueAfterReturn()
{
var source = AutoResetUniTaskCompletionSource<int>.Create();
source.TrySetResult(100);
(await source.Task).Should().Be(100);
source.TrySetException(new UniTaskTestException()).Should().BeFalse();
}
}
}

View File

@ -0,0 +1,14 @@
using System;
using Xunit;
namespace UniTask.NetCoreTests
{
public class UnitTest1
{
[Fact]
public void Test1()
{
}
}
}

View File

@ -1,69 +0,0 @@
using Cysharp.Threading.Tasks;
using FluentAssertions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xunit;
namespace NetCoreTests
{
public class WhenEachTest
{
[Fact]
public async Task Each()
{
var a = Delay(1, 3000);
var b = Delay(2, 1000);
var c = Delay(3, 2000);
var l = new List<int>();
await foreach (var item in UniTask.WhenEach(a, b, c))
{
l.Add(item.Result);
}
l.Should().Equal(2, 3, 1);
}
[Fact]
public async Task Error()
{
var a = Delay2(1, 3000);
var b = Delay2(2, 1000);
var c = Delay2(3, 2000);
var l = new List<WhenEachResult<int>>();
await foreach (var item in UniTask.WhenEach(a, b, c))
{
l.Add(item);
}
l[0].IsCompletedSuccessfully.Should().BeTrue();
l[0].IsFaulted.Should().BeFalse();
l[0].Result.Should().Be(2);
l[1].IsCompletedSuccessfully.Should().BeFalse();
l[1].IsFaulted.Should().BeTrue();
l[1].Exception.Message.Should().Be("ERROR");
l[2].IsCompletedSuccessfully.Should().BeTrue();
l[2].IsFaulted.Should().BeFalse();
l[2].Result.Should().Be(1);
}
async UniTask<int> Delay(int id, int sleep)
{
await Task.Delay(sleep);
return id;
}
async UniTask<int> Delay2(int id, int sleep)
{
await Task.Delay(sleep);
if (id == 3) throw new Exception("ERROR");
return id;
}
}
}

View File

@ -1,40 +0,0 @@
using Cysharp.Threading.Tasks;
using FluentAssertions;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Xunit;
namespace NetCoreTests
{
public class WithCancellationTest
{
[Fact]
public async Task Standard()
{
CancellationTokenSource cts = new CancellationTokenSource();
var v = await UniTask.Run(() => 10).AttachExternalCancellation(cts.Token);
v.Should().Be(10);
}
[Fact]
public async Task Cancel()
{
CancellationTokenSource cts = new CancellationTokenSource();
var t = UniTask.Create(async () =>
{
await Task.Delay(TimeSpan.FromSeconds(1));
return 10;
}).AttachExternalCancellation(cts.Token);
cts.Cancel();
(await Assert.ThrowsAsync<OperationCanceledException>(async () => await t)).CancellationToken.Should().Be(cts.Token);
}
}
}

View File

@ -1,33 +0,0 @@
#if UNITY_EDITOR
using Cysharp.Threading.Tasks;
using System;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEngine;
using UnityEngine.Networking;
public static class EditorRunnerChecker
{
[MenuItem("Tools/UniTaskEditorRunnerChecker")]
public static void RunUniTaskAsync()
{
RunCore().Forget();
}
static async UniTaskVoid RunCore()
{
Debug.Log("Start");
//var r = await UnityWebRequest.Get("https://bing.com/").SendWebRequest().ToUniTask();
//Debug.Log(r.downloadHandler.text.Substring(0, 100));
//await UniTask.Yield();
await UniTask.DelayFrame(30);
Debug.Log("End");
}
}
#endif

View File

@ -11,11 +11,9 @@ public static class PackageExporter
[MenuItem("Tools/Export Unitypackage")]
public static void Export()
{
// configure
var root = "Plugins/UniTask";
var version = GetVersion(root);
var fileName = string.IsNullOrEmpty(version) ? "UniTask.unitypackage" : $"UniTask.{version}.unitypackage";
var exportPath = "./" + fileName;
var exportPath = "./UniTask.unitypackage";
var path = Path.Combine(Application.dataPath, root);
var assets = Directory.EnumerateFiles(path, "*", SearchOption.AllDirectories)
@ -32,42 +30,6 @@ public static class PackageExporter
UnityEngine.Debug.Log("Export complete: " + Path.GetFullPath(exportPath));
}
static string GetVersion(string root)
{
var version = Environment.GetEnvironmentVariable("UNITY_PACKAGE_VERSION");
var versionJson = Path.Combine(Application.dataPath, root, "package.json");
if (File.Exists(versionJson))
{
var v = JsonUtility.FromJson<Version>(File.ReadAllText(versionJson));
if (!string.IsNullOrEmpty(version))
{
if (v.version != version)
{
var msg = $"package.json and env version are mismatched. UNITY_PACKAGE_VERSION:{version}, package.json:{v.version}";
if (Application.isBatchMode)
{
Console.WriteLine(msg);
Application.Quit(1);
}
throw new Exception("package.json and env version are mismatched.");
}
}
version = v.version;
}
return version;
}
public class Version
{
public string version;
}
}
#endif

View File

@ -0,0 +1,119 @@
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
using System.Threading;
namespace Cysharp.Threading.Tasks
{
public class AsyncLazy
{
Func<UniTask> valueFactory;
UniTask target;
object syncLock;
bool initialized;
public AsyncLazy(Func<UniTask> valueFactory)
{
this.valueFactory = valueFactory;
this.target = default;
this.syncLock = new object();
this.initialized = false;
}
internal AsyncLazy(UniTask value)
{
this.valueFactory = null;
this.target = value;
this.syncLock = null;
this.initialized = true;
}
public UniTask Task => EnsureInitialized();
public UniTask.Awaiter GetAwaiter() => EnsureInitialized().GetAwaiter();
UniTask EnsureInitialized()
{
if (Volatile.Read(ref initialized))
{
return target;
}
return EnsureInitializedCore();
}
UniTask EnsureInitializedCore()
{
lock (syncLock)
{
if (!Volatile.Read(ref initialized))
{
var f = Interlocked.Exchange(ref valueFactory, null);
if (f != null)
{
target = f().Preserve(); // with preserve(allow multiple await).
Volatile.Write(ref initialized, true);
}
}
}
return target;
}
}
public class AsyncLazy<T>
{
Func<UniTask<T>> valueFactory;
UniTask<T> target;
object syncLock;
bool initialized;
public AsyncLazy(Func<UniTask<T>> valueFactory)
{
this.valueFactory = valueFactory;
this.target = default;
this.syncLock = new object();
this.initialized = false;
}
internal AsyncLazy(UniTask<T> value)
{
this.valueFactory = null;
this.target = value;
this.syncLock = null;
this.initialized = true;
}
public UniTask<T> Task => EnsureInitialized();
public UniTask<T>.Awaiter GetAwaiter() => EnsureInitialized().GetAwaiter();
UniTask<T> EnsureInitialized()
{
if (Volatile.Read(ref initialized))
{
return target;
}
return EnsureInitializedCore();
}
UniTask<T> EnsureInitializedCore()
{
lock (syncLock)
{
if (!Volatile.Read(ref initialized))
{
var f = Interlocked.Exchange(ref valueFactory, null);
if (f != null)
{
target = f().Preserve(); // with preserve(allow multiple await).
Volatile.Write(ref initialized, true);
}
}
}
return target;
}
}
}

View File

@ -4,7 +4,7 @@ using System;
namespace Cysharp.Threading.Tasks
{
public readonly struct AsyncUnit : IEquatable<AsyncUnit>
public struct AsyncUnit : IEquatable<AsyncUnit>
{
public static readonly AsyncUnit Default = new AsyncUnit();

View File

@ -0,0 +1,74 @@
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
using System.Threading;
namespace Cysharp.Threading.Tasks
{
public static class CancellationTokenExtensions
{
static readonly Action<object> cancellationTokenCallback = Callback;
public static (UniTask, CancellationTokenRegistration) ToUniTask(this CancellationToken cts)
{
if (cts.IsCancellationRequested)
{
return (UniTask.FromCanceled(cts), default(CancellationTokenRegistration));
}
var promise = new UniTaskCompletionSource();
return (promise.Task, cts.RegisterWithoutCaptureExecutionContext(cancellationTokenCallback, promise));
}
static void Callback(object state)
{
var promise = (UniTaskCompletionSource)state;
promise.TrySetResult();
}
public static CancellationTokenRegistration RegisterWithoutCaptureExecutionContext(this CancellationToken cancellationToken, Action callback)
{
var restoreFlow = false;
if (!ExecutionContext.IsFlowSuppressed())
{
ExecutionContext.SuppressFlow();
restoreFlow = true;
}
try
{
return cancellationToken.Register(callback, false);
}
finally
{
if (restoreFlow)
{
ExecutionContext.RestoreFlow();
}
}
}
public static CancellationTokenRegistration RegisterWithoutCaptureExecutionContext(this CancellationToken cancellationToken, Action<object> callback, object state)
{
var restoreFlow = false;
if (!ExecutionContext.IsFlowSuppressed())
{
ExecutionContext.SuppressFlow();
restoreFlow = true;
}
try
{
return cancellationToken.Register(callback, state, false);
}
finally
{
if (restoreFlow)
{
ExecutionContext.RestoreFlow();
}
}
}
}
}

View File

@ -0,0 +1,50 @@
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System.Threading;
using UnityEngine;
using Cysharp.Threading.Tasks.Triggers;
using System;
namespace Cysharp.Threading.Tasks
{
public static class CancellationTokenSourceExtensions
{
public static void CancelAfterSlim(this CancellationTokenSource cts, int millisecondsDelay, bool ignoreTimeScale = false, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update)
{
var delay = UniTask.Delay(millisecondsDelay, ignoreTimeScale, delayTiming, cts.Token);
CancelAfterCore(cts, delay).Forget();
}
public static void CancelAfterSlim(this CancellationTokenSource cts, TimeSpan delayTimeSpan, bool ignoreTimeScale = false, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update)
{
var delay = UniTask.Delay(delayTimeSpan, ignoreTimeScale, delayTiming, cts.Token);
CancelAfterCore(cts, delay).Forget();
}
static async UniTaskVoid CancelAfterCore(CancellationTokenSource cts, UniTask delayTask)
{
var alreadyCanceled = await delayTask.SuppressCancellationThrow();
if (!alreadyCanceled)
{
cts.Cancel();
cts.Dispose();
}
}
public static void RegisterRaiseCancelOnDestroy(this CancellationTokenSource cts, Component component)
{
RegisterRaiseCancelOnDestroy(cts, component.gameObject);
}
public static void RegisterRaiseCancelOnDestroy(this CancellationTokenSource cts, GameObject gameObject)
{
var trigger = gameObject.GetAsyncDestroyTrigger();
trigger.CancellationToken.RegisterWithoutCaptureExecutionContext(state =>
{
var cts2 = (CancellationTokenSource)state;
cts2.Cancel();
}, cts);
}
}
}

View File

@ -12,8 +12,9 @@ namespace Cysharp.Threading.Tasks.CompilerServices
[StructLayout(LayoutKind.Auto)]
public struct AsyncUniTaskMethodBuilder
{
IStateMachineRunnerPromise runnerPromise;
Exception ex;
// cache items.
AutoResetUniTaskCompletionSource promise;
IMoveNextRunner runner;
// 1. Static Create method.
[DebuggerHidden]
@ -30,81 +31,98 @@ namespace Cysharp.Threading.Tasks.CompilerServices
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
if (runnerPromise != null)
if (promise != null)
{
return runnerPromise.Task;
return promise.Task;
}
else if (ex != null)
{
return UniTask.FromException(ex);
}
else
if (runner == null)
{
return UniTask.CompletedTask;
}
promise = AutoResetUniTaskCompletionSource.Create();
return promise.Task;
}
}
// 3. SetException
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetException(Exception exception)
{
if (runnerPromise == null)
// runner is finished, return first.
if (runner != null)
{
ex = exception;
runner.Return();
runner = null;
}
if (promise != null)
{
promise.TrySetException(exception);
}
else
{
runnerPromise.SetException(exception);
promise = AutoResetUniTaskCompletionSource.CreateFromException(exception, out _);
}
}
// 4. SetResult
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetResult()
{
if (runnerPromise != null)
// runner is finished, return first.
if (runner != null)
{
runnerPromise.SetResult();
runner.Return();
runner = null;
}
if (promise != null)
{
promise.TrySetResult();
}
}
// 5. AwaitOnCompleted
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
where TAwaiter : INotifyCompletion
where TStateMachine : IAsyncStateMachine
{
if (runnerPromise == null)
if (promise == null)
{
AsyncUniTask<TStateMachine>.SetStateMachine(ref stateMachine, ref runnerPromise);
promise = AutoResetUniTaskCompletionSource.Create();
}
if (runner == null)
{
runner = MoveNextRunner<TStateMachine>.Create(ref stateMachine);
}
awaiter.OnCompleted(runnerPromise.MoveNext);
awaiter.OnCompleted(runner.CallMoveNext);
}
// 6. AwaitUnsafeOnCompleted
[DebuggerHidden]
[SecuritySafeCritical]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
where TAwaiter : ICriticalNotifyCompletion
where TStateMachine : IAsyncStateMachine
{
if (runnerPromise == null)
if (promise == null)
{
AsyncUniTask<TStateMachine>.SetStateMachine(ref stateMachine, ref runnerPromise);
promise = AutoResetUniTaskCompletionSource.Create();
}
if (runner == null)
{
runner = MoveNextRunner<TStateMachine>.Create(ref stateMachine);
}
awaiter.UnsafeOnCompleted(runnerPromise.MoveNext);
awaiter.OnCompleted(runner.CallMoveNext);
}
// 7. Start
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Start<TStateMachine>(ref TStateMachine stateMachine)
where TStateMachine : IAsyncStateMachine
{
@ -138,8 +156,9 @@ namespace Cysharp.Threading.Tasks.CompilerServices
[StructLayout(LayoutKind.Auto)]
public struct AsyncUniTaskMethodBuilder<T>
{
IStateMachineRunnerPromise<T> runnerPromise;
Exception ex;
// cache items.
AutoResetUniTaskCompletionSource<T> promise;
IMoveNextRunner runner;
T result;
// 1. Static Create method.
@ -151,91 +170,106 @@ namespace Cysharp.Threading.Tasks.CompilerServices
}
// 2. TaskLike Task property.
[DebuggerHidden]
public UniTask<T> Task
{
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
if (runnerPromise != null)
if (promise != null)
{
return runnerPromise.Task;
return promise.Task;
}
else if (ex != null)
{
return UniTask.FromException<T>(ex);
}
else
if (runner == null)
{
return UniTask.FromResult(result);
}
promise = AutoResetUniTaskCompletionSource<T>.Create();
return promise.Task;
}
}
// 3. SetException
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetException(Exception exception)
{
if (runnerPromise == null)
// runner is finished, return first.
if (runner != null)
{
ex = exception;
runner.Return();
runner = null;
}
if (promise == null)
{
promise = AutoResetUniTaskCompletionSource<T>.CreateFromException(exception, out _);
}
else
{
runnerPromise.SetException(exception);
promise.TrySetException(exception);
}
}
// 4. SetResult
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetResult(T result)
{
if (runnerPromise == null)
// runner is finished, return first.
if (runner != null)
{
runner.Return();
runner = null;
}
if (promise == null)
{
this.result = result;
return;
}
else
{
runnerPromise.SetResult(result);
}
promise.TrySetResult(result);
}
// 5. AwaitOnCompleted
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
where TAwaiter : INotifyCompletion
where TStateMachine : IAsyncStateMachine
{
if (runnerPromise == null)
if (promise == null)
{
AsyncUniTask<TStateMachine, T>.SetStateMachine(ref stateMachine, ref runnerPromise);
promise = AutoResetUniTaskCompletionSource<T>.Create();
}
if (runner == null)
{
runner = MoveNextRunner<TStateMachine>.Create(ref stateMachine);
}
awaiter.OnCompleted(runnerPromise.MoveNext);
awaiter.OnCompleted(runner.CallMoveNext);
}
// 6. AwaitUnsafeOnCompleted
[DebuggerHidden]
[SecuritySafeCritical]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
where TAwaiter : ICriticalNotifyCompletion
where TStateMachine : IAsyncStateMachine
{
if (runnerPromise == null)
if (promise == null)
{
AsyncUniTask<TStateMachine, T>.SetStateMachine(ref stateMachine, ref runnerPromise);
promise = AutoResetUniTaskCompletionSource<T>.Create();
}
if (runner == null)
{
runner = MoveNextRunner<TStateMachine>.Create(ref stateMachine);
}
awaiter.UnsafeOnCompleted(runnerPromise.MoveNext);
awaiter.OnCompleted(runner.CallMoveNext);
}
// 7. Start
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Start<TStateMachine>(ref TStateMachine stateMachine)
where TStateMachine : IAsyncStateMachine
{

View File

@ -4,15 +4,13 @@
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
namespace Cysharp.Threading.Tasks.CompilerServices
{
[StructLayout(LayoutKind.Auto)]
public struct AsyncUniTaskVoidMethodBuilder
{
IStateMachineRunner runner;
IMoveNextRunner runner;
// 1. Static Create method.
[DebuggerHidden]
@ -35,18 +33,12 @@ namespace Cysharp.Threading.Tasks.CompilerServices
// 3. SetException
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetException(Exception exception)
{
// runner is finished, return first.
if (runner != null)
{
#if ENABLE_IL2CPP
// workaround for IL2CPP bug.
PlayerLoopHelper.AddContinuation(PlayerLoopTiming.LastPostLateUpdate, runner.ReturnAction);
#else
runner.Return();
#endif
runner = null;
}
@ -55,51 +47,43 @@ namespace Cysharp.Threading.Tasks.CompilerServices
// 4. SetResult
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetResult()
{
// runner is finished, return.
if (runner != null)
{
#if ENABLE_IL2CPP
// workaround for IL2CPP bug.
PlayerLoopHelper.AddContinuation(PlayerLoopTiming.LastPostLateUpdate, runner.ReturnAction);
#else
runner.Return();
#endif
runner = null;
}
}
// 5. AwaitOnCompleted
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
where TAwaiter : INotifyCompletion
where TStateMachine : IAsyncStateMachine
{
if (runner == null)
{
AsyncUniTaskVoid<TStateMachine>.SetStateMachine(ref stateMachine, ref runner);
runner = MoveNextRunner<TStateMachine>.Create(ref stateMachine);
}
awaiter.OnCompleted(runner.MoveNext);
awaiter.OnCompleted(runner.CallMoveNext);
}
// 6. AwaitUnsafeOnCompleted
[DebuggerHidden]
[SecuritySafeCritical]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
where TAwaiter : ICriticalNotifyCompletion
where TStateMachine : IAsyncStateMachine
{
if (runner == null)
{
AsyncUniTaskVoid<TStateMachine>.SetStateMachine(ref stateMachine, ref runner);
runner = MoveNextRunner<TStateMachine>.Create(ref stateMachine);
}
awaiter.UnsafeOnCompleted(runner.MoveNext);
awaiter.OnCompleted(runner.CallMoveNext);
}
// 7. Start

View File

@ -0,0 +1,57 @@

#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using Cysharp.Threading.Tasks.Internal;
namespace Cysharp.Threading.Tasks.CompilerServices
{
internal interface IMoveNextRunner
{
Action CallMoveNext { get; }
void Return();
}
internal sealed class MoveNextRunner<TStateMachine> : IMoveNextRunner, IPromisePoolItem
where TStateMachine : IAsyncStateMachine
{
static PromisePool<MoveNextRunner<TStateMachine>> pool = new PromisePool<MoveNextRunner<TStateMachine>>();
TStateMachine stateMachine;
internal readonly Action callMoveNext;
public Action CallMoveNext => callMoveNext;
MoveNextRunner()
{
callMoveNext = MoveNext;
}
public static MoveNextRunner<TStateMachine> Create(ref TStateMachine stateMachine)
{
var result = pool.TryRent() ?? new MoveNextRunner<TStateMachine>();
result.stateMachine = stateMachine;
return result;
}
[DebuggerHidden]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
void MoveNext()
{
stateMachine.MoveNext();
}
public void Return()
{
pool.TryReturn(this);
}
void IPromisePoolItem.Reset()
{
stateMachine = default;
}
}
}

View File

@ -10,7 +10,7 @@
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": false,
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false

View File

@ -12,55 +12,27 @@ namespace Cysharp.Threading.Tasks
{
public static class EnumeratorAsyncExtensions
{
public static UniTask.Awaiter GetAwaiter<T>(this T enumerator)
where T : IEnumerator
public static UniTask.Awaiter GetAwaiter(this IEnumerator enumerator)
{
var e = (IEnumerator)enumerator;
Error.ThrowArgumentNullException(e, nameof(enumerator));
return new UniTask(EnumeratorPromise.Create(e, PlayerLoopTiming.Update, CancellationToken.None, out var token), token).GetAwaiter();
return new UniTask(EnumeratorPromise.Create(enumerator, PlayerLoopTiming.Update, CancellationToken.None, out var token), token).GetAwaiter();
}
public static UniTask WithCancellation(this IEnumerator enumerator, CancellationToken cancellationToken)
public static UniTask ToUniTask(this IEnumerator enumerator)
{
Error.ThrowArgumentNullException(enumerator, nameof(enumerator));
return new UniTask(EnumeratorPromise.Create(enumerator, PlayerLoopTiming.Update, cancellationToken, out var token), token);
return new UniTask(EnumeratorPromise.Create(enumerator, PlayerLoopTiming.Update, CancellationToken.None, out var token), token);
}
public static UniTask ToUniTask(this IEnumerator enumerator, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
public static UniTask ConfigureAwait(this IEnumerator enumerator, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
{
Error.ThrowArgumentNullException(enumerator, nameof(enumerator));
return new UniTask(EnumeratorPromise.Create(enumerator, timing, cancellationToken, out var token), token);
}
public static UniTask ToUniTask(this IEnumerator enumerator, MonoBehaviour coroutineRunner)
class EnumeratorPromise : IUniTaskSource, IPlayerLoopItem, IPromisePoolItem
{
var source = AutoResetUniTaskCompletionSource.Create();
coroutineRunner.StartCoroutine(Core(enumerator, coroutineRunner, source));
return source.Task;
}
static IEnumerator Core(IEnumerator inner, MonoBehaviour coroutineRunner, AutoResetUniTaskCompletionSource source)
{
yield return coroutineRunner.StartCoroutine(inner);
source.TrySetResult();
}
sealed class EnumeratorPromise : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode<EnumeratorPromise>
{
static TaskPool<EnumeratorPromise> pool;
EnumeratorPromise nextNode;
public ref EnumeratorPromise NextNode => ref nextNode;
static EnumeratorPromise()
{
TaskPool.RegisterSizeGetter(typeof(EnumeratorPromise), () => pool.Size);
}
static readonly PromisePool<EnumeratorPromise> pool = new PromisePool<EnumeratorPromise>();
IEnumerator innerEnumerator;
CancellationToken cancellationToken;
int initialFrame;
bool loopRunning;
bool calledGetResult;
UniTaskCompletionSourceCore<object> core;
@ -75,26 +47,16 @@ namespace Cysharp.Threading.Tasks
return AutoResetUniTaskCompletionSource.CreateFromCanceled(cancellationToken, out token);
}
if (!pool.TryPop(out var result))
{
result = new EnumeratorPromise();
}
TaskTracker.TrackActiveTask(result, 3);
var result = pool.TryRent() ?? new EnumeratorPromise();
result.innerEnumerator = ConsumeEnumerator(innerEnumerator);
result.cancellationToken = cancellationToken;
result.loopRunning = true;
result.calledGetResult = false;
result.initialFrame = -1;
TaskTracker.TrackActiveTask(result, 3);
PlayerLoopHelper.AddAction(timing, result);
token = result.core.Version;
// run immediately.
if (result.MoveNext())
{
PlayerLoopHelper.AddAction(timing, result);
}
return result;
}
@ -102,15 +64,12 @@ namespace Cysharp.Threading.Tasks
{
try
{
calledGetResult = true;
TaskTracker.RemoveTracking(this);
core.GetResult(token);
}
finally
{
if (!loopRunning)
{
TryReturn();
}
pool.TryReturn(this);
}
}
@ -131,38 +90,12 @@ namespace Cysharp.Threading.Tasks
public bool MoveNext()
{
if (calledGetResult)
{
loopRunning = false;
TryReturn();
return false;
}
if (innerEnumerator == null) // invalid status, returned but loop running?
{
return false;
}
if (cancellationToken.IsCancellationRequested)
{
loopRunning = false;
core.TrySetCanceled(cancellationToken);
return false;
}
if (initialFrame == -1)
{
// Time can not touch in threadpool.
if (PlayerLoopHelper.IsMainThread)
{
initialFrame = Time.frameCount;
}
}
else if (initialFrame == Time.frameCount)
{
return true; // already executed in first frame, skip.
}
try
{
if (innerEnumerator.MoveNext())
@ -172,24 +105,27 @@ namespace Cysharp.Threading.Tasks
}
catch (Exception ex)
{
loopRunning = false;
core.TrySetException(ex);
return false;
}
loopRunning = false;
core.TrySetResult(null);
return false;
}
bool TryReturn()
public void Reset()
{
TaskTracker.RemoveTracking(this);
core.Reset();
innerEnumerator = default;
cancellationToken = default;
}
return pool.TryPush(this);
~EnumeratorPromise()
{
if (pool.TryReturn(this))
{
GC.ReRegisterForFinalize(this);
}
}
// Unwrap YieldInstructions
@ -203,10 +139,11 @@ namespace Cysharp.Threading.Tasks
{
yield return null;
}
else if (current is CustomYieldInstruction cyi)
else if (current is CustomYieldInstruction)
{
// WWW, WaitForSecondsRealtime
while (cyi.keepWaiting)
var e2 = UnwrapWaitCustomYieldInstruction((CustomYieldInstruction)current);
while (e2.MoveNext())
{
yield return null;
}
@ -232,7 +169,7 @@ namespace Cysharp.Threading.Tasks
}
else
{
goto WARN;
yield return null;
}
}
else if (current is IEnumerator e3)
@ -245,14 +182,17 @@ namespace Cysharp.Threading.Tasks
}
else
{
goto WARN;
// WaitForEndOfFrame, WaitForFixedUpdate, others.
yield return null;
}
}
}
continue;
WARN:
// WaitForEndOfFrame, WaitForFixedUpdate, others.
UnityEngine.Debug.LogWarning($"yield {current.GetType().Name} is not supported on await IEnumerator or IEnumerator.ToUniTask(), please use ToUniTask(MonoBehaviour coroutineRunner) instead.");
// WWW and others as CustomYieldInstruction.
static IEnumerator UnwrapWaitCustomYieldInstruction(CustomYieldInstruction yieldInstruction)
{
while (yieldInstruction.keepWaiting)
{
yield return null;
}
}
@ -262,12 +202,12 @@ namespace Cysharp.Threading.Tasks
static IEnumerator UnwrapWaitForSeconds(WaitForSeconds waitForSeconds)
{
var second = (float)waitForSeconds_Seconds.GetValue(waitForSeconds);
var elapsed = 0.0f;
var startTime = DateTimeOffset.UtcNow;
while (true)
{
yield return null;
elapsed += Time.deltaTime;
var elapsed = (DateTimeOffset.UtcNow - startTime).TotalSeconds;
if (elapsed >= second)
{
break;
@ -285,3 +225,4 @@ namespace Cysharp.Threading.Tasks
}
}
}

View File

@ -0,0 +1,373 @@
// asmdef Version Defines, enabled when com.unity.addressables is imported.
#if UNITASK_ADDRESSABLE_SUPPORT
using Cysharp.Threading.Tasks.Internal;
using System;
using System.Runtime.CompilerServices;
using System.Runtime.ExceptionServices;
using System.Threading;
using UnityEngine.ResourceManagement.AsyncOperations;
namespace Cysharp.Threading.Tasks
{
public static class AddressableAsyncExtensions
{
#region AsyncOperationHandle
public static AsyncOperationHandleAwaiter GetAwaiter(this AsyncOperationHandle handle)
{
return new AsyncOperationHandleAwaiter(handle);
}
public static UniTask ToUniTask(this AsyncOperationHandle handle)
{
return new UniTask(AsyncOperationHandleConfiguredSource.Create(handle, PlayerLoopTiming.Update, null, CancellationToken.None, out var token), token);
}
public static UniTask ConfigureAwait(this AsyncOperationHandle handle, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellation = default(CancellationToken))
{
return new UniTask(AsyncOperationHandleConfiguredSource.Create(handle, timing, progress, cancellation, out var token), token);
}
public struct AsyncOperationHandleAwaiter : ICriticalNotifyCompletion
{
AsyncOperationHandle handle;
Action<AsyncOperationHandle> continuationAction;
public AsyncOperationHandleAwaiter(AsyncOperationHandle handle)
{
this.handle = handle;
this.continuationAction = null;
}
public bool IsCompleted => handle.IsDone;
public void GetResult()
{
if (continuationAction != null)
{
handle.Completed -= continuationAction;
continuationAction = null;
}
if (handle.Status == AsyncOperationStatus.Failed)
{
var e = handle.OperationException;
handle = default;
ExceptionDispatchInfo.Capture(e).Throw();
}
var result = handle.Result;
handle = default;
}
public void OnCompleted(Action continuation)
{
UnsafeOnCompleted(continuation);
}
public void UnsafeOnCompleted(Action continuation)
{
Error.ThrowWhenContinuationIsAlreadyRegistered(continuationAction);
continuationAction = continuation.AsFuncOfT<AsyncOperationHandle>(); // allocate delegate.
handle.Completed += continuationAction;
}
}
class AsyncOperationHandleConfiguredSource : IUniTaskSource, IPlayerLoopItem, IPromisePoolItem
{
static readonly PromisePool<AsyncOperationHandleConfiguredSource> pool = new PromisePool<AsyncOperationHandleConfiguredSource>();
AsyncOperationHandle handle;
IProgress<float> progress;
CancellationToken cancellationToken;
UniTaskCompletionSourceCore<AsyncUnit> core;
AsyncOperationHandleConfiguredSource()
{
}
public static IUniTaskSource Create(AsyncOperationHandle handle, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, out short token)
{
if (cancellationToken.IsCancellationRequested)
{
return AutoResetUniTaskCompletionSource.CreateFromCanceled(cancellationToken, out token);
}
var result = pool.TryRent() ?? new AsyncOperationHandleConfiguredSource();
result.handle = handle;
result.progress = progress;
result.cancellationToken = cancellationToken;
TaskTracker.TrackActiveTask(result, 3);
PlayerLoopHelper.AddAction(timing, result);
token = result.core.Version;
return result;
}
public void GetResult(short token)
{
try
{
TaskTracker.RemoveTracking(this);
core.GetResult(token);
}
finally
{
pool.TryReturn(this);
}
}
public UniTaskStatus GetStatus(short token)
{
return core.GetStatus(token);
}
public UniTaskStatus UnsafeGetStatus()
{
return core.UnsafeGetStatus();
}
public void OnCompleted(Action<object> continuation, object state, short token)
{
core.OnCompleted(continuation, state, token);
}
public bool MoveNext()
{
if (cancellationToken.IsCancellationRequested)
{
core.TrySetCanceled(cancellationToken);
return false;
}
if (progress != null)
{
progress.Report(handle.PercentComplete);
}
if (handle.IsDone)
{
if (handle.Status == AsyncOperationStatus.Failed)
{
core.TrySetException(handle.OperationException);
}
else
{
core.TrySetResult(AsyncUnit.Default);
}
return false;
}
return true;
}
public void Reset()
{
core.Reset();
handle = default;
progress = default;
cancellationToken = default;
}
~AsyncOperationHandleConfiguredSource()
{
if (pool.TryReturn(this))
{
GC.ReRegisterForFinalize(this);
}
}
}
#endregion
#region AsyncOperationHandle_T
public static AsyncOperationHandleAwaiter<T> GetAwaiter<T>(this AsyncOperationHandle<T> handle)
{
return new AsyncOperationHandleAwaiter<T>(handle);
}
public static UniTask<T> ToUniTask<T>(this AsyncOperationHandle<T> handle)
{
return new UniTask<T>(AsyncOperationHandleConfiguredSource<T>.Create(handle, PlayerLoopTiming.Update, null, CancellationToken.None, out var token), token);
}
public static UniTask<T> ConfigureAwait<T>(this AsyncOperationHandle<T> handle, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellation = default(CancellationToken))
{
return new UniTask<T>(AsyncOperationHandleConfiguredSource<T>.Create(handle, timing, progress, cancellation, out var token), token);
}
public struct AsyncOperationHandleAwaiter<T> : ICriticalNotifyCompletion
{
AsyncOperationHandle<T> handle;
Action<AsyncOperationHandle> continuationAction;
public AsyncOperationHandleAwaiter(AsyncOperationHandle<T> handle)
{
this.handle = handle;
this.continuationAction = null;
}
public bool IsCompleted => handle.IsDone;
public T GetResult()
{
if (continuationAction != null)
{
handle.CompletedTypeless -= continuationAction;
continuationAction = null;
}
if (handle.Status == AsyncOperationStatus.Failed)
{
var e = handle.OperationException;
handle = default;
ExceptionDispatchInfo.Capture(e).Throw();
}
var result = handle.Result;
handle = default;
return result;
}
public void OnCompleted(Action continuation)
{
UnsafeOnCompleted(continuation);
}
public void UnsafeOnCompleted(Action continuation)
{
Error.ThrowWhenContinuationIsAlreadyRegistered(continuationAction);
continuationAction = continuation.AsFuncOfT<AsyncOperationHandle>(); // allocate delegate.
handle.CompletedTypeless += continuationAction;
}
}
class AsyncOperationHandleConfiguredSource<T> : IUniTaskSource<T>, IPlayerLoopItem, IPromisePoolItem
{
static readonly PromisePool<AsyncOperationHandleConfiguredSource<T>> pool = new PromisePool<AsyncOperationHandleConfiguredSource<T>>();
AsyncOperationHandle<T> handle;
IProgress<float> progress;
CancellationToken cancellationToken;
UniTaskCompletionSourceCore<T> core;
AsyncOperationHandleConfiguredSource()
{
}
public static IUniTaskSource<T> Create(AsyncOperationHandle<T> handle, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, out short token)
{
if (cancellationToken.IsCancellationRequested)
{
return AutoResetUniTaskCompletionSource<T>.CreateFromCanceled(cancellationToken, out token);
}
var result = pool.TryRent() ?? new AsyncOperationHandleConfiguredSource<T>();
result.handle = handle;
result.progress = progress;
result.cancellationToken = cancellationToken;
TaskTracker.TrackActiveTask(result, 3);
PlayerLoopHelper.AddAction(timing, result);
token = result.core.Version;
return result;
}
public T GetResult(short token)
{
try
{
TaskTracker.RemoveTracking(this);
return core.GetResult(token);
}
finally
{
pool.TryReturn(this);
}
}
void IUniTaskSource.GetResult(short token)
{
GetResult(token);
}
public UniTaskStatus GetStatus(short token)
{
return core.GetStatus(token);
}
public UniTaskStatus UnsafeGetStatus()
{
return core.UnsafeGetStatus();
}
public void OnCompleted(Action<object> continuation, object state, short token)
{
core.OnCompleted(continuation, state, token);
}
public bool MoveNext()
{
if (cancellationToken.IsCancellationRequested)
{
core.TrySetCanceled(cancellationToken);
return false;
}
if (progress != null)
{
progress.Report(handle.PercentComplete);
}
if (handle.IsDone)
{
if (handle.Status == AsyncOperationStatus.Failed)
{
core.TrySetException(handle.OperationException);
}
else
{
core.TrySetResult(handle.Result);
}
return false;
}
return true;
}
public void Reset()
{
core.Reset();
handle = default;
progress = default;
cancellationToken = default;
}
~AsyncOperationHandleConfiguredSource()
{
if (pool.TryReturn(this))
{
GC.ReRegisterForFinalize(this);
}
}
}
#endregion
}
}
#endif

View File

@ -0,0 +1,66 @@
#pragma warning disable CS1591
using System;
using System.Runtime.CompilerServices;
namespace Cysharp.Threading.Tasks
{
public enum UniTaskStatus
{
/// <summary>The operation has not yet completed.</summary>
Pending = 0,
/// <summary>The operation completed successfully.</summary>
Succeeded = 1,
/// <summary>The operation completed with an error.</summary>
Faulted = 2,
/// <summary>The operation completed due to cancellation.</summary>
Canceled = 3
}
// similar as IValueTaskSource
public interface IUniTaskSource
{
UniTaskStatus GetStatus(short token);
void OnCompleted(Action<object> continuation, object state, short token);
void GetResult(short token);
UniTaskStatus UnsafeGetStatus(); // only for debug use.
}
public interface IUniTaskSource<out T> : IUniTaskSource
{
new T GetResult(short token);
}
public static class UniTaskStatusExtensions
{
/// <summary>status != Pending.</summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsCompleted(this UniTaskStatus status)
{
return status != UniTaskStatus.Pending;
}
/// <summary>status == Succeeded.</summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsCompletedSuccessfully(this UniTaskStatus status)
{
return status == UniTaskStatus.Succeeded;
}
/// <summary>status == Canceled.</summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsCanceled(this UniTaskStatus status)
{
return status == UniTaskStatus.Canceled;
}
/// <summary>status == Faulted.</summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsFaulted(this UniTaskStatus status)
{
return status == UniTaskStatus.Faulted;
}
}
}

View File

@ -32,21 +32,11 @@ namespace Cysharp.Threading.Tasks.Internal
}
}
public static RentArray<T> Materialize<T>(IEnumerable<T> source)
public static RentArray<T> CopyToRentArray<T>(IEnumerable<T> source)
{
if (source is T[] array)
{
return new RentArray<T>(array, array.Length, null);
}
var defaultCount = 32;
if (source is ICollection<T> coll)
{
if (coll.Count == 0)
{
return new RentArray<T>(Array.Empty<T>(), 0, null);
}
defaultCount = coll.Count;
var pool = ArrayPool<T>.Shared;
var buffer = pool.Rent(defaultCount);

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