Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/d-edge/diffract

A .NET library to perform structural diff between two objects
https://github.com/d-edge/diffract

diff dotnet fsharp hacktoberfest hacktoberfest2021 testing unit-testing

Last synced: about 3 hours ago
JSON representation

A .NET library to perform structural diff between two objects

Awesome Lists containing this project

README

        



diffract logo


actions build
version
download
license


Diffract is a .NET library that displays a readable diff between two objects. It is particularly useful for unit testing complex objects. Diffract is maintained by folks at [D-EDGE](https://www.d-edge.com/).

Here is an example:

```csharp
using DEdge.Diffract;

record User(string Name, int Age, string[] Pets);

var expected = new User("Emma", 42, new[] { "Oscar", "Fluffy", "Tibbles" });
var actual = new User("Andy", 42, new[] { "Oscar", "Sparky" });

Differ.Assert(expected, actual);
```

The above throws an `AssertionFailedException` with the following message:

```
Value differs by 2 fields:
Name Expect = "Emma"
Actual = "Andy"
Pets collection differs:
Pets.Count Expect = 3
Actual = 2
Pets[1] Expect = "Fluffy"
Actual = "Sparky"
```

Diffract can drill down many composite types:
* POCOs;
* C# records;
* F# records and anonymous records;
* F# unions;
* enumerables (`IEnumerable`);
* dictionaries (`IDictionary`, `IReadOnlyDictionary`);
* value and reference tuples.

Values of any other equatable type (like `string` and `int` in the above example) are treated as leaves that can be tested for equality.

## Example outputs

POCO or record with multiple field differences:

```csharp
record User(string Name, int Age, bool IsActive);

var expected = new User("Emma", 42, true);
var actual = new User("Andy", 35, true);
```

```
Value differs by 2 fields:
Name Expect = "Emma"
Actual = "Andy"
Age Expect = 42
Actual = 35
```

F# union where the case is different:

```fsharp
type Contact =
| Email of address: string
| Phone of number: string

let expected = Email "[email protected]"
let actual = Phone "555-123-456"
```

```
Value differs by union case:
Expect is Email
Actual is Phone
```

F# union where the case is the same and the value is different:

```fsharp
type Contact =
| Email of address: string
| Phone of number: string

let expected = Email "[email protected]"
let actual = Email "[email protected]"
```

```
Value differs by union case Email fields:
address Expect = "[email protected]"
Actual = "[email protected]"
```

Enumerables show the counts if they differ, followed by the diffs per item:

```csharp
var expected = new string[] { "first", "second" };
var actual = new string[] { "first", "2nd", "third" };
```

```
Value collection differs:
Count Expect = 2
Actual = 3
[1] Expect = "second"
Actual = "2nd"
```

Dictionaries show the keys missing on either side, followed by the diffs per item that exists in both:

```csharp
var expected = new Dictionary
{
{ "first", 1 },
{ "second", 2 },
{ "third", 3 },
};
var actual = new Dictionary
{
{ "first", 1 },
{ "third", 2 },
{ "fourth", 4 },
};
```

```
Value dictionary differs:
["second"] Actual is missing
["fourth"] Expect is missing
["third"] Expect = 3
Actual = 2
```

## API

Diffract lives in the namespace `DEdge.Diffract`. Its main API is the class `Differ`, which provides the following methods:

```csharp
void Assert(T expected, T actual, IDiffer differ = null, PrintParams param = null)
```

Computes the diff between two objects and, if it is not empty, throws an `AssertionFailedException` with the diff as message.

```csharp
string ToString(T expected, T actual, IDiffer differ = null, PrintParams param = null)
```

Prints the diff between two objects to a string.

```csharp
void Write(T expected, T actual, TextWriter writer = null, IDiffer differ = null, PrintParams param = null)
```

Prints the diff between two objects to the given TextWriter (or to standard output if not provided).

```csharp
FSharpOption Diff(T expected, T actual, IDiffer differ = null)
```

Computes the diff between two objects. Returns `None` if the objects are found to be equal.