Skip to content

Commit

Permalink
Added Jest serializer for Hooks (to sanitize source location)
Browse files Browse the repository at this point in the history
  • Loading branch information
Brian Vaughn committed Jun 25, 2021
1 parent 5cb562d commit cf8a93a
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 29 deletions.
60 changes: 60 additions & 0 deletions packages/react-devtools-shared/src/__tests__/hookSerializer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
function hasAbsoluteFileName(hook) {
const fileName = hook.hookSource ? hook.hookSource.fileName : null;
if (fileName == null) {
return false;
} else {
return fileName.indexOf('/react-devtools-shared/') > 0;
}
}

function serializeHook(hook) {
if (!hook.hookSource) return hook;

// Remove user-specific portions of this file path.
let fileName = hook.hookSource.fileName;
const index = fileName.lastIndexOf('/react-devtools-shared/');
fileName = fileName.substring(index + 1);

let subHooks = hook.subHooks;
if (subHooks) {
subHooks = subHooks.map(serializeHook);
}

return {
...hook,
hookSource: {
...hook.hookSource,
fileName,

// Otherwise changes in any test case or formatting might invalidate other tests.
columnNumber: 'removed by Jest serializer',
lineNumber: 'removed by Jest serializer',
},
subHooks,
};
}

// test() is part of Jest's serializer API
export function test(maybeHook) {
if (maybeHook === null || typeof maybeHook !== 'object') {
return false;
}

const hasOwnProperty = Object.prototype.hasOwnProperty.bind(maybeHook);

return (
hasOwnProperty('id') &&
hasOwnProperty('isStateEditable') &&
hasOwnProperty('name') &&
hasOwnProperty('subHooks') &&
hasOwnProperty('value') &&
// Don't re-process an already printed hook.
hasAbsoluteFileName(maybeHook)
);
}

// print() is part of Jest's serializer API
export function print(hook, serialize, indent) {
// Don't stringify this object; that would break nested serializers.
return serialize(serializeHook(hook));
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ describe('InspectedElement', () => {
let BridgeContext;
let InspectedElementContext;
let InspectedElementContextController;
let SettingsContextController;
let StoreContext;
let TreeContextController;

Expand Down Expand Up @@ -57,6 +58,8 @@ describe('InspectedElement', () => {
.InspectedElementContext;
InspectedElementContextController = require('react-devtools-shared/src/devtools/views/Components/InspectedElementContext')
.InspectedElementContextController;
SettingsContextController = require('react-devtools-shared/src/devtools/views/Settings/SettingsContext')
.SettingsContextController;
StoreContext = require('react-devtools-shared/src/devtools/views/context')
.StoreContext;
TreeContextController = require('react-devtools-shared/src/devtools/views/Components/TreeContext')
Expand All @@ -79,15 +82,17 @@ describe('InspectedElement', () => {
}) => (
<BridgeContext.Provider value={bridge}>
<StoreContext.Provider value={store}>
<TreeContextController
defaultSelectedElementID={defaultSelectedElementID}
defaultSelectedElementIndex={defaultSelectedElementIndex}>
<React.Suspense fallback="Loading...">
<InspectedElementContextController>
{children}
</InspectedElementContextController>
</React.Suspense>
</TreeContextController>
<SettingsContextController>
<TreeContextController
defaultSelectedElementID={defaultSelectedElementID}
defaultSelectedElementIndex={defaultSelectedElementIndex}>
<React.Suspense fallback="Loading...">
<InspectedElementContextController>
{children}
</InspectedElementContextController>
</React.Suspense>
</TreeContextController>
</SettingsContextController>
</StoreContext.Provider>
</BridgeContext.Provider>
);
Expand Down Expand Up @@ -152,6 +157,12 @@ describe('InspectedElement', () => {
"events": undefined,
"hooks": Array [
Object {
"hookSource": Object {
"columnNumber": "removed by Jest serializer",
"fileName": "react-devtools-shared/src/__tests__/inspectedElement-test.js",
"functionName": "Example",
"lineNumber": "removed by Jest serializer",
},
"id": 0,
"isStateEditable": true,
"name": "State",
Expand Down Expand Up @@ -1036,6 +1047,12 @@ describe('InspectedElement', () => {
expect(inspectedElement.hooks).toMatchInlineSnapshot(`
Array [
Object {
"hookSource": Object {
"columnNumber": "removed by Jest serializer",
"fileName": "react-devtools-shared/src/__tests__/inspectedElement-test.js",
"functionName": "Example",
"lineNumber": "removed by Jest serializer",
},
"id": 0,
"isStateEditable": true,
"name": "State",
Expand All @@ -1057,6 +1074,12 @@ describe('InspectedElement', () => {
expect(inspectedElement.hooks).toMatchInlineSnapshot(`
Array [
Object {
"hookSource": Object {
"columnNumber": "removed by Jest serializer",
"fileName": "react-devtools-shared/src/__tests__/inspectedElement-test.js",
"functionName": "Example",
"lineNumber": "removed by Jest serializer",
},
"id": 0,
"isStateEditable": true,
"name": "State",
Expand Down Expand Up @@ -1542,6 +1565,12 @@ describe('InspectedElement', () => {
"events": undefined,
"hooks": Array [
Object {
"hookSource": Object {
"columnNumber": "removed by Jest serializer",
"fileName": "react-devtools-shared/src/__tests__/inspectedElement-test.js",
"functionName": "Example",
"lineNumber": "removed by Jest serializer",
},
"id": null,
"isStateEditable": false,
"name": "Context",
Expand Down Expand Up @@ -1794,11 +1823,23 @@ describe('InspectedElement', () => {
expect(hooks).toMatchInlineSnapshot(`
Array [
Object {
"hookSource": Object {
"columnNumber": "removed by Jest serializer",
"fileName": "react-devtools-shared/src/__tests__/inspectedElement-test.js",
"functionName": "DisplayedComplexValue",
"lineNumber": "removed by Jest serializer",
},
"id": null,
"isStateEditable": false,
"name": "DebuggableHook",
"subHooks": Array [
Object {
"hookSource": Object {
"columnNumber": "removed by Jest serializer",
"fileName": "react-devtools-shared/src/__tests__/inspectedElement-test.js",
"functionName": "useDebuggableHook",
"lineNumber": "removed by Jest serializer",
},
"id": 0,
"isStateEditable": true,
"name": "State",
Expand Down Expand Up @@ -1872,6 +1913,12 @@ describe('InspectedElement', () => {
Object {
"hooks": Array [
Object {
"hookSource": Object {
"columnNumber": "removed by Jest serializer",
"fileName": "react-devtools-shared/src/__tests__/inspectedElement-test.js",
"functionName": "Example",
"lineNumber": "removed by Jest serializer",
},
"id": 0,
"isStateEditable": true,
"name": "State",
Expand Down Expand Up @@ -1905,6 +1952,12 @@ describe('InspectedElement', () => {
Object {
"hooks": Array [
Object {
"hookSource": Object {
"columnNumber": "removed by Jest serializer",
"fileName": "react-devtools-shared/src/__tests__/inspectedElement-test.js",
"functionName": "Example",
"lineNumber": "removed by Jest serializer",
},
"id": 0,
"isStateEditable": true,
"name": "State",
Expand Down Expand Up @@ -1938,6 +1991,12 @@ describe('InspectedElement', () => {
Object {
"hooks": Array [
Object {
"hookSource": Object {
"columnNumber": "removed by Jest serializer",
"fileName": "react-devtools-shared/src/__tests__/inspectedElement-test.js",
"functionName": "Example",
"lineNumber": "removed by Jest serializer",
},
"id": 0,
"isStateEditable": true,
"name": "State",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,3 @@
// TODO (named hooks) Don't mutate hooks object
// This method should return a mirror object,
// and its return value should be used in `print()`
function serializeHookSourceFileNames(hooks) {
if (!hooks.length) return;
hooks.forEach(hook => {
if (!hook.hookSource) return;
const filename = hook.hookSource.fileName;
const truncateIdx = filename.lastIndexOf('/react-devtools-shared/');
hook.hookSource.fileName = filename.substring(truncateIdx + 1);
if (hook.subHooks && hook.subHooks.length)
serializeHookSourceFileNames(hook.subHooks);
});
}

// test() is part of Jest's serializer API
export function test(maybeInspectedElement) {
if (
Expand All @@ -26,11 +11,6 @@ export function test(maybeInspectedElement) {
maybeInspectedElement,
);

// TODO (named hooks) Remove this call
if (hasOwnProperty('hooks') && maybeInspectedElement.hooks != null) {
serializeHookSourceFileNames(maybeInspectedElement.hooks);
}

return (
hasOwnProperty('canEditFunctionProps') &&
hasOwnProperty('canEditHooks') &&
Expand Down
3 changes: 3 additions & 0 deletions scripts/jest/config.build-devtools.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ module.exports = Object.assign({}, baseConfig, {
require.resolve(
'../../packages/react-devtools-shared/src/__tests__/dehydratedValueSerializer.js'
),
require.resolve(
'../../packages/react-devtools-shared/src/__tests__/hookSerializer.js'
),
require.resolve(
'../../packages/react-devtools-shared/src/__tests__/inspectedElementSerializer.js'
),
Expand Down

0 comments on commit cf8a93a

Please sign in to comment.