1
0
mirror of https://github.com/JKorf/CryptoExchange.Net.git synced 2026-08-24 14:45:49 +00:00

Updated test validation to output a list of issues instead of throwing on the first

This commit is contained in:
Jkorf
2026-07-01 13:16:06 +02:00
parent 64c1cd5fa8
commit 69099922c9
5 changed files with 84 additions and 52 deletions
@@ -19,7 +19,7 @@ namespace CryptoExchange.Net.Testing.Comparers
{ {
internal class SystemTextJsonComparer internal class SystemTextJsonComparer
{ {
internal static void CompareData( internal static List<Exception> CompareData(
string method, string method,
object? resultData, object? resultData,
string json, string json,
@@ -27,6 +27,7 @@ namespace CryptoExchange.Net.Testing.Comparers
List<string>? ignoreProperties = null, List<string>? ignoreProperties = null,
bool userSingleArrayItem = false) bool userSingleArrayItem = false)
{ {
var outputExceptions = new List<Exception>();
var jsonObject = JsonDocument.Parse(json).RootElement; var jsonObject = JsonDocument.Parse(json).RootElement;
if (nestedJsonProperty != null) if (nestedJsonProperty != null)
{ {
@@ -47,10 +48,10 @@ namespace CryptoExchange.Net.Testing.Comparers
if (resultData == null) if (resultData == null)
{ {
if (jsonObject.ValueKind == JsonValueKind.Null) if (jsonObject.ValueKind == JsonValueKind.Null)
return; return outputExceptions;
if (jsonObject.ValueKind == JsonValueKind.Object && jsonObject.GetPropertyCount() == 0) if (jsonObject.ValueKind == JsonValueKind.Object && jsonObject.GetPropertyCount() == 0)
return; return outputExceptions;
throw new Exception("ResultData null"); throw new Exception("ResultData null");
} }
@@ -62,13 +63,13 @@ namespace CryptoExchange.Net.Testing.Comparers
foreach (var dictProp in jObj.EnumerateObject()) foreach (var dictProp in jObj.EnumerateObject())
{ {
if (!dict.Contains(dictProp.Name)) if (!dict.Contains(dictProp.Name))
throw new Exception($"{method}: Dictionary has no value for {dictProp.Name} while input json `{dictProp.Name}` has value {dictProp.Value}"); outputExceptions.Add(new Exception($"{method}: Dictionary has no value for {dictProp.Name} while input json `{dictProp.Name}` has value {dictProp.Value}"));
if (dictProp.Value.ValueKind == JsonValueKind.Object) if (dictProp.Value.ValueKind == JsonValueKind.Object)
{ {
// TODO Some additional checking for objects // TODO Some additional checking for objects
foreach (var prop in dictProp.Value.EnumerateObject()) foreach (var prop in dictProp.Value.EnumerateObject())
CheckObject(method, prop, dict[dictProp.Name]!, ignoreProperties!); CheckObject(method, prop, dict[dictProp.Name]!, ignoreProperties!, outputExceptions);
} }
else else
{ {
@@ -78,7 +79,7 @@ namespace CryptoExchange.Net.Testing.Comparers
continue; continue;
// Property value not correct // Property value not correct
throw new Exception($"{method}: Dictionary entry `{dictProp.Name}` has no value while input json has value {dictProp.Value}"); outputExceptions.Add(new Exception($"{method}: Dictionary entry `{dictProp.Name}` has no value while input json has value {dictProp.Value}"));
} }
} }
} }
@@ -100,7 +101,7 @@ namespace CryptoExchange.Net.Testing.Comparers
{ {
if (ignoreProperties?.Contains(subProp.Name) == true) if (ignoreProperties?.Contains(subProp.Name) == true)
continue; continue;
CheckObject(method, subProp, enumerator.Current, ignoreProperties!); CheckObject(method, subProp, enumerator.Current, ignoreProperties!, outputExceptions);
} }
} }
else if (jObj.ValueKind == JsonValueKind.Array) else if (jObj.ValueKind == JsonValueKind.Array)
@@ -122,7 +123,7 @@ namespace CryptoExchange.Net.Testing.Comparers
{ {
var arrayProp = resultProps.Where(p => p.Item2 != null).FirstOrDefault(p => p.Item2!.Index == i).p; var arrayProp = resultProps.Where(p => p.Item2 != null).FirstOrDefault(p => p.Item2!.Index == i).p;
if (arrayProp != null) if (arrayProp != null)
CheckPropertyValue(method, item.Value, arrayProp.GetValue(resultObj), arrayProp.PropertyType, arrayProp.Name, "Array index " + i, ignoreProperties!); CheckPropertyValue(method, item.Value, arrayProp.GetValue(resultObj), arrayProp.PropertyType, arrayProp.Name, "Array index " + i, ignoreProperties!, outputExceptions);
i++; i++;
} }
} }
@@ -130,7 +131,7 @@ namespace CryptoExchange.Net.Testing.Comparers
{ {
var value = enumerator.Current; var value = enumerator.Current;
if (value == default && jObj.ValueKind != JsonValueKind.Null) if (value == default && jObj.ValueKind != JsonValueKind.Null)
throw new Exception($"{method}: Array has no value while input json array has value {jObj}"); outputExceptions.Add(new Exception($"{method}: Array has no value while input json array has value {jObj}"));
} }
} }
} }
@@ -142,7 +143,7 @@ namespace CryptoExchange.Net.Testing.Comparers
{ {
var arrayProp = resultProps.Where(p => p.Item2 != null).FirstOrDefault(p => p.Item2!.Index == i).p; var arrayProp = resultProps.Where(p => p.Item2 != null).FirstOrDefault(p => p.Item2!.Index == i).p;
if (arrayProp != null) if (arrayProp != null)
CheckPropertyValue(method, item, arrayProp.GetValue(resultData), arrayProp.PropertyType, arrayProp.Name, "Array index " + i, ignoreProperties!); CheckPropertyValue(method, item, arrayProp.GetValue(resultData), arrayProp.PropertyType, arrayProp.Name, "Array index " + i, ignoreProperties!, outputExceptions);
i++; i++;
} }
} }
@@ -156,7 +157,7 @@ namespace CryptoExchange.Net.Testing.Comparers
if (ignoreProperties?.Contains(item.Name) == true) if (ignoreProperties?.Contains(item.Name) == true)
continue; continue;
CheckObject(method, item, resultData, ignoreProperties); CheckObject(method, item, resultData, ignoreProperties, outputExceptions);
//} //}
} }
} }
@@ -166,9 +167,10 @@ namespace CryptoExchange.Net.Testing.Comparers
} }
Debug.WriteLine($"Successfully validated {method}"); Debug.WriteLine($"Successfully validated {method}");
return outputExceptions;
} }
private static void CheckObject(string method, JsonProperty prop, object obj, List<string>? ignoreProperties) private static void CheckObject(string method, JsonProperty prop, object obj, List<string>? ignoreProperties, List<Exception> outputExceptions)
{ {
var publicProperties = obj.GetType().GetProperties( var publicProperties = obj.GetType().GetProperties(
System.Reflection.BindingFlags.Public System.Reflection.BindingFlags.Public
@@ -191,8 +193,11 @@ namespace CryptoExchange.Net.Testing.Comparers
property ??= resultProperties.SingleOrDefault(p => p.p.Name == prop.Name).p; property ??= resultProperties.SingleOrDefault(p => p.p.Name == prop.Name).p;
if (property is null) if (property is null)
{
// Property not found // Property not found
throw new MissingPropertyException(method, obj.GetType().Name, prop.Name, prop.Value.ValueKind == JsonValueKind.Null ? "[null]" : prop.Value.ToString()); outputExceptions.Add(new MissingPropertyException(method, obj.GetType().Name, prop.Name, prop.Value.ValueKind == JsonValueKind.Null ? "[null]" : prop.Value.ToString()));
return;
}
var getMethod = property.GetGetMethod(); var getMethod = property.GetGetMethod();
if (getMethod is null) if (getMethod is null)
@@ -200,10 +205,18 @@ namespace CryptoExchange.Net.Testing.Comparers
return; return;
var propertyValue = property.GetValue(obj); var propertyValue = property.GetValue(obj);
CheckPropertyValue(method, prop.Value, propertyValue, property.PropertyType, property.Name, prop.Name, ignoreProperties); CheckPropertyValue(method, prop.Value, propertyValue, property.PropertyType, property.Name, prop.Name, ignoreProperties, outputExceptions);
} }
private static void CheckPropertyValue(string method, JsonElement propValue, object? propertyValue, Type propertyType, string? propertyName = null, string? propName = null, List<string>? ignoreProperties = null) private static void CheckPropertyValue(
string method,
JsonElement propValue,
object? propertyValue,
Type propertyType,
string? propertyName,
string? propName,
List<string>? ignoreProperties,
List<Exception> outputExceptions)
{ {
if (propertyValue == default && propValue.ValueKind != JsonValueKind.Null && !string.IsNullOrEmpty(propValue.ToString())) if (propertyValue == default && propValue.ValueKind != JsonValueKind.Null && !string.IsNullOrEmpty(propValue.ToString()))
{ {
@@ -212,7 +225,7 @@ namespace CryptoExchange.Net.Testing.Comparers
// Property value not correct // Property value not correct
if (propValue.ToString() != "0") if (propValue.ToString() != "0")
throw new Exception($"{method}: Property `{propertyName}` has no value while input json `{propName}` has value {propValue}"); outputExceptions.Add(new Exception($"{method}: Property `{propertyName}` has no value while input json `{propName}` has value {propValue}"));
} }
if ((propertyValue == default && (propValue.ValueKind == JsonValueKind.Null || string.IsNullOrEmpty(propValue.ToString()))) || propValue.ToString() == "0") if ((propertyValue == default && (propValue.ValueKind == JsonValueKind.Null || string.IsNullOrEmpty(propValue.ToString()))) || propValue.ToString() == "0")
@@ -224,17 +237,17 @@ namespace CryptoExchange.Net.Testing.Comparers
foreach (var dictProp in propValue.EnumerateObject()) foreach (var dictProp in propValue.EnumerateObject())
{ {
if (!dict.Contains(dictProp.Name)) if (!dict.Contains(dictProp.Name))
throw new Exception($"{method}: Property `{propertyName}` has no value while input json `{propName}` has value {propValue}"); outputExceptions.Add(new Exception($"{method}: Property `{propertyName}` has no value while input json `{propName}` has value {propValue}"));
if (dictProp.Value.ValueKind == JsonValueKind.Object) if (dictProp.Value.ValueKind == JsonValueKind.Object)
{ {
CheckPropertyValue(method, dictProp.Value, dict[dictProp.Name]!, dict[dictProp.Name]!.GetType(), null, null, ignoreProperties); CheckPropertyValue(method, dictProp.Value, dict[dictProp.Name]!, dict[dictProp.Name]!.GetType(), null, null, ignoreProperties, outputExceptions);
} }
else else
{ {
if (dict[dictProp.Name] == default && dictProp.Value.ValueKind != JsonValueKind.Null) if (dict[dictProp.Name] == default && dictProp.Value.ValueKind != JsonValueKind.Null)
// Property value not correct // Property value not correct
throw new Exception($"{method}: Dictionary entry `{dictProp.Name}` has no value while input json has value {propValue} for"); outputExceptions.Add(new Exception($"{method}: Dictionary entry `{dictProp.Name}` has no value while input json has value {propValue} for"));
} }
} }
} }
@@ -264,7 +277,7 @@ namespace CryptoExchange.Net.Testing.Comparers
if (ignoreProperties?.Contains(subProp.Name) == true) if (ignoreProperties?.Contains(subProp.Name) == true)
continue; continue;
CheckObject(method, subProp, enumerator.Current, ignoreProperties); CheckObject(method, subProp, enumerator.Current, ignoreProperties, outputExceptions);
} }
} }
else if (jToken.ValueKind == JsonValueKind.Array) else if (jToken.ValueKind == JsonValueKind.Array)
@@ -282,7 +295,7 @@ namespace CryptoExchange.Net.Testing.Comparers
{ {
var arrayProp = resultProps.Where(p => p.Item2 != null).FirstOrDefault(p => p.Item2!.Index == i).p; var arrayProp = resultProps.Where(p => p.Item2 != null).FirstOrDefault(p => p.Item2!.Index == i).p;
if (arrayProp != null) if (arrayProp != null)
CheckPropertyValue(method, item, arrayProp.GetValue(resultObj), arrayProp.PropertyType, arrayProp.Name, "Array index " + i, ignoreProperties); CheckPropertyValue(method, item, arrayProp.GetValue(resultObj), arrayProp.PropertyType, arrayProp.Name, "Array index " + i, ignoreProperties, outputExceptions);
i++; i++;
} }
@@ -291,9 +304,9 @@ namespace CryptoExchange.Net.Testing.Comparers
{ {
var value = enumerator.Current; var value = enumerator.Current;
if (value == default && jToken.ValueKind != JsonValueKind.Null) if (value == default && jToken.ValueKind != JsonValueKind.Null)
throw new Exception($"{method}: Property `{propertyName}` has no value while input json `{propName}` has value {jToken}"); outputExceptions.Add(new Exception($"{method}: Property `{propertyName}` has no value while input json `{propName}` has value {jToken}"));
CheckValues(method, propertyName!, propertyType, jToken, value!); CheckValues(method, propertyName!, propertyType, jToken, value!, outputExceptions);
} }
} }
} }
@@ -308,7 +321,7 @@ namespace CryptoExchange.Net.Testing.Comparers
if (ignoreProperties?.Contains(item.Name) == true) if (ignoreProperties?.Contains(item.Name) == true)
continue; continue;
CheckObject(method, item, propertyValue, ignoreProperties); CheckObject(method, item, propertyValue, ignoreProperties, outputExceptions);
//} //}
} }
} }
@@ -329,7 +342,7 @@ namespace CryptoExchange.Net.Testing.Comparers
{ {
if (ignoreProperties?.Contains(subProp.Name) == true) if (ignoreProperties?.Contains(subProp.Name) == true)
continue; continue;
CheckObject(method, subProp, enumerator.Current, ignoreProperties!); CheckObject(method, subProp, enumerator.Current, ignoreProperties!, outputExceptions);
} }
} }
else if (jObj.ValueKind == JsonValueKind.Array) else if (jObj.ValueKind == JsonValueKind.Array)
@@ -347,7 +360,7 @@ namespace CryptoExchange.Net.Testing.Comparers
{ {
var arrayProp = resultProps.SingleOrDefault(p => p.Item2!.Index == i).p; var arrayProp = resultProps.SingleOrDefault(p => p.Item2!.Index == i).p;
if (arrayProp != null) if (arrayProp != null)
CheckPropertyValue(method, item, arrayProp.GetValue(resultObj), arrayProp.PropertyType, arrayProp.Name, "Array index " + i, ignoreProperties!); CheckPropertyValue(method, item, arrayProp.GetValue(resultObj), arrayProp.PropertyType, arrayProp.Name, "Array index " + i, ignoreProperties!, outputExceptions);
i++; i++;
} }
} }
@@ -355,7 +368,7 @@ namespace CryptoExchange.Net.Testing.Comparers
{ {
var value = enumerator.Current; var value = enumerator.Current;
if (value == default && jObj.ValueKind != JsonValueKind.Null) if (value == default && jObj.ValueKind != JsonValueKind.Null)
throw new Exception($"{method}: Array has no value while input json array has value {jObj}"); outputExceptions.Add(new Exception($"{method}: Array has no value while input json array has value {jObj}"));
} }
} }
} }
@@ -367,19 +380,19 @@ namespace CryptoExchange.Net.Testing.Comparers
{ {
var arrayProp = resultProps.Where(p => p.Item2 != null).FirstOrDefault(p => p.Item2!.Index == i).p; var arrayProp = resultProps.Where(p => p.Item2 != null).FirstOrDefault(p => p.Item2!.Index == i).p;
if (arrayProp != null) if (arrayProp != null)
CheckPropertyValue(method, item, arrayProp.GetValue(propertyValue), arrayProp.PropertyType, arrayProp.Name, "Array index " + i, ignoreProperties!); CheckPropertyValue(method, item, arrayProp.GetValue(propertyValue), arrayProp.PropertyType, arrayProp.Name, "Array index " + i, ignoreProperties!, outputExceptions);
i++; i++;
} }
} }
} }
else else
{ {
CheckValues(method, propertyName!, propertyType, propValue, propertyValue); CheckValues(method, propertyName!, propertyType, propValue, propertyValue, outputExceptions);
} }
} }
} }
private static void CheckValues(string method, string property, Type propertyType, JsonElement jsonValue, object objectValue) private static void CheckValues(string method, string property, Type propertyType, JsonElement jsonValue, object objectValue, List<Exception> outputExceptions)
{ {
if (jsonValue.ValueKind == JsonValueKind.String) if (jsonValue.ValueKind == JsonValueKind.String)
{ {
@@ -387,19 +400,19 @@ namespace CryptoExchange.Net.Testing.Comparers
if (objectValue is decimal dec) if (objectValue is decimal dec)
{ {
if (ExchangeHelpers.ParseDecimal(stringValue!) != dec) if (ExchangeHelpers.ParseDecimal(stringValue!) != dec)
throw new Exception($"{method}: {property} not equal: {stringValue} vs {dec}"); outputExceptions.Add(new Exception($"{method}: {property} not equal: {stringValue} vs {dec}") );
} }
else if (objectValue is DateTime time) else if (objectValue is DateTime time)
{ {
if (!string.IsNullOrEmpty(stringValue) && time != DateTimeConverter.ParseFromString(stringValue!, null)) if (!string.IsNullOrEmpty(stringValue) && time != DateTimeConverter.ParseFromString(stringValue!, null))
throw new Exception($"{method}: {property} not equal: {stringValue} vs {time}"); outputExceptions.Add(new Exception($"{method}: {property} not equal: {stringValue} vs {time}"));
} }
else if (objectValue is bool bl) else if (objectValue is bool bl)
{ {
if (bl && (stringValue != "1" && stringValue != "true" && stringValue != "True" && stringValue != "yes" && stringValue != "YES" && stringValue != "enabled")) if (bl && (stringValue != "1" && stringValue != "true" && stringValue != "True" && stringValue != "yes" && stringValue != "YES" && stringValue != "enabled"))
throw new Exception($"{method}: {property} not equal: {stringValue} vs {bl}"); outputExceptions.Add(new Exception($"{method}: {property} not equal: {stringValue} vs {bl}"));
if (!bl && (stringValue != "0" && stringValue != "-1" && stringValue != "false" && stringValue != "False" && stringValue != "no" && stringValue != "NO" && stringValue != "disabled")) if (!bl && (stringValue != "0" && stringValue != "-1" && stringValue != "false" && stringValue != "False" && stringValue != "no" && stringValue != "NO" && stringValue != "disabled"))
throw new Exception($"{method}: {property} not equal: {stringValue} vs {bl}"); outputExceptions.Add(new Exception($"{method}: {property} not equal: {stringValue} vs {bl}") );
} }
else if (propertyType.IsEnum || Nullable.GetUnderlyingType(propertyType)?.IsEnum == true) else if (propertyType.IsEnum || Nullable.GetUnderlyingType(propertyType)?.IsEnum == true)
{ {
@@ -407,7 +420,7 @@ namespace CryptoExchange.Net.Testing.Comparers
} }
else if (!stringValue!.Equals(Convert.ToString(objectValue, CultureInfo.InvariantCulture), StringComparison.InvariantCultureIgnoreCase)) else if (!stringValue!.Equals(Convert.ToString(objectValue, CultureInfo.InvariantCulture), StringComparison.InvariantCultureIgnoreCase))
{ {
throw new Exception($"{method}: {property} not equal: {stringValue} vs {objectValue}"); outputExceptions.Add(new Exception($"{method}: {property} not equal: {stringValue} vs {objectValue}"));
} }
} }
else if (jsonValue.ValueKind == JsonValueKind.Number) else if (jsonValue.ValueKind == JsonValueKind.Number)
@@ -416,7 +429,7 @@ namespace CryptoExchange.Net.Testing.Comparers
if (objectValue is DateTime time) if (objectValue is DateTime time)
{ {
if (time != DateTimeConverter.ParseFromDecimal(value)) if (time != DateTimeConverter.ParseFromDecimal(value))
throw new Exception($"{method}: {property} not equal: {DateTimeConverter.ParseFromDouble((double)value!)} vs {time}"); outputExceptions.Add(new Exception($"{method}: {property} not equal: {DateTimeConverter.ParseFromDouble((double)value!)} vs {time}"));
} }
else if (propertyType.IsEnum || Nullable.GetUnderlyingType(propertyType)?.IsEnum == true) else if (propertyType.IsEnum || Nullable.GetUnderlyingType(propertyType)?.IsEnum == true)
{ {
@@ -425,27 +438,27 @@ namespace CryptoExchange.Net.Testing.Comparers
else if(objectValue is decimal dec) else if(objectValue is decimal dec)
{ {
if (dec != value) if (dec != value)
throw new Exception($"{method}: {property} not equal: {dec} vs {value}"); outputExceptions.Add(new Exception($"{method}: {property} not equal: {dec} vs {value}"));
} }
else if (objectValue is double dbl) else if (objectValue is double dbl)
{ {
if ((decimal)dbl != value) if ((decimal)dbl != value)
throw new Exception($"{method}: {property} not equal: {dbl} vs {value}"); outputExceptions.Add(new Exception($"{method}: {property} not equal: {dbl} vs {value}"));
} }
else if(objectValue is string objStr) else if(objectValue is string objStr)
{ {
if (objStr != value.ToString()) if (objStr != value.ToString())
throw new Exception($"{method}: {property} not equal: {value} vs {objStr}"); outputExceptions.Add(new Exception($"{method}: {property} not equal: {value} vs {objStr}"));
} }
else if (value != Convert.ToInt64(objectValue, CultureInfo.InvariantCulture)) else if (value != Convert.ToInt64(objectValue, CultureInfo.InvariantCulture))
{ {
throw new Exception($"{method}: {property} not equal: {value} vs {Convert.ToInt64(objectValue)}"); outputExceptions.Add(new Exception($"{method}: {property} not equal: {value} vs {Convert.ToInt64(objectValue)}"));
} }
} }
else if (jsonValue.ValueKind == JsonValueKind.True || jsonValue.ValueKind == JsonValueKind.False) else if (jsonValue.ValueKind == JsonValueKind.True || jsonValue.ValueKind == JsonValueKind.False)
{ {
if (jsonValue.GetBoolean() != (bool)objectValue) if (jsonValue.GetBoolean() != (bool)objectValue)
throw new Exception($"{method}: {property} not equal: {jsonValue.GetBoolean()} vs {(bool)objectValue}"); outputExceptions.Add(new Exception($"{method}: {property} not equal: {jsonValue.GetBoolean()} vs {(bool)objectValue}"));
} }
} }
} }
@@ -6,6 +6,7 @@ using Microsoft.Extensions.Logging;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions; using System.Linq.Expressions;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -86,7 +87,7 @@ namespace CryptoExchange.Net.Testing
/// <param name="compareNestedProperty">Nested property to use for comparing when checking 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="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> /// <param name="useSingleArrayItem">Whether to use the single array item as compare when checking for missing fields</param>
/// <param name="warningExceptionsHolder">List for outputting warnings</param> /// <param name="warnings">List for outputting warnings</param>
public async Task RunAndCheckResult<T>( public async Task RunAndCheckResult<T>(
Expression<Func<TClient, Task<HttpResult<T>>>> expression, Expression<Func<TClient, Task<HttpResult<T>>>> expression,
bool authRequest, bool authRequest,
@@ -94,7 +95,7 @@ namespace CryptoExchange.Net.Testing
string? compareNestedProperty = null, string? compareNestedProperty = null,
List<string>? ignoreProperties = null, List<string>? ignoreProperties = null,
bool? useSingleArrayItem = null, bool? useSingleArrayItem = null,
List<Exception>? warningExceptionsHolder = null) List<Exception>? warnings = null)
{ {
if (!ShouldRun()) if (!ShouldRun())
return; return;
@@ -135,13 +136,20 @@ namespace CryptoExchange.Net.Testing
if (originalData == null) if (originalData == null)
throw new Exception($"Original data needs to be enabled in the client options to check for missing fields"); throw new Exception($"Original data needs to be enabled in the client options to check for missing fields");
var errors = new List<Exception>();
try try
{ {
SystemTextJsonComparer.CompareData(expressionBody.Method.Name, data, originalData, compareNestedProperty, ignoreProperties, useSingleArrayItem ?? false); var issues = SystemTextJsonComparer.CompareData(expressionBody.Method.Name, data, originalData, compareNestedProperty, ignoreProperties, useSingleArrayItem ?? false);
} foreach(var issue in issues)
catch (MissingPropertyException mpe) {
{ if (issue is MissingPropertyException)
warningExceptionsHolder?.Add(mpe); warnings?.Add(issue);
else
errors.Add(issue);
}
if (errors.Count > 0)
throw new AggregateException(errors);
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -1,6 +1,7 @@
using CryptoExchange.Net.Clients; using CryptoExchange.Net.Clients;
using CryptoExchange.Net.Objects; using CryptoExchange.Net.Objects;
using CryptoExchange.Net.Testing.Comparers; using CryptoExchange.Net.Testing.Comparers;
using CryptoExchange.Net.Testing.Exceptions;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Specialized; using System.Collections.Specialized;
@@ -184,7 +185,9 @@ namespace CryptoExchange.Net.Testing
{ {
// Check response data // Check response data
object responseData = (TActualResponse)result.Data!; object responseData = (TActualResponse)result.Data!;
SystemTextJsonComparer.CompareData(name, responseData, response, nestedJsonProperty ?? _nestedPropertyForCompare, ignoreProperties, useSingleArrayItem); var issues = SystemTextJsonComparer.CompareData(name, responseData, response, nestedJsonProperty ?? _nestedPropertyForCompare, ignoreProperties, useSingleArrayItem);
if (issues.Count > 0)
throw new AggregateException(issues);
} }
Trace.Listeners.Remove(listener); Trace.Listeners.Remove(listener);
@@ -155,7 +155,7 @@ namespace CryptoExchange.Net.Testing
else if (line.StartsWith("< ")) else if (line.StartsWith("< "))
{ {
// Expect a message from server to client // Expect a message from server to client
foreach(var item in replaceValues) foreach (var item in replaceValues)
line = line.Replace(item.Key, item.Value); line = line.Replace(item.Key, item.Value);
socket.InvokeMessage(line.Substring(2)); socket.InvokeMessage(line.Substring(2));
@@ -175,7 +175,11 @@ namespace CryptoExchange.Net.Testing
result = responseMapper(task.Result.Data!); result = responseMapper(task.Result.Data!);
if (!skipResponseValidation) if (!skipResponseValidation)
SystemTextJsonComparer.CompareData(name, result, compareData, nestedJsonProperty ?? _nestedPropertyForCompare, ignoreProperties, useSingleArrayItem); {
var issues = SystemTextJsonComparer.CompareData(name, result, compareData, nestedJsonProperty ?? _nestedPropertyForCompare, ignoreProperties, useSingleArrayItem);
if (issues.Count > 0)
throw new AggregateException(issues);
}
} }
} }
@@ -326,7 +326,11 @@ namespace CryptoExchange.Net.Testing
throw new Exception($"{name} Update send to client did not trigger in update handler"); throw new Exception($"{name} Update send to client did not trigger in update handler");
if (skipUpdateValidation != true) if (skipUpdateValidation != true)
SystemTextJsonComparer.CompareData(name, update, compareData, nestedJsonProperty ?? _nestedPropertyForCompare, ignoreProperties, useFirstUpdateItem ?? false); {
var issues = SystemTextJsonComparer.CompareData(name, update, compareData, nestedJsonProperty ?? _nestedPropertyForCompare, ignoreProperties, useFirstUpdateItem ?? false);
if (issues.Count > 0)
throw new AggregateException(issues);
}
} }
} }