@theia/api-tests 1.34.2 → 1.34.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,207 +1,207 @@
1
- // *****************************************************************************
2
- // Copyright (C) 2022 Ericsson and others.
3
- //
4
- // This program and the accompanying materials are made available under the
5
- // terms of the Eclipse Public License v. 2.0 which is available at
6
- // http://www.eclipse.org/legal/epl-2.0.
7
- //
8
- // This Source Code may also be made available under the following Secondary
9
- // Licenses when the conditions for such availability set forth in the Eclipse
10
- // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
- // with the GNU Classpath Exception which is available at
12
- // https://www.gnu.org/software/classpath/license.html.
13
- //
14
- // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15
- // *****************************************************************************
16
-
17
- // @ts-check
18
-
19
- describe('Preferences', function () {
20
- this.timeout(5_000);
21
- const { assert } = chai;
22
- const { PreferenceProvider } = require('@theia/core/lib/browser/preferences/preference-provider');
23
- const { PreferenceService, PreferenceScope } = require('@theia/core/lib/browser/preferences/preference-service');
24
- const { FileService } = require('@theia/filesystem/lib/browser/file-service');
25
- const { PreferenceLanguageOverrideService } = require('@theia/core/lib/browser/preferences/preference-language-override-service');
26
- const { MonacoTextModelService } = require('@theia/monaco/lib/browser/monaco-text-model-service');
27
- const { PreferenceSchemaProvider } = require('@theia/core/lib/browser/preferences/preference-contribution')
28
- const { container } = window.theia;
29
- /** @type {import ('@theia/core/lib/browser/preferences/preference-service').PreferenceService} */
30
- const preferenceService = container.get(PreferenceService);
31
- /** @type {import ('@theia/core/lib/browser/preferences/preference-language-override-service').PreferenceLanguageOverrideService} */
32
- const overrideService = container.get(PreferenceLanguageOverrideService);
33
- const fileService = container.get(FileService);
34
- /** @type {import ('@theia/core/lib/common/uri').default} */
35
- const uri = preferenceService.getConfigUri(PreferenceScope.Workspace);
36
- /** @type {import('@theia/preferences/lib/browser/folders-preferences-provider').FoldersPreferencesProvider} */
37
- const folderPreferences = container.getNamed(PreferenceProvider, PreferenceScope.Folder);
38
- /** @type PreferenceSchemaProvider */
39
- const schemaProvider = container.get(PreferenceSchemaProvider);
40
- const modelService = container.get(MonacoTextModelService);
41
-
42
- const overrideIdentifier = 'bargle-noddle-zaus'; // Probably not in our preference files...
43
- const tabSize = 'editor.tabSize';
44
- const fontSize = 'editor.fontSize';
45
- const override = overrideService.markLanguageOverride(overrideIdentifier);
46
- const overriddenTabSize = overrideService.overridePreferenceName({ overrideIdentifier, preferenceName: tabSize });
47
- const overriddenFontSize = overrideService.overridePreferenceName({ overrideIdentifier, preferenceName: fontSize });
48
- /**
49
- * @returns {Promise<Record<string, any>>}
50
- */
51
- async function getPreferences() {
52
- try {
53
- const content = (await fileService.read(uri)).value;
54
- return JSON.parse(content);
55
- } catch (e) {
56
- return {};
57
- }
58
- }
59
-
60
- /**
61
- * @param {string} key
62
- * @param {unknown} value
63
- */
64
- async function setPreference(key, value) {
65
- return preferenceService.set(key, value, PreferenceScope.Workspace);
66
- }
67
-
68
- async function deleteAllValues() {
69
- return setValueTo(undefined);
70
- }
71
-
72
- /**
73
- * @param {any} value - A JSON value to write to the workspace preference file.
74
- */
75
- async function setValueTo(value) {
76
- const reference = await modelService.createModelReference(uri);
77
- if (reference.object.dirty) {
78
- await reference.object.revert();
79
- }
80
- /** @type {import ('@theia/preferences/lib/browser/folder-preference-provider').FolderPreferenceProvider} */
81
- const provider = Array.from(folderPreferences['providers'].values()).find(candidate => candidate.getConfigUri().isEqual(uri));
82
- assert.isDefined(provider);
83
- await provider['doSetPreference']('', [], value);
84
- reference.dispose();
85
- }
86
-
87
- let fileExistsBeforehand = false;
88
- let contentBeforehand = '';
89
-
90
- before(async function () {
91
- assert.isDefined(uri, 'The workspace config URI should be defined!');
92
- fileExistsBeforehand = await fileService.exists(uri);
93
- contentBeforehand = await fileService.read(uri).then(({ value }) => value).catch(() => '');
94
- schemaProvider.registerOverrideIdentifier(overrideIdentifier);
95
- await deleteAllValues();
96
- });
97
-
98
- after(async function () {
99
- if (!fileExistsBeforehand) {
100
- await fileService.delete(uri, { fromUserGesture: false }).catch(() => { });
101
- } else {
102
- let content = '';
103
- try { content = JSON.parse(contentBeforehand); } catch { }
104
- // Use the preference service because its promise is guaranteed to resolve after the file change is complete.
105
- await setValueTo(content);
106
- }
107
- });
108
-
109
- beforeEach(async function () {
110
- const prefs = await getPreferences();
111
- for (const key of [tabSize, fontSize, override, overriddenTabSize, overriddenFontSize]) {
112
- shouldBeUndefined(prefs[key], key);
113
- }
114
- });
115
-
116
- afterEach(async function () {
117
- await deleteAllValues();
118
- });
119
-
120
- /**
121
- * @param {unknown} value
122
- * @param {string} key
123
- */
124
- function shouldBeUndefined(value, key) {
125
- assert.isUndefined(value, `There should be no ${key} object or value in the preferences.`);
126
- }
127
-
128
- /**
129
- * @returns {Promise<{newTabSize: number, newFontSize: number, startingTabSize: number, startingFontSize: number}>}
130
- */
131
- async function setUpOverride() {
132
- const startingTabSize = preferenceService.get(tabSize);
133
- const startingFontSize = preferenceService.get(fontSize);
134
- assert.equal(preferenceService.get(overriddenTabSize), startingTabSize, 'The overridden value should equal the default.');
135
- assert.equal(preferenceService.get(overriddenFontSize), startingFontSize, 'The overridden value should equal the default.');
136
- const newTabSize = startingTabSize + 2;
137
- const newFontSize = startingFontSize + 2;
138
- await Promise.all([
139
- setPreference(overriddenTabSize, newTabSize),
140
- setPreference(overriddenFontSize, newFontSize),
141
- ]);
142
- assert.equal(preferenceService.get(overriddenTabSize), newTabSize, 'After setting, the new value should be active for the override.');
143
- assert.equal(preferenceService.get(overriddenFontSize), newFontSize, 'After setting, the new value should be active for the override.');
144
- return { newTabSize, newFontSize, startingTabSize, startingFontSize };
145
- }
146
-
147
- it('Sets language overrides as objects', async function () {
148
- const { newTabSize, newFontSize } = await setUpOverride();
149
- const prefs = await getPreferences();
150
- assert.isObject(prefs[override], 'The override should be a key in the preference object.');
151
- assert.equal(prefs[override][tabSize], newTabSize, 'editor.tabSize should be a key in the override object and have the correct value.');
152
- assert.equal(prefs[override][fontSize], newFontSize, 'editor.fontSize should be a key in the override object and should have the correct value.');
153
- shouldBeUndefined(prefs[overriddenTabSize], overriddenTabSize);
154
- shouldBeUndefined(prefs[overriddenFontSize], overriddenFontSize);
155
- });
156
-
157
- it('Allows deletion of individual keys in the override object.', async function () {
158
- const { startingTabSize } = await setUpOverride();
159
- await setPreference(overriddenTabSize, undefined);
160
- assert.equal(preferenceService.get(overriddenTabSize), startingTabSize);
161
- const prefs = await getPreferences();
162
- shouldBeUndefined(prefs[override][tabSize], tabSize);
163
- shouldBeUndefined(prefs[overriddenFontSize], overriddenFontSize);
164
- shouldBeUndefined(prefs[overriddenTabSize], overriddenTabSize);
165
- });
166
-
167
- it('Allows deletion of the whole override object', async function () {
168
- const { startingFontSize, startingTabSize } = await setUpOverride();
169
- await setPreference(override, undefined);
170
- assert.equal(preferenceService.get(overriddenTabSize), startingTabSize, 'The overridden value should revert to the default.');
171
- assert.equal(preferenceService.get(overriddenFontSize), startingFontSize, 'The overridden value should revert to the default.');
172
- const prefs = await getPreferences();
173
- shouldBeUndefined(prefs[override], override);
174
- });
175
-
176
- it('Handles many synchronous settings of preferences gracefully', async function () {
177
- let settings = 0;
178
- const promises = [];
179
- const searchPref = 'search.searchOnTypeDebouncePeriod'
180
- const channelPref = 'output.maxChannelHistory'
181
- const hoverPref = 'workbench.hover.delay';
182
- let searchDebounce;
183
- let channelHistory;
184
- let hoverDelay;
185
- /** @type import ('@theia/core/src/browser/preferences/preference-service').PreferenceChanges | undefined */
186
- let event;
187
- const toDispose = preferenceService.onPreferencesChanged(e => event = e);
188
- while (settings++ < 50) {
189
- searchDebounce = 100 + Math.floor(Math.random() * 500);
190
- channelHistory = 200 + Math.floor(Math.random() * 800);
191
- hoverDelay = 250 + Math.floor(Math.random() * 2_500);
192
- promises.push(
193
- preferenceService.set(searchPref, searchDebounce),
194
- preferenceService.set(channelPref, channelHistory),
195
- preferenceService.set(hoverPref, hoverDelay)
196
- );
197
- }
198
- const results = await Promise.allSettled(promises);
199
- const expectedValues = { [searchPref]: searchDebounce, [channelPref]: channelHistory, [hoverPref]: hoverDelay };
200
- const actualValues = { [searchPref]: preferenceService.get(searchPref), [channelPref]: preferenceService.get(channelPref), [hoverPref]: preferenceService.get(hoverPref), }
201
- const eventValues = event && Object.keys(event).reduce((accu, key) => { accu[key] = event[key].newValue; return accu; }, {});
202
- toDispose.dispose();
203
- assert(results.every(setting => setting.status === 'fulfilled'), 'All promises should have resolved rather than rejected.');
204
- assert.deepEqual(actualValues, eventValues, 'The event should reflect the current state of the service.');
205
- assert.deepEqual(expectedValues, actualValues, 'The service state should reflect the most recent setting');
206
- });
207
- });
1
+ // *****************************************************************************
2
+ // Copyright (C) 2022 Ericsson and others.
3
+ //
4
+ // This program and the accompanying materials are made available under the
5
+ // terms of the Eclipse Public License v. 2.0 which is available at
6
+ // http://www.eclipse.org/legal/epl-2.0.
7
+ //
8
+ // This Source Code may also be made available under the following Secondary
9
+ // Licenses when the conditions for such availability set forth in the Eclipse
10
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ // with the GNU Classpath Exception which is available at
12
+ // https://www.gnu.org/software/classpath/license.html.
13
+ //
14
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15
+ // *****************************************************************************
16
+
17
+ // @ts-check
18
+
19
+ describe('Preferences', function () {
20
+ this.timeout(5_000);
21
+ const { assert } = chai;
22
+ const { PreferenceProvider } = require('@theia/core/lib/browser/preferences/preference-provider');
23
+ const { PreferenceService, PreferenceScope } = require('@theia/core/lib/browser/preferences/preference-service');
24
+ const { FileService } = require('@theia/filesystem/lib/browser/file-service');
25
+ const { PreferenceLanguageOverrideService } = require('@theia/core/lib/browser/preferences/preference-language-override-service');
26
+ const { MonacoTextModelService } = require('@theia/monaco/lib/browser/monaco-text-model-service');
27
+ const { PreferenceSchemaProvider } = require('@theia/core/lib/browser/preferences/preference-contribution')
28
+ const { container } = window.theia;
29
+ /** @type {import ('@theia/core/lib/browser/preferences/preference-service').PreferenceService} */
30
+ const preferenceService = container.get(PreferenceService);
31
+ /** @type {import ('@theia/core/lib/browser/preferences/preference-language-override-service').PreferenceLanguageOverrideService} */
32
+ const overrideService = container.get(PreferenceLanguageOverrideService);
33
+ const fileService = container.get(FileService);
34
+ /** @type {import ('@theia/core/lib/common/uri').default} */
35
+ const uri = preferenceService.getConfigUri(PreferenceScope.Workspace);
36
+ /** @type {import('@theia/preferences/lib/browser/folders-preferences-provider').FoldersPreferencesProvider} */
37
+ const folderPreferences = container.getNamed(PreferenceProvider, PreferenceScope.Folder);
38
+ /** @type PreferenceSchemaProvider */
39
+ const schemaProvider = container.get(PreferenceSchemaProvider);
40
+ const modelService = container.get(MonacoTextModelService);
41
+
42
+ const overrideIdentifier = 'bargle-noddle-zaus'; // Probably not in our preference files...
43
+ const tabSize = 'editor.tabSize';
44
+ const fontSize = 'editor.fontSize';
45
+ const override = overrideService.markLanguageOverride(overrideIdentifier);
46
+ const overriddenTabSize = overrideService.overridePreferenceName({ overrideIdentifier, preferenceName: tabSize });
47
+ const overriddenFontSize = overrideService.overridePreferenceName({ overrideIdentifier, preferenceName: fontSize });
48
+ /**
49
+ * @returns {Promise<Record<string, any>>}
50
+ */
51
+ async function getPreferences() {
52
+ try {
53
+ const content = (await fileService.read(uri)).value;
54
+ return JSON.parse(content);
55
+ } catch (e) {
56
+ return {};
57
+ }
58
+ }
59
+
60
+ /**
61
+ * @param {string} key
62
+ * @param {unknown} value
63
+ */
64
+ async function setPreference(key, value) {
65
+ return preferenceService.set(key, value, PreferenceScope.Workspace);
66
+ }
67
+
68
+ async function deleteAllValues() {
69
+ return setValueTo(undefined);
70
+ }
71
+
72
+ /**
73
+ * @param {any} value - A JSON value to write to the workspace preference file.
74
+ */
75
+ async function setValueTo(value) {
76
+ const reference = await modelService.createModelReference(uri);
77
+ if (reference.object.dirty) {
78
+ await reference.object.revert();
79
+ }
80
+ /** @type {import ('@theia/preferences/lib/browser/folder-preference-provider').FolderPreferenceProvider} */
81
+ const provider = Array.from(folderPreferences['providers'].values()).find(candidate => candidate.getConfigUri().isEqual(uri));
82
+ assert.isDefined(provider);
83
+ await provider['doSetPreference']('', [], value);
84
+ reference.dispose();
85
+ }
86
+
87
+ let fileExistsBeforehand = false;
88
+ let contentBeforehand = '';
89
+
90
+ before(async function () {
91
+ assert.isDefined(uri, 'The workspace config URI should be defined!');
92
+ fileExistsBeforehand = await fileService.exists(uri);
93
+ contentBeforehand = await fileService.read(uri).then(({ value }) => value).catch(() => '');
94
+ schemaProvider.registerOverrideIdentifier(overrideIdentifier);
95
+ await deleteAllValues();
96
+ });
97
+
98
+ after(async function () {
99
+ if (!fileExistsBeforehand) {
100
+ await fileService.delete(uri, { fromUserGesture: false }).catch(() => { });
101
+ } else {
102
+ let content = '';
103
+ try { content = JSON.parse(contentBeforehand); } catch { }
104
+ // Use the preference service because its promise is guaranteed to resolve after the file change is complete.
105
+ await setValueTo(content);
106
+ }
107
+ });
108
+
109
+ beforeEach(async function () {
110
+ const prefs = await getPreferences();
111
+ for (const key of [tabSize, fontSize, override, overriddenTabSize, overriddenFontSize]) {
112
+ shouldBeUndefined(prefs[key], key);
113
+ }
114
+ });
115
+
116
+ afterEach(async function () {
117
+ await deleteAllValues();
118
+ });
119
+
120
+ /**
121
+ * @param {unknown} value
122
+ * @param {string} key
123
+ */
124
+ function shouldBeUndefined(value, key) {
125
+ assert.isUndefined(value, `There should be no ${key} object or value in the preferences.`);
126
+ }
127
+
128
+ /**
129
+ * @returns {Promise<{newTabSize: number, newFontSize: number, startingTabSize: number, startingFontSize: number}>}
130
+ */
131
+ async function setUpOverride() {
132
+ const startingTabSize = preferenceService.get(tabSize);
133
+ const startingFontSize = preferenceService.get(fontSize);
134
+ assert.equal(preferenceService.get(overriddenTabSize), startingTabSize, 'The overridden value should equal the default.');
135
+ assert.equal(preferenceService.get(overriddenFontSize), startingFontSize, 'The overridden value should equal the default.');
136
+ const newTabSize = startingTabSize + 2;
137
+ const newFontSize = startingFontSize + 2;
138
+ await Promise.all([
139
+ setPreference(overriddenTabSize, newTabSize),
140
+ setPreference(overriddenFontSize, newFontSize),
141
+ ]);
142
+ assert.equal(preferenceService.get(overriddenTabSize), newTabSize, 'After setting, the new value should be active for the override.');
143
+ assert.equal(preferenceService.get(overriddenFontSize), newFontSize, 'After setting, the new value should be active for the override.');
144
+ return { newTabSize, newFontSize, startingTabSize, startingFontSize };
145
+ }
146
+
147
+ it('Sets language overrides as objects', async function () {
148
+ const { newTabSize, newFontSize } = await setUpOverride();
149
+ const prefs = await getPreferences();
150
+ assert.isObject(prefs[override], 'The override should be a key in the preference object.');
151
+ assert.equal(prefs[override][tabSize], newTabSize, 'editor.tabSize should be a key in the override object and have the correct value.');
152
+ assert.equal(prefs[override][fontSize], newFontSize, 'editor.fontSize should be a key in the override object and should have the correct value.');
153
+ shouldBeUndefined(prefs[overriddenTabSize], overriddenTabSize);
154
+ shouldBeUndefined(prefs[overriddenFontSize], overriddenFontSize);
155
+ });
156
+
157
+ it('Allows deletion of individual keys in the override object.', async function () {
158
+ const { startingTabSize } = await setUpOverride();
159
+ await setPreference(overriddenTabSize, undefined);
160
+ assert.equal(preferenceService.get(overriddenTabSize), startingTabSize);
161
+ const prefs = await getPreferences();
162
+ shouldBeUndefined(prefs[override][tabSize], tabSize);
163
+ shouldBeUndefined(prefs[overriddenFontSize], overriddenFontSize);
164
+ shouldBeUndefined(prefs[overriddenTabSize], overriddenTabSize);
165
+ });
166
+
167
+ it('Allows deletion of the whole override object', async function () {
168
+ const { startingFontSize, startingTabSize } = await setUpOverride();
169
+ await setPreference(override, undefined);
170
+ assert.equal(preferenceService.get(overriddenTabSize), startingTabSize, 'The overridden value should revert to the default.');
171
+ assert.equal(preferenceService.get(overriddenFontSize), startingFontSize, 'The overridden value should revert to the default.');
172
+ const prefs = await getPreferences();
173
+ shouldBeUndefined(prefs[override], override);
174
+ });
175
+
176
+ it('Handles many synchronous settings of preferences gracefully', async function () {
177
+ let settings = 0;
178
+ const promises = [];
179
+ const searchPref = 'search.searchOnTypeDebouncePeriod'
180
+ const channelPref = 'output.maxChannelHistory'
181
+ const hoverPref = 'workbench.hover.delay';
182
+ let searchDebounce;
183
+ let channelHistory;
184
+ let hoverDelay;
185
+ /** @type import ('@theia/core/src/browser/preferences/preference-service').PreferenceChanges | undefined */
186
+ let event;
187
+ const toDispose = preferenceService.onPreferencesChanged(e => event = e);
188
+ while (settings++ < 50) {
189
+ searchDebounce = 100 + Math.floor(Math.random() * 500);
190
+ channelHistory = 200 + Math.floor(Math.random() * 800);
191
+ hoverDelay = 250 + Math.floor(Math.random() * 2_500);
192
+ promises.push(
193
+ preferenceService.set(searchPref, searchDebounce),
194
+ preferenceService.set(channelPref, channelHistory),
195
+ preferenceService.set(hoverPref, hoverDelay)
196
+ );
197
+ }
198
+ const results = await Promise.allSettled(promises);
199
+ const expectedValues = { [searchPref]: searchDebounce, [channelPref]: channelHistory, [hoverPref]: hoverDelay };
200
+ const actualValues = { [searchPref]: preferenceService.get(searchPref), [channelPref]: preferenceService.get(channelPref), [hoverPref]: preferenceService.get(hoverPref), }
201
+ const eventValues = event && Object.keys(event).reduce((accu, key) => { accu[key] = event[key].newValue; return accu; }, {});
202
+ toDispose.dispose();
203
+ assert(results.every(setting => setting.status === 'fulfilled'), 'All promises should have resolved rather than rejected.');
204
+ assert.deepEqual(actualValues, eventValues, 'The event should reflect the current state of the service.');
205
+ assert.deepEqual(expectedValues, actualValues, 'The service state should reflect the most recent setting');
206
+ });
207
+ });