Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 99 additions & 12 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,16 @@ Extends [Verify](https://github.com/VerifyTests/Verify) to allow verification of

Converts documents pdfs to png for verification.

Verifying a `pdf` produces:

* The pdf itself as `.verified.pdf`. This can be omitted with [`ExcludeTargets`](#choosing-what-is-verified).
* A `.verified.txt` with the page count.
* A png render of every page as `#page_0001.verified.png`, `#page_0002.verified.png`, etc.

Verifying an `svg` produces the svg as `.verified.svg` and a png render of it as `.verified.png`.

The page files are named by Verify's [paged documents](https://github.com/VerifyTests/Verify/blob/main/docs/paged-documents.md) support, which every Verify plugin that splits a document into pages shares. So do the settings that [choose what is verified](#choosing-what-is-verified).

Contains [comparers](https://github.com/VerifyTests/Verify/blob/master/docs/comparer.md) for png, jpg, bmp, and tiff.


Expand Down Expand Up @@ -50,25 +60,55 @@ public static void Init()
`Initialize` registers the pdf to png converter and all comparers.


### Outputs
### Choosing what is verified

`Initialize` accepts an optional `ImageMagickOutputs` flags enum that controls, globally, which outputs a document is split into:
What a pdf or an svg is split into is controlled by Verify's settings for [paged documents](https://github.com/VerifyTests/Verify/blob/main/docs/paged-documents.md), which replace the options this plugin had of its own.

* `Png`: render pdf pages and svg documents to png.
* `None`: none of the above. Only the source document is emitted.
* `All`: all of the above. This is the default.
`PagesToInclude` limits the pages of a pdf that are verified, to its first pages or to those a delegate accepts. The pdf itself is still verified whole, and the info file still holds the number of pages it has:

Omitted outputs are skipped before any rendering, so no work is done for them. The source document target (pdf or svg) is always emitted; use `VerifierSettings.ExcludeTargets("pdf")` to exclude it. Png, webp, and tiff image files are not affected. To emit only the source document, pass `ImageMagickOutputs.None`:
<!-- snippet: PagesToInclude -->
<a id='snippet-PagesToInclude'></a>
```cs
[Test]
public Task PagesToInclude() =>
VerifyFile("sample.pdf")
.PagesToInclude(1);
```
<sup><a href='/src/Tests/Samples.cs#L51-L58' title='Snippet source file'>snippet source</a> | <a href='#snippet-PagesToInclude' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

`ExcludeDerivedTargets("png")` leaves out the png renders, keeping the pdf or the svg. The render is skipped rather than dropped afterwards. The pages of a pdf are then only counted, so its info file still says how many there are:

<!-- snippet: ExcludeDerivedTargets -->
<a id='snippet-ExcludeDerivedTargets'></a>
```cs
[Test]
public Task ExcludeDerivedTargets() =>
VerifyFile("sample.pdf")
.ExcludeDerivedTargets("png");
```
<sup><a href='/src/Tests/Samples.cs#L60-L67' title='Snippet source file'>snippet source</a> | <a href='#snippet-ExcludeDerivedTargets' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

It applies to a png rendered from a pdf or an svg. A png, webp or tiff that is itself being verified is not affected.

`ExcludeTargets("pdf")` leaves out the pdf, keeping its pages and its info file. A [password-protected pdf](#open-password-protected-pdfs) requires it.

Each can also be set for every test, on `VerifierSettings`:

<!-- snippet: InitializeOutputs -->
<a id='snippet-InitializeOutputs'></a>
```cs
[ModuleInitializer]
public static void Init() =>
// Only emit the source document. Skip rendering to png.
VerifyImageMagick.Initialize(ImageMagickOutputs.None);
public static void Init()
{
VerifyImageMagick.Initialize();

// For every test: no png, so only the source document is verified
VerifierSettings.ExcludeDerivedTargets("png");
}
```
<sup><a href='/src/StaticSettingsTests/ModuleInitializer.cs#L3-L10' title='Snippet source file'>snippet source</a> | <a href='#snippet-InitializeOutputs' title='Start of snippet'>anchor</a></sup>
<sup><a href='/src/StaticSettingsTests/ModuleInitializer.cs#L3-L14' title='Snippet source file'>snippet source</a> | <a href='#snippet-InitializeOutputs' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->


Expand Down Expand Up @@ -112,9 +152,21 @@ public Task VerifyPdfStream()

#### Result

[Samples.VerifyPdf#00.verified.png](/src/Tests/Samples.VerifyPdf#00.verified.png):
[Samples.VerifyPdf.verified.txt](/src/Tests/Samples.VerifyPdf.verified.txt):

<!-- snippet: Samples.VerifyPdf.verified.txt -->
<a id='snippet-Samples.VerifyPdf.verified.txt'></a>
```txt
{
PageCount: 2
}
```
<sup><a href='/src/Tests/Samples.VerifyPdf.verified.txt#L1-L3' title='Snippet source file'>snippet source</a> | <a href='#snippet-Samples.VerifyPdf.verified.txt' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

<img src="/src/Tests/Samples.VerifyPdf%2300.verified.png" width="200px">
[Samples.VerifyPdf#page_0001.verified.png](/src/Tests/Samples.VerifyPdf%23page_0001.verified.png):

<img src="/src/Tests/Samples.VerifyPdf%23page_0001.verified.png" width="200px">


### Image Comparers
Expand Down Expand Up @@ -174,6 +226,41 @@ public Task PdfPassword() =>
<sup><a href='/src/Tests/Samples.cs#L22-L30' title='Snippet source file'>snippet source</a> | <a href='#snippet-PdfPassword' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->


## Reviewing changes

A change to a pdf is a change to several files: the pdf, its info file, and every page. Verify tells the diff tool that the pages and the info file were derived from the pdf, and [DiffEngineViewer](https://github.com/VerifyTests/DiffEngine/blob/main/docs/viewer.md#files-derived-from-a-document), which draws a pdf's pages itself, shows them as one row and accepts them together. Other diff tools are given each file, as before. The png of an svg is derived from the svg in the same way.

When the pdf or the svg has itself changed, what was derived from it is compared exactly, skipping any [comparer](#image-comparers) registered for png. ImageMagick writes the time into every png it renders, so every page of a changed pdf is then reported as changed, whether or not it draws differently.


## Migrating from 3.x

Version 4 moves to the paged document support in Verify 33.3. The options of this plugin that chose what was verified are now settings of Verify:

| 3.x | 4.x |
| --- | --- |
| `Initialize(ImageMagickOutputs.None)` | `Initialize()` and `VerifierSettings.ExcludeDerivedTargets("png")` |
| `Initialize(ImageMagickOutputs.Png)` or `Initialize(ImageMagickOutputs.All)` | `Initialize()` |
| `.PagesToInclude(2)`, an extension method of this plugin | `.PagesToInclude(2)`, a member of Verify's `SettingsTask` and `VerifySettings` |

A call to `PagesToInclude` compiles unchanged. It can now also take a delegate, and both it and `ExcludeDerivedTargets` can be set for one verification or, on `VerifierSettings`, for all of them.

The page of a pdf is named by its number, which is 1 based. It was named by an index, which was 0 based and missing for a pdf with one page. A pdf also has an info file now, holding its page count:

| 3.x | 4.x |
| --- | --- |
| `Tests.Report#00.verified.png` | `Tests.Report#page_0001.verified.png` |
| `Tests.Report#01.verified.png` | `Tests.Report#page_0002.verified.png` |
| `Tests.Report.verified.png`, of a pdf with one page | `Tests.Report#page_0001.verified.png` |
| `Tests.Mail#Attachment.00.verified.png`, of a pdf that is a target named `Attachment` | `Tests.Mail#Attachment.page_0001.verified.png` |
| | `Tests.Report.verified.txt`, the info file |

The `.verified.pdf` is unchanged, and so are the `.verified.svg` and `.verified.png` of an svg.

Renamed snapshots show as a new file and a pending delete. Accepting both, or running once with [AutoVerify](https://github.com/VerifyTests/Verify/blob/main/docs/autoverify.md), moves a test over. A page draws as it did, but ImageMagick writes the time into every png it renders, so an accepted page differs from the file it replaces by those bytes, and source control shows a rename with a small change.


## Icon

[Swirl](https://thenounproject.com/term/wizard/2744075/) designed by [Philipp Petzka](https://thenounproject.com/masteroficon) from [The Noun Project](https://thenounproject.com/).
2 changes: 1 addition & 1 deletion src/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<Project>
<PropertyGroup>
<NoWarn>CS1591</NoWarn>
<Version>3.11.0</Version>
<Version>4.0.0</Version>
<AssemblyVersion>1.0.0</AssemblyVersion>
<ImplicitUsings>enable</ImplicitUsings>
<LangVersion>preview</LangVersion>
Expand Down
6 changes: 3 additions & 3 deletions src/Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@
<PackageVersion Include="ProjectFiles" Version="1.6.0" />
<PackageVersion Include="Sbom" Version="0.3.1" />
<PackageVersion Include="TUnit" Version="1.72.16" />
<PackageVersion Include="Verify" Version="33.2.0" />
<PackageVersion Include="Verify.TUnit" Version="33.2.0" />
<PackageVersion Include="Verify" Version="33.3.0" />
<PackageVersion Include="Verify.TUnit" Version="33.3.0" />
<PackageVersion Include="Argon" Version="0.37.0" />
<PackageVersion Include="DiffEngine" Version="20.6.0" />
<PackageVersion Include="DiffEngine" Version="20.7.0" />
<PackageVersion Include="EmptyFiles" Version="8.20.0" />
<PackageVersion Include="SimpleInfoName" Version="3.2.0" />
</ItemGroup>
Expand Down
10 changes: 7 additions & 3 deletions src/StaticSettingsTests/ModuleInitializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@ public static class ModuleInitializer
#region InitializeOutputs

[ModuleInitializer]
public static void Init() =>
// Only emit the source document. Skip rendering to png.
VerifyImageMagick.Initialize(ImageMagickOutputs.None);
public static void Init()
{
VerifyImageMagick.Initialize();

// For every test: no png, so only the source document is verified
VerifierSettings.ExcludeDerivedTargets("png");
}

#endregion
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
PageCount: 2
}
6 changes: 3 additions & 3 deletions src/Tests/Ghostscript.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ static class Ghostscript
// Replaces the pdf converter registered by Initialize with one that treats that as inconclusive,
// so pdf tests do not fail on machines that do not have Ghostscript installed.
public static void RegisterPdfConverter() =>
VerifierSettings.RegisterStreamConverter("pdf", Convert);
VerifierSettings.RegisterStreamConverter("pdf", (_, stream, context) => Convert(stream, context));

static ConversionResult Convert(string? name, Stream stream, IReadOnlyDictionary<string, object> context)
static ConversionResult Convert(Stream stream, IReadOnlyDictionary<string, object> context)
{
try
{
return VerifyImageMagick.Convert(name, stream, context, MagickFormat.Pdf);
return VerifyImageMagick.Convert(stream, context, MagickFormat.Pdf);
}
catch (MagickDelegateErrorException exception)
when (exception.Message.Contains("(127)"))
Expand Down
3 changes: 3 additions & 0 deletions src/Tests/PasswordSamples.PasswordSample.verified.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
PageCount: 2
}
Binary file not shown.
3 changes: 3 additions & 0 deletions src/Tests/Samples.ExcludeDerivedTargets.verified.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
PageCount: 2
}
Binary file added src/Tests/Samples.PagesToInclude.verified.pdf
Binary file not shown.
3 changes: 3 additions & 0 deletions src/Tests/Samples.PagesToInclude.verified.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
PageCount: 2
}
3 changes: 3 additions & 0 deletions src/Tests/Samples.PdfPassword.verified.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
PageCount: 2
}
3 changes: 3 additions & 0 deletions src/Tests/Samples.VerifyPdf.verified.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
PageCount: 2
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions src/Tests/Samples.VerifyPdfStream.verified.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
PageCount: 2
}
18 changes: 18 additions & 0 deletions src/Tests/Samples.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,24 @@ public Task VerifyPdfStream()

#endregion

#region PagesToInclude

[Test]
public Task PagesToInclude() =>
VerifyFile("sample.pdf")
.PagesToInclude(1);

#endregion

#region ExcludeDerivedTargets

[Test]
public Task ExcludeDerivedTargets() =>
VerifyFile("sample.pdf")
.ExcludeDerivedTargets("png");

#endregion

[Test]
public Task VerifySvg() =>
VerifyFile(ProjectFiles.sample_svg.Path);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
PageCount: 2
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
PageCount: 2
}
Binary file added src/Tests/Tests.PagesToInclude.verified.pdf
Binary file not shown.
3 changes: 3 additions & 0 deletions src/Tests/Tests.PagesToInclude.verified.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
PageCount: 2
}
3 changes: 3 additions & 0 deletions src/Tests/Tests.SkipPdfNormalization.verified.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
PageCount: 2
}
3 changes: 3 additions & 0 deletions src/Tests/Tests.VerifyPdf.verified.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
PageCount: 2
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions src/Tests/Tests.VerifyPdfWithName#name.verified.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
PageCount: 2
}
Binary file added src/Tests/Tests.VerifySvgWithName#name.verified.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 23 additions & 0 deletions src/Tests/Tests.VerifySvgWithName#name.verified.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions src/Tests/Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -176,4 +176,14 @@ public Task SkipPdfNormalization() =>
[Test]
public Task VerifyPdfWithName() =>
Verify(targets: [new("pdf", ProjectFiles.sample_pdf.OpenRead(), "name")]);

[Test]
public Task VerifySvgWithName() =>
Verify(targets: [new("svg", ProjectFiles.transparent_svg.OpenRead(), "name")]);

// A page keeps its number when the pages before it are left out, so this is #page_0002.
[Test]
public Task PagesToInclude() =>
VerifyFile(ProjectFiles.sample_pdf.Path)
.PagesToInclude(_ => _ == 2);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
PageCount: 1
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
PageCount: 1
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
PageCount: 1
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
PageCount: 1
}
1 change: 0 additions & 1 deletion src/Verify.ImageMagick/GlobalUsings.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
global using DeterministicPdf;
global using System.Diagnostics.CodeAnalysis;
global using EmptyFiles;
global using ImageMagick;
global using ImageMagick.Formats;
Expand Down
23 changes: 0 additions & 23 deletions src/Verify.ImageMagick/ImageMagickOutputs.cs

This file was deleted.

Loading
Loading