-
Notifications
You must be signed in to change notification settings - Fork 104
/
Copy pathTestExtensions.cs
112 lines (97 loc) · 4.87 KB
/
TestExtensions.cs
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
110
111
112
using Neo.Cryptography.ECC;
using Neo.SmartContract.Iterators;
using Neo.VM.Types;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Reflection;
namespace Neo.SmartContract.Testing.Extensions
{
public static class TestExtensions
{
/// <summary>
/// Convert Array stack item to dotnet array
/// </summary>
/// <param name="state">Item</param>
/// <param name="parameters">Parameters</param>
/// <returns>Object</returns>
public static object?[]? ConvertTo(this VM.Types.Array state, ParameterInfo[] parameters)
{
if (parameters.Length > 0)
{
object?[] args = new object[parameters.Length];
for (int x = 0; x < parameters.Length; x++)
{
args[x] = state[x].ConvertTo(parameters[x].ParameterType);
}
return args;
}
return null;
}
/// <summary>
/// Convert stack item to dotnet
/// </summary>
/// <param name="stackItem">Item</param>
/// <param name="type">Type</param>
/// <returns>Object</returns>
public static object? ConvertTo(this StackItem stackItem, Type type)
{
if (stackItem is null || stackItem.IsNull) return null;
return type switch
{
_ when type == typeof(string) => Utility.StrictUTF8.GetString(stackItem.GetSpan()),
_ when type == typeof(byte[]) => stackItem.GetSpan().ToArray(),
_ when type == typeof(bool) => stackItem.GetBoolean(),
_ when type == typeof(bool?) => stackItem.GetBoolean(),
_ when type == typeof(byte) => (byte)stackItem.GetInteger(),
_ when type == typeof(byte?) => (byte)stackItem.GetInteger(),
_ when type == typeof(sbyte) => (sbyte)stackItem.GetInteger(),
_ when type == typeof(sbyte?) => (sbyte)stackItem.GetInteger(),
_ when type == typeof(short) => (short)stackItem.GetInteger(),
_ when type == typeof(short?) => (short)stackItem.GetInteger(),
_ when type == typeof(ushort) => (ushort)stackItem.GetInteger(),
_ when type == typeof(ushort?) => (ushort)stackItem.GetInteger(),
_ when type == typeof(int) => (int)stackItem.GetInteger(),
_ when type == typeof(int?) => (int)stackItem.GetInteger(),
_ when type == typeof(uint) => (uint)stackItem.GetInteger(),
_ when type == typeof(uint?) => (uint)stackItem.GetInteger(),
_ when type == typeof(long) => (long)stackItem.GetInteger(),
_ when type == typeof(long?) => (long)stackItem.GetInteger(),
_ when type == typeof(ulong) => (ulong)stackItem.GetInteger(),
_ when type == typeof(ulong?) => (ulong)stackItem.GetInteger(),
_ when type.IsEnum => Enum.ToObject(type, (int)stackItem.GetInteger()),
_ when type == typeof(BigInteger) => stackItem.GetInteger(),
_ when type == typeof(BigInteger?) => stackItem.GetInteger(),
_ when type == typeof(UInt160) => new UInt160(stackItem.GetSpan().ToArray()),
_ when type == typeof(UInt256) => new UInt256(stackItem.GetSpan().ToArray()),
_ when type == typeof(ECPoint) => ECPoint.FromBytes(stackItem.GetSpan().ToArray(), ECCurve.Secp256r1),
_ when type == typeof(List<object>) && stackItem is CompoundType cp => new List<object>(cp.SubItems), // SubItems in StackItem type
_ when typeof(IInteroperable).IsAssignableFrom(type) => CreateInteroperable(stackItem, type),
_ when type.IsArray && stackItem is CompoundType cp => CreateTypeArray(cp.SubItems, type.GetElementType()!),
_ when type == typeof(IIterator) && stackItem is InteropInterface it => it.GetInterface<IIterator>(),
_ => throw new FormatException($"Impossible to convert {stackItem} to {type}"),
};
}
private static object CreateTypeArray(IEnumerable<StackItem> objects, Type elementType)
{
var obj = objects.ToArray();
if (elementType != typeof(object))
{
var arr = System.Array.CreateInstance(elementType, obj.Length);
for (int x = 0; x < arr.Length; x++)
{
arr.SetValue(ConvertTo(obj[x], elementType), x);
}
return arr;
}
return obj;
}
private static object CreateInteroperable(StackItem stackItem, Type type)
{
var interoperable = (IInteroperable)Activator.CreateInstance(type)!;
interoperable.FromStackItem(stackItem);
return interoperable;
}
}
}