public static void Deserialize_serializedString_type___Should_deserialize_DateTime___When_called() { // Arrange var systemUnderTest = new ObcDateTimeStringSerializer(); // note that this will return "+00:00" if machine is on UTC time, which is what we expect var offset = DateTime.Now.ToString("%K"); var scenarios = new List <(DateTime Expected, string SerializedString)> { (new DateTime(2019, 1, 5, 12, 14, 58, 192, DateTimeKind.Utc), "2019-01-05T12:14:58.1920000Z"), (new DateTime(2019, 1, 5, 12, 14, 58, 192, DateTimeKind.Utc).AddTicks(1), "2019-01-05T12:14:58.1920001Z"), (new DateTime(2019, 1, 5, 12, 14, 58, 192, DateTimeKind.Utc).AddTicks(20), "2019-01-05T12:14:58.1920020Z"), (new DateTime(2019, 1, 5, 12, 14, 58, 192, DateTimeKind.Unspecified), "2019-01-05T12:14:58.1920000"), (new DateTime(2019, 1, 5, 12, 14, 58, 192, DateTimeKind.Unspecified).AddTicks(1), "2019-01-05T12:14:58.1920001"), (new DateTime(2019, 1, 5, 12, 14, 58, 192, DateTimeKind.Unspecified).AddTicks(20), "2019-01-05T12:14:58.1920020"), (new DateTime(2019, 1, 5, 12, 14, 58, 192, DateTimeKind.Local), "2019-01-05T12:14:58.1920000" + offset), (new DateTime(2019, 1, 5, 12, 14, 58, 192, DateTimeKind.Local).AddTicks(1), "2019-01-05T12:14:58.1920001" + offset), (new DateTime(2019, 1, 5, 12, 14, 58, 192, DateTimeKind.Local).AddTicks(20), "2019-01-05T12:14:58.1920020" + offset), }; // Act var actuals = scenarios.Select(_ => (DateTime)systemUnderTest.Deserialize(_.SerializedString, typeof(DateTime))).ToList(); // Assert actuals.Must().BeEqualTo(scenarios.Select(_ => _.Expected).ToList()); }
public static void SerializeToString_DateTime___Should_return_serialized_string_representation_of_value_for_different_DateTimeKind___When_called() { // Arrange // note that this will return "+00:00" if machine is on UTC time, which is what we expect var offset = DateTime.Now.ToString("%K"); var scenarios = new List <(DateTime Value, string Expected)> { (new DateTime(2019, 1, 5, 12, 14, 58, 192, DateTimeKind.Utc), "2019-01-05T12:14:58.1920000Z"), (new DateTime(2019, 1, 5, 12, 14, 58, 192, DateTimeKind.Utc).AddTicks(1), "2019-01-05T12:14:58.1920001Z"), (new DateTime(2019, 1, 5, 12, 14, 58, 192, DateTimeKind.Utc).AddTicks(20), "2019-01-05T12:14:58.1920020Z"), (new DateTime(2019, 1, 5, 12, 14, 58, 192, DateTimeKind.Unspecified), "2019-01-05T12:14:58.1920000"), (new DateTime(2019, 1, 5, 12, 14, 58, 192, DateTimeKind.Unspecified).AddTicks(1), "2019-01-05T12:14:58.1920001"), (new DateTime(2019, 1, 5, 12, 14, 58, 192, DateTimeKind.Unspecified).AddTicks(20), "2019-01-05T12:14:58.1920020"), (new DateTime(2019, 1, 5, 12, 14, 58, 192, DateTimeKind.Local), "2019-01-05T12:14:58.1920000" + offset), (new DateTime(2019, 1, 5, 12, 14, 58, 192, DateTimeKind.Local).AddTicks(1), "2019-01-05T12:14:58.1920001" + offset), (new DateTime(2019, 1, 5, 12, 14, 58, 192, DateTimeKind.Local).AddTicks(20), "2019-01-05T12:14:58.1920020" + offset), }; // Act var actuals = scenarios.Select(_ => ObcDateTimeStringSerializer.SerializeToString(_.Value)).ToList(); // Assert actuals.Must().BeEqualTo(scenarios.Select(_ => _.Expected).ToList()); }
public static void Deserialize_serializedString_type___Should_deserialize_UTC_DateTime___When_serialized_strings_have_reduced_precision() { // Arrange var systemUnderTest = new ObcDateTimeStringSerializer(); var serializedDateTimes = new[] { "2017-05-06T02:28:46.2704883Z", "2017-05-06T02:28:46.270484Z", "2017-05-06T02:28:46.27048Z", "2017-05-06T02:28:46.2704Z", "2017-05-06T02:28:46.271Z", "2017-05-06T02:28:46.27Z", "2017-05-06T02:28:46.2Z", "2017-05-06T02:28:46Z", "2017-05-06T02:28:00Z", "2017-05-06T02:00:00Z", "2017-05-06T00:00:00Z", }; var expected = serializedDateTimes.Select(_ => DateTime.Parse(_, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal)).ToList(); // Act var actual = serializedDateTimes.Select(_ => (DateTime)systemUnderTest.Deserialize(_, typeof(DateTime))).ToList(); // Assert actual.Must().BeEqualTo(expected); }
public static void DeserializeToDateTime___Should_throw_InvalidOperationException___When_serializedString_is_malformed() { // Arrange var serializedDateTimes = new[] { "2017-05-06T02:28:46", // no precision not supported for Unspecified "2017-05-06T02:28:46+00:00", // no precision not supported for Local "2017-05-06T02:28:46.270488", // less than 7 precision not supported for Unspecified "2017-05-06T02:28:46.270488+00:00", // less than 7 precision not supported for Local "2017-05-06T02:28:46.27048838", // too much precision "2017-05-06T02:28:46.27048838+00:00", // too much precision "2017-05-06T02:28:46.27048838Z", // too much precision "2017-05-06T02:28:46.2704883K", // shouldn't end in K "some-string", // random string "2017-05-06", // only date "2017-05-06+00:00", // only date "2017-05-06Z", // only date "02:28:46.1938283", // only time "02:28:46.1938283+00:00", // only time "02:28:46.1938283Z", // only time }; // Act var actuals = serializedDateTimes.Select(_ => Record.Exception(() => ObcDateTimeStringSerializer.DeserializeToDateTime(_))).ToList(); // Assert actuals.Must().Each().BeOfType <InvalidOperationException>(); actuals.Select(_ => _.Message).Must().Each().ContainString("is malformed; it's not in a supported format and cannot be deserialized."); }
public static void DeserializeToDateTime___Should_throw_ArgumentNullException___When_parameter_serializedString_is_null() { // Arrange, Act var actual = Record.Exception(() => ObcDateTimeStringSerializer.DeserializeToDateTime(null)); // Assert actual.Must().BeOfType <ArgumentNullException>(); actual.Message.Must().ContainString("serializedString"); }
public static void DeserializeToDateTime___Should_throw_ArgumentException___When_parameter_serializedString_is_white_space() { // Arrange, Act var actual = Record.Exception(() => ObcDateTimeStringSerializer.DeserializeToDateTime(Invariant($" {Environment.NewLine} "))); // Assert actual.Must().BeOfType <ArgumentException>(); actual.Message.Must().ContainString("serializedString"); actual.Message.Must().ContainString("white space"); }
private string MakeStringFromObject( object value) { if (value == null) { return(null); } var propertyType = value.GetType(); if (this.configuredTypeToSerializerMap.ContainsKey(propertyType)) { var serializer = this.configuredTypeToSerializerMap[propertyType]; var result = serializer.SerializeToString(value); return(result); } else if (value is DateTime propertyValueAsDateTime) { var result = ObcDateTimeStringSerializer.SerializeToString(propertyValueAsDateTime); return(result); } else { string result; if ((propertyType != typeof(string)) && (value is IEnumerable propertyValueAsEnumerable)) { var values = new List <string>(); foreach (var element in propertyValueAsEnumerable) { var serializedItem = this.MakeStringFromObject(element); values.Add(serializedItem); } result = values.ToCsv(this.dictionaryStringSerializer.NullValueEncoding); } else if (value is ISerializeToString propertyValueAsSerializeToString) { result = propertyValueAsSerializeToString.SerializeToString(); } else { result = value.ToString(); } return(result); } }
public static void Deserialize_serializedString_type___Should_throw_ArgumentNullException___When_parameter_type_is_null() { // Arrange var systemUnderTest = new ObcDateTimeStringSerializer(); // Act var actual = Record.Exception(() => systemUnderTest.Deserialize("2019-01-05T12:14:58.1920000Z", null)); // Assert actual.Must().BeOfType <ArgumentNullException>(); actual.Message.Must().ContainString("type"); }
public static void Deserialize_T___Should_throw_ArgumentNullException___When_parameter_serializedString_is_null() { // Arrange var systemUnderTest = new ObcDateTimeStringSerializer(); // Act var actual = Record.Exception(() => systemUnderTest.Deserialize <DateTime>(null)); // Assert actual.Must().BeOfType <ArgumentNullException>(); actual.Message.Must().ContainString("serializedString"); }
public static void SerializeToString_object___Should_throw_ArgumentNullException___When_parameter_value_is_null() { // Arrange var systemUnderTest = new ObcDateTimeStringSerializer(); object value = null; // Act var actual = Record.Exception(() => systemUnderTest.SerializeToString(value)); // Assert actual.AsTest().Must().BeOfType <ArgumentNullException>(); }
public static void RoundtripSerializeDeserialize___Using_local_negative_offset___Works() { // Arrange var expected = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time")); var serializer = new ObcDateTimeStringSerializer(); // Act var serialized = serializer.SerializeToString(expected); var actual = serializer.Deserialize <DateTime>(serialized); // Assert actual.Kind.Must().BeEqualTo(expected.Kind); actual.Must().BeEqualTo(expected); }
public static void RoundtripSerializeDeserialize___Using_unspecified___Works() { // Arrange var expected = DateTime.UtcNow.ToUnspecified(); var serializer = new ObcDateTimeStringSerializer(); // Act var serialized = serializer.SerializeToString(expected); var actual = serializer.Deserialize <DateTime>(serialized); // Assert actual.Kind.Must().BeEqualTo(expected.Kind); actual.Must().BeEqualTo(expected); }
public static void SerializeToString_object___Should_throw_ArgumentException___When_parameter_value_is_not_DateTime() { // Arrange var systemUnderTest = new ObcDateTimeStringSerializer(); var values = new[] { new object(), A.Dummy <string>(), A.Dummy <int>(), A.Dummy <Guid>() }; // Act var actual = values.Select(_ => Record.Exception(() => systemUnderTest.SerializeToString(_))).ToList(); // Assert actual.Must().Each().BeOfType <ArgumentException>(); actual.Select(_ => _.Message).Must().Each().ContainString("objectToSerialize.GetType() != typeof(DateTime);"); }
public static void Deserialize_serializedString_type___Should_throw_ArgumentException___When_parameter_type_is_not_DateTime() { // Arrange var systemUnderTest = new ObcDateTimeStringSerializer(); // Act var actual1 = Record.Exception(() => systemUnderTest.Deserialize("2019-01-05T12:14:58.1920000Z", typeof(object))); var actual2 = Record.Exception(() => systemUnderTest.Deserialize("2019-01-05T12:14:58.1920000Z", typeof(DateTime?))); // Assert actual1.Must().BeOfType <ArgumentException>(); actual1.Message.Must().BeEqualTo("type != typeof(DateTime); 'type' is of type 'object'"); actual2.Must().BeOfType <ArgumentException>(); actual2.Message.Must().BeEqualTo("type != typeof(DateTime); 'type' is of type 'DateTime?'"); }
private object MakeObjectFromString( string value, Type type) { if (value == null) { return(null); } if (this.configuredTypeToSerializerMap.ContainsKey(type)) { var serializer = this.configuredTypeToSerializerMap[type]; var result = serializer.Deserialize(value, type); return(result); } else if (type.IsEnum) { var result = Enum.Parse(type, value); return(result); } else if (type.IsArray) { var arrayItemType = type.GetElementType() ?? throw new SerializationException(Invariant($"Found array type that cannot extract element type: {type}")); var asList = (IList)this.MakeObjectFromString(value, typeof(List <>).MakeGenericType(arrayItemType)); var asArrayList = new ArrayList(asList); var result = asArrayList.ToArray(arrayItemType); return(result); } else if (type == typeof(DateTime) || type == typeof(DateTime?)) { var result = ObcDateTimeStringSerializer.DeserializeToDateTime(value); return(result); } else if ((type != typeof(string)) && typeof(IEnumerable).IsAssignableFrom(type)) { var itemType = type.GenericTypeArguments.SingleOrDefault() ?? throw new SerializationException(Invariant($"Found {typeof(IEnumerable)} type that cannot extract element type: {type}")); var stringValues = value.FromCsv(this.dictionaryStringSerializer.NullValueEncoding); var result = (IList)typeof(List <>).MakeGenericType(itemType).Construct(); foreach (var stringValue in stringValues) { var itemValue = stringValue == null ? null : this.MakeObjectFromString(stringValue, itemType); result.Add(itemValue); } return(result); } else { var typeToSearchForParse = type; if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable <>)) { typeToSearchForParse = type.GenericTypeArguments.Single(); } var parseMethod = typeToSearchForParse .GetMethodsFiltered(MemberRelationships.DeclaredOrInherited, MemberOwners.All, MemberAccessModifiers.Public) .SingleOrDefault(_ => { var parameters = _.GetParameters(); return((_.Name == "Parse") && (parameters.Length == 1) && (parameters.Single().ParameterType == typeof(string))); }); var result = parseMethod == null ? value : parseMethod.Invoke(null, new object[] { value }); return(result); } }
public static void LogError(string message) { try { var serializedDateTimeUtcNow = ObcDateTimeStringSerializer.SerializeToString(DateTime.UtcNow); const ushort eventLogCharacterLimit = 31914; Action <string> logToFile = localMessage => { var preppedForFilePathTime = serializedDateTimeUtcNow.Replace(":", "-").Replace(".", "_").Replace("T", "--"); var fileName = preppedForFilePathTime + "--LastDitchLoggedError.log"; File.WriteAllText(fileName, localMessage); }; Action <string> logToEventLog = localMessage => { var preppedMessage = localMessage == null ? "Null Message Provided." : localMessage.Length <= eventLogCharacterLimit ? localMessage : localMessage.Substring(0, eventLogCharacterLimit); using (EventLog eventLog = new EventLog("Application")) { eventLog.Source = "Application"; eventLog.WriteEntry(preppedMessage, EventLogEntryType.Error, 101, 1); } }; Action <string> logToConsoleOut = localMessage => { var preppedMessage = serializedDateTimeUtcNow + "--" + localMessage; Console.Out.WriteLine(preppedMessage); }; Action <string> logToConsoleError = localMessage => { var preppedMessage = serializedDateTimeUtcNow + "--" + localMessage; Console.Error.WriteLine(preppedMessage); }; Action <string> logToTraceOut = localMessage => { var preppedMessage = serializedDateTimeUtcNow + "--" + localMessage; Trace.WriteLine(preppedMessage); }; Action <string> logToTraceError = localMessage => { var preppedMessage = serializedDateTimeUtcNow + "--" + localMessage; Trace.TraceError(preppedMessage); }; IReadOnlyCollection <Action <string> > actionsToRun = new[] { logToFile, logToEventLog, logToConsoleOut, logToConsoleError, logToTraceOut, logToTraceError, }; void RunActionWithExceptionSwallowing(Action <string> actionToRunWithoutAllowingExceptions, string input) { try { actionToRunWithoutAllowingExceptions(input); } catch (Exception) { /* no-op */ } } foreach (var actionToRun in actionsToRun) { RunActionWithExceptionSwallowing(actionToRun, message); } } catch (Exception) { /* no-op */ } }