-
Notifications
You must be signed in to change notification settings - Fork 14
Expand file tree
/
Copy pathtest-logger.ts
More file actions
107 lines (99 loc) · 3.9 KB
/
test-logger.ts
File metadata and controls
107 lines (99 loc) · 3.9 KB
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
import { Logger } from '../types/logging'
import { LogSnapshotConfig } from '../types/testing'
import { asJson } from '../util'
/** Exposes an AlgoKit logger which captures log messages, while wrapping an original logger.
* This is useful for automated testing.
*/
export class TestLogger implements Logger {
private originalLogger: Logger | undefined
private logs: string[]
/**
* Unique property marker for Symbol.hasInstance compatibility across module boundaries
*/
private readonly _isTestLogger = true
/**
* Custom Symbol.hasInstance to handle dual package hazard
* @param instance - The instance to check
* @returns true if the instance is of the Type of the class, regardless of which module loaded it
*/
static [Symbol.hasInstance](instance: unknown): boolean {
return !!(instance && (instance as TestLogger)._isTestLogger === true)
}
/**
* Create a new test logger that wraps the given logger if provided.
* @param originalLogger The optional original logger to wrap.
*/
constructor(originalLogger?: Logger) {
this.originalLogger = originalLogger
this.logs = []
}
/** Returns all logs captured thus far. */
get capturedLogs(): string[] {
return this.logs
}
/** Clears all logs captured so far. */
clear() {
this.logs = []
}
/**
* Returns a captured log snapshot.
* This helps ensure that the provided configuration items won't appear
* with random values in the log snapshot, but rather will get substituted with predictable ids.
*
* https://jestjs.io/docs/snapshot-testing#2-tests-should-be-deterministic
*
* @example Jest Example
* ```typescript
* const logger = new TestLogger()
* ...
* expect(logger.getLogSnapshot()).toMatchSnapshot()
* ```
* @param config The snapshot configuration
* @returns The snapshotted logs.
*/
getLogSnapshot(config?: LogSnapshotConfig) {
const { transactions: transactionIds, accounts, apps } = config ?? {}
let snapshot = this.capturedLogs.filter(config?.filterPredicate ?? (() => true)).join('\n')
transactionIds?.forEach(
(txn, id) => (snapshot = snapshot.replace(new RegExp(typeof txn === 'string' ? txn : txn.txID(), 'g'), `TXID_${id + 1}`)),
)
accounts?.forEach(
(sender, id) =>
(snapshot = snapshot.replace(
new RegExp(
typeof sender === 'string'
? sender
: 'addr' in sender
? sender.addr.toString()
: 'address' in sender
? sender.address().toString()
: sender.toString(),
'g',
),
`ACCOUNT_${id + 1}`,
)),
)
apps?.forEach((app, id) => (snapshot = snapshot.replace(new RegExp(`\\b${app.toString()}\\b(?! bytes)`, 'g'), `APP_${id + 1}`)))
return snapshot
}
error(message: string, ...optionalParams: unknown[]): void {
this.originalLogger?.error(message, ...optionalParams)
this.logs.push(`ERROR: ${message}${optionalParams.length ? ` | ${asJson(optionalParams)}` : ''}`)
}
warn(message: string, ...optionalParams: unknown[]): void {
this.originalLogger?.warn(message, ...optionalParams)
this.logs.push(`WARN: ${message}${optionalParams.length ? ` | ${asJson(optionalParams)}` : ''}`)
}
info(message: string, ...optionalParams: unknown[]): void {
this.originalLogger?.info(message, ...optionalParams)
this.logs.push(`INFO: ${message}${optionalParams.length ? ` | ${asJson(optionalParams)}` : ''}`)
}
verbose(message: string, ...optionalParams: unknown[]): void {
this.originalLogger?.verbose(message, ...optionalParams)
this.logs.push(`VERBOSE: ${message}${optionalParams.length ? ` | ${asJson(optionalParams)}` : ''}`)
}
debug(message: string, ...optionalParams: unknown[]): void {
this.originalLogger?.debug(message, ...optionalParams)
this.logs.push(`DEBUG: ${message}${optionalParams.length ? ` | ${asJson(optionalParams)}` : ''}`)
}
}