@@ -7,9 +7,10 @@ import { LogLevel } from '@codingame/monaco-vscode-api';
77import { render , type RenderResult } from '@testing-library/react' ;
88import { MonacoEditorReactComp } from '@typefox/monaco-editor-react' ;
99import { delayExecution } from 'monaco-languageclient/common' ;
10+ import type { EditorApp , TextContents } from 'monaco-languageclient/editorApp' ;
1011import { type LanguageClientManager } from 'monaco-languageclient/lcwrapper' ;
1112import { type MonacoVscodeApiConfig } from 'monaco-languageclient/vscodeApiWrapper' ;
12- import React , { StrictMode } from 'react' ;
13+ import React , { StrictMode , useState } from 'react' ;
1314import { describe , expect , test } from 'vitest' ;
1415import { cleanHtmlBody , createDefaultEditorAppConfig , createDefaultLanguageClientConfig , Deferred , unmountDelayMs } from './support/helper.js' ;
1516
@@ -218,5 +219,113 @@ describe('Test MonacoEditorReactComp', () => {
218219 cleanHtmlBody ( ) ;
219220 } ) ;
220221
222+ test . sequential ( 'srict mode: test render, modifiedTextValue' , async ( ) => {
223+ const code = 'const text = "Hello World!";' ;
224+ const codeUpdated = 'const text = "Goodbye World!";' ;
225+
226+ let editorApp : EditorApp | undefined ;
227+
228+ const deferredStart = new Deferred ( ) ;
229+ const deferredChanged = new Deferred ( ) ;
230+ let modified ;
231+ let count = 0 ;
232+
233+ const App = ( ) => {
234+ const [ testState , setTestState ] = useState < string > ( code ) ;
235+
236+ const editorAppConfig = createDefaultEditorAppConfig ( {
237+ modified : {
238+ text : code ,
239+ uri : `/workspace/${ expect . getState ( ) . testPath } .js`
240+ }
241+ } ) ;
242+
243+ return (
244+ < StrictMode >
245+ < button id = 'change-button' style = { { background : 'purple' } } onClick = { ( ) => setTestState ( codeUpdated ) } > Change Text</ button >
246+ < MonacoEditorReactComp
247+ vscodeApiConfig = { vscodeApiConfig }
248+ editorAppConfig = { editorAppConfig }
249+ style = { { 'height' : '800px' } }
250+ onTextChanged = { async ( textChanges : TextContents ) => {
251+ modified = textChanges . modified ;
252+ count ++ ;
253+ if ( codeUpdated === modified ) {
254+ deferredChanged . resolve ( ) ;
255+ }
256+ } }
257+ onEditorStartDone = { ( editorAppPassed ?: EditorApp ) => {
258+ editorApp = editorAppPassed ;
259+ deferredStart . resolve ( ) ;
260+ } }
261+ modifiedTextValue = { testState }
262+ />
263+ </ StrictMode >
264+ ) ;
265+ } ;
266+ const renderResult = render ( < App /> ) ;
267+ await expect ( await deferredStart . promise ) . toBeUndefined ( ) ;
268+
269+ // delay execute/click, so await below is already awaiting the deferredDispose
270+ setTimeout ( ( ) => {
271+ document . getElementById ( 'change-button' ) ?. click ( ) ;
272+ } , unmountDelayMs ) ;
273+
274+ await expect ( await deferredChanged . promise ) . toBeUndefined ( ) ;
275+ await expect ( count ) . toBe ( 2 ) ;
276+ await expect ( editorApp ?. getEditor ( ) ?. getValue ( ) ) . toBe ( codeUpdated ) ;
277+
278+ renderResult . unmount ( ) ;
279+
280+ cleanHtmlBody ( ) ;
281+ } ) ;
282+
283+ test . sequential ( 'strictmode: test state change effects editorconfig' , async ( ) => {
284+ const deferredStart = new Deferred ( ) ;
285+ const deferredDispose = new Deferred ( ) ;
286+ const App = ( ) => {
287+ const code = 'const text = "Hello World!";' ;
288+ const [ testState , setTestState ] = useState < string > ( code ) ;
289+
290+ const editorAppConfig = createDefaultEditorAppConfig ( {
291+ modified : {
292+ text : testState ,
293+ uri : `/workspace/${ expect . getState ( ) . testPath } .js`
294+ }
295+ } ) ;
296+
297+ return (
298+ < StrictMode >
299+ < button id = 'change-button' style = { { background : 'purple' } } onClick = { ( ) => setTestState ( testState + '\n// comment' ) } > Change Text</ button >
300+ < MonacoEditorReactComp
301+ vscodeApiConfig = { vscodeApiConfig }
302+ editorAppConfig = { editorAppConfig }
303+ style = { { 'height' : '800px' } }
304+ onEditorStartDone = { ( ) => deferredStart . resolve ( ) }
305+ onDisposeEditor = { ( ) => {
306+ console . log ( 'Editor disposed' ) ;
307+ deferredDispose . resolve ( ) ;
308+ } }
309+ />
310+ </ StrictMode >
311+ ) ;
312+ } ;
313+
314+ const renderResult = render ( < App /> ) ;
315+
316+ await expect ( await deferredStart . promise ) . toBeUndefined ( ) ;
317+ expect ( document . getElementsByClassName ( 'monaco-editor' ) . length ) . toBe ( 1 ) ;
318+
319+ // delay execute/click, so await below is already awaiting the deferredDispose
320+ setTimeout ( ( ) => {
321+ document . getElementById ( 'change-button' ) ?. click ( ) ;
322+ } , unmountDelayMs ) ;
323+ await expect ( await deferredDispose . promise ) . toBeUndefined ( ) ;
324+
325+ renderResult . unmount ( ) ;
326+
327+ cleanHtmlBody ( ) ;
328+ } ) ;
329+
221330} ) ;
222331
0 commit comments