|
| 1 | +'use strict'; |
| 2 | + |
| 3 | +// V8 uses a different message format when reading properties of null or undefined. |
| 4 | +// Older versions use e.g. "Cannot read property 'world' of undefined" |
| 5 | +// Newer versions use e.g. "Cannot read properties of undefined (reading 'world')" |
| 6 | +// This file overrides the built-in toThrow() matches to handle both cases, |
| 7 | +// enabling the React project to support Node 12-16 witout forking tests. |
| 8 | + |
| 9 | +const toThrowMatchers = require('expect/build/toThrowMatchers').default; |
| 10 | +const builtInToThrow = toThrowMatchers.toThrow; |
| 11 | + |
| 12 | +// Detect the newer stack format: |
| 13 | +let newErrorFormat = false; |
| 14 | +try { |
| 15 | + null.test(); |
| 16 | +} catch (error) { |
| 17 | + if (error.message.includes('Cannot read properties of null')) { |
| 18 | + newErrorFormat = true; |
| 19 | + } |
| 20 | +} |
| 21 | + |
| 22 | +// Detect the message pattern we need to rename: |
| 23 | +const regex = /Cannot read property '([^']+)' of (.+)/; |
| 24 | + |
| 25 | +// Massage strings (written in the older format) to match the newer format |
| 26 | +// if tests are currently running on Node 16+ |
| 27 | +function normalizeErrorMessage(message) { |
| 28 | + if (newErrorFormat) { |
| 29 | + const match = message.match(regex); |
| 30 | + if (match) { |
| 31 | + return `Cannot read properties of ${match[2]} (reading '${match[1]}')`; |
| 32 | + } |
| 33 | + } |
| 34 | + |
| 35 | + return message; |
| 36 | +} |
| 37 | + |
| 38 | +function toThrow(value, expectedValue) { |
| 39 | + if (typeof expectedValue === 'string') { |
| 40 | + expectedValue = normalizeErrorMessage(expectedValue); |
| 41 | + } else if (expectedValue instanceof Error) { |
| 42 | + expectedValue.message = normalizeErrorMessage(expectedValue.message); |
| 43 | + } |
| 44 | + |
| 45 | + return builtInToThrow.call(this, value, expectedValue); |
| 46 | +} |
| 47 | + |
| 48 | +module.exports = { |
| 49 | + toThrow, |
| 50 | +}; |
0 commit comments