public static string Serialize(object value)
        {
            if (value == null)
            {
                throw new ArgumentNullException(nameof(value));
            }

            var array = value as object[];

            if (array != null)
            {
                value = new XunitSerializationInfo.ArraySerializer(array);
            }

            var serializable = value as IXunitSerializable;

            if (serializable == null)
            {
                throw new ArgumentException("Cannot serialize an object that does not implement " + typeof(IXunitSerializable).FullName, nameof(value));
            }

            var serializationInfo = new XunitSerializationInfo(serializable);

            return($"{GetTypeNameForSerialization(value.GetType())}:{serializationInfo.ToSerializedString()}");
        }
        static IXunitSerializable DeserializeSerializable(Type type, string serializedValue)
        {
            var serializationInfo = new XunitSerializationInfo();

            // Will end up with an empty string if the serialization type did not serialize any data
            if (serializedValue != string.Empty)
            {
                var elements = FromBase64(serializedValue).Split('\n');

                foreach (var element in elements)
                {
                    var triple = DeserializeTriple(element);
                    serializationInfo.data[triple.Key] = triple;
                }
            }

            try
            {
                var value = (IXunitSerializable)Activator.CreateInstance(type);
                value.Deserialize(serializationInfo);
                return(value);
            }
            catch (MissingMemberException)
            {
                throw new InvalidOperationException($"Could not de-serialize type '{type.FullName}' because it lacks a parameterless constructor.");
            }
        }
        public static T Deserialize <T>(string serializedValue)
        {
            if (serializedValue == null)
            {
                throw new ArgumentNullException(nameof(serializedValue));
            }

            var pieces = serializedValue.Split(new[] { ':' }, 2);

            if (pieces.Length != 2)
            {
                throw new ArgumentException("De-serialized string is in the incorrect format.");
            }

            var deserializedType = GetType(pieces[0]);

            if (deserializedType == null)
            {
                throw new ArgumentException($"Could not load type '{pieces[0]}' from serialization value '{serializedValue}'", nameof(serializedValue));
            }

            if (!typeof(IXunitSerializable).IsAssignableFrom(deserializedType))
            {
                throw new ArgumentException("Cannot de-serialize an object that does not implement " + typeof(IXunitSerializable).FullName, nameof(serializedValue));
            }

            var obj             = XunitSerializationInfo.Deserialize(deserializedType, pieces[1]);
            var arraySerializer = obj as XunitSerializationInfo.ArraySerializer;

            if (arraySerializer != null)
            {
                obj = arraySerializer.ArrayData;
            }

            return((T)obj);
        }
 public static bool IsSerializable(object value)
 {
     return(XunitSerializationInfo.CanSerializeObject(value));
 }
        public static string Serialize(object value)
        {
            if (value == null)
            {
                return(null);
            }

            var serializable = value as IXunitSerializable;

            if (serializable != null)
            {
                var info = new XunitSerializationInfo();
                serializable.Serialize(info);
                return(info.ToSerializedString());
            }

            var charData = value as char?;

            if (charData != null)
            {
                return(((ushort)charData.GetValueOrDefault()).ToString(CultureInfo.InvariantCulture));
            }

            var stringData = value as string;

            if (stringData != null)
            {
                return(ToBase64(stringData));
            }

            var byteData = value as byte?;

            if (byteData != null)
            {
                return(byteData.GetValueOrDefault().ToString(CultureInfo.InvariantCulture));
            }

            var sbyteData = value as sbyte?;

            if (sbyteData != null)
            {
                return(sbyteData.GetValueOrDefault().ToString(CultureInfo.InvariantCulture));
            }

            var ushortData = value as ushort?;

            if (ushortData != null)
            {
                return(ushortData.GetValueOrDefault().ToString(CultureInfo.InvariantCulture));
            }

            var shortData = value as short?;

            if (shortData != null)
            {
                return(shortData.GetValueOrDefault().ToString(CultureInfo.InvariantCulture));
            }

            var uintData = value as uint?;

            if (uintData != null)
            {
                return(uintData.GetValueOrDefault().ToString(CultureInfo.InvariantCulture));
            }

            var intData = value as int?;

            if (intData != null)
            {
                return(intData.GetValueOrDefault().ToString(CultureInfo.InvariantCulture));
            }

            var ulongData = value as ulong?;

            if (ulongData != null)
            {
                return(ulongData.GetValueOrDefault().ToString(CultureInfo.InvariantCulture));
            }

            var longData = value as long?;

            if (longData != null)
            {
                return(longData.GetValueOrDefault().ToString(CultureInfo.InvariantCulture));
            }

            var floatData = value as float?;

            if (floatData != null)
            {
                var info     = new XunitSerializationInfo();
                var arraySer = new ArraySerializer(BitConverter.GetBytes(floatData.GetValueOrDefault()));
                arraySer.Serialize(info);
                return(info.ToSerializedString());
            }

            var doubleData = value as double?;

            if (doubleData != null)
            {
                var info     = new XunitSerializationInfo();
                var arraySer = new ArraySerializer(BitConverter.GetBytes(doubleData.GetValueOrDefault()));
                arraySer.Serialize(info);
                return(info.ToSerializedString());
            }

            var decimalData = value as decimal?;

            if (decimalData != null)
            {
                return(decimalData.GetValueOrDefault().ToString(CultureInfo.InvariantCulture));
            }

            var booleanData = value as bool?;

            if (booleanData != null)
            {
                return(booleanData.GetValueOrDefault().ToString());
            }

            var datetimeData = value as DateTime?;

            if (datetimeData != null)
            {
                return(datetimeData.GetValueOrDefault().ToString("o", CultureInfo.InvariantCulture));  // Round-trippable format
            }
            var datetimeoffsetData = value as DateTimeOffset?;

            if (datetimeoffsetData != null)
            {
                return(datetimeoffsetData.GetValueOrDefault().ToString("o", CultureInfo.InvariantCulture));  // Round-trippable format
            }
            var typeData = value as Type;

            if (typeData != null)
            {
                return(SerializationHelper.GetTypeNameForSerialization(typeData));
            }

            var valueType = value.GetType();

            if (valueType.IsEnum())
            {
                if (!valueType.IsFromLocalAssembly())
                {
                    throw new ArgumentException($"We cannot serialize enum {valueType.FullName}.{value} because it lives in the GAC", nameof(value));
                }
                return(value.ToString());
            }

            var arrayData = value as Array;

            if (arrayData != null)
            {
                var info     = new XunitSerializationInfo();
                var arraySer = new ArraySerializer(arrayData);
                arraySer.Serialize(info);
                return(info.ToSerializedString());
            }

            throw new ArgumentException($"We don't know how to serialize type {valueType.FullName}", nameof(value));
        }