aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2022-05-09 01:37:06 +0200
committerLibravatar Kristóf Marussy <kristof@marussy.com>2022-05-16 00:55:03 +0200
commita6fade92974dbba63a7d7a07f80bb447dfdf4f5b (patch)
tree8c7dfc3cc4a041412cc6be9a260acc8238b78013
parenttest: prefer jest API instead of jest-each (diff)
downloadsophie-a6fade92974dbba63a7d7a07f80bb447dfdf4f5b.tar.gz
sophie-a6fade92974dbba63a7d7a07f80bb447dfdf4f5b.tar.zst
sophie-a6fade92974dbba63a7d7a07f80bb447dfdf4f5b.zip
test: use test instead of it
Signed-off-by: Kristóf Marussy <kristof@marussy.com>
-rw-r--r--config/jest.config.base.cjs2
-rw-r--r--config/jest.config.base.js2
-rw-r--r--packages/main/src/infrastructure/electron/impl/__tests__/electron.integ.test.ts (renamed from packages/main/src/infrastructure/electron/impl/__tests__/electron.integ.spec.ts)2
-rw-r--r--packages/main/src/infrastructure/electron/impl/__tests__/hardenSession.test.ts (renamed from packages/main/src/infrastructure/electron/impl/__tests__/hardenSession.spec.ts)8
-rw-r--r--packages/main/src/infrastructure/electron/impl/__tests__/lockWebContentsToFile.test.ts (renamed from packages/main/src/infrastructure/electron/impl/__tests__/lockWebContentsToFile.spec.ts)20
-rw-r--r--packages/main/src/infrastructure/resources/impl/__tests__/getDistResources.test.ts (renamed from packages/main/src/infrastructure/resources/impl/__tests__/getDistResources.spec.ts)8
-rw-r--r--packages/main/src/reactions/__tests__/synchronizeConfig.test.ts (renamed from packages/main/src/reactions/__tests__/synchronizeConfig.spec.ts)30
-rw-r--r--packages/main/src/reactions/__tests__/synchronizeNativeTheme.test.ts (renamed from packages/main/src/reactions/__tests__/synchronizeNativeTheme.spec.ts)8
-rw-r--r--packages/main/src/stores/__tests__/SharedStore.test.ts (renamed from packages/main/src/stores/__tests__/SharedStore.spec.ts)16
-rw-r--r--packages/preload/src/contextBridge/__tests__/createSophieRenderer.test.ts (renamed from packages/preload/src/contextBridge/__tests__/createSophieRenderer.spec.ts)42
10 files changed, 69 insertions, 69 deletions
diff --git a/config/jest.config.base.cjs b/config/jest.config.base.cjs
index ee85d66..7bee8dd 100644
--- a/config/jest.config.base.cjs
+++ b/config/jest.config.base.cjs
@@ -5,7 +5,7 @@ module.exports = {
5 transform: { 5 transform: {
6 '\\.[jt]sx?$': path.join(__dirname, 'jestEsbuildCjsTransformer.cjs'), 6 '\\.[jt]sx?$': path.join(__dirname, 'jestEsbuildCjsTransformer.cjs'),
7 }, 7 },
8 testRegex: '(\\.|/)integ\\.spec\\.ts$', 8 testRegex: '(\\.|/)integ\\.test\\.ts$',
9 transformIgnorePatterns: ['/node_modules/(?!(chalk|lodash-es)/)'], 9 transformIgnorePatterns: ['/node_modules/(?!(chalk|lodash-es)/)'],
10 moduleNameMapper: { 10 moduleNameMapper: {
11 '^@sophie/(.+)$': path.join(__dirname, '../packages/$1/src/index.ts'), 11 '^@sophie/(.+)$': path.join(__dirname, '../packages/$1/src/index.ts'),
diff --git a/config/jest.config.base.js b/config/jest.config.base.js
index 32d2ecb..7524ab3 100644
--- a/config/jest.config.base.js
+++ b/config/jest.config.base.js
@@ -9,7 +9,7 @@ export default {
9 transform: { 9 transform: {
10 '\\.tsx?$': path.join(thisDir, 'jestEsbuildTransformer.js'), 10 '\\.tsx?$': path.join(thisDir, 'jestEsbuildTransformer.js'),
11 }, 11 },
12 testRegex: '((?<!integ)\\.|/)spec\\.tsx?$', 12 testRegex: '((?<!integ)\\.|/)test\\.tsx?$',
13 extensionsToTreatAsEsm: ['.ts', '.tsx'], 13 extensionsToTreatAsEsm: ['.ts', '.tsx'],
14 moduleNameMapper: { 14 moduleNameMapper: {
15 '^@sophie/(.+)$': path.join(thisDir, '../packages/$1/src/index.ts'), 15 '^@sophie/(.+)$': path.join(thisDir, '../packages/$1/src/index.ts'),
diff --git a/packages/main/src/infrastructure/electron/impl/__tests__/electron.integ.spec.ts b/packages/main/src/infrastructure/electron/impl/__tests__/electron.integ.test.ts
index f6bd440..67cf689 100644
--- a/packages/main/src/infrastructure/electron/impl/__tests__/electron.integ.spec.ts
+++ b/packages/main/src/infrastructure/electron/impl/__tests__/electron.integ.test.ts
@@ -2,7 +2,7 @@ import { BrowserWindow } from 'electron';
2 2
3import '../ElectronMainWindow'; 3import '../ElectronMainWindow';
4 4
5it('should create a BrowserWindow', async () => { 5test('create a BrowserWindow', async () => {
6 const w = new BrowserWindow(); 6 const w = new BrowserWindow();
7 await expect(w.loadURL('https://example.org')).resolves.toBeUndefined(); 7 await expect(w.loadURL('https://example.org')).resolves.toBeUndefined();
8 w.close(); 8 w.close();
diff --git a/packages/main/src/infrastructure/electron/impl/__tests__/hardenSession.spec.ts b/packages/main/src/infrastructure/electron/impl/__tests__/hardenSession.test.ts
index dc15d68..7b70d10 100644
--- a/packages/main/src/infrastructure/electron/impl/__tests__/hardenSession.spec.ts
+++ b/packages/main/src/infrastructure/electron/impl/__tests__/hardenSession.test.ts
@@ -94,14 +94,14 @@ beforeEach(() => {
94 onBeforeRequest = undefined; 94 onBeforeRequest = undefined;
95}); 95});
96 96
97it('should set permission request and before request handlers', () => { 97test('set permission request and before request handlers', () => {
98 hardenSession(getFakeResources(false), false, fakeSession); 98 hardenSession(getFakeResources(false), false, fakeSession);
99 expect(permissionRequestHandler).toBeDefined(); 99 expect(permissionRequestHandler).toBeDefined();
100 expect(onBeforeRequest).toBeDefined(); 100 expect(onBeforeRequest).toBeDefined();
101}); 101});
102 102
103it.each(permissions.map((permission) => [permission]))( 103test.each(permissions.map((permission) => [permission]))(
104 'should reject %s permission requests', 104 'reject %s permission requests',
105 (permission: Permission) => { 105 (permission: Permission) => {
106 hardenSession(getFakeResources(false), false, fakeSession); 106 hardenSession(getFakeResources(false), false, fakeSession);
107 const callback = jest.fn(); 107 const callback = jest.fn();
@@ -114,7 +114,7 @@ it.each(permissions.map((permission) => [permission]))(
114 }, 114 },
115); 115);
116 116
117it.each([ 117test.each([
118 [ 118 [
119 false, 119 false,
120 'GET', 120 'GET',
diff --git a/packages/main/src/infrastructure/electron/impl/__tests__/lockWebContentsToFile.spec.ts b/packages/main/src/infrastructure/electron/impl/__tests__/lockWebContentsToFile.test.ts
index c9aeaab..47525d3 100644
--- a/packages/main/src/infrastructure/electron/impl/__tests__/lockWebContentsToFile.spec.ts
+++ b/packages/main/src/infrastructure/electron/impl/__tests__/lockWebContentsToFile.test.ts
@@ -12,7 +12,7 @@
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Affero General Public License for more details. 13 * GNU Affero General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU Affero General Public License 15 * You have received a copy of the GNU Affero General Public License
16 * along with this program. If not, see <https://www.gnu.org/licenses/>. 16 * along with this program. If not, see <https://www.gnu.org/licenses/>.
17 * 17 *
18 * SPDX-License-Identifier: AGPL-3.0-only 18 * SPDX-License-Identifier: AGPL-3.0-only
@@ -85,16 +85,16 @@ describe('when loadURL does not throw', () => {
85 await lockWebContentsToFile(fakeResources, 'index.html', fakeWebContents); 85 await lockWebContentsToFile(fakeResources, 'index.html', fakeWebContents);
86 }); 86 });
87 87
88 it('should load the specified file', () => { 88 test('loads the specified file', () => {
89 expect(fakeWebContents.loadURL).toHaveBeenCalledWith(urlToLoad); 89 expect(fakeWebContents.loadURL).toHaveBeenCalledWith(urlToLoad);
90 }); 90 });
91 91
92 it('should set up will navigate and window open listeners', () => { 92 test('sets up will navigate and window open listeners', () => {
93 expect(willNavigate).toBeDefined(); 93 expect(willNavigate).toBeDefined();
94 expect(windowOpenHandler).toBeDefined(); 94 expect(windowOpenHandler).toBeDefined();
95 }); 95 });
96 96
97 it('should prevent opening a window', () => { 97 test('prevents opening a window', () => {
98 const { action } = windowOpenHandler!({ 98 const { action } = windowOpenHandler!({
99 url: 'https://example.com', 99 url: 'https://example.com',
100 frameName: 'newWindow', 100 frameName: 'newWindow',
@@ -108,12 +108,12 @@ describe('when loadURL does not throw', () => {
108 expect(action).toBe('deny'); 108 expect(action).toBe('deny');
109 }); 109 });
110 110
111 it('should allow navigation to the loaded URL', () => { 111 test('allows navigation to the loaded URL', () => {
112 willNavigate!(event, urlToLoad); 112 willNavigate!(event, urlToLoad);
113 expect(event.preventDefault).not.toHaveBeenCalled(); 113 expect(event.preventDefault).not.toHaveBeenCalled();
114 }); 114 });
115 115
116 it('should not allow navigation to another URL', () => { 116 test('does not allow navigation to another URL', () => {
117 willNavigate!( 117 willNavigate!(
118 event, 118 event,
119 'file:///opt/sophie/resources/app.asar/packages/renderer/not-allowed.html', 119 'file:///opt/sophie/resources/app.asar/packages/renderer/not-allowed.html',
@@ -132,7 +132,7 @@ describe('when loadURL throws', () => {
132 describe('when the URL points at a file', () => { 132 describe('when the URL points at a file', () => {
133 const fakeResources = createFakeResources('http://localhost:3000'); 133 const fakeResources = createFakeResources('http://localhost:3000');
134 134
135 it('should swallow ERR_ABORTED errors', async () => { 135 test('swallows ERR_ABORTED errors', async () => {
136 const error = createAbortedError(); 136 const error = createAbortedError();
137 mocked(fakeWebContents.loadURL).mockRejectedValueOnce(error); 137 mocked(fakeWebContents.loadURL).mockRejectedValueOnce(error);
138 await expect( 138 await expect(
@@ -140,7 +140,7 @@ describe('when loadURL throws', () => {
140 ).resolves.not.toThrow(); 140 ).resolves.not.toThrow();
141 }); 141 });
142 142
143 it('should pass through other errors', async () => { 143 test('passes through other errors', async () => {
144 mocked(fakeWebContents.loadURL).mockRejectedValueOnce( 144 mocked(fakeWebContents.loadURL).mockRejectedValueOnce(
145 new Error('other error'), 145 new Error('other error'),
146 ); 146 );
@@ -153,7 +153,7 @@ describe('when loadURL throws', () => {
153 describe('when the URL points at a local server', () => { 153 describe('when the URL points at a local server', () => {
154 const fakeResources = createFakeResources(filePrefix); 154 const fakeResources = createFakeResources(filePrefix);
155 155
156 it('should pass through ERR_ABORTED errors', async () => { 156 test('passes through ERR_ABORTED errors', async () => {
157 const error = createAbortedError(); 157 const error = createAbortedError();
158 mocked(fakeWebContents.loadURL).mockRejectedValueOnce(error); 158 mocked(fakeWebContents.loadURL).mockRejectedValueOnce(error);
159 await expect( 159 await expect(
@@ -161,7 +161,7 @@ describe('when loadURL throws', () => {
161 ).rejects.toBeInstanceOf(Error); 161 ).rejects.toBeInstanceOf(Error);
162 }); 162 });
163 163
164 it('should pass through other errors', async () => { 164 test('passes through other errors', async () => {
165 mocked(fakeWebContents.loadURL).mockRejectedValueOnce( 165 mocked(fakeWebContents.loadURL).mockRejectedValueOnce(
166 new Error('other error'), 166 new Error('other error'),
167 ); 167 );
diff --git a/packages/main/src/infrastructure/resources/impl/__tests__/getDistResources.spec.ts b/packages/main/src/infrastructure/resources/impl/__tests__/getDistResources.test.ts
index 8040601..649536b 100644
--- a/packages/main/src/infrastructure/resources/impl/__tests__/getDistResources.spec.ts
+++ b/packages/main/src/infrastructure/resources/impl/__tests__/getDistResources.test.ts
@@ -81,23 +81,23 @@ describe.each([
81 resources = getDistResources(devMode, thisDir, devServerURL); 81 resources = getDistResources(devMode, thisDir, devServerURL);
82 }); 82 });
83 83
84 it('getPath should return the path to the requested resource', () => { 84 test('getPath returns the path to the requested resource', () => {
85 const path = resources.getPath('preload', 'index.cjs'); 85 const path = resources.getPath('preload', 'index.cjs');
86 expect(path).toBe(preloadIndexPath); 86 expect(path).toBe(preloadIndexPath);
87 }); 87 });
88 88
89 it('getFileURL should return the file URL to the requested resource', () => { 89 test('getFileURL returns the file URL to the requested resource', () => {
90 const url = resources.getFileURL('preload', 'index.cjs'); 90 const url = resources.getFileURL('preload', 'index.cjs');
91 expect(url).toBe(preloadIndexFileURL); 91 expect(url).toBe(preloadIndexFileURL);
92 }); 92 });
93 93
94 describe('getRendererURL', () => { 94 describe('getRendererURL', () => {
95 it('should return the URL to the requested resource', () => { 95 test('returns the URL to the requested resource', () => {
96 const url = resources.getRendererURL('index.html'); 96 const url = resources.getRendererURL('index.html');
97 expect(url).toBe(rendererIndexURL); 97 expect(url).toBe(rendererIndexURL);
98 }); 98 });
99 99
100 it('should return the root URL', () => { 100 test('returns the root URL', () => {
101 const url = resources.getRendererURL('/'); 101 const url = resources.getRendererURL('/');
102 expect(url).toBe(rendererRootURL); 102 expect(url).toBe(rendererRootURL);
103 }); 103 });
diff --git a/packages/main/src/reactions/__tests__/synchronizeConfig.spec.ts b/packages/main/src/reactions/__tests__/synchronizeConfig.test.ts
index 403a608..f0e88c1 100644
--- a/packages/main/src/reactions/__tests__/synchronizeConfig.spec.ts
+++ b/packages/main/src/reactions/__tests__/synchronizeConfig.test.ts
@@ -51,12 +51,12 @@ describe('when synchronizeializing', () => {
51 }); 51 });
52 }); 52 });
53 53
54 it('should create a new config file', async () => { 54 test('should create a new config file', async () => {
55 await synchronizeConfig(store, repository); 55 await synchronizeConfig(store, repository);
56 expect(repository.writeConfig).toHaveBeenCalledTimes(1); 56 expect(repository.writeConfig).toHaveBeenCalledTimes(1);
57 }); 57 });
58 58
59 it('should bail if there is an an error creating the config file', async () => { 59 test('should bail if there is an an error creating the config file', async () => {
60 mocked(repository.writeConfig).mockRejectedValue(new Error('boo')); 60 mocked(repository.writeConfig).mockRejectedValue(new Error('boo'));
61 await expect(() => 61 await expect(() =>
62 synchronizeConfig(store, repository), 62 synchronizeConfig(store, repository),
@@ -76,13 +76,13 @@ describe('when synchronizeializing', () => {
76 }); 76 });
77 }); 77 });
78 78
79 it('should read the existing config file is there is one', async () => { 79 test('should read the existing config file is there is one', async () => {
80 await synchronizeConfig(store, repository); 80 await synchronizeConfig(store, repository);
81 expect(repository.writeConfig).not.toHaveBeenCalled(); 81 expect(repository.writeConfig).not.toHaveBeenCalled();
82 expect(store.settings.themeSource).toBe('dark'); 82 expect(store.settings.themeSource).toBe('dark');
83 }); 83 });
84 84
85 it('should bail if it cannot set up a watcher', async () => { 85 test('should bail if it cannot set up a watcher', async () => {
86 mocked(repository.watchConfig).mockImplementationOnce(() => { 86 mocked(repository.watchConfig).mockImplementationOnce(() => {
87 throw new Error('boo'); 87 throw new Error('boo');
88 }); 88 });
@@ -92,7 +92,7 @@ describe('when synchronizeializing', () => {
92 }); 92 });
93 }); 93 });
94 94
95 it('should update the config file if new details are added during read', async () => { 95 test('should update the config file if new details are added during read', async () => {
96 mocked(repository.readConfig).mockResolvedValueOnce({ 96 mocked(repository.readConfig).mockResolvedValueOnce({
97 found: true, 97 found: true,
98 contents: `{ 98 contents: `{
@@ -109,7 +109,7 @@ describe('when synchronizeializing', () => {
109 expect(repository.writeConfig).toHaveBeenCalledTimes(1); 109 expect(repository.writeConfig).toHaveBeenCalledTimes(1);
110 }); 110 });
111 111
112 it('should not apply an invalid config file but should not overwrite it', async () => { 112 test('should not apply an invalid config file but should not overwrite it', async () => {
113 mocked(repository.readConfig).mockResolvedValueOnce({ 113 mocked(repository.readConfig).mockResolvedValueOnce({
114 found: true, 114 found: true,
115 contents: `{ 115 contents: `{
@@ -122,7 +122,7 @@ describe('when synchronizeializing', () => {
122 expect(repository.writeConfig).not.toHaveBeenCalled(); 122 expect(repository.writeConfig).not.toHaveBeenCalled();
123 }); 123 });
124 124
125 it('should bail if it cannot determine whether there is a config file', async () => { 125 test('should bail if it cannot determine whether there is a config file', async () => {
126 mocked(repository.readConfig).mockRejectedValue(new Error('boo')); 126 mocked(repository.readConfig).mockRejectedValue(new Error('boo'));
127 await expect(() => 127 await expect(() =>
128 synchronizeConfig(store, repository), 128 synchronizeConfig(store, repository),
@@ -146,7 +146,7 @@ describe('when it has loaded the config', () => {
146 jest.resetAllMocks(); 146 jest.resetAllMocks();
147 }); 147 });
148 148
149 it('should throttle saving changes to the config file', () => { 149 test('should throttle saving changes to the config file', () => {
150 mocked(repository.writeConfig).mockResolvedValue(); 150 mocked(repository.writeConfig).mockResolvedValue();
151 store.settings.setThemeSource('dark'); 151 store.settings.setThemeSource('dark');
152 jest.advanceTimersByTime(lessThanThrottleMs); 152 jest.advanceTimersByTime(lessThanThrottleMs);
@@ -155,14 +155,14 @@ describe('when it has loaded the config', () => {
155 expect(repository.writeConfig).toHaveBeenCalledTimes(1); 155 expect(repository.writeConfig).toHaveBeenCalledTimes(1);
156 }); 156 });
157 157
158 it('should handle config writing errors gracefully', () => { 158 test('should handle config writing errors gracefully', () => {
159 mocked(repository.writeConfig).mockRejectedValue(new Error('boo')); 159 mocked(repository.writeConfig).mockRejectedValue(new Error('boo'));
160 store.settings.setThemeSource('dark'); 160 store.settings.setThemeSource('dark');
161 jest.advanceTimersByTime(throttleMs); 161 jest.advanceTimersByTime(throttleMs);
162 expect(repository.writeConfig).toHaveBeenCalledTimes(1); 162 expect(repository.writeConfig).toHaveBeenCalledTimes(1);
163 }); 163 });
164 164
165 it('should read the config file when it has changed', async () => { 165 test('should read the config file when it has changed', async () => {
166 mocked(repository.readConfig).mockResolvedValueOnce({ 166 mocked(repository.readConfig).mockResolvedValueOnce({
167 found: true, 167 found: true,
168 contents: serializeConfig({ 168 contents: serializeConfig({
@@ -177,7 +177,7 @@ describe('when it has loaded the config', () => {
177 expect(store.settings.themeSource).toBe('dark'); 177 expect(store.settings.themeSource).toBe('dark');
178 }); 178 });
179 179
180 it('should update the config file if new details are added', async () => { 180 test('should update the config file if new details are added', async () => {
181 mocked(repository.readConfig).mockResolvedValueOnce({ 181 mocked(repository.readConfig).mockResolvedValueOnce({
182 found: true, 182 found: true,
183 contents: `{ 183 contents: `{
@@ -194,7 +194,7 @@ describe('when it has loaded the config', () => {
194 expect(repository.writeConfig).toHaveBeenCalledTimes(1); 194 expect(repository.writeConfig).toHaveBeenCalledTimes(1);
195 }); 195 });
196 196
197 it('should not apply an invalid config file when it has changed but should not overwrite it', async () => { 197 test('should not apply an invalid config file when it has changed but should not overwrite it', async () => {
198 mocked(repository.readConfig).mockResolvedValueOnce({ 198 mocked(repository.readConfig).mockResolvedValueOnce({
199 found: true, 199 found: true,
200 contents: `{ 200 contents: `{
@@ -207,7 +207,7 @@ describe('when it has loaded the config', () => {
207 expect(repository.writeConfig).not.toHaveBeenCalled(); 207 expect(repository.writeConfig).not.toHaveBeenCalled();
208 }); 208 });
209 209
210 it('should handle config reading errors gracefully', async () => { 210 test('should handle config reading errors gracefully', async () => {
211 mocked(repository.readConfig).mockRejectedValue(new Error('boo')); 211 mocked(repository.readConfig).mockRejectedValue(new Error('boo'));
212 await expect(configChangedCallback()).resolves.not.toThrow(); 212 await expect(configChangedCallback()).resolves.not.toThrow();
213 }); 213 });
@@ -217,11 +217,11 @@ describe('when it has loaded the config', () => {
217 sutDisposer(); 217 sutDisposer();
218 }); 218 });
219 219
220 it('should dispose the watcher', () => { 220 test('should dispose the watcher', () => {
221 expect(watcherDisposer).toHaveBeenCalled(); 221 expect(watcherDisposer).toHaveBeenCalled();
222 }); 222 });
223 223
224 it('should not listen to store changes any more', () => { 224 test('should not listen to store changes any more', () => {
225 store.settings.setThemeSource('dark'); 225 store.settings.setThemeSource('dark');
226 jest.advanceTimersByTime(2 * throttleMs); 226 jest.advanceTimersByTime(2 * throttleMs);
227 expect(repository.writeConfig).not.toHaveBeenCalled(); 227 expect(repository.writeConfig).not.toHaveBeenCalled();
diff --git a/packages/main/src/reactions/__tests__/synchronizeNativeTheme.spec.ts b/packages/main/src/reactions/__tests__/synchronizeNativeTheme.test.ts
index cf37568..05f14fb 100644
--- a/packages/main/src/reactions/__tests__/synchronizeNativeTheme.spec.ts
+++ b/packages/main/src/reactions/__tests__/synchronizeNativeTheme.test.ts
@@ -50,16 +50,16 @@ beforeEach(() => {
50 disposeSut = synchronizeNativeTheme(store); 50 disposeSut = synchronizeNativeTheme(store);
51}); 51});
52 52
53it('should register a nativeTheme updated listener', () => { 53test('should register a nativeTheme updated listener', () => {
54 expect(nativeTheme.on).toHaveBeenCalledWith('updated', expect.anything()); 54 expect(nativeTheme.on).toHaveBeenCalledWith('updated', expect.anything());
55}); 55});
56 56
57it('should synchronize themeSource changes to the nativeTheme', () => { 57test('should synchronize themeSource changes to the nativeTheme', () => {
58 store.settings.setThemeSource('dark'); 58 store.settings.setThemeSource('dark');
59 expect(nativeTheme.themeSource).toBe('dark'); 59 expect(nativeTheme.themeSource).toBe('dark');
60}); 60});
61 61
62it('should synchronize shouldUseDarkColors changes to the store', () => { 62test('should synchronize shouldUseDarkColors changes to the store', () => {
63 const listener = mocked(nativeTheme.on).mock.calls.find( 63 const listener = mocked(nativeTheme.on).mock.calls.find(
64 ([event]) => event === 'updated', 64 ([event]) => event === 'updated',
65 )![1]; 65 )![1];
@@ -68,7 +68,7 @@ it('should synchronize shouldUseDarkColors changes to the store', () => {
68 expect(store.shouldUseDarkColors).toBe(true); 68 expect(store.shouldUseDarkColors).toBe(true);
69}); 69});
70 70
71it('should remove the listener on dispose', () => { 71test('should remove the listener on dispose', () => {
72 const listener = mocked(nativeTheme.on).mock.calls.find( 72 const listener = mocked(nativeTheme.on).mock.calls.find(
73 ([event]) => event === 'updated', 73 ([event]) => event === 'updated',
74 )![1]; 74 )![1];
diff --git a/packages/main/src/stores/__tests__/SharedStore.spec.ts b/packages/main/src/stores/__tests__/SharedStore.test.ts
index 268ce3f..0ed63e3 100644
--- a/packages/main/src/stores/__tests__/SharedStore.spec.ts
+++ b/packages/main/src/stores/__tests__/SharedStore.test.ts
@@ -39,7 +39,7 @@ beforeEach(() => {
39}); 39});
40 40
41describe('loadConfig', () => { 41describe('loadConfig', () => {
42 it('should load profiles with an ID', () => { 42 test('loads profiles with an ID', () => {
43 sut.loadConfig({ 43 sut.loadConfig({
44 profiles: [ 44 profiles: [
45 { 45 {
@@ -51,14 +51,14 @@ describe('loadConfig', () => {
51 expect(sut.profiles[0].id).toBe('someId'); 51 expect(sut.profiles[0].id).toBe('someId');
52 }); 52 });
53 53
54 it('should generate an ID for profiles without and ID', () => { 54 test('generates an ID for profiles without and ID', () => {
55 sut.loadConfig({ 55 sut.loadConfig({
56 profiles: [profileProps], 56 profiles: [profileProps],
57 }); 57 });
58 expect(sut.profiles[0].id).toBeDefined(); 58 expect(sut.profiles[0].id).toBeDefined();
59 }); 59 });
60 60
61 it('should load services with an ID and a profile', () => { 61 test('loads services with an ID and a profile', () => {
62 sut.loadConfig({ 62 sut.loadConfig({
63 profiles: [ 63 profiles: [
64 { 64 {
@@ -78,7 +78,7 @@ describe('loadConfig', () => {
78 expect(sut.services[0].settings.profile).toBe(sut.profiles[0]); 78 expect(sut.services[0].settings.profile).toBe(sut.profiles[0]);
79 }); 79 });
80 80
81 it('should refuse to load a profile without a name', () => { 81 test('refuses to load a profile without a name', () => {
82 expect(() => { 82 expect(() => {
83 sut.loadConfig({ 83 sut.loadConfig({
84 profiles: [ 84 profiles: [
@@ -93,7 +93,7 @@ describe('loadConfig', () => {
93 expect(sut.profiles).toHaveLength(0); 93 expect(sut.profiles).toHaveLength(0);
94 }); 94 });
95 95
96 it('should load services without an ID but with a profile', () => { 96 test('loads services without an ID but with a profile', () => {
97 sut.loadConfig({ 97 sut.loadConfig({
98 profiles: [ 98 profiles: [
99 { 99 {
@@ -112,7 +112,7 @@ describe('loadConfig', () => {
112 expect(sut.services[0].settings.profile).toBe(sut.profiles[0]); 112 expect(sut.services[0].settings.profile).toBe(sut.profiles[0]);
113 }); 113 });
114 114
115 it('should create a profile for a service with an ID but no profile', () => { 115 test('creates a profile for a service with an ID but no profile', () => {
116 sut.loadConfig({ 116 sut.loadConfig({
117 services: [ 117 services: [
118 { 118 {
@@ -128,7 +128,7 @@ describe('loadConfig', () => {
128 ); 128 );
129 }); 129 });
130 130
131 it('should create a profile for a service without an ID or profile', () => { 131 test('creates a profile for a service without an ID or profile', () => {
132 sut.loadConfig({ 132 sut.loadConfig({
133 services: [ 133 services: [
134 { 134 {
@@ -143,7 +143,7 @@ describe('loadConfig', () => {
143 ); 143 );
144 }); 144 });
145 145
146 it('should refuse to load a service without a name', () => { 146 test('refuses to load a service without a name', () => {
147 expect(() => { 147 expect(() => {
148 sut.loadConfig({ 148 sut.loadConfig({
149 services: [ 149 services: [
diff --git a/packages/preload/src/contextBridge/__tests__/createSophieRenderer.spec.ts b/packages/preload/src/contextBridge/__tests__/createSophieRenderer.test.ts
index 4411789..21620ed 100644
--- a/packages/preload/src/contextBridge/__tests__/createSophieRenderer.spec.ts
+++ b/packages/preload/src/contextBridge/__tests__/createSophieRenderer.test.ts
@@ -73,7 +73,7 @@ beforeAll(() => {
73}); 73});
74 74
75describe('createSophieRenderer', () => { 75describe('createSophieRenderer', () => {
76 it('registers a shared store patch listener', () => { 76 test('registers a shared store patch listener', () => {
77 createSophieRenderer(false); 77 createSophieRenderer(false);
78 expect(ipcRenderer.on).toHaveBeenCalledWith( 78 expect(ipcRenderer.on).toHaveBeenCalledWith(
79 MainToRendererIpcMessage.SharedStorePatch, 79 MainToRendererIpcMessage.SharedStorePatch,
@@ -103,7 +103,7 @@ describe('SharedStoreConnector', () => {
103 }); 103 });
104 104
105 describe('onSharedStoreChange', () => { 105 describe('onSharedStoreChange', () => {
106 it('should request a snapshot from the main process', async () => { 106 test('requests a snapshot from the main process', async () => {
107 mocked(ipcRenderer.invoke).mockResolvedValueOnce(snapshot); 107 mocked(ipcRenderer.invoke).mockResolvedValueOnce(snapshot);
108 await sut.onSharedStoreChange(listener); 108 await sut.onSharedStoreChange(listener);
109 expect(ipcRenderer.invoke).toHaveBeenCalledWith( 109 expect(ipcRenderer.invoke).toHaveBeenCalledWith(
@@ -112,7 +112,7 @@ describe('SharedStoreConnector', () => {
112 expect(listener.onSnapshot).toHaveBeenCalledWith(snapshot); 112 expect(listener.onSnapshot).toHaveBeenCalledWith(snapshot);
113 }); 113 });
114 114
115 it('should catch IPC errors without exposing them', async () => { 115 test('catches IPC errors without exposing them', async () => {
116 mocked(ipcRenderer.invoke).mockRejectedValue(new Error('s3cr3t')); 116 mocked(ipcRenderer.invoke).mockRejectedValue(new Error('s3cr3t'));
117 await expect( 117 await expect(
118 sut.onSharedStoreChange(listener), 118 sut.onSharedStoreChange(listener),
@@ -122,7 +122,7 @@ describe('SharedStoreConnector', () => {
122 }); 122 });
123 123
124 describe('dispatchAction', () => { 124 describe('dispatchAction', () => {
125 it('should dispatch valid actions', () => { 125 test('dispatches valid actions', () => {
126 sut.dispatchAction(action); 126 sut.dispatchAction(action);
127 expect(ipcRenderer.send).toHaveBeenCalledWith( 127 expect(ipcRenderer.send).toHaveBeenCalledWith(
128 RendererToMainIpcMessage.DispatchAction, 128 RendererToMainIpcMessage.DispatchAction,
@@ -130,31 +130,31 @@ describe('SharedStoreConnector', () => {
130 ); 130 );
131 }); 131 });
132 132
133 it('should not dispatch invalid actions', () => { 133 test('does not dispatch invalid actions', () => {
134 expect(() => sut.dispatchAction(invalidAction)).toThrow(); 134 expect(() => sut.dispatchAction(invalidAction)).toThrow();
135 expect(ipcRenderer.send).not.toHaveBeenCalled(); 135 expect(ipcRenderer.send).not.toHaveBeenCalled();
136 }); 136 });
137 }); 137 });
138 138
139 describe('when no listener is registered', () => { 139 describe('when no listener is registered', () => {
140 it('should discard the received patch without any error', () => { 140 test('discards the received patch without any error', () => {
141 expect(() => onSharedStorePatch(event, patch)).not.toThrow(); 141 expect(() => onSharedStorePatch(event, patch)).not.toThrow();
142 }); 142 });
143 }); 143 });
144 144
145 function itRefusesToRegisterAnotherListener(): void { 145 function testRefusesToRegisterAnotherListener(): void {
146 it('should refuse to register another listener', async () => { 146 test('refuses to register another listener', async () => {
147 await expect(sut.onSharedStoreChange(listener)).rejects.toBeInstanceOf( 147 await expect(sut.onSharedStoreChange(listener)).rejects.toBeInstanceOf(
148 Error, 148 Error,
149 ); 149 );
150 }); 150 });
151 } 151 }
152 152
153 function itDoesNotPassPatchesToTheListener( 153 function testDoesNotPassPatchesToTheListener(
154 name = 'should not pass patches to the listener', 154 name = 'does not pass patches to the listener',
155 ): void { 155 ): void {
156 // eslint-disable-next-line jest/valid-title -- Title is a string parameter. 156 // eslint-disable-next-line jest/valid-title -- Title is a string parameter.
157 it(name, () => { 157 test(name, () => {
158 onSharedStorePatch(event, patch); 158 onSharedStorePatch(event, patch);
159 expect(listener.onPatch).not.toHaveBeenCalled(); 159 expect(listener.onPatch).not.toHaveBeenCalled();
160 }); 160 });
@@ -166,19 +166,19 @@ describe('SharedStoreConnector', () => {
166 await sut.onSharedStoreChange(listener); 166 await sut.onSharedStoreChange(listener);
167 }); 167 });
168 168
169 it('should pass patches to the listener', () => { 169 test('passes patches to the listener', () => {
170 onSharedStorePatch(event, patch); 170 onSharedStorePatch(event, patch);
171 expect(listener.onPatch).toHaveBeenCalledWith(patch); 171 expect(listener.onPatch).toHaveBeenCalledWith(patch);
172 }); 172 });
173 173
174 it('should catch listener errors', () => { 174 test('catches listener errors', () => {
175 mocked(listener.onPatch).mockImplementation(() => { 175 mocked(listener.onPatch).mockImplementation(() => {
176 throw new Error('listener error'); 176 throw new Error('listener error');
177 }); 177 });
178 expect(() => onSharedStorePatch(event, patch)).not.toThrow(); 178 expect(() => onSharedStorePatch(event, patch)).not.toThrow();
179 }); 179 });
180 180
181 itRefusesToRegisterAnotherListener(); 181 testRefusesToRegisterAnotherListener();
182 182
183 describe('after the listener threw in onPatch', () => { 183 describe('after the listener threw in onPatch', () => {
184 beforeEach(() => { 184 beforeEach(() => {
@@ -189,7 +189,7 @@ describe('SharedStoreConnector', () => {
189 listener.onPatch.mockRestore(); 189 listener.onPatch.mockRestore();
190 }); 190 });
191 191
192 itDoesNotPassPatchesToTheListener('should not pass on patches any more'); 192 testDoesNotPassPatchesToTheListener('does not pass on patches any more');
193 }); 193 });
194 }); 194 });
195 195
@@ -205,9 +205,9 @@ describe('SharedStoreConnector', () => {
205 } 205 }
206 }); 206 });
207 207
208 itRefusesToRegisterAnotherListener(); 208 testRefusesToRegisterAnotherListener();
209 209
210 itDoesNotPassPatchesToTheListener(); 210 testDoesNotPassPatchesToTheListener();
211 }); 211 });
212 212
213 describe('when a listener failed to register due to listener error', () => { 213 describe('when a listener failed to register due to listener error', () => {
@@ -223,9 +223,9 @@ describe('SharedStoreConnector', () => {
223 } 223 }
224 }); 224 });
225 225
226 itRefusesToRegisterAnotherListener(); 226 testRefusesToRegisterAnotherListener();
227 227
228 itDoesNotPassPatchesToTheListener(); 228 testDoesNotPassPatchesToTheListener();
229 }); 229 });
230 230
231 describe('when it is allowed to replace listeners', () => { 231 describe('when it is allowed to replace listeners', () => {
@@ -239,7 +239,7 @@ describe('SharedStoreConnector', () => {
239 onPatch: jest.fn((_patch: IJsonPatch[]) => {}), 239 onPatch: jest.fn((_patch: IJsonPatch[]) => {}),
240 }; 240 };
241 241
242 it('should fetch a second snapshot', async () => { 242 test('fetches a second snapshot', async () => {
243 mocked(ipcRenderer.invoke).mockResolvedValueOnce(snapshot2); 243 mocked(ipcRenderer.invoke).mockResolvedValueOnce(snapshot2);
244 await sut.onSharedStoreChange(listener2); 244 await sut.onSharedStoreChange(listener2);
245 expect(ipcRenderer.invoke).toHaveBeenCalledWith( 245 expect(ipcRenderer.invoke).toHaveBeenCalledWith(
@@ -248,7 +248,7 @@ describe('SharedStoreConnector', () => {
248 expect(listener2.onSnapshot).toHaveBeenCalledWith(snapshot2); 248 expect(listener2.onSnapshot).toHaveBeenCalledWith(snapshot2);
249 }); 249 });
250 250
251 it('should pass the second snapshot to the new listener', async () => { 251 test('passes the second snapshot to the new listener', async () => {
252 mocked(ipcRenderer.invoke).mockResolvedValueOnce(snapshot2); 252 mocked(ipcRenderer.invoke).mockResolvedValueOnce(snapshot2);
253 await sut.onSharedStoreChange(listener2); 253 await sut.onSharedStoreChange(listener2);
254 onSharedStorePatch(event, patch); 254 onSharedStorePatch(event, patch);