Skip to content

Commit 3a26e11

Browse files
committed
Replace Newtonsoft from the rest of the files
1 parent a89c1d4 commit 3a26e11

14 files changed

+693
-178
lines changed

JsonFlatFileDataStore.Test/CollectionModificationTests.cs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
using System.Collections.Generic;
33
using System.Dynamic;
44
using System.Linq;
5+
using System.Text.Json;
6+
using System.Text.Json.Nodes;
57
using System.Threading.Tasks;
6-
using Newtonsoft.Json;
7-
using Newtonsoft.Json.Linq;
88
using Xunit;
99

1010
namespace JsonFlatFileDataStore.Test
@@ -146,7 +146,7 @@ public async Task UpdateOneAsync_TypedUser_WrongCase()
146146

147147
var collection2 = store2.GetCollection<User>("users2");
148148
await collection2.UpdateOneAsync(x => x.Id == 0, new { name = "new value" });
149-
await collection2.UpdateOneAsync(x => x.Id == 1, JToken.Parse("{ name: \"new value 2\"} "));
149+
await collection2.UpdateOneAsync(x => x.Id == 1, JsonNode.Parse("{ \"name\": \"new value 2\"} "));
150150

151151
var store3 = new DataStore(newFilePath);
152152

@@ -450,18 +450,19 @@ public async Task UpdateManyAsync_JsonUser()
450450

451451
var newUsersJson = @"
452452
[
453-
{ 'id': 20, 'name': 'A1', 'age': 55 },
454-
{ 'id': 21, 'name': 'A2', 'age': 55 },
455-
{ 'id': 22, 'name': 'A3', 'age': 55 }
453+
{ ""id"": 20, ""name"": ""A1"", ""age"": 55 },
454+
{ ""id"": 21, ""name"": ""A2"", ""age"": 55 },
455+
{ ""id"": 22, ""name"": ""A3"", ""age"": 55 }
456456
]
457457
";
458458

459-
var newUsers = JToken.Parse(newUsersJson);
459+
var newUsersArray = JsonNode.Parse(newUsersJson).AsArray();
460+
var newUsers = newUsersArray.Select(n => n as dynamic);
460461

461462
await collection.InsertManyAsync(newUsers);
462463

463-
var newUserJson = "{ 'id': 23, 'name': 'A4', 'age': 22 }";
464-
var newUser = JToken.Parse(newUserJson);
464+
var newUserJson = "{ \"id\": 23, \"name\": \"A4\", \"age\": 22 }";
465+
var newUser = JsonNode.Parse(newUserJson);
465466

466467
await collection.InsertOneAsync(newUser);
467468

@@ -627,7 +628,7 @@ public void ReplaceOne_Upsert_DynamicWithInnerData()
627628
var collection = store.GetCollection("sensor");
628629

629630
var success = collection.ReplaceOne(e => e.id == 11,
630-
JToken.Parse("{ 'id': 11, 'mac': 'F4:A5:74:89:16:57', 'data': { 'temperature': 20.5 } }"),
631+
JsonNode.Parse("{ \"id\": 11, \"mac\": \"F4:A5:74:89:16:57\", \"data\": { \"temperature\": 20.5 } }"),
631632
true);
632633
Assert.True(success);
633634

@@ -893,8 +894,9 @@ public void UpdateOne_InnerExpandos()
893894
{ "name", "James" },
894895
{ "Work", new Dictionary<string, object> { { "Name", "ACME" } } }
895896
};
896-
var jobject = JObject.FromObject(patchData);
897-
dynamic patchExpando = JsonConvert.DeserializeObject<ExpandoObject>(jobject.ToString());
897+
var jsonString = JsonSerializer.Serialize(patchData);
898+
var options = new JsonSerializerOptions { Converters = { new SystemExpandoObjectConverter() } };
899+
dynamic patchExpando = JsonSerializer.Deserialize<ExpandoObject>(jsonString, options);
898900

899901
collection.UpdateOne(i => i.Id == 4, patchExpando as object);
900902

JsonFlatFileDataStore.Test/CollectionQueryTests.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
using System.Linq;
2-
using Newtonsoft.Json.Linq;
2+
using System.Text.Json.Nodes;
33
using Xunit;
44

55
namespace JsonFlatFileDataStore.Test
@@ -134,19 +134,19 @@ public void GetNextIdValue_StringType_JToken()
134134
var collection = store.GetCollection("collectionWithStringId");
135135

136136
// Insert seed value with upsert
137-
collection.ReplaceOne(e => e, JToken.Parse("{ 'myId': 'test1' }"), true);
137+
collection.ReplaceOne(e => e, JsonNode.Parse("{ \"myId\": \"test1\" }"), true);
138138

139139
var nextId = collection.GetNextIdValue();
140140
Assert.Equal("test2", nextId);
141141

142-
var nextUpdate = JToken.Parse("{ 'myId': 'somethingWrong2' }");
142+
var nextUpdate = JsonNode.Parse("{ \"myId\": \"somethingWrong2\" }");
143143
collection.InsertOne(nextUpdate);
144-
Assert.Equal(nextId, nextUpdate["myId"]);
144+
Assert.Equal(nextId, nextUpdate["myId"].ToString());
145145

146146
nextId = collection.GetNextIdValue();
147147
Assert.Equal("test3", nextId);
148148

149-
nextUpdate = JToken.Parse("{ 'xxx': 111 }");
149+
nextUpdate = JsonNode.Parse("{ \"xxx\": 111 }");
150150
collection.InsertOne(nextUpdate);
151151
Assert.Equal(nextId, nextUpdate["myId"]);
152152
Assert.Equal(111, nextUpdate["xxx"]);

JsonFlatFileDataStore.Test/CopyPropertiesTests.cs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
using System.Collections.Generic;
22
using System.Collections.ObjectModel;
33
using System.Dynamic;
4-
using Newtonsoft.Json;
5-
using Newtonsoft.Json.Linq;
4+
using System.Text.Json;
65
using Xunit;
76

87
namespace JsonFlatFileDataStore.Test
@@ -257,8 +256,9 @@ public void CopyProperties_DynamicWithInnerExpandos()
257256
{ "name", "James" },
258257
{ "work", new Dictionary<string, object> { { "name", "ACME" } } }
259258
};
260-
var jobject = JObject.FromObject(patchData);
261-
dynamic patchExpando = JsonConvert.DeserializeObject<ExpandoObject>(jobject.ToString());
259+
var jsonString = JsonSerializer.Serialize(patchData);
260+
var options = new JsonSerializerOptions { Converters = { new SystemExpandoObjectConverter() } };
261+
dynamic patchExpando = JsonSerializer.Deserialize<ExpandoObject>(jsonString, options);
262262

263263
ObjectExtensions.CopyProperties(patchExpando, user);
264264
Assert.Equal("James", user.name);
@@ -325,8 +325,9 @@ public void CopyProperties_TypedWithInnerExpandos()
325325
{ "Name", "James" },
326326
{ "Work", new Dictionary<string, object> { { "Name", "ACME" } } }
327327
};
328-
var jobject = JObject.FromObject(patchData);
329-
dynamic patchExpando = JsonConvert.DeserializeObject<ExpandoObject>(jobject.ToString());
328+
var jsonString = JsonSerializer.Serialize(patchData);
329+
var options = new JsonSerializerOptions { Converters = { new SystemExpandoObjectConverter() } };
330+
dynamic patchExpando = JsonSerializer.Deserialize<ExpandoObject>(jsonString, options);
330331

331332
ObjectExtensions.CopyProperties(patchExpando, user);
332333
Assert.Equal("James", user.Name);

JsonFlatFileDataStore.Test/DataStoreTests.cs

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@
33
using System.Dynamic;
44
using System.IO;
55
using System.Linq;
6+
using System.Text.Json;
7+
using System.Text.Json.Nodes;
68
using System.Text.RegularExpressions;
79
using System.Threading.Tasks;
8-
using Newtonsoft.Json.Linq;
910
using NSubstitute;
1011
using Xunit;
1112

@@ -20,7 +21,7 @@ public void UpdateAll()
2021

2122
var store = new DataStore(newFilePath);
2223

23-
store.UpdateAll("{ 'tasks': [ { 'id': 0, 'task': 'Commit'} ] }");
24+
store.UpdateAll("{ \"tasks\": [ { \"id\": 0, \"task\": \"Commit\"} ] }");
2425

2526
var collection = store.GetCollection("tasks");
2627
Assert.Equal(1, collection.Count);
@@ -187,7 +188,7 @@ public async Task Readme_Example2()
187188
};
188189

189190
// Example with JSON object
190-
var employeeJson = JToken.Parse("{ 'id': 2, 'name': 'Raymond', 'age': 32 }");
191+
var employeeJson = JsonNode.Parse("{ \"id\": 2, \"name\": \"Raymond\", \"age\": 32 }");
191192

192193
// Example with JSON object
193194
var employeeDict = new Dictionary<string, object>
@@ -213,7 +214,7 @@ public async Task Readme_Example2()
213214
var updateData = new { name = "John Doe" };
214215
await collection.UpdateOneAsync(e => e.id == employee.id, updateData);
215216

216-
var updateJson = JObject.Parse("{ 'name': 'Raymond Doe' }");
217+
var updateJson = JsonNode.Parse("{ \"name\": \"Raymond Doe\" }");
217218
await collection.UpdateOneAsync(e => e.id == 1, updateJson);
218219

219220
var updateDict = new Dictionary<string, object> { ["name"] = "Andy Doe" };
@@ -248,7 +249,7 @@ public async Task Insert_CorrectIdWithDynamic()
248249
};
249250

250251
// Example with JSON object
251-
var employeeJson = JToken.Parse("{ 'id': 200, 'name': 'Raymond', 'age': 32 }");
252+
var employeeJson = JsonNode.Parse("{ \"id\": 200, \"name\": \"Raymond\", \"age\": 32 }");
252253

253254
// Example with JSON object
254255
var employeeDict = new Dictionary<string, object>
@@ -295,7 +296,7 @@ public async Task Insert_CorrectIdWithDynamic_No_InitialId()
295296
};
296297

297298
// Example with JSON object
298-
var employeeJson = JToken.Parse("{ 'name': 'Raymond', 'age': 32 }");
299+
var employeeJson = JsonNode.Parse("{ \"name\": \"Raymond\", \"age\": 32 }");
299300

300301
// Example with JSON object
301302
var employeeDict = new Dictionary<string, object>
@@ -315,7 +316,10 @@ public async Task Insert_CorrectIdWithDynamic_No_InitialId()
315316
await collection.InsertOneAsync(employeeDict);
316317
await collection.InsertOneAsync(employeeExpando);
317318

318-
Assert.Equal(1, employeeJson["acc"]);
319+
// System.Text.Json: JsonNode indexer returns JsonNode, requires explicit GetValue<T>()
320+
// Newtonsoft.Json: JToken had implicit conversion operators, allowed direct comparison
321+
Assert.Equal(1, employeeJson["acc"].GetValue<int>());
322+
// Dictionary and ExpandoObject return 'object' (boxed int), which Assert.Equal handles directly
319323
Assert.Equal(2, employeeDict["acc"]);
320324
Assert.Equal(3, ((IDictionary<string, object>)employeeExpando)["acc"]);
321325

@@ -340,7 +344,7 @@ public async Task Insert_CorrectIdWithDynamic_With_InitialId()
340344
};
341345

342346
// Example with JSON object
343-
var employeeJson = JToken.Parse("{ 'name': 'Raymond', 'age': 32 }");
347+
var employeeJson = JsonNode.Parse("{ \"name\": \"Raymond\", \"age\": 32 }");
344348

345349
// Example with JSON object
346350
var employeeDict = new Dictionary<string, object>
@@ -361,7 +365,10 @@ public async Task Insert_CorrectIdWithDynamic_With_InitialId()
361365
await collection.InsertOneAsync(employeeExpando);
362366

363367
Assert.Equal("hello", employee.acc);
364-
Assert.Equal("hello0", employeeJson["acc"]);
368+
// System.Text.Json: JsonNode indexer returns JsonNode, requires explicit GetValue<T>()
369+
// Newtonsoft.Json: JToken had implicit conversion operators, allowed direct comparison
370+
Assert.Equal("hello0", employeeJson["acc"].GetValue<string>());
371+
// Dictionary and ExpandoObject return 'object' (boxed string), which Assert.Equal handles directly
365372
Assert.Equal("hello1", employeeDict["acc"]);
366373
Assert.Equal("hello2", ((IDictionary<string, object>)employeeExpando)["acc"]);
367374

JsonFlatFileDataStore.Test/FileContentTests.cs

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ public void FileNotFound_CreateNewFile()
2727
}
2828

2929
[Theory]
30-
[InlineData(true, true, new[] { 40 })]
31-
[InlineData(false, true, new[] { 40 })]
32-
[InlineData(true, false, new[] { 81, 74 })]
33-
[InlineData(false, false, new[] { 81, 74 })]
30+
[InlineData(true, true, new[] { 40, 38 })] // Minified, lowerCamelCase: Newtonsoft=40, System.Text.Json=38
31+
[InlineData(false, true, new[] { 40, 38 })] // Minified, UpperCamelCase: Newtonsoft=40, System.Text.Json=38
32+
[InlineData(true, false, new[] { 81, 79, 74, 72 })] // Formatted, lowerCamelCase: Newtonsoft=81(Win)/74(Unix), System.Text.Json=79(Win)/72(Unix)
33+
[InlineData(false, false, new[] { 81, 79, 74, 72 })] // Formatted, UpperCamelCase: Newtonsoft=81(Win)/74(Unix), System.Text.Json=79(Win)/72(Unix)
3434
public async Task AllFormats_CorrectLength(bool useLowerCamelCase, bool useMinifiedJson, int[] allowedLengths)
3535
{
3636
var path = UTHelpers.GetFullFilePath($"AllFormats_CorrectLength_{DateTime.UtcNow.Ticks}");
@@ -41,13 +41,19 @@ public async Task AllFormats_CorrectLength(bool useLowerCamelCase, bool useMinif
4141

4242
var content = UTHelpers.GetFileContent(path);
4343

44-
// NOTE: File format is different depending on used OS. Windows uses \r\n and Linux/macOS \r
45-
// - "{\r\n \"movie\": [\r\n {\r\n \"name\": \"Test\",\r\n \"rating\": 5.0\r\n }\r\n ]\r\n}",
46-
// - "{\r \"movie\": [\r {\r \"name\": \"Test\",\r \"rating\": 5.0\r }\r ]\r}"
47-
// Length on Windows is 81 and on Linux/macOS 74
44+
// NOTE: File format is different depending on used OS and serializer:
4845
//
49-
// Minified length: 40
50-
// - "{\"movie\":\"name\":\"Test\",\"rating\":5.0}]}"
46+
// Newtonsoft.Json (formatted with "rating": 5.0):
47+
// - Windows (CRLF): 81 bytes
48+
// - Linux/macOS (LF): 74 bytes
49+
//
50+
// System.Text.Json (formatted with "rating": 5):
51+
// - Windows (CRLF): 79 bytes
52+
// - Linux/macOS (LF): 72 bytes
53+
//
54+
// Minified (both serializers):
55+
// - Newtonsoft.Json: 40 bytes (with 5.0)
56+
// - System.Text.Json: 38 bytes (with 5)
5157

5258
Assert.Contains(allowedLengths, i => i == content.Length);
5359

JsonFlatFileDataStore.Test/SingleItemTests.cs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,15 +81,24 @@ public void GetItem_DynamicAndTyped_DateType(string encryptionPassword)
8181

8282
var test = DateTime.Now.ToShortDateString();
8383

84-
var itemDynamic = store.GetItem("myDate_string");
84+
// Typed: System.Text.Json deserializes date strings to DateTime
8585
var itemTyped = store.GetItem<DateTime>("myDate_string");
8686
Assert.Equal(2009, itemTyped.Year);
8787

88-
var itemDynamic2 = store.GetItem("myDate_date");
88+
// Dynamic: Now automatically parses date strings to DateTime (Newtonsoft.Json compatibility)
89+
var itemDynamic = store.GetItem("myDate_string");
90+
Assert.IsType<DateTime>(itemDynamic);
91+
Assert.Equal(2009, itemDynamic.Year);
92+
93+
// Typed: System.Text.Json deserializes ISO date strings to DateTime
8994
var itemTyped2 = store.GetItem<DateTime>("myDate_date");
90-
Assert.Equal(2015, itemDynamic2.Year);
9195
Assert.Equal(2015, itemTyped2.Year);
9296

97+
// Dynamic: Now automatically parses ISO date strings to DateTime (Newtonsoft.Json compatibility)
98+
var itemDynamic2 = store.GetItem("myDate_date");
99+
Assert.IsType<DateTime>(itemDynamic2);
100+
Assert.Equal(2015, itemDynamic2.Year);
101+
93102
UTHelpers.Down(newFilePath);
94103
}
95104

JsonFlatFileDataStore/CommitActionHandler.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
using System.Collections.Concurrent;
33
using System.Collections.Generic;
44
using System.Threading;
5-
using Newtonsoft.Json.Linq;
5+
using System.Text.Json;
66

77
namespace JsonFlatFileDataStore
88
{
@@ -43,7 +43,9 @@ internal static void HandleStoreCommitActions(CancellationToken token, BlockingC
4343

4444
foreach (var action in batch)
4545
{
46-
var (actionSuccess, updatedJson) = action.HandleAction(JObject.Parse(jsonText));
46+
using var jsonDocument = JsonDocument.Parse(jsonText);
47+
var rootElement = jsonDocument.RootElement.Clone();
48+
var (actionSuccess, updatedJson) = action.HandleAction(rootElement);
4749

4850
callbacks.Enqueue((action, actionSuccess));
4951

0 commit comments

Comments
 (0)