-
Notifications
You must be signed in to change notification settings - Fork 1.5k
/
jestSnapshotSerializer.js
152 lines (131 loc) · 4.48 KB
/
jestSnapshotSerializer.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
const path = require('path')
const replaceAll = require('replace-string') // sindre's replaceAll polyfill
const stripAnsi = require('strip-ansi')
const { platformRegex } = require('./platformRegex')
// Pipe utility
const pipe =
(...fns) =>
(x) =>
fns.reduce((v, f) => f(v), x)
function normalizePrismaPaths(str) {
return str
.replace(/prisma\\([\w-]+)\.prisma/g, 'prisma/$1.prisma')
.replace(/prisma\\seed\.ts/g, 'prisma/seed.ts')
.replace(/custom-folder\\seed\.js/g, 'custom-folder/seed.js')
}
function normalizeLogs(str) {
return str
.replace(
/Started query engine http server on http:\/\/127\.0\.0\.1:\d{1,5}/g,
'Started query engine http server on http://127.0.0.1:00000',
)
.replace(/Starting a postgresql pool with \d+ connections./g, 'Starting a postgresql pool with XX connections.')
}
function normalizeTmpDir(str) {
return str.replace(/\/tmp\/([a-z0-9]+)\//g, '/tmp/dir/')
}
function trimErrorPaths(str) {
const parentDir = path.dirname(path.dirname(path.dirname(__dirname)))
return replaceAll(str, parentDir, '')
}
function normalizeToUnixPaths(str) {
// TODO: Windows: this breaks some tests by replacing backslashes outside of file names.
return replaceAll(str, path.sep, '/')
}
function normalizeGitHubLinks(str) {
return str.replace(/https:\/\/github.com\/prisma\/prisma(-client-js)?\/issues\/new\S+/, 'TEST_GITHUB_LINK')
}
function normalizeTsClientStackTrace(str) {
return str
.replace(/([/\\]client[/\\]src[/\\]__tests__[/\\].*test\.ts)(:\d*:\d*)/, '$1:0:0')
.replace(/([/\\]client[/\\]tests[/\\]functional[/\\].*\.ts)(:\d*:\d*)/, '$1:0:0')
}
function removePlatforms(str) {
return str.replace(platformRegex, 'TEST_PLATFORM')
}
// When updating snapshots this is sensitive to OS
// macOS will update extension to .dylib.node, but CI uses .so.node for example
// Note that on Windows the file name doesn't start with "lib".
function normalizeNodeApiLibFilePath(str) {
return str.replace(
/((lib)?query_engine-TEST_PLATFORM.)(.*)(.node)/,
'libquery_engine-TEST_PLATFORM.LIBRARY_TYPE.node',
)
}
function normalizeBinaryFilePath(str) {
return str.replace(/query-engine-TEST_PLATFORM\.exe/, 'query-engine-TEST_PLATFORM')
}
function normalizeMigrateTimestamps(str) {
return str.replace(/(?<!\d)\d{14}(?!\d)/g, '20201231000000')
}
function normalizeDbUrl(str) {
return str.replace(/(localhost|postgres|mysql|mssql|mongodb_migrate|cockroachdb):(\d+)/g, 'localhost:$2')
}
function normalizeRustError(str) {
return str.replace(/\/rustc\/(.+)\//g, '/rustc/hash/').replace(/(\[.*)(:\d*:\d*)(\])/g, '[/some/rust/path:0:0$3')
}
function normalizeArtificialPanic(str) {
return str.replace(/(Command failed with exit code 101:) (.+) /g, '$1 prisma-engines-path ')
}
function normalizeTime(str) {
// sometimes something can take a few seconds when usually it's less than 1s or a few ms
return str.replace(/ \d+ms/g, ' XXXms').replace(/ \d+(\.\d+)?s/g, ' XXXms')
}
/**
* Replace dynamic variable bits of Prisma schema with static strings.
* Only for integration-tests
*/
function prepareSchemaForSnapshot(str) {
if (!str.includes('tmp/prisma-tests/integration-test')) return str
const urlRegex = /url\s*=\s*.+/
const outputRegex = /output\s*=\s*.+/
return str
.split('\n')
.map((line) => {
const urlMatch = urlRegex.exec(line)
if (urlMatch) {
return `${line.slice(0, urlMatch.index)}url = "***"`
}
const outputMatch = outputRegex.exec(line)
if (outputMatch) {
return `${line.slice(0, outputMatch.index)}output = "***"`
}
return line
})
.join('\n')
}
module.exports = {
// Expected by Jest
test(value) {
return typeof value === 'string' || value instanceof Error
},
serialize(value) {
const message = typeof value === 'string' ? value : value instanceof Error ? value.message : ''
// order is important
return pipe(
stripAnsi,
// integration-tests pkg
prepareSchemaForSnapshot,
// Generic
normalizeTmpDir,
normalizeTime,
// From Client package
normalizeGitHubLinks,
removePlatforms,
normalizeNodeApiLibFilePath,
normalizeBinaryFilePath,
normalizeTsClientStackTrace,
trimErrorPaths,
normalizePrismaPaths,
normalizeLogs,
// remove windows \\
normalizeToUnixPaths,
// From Migrate/CLI package
normalizeDbUrl,
normalizeRustError,
normalizeMigrateTimestamps,
// artificial panic
normalizeArtificialPanic,
)(message)
},
}