1
1
import React , { useContext } from 'react' ;
2
2
import { DragDropContext , Droppable , DropResult } from 'react-beautiful-dnd' ;
3
+ import { GlobalContext } from '../../context/reducers/globalReducer' ;
4
+ import { createFile } from '../../context/actions/globalActions' ;
3
5
import styles from './TestCase.module.scss' ;
4
6
import { HooksTestCaseContext } from '../../context/reducers/hooksTestCaseReducer' ;
5
7
import {
@@ -10,12 +12,17 @@ import HooksTestMenu from '../TestMenu/HooksTestMenu';
10
12
import HooksTestStatements from './HooksTestStatements' ;
11
13
import { HooksStatements } from '../../utils/hooksTypes' ;
12
14
import HooksHelpModal from '../TestHelpModals/HooksHelpModal' ;
15
+ const remote = window . require ( 'electron' ) . remote ;
16
+ const beautify = remote . require ( 'js-beautify' ) ;
17
+ const path = remote . require ( 'path' ) ;
13
18
14
19
const HooksTestCase = ( ) => {
15
20
const [ { hooksTestStatement, hooksStatements, modalOpen } , dispatchToHooksTestCase ] = useContext (
16
21
HooksTestCaseContext
17
22
) ;
18
23
24
+ const [ { projectFilePath } , dispatchToGlobal ] = useContext < any > ( GlobalContext ) ;
25
+
19
26
const handleUpdateHooksTestStatement = ( e : React . ChangeEvent < HTMLInputElement > ) => {
20
27
dispatchToHooksTestCase ( updateHooksTestStatement ( e . target . value ) ) ;
21
28
} ;
@@ -41,12 +48,150 @@ const HooksTestCase = () => {
41
48
) ;
42
49
dispatchToHooksTestCase ( updateStatementsOrder ( reorderedStatements ) ) ;
43
50
} ;
51
+ let testFileCode = 'import React from "react";' ;
52
+ const generatHookFile = ( ) => {
53
+ return (
54
+ addHooksImportStatements ( ) ,
55
+ addHooksTestStatements ( ) ,
56
+ ( testFileCode = beautify ( testFileCode , {
57
+ indent_size : 2 ,
58
+ space_in_empty_paren : true ,
59
+ e4x : true ,
60
+ } ) )
61
+ ) ;
62
+ } ;
63
+
64
+ const addHooksImportStatements = ( ) => {
65
+ hooksStatements . forEach ( ( statement : any ) => {
66
+ switch ( statement . type ) {
67
+ case 'hook-updates' :
68
+ return addRenderHooksImportStatement ( ) , createPathToHooks ( statement ) ;
69
+ case 'hookRender' :
70
+ return addRenderHooksImportStatement ( ) , createPathToHooks ( statement ) ;
71
+ case 'context' :
72
+ return addContextImportStatements ( ) , createPathToContext ( statement ) ;
73
+ default :
74
+ return statement ;
75
+ }
76
+ } ) ;
77
+ testFileCode += '\n' ;
78
+ } ;
79
+
80
+ const addHooksTestStatements = ( ) => {
81
+ testFileCode += `\n test('${ hooksTestStatement } ', () => {` ;
82
+ hooksStatements . forEach ( ( statement : any ) => {
83
+ switch ( statement . type ) {
84
+ case 'hook-updates' :
85
+ return addHookUpdates ( statement ) ;
86
+ case 'hookRender' :
87
+ return addHookRender ( statement ) ;
88
+ case 'context' :
89
+ return addContext ( statement ) ;
90
+ default :
91
+ return statement ;
92
+ }
93
+ } ) ;
94
+ testFileCode += '});' ;
95
+ testFileCode += '\n' ;
96
+ } ;
97
+
98
+ // Hooks Import Statements
99
+ const addRenderHooksImportStatement = ( ) => {
100
+ if ( ! testFileCode . includes ( `import '@testing-library/jest-dom/extend-expect';` ) ) {
101
+ testFileCode += `import '@testing-library/jest-dom/extend-expect';` ;
102
+ }
103
+ if ( ! testFileCode . includes ( `import { renderHook, act } from '@testing-library/react-hooks';` ) ) {
104
+ testFileCode += `import { renderHook, act } from '@testing-library/react-hooks';` ;
105
+ }
106
+ } ;
107
+
108
+ // Hooks Filepath
109
+ const createPathToHooks = ( statement : any ) => {
110
+ let filePath = path . relative ( projectFilePath , statement . hookFilePath ) ;
111
+ filePath = filePath . replace ( / \\ / g, '/' ) ;
112
+ testFileCode += `import ${ statement . hook } from '../${ filePath } ';` ;
113
+ } ;
114
+
115
+ // Context Import Statements
116
+ const addContextImportStatements = ( ) => {
117
+ if ( ! testFileCode . includes ( `import '@testing-library/jest-dom/extend-expect';` ) ) {
118
+ testFileCode += `import '@testing-library/jest-dom/extend-expect';` ;
119
+ }
120
+ if ( ! testFileCode . includes ( `import { render } from '@testing-library/react';` ) ) {
121
+ testFileCode += `import { render } from '@testing-library/react';` ;
122
+ }
123
+ } ;
124
+
125
+ // Context Filepath
126
+ const createPathToContext = ( statement : any ) => {
127
+ let filePath = path . relative ( projectFilePath , statement . contextFilePath ) ;
128
+ filePath = filePath . replace ( / \\ / g, '/' ) ;
129
+ testFileCode += `import { ${ statement . providerComponent } , ${ statement . consumerComponent } , ${ statement . context } } from '../${ filePath } ';` ;
130
+ } ;
131
+
132
+ // Hook: Updates Jest Test Code
133
+ const addHookUpdates = ( hookUpdates : any ) => {
134
+ testFileCode += `const {result} = renderHook (() => ${ hookUpdates . hook } ());
135
+ act(() => {
136
+ result.current.${ hookUpdates . callbackFunc } ();
137
+ });
138
+ expect(result.current.${ hookUpdates . managedState } ).toBe(${ hookUpdates . updatedState } )` ;
139
+ } ;
140
+
141
+ // Hook: Renders Jest Test Code
142
+ const addHookRender = ( hookRender : any ) => {
143
+ testFileCode += `const {result} = renderHook(() => ${ hookRender . hook } (${ hookRender . parameterOne } ))
144
+ expect(result.current.${ hookRender . returnValue } ).toBe(${ hookRender . expectedReturnValue } )` ;
145
+ } ;
146
+
147
+ // Context Jest Test Code
148
+ const addContext = ( context : any ) => {
149
+ if ( context . queryValue === 'shows_default_value' ) {
150
+ testFileCode += `const mockValue = {Data: '${ context . values } '}
151
+ const { ${ context . querySelector } } = render(<${ context . consumerComponent } />)
152
+ expect(${ context . querySelector } (mockValue.Data)).${ context . queryVariant } ('${ context . values } ')` ;
153
+ }
154
+ if ( context . queryValue === 'shows_value_from_provider' ) {
155
+ testFileCode += `const mockValue = {Data: '${ context . values } '}
156
+ const { ${ context . querySelector } } = render (
157
+ <${ context . context } .Provider value={mockValue}>
158
+ <${ context . consumerComponent } />
159
+ </${ context . context } .Provider>
160
+ )
161
+ expect(${ context . querySelector } (mockValue.Data)).${ context . queryVariant } ('${ context . values } ')` ;
162
+ }
163
+ if ( context . queryValue === 'component_provides_context_value' ) {
164
+ testFileCode += `const mockValue = {Data: '${ context . values } '}
165
+ const { ${ context . querySelector } } = render (
166
+ <${ context . providerComponent } value={mockValue}>
167
+ <${ context . context } .Consumer>
168
+ {value => <span>Recieved: {value} </span>}
169
+ <${ context . context } .Consumer/>
170
+ </${ context . providerComponent } >
171
+ )
172
+ expect(${ context . querySelector } (/^Recieved:/).textContent).${ context . queryVariant } ('${ context . values } ')` ;
173
+ }
174
+ if ( context . queryValue === 'renders_providers_+_consumers_normally' ) {
175
+ testFileCode += `const mockValue = {Data: '${ context . values } '}
176
+ const { ${ context . querySelector } } = render (
177
+ <${ context . providerComponent } value={mockValue}>
178
+ <${ context . consumerComponent } />
179
+ </${ context . providerComponent } >
180
+ )
181
+ expect(${ context . querySelector } (mockValue.Data).textContent).${ context . queryVariant } ('${ context . values } ')` ;
182
+ }
183
+ } ;
184
+
185
+ const fileHandle = ( ) => {
186
+ dispatchToGlobal ( createFile ( generatHookFile ( ) ) ) ;
187
+ } ;
44
188
45
189
return (
46
190
< div >
47
191
< div id = 'head' >
48
192
< HooksTestMenu dispatchToHooksTestCase = { dispatchToHooksTestCase } />
49
193
</ div >
194
+ < button onClick = { fileHandle } > save me</ button >
50
195
{ modalOpen ? < HooksHelpModal /> : null }
51
196
< div id = { styles . testMockSection } >
52
197
< section id = { styles . testCaseHeader } >
0 commit comments