@@ -21,12 +21,13 @@ describe('Json Component', () => {
2121 getByText ( '"bar"' )
2222 } )
2323
24- it . for ( [
25- [ ] ,
26- [ 1 , 2 , 3 ] ,
27- Array . from ( { length : 101 } , ( _ , i ) => i ) ,
28- ] ) ( 'collapses any array with primitives' , ( array ) => {
29- const { getByRole } = render ( < Json json = { array } /> )
24+ it ( 'expands root array by default' , ( ) => {
25+ const { getByRole } = render ( < Json json = { [ 1 , 2 , 3 ] } /> )
26+ expect ( getByRole ( 'treeitem' ) . ariaExpanded ) . toBe ( 'true' )
27+ } )
28+
29+ it ( 'collapses array with primitives when expandRoot is false' , ( ) => {
30+ const { getByRole } = render ( < Json json = { [ 1 , 2 , 3 ] } expandRoot = { false } /> )
3031 expect ( getByRole ( 'treeitem' ) . ariaExpanded ) . toBe ( 'false' )
3132 } )
3233
@@ -41,10 +42,9 @@ describe('Json Component', () => {
4142 expect ( queryByText ( / l e n g t h / ) ) . toBeNull ( )
4243 } )
4344
44- it . for ( [
45- Array . from ( { length : 101 } , ( _ , i ) => i ) ,
46- ] ) ( 'hides long arrays with trailing comment about length' , ( array ) => {
47- const { getByText } = render ( < Json json = { array } /> )
45+ it ( 'hides long arrays with trailing comment about length when collapsed' , ( ) => {
46+ const longArray = Array . from ( { length : 101 } , ( _ , i ) => i )
47+ const { getByText } = render ( < Json json = { longArray } expandRoot = { false } /> )
4848 getByText ( '...' )
4949 getByText ( / l e n g t h / )
5050 } )
@@ -55,6 +55,11 @@ describe('Json Component', () => {
5555 getByText ( '"value"' )
5656 } )
5757
58+ it ( 'renders a Date as its ISO string' , ( ) => {
59+ const { getByText } = render ( < Json json = { new Date ( '2025-01-01' ) } /> )
60+ getByText ( '"2025-01-01T00:00:00.000Z"' )
61+ } )
62+
5863 it ( 'renders nested objects' , ( ) => {
5964 const { getByText } = render ( < Json json = { { obj : { arr : [ 314 , '42' ] } } } /> )
6065 getByText ( 'obj:' )
@@ -109,46 +114,85 @@ describe('Json Component', () => {
109114 getByText ( / e n t r i e s / )
110115 } )
111116
112- it . for ( [
113- { } ,
114- { a : 1 , b : 2 } ,
115- { a : 1 , b : true , c : null , d : undefined } ,
116- Object . fromEntries ( Array . from ( { length : 101 } , ( _ , i ) => [ `key ${ i } ` , { nested : true } ] ) ) ,
117- ] ) ( 'collapses long objects, or objects with only primitive values (included empty object) ' , ( obj ) => {
118- const { getByRole } = render ( < Json json = { obj } /> )
117+ it ( 'expands root object by default' , ( ) => {
118+ const { getByRole } = render ( < Json json = { { a : 1 , b : 2 } } /> )
119+ expect ( getByRole ( 'treeitem' ) . getAttribute ( 'aria-expanded' ) ) . toBe ( 'true' )
120+ } )
121+
122+ it ( 'collapses objects with only primitive values when expandRoot is false ' , ( ) => {
123+ const { getByRole } = render ( < Json json = { { a : 1 , b : 2 } } expandRoot = { false } /> )
119124 expect ( getByRole ( 'treeitem' ) . getAttribute ( 'aria-expanded' ) ) . toBe ( 'false' )
120125 } )
121126
122- it . for ( [
123- Object . fromEntries ( Array . from ( { length : 101 } , ( _ , i ) => [ `key${ i } ` , { nested : true } ] ) ) ,
124- ] ) ( 'hides the content and append number of entries when objects has many entries' , ( obj ) => {
125- const { getByText } = render ( < Json json = { obj } /> )
127+ it ( 'hides the content and append number of entries when objects has many entries when collapsed' , ( ) => {
128+ const longObject = Object . fromEntries ( Array . from ( { length : 101 } , ( _ , i ) => [ `key${ i } ` , { nested : true } ] ) )
129+ const { getByText } = render ( < Json json = { longObject } expandRoot = { false } /> )
126130 getByText ( '...' )
127131 getByText ( / e n t r i e s / )
128132 } )
129133
134+ it ( 'paginates large arrays showing only first 100 items' , ( ) => {
135+ const largeArray = Array . from ( { length : 150 } , ( _ , i ) => i )
136+ const { getByText, queryByText } = render ( < Json json = { largeArray } /> )
137+ getByText ( '0' )
138+ getByText ( '99' )
139+ expect ( queryByText ( '100' ) ) . toBeNull ( )
140+ getByText ( 'Show more...' )
141+ } )
142+
143+ it ( 'shows more array items when clicking Show more...' , async ( ) => {
144+ const largeArray = Array . from ( { length : 150 } , ( _ , i ) => i )
145+ const { getByText, queryByText } = render ( < Json json = { largeArray } /> )
146+ const user = userEvent . setup ( )
147+ await user . click ( getByText ( 'Show more...' ) )
148+ getByText ( '100' )
149+ getByText ( '149' )
150+ expect ( queryByText ( 'Show more...' ) ) . toBeNull ( )
151+ } )
152+
153+ it ( 'paginates large objects showing only first 100 entries' , ( ) => {
154+ const largeObj = Object . fromEntries ( Array . from ( { length : 150 } , ( _ , i ) => [ `key${ i } ` , i ] ) )
155+ const { getByText, queryByText } = render ( < Json json = { largeObj } /> )
156+ getByText ( 'key0:' )
157+ getByText ( 'key99:' )
158+ expect ( queryByText ( 'key100:' ) ) . toBeNull ( )
159+ getByText ( 'Show more...' )
160+ } )
161+
162+ it ( 'shows more object entries when clicking Show more...' , async ( ) => {
163+ const largeObj = Object . fromEntries ( Array . from ( { length : 150 } , ( _ , i ) => [ `key${ i } ` , i ] ) )
164+ const { getByText, queryByText } = render ( < Json json = { largeObj } /> )
165+ const user = userEvent . setup ( )
166+ await user . click ( getByText ( 'Show more...' ) )
167+ getByText ( 'key100:' )
168+ getByText ( 'key149:' )
169+ expect ( queryByText ( 'Show more...' ) ) . toBeNull ( )
170+ } )
171+
130172 it ( 'toggles array collapse state' , async ( ) => {
131173 const longArray = Array . from ( { length : 101 } , ( _ , i ) => i )
132174 const { getByRole, getByText, queryByText } = render ( < Json json = { longArray } /> )
133175 const treeItem = getByRole ( 'treeitem' )
134- getByText ( '...' )
176+ expect ( queryByText ( '...' ) ) . toBeNull ( ) // expanded by default
135177 const user = userEvent . setup ( )
136- await user . click ( treeItem )
137- expect ( queryByText ( '...' ) ) . toBeNull ( )
138- await user . click ( treeItem )
178+ await user . click ( treeItem ) // collapse
139179 getByText ( '...' )
180+ await user . click ( treeItem ) // expand again
181+ expect ( queryByText ( '...' ) ) . toBeNull ( )
140182 } )
141183
142184 it ( 'toggles object collapse state' , async ( ) => {
143185 const longObject = Object . fromEntries ( Array . from ( { length : 101 } , ( _ , i ) => [ `key${ i } ` , { nested : true } ] ) )
144- const { getByRole, getByText, queryByText } = render ( < Json json = { longObject } /> )
145- const treeItem = getByRole ( 'treeitem' ) // only one treeitem because the inner objects are collapsed and not represented as treeitems
146- getByText ( '...' )
147- const user = userEvent . setup ( )
148- await user . click ( treeItem )
186+ const { getAllByRole, getByRole, getByText, queryByText } = render ( < Json json = { longObject } /> )
187+ const treeItem = getAllByRole ( 'treeitem' ) [ 0 ] // expanded by default due to expandRoot
188+ if ( ! treeItem ) throw new Error ( 'No root element found' )
149189 expect ( queryByText ( '...' ) ) . toBeNull ( )
150- await user . click ( treeItem )
190+ const user = userEvent . setup ( )
191+ await user . click ( treeItem ) // collapse
192+ getByRole ( 'treeitem' ) // now only one treeitem
151193 getByText ( '...' )
194+ await user . click ( treeItem ) // expand again
195+ expect ( queryByText ( '...' ) ) . toBeNull ( )
152196 } )
153197} )
154198
0 commit comments