mirror of
https://github.com/JKorf/CryptoExchange.Net
synced 2026-04-12 16:13:12 +00:00
wip
This commit is contained in:
parent
ee30618566
commit
ab356681fb
@ -155,8 +155,8 @@ namespace CryptoExchange.Net.UnitTests
|
|||||||
[TestCase("three", TestEnum.Three)]
|
[TestCase("three", TestEnum.Three)]
|
||||||
[TestCase("Four", TestEnum.Four)]
|
[TestCase("Four", TestEnum.Four)]
|
||||||
[TestCase("four", TestEnum.Four)]
|
[TestCase("four", TestEnum.Four)]
|
||||||
[TestCase("Four1", (TestEnum)(-1))]
|
[TestCase("Four1", (TestEnum)(-9))]
|
||||||
[TestCase(null, (TestEnum)(-1))]
|
[TestCase(null, (TestEnum)(-9))]
|
||||||
public void TestEnumConverterNotNullableDeserializeTests(string value, TestEnum expected)
|
public void TestEnumConverterNotNullableDeserializeTests(string value, TestEnum expected)
|
||||||
{
|
{
|
||||||
var val = value == null ? "null" : $"\"{value}\"";
|
var val = value == null ? "null" : $"\"{value}\"";
|
||||||
@ -164,6 +164,13 @@ namespace CryptoExchange.Net.UnitTests
|
|||||||
Assert.That(output.Value == expected);
|
Assert.That(output.Value == expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestEnumConverterMapsUndefinedValueCorrectlyIfDefaultIsDefined()
|
||||||
|
{
|
||||||
|
var output = JsonSerializer.Deserialize<TestEnum2>($"\"TestUndefined\"");
|
||||||
|
Assert.That((int)output == -99);
|
||||||
|
}
|
||||||
|
|
||||||
[TestCase("1", TestEnum.One)]
|
[TestCase("1", TestEnum.One)]
|
||||||
[TestCase("2", TestEnum.Two)]
|
[TestCase("2", TestEnum.Two)]
|
||||||
[TestCase("3", TestEnum.Three)]
|
[TestCase("3", TestEnum.Three)]
|
||||||
@ -425,6 +432,20 @@ namespace CryptoExchange.Net.UnitTests
|
|||||||
Four
|
Four
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[JsonConverter(typeof(EnumConverter<TestEnum2>))]
|
||||||
|
public enum TestEnum2
|
||||||
|
{
|
||||||
|
[Map("-9")]
|
||||||
|
Minus9 = -9,
|
||||||
|
[Map("1")]
|
||||||
|
One,
|
||||||
|
[Map("2")]
|
||||||
|
Two,
|
||||||
|
[Map("three", "3")]
|
||||||
|
Three,
|
||||||
|
Four
|
||||||
|
}
|
||||||
|
|
||||||
[JsonSerializable(typeof(Test))]
|
[JsonSerializable(typeof(Test))]
|
||||||
[JsonSerializable(typeof(Test2))]
|
[JsonSerializable(typeof(Test2))]
|
||||||
[JsonSerializable(typeof(Test3))]
|
[JsonSerializable(typeof(Test3))]
|
||||||
|
|||||||
@ -487,10 +487,12 @@ namespace CryptoExchange.Net.Authentication
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// ctor
|
/// ctor
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected AuthenticationProvider(TApiCredentials credentials, TCredentialType? credential) : base(credentials)
|
protected AuthenticationProvider(
|
||||||
|
TApiCredentials credentials,
|
||||||
|
TCredentialType? credential) : base(credentials)
|
||||||
{
|
{
|
||||||
if (credential == null)
|
if (credential == null)
|
||||||
throw new ArgumentException("Missing required credentials");
|
throw new ArgumentException($"Missing \"{typeof(TCredentialType).Name}\" credentials on \"{credentials.GetType().Name}\"");
|
||||||
|
|
||||||
Credential = credential;
|
Credential = credential;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -35,7 +35,7 @@ namespace CryptoExchange.Net.Authentication
|
|||||||
public override void Validate()
|
public override void Validate()
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(Key))
|
if (string.IsNullOrEmpty(Key))
|
||||||
throw new ArgumentException("Key unset", nameof(Key));
|
throw new ArgumentException($"Key not set on {GetType().Name}", nameof(Key));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,7 +103,7 @@ namespace CryptoExchange.Net.Authentication
|
|||||||
{
|
{
|
||||||
base.Validate();
|
base.Validate();
|
||||||
if (string.IsNullOrEmpty(Secret))
|
if (string.IsNullOrEmpty(Secret))
|
||||||
throw new ArgumentException("Secret unset", nameof(Secret));
|
throw new ArgumentException($"Secret not set on {GetType().Name}", nameof(Secret));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,7 +144,7 @@ namespace CryptoExchange.Net.Authentication
|
|||||||
{
|
{
|
||||||
base.Validate();
|
base.Validate();
|
||||||
if (string.IsNullOrEmpty(Pass))
|
if (string.IsNullOrEmpty(Pass))
|
||||||
throw new ArgumentException("Pass unset", nameof(Pass));
|
throw new ArgumentException($"Pass not set on {GetType().Name}", nameof(Pass));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,7 +185,7 @@ namespace CryptoExchange.Net.Authentication
|
|||||||
{
|
{
|
||||||
base.Validate();
|
base.Validate();
|
||||||
if (string.IsNullOrEmpty(PrivateKey))
|
if (string.IsNullOrEmpty(PrivateKey))
|
||||||
throw new ArgumentException("PrivateKey unset", nameof(PrivateKey));
|
throw new ArgumentException($"PrivateKey not set on {GetType().Name}", nameof(PrivateKey));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,7 +223,7 @@ namespace CryptoExchange.Net.Authentication
|
|||||||
{
|
{
|
||||||
base.Validate();
|
base.Validate();
|
||||||
if (string.IsNullOrEmpty(Pass))
|
if (string.IsNullOrEmpty(Pass))
|
||||||
throw new ArgumentException("Pass unset", nameof(Pass));
|
throw new ArgumentException($"PrivateKey not set on {GetType().Name}", nameof(PrivateKey));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,15 +268,7 @@ namespace CryptoExchange.Net.Authentication
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override ApiCredentials Copy() => new RSAPemCredential(Key, PrivateKey);
|
public override ApiCredentials Copy() => new RSAPemCredential(Key, PrivateKey);
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override void Validate()
|
|
||||||
{
|
|
||||||
base.Validate();
|
|
||||||
if (string.IsNullOrEmpty(PrivateKey))
|
|
||||||
throw new ArgumentException("PrivateKey unset", nameof(PrivateKey));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -451,7 +443,7 @@ namespace CryptoExchange.Net.Authentication
|
|||||||
{
|
{
|
||||||
base.Validate();
|
base.Validate();
|
||||||
if (string.IsNullOrEmpty(PrivateKey))
|
if (string.IsNullOrEmpty(PrivateKey))
|
||||||
throw new ArgumentException("PrivateKey unset", nameof(PrivateKey));
|
throw new ArgumentException($"PrivateKey not set on {GetType().Name}", nameof(PrivateKey));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -491,7 +483,7 @@ namespace CryptoExchange.Net.Authentication
|
|||||||
{
|
{
|
||||||
base.Validate();
|
base.Validate();
|
||||||
if (string.IsNullOrEmpty(Pass))
|
if (string.IsNullOrEmpty(Pass))
|
||||||
throw new ArgumentException("Pass unset", nameof(Pass));
|
throw new ArgumentException($"Pass not set on {GetType().Name}", nameof(Pass));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -531,7 +523,7 @@ namespace CryptoExchange.Net.Authentication
|
|||||||
{
|
{
|
||||||
base.Validate();
|
base.Validate();
|
||||||
if (string.IsNullOrEmpty(PrivateKey))
|
if (string.IsNullOrEmpty(PrivateKey))
|
||||||
throw new ArgumentException("PrivateKey unset", nameof(PrivateKey));
|
throw new ArgumentException($"PrivateKey not set on {GetType().Name}", nameof(PrivateKey));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -571,7 +563,7 @@ namespace CryptoExchange.Net.Authentication
|
|||||||
{
|
{
|
||||||
base.Validate();
|
base.Validate();
|
||||||
if (string.IsNullOrEmpty(Pass))
|
if (string.IsNullOrEmpty(Pass))
|
||||||
throw new ArgumentException("Pass unset", nameof(Pass));
|
throw new ArgumentException($"Pass not set on {GetType().Name}", nameof(Pass));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -152,7 +152,7 @@ namespace CryptoExchange.Net.Authentication.Signing
|
|||||||
if (memberValue.Value is string v)
|
if (memberValue.Value is string v)
|
||||||
{
|
{
|
||||||
if (!BigInteger.TryParse(v, out BigInteger parsedOutput))
|
if (!BigInteger.TryParse(v, out BigInteger parsedOutput))
|
||||||
throw new Exception("");
|
throw new Exception($"Failed to encode BigInteger string {v}");
|
||||||
|
|
||||||
writer.Write(CeAbiEncoder.AbiValueEncodeBigInteger(memberValue.TypeName[0] != 'u', parsedOutput));
|
writer.Write(CeAbiEncoder.AbiValueEncodeBigInteger(memberValue.TypeName[0] != 'u', parsedOutput));
|
||||||
}
|
}
|
||||||
@ -186,19 +186,11 @@ namespace CryptoExchange.Net.Authentication.Signing
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw new Exception();
|
throw new Exception("Unknown number value");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (memberValue.TypeName.StartsWith("bytes"))
|
else if (memberValue.TypeName.StartsWith("bytes"))
|
||||||
{
|
{
|
||||||
// Applicable?
|
|
||||||
//if (memberValue.Value is string v)
|
|
||||||
// writer.Write(AbiEncoder.AbiValueEncodeHexBytes(v));
|
|
||||||
//else if (memberValue.Value is byte[] b)
|
|
||||||
// writer.Write(AbiEncoder.AbiValueEncodeBytes(b));
|
|
||||||
//else
|
|
||||||
// throw new Exception("Unknown byte value type");
|
|
||||||
|
|
||||||
var length = memberValue.TypeName.Length == 5 ? 32 : int.Parse(memberValue.TypeName.Substring(5));
|
var length = memberValue.TypeName.Length == 5 ? 32 : int.Parse(memberValue.TypeName.Substring(5));
|
||||||
writer.Write(CeAbiEncoder.AbiValueEncodeBytes(length, (byte[])memberValue.Value));
|
writer.Write(CeAbiEncoder.AbiValueEncodeBytes(length, (byte[])memberValue.Value));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,67 +0,0 @@
|
|||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace CryptoExchange.Net.Clients
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Base crypto client
|
|
||||||
/// </summary>
|
|
||||||
public class CryptoBaseClient : IDisposable
|
|
||||||
{
|
|
||||||
private readonly Dictionary<Type, object> _serviceCache = new Dictionary<Type, object>();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Service provider
|
|
||||||
/// </summary>
|
|
||||||
protected readonly IServiceProvider? _serviceProvider;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// ctor
|
|
||||||
/// </summary>
|
|
||||||
public CryptoBaseClient() { }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// ctor
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="serviceProvider"></param>
|
|
||||||
public CryptoBaseClient(IServiceProvider serviceProvider)
|
|
||||||
{
|
|
||||||
_serviceProvider = serviceProvider;
|
|
||||||
_serviceCache = new Dictionary<Type, object>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Try get a client by type for the service collection
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T"></typeparam>
|
|
||||||
/// <returns></returns>
|
|
||||||
public T TryGet<T>(Func<T> createFunc)
|
|
||||||
{
|
|
||||||
var type = typeof(T);
|
|
||||||
if (_serviceCache.TryGetValue(type, out var value))
|
|
||||||
return (T)value;
|
|
||||||
|
|
||||||
if (_serviceProvider == null)
|
|
||||||
{
|
|
||||||
// Create with default options
|
|
||||||
var createResult = createFunc();
|
|
||||||
_serviceCache.Add(typeof(T), createResult!);
|
|
||||||
return createResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
var result = _serviceProvider.GetService<T>()
|
|
||||||
?? throw new InvalidOperationException($"No service was found for {typeof(T).Name}, make sure the exchange is registered in dependency injection with the `services.Add[Exchange]()` method");
|
|
||||||
_serviceCache.Add(type, result!);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Dispose
|
|
||||||
/// </summary>
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
_serviceCache.Clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,24 +0,0 @@
|
|||||||
using CryptoExchange.Net.Interfaces.Clients;
|
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace CryptoExchange.Net.Clients
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
public class CryptoRestClient : CryptoBaseClient, ICryptoRestClient
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// ctor
|
|
||||||
/// </summary>
|
|
||||||
public CryptoRestClient()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// ctor
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="serviceProvider"></param>
|
|
||||||
public CryptoRestClient(IServiceProvider serviceProvider) : base(serviceProvider)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,24 +0,0 @@
|
|||||||
using CryptoExchange.Net.Interfaces.Clients;
|
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace CryptoExchange.Net.Clients
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
public class CryptoSocketClient : CryptoBaseClient, ICryptoSocketClient
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// ctor
|
|
||||||
/// </summary>
|
|
||||||
public CryptoSocketClient()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// ctor
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="serviceProvider"></param>
|
|
||||||
public CryptoSocketClient(IServiceProvider serviceProvider) : base(serviceProvider)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -88,6 +88,7 @@ namespace CryptoExchange.Net.Converters.SystemTextJson
|
|||||||
#endif
|
#endif
|
||||||
private NullableEnumConverter? _nullableEnumConverter = null;
|
private NullableEnumConverter? _nullableEnumConverter = null;
|
||||||
|
|
||||||
|
private static T? _undefinedEnumValue;
|
||||||
private static ConcurrentBag<string> _unknownValuesWarned = new ConcurrentBag<string>();
|
private static ConcurrentBag<string> _unknownValuesWarned = new ConcurrentBag<string>();
|
||||||
|
|
||||||
internal class NullableEnumConverter : JsonConverter<T?>
|
internal class NullableEnumConverter : JsonConverter<T?>
|
||||||
@ -129,7 +130,23 @@ namespace CryptoExchange.Net.Converters.SystemTextJson
|
|||||||
LibraryHelpers.StaticLogger?.LogWarning($"Received null or empty enum value, but property type is not a nullable enum. EnumType: {typeof(T).FullName}. If you think {typeof(T).FullName} should be nullable please open an issue on the Github repo");
|
LibraryHelpers.StaticLogger?.LogWarning($"Received null or empty enum value, but property type is not a nullable enum. EnumType: {typeof(T).FullName}. If you think {typeof(T).FullName} should be nullable please open an issue on the Github repo");
|
||||||
}
|
}
|
||||||
|
|
||||||
return (T)Enum.ToObject(typeof(T), -1);
|
return GetUndefinedEnumValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
private T GetUndefinedEnumValue()
|
||||||
|
{
|
||||||
|
if (_undefinedEnumValue != null)
|
||||||
|
return _undefinedEnumValue.Value;
|
||||||
|
|
||||||
|
var type = typeof(T);
|
||||||
|
if (!Enum.IsDefined(type, -9))
|
||||||
|
_undefinedEnumValue = (T)Enum.ToObject(type, -9);
|
||||||
|
else if (!Enum.IsDefined(type, -99))
|
||||||
|
_undefinedEnumValue = (T)Enum.ToObject(type, -99);
|
||||||
|
else
|
||||||
|
_undefinedEnumValue = (T)Enum.ToObject(type, -999);
|
||||||
|
|
||||||
|
return (T)_undefinedEnumValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
private T? ReadNullable(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options, out bool isEmptyString)
|
private T? ReadNullable(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options, out bool isEmptyString)
|
||||||
|
|||||||
@ -13,7 +13,7 @@ namespace CryptoExchange.Net.Converters.SystemTextJson
|
|||||||
public override T? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
public override T? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||||
{
|
{
|
||||||
if (reader.TokenType != JsonTokenType.StartArray)
|
if (reader.TokenType != JsonTokenType.StartArray)
|
||||||
throw new Exception("");
|
throw new Exception("Invalid JSON structure");
|
||||||
|
|
||||||
reader.Read(); // Start array
|
reader.Read(); // Start array
|
||||||
var baseQuantity = reader.TokenType == JsonTokenType.Null ? (decimal?)null : reader.GetDecimal();
|
var baseQuantity = reader.TokenType == JsonTokenType.Null ? (decimal?)null : reader.GetDecimal();
|
||||||
@ -24,7 +24,7 @@ namespace CryptoExchange.Net.Converters.SystemTextJson
|
|||||||
reader.Read();
|
reader.Read();
|
||||||
|
|
||||||
if (reader.TokenType != JsonTokenType.EndArray)
|
if (reader.TokenType != JsonTokenType.EndArray)
|
||||||
throw new Exception("");
|
throw new Exception("Invalid JSON structure");
|
||||||
|
|
||||||
reader.Read(); // End array
|
reader.Read(); // End array
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,7 @@ namespace CryptoExchange.Net.Converters.SystemTextJson
|
|||||||
public override SharedSymbol? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
public override SharedSymbol? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||||
{
|
{
|
||||||
if (reader.TokenType != JsonTokenType.StartArray)
|
if (reader.TokenType != JsonTokenType.StartArray)
|
||||||
throw new Exception("");
|
throw new Exception("Invalid JSON structure");
|
||||||
|
|
||||||
reader.Read(); // Start array
|
reader.Read(); // Start array
|
||||||
var tradingMode = (TradingMode)Enum.Parse(typeof(TradingMode), reader.GetString()!);
|
var tradingMode = (TradingMode)Enum.Parse(typeof(TradingMode), reader.GetString()!);
|
||||||
@ -24,7 +24,7 @@ namespace CryptoExchange.Net.Converters.SystemTextJson
|
|||||||
reader.Read();
|
reader.Read();
|
||||||
|
|
||||||
if (reader.TokenType != JsonTokenType.EndArray)
|
if (reader.TokenType != JsonTokenType.EndArray)
|
||||||
throw new Exception("");
|
throw new Exception("Invalid JSON structure");
|
||||||
|
|
||||||
reader.Read(); // End array
|
reader.Read(); // End array
|
||||||
|
|
||||||
|
|||||||
@ -1,17 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace CryptoExchange.Net.Interfaces.Clients
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Client for accessing REST API's for different exchanges
|
|
||||||
/// </summary>
|
|
||||||
public interface ICryptoRestClient
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Try get
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T"></typeparam>
|
|
||||||
/// <returns></returns>
|
|
||||||
T TryGet<T>(Func<T> createFunc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace CryptoExchange.Net.Interfaces.Clients
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Client for accessing Websocket API's for different exchanges
|
|
||||||
/// </summary>
|
|
||||||
public interface ICryptoSocketClient
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Try get a client by type for the service collection
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T"></typeparam>
|
|
||||||
/// <returns></returns>
|
|
||||||
T TryGet<T>(Func<T> createFunc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -130,7 +130,8 @@ namespace CryptoExchange.Net.Objects
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Default error info
|
/// Default error info
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected static readonly ErrorInfo _errorInfo = new ErrorInfo(ErrorType.MissingCredentials, false, "No credentials provided for private endpoint");
|
protected static readonly ErrorInfo _errorInfo = new ErrorInfo(ErrorType.MissingCredentials, false,
|
||||||
|
"No credentials provided for private endpoint, set the `ApiCredentials` option in the client configuration");
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// ctor
|
/// ctor
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
using CryptoExchange.Net.Interfaces;
|
using CryptoExchange.Net.Interfaces;
|
||||||
using CryptoExchange.Net.Objects;
|
using CryptoExchange.Net.Objects;
|
||||||
|
using CryptoExchange.Net.Testing.Comparers;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@ -59,7 +61,17 @@ namespace CryptoExchange.Net.Testing
|
|||||||
/// <typeparam name="T">Type of response</typeparam>
|
/// <typeparam name="T">Type of response</typeparam>
|
||||||
/// <param name="expression">The call expression</param>
|
/// <param name="expression">The call expression</param>
|
||||||
/// <param name="authRequest">Whether this is an authenticated request</param>
|
/// <param name="authRequest">Whether this is an authenticated request</param>
|
||||||
public async Task RunAndCheckResult<T>(Expression<Func<TClient, Task<WebCallResult<T>>>> expression, bool authRequest)
|
/// <param name="checkMissingFields">Whether to check the response for missing fields</param>
|
||||||
|
/// <param name="compareNestedProperty">Nested property to use for comparing when checking for missing fields</param>
|
||||||
|
/// <param name="ignoreProperties">Properties to ignore when checking for missing fields</param>
|
||||||
|
/// <param name="useSingleArrayItem">Whether to use the single array item as compare when checking for missing fields</param>
|
||||||
|
public async Task RunAndCheckResult<T>(
|
||||||
|
Expression<Func<TClient, Task<WebCallResult<T>>>> expression,
|
||||||
|
bool authRequest,
|
||||||
|
bool checkMissingFields = false,
|
||||||
|
string? compareNestedProperty = null,
|
||||||
|
List<string>? ignoreProperties = null,
|
||||||
|
bool? useSingleArrayItem = null)
|
||||||
{
|
{
|
||||||
if (!ShouldRun())
|
if (!ShouldRun())
|
||||||
return;
|
return;
|
||||||
@ -93,6 +105,22 @@ namespace CryptoExchange.Net.Testing
|
|||||||
if (!result.Success)
|
if (!result.Success)
|
||||||
throw new Exception($"Method {expressionBody.Method.Name} returned error: " + result.Error);
|
throw new Exception($"Method {expressionBody.Method.Name} returned error: " + result.Error);
|
||||||
|
|
||||||
|
if (checkMissingFields)
|
||||||
|
{
|
||||||
|
var data = result.Data;
|
||||||
|
var originalData = result.OriginalData;
|
||||||
|
if (originalData == null)
|
||||||
|
throw new Exception($"Original data needs to be enabled in the client options to check for missing fields");
|
||||||
|
|
||||||
|
try {
|
||||||
|
SystemTextJsonComparer.CompareData(expressionBody.Method.Name, data, originalData, compareNestedProperty, ignoreProperties, useSingleArrayItem ?? false);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
throw new Exception($"Compare failed: {ex.Message}; original data: {originalData}", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Debug.WriteLine($"{expressionBody.Method.Name} {result}");
|
Debug.WriteLine($"{expressionBody.Method.Name} {result}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user