Repository navigation
Expand file tree
/
Copy pathjest.setup.js
More file actions
98 lines (90 loc) · 3.53 KB
/
Copy pathjest.setup.js
File metadata and controls
98 lines (90 loc) · 3.53 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
/**
* jsdom ships no TextEncoder; @noble/hashes (the substrate's command signer)
* needs one. Node's real implementation, so the suite exercises what the
* browser will. Mirrors newspack-nodes/jest.setup.js.
*/
const { TextEncoder, TextDecoder } = require( 'util' );
global.TextEncoder = global.TextEncoder || TextEncoder;
global.TextDecoder = global.TextDecoder || TextDecoder;
/* eslint-env jest */
// jest-dom custom matchers (toBeInTheDocument, etc.) for the React dashboard tests.
import '@testing-library/jest-dom';
// Jest setup — FAIL any test that emits an unexpected console.warn or
// console.error (mirrors the sibling newspack-nodes setup).
//
// The substrate's `Core.stderr()` and `printLessOften()`
// (newspack-nodes/src/runtime/core.js) route node faults, rate-limited logs, and
// dropped-message notices through console.warn (never console.error, to skip
// devtools' error counter), each line stamped `YYYY-MM-DD HH:MM:SS <zone> <argv0>: `.
// Those are expected spam on any test exercising a fault path, so warn lines
// matching that signature are dropped. EVERY other console.warn and EVERY
// console.error (React `act(...)` warnings, third-party deprecations like
// @wordpress/components' 36px notice, genuine errors) is recorded and re-thrown
// in afterEach, failing the test. Throwing in afterEach — not inside the mock —
// keeps React's render/commit from swallowing the throw or cascading into
// confusing secondary failures, and the captured Error preserves the call site.
//
// Tests that legitimately assert on console.warn/error install their own
// `jest.spyOn( console, … )`; that shadows the recorder for that test and the
// afterEach restore unwinds both.
// The Core.stderr() line prefix: ISO-ish date + " <zone> <argv0>: ".
// The zone token is constrained to the shapes Intl actually emits — a bare
// `\S+` there matches any `<date> <time> <word> <word>: ` warning text and
// strips it, which is the gate swallowing the very lines it exists to report.
const SUBSTRATE_STDERR =
/^\d{4}-\d\d-\d\d \d\d:\d\d:\d\d (?:UTC|GMT[+-][\d:]+|[A-Z]{2,5}) \S+: /;
let violations = [];
const record =
( channel ) =>
( ...args ) => {
if (
'warn' === channel &&
'string' === typeof args[ 0 ] &&
SUBSTRATE_STDERR.test( args[ 0 ] )
) {
return;
}
violations.push(
new Error(
`Unexpected console.${ channel }: ${ args
.map( String )
.join( ' ' ) }`
)
);
};
beforeEach( () => {
violations = [];
jest.spyOn( console, 'warn' ).mockImplementation( record( 'warn' ) );
jest.spyOn( console, 'error' ).mockImplementation( record( 'error' ) );
} );
afterEach( () => {
const captured = violations;
violations = [];
if ( jest.isMockFunction( console.warn ) ) {
console.warn.mockRestore();
}
if ( jest.isMockFunction( console.error ) ) {
console.error.mockRestore();
}
if ( captured.length ) {
throw captured[ 0 ];
}
} );
// @longform
// The substrate's emitters hold until authenticated, and this plugin inlines
// that runtime — so the harness authenticates too, or every poll test asserts
// silence. Guarded on `window`: node-environment suites must not pull in the
// browser runtime graph. Mirrors newspack-nodes/jest.setup.js.
if ( 'undefined' !== typeof window ) {
const auth = require( '@newspack-nodes/runtime' );
beforeEach( async () => {
auth.forgetSession();
auth.__setAuthFetch( async () => ( {
handle: 'e2e11111e2e22222e2e33333e2e44444',
secret: 'jest-harness-session-secret',
expires_in: 3600,
now: Math.floor( Date.now() / 1000 ),
} ) );
await auth.ensureSession();
} );
}