Skip to content

Commit 0737d66

Browse files
authored
fix: improve handling of array + dictionary combo (#251)
1 parent b76157a commit 0737d66

File tree

3 files changed

+111
-3
lines changed

3 files changed

+111
-3
lines changed

src/__tests__/index.spec.tsx

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,113 @@ describe('HTML Output', () => {
208208
`);
209209
});
210210

211+
it('should render top-level dictionary', () => {
212+
const schema: JSONSchema7 = {
213+
type: 'object',
214+
additionalProperties: {
215+
type: 'string',
216+
},
217+
};
218+
219+
expect(dumpDom(<JsonSchemaViewer schema={schema} defaultExpandedDepth={Infinity} />)).toMatchInlineSnapshot(`
220+
"<div class=\\"\\" id=\\"mosaic-provider-react-aria-0-1\\">
221+
<div data-overlay-container=\\"true\\">
222+
<div class=\\"JsonSchemaViewer\\">
223+
<div></div>
224+
<div data-id=\\"bf8b96e78f11d\\" data-test=\\"schema-row\\">
225+
<div>
226+
<div>
227+
<div><span data-test=\\"property-type\\">dictionary[string, string]</span></div>
228+
</div>
229+
</div>
230+
</div>
231+
</div>
232+
</div>
233+
</div>
234+
"
235+
`);
236+
});
237+
238+
it('should not merge array of dictionaries', () => {
239+
const schema: JSONSchema7 = {
240+
type: 'array',
241+
items: {
242+
type: 'object',
243+
additionalProperties: {
244+
type: 'string',
245+
},
246+
},
247+
};
248+
249+
expect(dumpDom(<JsonSchemaViewer schema={schema} defaultExpandedDepth={Infinity} />)).toMatchInlineSnapshot(`
250+
"<div class=\\"\\" id=\\"mosaic-provider-react-aria-0-1\\">
251+
<div data-overlay-container=\\"true\\">
252+
<div class=\\"JsonSchemaViewer\\">
253+
<div></div>
254+
<div data-id=\\"bf8b96e78f11d\\" data-test=\\"schema-row\\">
255+
<div>
256+
<div>
257+
<div role=\\"button\\"></div>
258+
<div><span data-test=\\"property-type\\">array</span></div>
259+
</div>
260+
</div>
261+
</div>
262+
<div data-level=\\"0\\">
263+
<div data-id=\\"98538b996305d\\" data-test=\\"schema-row\\">
264+
<div>
265+
<div>
266+
<div><span data-test=\\"property-type\\">dictionary[string, string]</span></div>
267+
</div>
268+
</div>
269+
</div>
270+
</div>
271+
</div>
272+
</div>
273+
</div>
274+
"
275+
`);
276+
});
277+
278+
it('should merge dictionaries with array values', () => {
279+
const schema: JSONSchema7 = {
280+
type: 'object',
281+
additionalProperties: {
282+
type: 'array',
283+
items: {
284+
type: 'string',
285+
},
286+
},
287+
};
288+
289+
expect(dumpDom(<JsonSchemaViewer schema={schema} defaultExpandedDepth={Infinity} />)).toMatchInlineSnapshot(`
290+
"<div class=\\"\\" id=\\"mosaic-provider-react-aria-0-1\\">
291+
<div data-overlay-container=\\"true\\">
292+
<div class=\\"JsonSchemaViewer\\">
293+
<div></div>
294+
<div data-id=\\"bf8b96e78f11d\\" data-test=\\"schema-row\\">
295+
<div>
296+
<div>
297+
<div role=\\"button\\"></div>
298+
<div><span data-test=\\"property-type\\">dictionary[string, array]</span></div>
299+
</div>
300+
</div>
301+
</div>
302+
<div data-level=\\"0\\">
303+
<div data-id=\\"98538b996305d\\" data-test=\\"schema-row\\">
304+
<div>
305+
<div>
306+
<div><span data-test=\\"property-type\\">string</span></div>
307+
</div>
308+
</div>
309+
</div>
310+
</div>
311+
</div>
312+
</div>
313+
</div>
314+
"
315+
`);
316+
});
317+
211318
it('should not render true/false additionalProperties', () => {
212319
const schema: JSONSchema7 = {
213320
type: 'object',

src/components/SchemaRow/TopLevelSchemaRow.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import * as React from 'react';
66

77
import { COMBINER_NAME_MAP } from '../../consts';
88
import { useIsOnScreen } from '../../hooks/useIsOnScreen';
9-
import { isComplexArray, visibleChildren } from '../../tree';
9+
import { isComplexArray, isDictionaryNode, visibleChildren } from '../../tree';
1010
import { showPathCrumbsAtom } from '../PathCrumbs/state';
1111
import { Description, getValidationsFromSchema, Validations } from '../shared';
1212
import { ChildStack } from '../shared/ChildStack';
@@ -142,5 +142,5 @@ function ScrollCheck() {
142142
}
143143

144144
function isPureObjectNode(schemaNode: RegularNode) {
145-
return schemaNode.primaryType === 'object' && schemaNode.types?.length === 1;
145+
return schemaNode.primaryType === 'object' && schemaNode.types?.length === 1 && !isDictionaryNode(schemaNode);
146146
}

src/tree/utils.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ export function isFlattenableNode(node: SchemaNode): node is FlattenableNode {
4141

4242
return (
4343
node.children.length === 1 &&
44-
(isRegularNode(node.children[0]) || (isReferenceNode(node.children[0]) && node.children[0].error !== null))
44+
((isRegularNode(node.children[0]) && (!isArrayNode(node) || !isDictionaryNode(node.children[0]))) ||
45+
(isReferenceNode(node.children[0]) && node.children[0].error !== null))
4546
);
4647
}
4748

0 commit comments

Comments
 (0)