Skip to content

Commit c085223

Browse files
committed
fix tests
1 parent fc97856 commit c085223

File tree

3 files changed

+51
-34
lines changed

3 files changed

+51
-34
lines changed

src/components/Json/Json.test.tsx

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { fireEvent, render } from '@testing-library/react'
22
import { describe, expect, it } from 'vitest'
33
import Json from './Json.js'
4+
import { isPrimitive, shouldObjectCollapse } from './helpers.js'
45

56
describe('Json Component', () => {
67
it('renders primitive types correctly', () => {
@@ -26,32 +27,68 @@ describe('Json Component', () => {
2627
})
2728

2829
it('renders nested objects', () => {
30+
const { getByText } = render(<Json json={{ obj: { arr: [314, '42'] } }} />)
31+
expect(getByText('obj:')).toBeDefined()
32+
expect(getByText('arr:')).toBeDefined()
33+
expect(getByText('314')).toBeDefined()
34+
expect(getByText('"42"')).toBeDefined()
35+
})
36+
37+
it('collapses non-primitive nested objects', () => {
2938
const { getByText } = render(<Json json={{ obj: { arr: [314, null] } }} />)
3039
expect(getByText('obj:')).toBeDefined()
3140
expect(getByText('arr:')).toBeDefined()
3241
expect(getByText('314')).toBeDefined()
33-
expect(getByText('null')).toBeDefined()
42+
expect(getByText('...')).toBeDefined()
3443
})
3544

3645
it('toggles array collapse state', () => {
37-
const { getByText, queryByText } = render(<Json json={['foo', 'bar']} />)
46+
const { getByText, queryByText } = render(<Json json={['foo', null]} />)
3847
expect(getByText('"foo"')).toBeDefined()
39-
expect(getByText('"bar"')).toBeDefined()
48+
expect(queryByText('null')).toBeNull()
49+
fireEvent.click(getByText('▶'))
50+
expect(getByText('null')).toBeDefined()
4051
fireEvent.click(getByText('▼'))
41-
expect(queryByText('0: 1')).toBeNull()
42-
fireEvent.click(getByText('[...]'))
4352
expect(getByText('"foo"')).toBeDefined()
44-
expect(getByText('"bar"')).toBeDefined()
53+
expect(queryByText('null')).toBeNull()
4554
})
4655

4756
it('toggles object collapse state', () => {
4857
const { getByText, queryByText } = render(<Json json={{ key: 'value' }} />)
4958
expect(getByText('key:')).toBeDefined()
5059
expect(getByText('"value"')).toBeDefined()
51-
fireEvent.click(getByText(''))
60+
fireEvent.click(getByText(''))
5261
expect(queryByText('key: "value"')).toBeNull()
53-
fireEvent.click(getByText('{...}'))
62+
fireEvent.click(getByText(''))
5463
expect(getByText('key:')).toBeDefined()
5564
expect(getByText('"value"')).toBeDefined()
5665
})
5766
})
67+
68+
describe('isPrimitive', () => {
69+
it('returns true only for primitive types', () => {
70+
expect(isPrimitive('test')).toBe(true)
71+
expect(isPrimitive(42)).toBe(true)
72+
expect(isPrimitive(true)).toBe(true)
73+
expect(isPrimitive(1n)).toBe(true)
74+
expect(isPrimitive(null)).toBe(false)
75+
expect(isPrimitive(undefined)).toBe(false)
76+
expect(isPrimitive({})).toBe(false)
77+
expect(isPrimitive([])).toBe(false)
78+
})
79+
})
80+
81+
describe('shouldObjectCollapse', () => {
82+
it('returns true for objects with all primitive values', () => {
83+
expect(shouldObjectCollapse({ a: 1, b: 'test' })).toBe(true)
84+
})
85+
86+
it('returns false for objects with non-primitive values', () => {
87+
expect(shouldObjectCollapse({ a: 1, b: {} })).toBe(false)
88+
})
89+
90+
it('returns true for large objects', () => {
91+
const largeObject = Object.fromEntries(Array.from({ length: 101 }, (_, i) => [`key${i}`, i]))
92+
expect(shouldObjectCollapse(largeObject)).toBe(true)
93+
})
94+
})

src/components/Json/Json.tsx

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { ReactNode, useState } from 'react'
22
import styles from './Json.module.css'
3+
import { isPrimitive, shouldObjectCollapse } from './helpers.js'
34

45
interface JsonProps {
56
json: unknown
@@ -36,15 +37,6 @@ function JsonContent({ json, label }: JsonProps): ReactNode {
3637
return div
3738
}
3839

39-
function isPrimitive(value: unknown): boolean {
40-
return (
41-
value !== undefined &&
42-
!Array.isArray(value) &&
43-
typeof value !== 'object' &&
44-
typeof value !== 'function'
45-
)
46-
}
47-
4840
function CollapsedArray({ array }: {array: unknown[]}): ReactNode {
4941
// the character count is approximate, but it should be enough
5042
// to avoid showing too many entries
@@ -148,21 +140,8 @@ function CollapsedObject({ obj }: {obj: object}): ReactNode {
148140
)
149141
}
150142

151-
function shouldCollapse(obj: object): boolean {
152-
const values = Object.values(obj)
153-
if (
154-
// if all the values are primitive
155-
values.every(value => isPrimitive(value))
156-
// if the object has too many entries
157-
|| values.length >= 100
158-
) {
159-
return true
160-
}
161-
return false
162-
}
163-
164143
function JsonObject({ obj, label }: { obj: object, label?: string }): ReactNode {
165-
const [collapsed, setCollapsed] = useState(shouldCollapse(obj))
144+
const [collapsed, setCollapsed] = useState(shouldObjectCollapse(obj))
166145
const key = label ? <span className={styles.key}>{label}: </span> : ''
167146
if (collapsed) {
168147
return <div className={styles.clickable} onClick={() => { setCollapsed(false) }}>

src/components/JsonView/JsonView.test.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@ globalThis.fetch = vi.fn()
1313
describe('JsonView Component', () => {
1414
const encoder = new TextEncoder()
1515

16-
it('renders json content as nested lists', async () => {
17-
const body = encoder.encode('{"key":"value"}').buffer as ArrayBuffer
16+
it('renders json content as nested lists (if not collapsed)', async () => {
17+
const text = '{"key":["value"]}'
18+
const body = encoder.encode(text).buffer as ArrayBuffer
1819
const source: FileSource = {
1920
resolveUrl: 'testKey0',
2021
kind: 'file',
@@ -25,7 +26,7 @@ describe('JsonView Component', () => {
2526
vi.mocked(fetch).mockResolvedValueOnce({
2627
status: 200,
2728
headers: new Headers({ 'Content-Length': body.byteLength.toString() }),
28-
text: () => Promise.resolve('{"key":"value"}'),
29+
text: () => Promise.resolve(text),
2930
} as Response)
3031

3132
const { findByRole, findByText } = render(

0 commit comments

Comments
 (0)