зеркало из https://github.com/stride3d/SharpYaml.git
Add tests for NaN and Infinity float/double.
This commit is contained in:
Родитель
4d76ec9370
Коммит
d9a5b8bdf1
|
@ -339,6 +339,39 @@ Float: 1E-05
|
||||||
SerialRoundTrip(settings, text);
|
SerialRoundTrip(settings, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class ObjectFloatDoubleNaNInfinity
|
||||||
|
{
|
||||||
|
public double DoubleNaN { get; set; }
|
||||||
|
|
||||||
|
public double DoubleNegativeInfinity { get; set; }
|
||||||
|
|
||||||
|
public double DoublePositiveInfinity { get; set; }
|
||||||
|
|
||||||
|
public float FloatNaN { get; set; }
|
||||||
|
|
||||||
|
public float FloatNegativeInfinity { get; set; }
|
||||||
|
|
||||||
|
public float FloatPositiveInfinity { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestFloatDoubleNaNInfinity()
|
||||||
|
{
|
||||||
|
var settings = new SerializerSettings() { LimitPrimitiveFlowSequence = 20 };
|
||||||
|
settings.RegisterTagMapping("ObjectFloatDoubleNaNInfinity", typeof(ObjectFloatDoubleNaNInfinity));
|
||||||
|
|
||||||
|
var text = @"!ObjectFloatDoubleNaNInfinity
|
||||||
|
DoubleNaN: NaN
|
||||||
|
DoubleNegativeInfinity: -Infinity
|
||||||
|
DoublePositiveInfinity: Infinity
|
||||||
|
FloatNaN: NaN
|
||||||
|
FloatNegativeInfinity: -Infinity
|
||||||
|
FloatPositiveInfinity: Infinity
|
||||||
|
".Trim();
|
||||||
|
|
||||||
|
SerialRoundTrip(settings, text);
|
||||||
|
}
|
||||||
|
|
||||||
public class MyObjectAndCollection
|
public class MyObjectAndCollection
|
||||||
{
|
{
|
||||||
public MyObjectAndCollection()
|
public MyObjectAndCollection()
|
||||||
|
|
|
@ -58,7 +58,7 @@ namespace SharpYaml.Serialization.Serializers
|
||||||
|
|
||||||
public override object ConvertFrom(ref ObjectContext context, Scalar scalar)
|
public override object ConvertFrom(ref ObjectContext context, Scalar scalar)
|
||||||
{
|
{
|
||||||
var primitiveType = (PrimitiveDescriptor)context.Descriptor;
|
var primitiveType = (PrimitiveDescriptor)context.Descriptor;
|
||||||
var type = primitiveType.Type;
|
var type = primitiveType.Type;
|
||||||
var text = scalar.Value;
|
var text = scalar.Value;
|
||||||
|
|
||||||
|
@ -80,21 +80,21 @@ namespace SharpYaml.Serialization.Serializers
|
||||||
// If type is an enum, try to parse it
|
// If type is an enum, try to parse it
|
||||||
if (type.IsEnum)
|
if (type.IsEnum)
|
||||||
{
|
{
|
||||||
bool enumRemapped;
|
bool enumRemapped;
|
||||||
var result = primitiveType.ParseEnum(text, out enumRemapped);
|
var result = primitiveType.ParseEnum(text, out enumRemapped);
|
||||||
if (enumRemapped)
|
if (enumRemapped)
|
||||||
{
|
{
|
||||||
context.SerializerContext.HasRemapOccurred = true;
|
context.SerializerContext.HasRemapOccurred = true;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse default types
|
// Parse default types
|
||||||
switch (Type.GetTypeCode(type))
|
switch (Type.GetTypeCode(type))
|
||||||
{
|
{
|
||||||
case TypeCode.Boolean:
|
case TypeCode.Boolean:
|
||||||
object value;
|
object value;
|
||||||
context.SerializerContext.Schema.TryParse(scalar, type, out value);
|
context.SerializerContext.Schema.TryParse(scalar, type, out value);
|
||||||
return value;
|
return value;
|
||||||
case TypeCode.DateTime:
|
case TypeCode.DateTime:
|
||||||
return DateTime.Parse(text, CultureInfo.InvariantCulture);
|
return DateTime.Parse(text, CultureInfo.InvariantCulture);
|
||||||
|
@ -102,9 +102,9 @@ namespace SharpYaml.Serialization.Serializers
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == typeof (TimeSpan))
|
if (type == typeof(TimeSpan))
|
||||||
{
|
{
|
||||||
return TimeSpan.Parse(text, CultureInfo.InvariantCulture);
|
return TimeSpan.Parse(text, CultureInfo.InvariantCulture);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove _ character from numeric values
|
// Remove _ character from numeric values
|
||||||
|
@ -145,7 +145,7 @@ namespace SharpYaml.Serialization.Serializers
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we are expecting a type object, return directly the string
|
// If we are expecting a type object, return directly the string
|
||||||
if (type == typeof (object))
|
if (type == typeof(object))
|
||||||
{
|
{
|
||||||
// Try to parse the scalar directly
|
// Try to parse the scalar directly
|
||||||
string defaultTag;
|
string defaultTag;
|
||||||
|
@ -154,43 +154,43 @@ namespace SharpYaml.Serialization.Serializers
|
||||||
{
|
{
|
||||||
return scalarValue;
|
return scalarValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new YamlException(scalar.Start, scalar.End, "Unable to decode scalar [{0}] not supported by current schema".DoFormat(scalar));
|
throw new YamlException(scalar.Start, scalar.End, "Unable to decode scalar [{0}] not supported by current schema".DoFormat(scalar));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Appends decimal point to arg if it does not exist
|
/// Appends decimal point to arg if it does not exist
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="text"></param>
|
/// <param name="text"></param>
|
||||||
/// <param name="hasNaN">True if the floating point type supports NaN or Infinity.</param>
|
/// <param name="hasNaN">True if the floating point type supports NaN or Infinity.</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private static string AppendDecimalPoint(string text, bool hasNaN)
|
private static string AppendDecimalPoint(string text, bool hasNaN)
|
||||||
{
|
{
|
||||||
for (var i = 0; i < text.Length; i++)
|
for (var i = 0; i < text.Length; i++)
|
||||||
{
|
{
|
||||||
var c = text[i];
|
var c = text[i];
|
||||||
// Do not append a decimal point if floating point type value
|
// Do not append a decimal point if floating point type value
|
||||||
// - is in exponential form, or
|
// - is in exponential form, or
|
||||||
// - already has a decimal point
|
// - already has a decimal point
|
||||||
if (c == 'e' || c == 'E' || c == '.')
|
if (c == 'e' || c == 'E' || c == '.')
|
||||||
{
|
{
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Special cases for floating point type supporting NaN and Infinity
|
// Special cases for floating point type supporting NaN and Infinity
|
||||||
if (hasNaN && (string.Equals(text, "NaN") || text.Contains("Infinity")))
|
if (hasNaN && (string.Equals(text, "NaN") || text.Contains("Infinity")))
|
||||||
return text;
|
return text;
|
||||||
|
|
||||||
return text + ".0";
|
return text + ".0";
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ConvertTo(ref ObjectContext objectContext)
|
public override string ConvertTo(ref ObjectContext objectContext)
|
||||||
{
|
{
|
||||||
var text = string.Empty;
|
var text = string.Empty;
|
||||||
var value = objectContext.Instance;
|
var value = objectContext.Instance;
|
||||||
|
|
||||||
// Return null if expected type is an object and scalar is null
|
// Return null if expected type is an object and scalar is null
|
||||||
if (value == null)
|
if (value == null)
|
||||||
|
@ -203,60 +203,60 @@ namespace SharpYaml.Serialization.Serializers
|
||||||
// Handle string
|
// Handle string
|
||||||
if (valueType.IsEnum)
|
if (valueType.IsEnum)
|
||||||
{
|
{
|
||||||
text = ((Enum) Enum.ToObject(valueType, value)).ToString("G");
|
text = ((Enum)Enum.ToObject(valueType, value)).ToString("G");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Parse default types
|
// Parse default types
|
||||||
switch (Type.GetTypeCode(valueType))
|
switch (Type.GetTypeCode(valueType))
|
||||||
{
|
{
|
||||||
case TypeCode.String:
|
case TypeCode.String:
|
||||||
case TypeCode.Char:
|
case TypeCode.Char:
|
||||||
text = value.ToString();
|
text = value.ToString();
|
||||||
break;
|
break;
|
||||||
case TypeCode.Boolean:
|
case TypeCode.Boolean:
|
||||||
text = (bool) value ? "true" : "false";
|
text = (bool)value ? "true" : "false";
|
||||||
break;
|
break;
|
||||||
case TypeCode.Byte:
|
case TypeCode.Byte:
|
||||||
text = ((byte) value).ToString("G", CultureInfo.InvariantCulture);
|
text = ((byte)value).ToString("G", CultureInfo.InvariantCulture);
|
||||||
break;
|
break;
|
||||||
case TypeCode.SByte:
|
case TypeCode.SByte:
|
||||||
text = ((sbyte) value).ToString("G", CultureInfo.InvariantCulture);
|
text = ((sbyte)value).ToString("G", CultureInfo.InvariantCulture);
|
||||||
break;
|
break;
|
||||||
case TypeCode.Int16:
|
case TypeCode.Int16:
|
||||||
text = ((short) value).ToString("G", CultureInfo.InvariantCulture);
|
text = ((short)value).ToString("G", CultureInfo.InvariantCulture);
|
||||||
break;
|
break;
|
||||||
case TypeCode.UInt16:
|
case TypeCode.UInt16:
|
||||||
text = ((ushort) value).ToString("G", CultureInfo.InvariantCulture);
|
text = ((ushort)value).ToString("G", CultureInfo.InvariantCulture);
|
||||||
break;
|
break;
|
||||||
case TypeCode.Int32:
|
case TypeCode.Int32:
|
||||||
text = ((int) value).ToString("G", CultureInfo.InvariantCulture);
|
text = ((int)value).ToString("G", CultureInfo.InvariantCulture);
|
||||||
break;
|
break;
|
||||||
case TypeCode.UInt32:
|
case TypeCode.UInt32:
|
||||||
text = ((uint) value).ToString("G", CultureInfo.InvariantCulture);
|
text = ((uint)value).ToString("G", CultureInfo.InvariantCulture);
|
||||||
break;
|
break;
|
||||||
case TypeCode.Int64:
|
case TypeCode.Int64:
|
||||||
text = ((long) value).ToString("G", CultureInfo.InvariantCulture);
|
text = ((long)value).ToString("G", CultureInfo.InvariantCulture);
|
||||||
break;
|
break;
|
||||||
case TypeCode.UInt64:
|
case TypeCode.UInt64:
|
||||||
text = ((ulong) value).ToString("G", CultureInfo.InvariantCulture);
|
text = ((ulong)value).ToString("G", CultureInfo.InvariantCulture);
|
||||||
break;
|
break;
|
||||||
case TypeCode.Single:
|
case TypeCode.Single:
|
||||||
//Append decimal point to floating point type values
|
//Append decimal point to floating point type values
|
||||||
//because type changes in round trip conversion if ( value * 10.0 ) % 10.0 == 0
|
//because type changes in round trip conversion if ( value * 10.0 ) % 10.0 == 0
|
||||||
text = AppendDecimalPoint(((float)value).ToString("R", CultureInfo.InvariantCulture), true);
|
text = AppendDecimalPoint(((float)value).ToString("R", CultureInfo.InvariantCulture), true);
|
||||||
break;
|
break;
|
||||||
case TypeCode.Double:
|
case TypeCode.Double:
|
||||||
text = AppendDecimalPoint(((double)value).ToString("R", CultureInfo.InvariantCulture), true);
|
text = AppendDecimalPoint(((double)value).ToString("R", CultureInfo.InvariantCulture), true);
|
||||||
break;
|
break;
|
||||||
case TypeCode.Decimal:
|
case TypeCode.Decimal:
|
||||||
text = AppendDecimalPoint(((decimal)value).ToString("G", CultureInfo.InvariantCulture), false);
|
text = AppendDecimalPoint(((decimal)value).ToString("G", CultureInfo.InvariantCulture), false);
|
||||||
break;
|
break;
|
||||||
case TypeCode.DateTime:
|
case TypeCode.DateTime:
|
||||||
text = ((DateTime) value).ToString("o", CultureInfo.InvariantCulture);
|
text = ((DateTime)value).ToString("o", CultureInfo.InvariantCulture);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (valueType == typeof (TimeSpan))
|
if (valueType == typeof(TimeSpan))
|
||||||
{
|
{
|
||||||
text = ((TimeSpan)value).ToString("G", CultureInfo.InvariantCulture);
|
text = ((TimeSpan)value).ToString("G", CultureInfo.InvariantCulture);
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче