OSDN Git Service

Merge pull request #307 from opentween/detect-rate-limits
[opentween/open-tween.git] / OpenTween.Tests / AsyncExceptionBoundaryTest.cs
1 // OpenTween - Client of Twitter
2 // Copyright (c) 2024 kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/>
3 // All rights reserved.
4 //
5 // This file is part of OpenTween.
6 //
7 // This program is free software; you can redistribute it and/or modify it
8 // under the terms of the GNU General Public License as published by the Free
9 // Software Foundation; either version 3 of the License, or (at your option)
10 // any later version.
11 //
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 // for more details.
16 //
17 // You should have received a copy of the GNU General Public License along
18 // with this program. If not, see <http://www.gnu.org/licenses/>, or write to
19 // the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
20 // Boston, MA 02110-1301, USA.
21
22 using System;
23 using System.IO;
24 using System.Threading.Tasks;
25 using Xunit;
26
27 namespace OpenTween
28 {
29     public class AsyncExceptionBoundaryTest
30     {
31         [Fact]
32         public async Task Wrap_SynchronousTest()
33         {
34             static Task AsyncFunc()
35                 => throw new OperationCanceledException();
36
37             // 例外を無視して終了する
38             await AsyncExceptionBoundary.Wrap(AsyncFunc);
39         }
40
41         [Fact]
42         public async Task Wrap_AsynchronousTest()
43         {
44             static async Task AsyncFunc()
45             {
46                 await Task.Yield();
47                 throw new OperationCanceledException();
48             }
49
50             // 例外を無視して終了する
51             await AsyncExceptionBoundary.Wrap(AsyncFunc);
52         }
53
54         [Fact]
55         public async Task Wrap_IgnoredTest()
56         {
57             static Task AsyncFunc()
58                 => throw new OperationCanceledException();
59
60             static bool IgnoreException(Exception ex)
61                 => ex is OperationCanceledException;
62
63             // 例外を無視して終了する
64             await AsyncExceptionBoundary.Wrap(AsyncFunc, IgnoreException);
65         }
66
67         [Fact]
68         public async Task Wrap_NotIgnoredTest()
69         {
70             static Task AsyncFunc()
71                 => throw new IOException();
72
73             static bool IgnoreException(Exception ex)
74                 => ex is OperationCanceledException;
75
76             // 例外を返して終了する
77             await Assert.ThrowsAsync<IOException>(
78                 () => AsyncExceptionBoundary.Wrap(AsyncFunc, IgnoreException)
79             );
80         }
81
82         [Fact]
83         public async Task IgnoreException_Test()
84         {
85             var task = Task.FromException(new OperationCanceledException());
86
87             // 例外を無視して終了する
88             await AsyncExceptionBoundary.IgnoreException(task);
89         }
90
91         [Fact]
92         public async Task IgnoreExceptionAndDispose_Test()
93         {
94             var task = Task.FromException<int>(new OperationCanceledException());
95
96             // 例外を無視して終了する
97             await AsyncExceptionBoundary.IgnoreExceptionAndDispose(task);
98         }
99
100         [Fact]
101         public async Task IgnoreExceptionAndDispose_DisposeTest()
102         {
103             using var image = TestUtils.CreateDummyImage();
104             var task = Task.FromResult<object>(image); // IDisposable であることを静的に判定できない場合も想定
105
106             // 正常終了したとき Result が IDisposable だった場合は破棄する
107             await AsyncExceptionBoundary.IgnoreExceptionAndDispose(task);
108             Assert.True(image.IsDisposed);
109         }
110
111         [Fact]
112         public async Task IgnoreExceptionAndDispose_IEnumerableTest()
113         {
114             using var image1 = TestUtils.CreateDummyImage();
115             using var image2 = TestUtils.CreateDummyImage();
116             var tasks = new[]
117             {
118                 Task.FromResult<object>(image1), // IDisposable であることを静的に判定できない場合も想定
119                 Task.FromResult<object>(image2),
120             };
121
122             // 正常終了したとき Result が IDisposable だった場合は破棄する
123             await AsyncExceptionBoundary.IgnoreExceptionAndDispose(tasks);
124             Assert.True(image1.IsDisposed);
125             Assert.True(image2.IsDisposed);
126         }
127     }
128 }