Skip to content

Commit

Permalink
Merge pull request #1 from tomasbruckner/version-1-2-0
Browse files Browse the repository at this point in the history
[1.2.0] improved configuration
  • Loading branch information
tomasbruckner authored Jun 26, 2020
2 parents 7ea8bf1 + 48542d3 commit c06291c
Show file tree
Hide file tree
Showing 11 changed files with 260 additions and 17 deletions.
95 changes: 95 additions & 0 deletions JestDotnet/JestDotnet/Core/Settings/SnapshotSettings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
using System;
using System.Globalization;
using System.IO;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace JestDotnet.Core.Settings
{
public static class SnapshotSettings
{
/// <summary>
/// Default snapshot extension
/// </summary>
public const string DefaultSnapshotExtension = "snap";

/// <summary>
/// default snapshot directory
/// </summary>
public const string DefaultSnapshotDirectory = "__snapshots__";

/// <summary>
/// snapshot extension
/// </summary>
public static string SnapshotExtension = DefaultSnapshotExtension;

/// <summary>
/// snapshot directory
/// </summary>
public static string SnapshotDirectory = DefaultSnapshotDirectory;

/// <summary>
/// default snapshot dot extension creator
/// </summary>
public static readonly Func<string> DefaultCreateSnapshotDotExtension = () => $".{SnapshotExtension}";

/// <summary>
/// snapshot dot extension creator
/// </summary>
public static Func<string> CreateSnapshotDotExtension = DefaultCreateSnapshotDotExtension;

/// <summary>
/// default function that creates snapshot path
/// </summary>
public static readonly Func<(string sourceFilePath, string memberName, string hint), string> DefaultCreatePath =
SnapshotResolver.CreatePath;

/// <summary>
/// function that creates snapshot path
/// </summary>
public static Func<(string sourceFilePath, string memberName, string hint), string> CreatePath =
DefaultCreatePath;

/// <summary>
/// default JSON serializer creator
/// </summary>
public static readonly Func<JsonSerializer> DefaultCreateJsonSerializer = JsonSerializer.CreateDefault;

/// <summary>
/// JSON serializer creator
/// </summary>
public static Func<JsonSerializer> CreateJsonSerializer = DefaultCreateJsonSerializer;

/// <summary>
/// default JToken writer creator
/// </summary>
public static readonly Func<JTokenWriter> DefaultCreateJTokenWriter = () => new JTokenWriter();

/// <summary>
/// JToken writer creator
/// </summary>
public static Func<JTokenWriter> CreateJTokenWriter = DefaultCreateJTokenWriter;

/// <summary>
/// default string writer creator
/// </summary>
public static readonly Func<StringWriter> DefaultCreateStringWriter =
() => new StringWriter(CultureInfo.InvariantCulture);

/// <summary>
/// string writer creator
/// </summary>
public static Func<StringWriter> CreateStringWriter = DefaultCreateStringWriter;

/// <summary>
/// default text writer creator
/// </summary>
public static readonly Func<StringWriter, JsonTextWriter> DefaultCreateTextWriter = stringWriter =>
new JsonTextWriter(stringWriter) {Formatting = Formatting.Indented};

/// <summary>
/// text writer creator
/// </summary>
public static Func<StringWriter, JsonTextWriter> CreateTextWriter = DefaultCreateTextWriter;
}
}
9 changes: 0 additions & 9 deletions JestDotnet/JestDotnet/Core/SnapshotConstants.cs

This file was deleted.

18 changes: 13 additions & 5 deletions JestDotnet/JestDotnet/Core/SnapshotResolver.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using System.IO;
using Newtonsoft.Json.Linq;
using JestDotnet.Core.Settings;

namespace JestDotnet.Core
{
Expand All @@ -12,16 +12,24 @@ internal static string GetSnapshotData(string path)

internal static void StoreSnapshotData(string path, object actualObject)
{
var serialized = JToken.FromObject(actualObject).ToString();
var jsonSerializer = SnapshotSettings.CreateJsonSerializer();
using var jsonWriter = SnapshotSettings.CreateJTokenWriter();
jsonSerializer.Serialize(jsonWriter, actualObject);
using var stringWriter = SnapshotSettings.CreateStringWriter();
using var jsonTextWriter = SnapshotSettings.CreateTextWriter(stringWriter);
jsonWriter.Token!.WriteTo(jsonTextWriter);
var serialized = stringWriter.ToString();

Directory.CreateDirectory(Path.GetDirectoryName(path));
File.WriteAllText(path, serialized);
}

internal static string CreatePath(string sourceFilePath, string memberName, string hint)
internal static string CreatePath((string sourceFilePath, string memberName, string hint) args)
{
var directoryName = $"{Path.GetDirectoryName(sourceFilePath)}/{SnapshotConstants.SnapshotDirectory}";
var (sourceFilePath, memberName, hint) = args;
var directoryName = $"{Path.GetDirectoryName(sourceFilePath)}/{SnapshotSettings.SnapshotDirectory}";
var fileName =
$"{Path.GetFileNameWithoutExtension(sourceFilePath)}{memberName}{hint}{SnapshotConstants.SnapshotDotExtension}";
$"{Path.GetFileNameWithoutExtension(sourceFilePath)}{memberName}{hint}{SnapshotSettings.CreateSnapshotDotExtension()}";

return $"{directoryName}/{fileName}";
}
Expand Down
3 changes: 2 additions & 1 deletion JestDotnet/JestDotnet/JestAssert.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Runtime.CompilerServices;
using JestDotnet.Core;
using JestDotnet.Core.Exceptions;
using JestDotnet.Core.Settings;

namespace JestDotnet
{
Expand All @@ -14,7 +15,7 @@ public static void ShouldMatchSnapshot(
[CallerFilePath] string sourceFilePath = ""
)
{
var path = SnapshotResolver.CreatePath(sourceFilePath, memberName, hint);
var path = SnapshotSettings.CreatePath((sourceFilePath, memberName, hint));
var snapshot = SnapshotResolver.GetSnapshotData(path);

if (string.IsNullOrEmpty(snapshot))
Expand Down
2 changes: 1 addition & 1 deletion JestDotnet/JestDotnet/JestDotnet.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<Version>1.1.0</Version>
<Version>1.2.0</Version>
<Authors>Tomas Bruckner</Authors>
<RepositoryUrl>https://github.com/tomasbruckner/jest-dotnet</RepositoryUrl>
<Description>Snapshot testing in C#. See Project Site for more details</Description>
Expand Down
3 changes: 2 additions & 1 deletion JestDotnet/JestDotnet/JestDotnetExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Runtime.CompilerServices;
using JestDotnet.Core;
using JestDotnet.Core.Exceptions;
using JestDotnet.Core.Settings;

namespace JestDotnet
{
Expand All @@ -13,7 +14,7 @@ public static void ShouldMatchSnapshot(
[CallerFilePath] string sourceFilePath = ""
)
{
var path = SnapshotResolver.CreatePath(sourceFilePath, memberName, hint);
var path = SnapshotSettings.CreatePath((sourceFilePath, memberName, hint));
var snapshot = SnapshotResolver.GetSnapshotData(path);

if (string.IsNullOrEmpty(snapshot))
Expand Down
74 changes: 74 additions & 0 deletions JestDotnet/XUnitTests/SettingsTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
using System;
using System.Globalization;
using System.IO;
using JestDotnet;
using JestDotnet.Core.Settings;
using Xunit;
using XUnitTests.Helpers;

namespace XUnitTests
{
public class SettingsTests
{
[Fact]
public void ShouldMatchCustomSnapExtension()
{
SnapshotSettings.CreateStringWriter = () => new StringWriter(CultureInfo.InvariantCulture)
{
NewLine = "\n"
};

SnapshotSettings.SnapshotExtension = "snap2";

var testObject = new Person
{
Age = 13,
DateOfBirth = new DateTime(2008, 7, 7),
FirstName = "John",
LastName = "Bam"
};

JestAssert.ShouldMatchSnapshot(testObject);

SnapshotSettings.SnapshotExtension = SnapshotSettings.DefaultSnapshotExtension;
}

[Fact]
public void ShouldMatchLinuxLineEnding()
{
SnapshotSettings.CreateStringWriter = () => new StringWriter(CultureInfo.InvariantCulture)
{
NewLine = "\n"
};

var testObject = new Person
{
Age = 13,
DateOfBirth = new DateTime(2008, 7, 7),
FirstName = "John",
LastName = "Bam"
};

JestAssert.ShouldMatchSnapshot(testObject);
}

[Fact]
public void ShouldMatchWindowsLineEnding()
{
SnapshotSettings.CreateStringWriter = () => new StringWriter(CultureInfo.InvariantCulture)
{
NewLine = "\r\n"
};

var testObject = new Person
{
Age = 13,
DateOfBirth = new DateTime(2008, 7, 7),
FirstName = "John",
LastName = "Bam"
};

JestAssert.ShouldMatchSnapshot(testObject);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"FirstName": "John",
"LastName": "Bam",
"DateOfBirth": "2008-07-07T00:00:00",
"Age": 13
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"FirstName": "John",
"LastName": "Bam",
"DateOfBirth": "2008-07-07T00:00:00",
"Age": 13
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"FirstName": "John",
"LastName": "Bam",
"DateOfBirth": "2008-07-07T00:00:00",
"Age": 13
}
55 changes: 55 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,61 @@ var expected = new Person
JestAssert.ShouldMatchObject(actual,expected);
```

## Advanced
### Configuring directory and file extensions
If you need to configure it, you can use `SnapshotSettings` class to specify your own
* extension instead of `.snap` (use `SnapshotSettings.SnapshotExtension`)
* directory instead of `__snapshots__` (use `SnapshotSettings.SnapshotDirectory`)
* function that generates directory, extension and filename (use `SnapshotSettings.CreatePath`)

Popular use is to change directory of the snapshot files. You can do it like this:

```csharp
SnapshotSettings.SnapshotDirectory = "__custom__";

var testObject = new Person
{
Age = 13,
DateOfBirth = new DateTime(2008, 7, 7),
FirstName = "John",
LastName = "Bam"
};

JestAssert.ShouldMatchSnapshot(testObject);

// you can return it back using
SnapshotSettings.SnapshotDirectory = SnapshotSettings.DefaultSnapshotDirectory;
```

### Configuring serialization
For serialization, I am using Json.NET. If you need to configure it, you can use `SnapshotSettings` class to specify your own

* `JsonSerializer` (use `SnapshotSettings.CreateJsonSerializer`)
* `JTokenWriter` (use `SnapshotSettings.CreateJTokenWriter`)
* `StringWriter` (use `SnapshotSettings.CreateStringWriter`)
* `JsonTextWriter` (use `SnapshotSettings.CreateJsonTextWriter`).

Popular use is to change line ending of the `.snap` files. For example if you want to set line ending to Linux `LF`, you can do it like this:

```csharp
SnapshotSettings.CreateStringWriter = () => new StringWriter(CultureInfo.InvariantCulture)
{
NewLine = "\n"
};

var testObject = new Person
{
Age = 13,
DateOfBirth = new DateTime(2008, 7, 7),
FirstName = "John",
LastName = "Bam"
};

JestAssert.ShouldMatchSnapshot(testObject);
```

`SnapshotSettings` expects you define your own function that returns new configured instance.

## Caveats
### Dynamic objects
You cannot call neither extension nor `JestAssert` with `dynamic` object. You need to cast it to `object` (or real type).

0 comments on commit c06291c

Please sign in to comment.