From 9b6a84da38156a50f55660340902596251751717 Mon Sep 17 00:00:00 2001 From: Folker Kinzel Date: Thu, 23 Jan 2025 01:14:55 +0100 Subject: [PATCH] tests --- .../BuilderParts/RelationBuilderTests.cs | 26 +++- .../StringCollectionBuilderTests.cs | 15 ++- .../BuilderParts/TimeZoneBuilderTests.cs | 14 ++- .../Models/ContactIDTests.cs | 85 +++++++++++++ .../Models/DateAndOrTimeTests.cs | 112 +++++++++++++++++- .../Models/GeoCoordinateTests.cs | 41 ++++--- src/FolkerKinzel.VCards.Tests/V4Tests.cs | 21 ++++ .../Serializers/ParameterSerializer4_0.cs | 1 - .../Models/DateAndOrTime.cs | 27 +++-- 9 files changed, 311 insertions(+), 31 deletions(-) diff --git a/src/FolkerKinzel.VCards.Tests/BuilderParts/RelationBuilderTests.cs b/src/FolkerKinzel.VCards.Tests/BuilderParts/RelationBuilderTests.cs index 1321865e4..3fabf370b 100644 --- a/src/FolkerKinzel.VCards.Tests/BuilderParts/RelationBuilderTests.cs +++ b/src/FolkerKinzel.VCards.Tests/BuilderParts/RelationBuilderTests.cs @@ -1,4 +1,8 @@ -namespace FolkerKinzel.VCards.BuilderParts.Tests; +using FolkerKinzel.VCards.Extensions; +using FolkerKinzel.VCards.Models; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace FolkerKinzel.VCards.BuilderParts.Tests; [TestClass] public class RelationBuilderTests @@ -101,6 +105,26 @@ public void SetIndexesTest2() [ExpectedException(typeof(InvalidOperationException))] public void AddTest4() => new RelationBuilder().Add((VCard?)null); + [TestMethod] + public void AddTest5() + { + var vc = VCardBuilder.Create().Relations.Add((Relation?)null).VCard; + + var relation = vc.Relations.FirstOrNull(skipEmptyItems:false); + Assert.IsNotNull(relation); + Assert.IsTrue(relation.IsEmpty); + } + + [TestMethod] + public void AddTest6() + { + var vc = VCardBuilder.Create().Relations.Add((ContactID?)null).VCard; + + var relation = vc.Relations.FirstOrNull(skipEmptyItems: false); + Assert.IsNotNull(relation); + Assert.IsTrue(relation.IsEmpty); + } + [TestMethod] [ExpectedException(typeof(InvalidOperationException))] public void ClearTest1() => new RelationBuilder().Clear(); diff --git a/src/FolkerKinzel.VCards.Tests/BuilderParts/StringCollectionBuilderTests.cs b/src/FolkerKinzel.VCards.Tests/BuilderParts/StringCollectionBuilderTests.cs index a91c9a526..66ce3a566 100644 --- a/src/FolkerKinzel.VCards.Tests/BuilderParts/StringCollectionBuilderTests.cs +++ b/src/FolkerKinzel.VCards.Tests/BuilderParts/StringCollectionBuilderTests.cs @@ -1,4 +1,6 @@ -using FolkerKinzel.VCards.Models.Properties; +using FolkerKinzel.VCards.Extensions; +using FolkerKinzel.VCards.Models.Properties; +using Microsoft.VisualStudio.TestTools.UnitTesting; namespace FolkerKinzel.VCards.BuilderParts.Tests; @@ -93,7 +95,16 @@ public void SetIndexesTest2() [TestMethod] [ExpectedException(typeof(InvalidOperationException))] - public void AddTest2() => new StringCollectionBuilder().Add(Enumerable.Empty()); + public void AddTest2() => new StringCollectionBuilder().Add([]); + + [TestMethod] + public void AddTest3() + { + var vc = VCardBuilder.Create().NickNames.Add((string[]?)null).VCard; + var nickName = vc.NickNames.FirstOrNull(skipEmptyItems:false); + Assert.IsNotNull(nickName); + Assert.IsTrue(nickName.IsEmpty); + } [TestMethod] [ExpectedException(typeof(InvalidOperationException))] diff --git a/src/FolkerKinzel.VCards.Tests/BuilderParts/TimeZoneBuilderTests.cs b/src/FolkerKinzel.VCards.Tests/BuilderParts/TimeZoneBuilderTests.cs index 04586c6c2..51632e468 100644 --- a/src/FolkerKinzel.VCards.Tests/BuilderParts/TimeZoneBuilderTests.cs +++ b/src/FolkerKinzel.VCards.Tests/BuilderParts/TimeZoneBuilderTests.cs @@ -1,4 +1,6 @@ -using FolkerKinzel.VCards.Models; +using FolkerKinzel.VCards.Extensions; +using FolkerKinzel.VCards.Models; +using Microsoft.VisualStudio.TestTools.UnitTesting; namespace FolkerKinzel.VCards.BuilderParts.Tests; @@ -93,6 +95,16 @@ public void SetIndexesTest2() [ExpectedException(typeof(InvalidOperationException))] public void AddTest2() => new TimeZoneBuilder().Add("Europe/Berlin"); + [TestMethod] + public void AddTest3() + { + var vc = VCardBuilder.Create().TimeZones.Add((string?)null!).VCard; + var timeZone = vc.TimeZones.FirstOrNull(skipEmptyItems: false); + + Assert.IsNotNull(timeZone); + Assert.IsTrue(timeZone.IsEmpty); + } + [TestMethod] [ExpectedException(typeof(InvalidOperationException))] public void ClearTest1() => new TimeZoneBuilder().Clear(); diff --git a/src/FolkerKinzel.VCards.Tests/Models/ContactIDTests.cs b/src/FolkerKinzel.VCards.Tests/Models/ContactIDTests.cs index 4a7066d39..c868096d0 100644 --- a/src/FolkerKinzel.VCards.Tests/Models/ContactIDTests.cs +++ b/src/FolkerKinzel.VCards.Tests/Models/ContactIDTests.cs @@ -13,6 +13,20 @@ public class ContactIDTests [ExpectedException(typeof(ArgumentException))] public void CreateTest2() => ContactID.Create(new Uri("../relative", UriKind.Relative)); + [TestMethod] + public void CreateTest3() + { + var id = ContactID.Create(new Uri("urn:uuid:A0CD4379-64AB-4BFA-9CEC-66DC76CA585E", UriKind.Absolute)); + Assert.IsNotNull(id.Guid); + } + + [TestMethod] + public void CreateTest4() + { + var id = ContactID.Create(new Uri("urn:uuid:blabla", UriKind.Absolute)); + Assert.IsNotNull(id.Uri); + } + [TestMethod] public void ToStringTest1() => Assert.IsNotNull(ContactID.Empty.ToString()); @@ -77,6 +91,52 @@ public void ConvertTest1() Assert.AreEqual(test, result); } + [TestMethod] + public void ConvertTest1b() + { + const string test = "test"; + string? result = null; + + result = ContactID.Create(new Uri("http://folker.com/")).Convert(test, null!, (guid, str) => str, null!); + + Assert.AreEqual(test, result); + } + + [TestMethod] + public void ConvertTest1c() + { + const string test = "test"; + string? result = null; + + result = ContactID.Create("Hi").Convert(test, null!, null!, (guid, str) => str); + + Assert.AreEqual(test, result); + } + + [TestMethod] + [ExpectedException(typeof(ArgumentNullException))] + public void ConvertTest2() => _ = ContactID.Create().Convert("", null!, null!, null!); + + [TestMethod] + [ExpectedException(typeof(ArgumentNullException))] + public void ConvertTest3() => _ = ContactID.Create(new Uri("http://folker.com/")).Convert("", null!, null!, null!); + + [TestMethod] + [ExpectedException(typeof(ArgumentNullException))] + public void ConvertTest4() => _ = ContactID.Create("Hi").Convert("", null!, null!, null!); + + [TestMethod] + [ExpectedException(typeof(ArgumentNullException))] + public void ConvertTest5() => _ = ContactID.Create().Convert(null!, null!, null!); + + [TestMethod] + [ExpectedException(typeof(ArgumentNullException))] + public void ConvertTest6() => _ = ContactID.Create(new Uri("http://folker.com/")).Convert(null!, null!, null!); + + [TestMethod] + [ExpectedException(typeof(ArgumentNullException))] + public void ConvertTest7() => _ = ContactID.Create("Hi").Convert(null!, null!, null!); + [TestMethod] public void EqualsTest1() { @@ -91,6 +151,31 @@ public void EqualsTest1() Assert.IsFalse(o1.Equals(42)); } + + [TestMethod] + public void EqualsTest2() + { + var uid1 = ContactID.Create(); + ContactID? uid2 = null; + Assert.IsFalse(uid1.Equals(uid2)); + } + + [TestMethod] + public void EqualsTest3() + { + var uid1 = ContactID.Create("Hi"); + ContactID? uid2 = ContactID.Create(); + Assert.IsFalse(uid1.Equals(uid2)); + } + + [TestMethod] + public void EqualityTest4() + { + const string test = "http://folker.com/"; + var uid1 = ContactID.Create(test); + var uid2 = ContactID.Create(new Uri(test, UriKind.Absolute)); + Assert.IsTrue(uid1.Equals(uid2)); + } } diff --git a/src/FolkerKinzel.VCards.Tests/Models/DateAndOrTimeTests.cs b/src/FolkerKinzel.VCards.Tests/Models/DateAndOrTimeTests.cs index 19cb3776d..f5d43b136 100644 --- a/src/FolkerKinzel.VCards.Tests/Models/DateAndOrTimeTests.cs +++ b/src/FolkerKinzel.VCards.Tests/Models/DateAndOrTimeTests.cs @@ -34,7 +34,6 @@ public void ValueTest2() Assert.IsTrue(rel.TryAsDateTimeOffset(out _)); } - [TestMethod] public void ValueTest3() { @@ -159,6 +158,36 @@ public void ConvertTest1() [TestMethod] public void ConvertTest2() + { + const int expected = 42; + DateAndOrTime rel = DateTimeOffset.Now; + + int result = rel.Convert(null!, s => expected, null!, null!); + Assert.AreEqual(expected, result); + } + + [TestMethod] + public void ConvertTest3() + { + const int expected = 42; + DateAndOrTime rel = TimeOnly.FromDateTime(DateTime.Now); + + int result = rel.Convert(null!, null!, s => expected, null!); + Assert.AreEqual(expected, result); + } + + [TestMethod] + public void ConvertTest4() + { + const int expected = 42; + DateAndOrTime rel = "Midnight"; + + int result = rel.Convert(null!, null!, null!, s => expected); + Assert.AreEqual(expected, result); + } + + [TestMethod] + public void ConvertTest5() { const string test = "test"; string? result = null; @@ -168,6 +197,79 @@ public void ConvertTest2() Assert.AreEqual(test, result); } + [TestMethod] + public void ConvertTest6() + { + const string test = "test"; + string? result = null; + + result = DateAndOrTime.Create(DateTimeOffset.Now).Convert(test, null!, (guid, str) => str, null!, null!); + + Assert.AreEqual(test, result); + } + + [TestMethod] + public void ConvertTest7() + { + const string test = "test"; + string? result = null; + + result = DateAndOrTime.Create(TimeOnly.FromDateTime(DateTime.Now)).Convert(test, null!, null!, (guid, str) => str, null!); + + Assert.AreEqual(test, result); + } + + [TestMethod] + public void ConvertTest8() + { + const string test = "test"; + string? result = null; + + result = DateAndOrTime.Create("Midnight").Convert(test, null!, null!, null!, (guid, str) => str); + + Assert.AreEqual(test, result); + } + + [TestMethod] + [ExpectedException(typeof(ArgumentNullException))] + public void ConvertTest9() + => _ = DateAndOrTime.Create(DateOnly.FromDateTime(DateTime.Now)).Convert("", null!, null!, null!, null!); + + [TestMethod] + [ExpectedException(typeof(ArgumentNullException))] + public void ConvertTest10() + => _ = DateAndOrTime.Create(DateTimeOffset.Now).Convert("", null!, null!, null!, null!); + + [TestMethod] + [ExpectedException(typeof(ArgumentNullException))] + public void ConvertTest11() + => _ = DateAndOrTime.Create(TimeOnly.FromDateTime(DateTime.Now)).Convert("", null!, null!, null!, null!); + + [TestMethod] + [ExpectedException(typeof(ArgumentNullException))] + public void ConvertTest12() + => _ = DateAndOrTime.Create("Midnight").Convert("", null!, null!, null!, null!); + + [TestMethod] + [ExpectedException(typeof(ArgumentNullException))] + public void ConvertTest13() + => _ = DateAndOrTime.Create(DateOnly.FromDateTime(DateTime.Now)).Convert(null!, null!, null!, null!); + + [TestMethod] + [ExpectedException(typeof(ArgumentNullException))] + public void ConvertTest14() + => _ = DateAndOrTime.Create(DateTimeOffset.Now).Convert(null!, null!, null!, null!); + + [TestMethod] + [ExpectedException(typeof(ArgumentNullException))] + public void ConvertTest15() + => _ = DateAndOrTime.Create(TimeOnly.FromDateTime(DateTime.Now)).Convert(null!, null!, null!, null!); + + [TestMethod] + [ExpectedException(typeof(ArgumentNullException))] + public void ConvertTest16() + => _ = DateAndOrTime.Create("Midnight").Convert(null!, null!, null!, null!); + [TestMethod] public void TryAsDateTest1() => Assert.IsFalse(DateAndOrTime.Create(new DateTimeOffset(2, 1, 1, 17, 24, 32, TimeSpan.FromHours(1))).TryAsDateOnly(out _)); @@ -204,4 +306,12 @@ public void EqualsTest1() Assert.IsTrue(daot != null); Assert.IsFalse(daot.Equals(42)); } + + [TestMethod] + public void AsStringTest1() + { + var daot = DateAndOrTime.Create(2, 4); + string str = daot.AsString(CultureInfo.InvariantCulture); + Assert.AreEqual("02/04", str); + } } diff --git a/src/FolkerKinzel.VCards.Tests/Models/GeoCoordinateTests.cs b/src/FolkerKinzel.VCards.Tests/Models/GeoCoordinateTests.cs index c7a2038ee..e104bbcfa 100644 --- a/src/FolkerKinzel.VCards.Tests/Models/GeoCoordinateTests.cs +++ b/src/FolkerKinzel.VCards.Tests/Models/GeoCoordinateTests.cs @@ -18,7 +18,6 @@ public void GeoCoordinateTest1() Assert.AreEqual(longitude, geo.Longitude); } - [DataTestMethod()] [DataRow(double.NaN, 15, null)] [DataRow(15, double.NegativeInfinity, null)] @@ -63,6 +62,22 @@ public void GeoCoordinateTest4() Assert.AreEqual(180, geo.Longitude, 0.1); } + [TestMethod()] + public void EqualsTest1() + { + var geo = new GeoCoordinate(1, 1); + var o = new object(); + + Assert.IsFalse(geo.Equals(null)); + Assert.IsFalse(geo!.Equals(o)); + } + + [TestMethod()] + public void EqualsTest2() => Assert.IsTrue(null == (GeoCoordinate?)null); + + [TestMethod()] + public void EqualsTest3() => Assert.IsFalse(null == new GeoCoordinate(1, 1)); + [DataTestMethod()] [DataRow(50, 50, 0.0F, 50, 50, null, false)] [DataRow(90, 50, null, 90, 0, null, true)] @@ -93,6 +108,14 @@ public void EqualsTest4(double latitude1, double longitude1, float? uncertainty1 } } + [TestMethod()] + public void EqualsTest5() + { + Assert.IsTrue(GeoCoordinate.Empty.Equals(GeoCoordinate.Empty)); + Assert.IsFalse(GeoCoordinate.Empty == new GeoCoordinate(0,0)); + Assert.IsFalse(new GeoCoordinate(0, 0) == GeoCoordinate.Empty); + } + [DataTestMethod()] [DataRow(51.05022555003223, 12.130624133575036, null, 51.04930951936781, 12.128100583930106, 1000.0F, true)] [DataRow(51.05022555003223, 12.130624133575036, null, 51.04930951936781, 12.128100583930106, 100.0F, false)] @@ -130,21 +153,7 @@ public void AreSamePositionTest4() public void AreSamePositionTest5() => Assert.IsFalse(GeoCoordinate.AreSamePosition(GeoCoordinate.Empty, new GeoCoordinate(0, 0))); - [TestMethod()] - public void EqualsTest1() - { - var geo = new GeoCoordinate(1, 1); - var o = new object(); - - Assert.IsFalse(geo.Equals(null)); - Assert.IsFalse(geo!.Equals(o)); - } - - [TestMethod()] - public void EqualsTest2() => Assert.IsTrue(null == (GeoCoordinate?)null); - - [TestMethod()] - public void EqualsTest3() => Assert.IsFalse(null == new GeoCoordinate(1, 1)); + //[TestMethod()] //public void GetHashCodeTest() diff --git a/src/FolkerKinzel.VCards.Tests/V4Tests.cs b/src/FolkerKinzel.VCards.Tests/V4Tests.cs index 21a4fee79..e55667877 100644 --- a/src/FolkerKinzel.VCards.Tests/V4Tests.cs +++ b/src/FolkerKinzel.VCards.Tests/V4Tests.cs @@ -541,6 +541,9 @@ public void LogoPhotoSoundTest1() .Logos.AddText("text") .Photos.AddText("text") .Sounds.AddText("text") + .Logos.Edit(props => props.Append(null)) + .Photos.Edit(props => props.Append(null)) + .Sounds.Edit(props => props.Append(null)) .VCard; string vcf = vc.ToVcfString(VCdVersion.V4_0); @@ -550,6 +553,24 @@ public void LogoPhotoSoundTest1() Assert.IsFalse(vcf.Contains("SOUND", StringComparison.OrdinalIgnoreCase)); } + [TestMethod] + public void LogoPhotoSoundTest2() + { + byte[] bytes = [1,2,3]; + VCard vc = VCardBuilder + .Create() + .Logos.AddBytes(bytes) + .Photos.AddBytes(bytes) + .Sounds.AddBytes(bytes) + .VCard; + + string vcf = vc.ToVcfString(VCdVersion.V4_0); + + Assert.IsTrue(vcf.Contains("LOGO", StringComparison.OrdinalIgnoreCase)); + Assert.IsTrue(vcf.Contains("PHOTO", StringComparison.OrdinalIgnoreCase)); + Assert.IsTrue(vcf.Contains("SOUND", StringComparison.OrdinalIgnoreCase)); + } + [TestMethod] public void AltIdTest1() { diff --git a/src/FolkerKinzel.VCards/Intls/Serializers/ParameterSerializer4_0.cs b/src/FolkerKinzel.VCards/Intls/Serializers/ParameterSerializer4_0.cs index 36cd3ef16..e6d25c047 100644 --- a/src/FolkerKinzel.VCards/Intls/Serializers/ParameterSerializer4_0.cs +++ b/src/FolkerKinzel.VCards/Intls/Serializers/ParameterSerializer4_0.cs @@ -1045,7 +1045,6 @@ private void AppendServiceTypeAndUsername() private void AppendSortAs() { - Debug.Assert(ParaSection.SortAs is null or string[]); string[]? sortAs = (string[]?)ParaSection.SortAs; if (!sortAs.ContainsData()) diff --git a/src/FolkerKinzel.VCards/Models/DateAndOrTime.cs b/src/FolkerKinzel.VCards/Models/DateAndOrTime.cs index 4e558b9be..f4a9e1c0e 100644 --- a/src/FolkerKinzel.VCards/Models/DateAndOrTime.cs +++ b/src/FolkerKinzel.VCards/Models/DateAndOrTime.cs @@ -42,7 +42,9 @@ public sealed class DateAndOrTime : IEquatable /// The value. /// /// The newly created instance. - public static DateAndOrTime Create(DateOnly value) => new(value); + public static DateAndOrTime Create(DateOnly value) + => value.HasYear() ? new(value) + : new(new DateOnly(DateAndOrTimeConverter.FIRST_LEAP_YEAR, value.Month, value.Day)); /// /// Creates a new instance from a @@ -56,9 +58,15 @@ public sealed class DateAndOrTime : IEquatable /// an empty instance. /// public static DateAndOrTime Create(DateTimeOffset value) - => !DateAndOrTimeConverter.HasDate(value) && !DateAndOrTimeConverter.HasTime(value) - ? Empty - : new(value); + => !DateAndOrTimeConverter.HasDate(value) + ? !DateAndOrTimeConverter.HasTime(value) ? Empty : new(new DateTimeOffset(2, 1, 1, value.Hour, value.Minute, value.Second, value.Offset)) + : DateAndOrTimeConverter.HasYear(value) ? new(value) : new(new DateTimeOffset(DateAndOrTimeConverter.FIRST_LEAP_YEAR, + value.Month, + value.Day, + value.Hour, + value.Minute, + value.Second, + value.Offset)); /// /// Creates a new instance from a @@ -326,7 +334,8 @@ public string AsString(IFormatProvider? formatProvider = null) static (date, fp) => date.HasYear() ? date.ToString(fp) : date.ToString(fp) - .Replace(date.Year.ToString(), "", StringComparison.Ordinal), + .Replace(date.Year.ToString("0000"), "", StringComparison.Ordinal) + .Trim('/'), static (dtOffset, fp) => DateTimeOffsetToString(dtOffset), static (time, fp) => time.ToString(fp), static (str, fp) => str @@ -445,8 +454,8 @@ public TResult Convert(Func dateFunc, : DateTimeOffset.HasValue ? dtoFunc is null ? throw new ArgumentNullException(nameof(dtoFunc)) : dtoFunc(DateTimeOffset.Value) : TimeOnly.HasValue - ? timeFunc is null ? throw new ArgumentNullException(nameof(timeFunc)) : timeFunc(TimeOnly.Value) - : stringFunc is null ? throw new ArgumentNullException(nameof(stringFunc)) : stringFunc(String!); + ? timeFunc is null ? throw new ArgumentNullException(nameof(timeFunc)) : timeFunc(TimeOnly.Value) + : stringFunc is null ? throw new ArgumentNullException(nameof(stringFunc)) : stringFunc(String!); /// /// Converts the encapsulated value to and allows to specify an @@ -479,8 +488,8 @@ public TResult Convert(TArg arg, : DateTimeOffset.HasValue ? dtoFunc is null ? throw new ArgumentNullException(nameof(dtoFunc)) : dtoFunc(DateTimeOffset.Value, arg) : TimeOnly.HasValue - ? timeFunc is null ? throw new ArgumentNullException(nameof(timeFunc)) : timeFunc(TimeOnly.Value, arg) - : stringFunc is null ? throw new ArgumentNullException(nameof(stringFunc)) : stringFunc(String!, arg); + ? timeFunc is null ? throw new ArgumentNullException(nameof(timeFunc)) : timeFunc(TimeOnly.Value, arg) + : stringFunc is null ? throw new ArgumentNullException(nameof(stringFunc)) : stringFunc(String!, arg); /// [MethodImpl(MethodImplOptions.AggressiveInlining)]