Repository navigation
Expand file tree
/
Copy pathTest.cs
More file actions
109 lines (85 loc) · 3.23 KB
/
Copy pathTest.cs
File metadata and controls
109 lines (85 loc) · 3.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
using System.Buffers;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
namespace DotNext;
using static Buffers.Memory;
[ExcludeFromCodeCoverage]
public abstract class Test : Assert
{
protected const string Alphabet = "abcdefghijklmnopqrstuvwxyz";
protected const string AlphabetUpperCase = "ABCDEFGHIJKLMNOPQRSTUVWXY";
protected const string Numbers = "0123456789";
private protected static readonly TimeSpan DefaultTimeout = TimeSpan.FromSeconds(20);
private protected static byte[] RandomBytes(int size)
{
var result = new byte[size];
Random.Shared.NextBytes(result);
return result;
}
private protected static CancellationToken TestToken => TestContext.Current.CancellationToken;
private static IEnumerable<ReadOnlyMemory<T>> Split<T>(ReadOnlyMemory<T> memory, int chunkSize)
{
var startIndex = 0;
var length = int.Min(chunkSize, memory.Length);
do
{
yield return memory.Slice(startIndex, length);
startIndex += chunkSize;
length = int.Min(memory.Length - startIndex, chunkSize);
}
while (startIndex < memory.Length);
}
private protected static ReadOnlySequence<T> ToReadOnlySequence<T>(ReadOnlyMemory<T> memory, int chunkSize)
=> Split(memory, chunkSize).Concat();
private protected static Action<T> Equal<T>(T expected) => actual => Equal(expected, actual);
private protected static Action<T> Same<T>(T expected)
where T : class
=> actual => Same(expected, actual);
private protected static Task<TException> ThrowsAsync<TException>(Task task)
where TException : Exception
=> ThrowsAsync<TException>(Func<Task>.Constant(task));
private protected static Task<TException> ThrowsAnyAsync<TException>(Task task)
where TException : Exception
=> ThrowsAnyAsync<TException>(Func<Task>.Constant(task));
protected static TResult InvokeAsThread<TResult>(Func<TResult> func, [CallerMemberName] string threadName = "")
{
var state = new State<TResult>(func);
var thread = new Thread(Start)
{
IsBackground = true,
Name = threadName,
};
thread.UnsafeStart(state);
True(thread.Join(DefaultTimeout));
return state.Result;
static void Start(object state)
{
var tuple = (State<TResult>)state;
tuple.Invoke();
}
}
private sealed class State<T>(Func<T> func)
{
internal T Result;
internal void Invoke() => Result = func();
}
public static string GetTempPath()
{
var root = Path.Combine(Path.GetTempPath(), "dotnext.test");
if (!Directory.Exists(root))
Directory.CreateDirectory(root);
return Path.Combine(root, Path.GetRandomFileName());
}
protected static void SpinWait(Task task, CancellationToken token)
{
for (var spin = new SpinWait(); !task.IsCompleted; token.ThrowIfCancellationRequested())
{
spin.SpinOnce();
}
}
protected static T GetResultIfCompleted<T>(Task<T> task)
{
True(task.IsCompleted);
return task.Result;
}
}