From ae684988963b93a6ca6f3237564978d141c08381 Mon Sep 17 00:00:00 2001 From: "David Mueller x." Date: Thu, 29 Feb 2024 20:36:37 +0100 Subject: [PATCH 1/4] started moving back to newtonsoft json --- Directory.Packages.props | 1 - src/coverlet.core/Coverage.cs | 24 ++++---- src/coverlet.core/CoverageResult.cs | 8 +-- src/coverlet.core/Reporters/JsonReporter.cs | 11 +--- src/coverlet.core/coverlet.core.csproj | 2 +- .../Coverage/CoverageTests.cs | 58 +++++++++---------- 6 files changed, 44 insertions(+), 60 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 580a1c491..6c94f40a1 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -44,7 +44,6 @@ - diff --git a/src/coverlet.core/Coverage.cs b/src/coverlet.core/Coverage.cs index 3e0f46216..7fd2307a6 100644 --- a/src/coverlet.core/Coverage.cs +++ b/src/coverlet.core/Coverage.cs @@ -6,8 +6,8 @@ using System.IO; using System.Linq; using System.Runtime.Serialization; -using System.Text.Json; -using System.Text.Json.Nodes; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using Coverlet.Core.Abstractions; using Coverlet.Core.Helpers; using Coverlet.Core.Instrumentation; @@ -60,13 +60,13 @@ internal class Coverage public string Identifier { get; } - readonly JsonSerializerOptions _options = new() - { - PropertyNameCaseInsensitive = true, - DictionaryKeyPolicy = JsonNamingPolicy.CamelCase, - IncludeFields = true, - WriteIndented = true - }; + //readonly JsonSerializerOptions _options = new() + //{ + // PropertyNameCaseInsensitive = true, + // DictionaryKeyPolicy = JsonNamingPolicy.CamelCase, + // IncludeFields = true, + // WriteIndented = true + //}; public Coverage(string moduleOrDirectory, CoverageParameters parameters, @@ -325,7 +325,7 @@ public CoverageResult GetCoverageResult() { _logger.LogInformation($"MergeWith: '{_parameters.MergeWith}'."); string json = _fileSystem.ReadAllText(_parameters.MergeWith); - coverageResult.Merge(JsonSerializer.Deserialize(json, _options)); + coverageResult.Merge(JsonConvert.DeserializeObject(json)); } else { _logger.LogInformation($"MergeWith: file '{_parameters.MergeWith}' does not exist."); @@ -387,8 +387,8 @@ private void CalculateCoverage() var documents = result.Documents.Values.ToList(); if (_parameters.UseSourceLink && result.SourceLink != null) { - JsonNode jObject = JsonNode.Parse(result.SourceLink)["documents"]; - Dictionary sourceLinkDocuments = JsonSerializer.Deserialize>(jObject.ToString()); + JToken jObject = JObject.Parse(result.SourceLink)["documents"]; + Dictionary sourceLinkDocuments = JsonConvert.DeserializeObject>(jObject.ToString()); foreach (Document document in documents) { document.Path = GetSourceLinkUrl(sourceLinkDocuments, document.Path); diff --git a/src/coverlet.core/CoverageResult.cs b/src/coverlet.core/CoverageResult.cs index c547f6a40..00a64568c 100644 --- a/src/coverlet.core/CoverageResult.cs +++ b/src/coverlet.core/CoverageResult.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Linq; -using System.Text.Json.Serialization; using Coverlet.Core.Enums; using Coverlet.Core.Instrumentation; @@ -23,11 +22,10 @@ internal class Branches : List { } internal class Method { - [JsonConstructor] - public Method() + internal Method() { - Lines = []; - Branches = []; + Lines = new Lines(); + Branches = new Branches(); } public Lines Lines; diff --git a/src/coverlet.core/Reporters/JsonReporter.cs b/src/coverlet.core/Reporters/JsonReporter.cs index 62be3373a..e684e8c8a 100644 --- a/src/coverlet.core/Reporters/JsonReporter.cs +++ b/src/coverlet.core/Reporters/JsonReporter.cs @@ -1,9 +1,8 @@ // Copyright (c) Toni Solarin-Sodara // Licensed under the MIT license. See LICENSE file in the project root for full license information. -using System.Text.Encodings.Web; -using System.Text.Json; using Coverlet.Core.Abstractions; +using Newtonsoft.Json; namespace Coverlet.Core.Reporters { @@ -17,13 +16,7 @@ internal class JsonReporter : IReporter public string Report(CoverageResult result, ISourceRootTranslator _) { - var options = new JsonSerializerOptions - { - Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, - IncludeFields = true, - WriteIndented = true, - }; - return JsonSerializer.Serialize(result.Modules, options); + return JsonConvert.SerializeObject(result.Modules, Formatting.Indented); } } } diff --git a/src/coverlet.core/coverlet.core.csproj b/src/coverlet.core/coverlet.core.csproj index 77ef61484..fd4fe2c2b 100644 --- a/src/coverlet.core/coverlet.core.csproj +++ b/src/coverlet.core/coverlet.core.csproj @@ -13,7 +13,7 @@ - + diff --git a/test/coverlet.core.tests/Coverage/CoverageTests.cs b/test/coverlet.core.tests/Coverage/CoverageTests.cs index 25761f83d..3c7084bf2 100644 --- a/test/coverlet.core.tests/Coverage/CoverageTests.cs +++ b/test/coverlet.core.tests/Coverage/CoverageTests.cs @@ -2,17 +2,18 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; +using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text.Encodings.Web; using System.Text.Json; -using System.Text.Json.Serialization; using Coverlet.Core.Abstractions; using Coverlet.Core.Helpers; using Coverlet.Core.Instrumentation; using Coverlet.Core.Symbols; using Moq; +using Newtonsoft.Json; using Xunit; namespace Coverlet.Core.Tests @@ -27,7 +28,7 @@ public partial class CoverageTests WriteIndented = true, Converters = { - new BranchDictionaryConverterFactory() + //new BranchDictionaryConverterFactory() } }; @@ -102,7 +103,7 @@ public void TestCoverageWithTestAssembly() new SourceRootTranslator(module, _mockLogger.Object, new FileSystem(), new AssemblyAdapter()), new CecilSymbolHelper()); coverage.PrepareModules(); - string result = JsonSerializer.Serialize(coverage.GetCoverageResult(), _options); + string result = JsonConvert.SerializeObject(coverage.GetCoverageResult(), Formatting.Indented, new BranchDictionaryConverter()); Assert.Contains("coverlet.core.tests.dll", result); @@ -141,7 +142,7 @@ public void TestCoverageMergeWithParameter() var coverage = new Coverage(Path.Combine(directory.FullName, Path.GetFileName(module)), parameters, _mockLogger.Object, instrumentationHelper, new FileSystem(), new SourceRootTranslator(_mockLogger.Object, new FileSystem()), new CecilSymbolHelper()); coverage.PrepareModules(); - string result = JsonSerializer.Serialize(coverage.GetCoverageResult(), _options); + string result = JsonConvert.SerializeObject(coverage.GetCoverageResult(), Formatting.Indented, new BranchDictionaryConverter()); Assert.Contains("DeepThought.cs", result); @@ -182,7 +183,7 @@ public void TestCoverageMergeWithWrongParameter() var coverage = new Coverage(Path.Combine(directory.FullName, Path.GetFileName(module)), parameters, _mockLogger.Object, instrumentationHelper, new FileSystem(), new SourceRootTranslator(_mockLogger.Object, new FileSystem()), new CecilSymbolHelper()); coverage.PrepareModules(); - string result = JsonSerializer.Serialize(coverage.GetCoverageResult(), _options); + JsonConvert.SerializeObject(coverage.GetCoverageResult()); _mockLogger.Verify(l => l.LogInformation(It.Is(v => v.Equals("MergeWith: file 'FileDoesNotExist.json' does not exist.")), It.IsAny()), Times.Once); @@ -190,43 +191,36 @@ public void TestCoverageMergeWithWrongParameter() } } } -public class BranchDictionaryConverterFactory : JsonConverterFactory -{ - public override bool CanConvert(Type typeToConvert) - { - return typeof(Dictionary).IsAssignableFrom(typeToConvert); - } - public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) +public class BranchDictionaryConverter: JsonConverter +{ + public override void WriteJson(JsonWriter writer, object? value, Newtonsoft.Json.JsonSerializer serializer) { - Type[] genericArgs = typeToConvert.GetGenericArguments(); - Type keyType = genericArgs[0]; - Type valueType = genericArgs[1]; + Type type = value.GetType(); + IEnumerable keys = (IEnumerable)type.GetProperty("Keys").GetValue(value, null); + IEnumerable values = (IEnumerable)type.GetProperty("Values").GetValue(value, null); + IEnumerator valueEnumerator = values.GetEnumerator(); - JsonConverter converter = (JsonConverter)Activator.CreateInstance( - typeof(BranchDictionaryConverter<,>).MakeGenericType(new Type[] { keyType, valueType })); + writer.WriteStartArray(); + foreach (object key in keys) + { + valueEnumerator.MoveNext(); - return converter; + writer.WriteStartArray(); + serializer.Serialize(writer, key); + serializer.Serialize(writer, valueEnumerator.Current); + writer.WriteEndArray(); + } + writer.WriteEndArray(); } -} -public class BranchDictionaryConverter : JsonConverter> -{ - public override Dictionary Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, Newtonsoft.Json.JsonSerializer serializer) { throw new NotImplementedException(); } - public override void Write(Utf8JsonWriter writer, Dictionary value, JsonSerializerOptions options) + public override bool CanConvert(Type objectType) { - writer.WriteStartObject(); - - foreach (KeyValuePair pair in value) - { - writer.WritePropertyName(pair.Key.ToString()); - JsonSerializer.Serialize(writer, pair.Value, options); - } - - writer.WriteEndObject(); + return typeof(Dictionary).IsAssignableFrom(objectType); } } From 87c56cafd43271a6d1df62f71c295b84b4704e3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20M=C3=BCller?= Date: Sat, 2 Mar 2024 23:20:20 +0100 Subject: [PATCH 2/4] removed system text json --- src/coverlet.core/Coverage.cs | 8 ----- .../Instrumentation/CecilAssemblyResolver.cs | 21 +++++++------ .../Coverage/CoverageTests.cs | 30 +++++++++---------- 3 files changed, 24 insertions(+), 35 deletions(-) diff --git a/src/coverlet.core/Coverage.cs b/src/coverlet.core/Coverage.cs index 7fd2307a6..e057a09bb 100644 --- a/src/coverlet.core/Coverage.cs +++ b/src/coverlet.core/Coverage.cs @@ -60,14 +60,6 @@ internal class Coverage public string Identifier { get; } - //readonly JsonSerializerOptions _options = new() - //{ - // PropertyNameCaseInsensitive = true, - // DictionaryKeyPolicy = JsonNamingPolicy.CamelCase, - // IncludeFields = true, - // WriteIndented = true - //}; - public Coverage(string moduleOrDirectory, CoverageParameters parameters, ILogger logger, diff --git a/src/coverlet.core/Instrumentation/CecilAssemblyResolver.cs b/src/coverlet.core/Instrumentation/CecilAssemblyResolver.cs index c8e0a4109..49790660e 100644 --- a/src/coverlet.core/Instrumentation/CecilAssemblyResolver.cs +++ b/src/coverlet.core/Instrumentation/CecilAssemblyResolver.cs @@ -5,12 +5,12 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using System.Text.Json; using Coverlet.Core.Abstractions; using Coverlet.Core.Exceptions; using Microsoft.Extensions.DependencyModel; using Microsoft.Extensions.DependencyModel.Resolution; using Mono.Cecil; +using Newtonsoft.Json.Linq; using NuGet.Versioning; namespace Coverlet.Core.Instrumentation @@ -298,25 +298,24 @@ public RuntimeConfigurationReader(string runtimeConfigFile) { string jsonString = File.ReadAllText(_runtimeConfigFile); - var documentOptions = new JsonDocumentOptions + var jsonLoadSettings = new JsonLoadSettings() { - CommentHandling = JsonCommentHandling.Skip + CommentHandling = CommentHandling.Ignore }; - using var configuration = JsonDocument.Parse(jsonString, documentOptions); + var configuration = JObject.Parse(jsonString, jsonLoadSettings); - JsonElement rootElement = configuration.RootElement; + JToken rootElement = configuration.Root; + JToken runtimeOptionsElement = rootElement["runtimeOptions"]; - JsonElement runtimeOptionsElement = rootElement.GetProperty("runtimeOptions"); - - if (runtimeOptionsElement.TryGetProperty("framework", out JsonElement frameworkElement)) + if (runtimeOptionsElement?["framework"] != null) { - return new[] { (frameworkElement.GetProperty("name").GetString(), frameworkElement.GetProperty("version").GetString()) }; + return new[] { (runtimeOptionsElement["framework"]["name"]?.Value(), runtimeOptionsElement["framework"]["version"]?.Value()) }; } - if (runtimeOptionsElement.TryGetProperty("frameworks", out JsonElement frameworksElement)) + if (runtimeOptionsElement?["frameworks"] != null) { - return frameworksElement.EnumerateArray().Select(x => (x.GetProperty("name").GetString(), x.GetProperty("version").GetString())).ToList(); + return runtimeOptionsElement["frameworks"].Select(x => (x["name"]?.Value(), x["version"]?.Value())).ToList(); } throw new InvalidOperationException($"Unable to read runtime configuration from {_runtimeConfigFile}."); diff --git a/test/coverlet.core.tests/Coverage/CoverageTests.cs b/test/coverlet.core.tests/Coverage/CoverageTests.cs index 3c7084bf2..80343b2d9 100644 --- a/test/coverlet.core.tests/Coverage/CoverageTests.cs +++ b/test/coverlet.core.tests/Coverage/CoverageTests.cs @@ -6,8 +6,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using System.Text.Encodings.Web; -using System.Text.Json; using Coverlet.Core.Abstractions; using Coverlet.Core.Helpers; using Coverlet.Core.Instrumentation; @@ -21,16 +19,16 @@ namespace Coverlet.Core.Tests public partial class CoverageTests { private readonly Mock _mockLogger = new(); - readonly JsonSerializerOptions _options = new() - { - Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, - IncludeFields = true, - WriteIndented = true, - Converters = - { - //new BranchDictionaryConverterFactory() - } - }; + //readonly JsonSerializerOptions _options = new() + //{ + // Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, + // IncludeFields = true, + // WriteIndented = true, + // Converters = + // { + // //new BranchDictionaryConverterFactory() + // } + //}; [Fact] public void TestCoverage() @@ -194,11 +192,11 @@ public void TestCoverageMergeWithWrongParameter() public class BranchDictionaryConverter: JsonConverter { - public override void WriteJson(JsonWriter writer, object? value, Newtonsoft.Json.JsonSerializer serializer) + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { Type type = value.GetType(); - IEnumerable keys = (IEnumerable)type.GetProperty("Keys").GetValue(value, null); - IEnumerable values = (IEnumerable)type.GetProperty("Values").GetValue(value, null); + var keys = (IEnumerable)type.GetProperty("Keys")?.GetValue(value, null); + var values = (IEnumerable)type.GetProperty("Values")?.GetValue(value, null); IEnumerator valueEnumerator = values.GetEnumerator(); writer.WriteStartArray(); @@ -214,7 +212,7 @@ public override void WriteJson(JsonWriter writer, object? value, Newtonsoft.Json writer.WriteEndArray(); } - public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, Newtonsoft.Json.JsonSerializer serializer) + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer) { throw new NotImplementedException(); } From 7e6afb9ba7df28af8b33c1b82b6047ad4d9cd205 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20M=C3=BCller?= Date: Sat, 2 Mar 2024 23:23:23 +0100 Subject: [PATCH 3/4] update change log --- Documentation/Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/Changelog.md b/Documentation/Changelog.md index 18851252f..eb9ec0bb9 100644 --- a/Documentation/Changelog.md +++ b/Documentation/Changelog.md @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased ### Fixed +- Fixed coverlet collector 6.0.1 requires dotnet sdk 8 [#1625](https://github.com/coverlet-coverage/coverlet/issues/1625) - Exception when multiple exclude-by-attribute filters specified [#1624](https://github.com/coverlet-coverage/coverlet/issues/1624) ### Improvements From 2411083a59cf2982a3ad5baf20aa915552c12659 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20M=C3=BCller?= Date: Sat, 2 Mar 2024 23:27:19 +0100 Subject: [PATCH 4/4] nit --- test/coverlet.core.tests/Coverage/CoverageTests.cs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/test/coverlet.core.tests/Coverage/CoverageTests.cs b/test/coverlet.core.tests/Coverage/CoverageTests.cs index 80343b2d9..701df8f30 100644 --- a/test/coverlet.core.tests/Coverage/CoverageTests.cs +++ b/test/coverlet.core.tests/Coverage/CoverageTests.cs @@ -19,16 +19,6 @@ namespace Coverlet.Core.Tests public partial class CoverageTests { private readonly Mock _mockLogger = new(); - //readonly JsonSerializerOptions _options = new() - //{ - // Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, - // IncludeFields = true, - // WriteIndented = true, - // Converters = - // { - // //new BranchDictionaryConverterFactory() - // } - //}; [Fact] public void TestCoverage()