Skip to content

Commit aa02d2e

Browse files
committed
Update complete uri and model handling in EditorApp, fix onTextChanged handling in react component.
- Enforce proper uri usage in tests - Allow model dispose in EditorApp to be asynchronous in tests
1 parent 916e77d commit aa02d2e

22 files changed

+589
-376
lines changed

Diff for: package-lock.json

+2-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@
6767
"reset:chrome": "tsx ./scripts/clean.ts --relativePath . --recursive --paths .chrome",
6868
"reset:repo": "git clean -f -d -x --exclude=.chrome",
6969
"test": "npm run test:install && npm run test:direct",
70-
"test:direct": "vitest --config vitest.config.ts",
70+
"test:direct": "vitest --config vitest.config.ts --dangerouslyIgnoreUnhandledErrors=true",
7171
"test:run": "npm run test:install && npm run test:direct:run",
7272
"test:direct:run": "vitest --config vitest.config.ts --run",
7373
"test:debug": "npm run test:playwright -- --inspect-brk=20222 --browser --no-file-parallelism",

Diff for: packages/client/test/fs/endpoints/emptyEndpoint.test.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ describe('EmptyFileSystemEndpoint Tests', () => {
2121
test('writeFile', async () => {
2222
const result = await endpoint.writeFile({
2323
resourceUri: '/tmp/test.js',
24-
content: 'console.log("Hello World!");'
24+
content: 'const text = "Hello World!";'
2525
});
2626
expect(result).toEqual({
2727
status: 'denied'
@@ -31,7 +31,7 @@ describe('EmptyFileSystemEndpoint Tests', () => {
3131
test('syncFile', async () => {
3232
const result = await endpoint.syncFile({
3333
resourceUri: '/tmp/test.js',
34-
content: 'console.log("Hello World!");'
34+
content: 'const text = "Hello World!";'
3535
});
3636
expect(result).toEqual({
3737
status: 'denied'

Diff for: packages/examples/package.json

-1
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,6 @@
9292
"@codingame/monaco-vscode-search-service-override": "~15.0.3",
9393
"@codingame/monaco-vscode-secret-storage-service-override": "~15.0.3",
9494
"@codingame/monaco-vscode-standalone-json-language-features": "~15.0.3",
95-
"@codingame/monaco-vscode-standalone-languages": "~15.0.3",
9695
"@codingame/monaco-vscode-standalone-typescript-language-features": "~15.0.3",
9796
"@codingame/monaco-vscode-testing-service-override": "~15.0.3",
9897
"@codingame/monaco-vscode-storage-service-override": "~15.0.3",

Diff for: packages/examples/src/langium/statemachine/main-react.tsx

+18-11
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,6 @@ export const runStatemachineReact = async () => {
3333
});
3434
const root = ReactDOM.createRoot(document.getElementById('react-root')!);
3535

36-
const onTextChanged = (textChanges: TextContents) => {
37-
console.log(`text: ${textChanges.modified}\ntextOriginal: ${textChanges.original}`);
38-
};
3936
try {
4037
document.querySelector('#button-start')?.addEventListener('click', async () => {
4138
disableElement('button-start', true);
@@ -44,23 +41,33 @@ export const runStatemachineReact = async () => {
4441
const App = () => {
4542

4643
const [ height, setHeight ] = useState('80vh');
44+
const [testState, setTestState] = useState<string>('');
45+
46+
const onTextChanged = (textChanges: TextContents) => {
47+
console.log(`text: ${textChanges.modified}\ntextOriginal: ${textChanges.original}`);
48+
setTestState(textChanges.modified as string);
49+
};
4750

4851
useEffect(() => {
4952
const timer = setTimeout(() => {
5053
console.log('Updating styles');
51-
setHeight('85vh');
52-
}, 2000);
54+
setHeight('50vh');
55+
}, 1000);
5356

5457
return () => clearTimeout(timer);
5558
}, []);
5659

5760
return (
58-
<div style={{ 'height': height }} >
59-
<MonacoEditorReactComp
60-
style={{ 'height': '100%' }}
61-
wrapperConfig={wrapperConfig}
62-
onTextChanged={onTextChanged} />
63-
</div>
61+
<>
62+
<div style={{ 'height': height }} >
63+
<MonacoEditorReactComp
64+
style={{ 'height': '100%' }}
65+
wrapperConfig={wrapperConfig}
66+
onTextChanged={onTextChanged}
67+
/>
68+
<b>Debug:</b><br />{testState}
69+
</div>
70+
</>
6471
);
6572
};
6673
const strictMode = (document.getElementById('checkbox-strictmode')! as HTMLInputElement).checked;

Diff for: packages/examples/src/langium/statemachine/main.ts

+7-8
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import * as vscode from 'vscode';
77
import { BrowserMessageReader, BrowserMessageWriter } from 'vscode-languageclient/browser.js';
8-
import { buildModelReference, MonacoEditorLanguageClientWrapper } from 'monaco-editor-wrapper';
8+
import { MonacoEditorLanguageClientWrapper } from 'monaco-editor-wrapper';
99
import { createLangiumGlobalConfig } from './config/wrapperStatemachineConfig.js';
1010
import workerUrl from './worker/statemachine-server?worker&url';
1111
import workerPortUrl from './worker/statemachine-server-port?worker&url';
@@ -57,12 +57,11 @@ const startEditor = async () => {
5757
});
5858
await wrapper.initAndStart(langiumGlobalConfig);
5959

60-
// here the modelReference is created manually and given to the updateEditorModels of the wrapper
61-
wrapper.updateEditorModels({
62-
modelRefModified: await buildModelReference({
60+
wrapper.updateCodeResources({
61+
modified: {
6362
text,
6463
uri: '/workspace/statemachine-mod.statemachine'
65-
})
64+
}
6665
});
6766

6867
// start the second wrapper without any languageclient config
@@ -84,11 +83,11 @@ const startEditor = async () => {
8483

8584
await delayExecution(1000);
8685

87-
wrapper.updateEditorModels({
88-
modelRefModified: await buildModelReference({
86+
wrapper.updateCodeResources({
87+
modified: {
8988
text: `// modified file\n\n${text}`,
9089
uri: '/workspace/statemachine-mod2.statemachine'
91-
})
90+
}
9291
});
9392
};
9493

Diff for: packages/examples/src/ts/wrapperTs.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import '@codingame/monaco-vscode-typescript-language-features-default-extension'
1010
import { LogLevel } from '@codingame/monaco-vscode-api';
1111
import { MonacoEditorLanguageClientWrapper, type WrapperConfig } from 'monaco-editor-wrapper';
1212
import { configureDefaultWorkerFactory } from 'monaco-editor-wrapper/workers/workerLoaders';
13+
import { disableElement } from '../common/client/utils.js';
1314

1415
export const runTsWrapper = async () => {
1516
const codeUri = '/workspace/hello.ts';
@@ -60,6 +61,7 @@ export const runTsWrapper = async () => {
6061
};
6162

6263
const wrapper = new MonacoEditorLanguageClientWrapper();
64+
disableElement('button-swap-code', true);
6365

6466
try {
6567
document.querySelector('#button-start')?.addEventListener('click', async () => {
@@ -75,7 +77,7 @@ export const runTsWrapper = async () => {
7577
await vscode.commands.executeCommand('actions.find');
7678
});
7779
document.querySelector('#button-swap-code')?.addEventListener('click', () => {
78-
const codeResources = wrapper.getMonacoEditorApp()?.getConfig().codeResources;
80+
const codeResources = wrapper.getEditorApp()?.getConfig().codeResources;
7981
if (codeResources?.modified?.uri === codeUri) {
8082
wrapper.updateCodeResources({
8183
modified: {
@@ -104,6 +106,8 @@ export const runTsWrapper = async () => {
104106
// ensure it is boolean value and not undefined
105107
const useDiffEditor = wrapperConfig.editorAppConfig!.useDiffEditor ?? false;
106108
wrapperConfig.editorAppConfig!.useDiffEditor = !useDiffEditor;
109+
disableElement('button-swap-code', !wrapperConfig.editorAppConfig!.useDiffEditor);
110+
107111
await wrapper.initAndStart(wrapperConfig);
108112
});
109113
document.querySelector('#button-dispose')?.addEventListener('click', async () => {

Diff for: packages/wrapper-react/src/index.tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export type MonacoEditorProps = {
1111
className?: string;
1212
wrapperConfig: WrapperConfig,
1313
onTextChanged?: (textChanges: TextContents) => void;
14+
onTextOriginalChanged?: (textChanges: TextContents) => void;
1415
onLoad?: (wrapper: MonacoEditorLanguageClientWrapper) => void;
1516
onError?: (e: unknown) => void;
1617
}
@@ -49,7 +50,7 @@ export const MonacoEditorReactComp: React.FC<MonacoEditorProps> = (props) => {
4950
const startMonaco = async () => {
5051
if (containerRef.current) {
5152
try {
52-
wrapperRef.current.registerTextChangeCallback(onTextChanged);
53+
wrapperRef.current.registerTextChangedCallback(onTextChanged);
5354
await wrapperRef.current.start();
5455
onLoad?.(wrapperRef.current);
5556
} catch (e) {
@@ -69,7 +70,7 @@ export const MonacoEditorReactComp: React.FC<MonacoEditorProps> = (props) => {
6970
await initMonaco();
7071
await startMonaco();
7172
})();
72-
}, [wrapperConfig, onTextChanged, onLoad, onError]);
73+
}, [wrapperConfig]);
7374

7475
useEffect(() => {
7576
// exact copy of the above function, to prevent declaration in useCallback

Diff for: packages/wrapper-react/test/helper.ts

+3-8
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,18 @@
44
* ------------------------------------------------------------------------------------------ */
55

66
import { LogLevel } from '@codingame/monaco-vscode-api';
7-
import type { WrapperConfig } from 'monaco-editor-wrapper';
7+
import type { CodeResources, WrapperConfig } from 'monaco-editor-wrapper';
88
import { configureDefaultWorkerFactory } from 'monaco-editor-wrapper/workers/workerLoaders';
99

10-
export const createDefaultWrapperConfig = (): WrapperConfig => {
10+
export const createDefaultWrapperConfig = (codeResources: CodeResources): WrapperConfig => {
1111
return {
1212
$type: 'extended',
1313
logLevel: LogLevel.Debug,
1414
vscodeApiConfig: {
1515
loadThemes: false
1616
},
1717
editorAppConfig: {
18-
codeResources: {
19-
modified: {
20-
text: 'hello world',
21-
uri: '/workspace/test.js'
22-
}
23-
},
18+
codeResources,
2419
monacoWorkerFactory: configureDefaultWorkerFactory
2520
}
2621
};

Diff for: packages/wrapper-react/test/index.test.tsx

+36-12
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,12 @@ import { createDefaultWrapperConfig } from './helper.js';
1313
describe('Test MonacoEditorReactComp', () => {
1414

1515
test('onLoad', async () => {
16-
const wrapperConfig = createDefaultWrapperConfig();
16+
const wrapperConfig = createDefaultWrapperConfig({
17+
modified: {
18+
text: 'const text = "Hello World!";',
19+
uri: `/workspace/${expect.getState().testPath}.js`,
20+
}
21+
});
1722

1823
let renderResult: RenderResult;
1924
// we have to await the full start of the editor with the onLoad callback, then it is save to contine
@@ -28,37 +33,47 @@ describe('Test MonacoEditorReactComp', () => {
2833
});
2934

3035
test('update onTextChanged', async () => {
31-
const wrapperConfig = createDefaultWrapperConfig();
36+
const wrapperConfig = createDefaultWrapperConfig({
37+
modified: {
38+
text: 'const text = "Hello World!";',
39+
uri: `/workspace/${expect.getState().testPath}.js`,
40+
}
41+
});
3242

3343
const textReceiverHello = (textChanges: TextContents) => {
34-
expect(textChanges.modified).toEqual('hello world');
44+
expect(textChanges.modified).toEqual('const text = "Hello World!";');
3545
};
3646

3747
const handleOnLoad = async (wrapper: MonacoEditorLanguageClientWrapper) => {
38-
expect(wrapper.getTextModels()?.modified?.getValue()).toEqual('hello world');
48+
expect(wrapper.getTextModels()?.modified?.getValue()).toEqual('const text = "Hello World!";');
3949
};
4050
render(<MonacoEditorReactComp wrapperConfig={wrapperConfig} onTextChanged={(textReceiverHello)} onLoad={handleOnLoad} />);
4151
});
4252

4353
test('update codeResources', async () => {
44-
const wrapperConfig = createDefaultWrapperConfig();
54+
const wrapperConfig = createDefaultWrapperConfig({
55+
modified: {
56+
text: 'const text = "Hello World!";',
57+
uri: `/workspace/${expect.getState().testPath}.js`,
58+
}
59+
});
4560

4661
let count = 0;
4762
const textReceiver = (textChanges: TextContents) => {
4863
// initial call
4964
if (count === 0) {
50-
expect(textChanges.modified).toBe('hello world');
65+
expect(textChanges.modified).toBe('const text = "Hello World!";');
5166
} else {
52-
expect(textChanges.modified).toBe('goodbye world');
67+
expect(textChanges.modified).toBe('const text = "Goodbye World!";');
5368
}
5469
};
5570

5671
const handleOnLoad = async (wrapper: MonacoEditorLanguageClientWrapper) => {
5772
count++;
5873
await wrapper.updateCodeResources({
5974
modified: {
60-
text: 'goodbye world',
61-
uri: '/workspace/test.js'
75+
text: 'const text = "Goodbye World!";',
76+
uri: `/workspace/${expect.getState().testPath}_goodbye.js`,
6277
}
6378
});
6479

@@ -69,9 +84,18 @@ describe('Test MonacoEditorReactComp', () => {
6984
test('rerender without error', async () => {
7085
let error = false;
7186
try {
72-
const wrapperConfig = createDefaultWrapperConfig();
73-
const newWrapperConfig = createDefaultWrapperConfig();
74-
newWrapperConfig.editorAppConfig!.codeResources!.modified!.text = 'hello world 2';
87+
const wrapperConfig = createDefaultWrapperConfig({
88+
modified: {
89+
text: 'const text = "Hello World!";',
90+
uri: `/workspace/${expect.getState().testPath}.js`,
91+
}
92+
});
93+
const newWrapperConfig = createDefaultWrapperConfig({
94+
modified: {
95+
text: 'const text = "Goodbye World 2!";',
96+
uri: `/workspace/${expect.getState().testPath}_2.js`,
97+
}
98+
});
7599
let renderResult: RenderResult;
76100

77101
const result1 = await new Promise<void>(resolve => {

Diff for: packages/wrapper/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@
9898
"vscode-ws-jsonrpc": "~3.4.0"
9999
},
100100
"devDependencies": {
101+
"@codingame/monaco-vscode-standalone-languages": "~15.0.3",
101102
"@codingame/monaco-vscode-standalone-css-language-features": "~15.0.3",
102103
"@codingame/monaco-vscode-standalone-html-language-features": "~15.0.3",
103104
"@codingame/monaco-vscode-standalone-json-language-features": "~15.0.3",

0 commit comments

Comments
 (0)