From 8886a73b21b355b806072fffdff19578b4beba50 Mon Sep 17 00:00:00 2001 From: Fan Pei Date: Sat, 13 Jan 2024 15:28:44 +0900 Subject: [PATCH] fix(client): resolve nested custom object (#167) --- .../component/state/__tests__/format.spec.ts | 71 +++++++++++++++++++ .../src/core/component/state/format.ts | 11 ++- .../src/core/component/types/state.ts | 4 +- 3 files changed, 81 insertions(+), 5 deletions(-) create mode 100644 packages/devtools-kit/src/core/component/state/__tests__/format.spec.ts diff --git a/packages/devtools-kit/src/core/component/state/__tests__/format.spec.ts b/packages/devtools-kit/src/core/component/state/__tests__/format.spec.ts new file mode 100644 index 00000000..132c880c --- /dev/null +++ b/packages/devtools-kit/src/core/component/state/__tests__/format.spec.ts @@ -0,0 +1,71 @@ +import * as format from '../format' +import { INFINITY, NAN, NEGATIVE_INFINITY, UNDEFINED } from '../constants' + +describe('format: displayText and rawValue can be calculated by formatInspectorStateValue, getRawValue', () => { + describe('type: literals', () => { + // eslint-disable-next-line test/consistent-test-it + test.each([ + { literal: 'test-string', displayText: 'test-string' }, + { literal: 123, displayText: 123 }, + { literal: true, displayText: true }, + { literal: null, displayText: 'null' }, + // Tokenlized values + { literal: INFINITY, displayText: 'Infinity' }, + { literal: NAN, displayText: 'NaN' }, + { literal: NEGATIVE_INFINITY, displayText: '-Infinity' }, + { literal: UNDEFINED, displayText: 'undefined' }, + ])('type: %s', (value) => { + const displayText = format.formatInspectorStateValue(value.literal) + const rawValue = format.getRawValue(value.literal).value + + expect(displayText).toBe(value.displayText) + expect(rawValue).toBe(value.literal) + }) + }) + + it('type: plain object', () => { + const value = { foo: 'bar' } + const displayText = format.formatInspectorStateValue(value) + const rawValue = format.getRawValue(value).value + + expect(displayText).toBe('Object') + expect(rawValue).toEqual(value) + }) + + it('type: array', () => { + const value = ['foo', { bar: 'baz' }] + const displayText = format.formatInspectorStateValue(value) + const rawValue = format.getRawValue(value).value + + expect(displayText).toBe('Array[2]') + expect(rawValue).toEqual(value) + }) + + describe('type: custom', () => { + it('type: common custom', () => { + const value = { _custom: { displayText: 'custom-display', value: Symbol(123) } } + const displayText = format.formatInspectorStateValue(value) + const rawValue = format.getRawValue(value).value + + expect(displayText).toBe(value._custom.displayText) + expect(rawValue).toEqual(value._custom.value) + }) + + it('type: nested custom', () => { + const value = { + _custom: { + displayText: 'custom-display', + value: { + _custom: { displayText: 'nested-custom-display', value: Symbol(123) }, + }, + }, + } + + const displayText = format.formatInspectorStateValue(value) + const rawValue = format.getRawValue(value).value + + expect(displayText).toBe(value._custom.value._custom.displayText) + expect(rawValue).toEqual(value._custom.value._custom.value) + }) + }) +}) diff --git a/packages/devtools-kit/src/core/component/state/format.ts b/packages/devtools-kit/src/core/component/state/format.ts index 2070a710..64decff4 100644 --- a/packages/devtools-kit/src/core/component/state/format.ts +++ b/packages/devtools-kit/src/core/component/state/format.ts @@ -56,7 +56,9 @@ export function formatInspectorStateValue(value, quotes = false) { return result } else if (type === 'custom') { - return value._custom.displayText ?? value._custom.display + // For digging out nested custom name. + const nestedName = value._custom.value?._custom && formatInspectorStateValue(value._custom.value) + return nestedName || value._custom.displayText || value._custom.display } else if (type === 'array') { return `Array[${value.length}]` @@ -89,8 +91,11 @@ export function getRawValue(value: InspectorState['value']) { let inherit = {} if (isCustom) { const data = value as InspectorCustomState - inherit = data._custom?.fields || {} - value = data._custom?.value as string + const nestedCustom = typeof data._custom?.value === 'object' && '_custom' in data._custom.value + ? getRawValue(data._custom?.value) + : { inherit: undefined, value: undefined } + inherit = nestedCustom.inherit || data._custom?.fields || {} + value = nestedCustom.value || data._custom?.value as string } // @ts-expect-error @TODO: type if (value && value._isArray) diff --git a/packages/devtools-kit/src/core/component/types/state.ts b/packages/devtools-kit/src/core/component/types/state.ts index 87c3ea4b..c261f990 100644 --- a/packages/devtools-kit/src/core/component/types/state.ts +++ b/packages/devtools-kit/src/core/component/types/state.ts @@ -5,7 +5,7 @@ export interface InspectorCustomState { type?: string displayText?: string tooltipText?: string - value?: string + value?: string | InspectorCustomState stateTypeName?: string fields?: { abstract?: boolean @@ -15,7 +15,7 @@ export interface InspectorCustomState { export interface InspectorState { key: string - value: string | number | Record | InspectorCustomState | Array + value: string | number | boolean | null | Record | InspectorCustomState | Array type: string stateType?: string stateTypeName?: string