1 | 'use strict'
|
2 |
|
3 | const fs = require('fs')
|
4 | const mkdirp = require('mkdirp')
|
5 | const path = require('path')
|
6 | const rimraf = require('rimraf')
|
7 | const cwd = process.cwd()
|
8 |
|
9 | class Snapshot {
|
10 | constructor (test) {
|
11 | this.indexes = new Map()
|
12 | this.test = test
|
13 |
|
14 | this.file = path.resolve(
|
15 | cwd,
|
16 | 'tap-snapshots',
|
17 | this.test.fullname.trim().replace(/[^a-zA-Z0-9\._\-]+/g, '-')
|
18 | ) + '.test.js'
|
19 | this.snapshot = null
|
20 | }
|
21 |
|
22 |
|
23 | read (message) {
|
24 | const index = +this.indexes.get(message) || 1
|
25 | this.indexes.set(message, index + 1)
|
26 | try {
|
27 | this.snapshot = this.snapshot || require(this.file)
|
28 | } catch (er) {
|
29 | throw new Error(
|
30 | 'Snapshot file not found: ' + this.file + '\n' +
|
31 | 'Run with TAP_SNAPSHOT=1 in the environment\n' +
|
32 | 'to create snapshot files'
|
33 | )
|
34 | }
|
35 |
|
36 | const entry = message + ' ' + index
|
37 | const s = this.snapshot[entry]
|
38 | if (s === undefined)
|
39 | throw new Error(
|
40 | 'Snapshot entry not found: "' + entry + '"\n' +
|
41 | 'Run with TAP_SNAPSHOT=1 in the environment\n' +
|
42 | 'to create snapshots'
|
43 | )
|
44 |
|
45 | return s.replace(/^\n|\n$/g, '')
|
46 | }
|
47 |
|
48 | snap (data, message) {
|
49 | const index = +this.indexes.get(message) || 1
|
50 | this.indexes.set(message, index + 1)
|
51 | this.snapshot = this.snapshot || {}
|
52 | this.snapshot[message + ' ' + index] = data
|
53 | }
|
54 |
|
55 | save () {
|
56 | if (!this.snapshot)
|
57 | rimraf.sync(this.file)
|
58 | else {
|
59 | const escape = s => s
|
60 | .replace(/\\/g, '\\\\')
|
61 | .replace(/\`/g, '\\\`')
|
62 | .replace(/\$\{/g, '\\${')
|
63 |
|
64 | const data =
|
65 | '/* IMPORTANT\n' +
|
66 | ' * This snapshot file is auto-generated, but designed for humans.\n' +
|
67 | ' * It should be checked into source control and tracked carefully.\n' +
|
68 | ' * Re-generate by setting TAP_SNAPSHOT=1 and running tests.\n' +
|
69 | ' * Make sure to inspect the output below. Do not ignore changes!\n' +
|
70 | ' */\n\'use strict\'\n' + (
|
71 | Object.keys(this.snapshot).sort().map(s =>
|
72 | `exports[\`${
|
73 | escape(s)
|
74 | }\`] = \`\n${
|
75 | escape(this.snapshot[s])
|
76 | }\n\`\n`).join('\n'))
|
77 | mkdirp.sync(path.dirname(this.file))
|
78 | const writeFile = require('write-file-atomic')
|
79 | writeFile.sync(this.file, data, 'utf8')
|
80 | }
|
81 | }
|
82 | }
|
83 |
|
84 | module.exports = Snapshot
|