Skip to content

Commit

Permalink
feat: add failOnMissingSnapshot option (#70)
Browse files Browse the repository at this point in the history
* feat: add new options

* feat: impl

* chore: typo

* feat: simplify comparison options (#74)

* feat: reduce and simplify options

* fix: set failOnMissingSnapshot to false in test
  • Loading branch information
moshensky authored Sep 26, 2024
1 parent 5f90768 commit 4e852a0
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 20 deletions.
44 changes: 44 additions & 0 deletions src/compare-pdf-to-snapshot.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,4 +193,48 @@ describe('comparePdfToSnapshot()', () => {
.then(() => unlinkSync(snapshotPath))
})
})

describe('when reference snapshot does not exist', () => {
it('should be created when `failOnMissingSnapshot` is not set', () => {
const snapshotName = 'allow-create-snapshot-when-failOnMissingSnapshot-is-not-set'
const snapshotPath = join(__dirname, snapshotsDirName, snapshotName + '.png')
if (existsSync(snapshotPath)) {
unlinkSync(snapshotPath)
}
return comparePdfToSnapshot(singlePageSmallPdfPath, __dirname, snapshotName).then((x) => {
assert.strictEqual(x, true)
assert.strictEqual(existsSync(snapshotPath), true, 'Snapshot should be created')
unlinkSync(snapshotPath)
})
})

it('should be created when `failOnMissingSnapshot` is set to `false`', () => {
const snapshotName = 'allow-create-snapshot-when-failOnMissingSnapshot-is-set-to-false'
const snapshotPath = join(__dirname, snapshotsDirName, snapshotName + '.png')
if (existsSync(snapshotPath)) {
unlinkSync(snapshotPath)
}
return comparePdfToSnapshot(singlePageSmallPdfPath, __dirname, snapshotName, {
failOnMissingSnapshot: false,
}).then((x) => {
assert.strictEqual(x, true)
assert.strictEqual(existsSync(snapshotPath), true, 'Snapshot should be created')
unlinkSync(snapshotPath)
})
})

it('should not be created and return `false` when `failOnMissingSnapshot` is set to `true`', () => {
const snapshotName = 'fail-on-missing-snapshot-when-failOnMissingSnapshot-is-set-to-true'
const snapshotPath = join(__dirname, snapshotsDirName, snapshotName + '.png')
if (existsSync(snapshotPath)) {
unlinkSync(snapshotPath)
}
return comparePdfToSnapshot(singlePageSmallPdfPath, __dirname, snapshotName, {
failOnMissingSnapshot: true,
}).then((x) => {
assert.strictEqual(x, false)
assert.strictEqual(existsSync(snapshotPath), false, 'Snapshot should not be created')
})
})
})
})
61 changes: 41 additions & 20 deletions src/compare-pdf-to-snapshot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,56 +100,77 @@ export type CompareOptions = {
maskRegions?: MaskRegions
/** {@inheritDoc PdfToPngOptions} */
pdf2PngOptions?: PdfToPngOptions
/**
* Whether a missing snapshot should cause the comparison to fail.
*
* @defaultValue false
*/
failOnMissingSnapshot?: boolean
}

export const snapshotsDirName = '__snapshots__'

/**
* Compares a PDF to a persisted snapshot. If a snapshot does not exists, one is
* created.
* Compares a PDF to a persisted snapshot, with behavior for handling missing snapshots
* controlled by the `failOnMissingSnapshot` option.
*
* @remarks
* When the function is executed, it has following **side effects**:
* - If a previous snapshot file does not exist, the PDF is converted to an
* image, saved as a snapshot, and the function returns `true`.
* - If a snapshot exists, the PDF is converted to an image and compared to the
* snapshot:
* - If they differ, the function returns `false` and creates two additional
* images next to the snapshot: one with the suffix `new` (the current view
* of the PDF as an image) and one with the suffix `diff` (showing the
* difference between the snapshot and the `new` image).
* - If they are equal, the function returns `true`. If `new` and `diff`
* versions are present, they are deleted.
* The function has the following **side effects**:
* - If no snapshot exists:
* - If `failOnMissingSnapshot` is `false` (default), the PDF is converted to an image,
* saved as a new snapshot, and the function returns `true`.
* - If `failOnMissingSnapshot` is `true`, the function returns `false` without creating a new snapshot.
* - If a snapshot exists, the PDF is converted to an image and compared to the snapshot:
* - If they differ, the function returns `false` and creates two additional images
* next to the snapshot: one with the suffix `new` (the current view of the PDF as an image)
* and one with the suffix `diff` (showing the difference between the snapshot and the `new` image).
* - If they are equal, the function returns `true`. If `new` and `diff` versions are present, they are deleted.
*
* @param pdf - Path to the PDF file or a Buffer containing the PDF.
* @param snapshotDir - Path to the directory where the `__snapshots__` folder will be created.
* @param snapshotName - Unique name for the snapshot within the specified path.
* @param options - Options for comparison, including tolerance, mask regions, and behavior
* regarding missing snapshots. See {@link CompareOptions} for more details.
*
* @returns
* A promise that resolves to `true` if the PDF matches the snapshot or
* if a new snapshot is created, and `false` if the PDF differs from the snapshot.
* A promise that resolves to `true` if the PDF matches the snapshot or if the behavior
* allows for missing snapshots. Resolves to `false` if the PDF differs from the snapshot
* or if `failOnMissingSnapshot` is `true` and no snapshot exists.
*/
export function comparePdfToSnapshot(
/** Path to the PDF file or a Buffer containing the PDF. */
pdf: string | Buffer,
/** Path to the directory where `__snapshots__` folder will be created. */
snapshotDir: string,
/** Unique name for the snapshot within the specified path. */
snapshotName: string,
/** Check the type for available options. */
options?: CompareOptions,
): Promise<boolean> {
const { maskRegions = () => [], pdf2PngOptions, ...restOpts } = options || {}
const {
maskRegions = () => [],
pdf2PngOptions,
failOnMissingSnapshot = false,
...restOpts
} = options || {}
const dir = path.join(snapshotDir, snapshotsDirName)
if (!existsSync(dir)) {
mkdirSync(dir, { recursive: true })
}

const snapshotPath = path.join(dir, snapshotName + '.png')

// If the snapshot doesn't exist
if (!existsSync(snapshotPath)) {
// If we shouldn't generate a snapshot fail.
if (failOnMissingSnapshot) {
return Promise.resolve(false)
}

// Proceed with snapshot generation
return pdf2png(pdf, pdf2PngOptions)
.then(maskImgWithRegions(maskRegions))
.then(writeImages(snapshotPath))
.then(() => true)
}

// If the snapshot exists, perform comparison
return pdf2png(pdf, pdf2PngOptions)
.then(maskImgWithRegions(maskRegions))
.then((images) =>
Expand Down

0 comments on commit 4e852a0

Please sign in to comment.