1- /* eslint-disable react/jsx-key */
1+ /* eslint-disable @typescript-eslint/naming-convention */
2+
23import * as React from 'react' ;
3- import { Source } from '@storybook/addon-docs ' ;
4- import { createRenderer } from 'react-test-renderer/shallow' ;
4+ import { render } from '@testing-library/react ' ;
5+
56import { CodeExample } from './utils.stories' ;
67
8+ // Mock the Source component to verify it receives correct props
9+ const mockSource = jest . fn ( ( { code, language } : { code : string ; language : string } ) => (
10+ < pre data-testid = "source" data-language = { language } >
11+ < code > { code } </ code >
12+ </ pre >
13+ ) ) ;
14+
15+ // `Source` wont be available in the test environment, so we need to mock it to test the code output
16+ jest . mock ( '@storybook/addon-docs' , ( ) => ( {
17+ Source : ( props : { code : string ; language : string } ) => mockSource ( props ) ,
18+ } ) ) ;
19+
720function mockMDXSourceCodeBlock ( source : string ) {
821 return {
922 props : {
@@ -16,23 +29,22 @@ function mockMDXSourceCodeBlock(source: string) {
1629 } as React . ReactElement ;
1730}
1831
32+ beforeEach ( ( ) => {
33+ mockSource . mockClear ( ) ;
34+ } ) ;
35+
1936test ( 'renders children' , ( ) => {
20- const renderer = createRenderer ( ) ;
21- renderer . render (
37+ const { container } = render (
2238 < CodeExample >
2339 < span > Child</ span >
2440 </ CodeExample > ,
2541 ) ;
26- const result = renderer . getRenderOutput ( ) ;
2742
28- expect ( result . props ) . toEqual ( {
29- children : 'Child' ,
30- } ) ;
43+ expect ( container . textContent ) . toBe ( 'Child' ) ;
3144} ) ;
3245
3346test ( 'renders Markdown source blocks' , ( ) => {
34- const renderer = createRenderer ( ) ;
35- renderer . render (
47+ const { getByRole, getByTestId } = render (
3648 < CodeExample >
3749 { mockMDXSourceCodeBlock ( `\`\`\`js
3850 function test() {
@@ -41,53 +53,60 @@ test('renders Markdown source blocks', () => {
4153 \`\`\`` ) }
4254 </ CodeExample > ,
4355 ) ;
44- const result = renderer . getRenderOutput ( ) ;
4556
46- expect ( result . props ) . toEqual ( {
47- children : [
48- < h3 > JavaScript</ h3 > ,
49- < Source
50- code = { `function test() {
57+ // Test that CodeExample correctly parses and renders the header
58+ const heading = getByRole ( 'heading' , { level : 3 } ) ;
59+ expect ( heading . textContent ) . toBe ( 'JavaScript' ) ;
60+
61+ // Verify Source component was called with correct props
62+ expect ( mockSource ) . toHaveBeenCalledWith (
63+ expect . objectContaining ( {
64+ code : `function test() {
5165 console.log("test");
52- }` }
53- language = "jsextra"
54- /> ,
55- ] ,
56- } ) ;
66+ }` ,
67+ language : 'jsextra' ,
68+ } ) ,
69+ ) ;
70+
71+ // Verify Source component rendered correctly
72+ const sourceElement = getByTestId ( 'source' ) ;
73+ expect ( sourceElement . getAttribute ( 'data-language' ) ) . toBe ( 'jsextra' ) ;
74+ expect ( sourceElement . textContent ) . toContain ( 'function test()' ) ;
5775} ) ;
5876
5977test ( 'uses JSX for no header JSX source code blocks' , ( ) => {
60- const renderer = createRenderer ( ) ;
61- renderer . render (
78+ const { getByRole, getByTestId } = render (
6279 < CodeExample >
6380 { mockMDXSourceCodeBlock ( `<div>
6481 <Test title={"Example"} />
6582 </div>` ) }
6683 </ CodeExample > ,
6784 ) ;
68- const result = renderer . getRenderOutput ( ) ;
6985
70- expect ( result . props ) . toEqual ( {
71- children : [
72- < h3 > React</ h3 > ,
73- < Source
74- code = { `<div>
86+ const heading = getByRole ( 'heading' , { level : 3 } ) ;
87+ expect ( heading . textContent ) . toBe ( 'React' ) ;
88+
89+ // Verify Source component was called with JSX language
90+ expect ( mockSource ) . toHaveBeenCalledWith (
91+ expect . objectContaining ( {
92+ code : `<div>
7593 <Test title={"Example"} />
76- </div>` }
77- language = "jsx"
78- /> ,
79- ] ,
80- } ) ;
94+ </div>` ,
95+ language : 'jsx' ,
96+ } ) ,
97+ ) ;
98+
99+ const sourceElement = getByTestId ( 'source' ) ;
100+ expect ( sourceElement . getAttribute ( 'data-language' ) ) . toBe ( 'jsx' ) ;
81101} ) ;
82102
83103test . each ( [
84104 [ 'html' , 'HTML' ] ,
85105 [ 'css' , 'CSS' ] ,
86106 [ 'js' , 'JavaScript' ] ,
87107 [ 'jsx' , 'React' ] ,
88- ] as const ) ( 'for language %s uses the header %s' , ( language , expectedHeader ) => {
89- const renderer = createRenderer ( ) ;
90- renderer . render (
108+ ] ) ( 'for language %s uses the header %s' , ( language , expectedHeader ) => {
109+ const { getByRole, getByTestId } = render (
91110 < CodeExample >
92111 { mockMDXSourceCodeBlock ( `
93112 \`\`\`${ language }
@@ -96,16 +115,27 @@ test.each([
96115 ` ) }
97116 </ CodeExample > ,
98117 ) ;
99- const result = renderer . getRenderOutput ( ) ;
100118
101- expect ( result . props ) . toEqual ( {
102- children : [ < h3 > { expectedHeader } </ h3 > , < Source code = { `Code` } language = { language === 'js' ? 'jsextra' : language } /> ] ,
103- } ) ;
119+ const resolvedLanguage = language === 'js' ? 'jsextra' : language ;
120+
121+ const heading = getByRole ( 'heading' , { level : 3 } ) ;
122+ expect ( heading . textContent ) . toBe ( expectedHeader ) ;
123+
124+ // Verify Source component was called with correct language
125+ expect ( mockSource ) . toHaveBeenCalledWith (
126+ expect . objectContaining ( {
127+ code : 'Code' ,
128+ language : resolvedLanguage ,
129+ } ) ,
130+ ) ;
131+
132+ const sourceElement = getByTestId ( 'source' ) ;
133+ expect ( sourceElement . getAttribute ( 'data-language' ) ) . toBe ( resolvedLanguage ) ;
134+ expect ( sourceElement . textContent ) . toBe ( 'Code' ) ;
104135} ) ;
105136
106137test ( 'overrides the default title' , ( ) => {
107- const renderer = createRenderer ( ) ;
108- renderer . render (
138+ const { getByRole, getByTestId } = render (
109139 < CodeExample title = "Custom title" >
110140 { mockMDXSourceCodeBlock ( `
111141 \`\`\`js
@@ -114,9 +144,18 @@ test('overrides the default title', () => {
114144 ` ) }
115145 </ CodeExample > ,
116146 ) ;
117- const result = renderer . getRenderOutput ( ) ;
118147
119- expect ( result . props ) . toEqual ( {
120- children : [ < h3 > Custom title</ h3 > , < Source code = { `Code` } language = "jsextra" /> ] ,
121- } ) ;
148+ const heading = getByRole ( 'heading' , { level : 3 } ) ;
149+ expect ( heading . textContent ) . toBe ( 'Custom title' ) ;
150+
151+ // Verify Source component still receives correct code and language
152+ expect ( mockSource ) . toHaveBeenCalledWith (
153+ expect . objectContaining ( {
154+ code : 'Code' ,
155+ language : 'jsextra' ,
156+ } ) ,
157+ ) ;
158+
159+ const sourceElement = getByTestId ( 'source' ) ;
160+ expect ( sourceElement . getAttribute ( 'data-language' ) ) . toBe ( 'jsextra' ) ;
122161} ) ;
0 commit comments