Skip to content

Commit 8285bb9

Browse files
committed
fix: fix Map/Set render issue & add test case.
1 parent 9cbb860 commit 8285bb9

File tree

11 files changed

+279
-26
lines changed

11 files changed

+279
-26
lines changed

core/src/comps/NestedOpen.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ export const NestedOpen = <T extends object>(props: NestedOpenProps<T>) => {
4444
<span {...reset}>
4545
{showArrow && <Arrow style={arrowStyle} expandKey={expandKey} />}
4646
{(keyName || typeof keyName === 'number') && <KayName keyName={keyName} />}
47-
<SetComp isSet={initialValue instanceof Set} />
48-
<MapComp isMap={initialValue instanceof Map} />
47+
<SetComp value={initialValue} />
48+
<MapComp value={initialValue} />
4949
<BracketsOpen isBrackets={isArray || isMySet} />
5050
<Ellipsis keyName={keyName!} value={value} isExpanded={isExpanded} />
5151
<BracketsClose isVisiable={isExpanded || !showArrow} isBrackets={isArray || isMySet} />

core/src/comps/ReRender/Types.tsx

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,30 +4,32 @@ import { useStore } from '../../store';
44
import { ValueQuote } from './Symbols';
55
import { Copied } from '../Copied';
66

7-
export const SetComp = ({ isSet }: { isSet: boolean }) => {
8-
const { Set = {}, displayDataTypes } = useTypesStore();
7+
export const SetComp: FC<PropsWithChildren<{ value: unknown }>> = ({ value }) => {
8+
const { Set: Comp = {}, displayDataTypes } = useTypesStore();
9+
const isSet = value instanceof Set;
910
if (!isSet || !displayDataTypes) return null;
10-
const { as, render, ...reset } = Set;
11+
const { as, render, ...reset } = Comp;
1112
const isRender = render && typeof render === 'function';
12-
const type = isRender && render(reset, { type: 'type' });
13+
const type = isRender && render(reset, { type: 'type', value });
1314
if (type) return type;
1415

15-
const Comp = as || 'span';
16-
return <Comp {...reset} />;
16+
const Elm = as || 'span';
17+
return <Elm {...reset} />;
1718
};
1819

1920
SetComp.displayName = 'JVR.SetComp';
2021

21-
export const MapComp = ({ isMap }: { isMap: boolean }) => {
22-
const { Map = {}, displayDataTypes } = useTypesStore();
22+
export const MapComp: FC<PropsWithChildren<{ value: unknown }>> = ({ value }) => {
23+
const { Map: Comp = {}, displayDataTypes } = useTypesStore();
24+
const isMap = value instanceof Map;
2325
if (!isMap || !displayDataTypes) return null;
24-
const { as, render, ...reset } = Map;
26+
const { as, render, ...reset } = Comp;
2527
const isRender = render && typeof render === 'function';
26-
const type = isRender && render(reset, { type: 'type' });
28+
const type = isRender && render(reset, { type: 'type', value });
2729
if (type) return type;
2830

29-
const Comp = as || 'span';
30-
return <Comp {...reset} />;
31+
const Elm = as || 'span';
32+
return <Elm {...reset} />;
3133
};
3234

3335
MapComp.displayName = 'JVR.MapComp';
@@ -249,7 +251,8 @@ export const TypeUrl: FC<{ children?: URL } & Omit<TypeProps, 'children'>> = ({
249251
const isRender = render && typeof render === 'function';
250252
const type = isRender && render({ ...reset, style }, { type: 'type', value: children });
251253
const child =
252-
isRender && render({ ...reset, children, className: 'w-rjv-value' }, { type: 'value', value: children });
254+
isRender &&
255+
render({ ...reset, children: children?.href, className: 'w-rjv-value' }, { type: 'value', value: children });
253256

254257
return (
255258
<Fragment>
@@ -279,15 +282,16 @@ export const TypeDate: FC<{ children?: Date } & Omit<TypeProps, 'children'>> = (
279282

280283
const isRender = render && typeof render === 'function';
281284
const type = isRender && render({ ...reset, style }, { type: 'type', value: children });
285+
const childStr = children?.toString();
282286
const child =
283-
isRender && render({ ...reset, children, className: 'w-rjv-value' }, { type: 'value', value: children });
287+
isRender && render({ ...reset, children: childStr, className: 'w-rjv-value' }, { type: 'value', value: children });
284288

285289
return (
286290
<Fragment>
287291
{displayDataTypes && (type || <Comp {...reset} style={style} />)}
288292
{child || (
289293
<Comp {...reset} className="w-rjv-value">
290-
{children?.toString()}
294+
{childStr}
291295
</Comp>
292296
)}
293297
<Copied keyName={keyName} value={children as object} expandKey={expandKey} />
@@ -359,7 +363,8 @@ export const TypeNan: FC<TypeProps> = ({ children, expandKey, keyName }) => {
359363
const isRender = render && typeof render === 'function';
360364
const type = isRender && render({ ...reset, style }, { type: 'type', value: children });
361365
const child =
362-
isRender && render({ ...reset, children, className: 'w-rjv-value' }, { type: 'value', value: children });
366+
isRender &&
367+
render({ ...reset, children: children?.toString(), className: 'w-rjv-value' }, { type: 'value', value: children });
363368

364369
return (
365370
<Fragment>
@@ -395,4 +400,4 @@ export const TypeEmptyValue: FC<TypeProps> = ({ children, expandKey, keyName })
395400
);
396401
};
397402

398-
TypeNan.displayName = 'JVR.TypeNan';
403+
TypeEmptyValue.displayName = 'JVR.TypeEmptyValue';

core/src/index.test.tsx

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -98,13 +98,6 @@ it('renders <JsonView.String /> test case', async () => {
9898
field: 'bigint',
9999
color: 'var(--w-rjv-type-bigint-color, #268bd2)',
100100
},
101-
// {
102-
// name: 'Date',
103-
// Comp: JsonView.Date,
104-
// value: new Date('2023/02/12'),
105-
// field: 'date',
106-
// color: 'var(--w-rjv-type-date-color, #268bd2)',
107-
// },
108101
{
109102
name: 'False',
110103
Comp: JsonView.False,
@@ -148,6 +141,20 @@ it('renders <JsonView.String /> test case', async () => {
148141
color: 'var(--w-rjv-type-undefined-color, #586e75)',
149142
},
150143
// {
144+
// name: 'Nan',
145+
// Comp: JsonView.Nan,
146+
// value: NaN,
147+
// field: 'NaN',
148+
// color: 'var(--w-rjv-type-nan-color, #859900)',
149+
// },
150+
// {
151+
// name: 'Date',
152+
// Comp: JsonView.Date,
153+
// value: new Date('2023/02/12'),
154+
// field: 'date',
155+
// color: 'var(--w-rjv-type-date-color, #268bd2)',
156+
// },
157+
// {
151158
// name: 'Url',
152159
// Comp: JsonView.Url,
153160
// value: new URL('https://www.google.com'),

core/src/store/Symbols.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ type Dispatch = React.Dispatch<InitialState<TagType>>;
3232
const initialState: InitialState<TagType> = {
3333
Arrow: {
3434
as: 'span',
35+
className: 'w-rjv-arrow',
3536
style: {
3637
transform: 'rotate(0deg)',
3738
transition: 'all 0.3s',

core/src/symbol/Arrow.test.tsx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { screen, render, waitFor } from '@testing-library/react';
2+
import JsonView from '..';
3+
4+
import { TriangleSolidArrow } from '@uiw/react-json-view/triangle-solid-arrow';
5+
6+
it('renders <JsonView.Arrow /> test case', async () => {
7+
const demo = {
8+
value: '123',
9+
};
10+
const { container } = render(
11+
<JsonView value={demo}>
12+
<JsonView.Arrow>
13+
<TriangleSolidArrow data-testid="arrow" />
14+
</JsonView.Arrow>
15+
</JsonView>,
16+
);
17+
expect(container.firstElementChild).toBeInstanceOf(Element);
18+
await waitFor(() => {
19+
const arrow = screen.getByTestId('arrow') as unknown as SVGSVGElement;
20+
expect(arrow.tagName).toBe('svg');
21+
});
22+
});

core/src/symbol/BraceLeft.test.tsx

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { screen, render, waitFor } from '@testing-library/react';
2+
import JsonView from '..';
3+
4+
it('renders <JsonView.BraceLeft /> test case', async () => {
5+
const demo = {
6+
value: '123',
7+
};
8+
const { container } = render(
9+
<JsonView value={demo}>
10+
<JsonView.BraceLeft data-testid="brace">x</JsonView.BraceLeft>
11+
</JsonView>,
12+
);
13+
expect(container.firstElementChild).toBeInstanceOf(Element);
14+
await waitFor(() => {
15+
const arrow = screen.getByTestId('brace');
16+
expect(arrow.tagName).toBe('SPAN');
17+
expect(arrow.innerHTML).toBe('x');
18+
});
19+
});
20+
21+
it('renders <JsonView.BraceLeft render /> test case', async () => {
22+
const demo = {
23+
value: '123',
24+
};
25+
const { container } = render(
26+
<JsonView value={demo}>
27+
<JsonView.BraceLeft
28+
data-testid="brace"
29+
render={(props) => {
30+
expect(props.style).toHaveProperty('color', 'var(--w-rjv-curlybraces-color, #236a7c)');
31+
return <span {...props}>.......</span>;
32+
}}
33+
/>
34+
</JsonView>,
35+
);
36+
expect(container.firstElementChild).toBeInstanceOf(Element);
37+
await waitFor(() => {
38+
const arrow = screen.getByTestId('brace');
39+
expect(arrow.tagName).toBe('SPAN');
40+
expect(arrow.className).toBe('w-rjv-curlybraces-start');
41+
expect(arrow.innerHTML).toBe('.......');
42+
});
43+
});

core/src/types/Date.test.tsx

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { screen, render, waitFor } from '@testing-library/react';
2+
import JsonView from '../';
3+
4+
it('renders <JsonView.Date /> test case', async () => {
5+
const demo = {
6+
date: new Date('2023/02/12'),
7+
};
8+
const { container } = render(
9+
<JsonView value={demo}>
10+
<JsonView.Date
11+
as="span"
12+
render={(props, { type, value }) => {
13+
expect((value as Date).getDate()).toBe(demo.date.getDate());
14+
expect(props.style).toHaveProperty('color', 'var(--w-rjv-type-date-color, #268bd2)');
15+
16+
if (type === 'type') {
17+
return <span {...props} data-testid="date-type" />;
18+
}
19+
props.children = (value as Date).toLocaleString();
20+
return <span {...props} data-testid="date-value" />;
21+
}}
22+
/>
23+
</JsonView>,
24+
);
25+
expect(container.firstElementChild).toBeInstanceOf(Element);
26+
await waitFor(() => {
27+
const type = screen.getByTestId('date-type');
28+
expect(type.className).toBe('w-rjv-type');
29+
expect(type.tagName).toBe('SPAN');
30+
expect(type.innerHTML).toBe('date');
31+
const value = screen.getByTestId('date-value');
32+
expect(value.className).toBe('w-rjv-value');
33+
expect(value.tagName).toBe('SPAN');
34+
expect(value.innerHTML).toBe(demo.date.toLocaleString());
35+
});
36+
});

core/src/types/Map.test.tsx

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { screen, render, waitFor } from '@testing-library/react';
2+
import JsonView from '..';
3+
4+
const myMap = new Map();
5+
myMap.set('www', 'foo');
6+
myMap.set(1, 'bar');
7+
8+
it('renders <JsonView.Map /> test case', async () => {
9+
const demo = {
10+
value: myMap,
11+
};
12+
const { container } = render(
13+
<JsonView value={demo}>
14+
<JsonView.Map
15+
as="span"
16+
render={(props, { type, value }) => {
17+
expect(type).toEqual('type');
18+
expect(value).toEqual(myMap);
19+
expect(props.style).toHaveProperty('color', 'var(--w-rjv-type-map-color, #268bd2)');
20+
if (type === 'type') {
21+
return <span {...props} data-testid="type" />;
22+
}
23+
}}
24+
/>
25+
</JsonView>,
26+
);
27+
expect(container.firstElementChild).toBeInstanceOf(Element);
28+
await waitFor(() => {
29+
const type = screen.getByTestId('type');
30+
expect(type.className).toBe('w-rjv-type');
31+
expect(type.tagName).toBe('SPAN');
32+
expect(type.innerHTML).toBe('Map');
33+
});
34+
});

core/src/types/Nan.test.tsx

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { screen, render, waitFor } from '@testing-library/react';
2+
import JsonView from '../';
3+
import { Nan } from './Nan';
4+
5+
it('renders <JsonView.Nan /> test case', async () => {
6+
const demo = {
7+
value: NaN,
8+
};
9+
const { container } = render(
10+
<JsonView value={demo}>
11+
<Nan
12+
as="span"
13+
render={(props, { type, value }) => {
14+
expect(value).toBeNaN();
15+
expect(props.style).toHaveProperty('color', 'var(--w-rjv-type-nan-color, #859900)');
16+
if (type === 'type') {
17+
return <span {...props} data-testid="type" />;
18+
}
19+
return <span {...props} data-testid="value" />;
20+
}}
21+
/>
22+
</JsonView>,
23+
);
24+
expect(container.firstElementChild).toBeInstanceOf(Element);
25+
await waitFor(() => {
26+
const type = screen.getByTestId('type');
27+
expect(type.className).toBe('w-rjv-type');
28+
expect(type.tagName).toBe('SPAN');
29+
expect(type.innerHTML).toBe('NaN');
30+
const value = screen.getByTestId('value');
31+
expect(value.className).toBe('w-rjv-value');
32+
expect(value.tagName).toBe('SPAN');
33+
expect(type.innerHTML).toBe('NaN');
34+
});
35+
});

core/src/types/Set.test.tsx

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { screen, render, waitFor } from '@testing-library/react';
2+
import JsonView from '..';
3+
4+
const mySet = new Set();
5+
mySet.add(1); // Set(1) { 1 }
6+
mySet.add(5); // Set(2) { 1, 5 }
7+
mySet.add(5); // Set(2) { 1, 5 }
8+
mySet.add('some text'); // Set(3) { 1, 5, 'some text' }
9+
10+
it('renders <JsonView.Set /> test case', async () => {
11+
const demo = {
12+
value: mySet,
13+
};
14+
const { container } = render(
15+
<JsonView value={demo}>
16+
<JsonView.Set
17+
as="span"
18+
render={(props, { type, value }) => {
19+
expect(type).toEqual('type');
20+
expect(value).toEqual(mySet);
21+
expect(props.style).toHaveProperty('color', 'var(--w-rjv-type-set-color, #268bd2)');
22+
if (type === 'type') {
23+
return <span {...props} data-testid="type" />;
24+
}
25+
}}
26+
/>
27+
</JsonView>,
28+
);
29+
expect(container.firstElementChild).toBeInstanceOf(Element);
30+
await waitFor(() => {
31+
const type = screen.getByTestId('type');
32+
expect(type.className).toBe('w-rjv-type');
33+
expect(type.tagName).toBe('SPAN');
34+
expect(type.innerHTML).toBe('Set');
35+
});
36+
});

0 commit comments

Comments
 (0)