From 429094565aacfb420196dbcf37d6976256f5bd67 Mon Sep 17 00:00:00 2001 From: Ewout Kramer Date: Mon, 25 Nov 2024 16:49:42 +0100 Subject: [PATCH] Fixed unit tests --- .../ElementModel/NewPocoBuilder.cs | 11 ++- .../ElementModel/PocoElementNode.cs | 6 +- .../Introspection/PropertyMapping.cs | 3 +- src/Hl7.Fhir.Base/Model/Base.Dictionary.cs | 6 +- src/Hl7.Fhir.Base/Model/Base.Extensions.cs | 7 +- src/Hl7.Fhir.Base/Model/Base.TypedElement.cs | 26 ++---- src/Hl7.Fhir.Base/Model/Base.cs | 16 ++-- src/Hl7.Fhir.Base/Model/PrimitiveType.cs | 30 ------ .../BaseFhirJsonPocoSerializer.cs | 93 ++++++++++--------- .../BaseFhirXmlPocoSerializer.cs | 9 +- .../ScopedNodeOnBaseTests.cs | 2 +- ...SerializationExcexptionHandlersJsonPoco.cs | 10 +- .../Model/PocoDictionaryTests.cs | 5 +- .../FhirJsonDeserializationTests.cs | 7 +- .../TestDictionaryImplementation.cs | 28 ++---- 15 files changed, 112 insertions(+), 147 deletions(-) diff --git a/src/Hl7.Fhir.Base/ElementModel/NewPocoBuilder.cs b/src/Hl7.Fhir.Base/ElementModel/NewPocoBuilder.cs index 8209c3ff88..b6d83b4b82 100644 --- a/src/Hl7.Fhir.Base/ElementModel/NewPocoBuilder.cs +++ b/src/Hl7.Fhir.Base/ElementModel/NewPocoBuilder.cs @@ -54,9 +54,16 @@ private Base readFromElement(ITypedElement node, ClassMapping classMapping) var objectValue = newInstance is DynamicPrimitive ? value : convertTypedElementValue(value, node.InstanceType); - newInstance["value"] = objectValue; - if (settings?.AllowUnrecognizedEnums == false && classMapping.EnumType is not null && objectValue is string enumLiteral) + if(newInstance is PrimitiveType pt) + pt.ObjectValue = objectValue; + else + raiseFormatError($"{node.Name} is a primitive of type {value.GetType()}, but the target POCO is a {newInstance.GetType()}, " + + $"which is not FHIR primitive.", node.Location); + + if (settings?.AllowUnrecognizedEnums == false && + classMapping.EnumType is not null && + objectValue is string enumLiteral) { // Backwards-compatible check for enums. Although our POCOs accept strings rather // than enum values, this check is still useful for catching typos in the data and may diff --git a/src/Hl7.Fhir.Base/ElementModel/PocoElementNode.cs b/src/Hl7.Fhir.Base/ElementModel/PocoElementNode.cs index e263074fea..e32b48d3b8 100644 --- a/src/Hl7.Fhir.Base/ElementModel/PocoElementNode.cs +++ b/src/Hl7.Fhir.Base/ElementModel/PocoElementNode.cs @@ -36,7 +36,7 @@ internal PocoElementNode(ModelInspector inspector, Base root, string rootName = InstanceType = ((IStructureDefinitionSummary)_myClassMapping).TypeName; Definition = ElementDefinitionSummary.ForRoot(_myClassMapping, rootName ?? root.TypeName); - Location = InstanceType; + Location = InstanceType!; ShortPath = InstanceType; } @@ -49,9 +49,9 @@ private PocoElementNode(ModelInspector inspector, Base instance, PocoElementNode var instanceType = definition.Choice != ChoiceType.None ? instance.GetType() : determineInstanceType(definition); - _myClassMapping = _inspector.FindOrImportClassMapping(instanceType); + _myClassMapping = _inspector.FindOrImportClassMapping(instanceType)!; InstanceType = ((IStructureDefinitionSummary)_myClassMapping).TypeName; - Definition = definition ?? throw Error.ArgumentNull(nameof(definition)); + Definition = definition; ExceptionHandler = parent.ExceptionHandler; Location = location; diff --git a/src/Hl7.Fhir.Base/Introspection/PropertyMapping.cs b/src/Hl7.Fhir.Base/Introspection/PropertyMapping.cs index b0a7650d56..d922a469aa 100644 --- a/src/Hl7.Fhir.Base/Introspection/PropertyMapping.cs +++ b/src/Hl7.Fhir.Base/Introspection/PropertyMapping.cs @@ -343,7 +343,8 @@ private ITypeSerializationInfo[] buildTypes() } else if (IsPrimitive) { - throw new NotSupportedException($"Encountered unexpected primitive type {Name} for ITypedElement.InstanceType.") + throw new NotSupportedException( + $"Encountered unexpected primitive type {Name} for ITypedElement.InstanceType."); } else { diff --git a/src/Hl7.Fhir.Base/Model/Base.Dictionary.cs b/src/Hl7.Fhir.Base/Model/Base.Dictionary.cs index 8cbd87fc57..d8b024102a 100644 --- a/src/Hl7.Fhir.Base/Model/Base.Dictionary.cs +++ b/src/Hl7.Fhir.Base/Model/Base.Dictionary.cs @@ -1,3 +1,5 @@ +#if NOT_USED + using System; using System.Collections; using System.Collections.Generic; @@ -46,4 +48,6 @@ IEnumerator IEnumerable.GetEnumerator() => #endregion -} \ No newline at end of file +} + +#endif \ No newline at end of file diff --git a/src/Hl7.Fhir.Base/Model/Base.Extensions.cs b/src/Hl7.Fhir.Base/Model/Base.Extensions.cs index 261b45612c..0a0a33965a 100644 --- a/src/Hl7.Fhir.Base/Model/Base.Extensions.cs +++ b/src/Hl7.Fhir.Base/Model/Base.Extensions.cs @@ -18,11 +18,8 @@ public static IEnumerable Children(this Base instance) case ("div", XHtml xhtml): yield return new FhirString(xhtml.Value); break; - case ("id", string id): - yield return new FhirString(id); - break; - case ("url", string url): - yield return new FhirUri(url); + case ("id", FhirUri id): + yield return new FhirString(id.Value); break; case (_, IEnumerable list): foreach (var item in list) diff --git a/src/Hl7.Fhir.Base/Model/Base.TypedElement.cs b/src/Hl7.Fhir.Base/Model/Base.TypedElement.cs index 3cba3661a3..b1f61ff0b1 100644 --- a/src/Hl7.Fhir.Base/Model/Base.TypedElement.cs +++ b/src/Hl7.Fhir.Base/Model/Base.TypedElement.cs @@ -93,17 +93,13 @@ IEnumerable ITypedElement.Children(string? name) => this.GetElementPairs() .Where(ep => (name == null || name == ep.Key)) .SelectMany, Base>(ep => - (ep.Key, ep.Value) switch + ep.Value switch { - (_, Base b) => (IEnumerable) [b.WithScopeInfo(new ScopeInformation(this, ep.Key, null))], - (_, IEnumerable list) => list.Select((item, idx) => + Base b => (IEnumerable) [b.WithScopeInfo(new ScopeInformation(this, ep.Key, null))], + IEnumerable list => list.Select((item, idx) => item.WithScopeInfo(new ScopeInformation(this, ep.Key, idx))), - ("url", string s) when this is Extension => - [new FhirUri(s).WithScopeInfo(new ScopeInformation(this, ep.Key, null))], - ("id", string s) when this is Element => - [new FhirString(s).WithScopeInfo(new ScopeInformation(this, ep.Key, null))], - ("value", _) => [], - _ => throw new InvalidOperationException("Unexpected system primitive in child list") + _ => throw new InvalidOperationException($"Key '{ep.Key}' has a value with " + + $"unexpected type '{ep.Value.GetType()}'.") } ); @@ -218,14 +214,12 @@ bool IScopedNode.TryResolveContainedEntry(string id, [NotNullWhen(true)] out ISc IEnumerable IScopedNode.Children(string? name) => this.GetElementPairs() .Where(ep => (name == null || name == ep.Key)) .SelectMany, Base>(ep => - (ep.Key, ep.Value) switch + ep.Value switch { - (_, Base b) => (IEnumerable)[b.WithScopeInfo(new ScopeInformation(this, ep.Key, null))], - (_, IEnumerable list) => list.Select((item, idx) => item.WithScopeInfo(new ScopeInformation(this, ep.Key, idx))), - ("url", string s) when this is Extension => [new FhirUri(s).WithScopeInfo(new ScopeInformation(this, ep.Key, null))], - ("id", string s) when this is Element => [new FhirString(s).WithScopeInfo(new ScopeInformation(this, ep.Key, null))], - ("value", _) => [], - _ => throw new InvalidOperationException("Unexpected system primitive in child list") + Base b => (IEnumerable)[b.WithScopeInfo(new ScopeInformation(this, ep.Key, null))], + IEnumerable list => list.Select((item, idx) => item.WithScopeInfo(new ScopeInformation(this, ep.Key, idx))), + _ => throw new InvalidOperationException($"Key '{ep.Key}' has a value with " + + $"unexpected type '{ep.Value.GetType()}'.") } ); diff --git a/src/Hl7.Fhir.Base/Model/Base.cs b/src/Hl7.Fhir.Base/Model/Base.cs index 4a4873687a..8e366b4331 100644 --- a/src/Hl7.Fhir.Base/Model/Base.cs +++ b/src/Hl7.Fhir.Base/Model/Base.cs @@ -30,15 +30,12 @@ POSSIBILITY OF SUCH DAMAGE. #nullable enable using Hl7.Fhir.ElementModel; -using Hl7.Fhir.Introspection; using Hl7.Fhir.Utility; using System; using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Diagnostics.CodeAnalysis; -using System.Linq; -using System.Runtime.Serialization; using System.Threading; namespace Hl7.Fhir.Model; @@ -51,7 +48,6 @@ public abstract partial class Base : IDeepCopyable, IDeepComparable, /// public virtual string TypeName => GetType().Name; - private Dictionary? _overflow = null; /// @@ -71,11 +67,11 @@ public abstract partial class Base : IDeepCopyable, IDeepComparable, public IEnumerable Annotations(Type type) { if (type == typeof(ITypedElement) || type == typeof(IShortPathGenerator) || type == typeof(IScopedNode)) - return new[] { this }; + return [this]; else if (type == typeof(IFhirValueProvider)) - return new[] { this }; + return [this]; else if (type == typeof(IResourceTypeSupplier)) - return new[] { this }; + return [this]; else return annotations.OfType(type); } @@ -100,7 +96,11 @@ internal protected virtual Base SetValue(string key, object? value) if (value is null) Overflow.Remove(key); else + { + if (value is not Base && value is not IReadOnlyList) + throw new InvalidCastException($"Value for key '{key}' must be of type Base or a list of type Base."); Overflow[key] = value; + } return this; } @@ -117,6 +117,4 @@ internal protected virtual bool TryGetValue(string key, [NotNullWhen(true)] out Overflow.TryGetValue(key, out value); internal protected virtual IEnumerable> GetElementPairs() => Overflow; - - // TODO bring Children + NamedChildren over as well. } \ No newline at end of file diff --git a/src/Hl7.Fhir.Base/Model/PrimitiveType.cs b/src/Hl7.Fhir.Base/Model/PrimitiveType.cs index 03ce85beca..05fd3ae6c7 100644 --- a/src/Hl7.Fhir.Base/Model/PrimitiveType.cs +++ b/src/Hl7.Fhir.Base/Model/PrimitiveType.cs @@ -57,36 +57,6 @@ protected virtual void OnObjectValueChanged() return ObjectValue is null ? null : PrimitiveTypeConverter.ConvertTo(ObjectValue); } - /// - internal protected override bool TryGetValue(string key, [NotNullWhen(true)] out object? value) - { - if (key == "value") - { - value = ObjectValue; - return value is not null; - } - else - return base.TryGetValue(key, out value); - } - - internal protected override Base SetValue(string key, object? value) - { - switch (key) - { - case "value": - ObjectValue = value; - return this; - default: - return base.SetValue(key, value); - } - } - /// - internal protected override IEnumerable> GetElementPairs() - { - if (ObjectValue is not null) yield return new KeyValuePair("value", ObjectValue); - foreach (var kvp in base.GetElementPairs()) yield return kvp; - } - /// /// Returns true if the primitive has any child elements (currently in FHIR this can /// be only the element id and zero or more extensions). diff --git a/src/Hl7.Fhir.Base/Serialization/BaseFhirJsonPocoSerializer.cs b/src/Hl7.Fhir.Base/Serialization/BaseFhirJsonPocoSerializer.cs index 18780b92bb..8974e0de54 100644 --- a/src/Hl7.Fhir.Base/Serialization/BaseFhirJsonPocoSerializer.cs +++ b/src/Hl7.Fhir.Base/Serialization/BaseFhirJsonPocoSerializer.cs @@ -13,7 +13,6 @@ using Hl7.Fhir.Specification; using Hl7.Fhir.Utility; using System; -using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; @@ -61,7 +60,7 @@ public BaseFhirJsonPocoSerializer(FhirRelease release, FhirJsonPocoSerializerSet /// Serializes the given dictionary with FHIR data into Json. /// public void Serialize(Base element, Utf8JsonWriter writer) => - serializeInternal(element, writer, skipValue: false); + serializeInternal(element, writer); /// /// Serializes the given dictionary with FHIR data into a Json string. @@ -70,21 +69,28 @@ public string SerializeToString(Base element) { var stream = new MemoryStream(); var writer = new Utf8JsonWriter(stream); - serializeInternal(element, writer, skipValue: false); + serializeInternal(element, writer); writer.Flush(); return Encoding.UTF8.GetString(stream.ToArray()); } /// - /// Serializes the given dictionary with FHIR data into Json, optionally skipping the "value" element. + /// Serializes the given POCO with FHIR data into Json, optionally skipping the "value" element. /// /// Not serializing the "value" element is useful when serializing FHIR primitives into two properties, one /// with just the value, and one with the id/extensions. private void serializeInternal( - Base element, - Utf8JsonWriter writer, - bool skipValue) + Base? element, + Utf8JsonWriter writer + ) { + if (element is null) + { + // empty objects in arrays may occur in error situations. + writer.WriteNullValue(); + return; + } + writer.WriteStartObject(); var filter = Settings.SummaryFilter; @@ -100,8 +106,6 @@ private void serializeInternal( foreach (var member in element.GetElementPairs()) { - if (skipValue && member.Key == "value") continue; - var propertyMapping = mapping?.FindMappedElementByName(member.Key); if (filter?.TryEnterMember(member.Key, member.Value, propertyMapping) == false) @@ -116,25 +120,33 @@ private void serializeInternal( ? (member.Value is Integer64 ? typeof(Integer64) : null) : propertyMapping?.FhirType.FirstOrDefault(); - if (member.Value is PrimitiveType pt) - serializeFhirPrimitive(propertyName, pt, writer, requiredType); - else if (member.Value is IReadOnlyCollection pts) - serializeFhirPrimitiveList(propertyName, pts, writer, requiredType); - else + switch (member.Value) { - writer.WritePropertyName(propertyName); - - if (member.Value is ICollection coll and not byte[]) - { - writer.WriteStartArray(); - - foreach (var value in coll) - serializeMemberValue(value, writer, requiredType); - - writer.WriteEndArray(); - } - else - serializeMemberValue(member.Value, writer, requiredType); + case PrimitiveType pt: + serializeFhirPrimitive(propertyName, pt, writer, requiredType); + break; + case IReadOnlyList pts: + serializeFhirPrimitiveList(propertyName, pts, writer, requiredType); + break; + case IReadOnlyList children: // Not List, since that is an invariant type. + { + writer.WritePropertyName(propertyName); + writer.WriteStartArray(); + + foreach (var child in children) + serializeInternal(child, writer); + + writer.WriteEndArray(); + break; + } + case Base b: + { + writer.WritePropertyName(propertyName); + serializeInternal(b, writer); + break; + } + default: + throw new InvalidOperationException($"GetElementPairs() returned a non-Base element of type {member.Value.GetType()}."); } filter?.LeaveMember(member.Key, member.Value, propertyMapping); @@ -153,15 +165,7 @@ private static string addSuffixToElementName(string elementName, object elementV _ => null }; - return typeName is null ? elementName : elementName + char.ToUpperInvariant(typeName[0]) + typeName.Substring(1); - } - - private void serializeMemberValue(object value, Utf8JsonWriter writer, Type? requiredType = null) - { - if (value is Base complex) - serializeInternal(complex, writer, skipValue: false); - else - SerializePrimitiveValue(value, writer, requiredType); + return typeName is null ? elementName : elementName + char.ToUpperInvariant(typeName[0]) + typeName[1..]; } /// @@ -172,7 +176,7 @@ private void serializeMemberValue(object value, Utf8JsonWriter writer, Type? req /// may use Json nulls as placeholders. private void serializeFhirPrimitiveList( string elementName, - IReadOnlyCollection values, + IReadOnlyList values, Utf8JsonWriter writer, Type? requiredType = null) { @@ -198,7 +202,7 @@ private void serializeFhirPrimitiveList( writeStartArray(elementName, numNullsMissed, writer); } - SerializePrimitiveValue(value!.ObjectValue, writer, requiredType); + SerializePrimitiveValue(value.ObjectValue, writer, requiredType); } else { @@ -228,7 +232,7 @@ private void serializeFhirPrimitiveList( writeStartArray("_" + elementName, numNullsMissed, writer); } - serializeInternal(value, writer, skipValue: true); + serializeInternal(value, writer); } else { @@ -267,12 +271,11 @@ private void serializeFhirPrimitive(string elementName, PrimitiveType value, Utf SerializePrimitiveValue(value.ObjectValue, writer, requiredType); } - if (value.HasElements) - { - // Write a property with '_elementName' - writer.WritePropertyName("_" + elementName); - serializeInternal(value, writer, skipValue: true); - } + if (!value.HasElements) return; + + // Write a property with '_elementName' + writer.WritePropertyName("_" + elementName); + serializeInternal(value, writer); } /// diff --git a/src/Hl7.Fhir.Base/Serialization/BaseFhirXmlPocoSerializer.cs b/src/Hl7.Fhir.Base/Serialization/BaseFhirXmlPocoSerializer.cs index 240e997437..7ce442d299 100644 --- a/src/Hl7.Fhir.Base/Serialization/BaseFhirXmlPocoSerializer.cs +++ b/src/Hl7.Fhir.Base/Serialization/BaseFhirXmlPocoSerializer.cs @@ -14,7 +14,6 @@ using Hl7.Fhir.Specification; using Hl7.Fhir.Utility; using System; -using System.Collections; using System.Collections.Generic; using System.Linq; using System.Xml; @@ -77,10 +76,8 @@ public string SerializeToString( SerializationUtil.WriteXmlToString(element, (o,w) => Serialize(o, w, summary)); /// - /// Serializes the given dictionary with FHIR data into Json, optionally skipping the "value" element. + /// Serializes the given PCO with FHIR data into XML. /// - /// Not serializing the "value" element is useful when serializing FHIR primitives into two properties, one - /// with just the value, and one with the id/extensions. private void serializeInternal( Base element, XmlWriter writer, @@ -106,8 +103,10 @@ private void serializeInternal( private void serializeElement(Base element, XmlWriter writer, SerializationFilter? filter, ClassMapping? mapping) { // Make sure that elements with attributes are serialized first. + // Add the special "value" attribute if this is a FhirPrimitive. var orderedMembers = element .GetElementPairs() + .Concat(element is PrimitiveType { ObjectValue: {} ptValue } ? [KeyValuePair.Create("value", ptValue)] : []) .Select(m => (m, mapping: mapping?.FindMappedElementByName(m.Key))) .OrderBy(p => p.mapping?.SerializationHint != XmlRepresentation.XmlAttr); @@ -129,7 +128,7 @@ private void serializeElement(Base element, XmlWriter writer, SerializationFilte var elementName = propertyMapping?.Choice == ChoiceType.DatatypeChoice ? addSuffixToElementName(mKey, serializeValue) : mKey; - if (serializeValue is ICollection coll and not byte[]) + if (serializeValue is IReadOnlyList coll) { foreach (var value in coll) serializeMemberValue(elementName, value, writer, filter); diff --git a/src/Hl7.Fhir.ElementModel.Shared.Tests/ScopedNodeOnBaseTests.cs b/src/Hl7.Fhir.ElementModel.Shared.Tests/ScopedNodeOnBaseTests.cs index c0cb5a8166..32eace38e4 100644 --- a/src/Hl7.Fhir.ElementModel.Shared.Tests/ScopedNodeOnBaseTests.cs +++ b/src/Hl7.Fhir.ElementModel.Shared.Tests/ScopedNodeOnBaseTests.cs @@ -132,7 +132,7 @@ public void TestResolve() Assert.IsNull(inner7.Resolve("http://nu.nl/3", externalResolve)); Assert.AreEqual("http://nu.nl/3", lastUrlResolved); - IScopedNode? externalResolve(string url) + IScopedNode externalResolve(string url) { lastUrlResolved = url; return null; diff --git a/src/Hl7.Fhir.Serialization.Shared.Tests/SerializationExcexptionHandlersJsonPoco.cs b/src/Hl7.Fhir.Serialization.Shared.Tests/SerializationExcexptionHandlersJsonPoco.cs index b767224fb1..6c4a473c7a 100644 --- a/src/Hl7.Fhir.Serialization.Shared.Tests/SerializationExcexptionHandlersJsonPoco.cs +++ b/src/Hl7.Fhir.Serialization.Shared.Tests/SerializationExcexptionHandlersJsonPoco.cs @@ -591,8 +591,8 @@ public void JsonInvalidElementId() DebugDump.OutputJson(ex.PartialResult); Assert.AreEqual("Patient.birthDate.id", oc.Issue[0].Expression.First()); - Assert.AreEqual(OperationOutcome.IssueSeverity.Fatal, oc.Issue[0].Severity); - Assert.AreEqual("JSON126", oc.Issue[0].Details.Coding[0].Code); + Assert.AreEqual(OperationOutcome.IssueSeverity.Warning, oc.Issue[0].Severity); + Assert.AreEqual("JSON110", oc.Issue[0].Details.Coding[0].Code); Assert.AreEqual(1, oc.Issue.Count); } @@ -799,8 +799,8 @@ public void JsonInvalidElementIdArrayPath() DebugDump.OutputXml(oc); DebugDump.OutputJson(ex.PartialResult); - Assert.AreEqual(OperationOutcome.IssueSeverity.Fatal, oc.Issue[0].Severity); - Assert.AreEqual("JSON126", oc.Issue[0].Details.Coding[0].Code); + Assert.AreEqual(OperationOutcome.IssueSeverity.Warning, oc.Issue[0].Severity); + Assert.AreEqual("JSON110", oc.Issue[0].Details.Coding[0].Code); Assert.AreEqual("Patient.name[0].given[1].id", oc.Issue[0].Expression.First()); Assert.AreEqual(OperationOutcome.IssueSeverity.Fatal, oc.Issue[1].Severity); @@ -1070,4 +1070,4 @@ public void JsonInvalidBundledResources() } } } -} +} \ No newline at end of file diff --git a/src/Hl7.Fhir.Support.Poco.Tests/Model/PocoDictionaryTests.cs b/src/Hl7.Fhir.Support.Poco.Tests/Model/PocoDictionaryTests.cs index f7b761f672..fd68c6c8a5 100644 --- a/src/Hl7.Fhir.Support.Poco.Tests/Model/PocoDictionaryTests.cs +++ b/src/Hl7.Fhir.Support.Poco.Tests/Model/PocoDictionaryTests.cs @@ -46,10 +46,11 @@ public void ResourceAcceptsOverflow() pat["name"] = new List { new HumanName().WithGiven("John") }; // Adding a non-existing property should work - pat["weight"] = 80.0m; + Assert.ThrowsException(() => pat["weight"] = 80.0m); + pat["weight"] = new FhirDecimal(80.0m); pat["name"].Should().BeOfType>(); - pat["weight"].Should().Be(80.0m); + pat["weight"].Should().BeOfType().Which.Value.Should().Be(80.0m); pat["name"] = null!; pat["weight"] = null!; diff --git a/src/Hl7.Fhir.Support.Poco.Tests/NewPocoSerializers/FhirJsonDeserializationTests.cs b/src/Hl7.Fhir.Support.Poco.Tests/NewPocoSerializers/FhirJsonDeserializationTests.cs index 93d788f398..f33a43247a 100644 --- a/src/Hl7.Fhir.Support.Poco.Tests/NewPocoSerializers/FhirJsonDeserializationTests.cs +++ b/src/Hl7.Fhir.Support.Poco.Tests/NewPocoSerializers/FhirJsonDeserializationTests.cs @@ -646,10 +646,9 @@ public void TestRecovery() var recoveredActual = JsonSerializer.Serialize(dfe.PartialResult, options); Console.WriteLine(recoveredActual); - assertErrors(dfe.Exceptions, new string[] - { + assertErrors(dfe.Exceptions, [ ERR.STRING_ISNOTAN_INSTANT_CODE, - ERR.UNKNOWN_PROPERTY_FOUND_CODE, // resourceType at the non-root level + ERR.UNKNOWN_PROPERTY_FOUND_CODE, // resourceType at the non-root level ERR.UNKNOWN_RESOURCE_TYPE_CODE, ERR.RESOURCE_TYPE_NOT_A_RESOURCE_CODE, ERR.RESOURCETYPE_SHOULD_BE_STRING_CODE, ERR.NO_RESOURCETYPE_PROPERTY_CODE, ERR.UNEXPECTED_JSON_TOKEN_CODE, ERR.EXPECTED_START_OF_ARRAY_CODE, @@ -673,7 +672,7 @@ public void TestRecovery() ERR.NUMBER_CANNOT_BE_PARSED_CODE, // multipleBirthInteger should not be a float (3.14) ERR.INCORRECT_BASE64_DATA_CODE, ERR.ARRAYS_CANNOT_BE_EMPTY_CODE, ERR.PROPERTY_MAY_NOT_BE_EMPTY_CODE, ERR.OBJECTS_CANNOT_BE_EMPTY_CODE - }); + ]); var recoveredFilename = Path.Combine("TestData", "fp-test-patient-errors-recovered.json"); var recoveredExpected = File.ReadAllText(recoveredFilename); diff --git a/src/Hl7.Fhir.Support.Tests/Serialization/TestDictionaryImplementation.cs b/src/Hl7.Fhir.Support.Tests/Serialization/TestDictionaryImplementation.cs index 54c4ea99bd..4fa909d50b 100644 --- a/src/Hl7.Fhir.Support.Tests/Serialization/TestDictionaryImplementation.cs +++ b/src/Hl7.Fhir.Support.Tests/Serialization/TestDictionaryImplementation.cs @@ -25,34 +25,25 @@ public void CanEnumerateFhirPrimitive() b.Any().Should().Be(false); b = new FhirBoolean(true).GetElementList(); - b.Count.Should().Be(1); - b.First().Should().BeEquivalentTo(KeyValuePair.Create("value", true)); + b.Any().Should().Be(false); var nb = new FhirBoolean(true); nb.SetStringExtension("http://nu.nl", "then"); nb.ElementId = "id1"; b = nb.GetElementList(); - b.Count.Should().Be(3); - b.Select(kvp => kvp.Key).Should().BeEquivalentTo("value", "id", "extension"); - var values = b.Select(kvp => kvp.Value).ToList(); - values.First().Should().BeOfType(); - values.Skip(1).First().Should().BeOfType(); - values.Skip(2).First().Should().BeAssignableTo>(); - b[2].Value.Should().BeAssignableTo>(); + b.Count.Should().Be(2); + + b[0].Key.Should().Be("id"); + b[0].Value.Should().BeOfType().Which.Value.Should().Be("id1"); + b[1].Key.Should().Be("extension"); + b[1].Value.Should().BeAssignableTo>(); nb.TryGetValue("id", out var v).Should().BeTrue(); - v.Should().Be("id1"); + v.Should().BeOfType().Which.Value.Should().Be("id1"); nb.TryGetValue("idX", out _).Should().BeFalse(); } - [TestMethod] - public void CanEnumerateCodedValue() - { - var b = new Code(Narrative.NarrativeStatus.Additional).GetElementList(); - b.Should().BeEquivalentTo(new[] { KeyValuePair.Create("value", Narrative.NarrativeStatus.Additional.GetLiteral()) }); - } - [TestMethod] public void CanEnumerateNarrative() { @@ -73,7 +64,8 @@ public void CanEnumerateExtension() var ext = new Extension("http://nu.nl", new FhirBoolean(true)); var b = ext.GetElementList(); b.Count.Should().Be(2); - b[0].Should().Be(KeyValuePair.Create("url", "http://nu.nl")); + b[0].Key.Should().Be("url"); + b[0].Value.Should().BeOfType().Which.Value.Should().Be("http://nu.nl"); b[1].Key.Should().Be("value"); b[1].Value.Should().BeOfType().Which.Value.Should().BeTrue();