Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove usage of System.Text.Json for now #1637

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 0 additions & 1 deletion Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@
<PackageVersion Include="System.Configuration.ConfigurationManager" Version="8.0.0" />
<PackageVersion Include="System.Linq.Async" Version="6.0.1" />
<PackageVersion Include="System.Reflection.Metadata" Version="8.0.0" />
<PackageVersion Include="System.Text.Json" Version="8.0.2" />
<PackageVersion Include="Tmds.ExecFunction" Version="0.7.1" />
<PackageVersion Include="xunit" Version="2.6.6" />
<PackageVersion Include="xunit.assemblyfixture" Version="2.2.0" />
Expand Down
1 change: 1 addition & 0 deletions Documentation/Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Fixed
- Threshold-stat triggers error [#1634](https://github.com/coverlet-coverage/coverlet/issues/1634)
- 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
Expand Down
18 changes: 5 additions & 13 deletions src/coverlet.core/Coverage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -325,7 +317,7 @@ public CoverageResult GetCoverageResult()
{
_logger.LogInformation($"MergeWith: '{_parameters.MergeWith}'.");
string json = _fileSystem.ReadAllText(_parameters.MergeWith);
coverageResult.Merge(JsonSerializer.Deserialize<Modules>(json, _options));
coverageResult.Merge(JsonConvert.DeserializeObject<Modules>(json));
} else
{
_logger.LogInformation($"MergeWith: file '{_parameters.MergeWith}' does not exist.");
Expand Down Expand Up @@ -387,8 +379,8 @@ private void CalculateCoverage()
var documents = result.Documents.Values.ToList();
if (_parameters.UseSourceLink && result.SourceLink != null)
{
JsonNode jObject = JsonNode.Parse(result.SourceLink)["documents"];
Dictionary<string, string> sourceLinkDocuments = JsonSerializer.Deserialize<Dictionary<string, string>>(jObject.ToString());
JToken jObject = JObject.Parse(result.SourceLink)["documents"];
Dictionary<string, string> sourceLinkDocuments = JsonConvert.DeserializeObject<Dictionary<string, string>>(jObject.ToString());
foreach (Document document in documents)
{
document.Path = GetSourceLinkUrl(sourceLinkDocuments, document.Path);
Expand Down
8 changes: 3 additions & 5 deletions src/coverlet.core/CoverageResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

using System.Collections.Generic;
using System.Linq;
using System.Text.Json.Serialization;
using Coverlet.Core.Enums;
using Coverlet.Core.Instrumentation;

Expand All @@ -23,11 +22,10 @@ internal class Branches : List<BranchInfo> { }

internal class Method
{
[JsonConstructor]
public Method()
internal Method()
{
Lines = [];
Branches = [];
Lines = new Lines();
Branches = new Branches();
}

public Lines Lines;
Expand Down
21 changes: 10 additions & 11 deletions src/coverlet.core/Instrumentation/CecilAssemblyResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -298,25 +298,24 @@ public IEnumerable<(string Name, string Version)> GetFrameworks()
{
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<string>(), runtimeOptionsElement["framework"]["version"]?.Value<string>()) };
}

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<string>(), x["version"]?.Value<string>())).ToList();
}

throw new InvalidOperationException($"Unable to read runtime configuration from {_runtimeConfigFile}.");
Expand Down
11 changes: 2 additions & 9 deletions src/coverlet.core/Reporters/JsonReporter.cs
Original file line number Diff line number Diff line change
@@ -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
{
Expand All @@ -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);
}
}
}
2 changes: 1 addition & 1 deletion src/coverlet.core/coverlet.core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<PackageReference Include="Microsoft.Extensions.DependencyInjection" VersionOverride="6.0.1"/>
<PackageReference Include="Mono.Cecil" />
<PackageReference Include="NuGet.Versioning" />
<PackageReference Include="System.Text.Json" VersionOverride="6.0.9"/>
<PackageReference Include="Newtonsoft.Json" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' != 'netstandard2.0'">
Expand Down
68 changes: 25 additions & 43 deletions test/coverlet.core.tests/Coverage/CoverageTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,23 @@
// 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
{
public partial class CoverageTests
{
private readonly Mock<ILogger> _mockLogger = new();
readonly JsonSerializerOptions _options = new()
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
IncludeFields = true,
WriteIndented = true,
Converters =
{
new BranchDictionaryConverterFactory()
}
};

[Fact]
public void TestCoverage()
Expand Down Expand Up @@ -102,7 +91,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);

Expand Down Expand Up @@ -141,7 +130,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);

Expand Down Expand Up @@ -182,51 +171,44 @@ 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<string>(v => v.Equals("MergeWith: file 'FileDoesNotExist.json' does not exist.")), It.IsAny<bool>()), Times.Once);

directory.Delete(true);
}
}
}
public class BranchDictionaryConverterFactory : JsonConverterFactory
{
public override bool CanConvert(Type typeToConvert)
{
return typeof(Dictionary<BranchKey, Branch>).IsAssignableFrom(typeToConvert);
}

public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options)
public class BranchDictionaryConverter: JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
Type[] genericArgs = typeToConvert.GetGenericArguments();
Type keyType = genericArgs[0];
Type valueType = genericArgs[1];
Type type = value.GetType();
var keys = (IEnumerable)type.GetProperty("Keys")?.GetValue(value, null);
var 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<TKey, TValue> : JsonConverter<Dictionary<TKey, TValue>>
{
public override Dictionary<TKey, TValue> 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<TKey, TValue> value, JsonSerializerOptions options)
public override bool CanConvert(Type objectType)
{
writer.WriteStartObject();

foreach (KeyValuePair<TKey, TValue> pair in value)
{
writer.WritePropertyName(pair.Key.ToString());
JsonSerializer.Serialize(writer, pair.Value, options);
}

writer.WriteEndObject();
return typeof(Dictionary<BranchKey, Branch>).IsAssignableFrom(objectType);
}
}