Skip to content

Commit ac777b6

Browse files
committed
Migrate some tests from Newtonsoft.Json to System.Text.Json
1 parent 1cfb7b2 commit ac777b6

File tree

10 files changed

+63
-38
lines changed

10 files changed

+63
-38
lines changed
Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
namespace Microsoft.ComponentDetection.Detectors.Pip;
22

3+
using System.Text.Json.Serialization;
34
using Newtonsoft.Json;
45

56
/// <summary>
@@ -12,68 +13,79 @@ public sealed record PipInstallationMetadata
1213
/// Version of the file format; legal values are "1.0", "1.1", "1.2", "2.1", "2.2", and "2.3"
1314
/// as of May 2024.
1415
/// </summary>
16+
[JsonPropertyName("metadata_version")]
1517
[JsonProperty("metadata_version")]
1618
public string MetadataVersion { get; set; }
1719

1820
/// <summary>
1921
/// The name of the distribution.
2022
/// </summary>
23+
[JsonPropertyName("name")]
2124
[JsonProperty("name")]
2225
public string Name { get; set; }
2326

2427
/// <summary>
25-
/// A string containing the distributions version number.
28+
/// A string containing the distribution's version number.
2629
/// </summary>
30+
[JsonPropertyName("version")]
2731
[JsonProperty("version")]
2832
public string Version { get; set; }
2933

3034
/// <summary>
3135
/// Each entry contains a string naming some other distutils project required by this distribution.
3236
/// See https://peps.python.org/pep-0508/ for the format of the strings.
3337
/// </summary>
38+
[JsonPropertyName("requires_dist")]
3439
[JsonProperty("requires_dist")]
3540
public string[] RequiresDist { get; set; }
3641

3742
/// <summary>
38-
/// URL for the distributions home page.
43+
/// URL for the distribution's home page.
3944
/// </summary>
45+
[JsonPropertyName("home_page")]
4046
[JsonProperty("home_page")]
4147
public string HomePage { get; set; }
4248

4349
/// <summary>
44-
/// Maintainers name at a minimum; additional contact information may be provided.
50+
/// Maintainer's name at a minimum; additional contact information may be provided.
4551
/// </summary>
52+
[JsonPropertyName("maintainer")]
4653
[JsonProperty("maintainer")]
4754
public string Maintainer { get; set; }
4855

4956
/// <summary>
50-
/// Maintainers e-mail address. It can contain a name and e-mail address in the legal forms for a RFC-822 From: header.
57+
/// Maintainer's e-mail address. It can contain a name and e-mail address in the legal forms for a RFC-822 From: header.
5158
/// </summary>
59+
[JsonPropertyName("maintainer_email")]
5260
[JsonProperty("maintainer_email")]
5361
public string MaintainerEmail { get; set; }
5462

5563
/// <summary>
56-
/// Authors name at a minimum; additional contact information may be provided.
64+
/// Author's name at a minimum; additional contact information may be provided.
5765
/// </summary>
66+
[JsonPropertyName("author")]
5867
[JsonProperty("author")]
5968
public string Author { get; set; }
6069

6170
/// <summary>
62-
/// Authors e-mail address. It can contain a name and e-mail address in the legal forms for a RFC-822 From: header.
71+
/// Author's e-mail address. It can contain a name and e-mail address in the legal forms for a RFC-822 From: header.
6372
/// </summary>
73+
[JsonPropertyName("author_email")]
6474
[JsonProperty("author_email")]
6575
public string AuthorEmail { get; set; }
6676

6777
/// <summary>
6878
/// Text indicating the license covering the distribution.
6979
/// </summary>
80+
[JsonPropertyName("license")]
7081
[JsonProperty("license")]
7182
public string License { get; set; }
7283

7384
/// <summary>
7485
/// Each entry is a string giving a single classification value for the distribution.
7586
/// Classifiers are described in PEP 301 https://peps.python.org/pep-0301/.
7687
/// </summary>
88+
[JsonPropertyName("classifier")]
7789
[JsonProperty("classifier")]
7890
public string[] Classifier { get; set; }
7991
}

src/Microsoft.ComponentDetection.Detectors/pip/Contracts/PipInstallationReport.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
namespace Microsoft.ComponentDetection.Detectors.Pip;
22

33
using System.Collections.Generic;
4+
using System.Text.Json.Serialization;
45
using Newtonsoft.Json;
56

67
/// <summary>
@@ -11,24 +12,28 @@ public sealed record PipInstallationReport
1112
/// <summary>
1213
/// Version of the installation report specification. Currently 1, but will be incremented if the format changes.
1314
/// </summary>
15+
[JsonPropertyName("version")]
1416
[JsonProperty("version")]
1517
public string Version { get; set; }
1618

1719
/// <summary>
1820
/// Version of pip used to produce the report.
1921
/// </summary>
22+
[JsonPropertyName("pip_version")]
2023
[JsonProperty("pip_version")]
2124
public string PipVersion { get; set; }
2225

2326
/// <summary>
2427
/// Distribution packages (to be) installed.
2528
/// </summary>
29+
[JsonPropertyName("install")]
2630
[JsonProperty("install")]
2731
public PipInstallationReportItem[] InstallItems { get; set; }
2832

2933
/// <summary>
3034
/// Environment metadata for the report. See https://peps.python.org/pep-0508/#environment-markers.
3135
/// </summary>
36+
[JsonPropertyName("environment")]
3237
[JsonProperty("environment")]
3338
public IDictionary<string, string> Environment { get; set; }
3439
}

src/Microsoft.ComponentDetection.Detectors/pip/Contracts/PipInstallationReportItem.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,30 @@
11
namespace Microsoft.ComponentDetection.Detectors.Pip;
22

3+
using System.Text.Json.Serialization;
34
using Newtonsoft.Json;
45
using Newtonsoft.Json.Linq;
6+
using JsonIgnoreAttribute = System.Text.Json.Serialization.JsonIgnoreAttribute;
57

68
public sealed record PipInstallationReportItem
79
{
810
/// <summary>
911
/// The metadata of the distribution.
1012
/// </summary>
13+
[JsonPropertyName("metadata")]
1114
[JsonProperty("metadata")]
1215
public PipInstallationMetadata Metadata { get; set; }
1316

1417
/// <summary>
1518
/// true if the requirement was provided as, or constrained to, a direct URL reference. false if the requirements was provided as a name and version specifier.
1619
/// </summary>
20+
[JsonPropertyName("is_direct")]
1721
[JsonProperty("is_direct")]
1822
public bool IsDirect { get; set; }
1923

2024
/// <summary>
2125
/// true if the requirement was yanked from the index, but was still selected by pip conform.
2226
/// </summary>
27+
[JsonPropertyName("is_yanked")]
2328
[JsonProperty("is_yanked")]
2429
public bool IsYanked { get; set; }
2530

@@ -28,18 +33,21 @@ public sealed record PipInstallationReportItem
2833
/// a command line argument or indirectly via a requirements file. false if the requirement
2934
/// was installed as a dependency of another requirement.
3035
/// </summary>
36+
[JsonPropertyName("requested")]
3137
[JsonProperty("requested")]
3238
public bool Requested { get; set; }
3339

3440
/// <summary>
3541
/// See https://packaging.python.org/en/latest/specifications/direct-url-data-structure/.
3642
/// </summary>
43+
[JsonIgnore]
3744
[JsonProperty("download_info")]
3845
public JObject DownloadInfo { get; set; }
3946

4047
/// <summary>
4148
/// Extras requested by the user.
4249
/// </summary>
50+
[JsonIgnore]
4351
[JsonProperty("requested_extras")]
4452
public JArray RequestedExtras { get; set; }
4553
}

test/Microsoft.ComponentDetection.Detectors.Tests/PipReportComponentDetectorTests.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ namespace Microsoft.ComponentDetection.Detectors.Tests;
44
using System.Collections.Generic;
55
using System.IO;
66
using System.Linq;
7+
using System.Text.Json;
78
using System.Threading;
89
using System.Threading.Tasks;
910
using AwesomeAssertions;
@@ -17,7 +18,6 @@ namespace Microsoft.ComponentDetection.Detectors.Tests;
1718
using Microsoft.Extensions.Logging;
1819
using Microsoft.VisualStudio.TestTools.UnitTesting;
1920
using Moq;
20-
using Newtonsoft.Json;
2121

2222
[TestClass]
2323
public class PipReportComponentDetectorTests : BaseDetectorTest<PipReportComponentDetector>
@@ -63,12 +63,12 @@ public PipReportComponentDetectorTests()
6363
this.pipCommandService.Setup(x => x.GetPipVersionAsync(It.IsAny<string>(), It.IsAny<string>()))
6464
.ReturnsAsync(new Version(23, 0, 0));
6565

66-
this.singlePackageReport = JsonConvert.DeserializeObject<PipInstallationReport>(TestResources.pip_report_single_pkg);
67-
this.singlePackageReportBadVersion = JsonConvert.DeserializeObject<PipInstallationReport>(TestResources.pip_report_single_pkg_bad_version);
68-
this.singlePackageReportInvalidPkgVersion = JsonConvert.DeserializeObject<PipInstallationReport>(TestResources.pip_report_single_pkg_invalid_pkg_version);
69-
this.multiPackageReport = JsonConvert.DeserializeObject<PipInstallationReport>(TestResources.pip_report_multi_pkg);
70-
this.jupyterPackageReport = JsonConvert.DeserializeObject<PipInstallationReport>(TestResources.pip_report_jupyterlab);
71-
this.simpleExtrasReport = JsonConvert.DeserializeObject<PipInstallationReport>(TestResources.pip_report_simple_extras);
66+
this.singlePackageReport = JsonSerializer.Deserialize<PipInstallationReport>(TestResources.pip_report_single_pkg);
67+
this.singlePackageReportBadVersion = JsonSerializer.Deserialize<PipInstallationReport>(TestResources.pip_report_single_pkg_bad_version);
68+
this.singlePackageReportInvalidPkgVersion = JsonSerializer.Deserialize<PipInstallationReport>(TestResources.pip_report_single_pkg_invalid_pkg_version);
69+
this.multiPackageReport = JsonSerializer.Deserialize<PipInstallationReport>(TestResources.pip_report_multi_pkg);
70+
this.jupyterPackageReport = JsonSerializer.Deserialize<PipInstallationReport>(TestResources.pip_report_jupyterlab);
71+
this.simpleExtrasReport = JsonSerializer.Deserialize<PipInstallationReport>(TestResources.pip_report_simple_extras);
7272
}
7373

7474
[TestMethod]

test/Microsoft.ComponentDetection.Detectors.Tests/PyPiClientTests.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ namespace Microsoft.ComponentDetection.Detectors.Tests;
66
using System.Linq;
77
using System.Net;
88
using System.Net.Http;
9+
using System.Text.Json;
910
using System.Threading;
1011
using System.Threading.Tasks;
1112
using AwesomeAssertions;
@@ -16,7 +17,6 @@ namespace Microsoft.ComponentDetection.Detectors.Tests;
1617
using Microsoft.VisualStudio.TestTools.UnitTesting;
1718
using Moq;
1819
using Moq.Protected;
19-
using Newtonsoft.Json;
2020

2121
[TestClass]
2222
public class PyPiClientTests
@@ -40,7 +40,7 @@ public async Task GetReleases_InvalidSpecVersion_NotThrowAsync()
4040
},
4141
};
4242

43-
var mockHandler = this.MockHttpMessageHandler(JsonConvert.SerializeObject(pythonProject));
43+
var mockHandler = this.MockHttpMessageHandler(JsonSerializer.Serialize(pythonProject));
4444
PyPiClient.HttpClient = new HttpClient(mockHandler.Object);
4545

4646
Func<Task> action = async () => await this.pypiClient.GetProjectAsync(pythonSpecs);
@@ -63,7 +63,7 @@ public async Task GetProject_SupportsReleaseCandidatesDependenciesAsync()
6363
},
6464
};
6565

66-
var mockHandler = this.MockHttpMessageHandler(JsonConvert.SerializeObject(pythonProject));
66+
var mockHandler = this.MockHttpMessageHandler(JsonSerializer.Serialize(pythonProject));
6767
PyPiClient.HttpClient = new HttpClient(mockHandler.Object);
6868

6969
var result = await this.pypiClient.GetProjectAsync(pythonSpecs);
@@ -83,7 +83,7 @@ public async Task GetReleases_DuplicateEntries_CallsGetAsync_OnceAsync()
8383
},
8484
};
8585

86-
var mockHandler = this.MockHttpMessageHandler(JsonConvert.SerializeObject(pythonProject));
86+
var mockHandler = this.MockHttpMessageHandler(JsonSerializer.Serialize(pythonProject));
8787
PyPiClient.HttpClient = new HttpClient(mockHandler.Object);
8888

8989
Func<Task> action = async () => await this.pypiClient.GetProjectAsync(pythonSpecs);
@@ -111,7 +111,7 @@ public async Task GetReleases_DifferentEntries_CallsGetAsync_OnceAsync()
111111
},
112112
};
113113

114-
var mockHandler = this.MockHttpMessageHandler(JsonConvert.SerializeObject(pythonProject));
114+
var mockHandler = this.MockHttpMessageHandler(JsonSerializer.Serialize(pythonProject));
115115
PyPiClient.HttpClient = new HttpClient(mockHandler.Object);
116116

117117
Func<Task> action = async () =>
@@ -123,7 +123,7 @@ public async Task GetReleases_DifferentEntries_CallsGetAsync_OnceAsync()
123123
await action.Should().NotThrowAsync();
124124
await action.Should().NotThrowAsync();
125125

126-
// Verify the API call was performed only once
126+
// Verify the API call was performed twice
127127
mockHandler.Protected().Verify(
128128
"SendAsync",
129129
Times.Exactly(2),
@@ -181,7 +181,7 @@ public async Task GetReleases_MaxEntriesVariable_CreatesNewCacheAsync()
181181
},
182182
};
183183

184-
var mockHandler = this.MockHttpMessageHandler(JsonConvert.SerializeObject(pythonProject));
184+
var mockHandler = this.MockHttpMessageHandler(JsonSerializer.Serialize(pythonProject));
185185
PyPiClient.HttpClient = new HttpClient(mockHandler.Object);
186186

187187
var mockLogger = new Mock<ILogger<PyPiClient>>();
@@ -221,7 +221,7 @@ public async Task GetReleases_AddsUserAgentHeadersAsync()
221221
},
222222
};
223223

224-
var mockHandler = this.MockHttpMessageHandler(JsonConvert.SerializeObject(pythonProject));
224+
var mockHandler = this.MockHttpMessageHandler(JsonSerializer.Serialize(pythonProject));
225225
PyPiClient.HttpClient = new HttpClient(mockHandler.Object);
226226

227227
var action = async () => await this.pypiClient.GetProjectAsync(pythonSpecs);

test/Microsoft.ComponentDetection.Detectors.Tests/SimplePipComponentDetectorTests.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ namespace Microsoft.ComponentDetection.Detectors.Tests;
44
using System.Collections.Generic;
55
using System.IO;
66
using System.Linq;
7+
using System.Text.Json;
78
using System.Threading.Tasks;
89
using AwesomeAssertions;
910
using Microsoft.ComponentDetection.Contracts;
@@ -14,7 +15,6 @@ namespace Microsoft.ComponentDetection.Detectors.Tests;
1415
using Microsoft.Extensions.Logging;
1516
using Microsoft.VisualStudio.TestTools.UnitTesting;
1617
using Moq;
17-
using Newtonsoft.Json;
1818

1919
[TestClass]
2020
public class SimplePipComponentDetectorTests : BaseDetectorTest<SimplePipComponentDetector>
@@ -290,12 +290,12 @@ private void CheckGraphStructure(IDependencyGraph graph, Dictionary<string, stri
290290

291291
recordedDeps.Should().HaveCount(
292292
expectedDeps.Length,
293-
$"Count missmatch of expected dependencies ({JsonConvert.SerializeObject(expectedDeps)}) and recorded dependencies ({JsonConvert.SerializeObject(recordedDeps)}) for `{componentId}`!");
293+
$"Count missmatch of expected dependencies ({JsonSerializer.Serialize(expectedDeps)}) and recorded dependencies ({JsonSerializer.Serialize(recordedDeps)}) for `{componentId}`!");
294294

295295
foreach (var expectedDep in expectedDeps)
296296
{
297297
recordedDeps.Should().Contain(
298-
expectedDep, $"Expected `{expectedDep}` in the list of dependencies for `{componentId}` but only recorded: {JsonConvert.SerializeObject(recordedDeps)}");
298+
expectedDep, $"Expected `{expectedDep}` in the list of dependencies for `{componentId}` but only recorded: {JsonSerializer.Serialize(recordedDeps)}");
299299
}
300300
}
301301
}

test/Microsoft.ComponentDetection.Detectors.Tests/SimplePypiClientTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ namespace Microsoft.ComponentDetection.Detectors.Tests;
44
using System.Linq;
55
using System.Net;
66
using System.Net.Http;
7+
using System.Text.Json;
78
using System.Threading;
89
using System.Threading.Tasks;
910
using AwesomeAssertions;
@@ -14,7 +15,6 @@ namespace Microsoft.ComponentDetection.Detectors.Tests;
1415
using Microsoft.VisualStudio.TestTools.UnitTesting;
1516
using Moq;
1617
using Moq.Protected;
17-
using Newtonsoft.Json;
1818

1919
[TestClass]
2020
public class SimplePyPiClientTests
@@ -72,7 +72,7 @@ public async Task GetSimplePypiProject_DifferentEntries_CallsGetAsync_TwiceAsync
7272
Files = [new SimplePypiProjectRelease()],
7373
};
7474

75-
var mockHandler = this.MockHttpMessageHandler(JsonConvert.SerializeObject(pythonProject), HttpStatusCode.OK);
75+
var mockHandler = this.MockHttpMessageHandler(JsonSerializer.Serialize(pythonProject), HttpStatusCode.OK);
7676
var simplePypiClient = this.CreateSimplePypiClient(mockHandler.Object, new Mock<EnvironmentVariableService>().Object, new Mock<ILogger<SimplePyPiClient>>().Object);
7777

7878
var action = async () =>

0 commit comments

Comments
 (0)