| File: Serialization\TestCaseConverterV2.cs | Web Access |
| Project: src\vstest\src\Microsoft.TestPlatform.CommunicationUtilities\Microsoft.TestPlatform.CommunicationUtilities.csproj (Microsoft.TestPlatform.CommunicationUtilities) |
// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. #if NETCOREAPP using System; using System.Globalization; using System.Text.Json; using System.Text.Json.Serialization; using Microsoft.VisualStudio.TestPlatform.ObjectModel; namespace Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.Serialization; /// <summary> /// Converter used by v2 protocol serializer to serialize TestCase object to and from v2 json. /// In v2, core properties are flat fields; only custom properties use the Properties array. /// </summary> internal class TestCaseConverterV2 : JsonConverter<TestCase> { /// <inheritdoc/> public override TestCase? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { var testCase = new TestCase(); using var doc = JsonDocument.ParseValue(ref reader); var data = doc.RootElement; if (data.TryGetProperty("FullyQualifiedName", out var fqn)) testCase.FullyQualifiedName = fqn.GetString()!; if (data.TryGetProperty("ExecutorUri", out var uri) && uri.ValueKind != JsonValueKind.Null) testCase.ExecutorUri = new Uri(uri.GetString()!); if (data.TryGetProperty("Source", out var source)) testCase.Source = source.GetString()!; if (data.TryGetProperty("Id", out var id) && id.ValueKind != JsonValueKind.Null) testCase.Id = GuidPolyfill.Parse(id.GetString()!, CultureInfo.InvariantCulture); if (data.TryGetProperty("DisplayName", out var display) && display.ValueKind != JsonValueKind.Null) testCase.DisplayName = display.GetString()!; if (data.TryGetProperty("CodeFilePath", out var codePath) && codePath.ValueKind != JsonValueKind.Null) testCase.CodeFilePath = codePath.GetString(); if (data.TryGetProperty("LineNumber", out var lineNum)) testCase.LineNumber = lineNum.GetInt32(); // Process custom properties (e.g. Traits) if (data.TryGetProperty("Properties", out var properties) && properties.GetArrayLength() > 0) { foreach (var prop in properties.EnumerateArray()) { if (!prop.TryGetProperty("Key", out var keyElement)) continue; var testProperty = StjSafe.Deserialize<TestProperty>(keyElement, options); if (testProperty is null) continue; if (!prop.TryGetProperty("Value", out var valueElement)) continue; string? propertyData = null; if (valueElement.ValueKind != JsonValueKind.Null) { propertyData = valueElement.ValueKind == JsonValueKind.String ? valueElement.GetString() : valueElement.GetRawText().Trim('"'); } testProperty = TestProperty.Register(testProperty.Id, testProperty.Label, testProperty.GetValueType(), testProperty.Attributes, typeof(TestObject)); testCase.SetPropertyValue(testProperty, propertyData); } } return testCase; } /// <inheritdoc/> public override void Write(Utf8JsonWriter writer, TestCase value, JsonSerializerOptions options) { writer.WriteStartObject(); writer.WriteString("Id", value.Id); writer.WriteString("FullyQualifiedName", value.FullyQualifiedName); writer.WriteString("DisplayName", value.DisplayName); writer.WriteString("ExecutorUri", value.ExecutorUri?.OriginalString); writer.WriteString("Source", value.Source); writer.WriteString("CodeFilePath", value.CodeFilePath); writer.WriteNumber("LineNumber", value.LineNumber); // Custom properties (e.g. Traits) — only non-core properties from the store writer.WritePropertyName("Properties"); writer.WriteStartArray(); foreach (var property in value.GetProperties()) { writer.WriteStartObject(); writer.WritePropertyName("Key"); StjSafe.Serialize(writer, property.Key, options); writer.WritePropertyName("Value"); if (property.Value is null) { writer.WriteNullValue(); } else { // Avoid JsonSerializer.Serialize(writer, value, value.GetType(), options) which // requires reflection metadata that NativeAOT trims. TestObjectBaseConverter.WritePropertyValue(writer, property.Value, options); } writer.WriteEndObject(); } writer.WriteEndArray(); writer.WriteEndObject(); } } #endif