<!--
GENERATED FILE - DO NOT EDIT
This file was generated by [MarkdownSnippets](https://github.com/SimonCropp/MarkdownSnippets).
Source File: /docs/mdsource/converter.source.md
To change this file edit the source file and then run MarkdownSnippets.
-->

# Converters

Converters are used to split a target into its component parts, then verify each of those parts.

When a target is split the result is:

 * An info file (containing the metadata of the target) serialized as json. File name: `{TestType}.{TestMethod}.info.verified.txt`
 * Zero or more documents of a specified extension. File name: `{TestType}.{TestMethod}.{Index}.verified.{Extension}`


## Usage scenarios

 * tiff => png per page
 * spreadsheet => csv per sheet
 * pdf => png per page


## Example

Both the following examples take an input tiff and convert it to:

The info file:

<!-- snippet: ConverterSnippets.Type.verified.txt -->
<a id='snippet-ConverterSnippets.Type.verified.txt'></a>
```txt
{
  PixelFormat: Format8bppIndexed,
  Size: 473, 355
}
```
<sup><a href='/src/Verify.Tests/Snippets/ConverterSnippets.Type.verified.txt#L1-L4' title='Snippet source file'>snippet source</a> | <a href='#snippet-ConverterSnippets.Type.verified.txt' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

Multiple png files:

<img src="/src/Verify.Tests/Snippets/ConverterSnippets.Type%2300.verified.png" alt="Converter page one verified" width="200"><img src="/src/Verify.Tests/Snippets/ConverterSnippets.Type%2301.verified.png" alt="Converter page one verified" width="200">


### Typed converter

This sample uses a typed approach. So the converter acts on an in memory instance matching based on type.

<!-- snippet: RegisterFileConverterType -->
<a id='snippet-RegisterFileConverterType'></a>
```cs
VerifierSettings.RegisterFileConverter<Image>(

    canConvert: (target, context) => Equals(target.RawFormat, ImageFormat.Tiff),

    conversion: (image, settings) =>
    {
        var pages = image.GetFrameCount(FrameDimension.Page);

        var targets = new List<Target>();
        for (var index = 0; index < pages; index++)
        {
            image.SelectActiveFrame(FrameDimension.Page, index);

            var page = new MemoryStream();
            image.Save(page, ImageFormat.Png);
            targets.Add(new("png", page));
        }

        return new(
            info: new
            {
                image.PixelFormat,
                image.Size
            },
            targets);
    });
```
<sup><a href='/src/Verify.Tests/Snippets/ConverterSnippets.cs#L9-L41' title='Snippet source file'>snippet source</a> | <a href='#snippet-RegisterFileConverterType' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

<!-- snippet: FileConverterTypeVerify -->
<a id='snippet-FileConverterTypeVerify'></a>
```cs
using var stream = File.OpenRead("sample.tif");
await Verify(Image.FromStream(stream));
```
<sup><a href='/src/Verify.Tests/Snippets/ConverterSnippets.cs#L46-L51' title='Snippet source file'>snippet source</a> | <a href='#snippet-FileConverterTypeVerify' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

Note that this sample also uses the optional `canConvert` to ensure that only `Image`s that are tiffs are converted.

<!-- snippet: ConverterCanConvert -->
<a id='snippet-ConverterCanConvert'></a>
```cs
canConvert: (target, context) => Equals(target.RawFormat, ImageFormat.Tiff),
```
<sup><a href='/src/Verify.Tests/Snippets/ConverterSnippets.cs#L13-L17' title='Snippet source file'>snippet source</a> | <a href='#snippet-ConverterCanConvert' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->


### Expression converter

This sample uses a extension approach. So the converter acts on a file or stream based on the extension (configured or detected).

<!-- snippet: RegisterFileConverterExtension -->
<a id='snippet-RegisterFileConverterExtension'></a>
```cs
VerifierSettings.RegisterFileConverter(
    fromExtension: "tif",
    conversion: (stream, settings) =>
    {
        using var image = Image.FromStream(stream);
        var pages = image.GetFrameCount(FrameDimension.Page);

        var targets = new List<Target>();
        for (var index = 0; index < pages; index++)
        {
            image.SelectActiveFrame(FrameDimension.Page, index);

            var page = new MemoryStream();
            image.Save(page, ImageFormat.Png);
            targets.Add(new("png", page));
        }

        return new(
            info: new
            {
                image.PixelFormat,
                image.Size
            },
            targets);
    });
```
<sup><a href='/src/Verify.Tests/Snippets/ConverterSnippets.cs#L56-L83' title='Snippet source file'>snippet source</a> | <a href='#snippet-RegisterFileConverterExtension' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

<!-- snippet: FileConverterExtensionVerify -->
<a id='snippet-FileConverterExtensionVerify'></a>
```cs
await VerifyFile("sample.tif");
```
<sup><a href='/src/Verify.Tests/Snippets/ConverterSnippets.cs#L87-L89' title='Snippet source file'>snippet source</a> | <a href='#snippet-FileConverterExtensionVerify' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->


### Cleanup

If cleanup needs to occur after verification a callback can be passes to `ConversionResult`:

<!-- snippet: ConversionResultWithCleanup -->
<a id='snippet-ConversionResultWithCleanup'></a>
```cs
return new(
    info: null,
    "bin",
    stream: File.OpenRead(withStreamRequiringCleanupPath),
    cleanup: () =>
    {
        File.Delete(withStreamRequiringCleanupPath);
        return Task.CompletedTask;
    });
```
<sup><a href='/src/Verify.Tests/Converters/TypeConverterTests.cs#L32-L44' title='Snippet source file'>snippet source</a> | <a href='#snippet-ConversionResultWithCleanup' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->


## Shipping

Converters can be shipped as NuGet packages:

 * [Verify.Aspose](https://github.com/VerifyTests/VerifyTests.Aspose): Verification of documents (pdf, docx, xlsx, and pptx) via Aspose.
 * [Verify.EntityFramework](https://github.com/VerifyTests/Verify.EntityFramework): Verification of EntityFramework bits.
 * [Verify.ImageMagick](https://github.com/VerifyTests/Verify.ImageMagick): Verification and comparison of images via [Magick.NET](https://github.com/dlemstra/Magick.NET).
 * [Verify.ImageSharp](https://github.com/VerifyTests/Verify.ImageSharp): Verification of images via [ImageSharp](https://github.com/SixLabors/ImageSharp).
 * [Verify.NServiceBus](https://github.com/NServiceBusExtensions/Verify.NServiceBus): Verify NServiceBus Test Contexts.
 * [Verify.RavenDb](https://github.com/VerifyTests/Verify.RavenDb): Verification of [RavenDb](https://ravendb.net) bits.
 * [Verify.SqlServer](https://github.com/VerifyTests/Verify.SqlServer): Verification of SqlServer bits.
 * [Verify.Syncfusion](https://github.com/VerifyTests/Verify.Syncfusion): Converts documents (pdf, docx, xlsx, and pptx) to png/csv/text for verification.
 * [Verify.Web](https://github.com/VerifyTests/Verify.Web): Verification of web bits.
 * [Verify.WinForms](https://github.com/VerifyTests/Verify.WinForms): Verification of WinForms UIs.
 * [Verify.Xaml](https://github.com/VerifyTests/Verify.Xaml): Verification of Xaml UIs.