From 510ec2c94c47323d72b558b2cd4f9e9a370fd8f1 Mon Sep 17 00:00:00 2001 From: Daniel Tschinder <231804+danez@users.noreply.github.com> Date: Sun, 26 Mar 2023 20:42:10 +0200 Subject: [PATCH] Correctly resolve values in `Object.values` --- .changeset/witty-ligers-press.md | 5 +++ .../__snapshots__/getPropType-test.ts.snap | 32 +++++++++++++++++ .../src/utils/__tests__/getPropType-test.ts | 35 +++++++++++++++++++ .../src/utils/resolveObjectValuesToArray.ts | 6 ++-- 4 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 .changeset/witty-ligers-press.md diff --git a/.changeset/witty-ligers-press.md b/.changeset/witty-ligers-press.md new file mode 100644 index 00000000000..16587645071 --- /dev/null +++ b/.changeset/witty-ligers-press.md @@ -0,0 +1,5 @@ +--- +'react-docgen': patch +--- + +Correctly resolve the values in an `Object.values()` call diff --git a/packages/react-docgen/src/utils/__tests__/__snapshots__/getPropType-test.ts.snap b/packages/react-docgen/src/utils/__tests__/__snapshots__/getPropType-test.ts.snap index c70b3d38f0b..87ee1dd19b2 100644 --- a/packages/react-docgen/src/utils/__tests__/__snapshots__/getPropType-test.ts.snap +++ b/packages/react-docgen/src/utils/__tests__/__snapshots__/getPropType-test.ts.snap @@ -250,6 +250,22 @@ exports[`getPropType > resolve identifier to their values > handles unresolved n } `; +exports[`getPropType > resolve identifier to their values > handles unresolved value constants from imported objects 1`] = ` +{ + "name": "enum", + "value": [ + { + "computed": false, + "value": "null", + }, + { + "computed": false, + "value": "null", + }, + ], +} +`; + exports[`getPropType > resolve identifier to their values > resolves imported identifier to their initialization value in array 1`] = ` { "name": "enum", @@ -358,6 +374,22 @@ exports[`getPropType > resolve identifier to their values > resolves simple iden } `; +exports[`getPropType > resolve identifier to their values > resolves value constants from imported objects 1`] = ` +{ + "name": "enum", + "value": [ + { + "computed": false, + "value": "\\"foo\\"", + }, + { + "computed": false, + "value": "\\"bar\\"", + }, + ], +} +`; + exports[`getPropType > resolve identifier to their values > resolves values from imported Object.keys call 1`] = ` { "name": "enum", diff --git a/packages/react-docgen/src/utils/__tests__/getPropType-test.ts b/packages/react-docgen/src/utils/__tests__/getPropType-test.ts index bb999613058..65e161d06af 100644 --- a/packages/react-docgen/src/utils/__tests__/getPropType-test.ts +++ b/packages/react-docgen/src/utils/__tests__/getPropType-test.ts @@ -436,6 +436,41 @@ describe('getPropType', () => { expect(getPropType(propTypeExpression)).toMatchSnapshot(); }); + test('resolves value constants from imported objects', () => { + const propTypeExpression = parse + .statement( + ` + const values = { + FOO: consts.FOO, BAR: consts.BAR + } + PropTypes.oneOf(Object.values(values)); + import consts from 'obj'; + `, + mockImporter, + 1, + ) + .get('expression'); + + expect(getPropType(propTypeExpression)).toMatchSnapshot(); + }); + + test('handles unresolved value constants from imported objects', () => { + const propTypeExpression = parse + .statement( + ` + const values = { + FOO: consts.FOO, BAR: consts.BAR + } + PropTypes.oneOf(Object.values(values)); + import consts from 'obj'; + `, + 1, + ) + .get('expression'); + + expect(getPropType(propTypeExpression)).toMatchSnapshot(); + }); + test('does not resolve external values without proper importer', () => { const propTypeExpression = parse .statement( diff --git a/packages/react-docgen/src/utils/resolveObjectValuesToArray.ts b/packages/react-docgen/src/utils/resolveObjectValuesToArray.ts index 0744efe9324..fbc385a68da 100644 --- a/packages/react-docgen/src/utils/resolveObjectValuesToArray.ts +++ b/packages/react-docgen/src/utils/resolveObjectValuesToArray.ts @@ -52,13 +52,13 @@ function resolveObjectToPropMap(object: NodePath): Map | null { return; } - // Identifiers as values are not followed at all - const valuePath = propPath.get('value'); + const valuePath = resolveToValue(propPath.get('value')); const value = valuePath.isStringLiteral() ? `"${valuePath.node.value}"` : valuePath.isNumericLiteral() ? `${valuePath.node.value}` - : 'null'; + : // we return null here because there are a lot of cases and we don't know yet what we need to handle + 'null'; values.set(name, value); } else if (propPath.isSpreadElement()) {