Writers

Default Behaviour

By default, when Approval Tests verifies an object, it uses the StringWriter class to write out the string representation of the object.

And by default, StringWriter gives the saved file the extension .txt.

StringWriter implements the ApprovalWriter interface.

Using custom writers

Suppose that you are serialising an object that cannot easily be represented in a text file, such as an image. In this case, the built-in StringWriter is not suitable, and you will need to write and use a custom implementation of ApprovalWriter.

Here is a simple example of using a custom writer to produce an HTML file.

HtmlWriter writer("<h1>hello world</h1>", ".html");
ApprovalTests::Approvals::verify(writer);

(See snippet source)

Using custom filename extensions

Suppose that you are serializing an object in some text format like JSON or CSV. By writing to this file extension, different tools will render it appropriately.

If all you want to do is change the file extension, here is how:

ApprovalTests::Approvals::verify(
    "<h1>hello world</h1>",
    ApprovalTests::Options().fileOptions().withFileExtension(".html"));

(See snippet source)

Empty Files

Most reporters will create a .approved. file if one does not exist, as most diff tools do not handle a missing file well. By default, these empty files are empty text files with an empty string "".

If the file extension is not a text file (for example, a PNG), you will still get this behaviour, which can result in some diff tools saying ‘this is not a valid file’.

ApprovalTests allows for you to customize this behaviour.

For a tool which will help you with this, see EmptyFiles.

Customizing by File Extension

To add new behaviour for a specific file extension, you can register customizations as follows:

ApprovalTests::EmptyFileCreator htmlCreator = [](std::string fileName) {
    ApprovalTests::StringWriter s("<!doctype html><title>TITLE</title>");
    s.write(fileName);
};
ApprovalTests::EmptyFileCreatorByType::registerCreator(".html", htmlCreator);

(See snippet source)

This will leave the creation of files with all other extensions alone, and will last for the remainder of program execution, or until a new creator for this file extension is registered.

Full Customization

Here is an example of replacing the entire empty file creation code, for the lifetime of the disposer.

New .approved. files will be created with minimal, valid HTML content, and everything else will be empty.

ApprovalTests::EmptyFileCreator htmlCreator = [](std::string fileName) {
    std::string contents = "";
    if (ApprovalTests::StringUtils::endsWith(fileName, ".html"))
    {
        contents = "<!doctype html><title>TITLE</title>";
    }
    ApprovalTests::StringWriter s(contents);
    s.write(fileName);
};
auto disposer = ApprovalTests::FileUtils::useEmptyFileCreator(htmlCreator);

(See snippet source)