Skip to content

Commit 3e9b4fc

Browse files
authored
Add test assertion libraries (#6)
* Add JsonAssert for Xunit * Add JsonAssert for MSTest * Add NUnit asserts * Add assert docs * Tidy up benchmark result
1 parent 7abec50 commit 3e9b4fc

28 files changed

+2157
-91
lines changed

Benchmark.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Benchmark
2+
3+
## Demo JSON object from jsondiffpatch
4+
5+
``` ini
6+
7+
BenchmarkDotNet=v0.13.1, OS=Windows 10.0.19043.1415 (21H1/May2021Update)
8+
11th Gen Intel Core i7-1185G7 3.00GHz, 1 CPU, 8 logical and 4 physical cores
9+
.NET SDK=6.0.200
10+
[Host] : .NET 6.0.2 (6.0.222.6406), X64 RyuJIT
11+
DefaultJob : .NET 6.0.2 (6.0.222.6406), X64 RyuJIT
12+
13+
14+
```
15+
| Method | Mean | Min | Max | P95 | P80 | Allocated |
16+
|-------------------------- |----------:|----------:|----------:|----------:|----------:|----------:|
17+
| Diff_JsonNet | 107.55 μs | 95.29 μs | 122.73 μs | 118.01 μs | 113.43 μs | 132 KB |
18+
| Diff_SystemTextJson | 91.79 μs | 75.05 μs | 126.17 μs | 112.61 μs | 101.81 μs | 70 KB |
19+
| Diff_JsonNet_Rfc | 130.02 μs | 115.41 μs | 156.85 μs | 151.16 μs | 136.42 μs | 150 KB |
20+
| Diff_SystemTextJson_Rfc | 106.12 μs | 95.75 μs | 120.03 μs | 115.57 μs | 110.23 μs | 93 KB |
21+
| Patch_JsonNet | 116.92 μs | 107.06 μs | 137.86 μs | 133.26 μs | 122.34 μs | 162 KB |
22+
| Patch_SystemTextJson | 45.05 μs | 37.98 μs | 56.60 μs | 55.13 μs | 47.42 μs | 37 KB |
23+
| DeepEquals_JsonNet | 69.14 μs | 62.38 μs | 76.96 μs | 74.78 μs | 71.95 μs | 91 KB |
24+
| DeepEquals_SystemTextJson | 53.43 μs | 47.96 μs | 65.03 μs | 60.30 μs | 56.35 μs | 40 KB |
25+
| DeepClone_JsonNet | 51.28 μs | 44.65 μs | 62.34 μs | 58.69 μs | 54.52 μs | 70 KB |
26+
| DeepClone_SystemTextJson | 47.82 μs | 38.78 μs | 59.26 μs | 56.94 μs | 51.11 μs | 45 KB |
27+
28+
29+
## Large JSON object
30+
31+
``` ini
32+
33+
BenchmarkDotNet=v0.13.1, OS=Windows 10.0.19043.1415 (21H1/May2021Update)
34+
11th Gen Intel Core i7-1185G7 3.00GHz, 1 CPU, 8 logical and 4 physical cores
35+
.NET SDK=6.0.200
36+
[Host] : .NET 6.0.2 (6.0.222.6406), X64 RyuJIT
37+
DefaultJob : .NET 6.0.2 (6.0.222.6406), X64 RyuJIT
38+
39+
40+
```
41+
| Method | Mean | Min | Max | P95 | P80 | Allocated |
42+
|-------------------------- |----------:|----------:|----------:|----------:|----------:|----------:|
43+
| Diff_JsonNet | 11.155 ms | 9.132 ms | 13.732 ms | 12.802 ms | 11.896 ms | 4 MB |
44+
| Diff_SystemTextJson | 8.375 ms | 7.334 ms | 9.132 ms | 8.978 ms | 8.690 ms | 3 MB |
45+
| Diff_JsonNet_Rfc | 12.774 ms | 9.807 ms | 17.990 ms | 17.479 ms | 13.374 ms | 6 MB |
46+
| Diff_SystemTextJson_Rfc | 11.664 ms | 10.341 ms | 12.918 ms | 12.668 ms | 12.142 ms | 5 MB |
47+
| Patch_JsonNet | 12.146 ms | 10.344 ms | 13.576 ms | 13.302 ms | 12.647 ms | 5 MB |
48+
| Patch_SystemTextJson | 4.693 ms | 2.422 ms | 5.685 ms | 5.412 ms | 5.061 ms | 2 MB |
49+
| DeepEquals_JsonNet | 4.164 ms | 2.584 ms | 5.424 ms | 4.917 ms | 4.652 ms | 2 MB |
50+
| DeepEquals_SystemTextJson | 3.254 ms | 2.071 ms | 3.837 ms | 3.709 ms | 3.499 ms | 2 MB |
51+
| DeepClone_JsonNet | 3.997 ms | 2.529 ms | 5.165 ms | 4.772 ms | 4.531 ms | 2 MB |
52+
| DeepClone_SystemTextJson | 3.396 ms | 2.085 ms | 3.981 ms | 3.811 ms | 3.609 ms | 2 MB |
53+

README.md

Lines changed: 63 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,24 @@
11
# system-text-json-jsondiffpatch
22

3-
High-performance, low-allocating JSON objects diff and patch extension for `System.Text.Json`.
3+
High-performance, low-allocating JSON objects diff and patch extension for System.Text.Json.
44

55
## Features
66

77
- Use [jsondiffpatch](https://github.com/benjamine/jsondiffpatch) delta format described [here](https://github.com/benjamine/jsondiffpatch/blob/master/docs/deltas.md)
8-
- Target latest `.NET Standard` and `.NET Framework 4.6.1` (for legacy apps) and leverage latest .NET features
9-
- Alternative to [jsondiffpatch.net](https://github.com/wbish/jsondiffpatch.net) which is based on `Newtonsoft.Json`
108
- Support generating patch document in RFC 6902 JSON Patch format
11-
- Fast large JSON document diffing with less memory consumption
9+
- Target latest .NET Standard and .NET Framework 4.6.1 (for legacy apps) and leverage latest .NET features
10+
- Alternative to [jsondiffpatch.net](https://github.com/wbish/jsondiffpatch.net) which is based on Newtonsoft.Json
11+
- Fast large JSON document diffing with less memory consumption (see [benchmark](https://github.com/weichch/system-text-json-jsondiffpatch/blob/main/Benchmark.md))
1212
- Support smart array diffing (e.g. move detect) using LCS and custom array item matcher
1313
- _(Only when not using RFC 6902 format)_ Support diffing long text using [google-diff-match-patch](http://code.google.com/p/google-diff-match-patch/), or write your own diff algorithm
14-
- `JsonNode.DeepClone` and `JsonNode.DeepEquals` methods
14+
- Bonus `JsonNode.DeepClone` and `JsonNode.DeepEquals` methods
15+
- JSON assert for xUnit, MSTest v2 and NUnit with customizable delta output
1516

16-
# Install
17+
## Install
1718

18-
Install from [NuGet.org](https://www.nuget.org/packages/SystemTextJson.JsonDiffPatch/):
19-
20-
```
21-
Install-Package SystemTextJson.JsonDiffPatch
22-
```
19+
| JsonDiffPatch | xUnit Assert | MSTest v2 Assert | NUnit Assert |
20+
|------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------|
21+
| [![JsonDiffPatch](https://img.shields.io/nuget/vpre/SystemTextJson.JsonDiffPatch?style=for-the-badge)](https://www.nuget.org/packages/SystemTextJson.JsonDiffPatch/) | [![xUnit Assert](https://img.shields.io/nuget/vpre/SystemTextJson.JsonDiffPatch.Xunit?style=for-the-badge)](https://www.nuget.org/packages/SystemTextJson.JsonDiffPatch.Xunit/) | [![MSTest v2 Assert](https://img.shields.io/nuget/vpre/SystemTextJson.JsonDiffPatch.MSTest?style=for-the-badge)](https://www.nuget.org/packages/SystemTextJson.JsonDiffPatch.MSTest/) | [![NUnit Assert](https://img.shields.io/nuget/vpre/SystemTextJson.JsonDiffPatch.NUnit?style=for-the-badge)](https://www.nuget.org/packages/SystemTextJson.JsonDiffPatch.NUnit/) |
2322

2423
## Usage
2524
### Diff
@@ -66,64 +65,65 @@ bool equal = node1.DeepEquals(node2);
6665
var node1 = JsonNode.Parse(...);
6766
var node2 = JsonNode.Parse(...);
6867
JsonNode? diff = node1.Diff(node2);
69-
// Patch
68+
// In-place patch
7069
JsonDiffPatcher.Patch(ref node1, diff);
71-
// Unpatch
70+
// Clone & patch
71+
node1.PatchNew(diff);
72+
// In-place unpatch
7273
JsonDiffPatcher.ReversePatch(ref node1, diff);
74+
// Clone & unpatch
75+
node1.ReversePatchNew(diff);
7376
```
7477

75-
## Benchmark
76-
77-
Benchmarks were generated using example objects [here](https://github.com/weichch/system-text-json-jsondiffpatch/tree/main/test/Examples) and benchmark tests [here](https://github.com/weichch/system-text-json-jsondiffpatch/tree/main/test/SystemTextJson.JsonDiffPatch.Benchmark/).
78-
79-
### Demo JSON object from `jsondiffpatch`
80-
81-
``` ini
82-
83-
BenchmarkDotNet=v0.13.1, OS=Windows 10.0.19043.1415 (21H1/May2021Update)
84-
11th Gen Intel Core i7-1185G7 3.00GHz, 1 CPU, 8 logical and 4 physical cores
85-
.NET SDK=6.0.200
86-
[Host] : .NET 6.0.2 (6.0.222.6406), X64 RyuJIT
87-
DefaultJob : .NET 6.0.2 (6.0.222.6406), X64 RyuJIT
88-
78+
### Assert (Unit Testing)
8979

80+
```csharp
81+
var expected = JsonNode.Parse(...);
82+
var actual = JsonNode.Parse(...);
83+
84+
// xUnit
85+
JsonAssert.Equal(expected, actual);
86+
actual.ShouldEqual(expected);
87+
JsonAssert.NotEqual(expected, actual);
88+
actual.ShouldNotEqual(expected);
89+
90+
// MSTest
91+
JsonAssert.AreEqual(expected, actual);
92+
Assert.That.JsonAreEqual(expected, actual);
93+
JsonAssert.AreNotEqual(expected, actual);
94+
Assert.That.JsonAreNotEqual(expected, actual);
95+
96+
// NUnit
97+
JsonAssert.AreEqual(expected, actual);
98+
Assert.That(actual, JsonIs.EqualTo(expected));
99+
JsonAssert.AreNotEqual(expected, actual);
100+
Assert.That(actual, JsonIs.NotEqualTo(expected));
90101
```
91-
| Method | Mean | Min | Max | P95 | P80 | Allocated |
92-
|-------------------------- |----------:|----------:|----------:|----------:|----------:|----------:|
93-
| Diff_JsonNet | 107.55 μs | 95.29 μs | 122.73 μs | 118.01 μs | 113.43 μs | 132 KB |
94-
| Diff_SystemTextJson | 91.79 μs | 75.05 μs | 126.17 μs | 112.61 μs | 101.81 μs | 70 KB |
95-
| Diff_JsonNet_Rfc | 130.02 μs | 115.41 μs | 156.85 μs | 151.16 μs | 136.42 μs | 150 KB |
96-
| Diff_SystemTextJson_Rfc | 106.12 μs | 95.75 μs | 120.03 μs | 115.57 μs | 110.23 μs | 93 KB |
97-
| Patch_JsonNet | 116.92 μs | 107.06 μs | 137.86 μs | 133.26 μs | 122.34 μs | 162 KB |
98-
| Patch_SystemTextJson | 45.05 μs | 37.98 μs | 56.60 μs | 55.13 μs | 47.42 μs | 37 KB |
99-
| DeepEquals_JsonNet | 69.14 μs | 62.38 μs | 76.96 μs | 74.78 μs | 71.95 μs | 91 KB |
100-
| DeepEquals_SystemTextJson | 53.43 μs | 47.96 μs | 65.03 μs | 60.30 μs | 56.35 μs | 40 KB |
101-
| DeepClone_JsonNet | 51.28 μs | 44.65 μs | 62.34 μs | 58.69 μs | 54.52 μs | 70 KB |
102-
| DeepClone_SystemTextJson | 47.82 μs | 38.78 μs | 59.26 μs | 56.94 μs | 51.11 μs | 45 KB |
103-
104-
105-
### Large JSON object
106-
107-
``` ini
108-
109-
BenchmarkDotNet=v0.13.1, OS=Windows 10.0.19043.1415 (21H1/May2021Update)
110-
11th Gen Intel Core i7-1185G7 3.00GHz, 1 CPU, 8 logical and 4 physical cores
111-
.NET SDK=6.0.200
112-
[Host] : .NET 6.0.2 (6.0.222.6406), X64 RyuJIT
113-
DefaultJob : .NET 6.0.2 (6.0.222.6406), X64 RyuJIT
114-
115102

103+
Example output _(when output is enabled)_:
104+
```
105+
JsonAssert.Equal() failure.
106+
Expected:
107+
{
108+
"foo": "baz"
109+
}
110+
Actual:
111+
{
112+
"foo": "bar",
113+
"baz": "qux"
114+
}
115+
Delta:
116+
{
117+
"foo": [
118+
"baz",
119+
"bar"
120+
],
121+
"baz": [
122+
"qux"
123+
]
124+
}
116125
```
117-
| Method | Mean | Min | Max | P95 | P80 | Allocated |
118-
|-------------------------- |----------:|----------:|----------:|----------:|----------:|----------:|
119-
| Diff_JsonNet | 11.155 ms | 9.132 ms | 13.732 ms | 12.802 ms | 11.896 ms | 4 MB |
120-
| Diff_SystemTextJson | 8.375 ms | 7.334 ms | 9.132 ms | 8.978 ms | 8.690 ms | 3 MB |
121-
| Diff_JsonNet_Rfc | 12.774 ms | 9.807 ms | 17.990 ms | 17.479 ms | 13.374 ms | 6 MB |
122-
| Diff_SystemTextJson_Rfc | 11.664 ms | 10.341 ms | 12.918 ms | 12.668 ms | 12.142 ms | 5 MB |
123-
| Patch_JsonNet | 12.146 ms | 10.344 ms | 13.576 ms | 13.302 ms | 12.647 ms | 5 MB |
124-
| Patch_SystemTextJson | 4.693 ms | 2.422 ms | 5.685 ms | 5.412 ms | 5.061 ms | 2 MB |
125-
| DeepEquals_JsonNet | 4.164 ms | 2.584 ms | 5.424 ms | 4.917 ms | 4.652 ms | 2 MB |
126-
| DeepEquals_SystemTextJson | 3.254 ms | 2.071 ms | 3.837 ms | 3.709 ms | 3.499 ms | 2 MB |
127-
| DeepClone_JsonNet | 3.997 ms | 2.529 ms | 5.165 ms | 4.772 ms | 4.531 ms | 2 MB |
128-
| DeepClone_SystemTextJson | 3.396 ms | 2.085 ms | 3.981 ms | 3.811 ms | 3.609 ms | 2 MB |
129126

127+
## Benchmark
128+
129+
[Benchmark results](https://github.com/weichch/system-text-json-jsondiffpatch/blob/main/Benchmark.md) were generated using example objects [here](https://github.com/weichch/system-text-json-jsondiffpatch/tree/main/test/Examples) and benchmark tests [here](https://github.com/weichch/system-text-json-jsondiffpatch/tree/main/test/SystemTextJson.JsonDiffPatch.Benchmark/).

src/Directory.Build.props

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<Project>
2+
3+
<PropertyGroup>
4+
<TargetFrameworks>netstandard2.0;netstandard2.1;net461</TargetFrameworks>
5+
<Nullable>enable</Nullable>
6+
<LangVersion>latest</LangVersion>
7+
<GenerateDocumentationFile>true</GenerateDocumentationFile>
8+
<NoWarn>$(NoWarn);CS1591</NoWarn>
9+
</PropertyGroup>
10+
11+
<PropertyGroup>
12+
<Authors>Wei Chen</Authors>
13+
<PackageProjectUrl>https://github.com/weichch/system-text-json-jsondiffpatch</PackageProjectUrl>
14+
<Copyright>Copyright © Wei Chen 2022</Copyright>
15+
<PackageIcon>icon.png</PackageIcon>
16+
<PackageLicenseFile>LICENSE</PackageLicenseFile>
17+
</PropertyGroup>
18+
19+
<PropertyGroup>
20+
<Version>1.0.0</Version>
21+
<AssemblyVersion>1.0.0.0</AssemblyVersion>
22+
<FileVersion>1.0.0.0</FileVersion>
23+
</PropertyGroup>
24+
25+
<ItemGroup>
26+
<None Include="..\..\icon.png" Link="Packaging\icon.png" Pack="true" PackagePath="\" />
27+
<None Include="..\..\LICENSE" Link="Packaging\LICENSE" Pack="true" PackagePath="\" />
28+
</ItemGroup>
29+
30+
</Project>

0 commit comments

Comments
 (0)