Skip to content

Commit 57938d0

Browse files
alexeyr-ci2alexeyr
andauthored
Enable Jest ESLint plugin with recommended config (#1728)
* Enable Jest ESLint plugin with recommended config * Remove expect.assertions * Fix CI --------- Co-authored-by: Alexey Romanov <[email protected]>
1 parent 1d52482 commit 57938d0

12 files changed

+94
-146
lines changed

eslint.config.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import path from 'node:path';
22
import { globalIgnores } from 'eslint/config';
3+
import jest from 'eslint-plugin-jest';
34
import prettierRecommended from 'eslint-plugin-prettier/recommended';
45
import globals from 'globals';
56
import tsEslint from 'typescript-eslint';
@@ -52,10 +53,6 @@ const config = tsEslint.config([
5253
globals: {
5354
...globals.browser,
5455
...globals.node,
55-
...globals.mocha,
56-
...globals.jest,
57-
__DEBUG_SERVER_ERRORS__: true,
58-
__SERVER_ERRORS__: true,
5956
},
6057

6158
parserOptions: {
@@ -190,6 +187,16 @@ const config = tsEslint.config([
190187
'react/no-deprecated': 'off',
191188
},
192189
},
190+
{
191+
files: ['node_package/tests/**', '**/*.test.{js,jsx,ts,tsx}'],
192+
193+
extends: [jest.configs['flat/recommended'], jest.configs['flat/style']],
194+
195+
rules: {
196+
// Allows Jest mocks before import
197+
'import/first': 'off',
198+
},
199+
},
193200
// must be the last config in the array
194201
// https://github.com/prettier/eslint-plugin-prettier?tab=readme-ov-file#configuration-new-eslintconfigjs
195202
prettierRecommended,

node_package/tests/Authenticity.test.js

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,28 +8,22 @@ meta.content = testToken;
88
document.head.appendChild(meta);
99

1010
describe('authenticityToken', () => {
11-
expect.assertions(2);
1211
it('exists in ReactOnRails API', () => {
13-
expect.assertions(1);
14-
expect(typeof ReactOnRails.authenticityToken).toEqual('function');
12+
expect(typeof ReactOnRails.authenticityToken).toBe('function');
1513
});
1614

1715
it('can read Rails CSRF token from <meta>', () => {
18-
expect.assertions(1);
1916
const realToken = ReactOnRails.authenticityToken();
2017
expect(realToken).toEqual(testToken);
2118
});
2219
});
2320

2421
describe('authenticityHeaders', () => {
25-
expect.assertions(2);
2622
it('exists in ReactOnRails API', () => {
27-
expect.assertions(1);
28-
expect(typeof ReactOnRails.authenticityHeaders).toEqual('function');
23+
expect(typeof ReactOnRails.authenticityHeaders).toBe('function');
2924
});
3025

3126
it('returns valid header with CSRF token', () => {
32-
expect.assertions(1);
3327
const realHeader = ReactOnRails.authenticityHeaders();
3428
expect(realHeader).toEqual({ 'X-CSRF-Token': testToken, 'X-Requested-With': 'XMLHttpRequest' });
3529
});

node_package/tests/ComponentRegistry.test.js

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ describe('ComponentRegistry', () => {
3737
});
3838

3939
it('registers and retrieves React function components', () => {
40-
expect.assertions(1);
4140
const C1 = () => <div>HELLO</div>;
4241
ComponentRegistry.register({ C1 });
4342
const actual = ComponentRegistry.get('C1');
@@ -46,7 +45,6 @@ describe('ComponentRegistry', () => {
4645
});
4746

4847
it('registers and retrieves Render-Function components where property renderFunction is set and zero params', () => {
49-
expect.assertions(1);
5048
const C1 = () => <div>HELLO</div>;
5149
C1.renderFunction = true;
5250
ComponentRegistry.register({ C1 });
@@ -56,7 +54,6 @@ describe('ComponentRegistry', () => {
5654
});
5755

5856
it('registers and retrieves ES5 class components', () => {
59-
expect.assertions(1);
6057
const C2 = createReactClass({
6158
render() {
6259
return <div> WORLD </div>;
@@ -69,7 +66,6 @@ describe('ComponentRegistry', () => {
6966
});
7067

7168
it('registers and retrieves ES6 class components', () => {
72-
expect.assertions(1);
7369
class C3 extends React.Component {
7470
render() {
7571
return <div>Wow!</div>;
@@ -82,7 +78,6 @@ describe('ComponentRegistry', () => {
8278
});
8379

8480
it('registers and retrieves renderers if 3 params', () => {
85-
expect.assertions(1);
8681
const C4 = (a1, a2, a3) => null;
8782
ComponentRegistry.register({ C4 });
8883
const actual = ComponentRegistry.get('C4');
@@ -95,7 +90,6 @@ describe('ComponentRegistry', () => {
9590
* Thus, tests are cumulative.
9691
*/
9792
it('registers and retrieves multiple components', () => {
98-
expect.assertions(4);
9993
// Plain react stateless functional components
10094
const C5 = () => <div>WHY</div>;
10195
const C6 = () => <div>NOW</div>;
@@ -127,7 +121,6 @@ describe('ComponentRegistry', () => {
127121
});
128122

129123
it('only detects a renderer function if it has three arguments', () => {
130-
expect.assertions(2);
131124
const C7 = (a1, a2) => null;
132125
const C8 = (a1) => null;
133126
ComponentRegistry.register({ C7 });
@@ -148,20 +141,17 @@ describe('ComponentRegistry', () => {
148141
});
149142

150143
it('throws error for retrieving unregistered component', () => {
151-
expect.assertions(1);
152144
expect(() => ComponentRegistry.get('foobar')).toThrow(
153145
/Could not find component registered with name foobar/,
154146
);
155147
});
156148

157149
it('throws error for setting null component', () => {
158-
expect.assertions(1);
159150
const C9 = null;
160151
expect(() => ComponentRegistry.register({ C9 })).toThrow(/Called register with null component named C9/);
161152
});
162153

163154
it('retrieves component asynchronously when registered later', async () => {
164-
expect.assertions(1);
165155
const C1 = () => <div>HELLO</div>;
166156
const componentPromise = ComponentRegistry.getOrWaitForComponent('C1');
167157
ComponentRegistry.register({ C1 });
@@ -175,11 +165,12 @@ describe('ComponentRegistry', () => {
175165
});
176166

177167
it('handles timeout for unregistered components', async () => {
178-
expect.assertions(1);
168+
let error;
179169
try {
180170
await ComponentRegistry.getOrWaitForComponent('NonExistent');
181-
} catch (error) {
182-
expect(error.message).toMatch(/Could not find component/);
171+
} catch (e) {
172+
error = e;
183173
}
174+
expect(error.message).toMatch(/Could not find component/);
184175
});
185176
});

node_package/tests/ReactOnRails.test.jsx

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,7 @@ import * as createReactClass from 'create-react-class';
77
import ReactOnRails from '../src/ReactOnRails.client.ts';
88

99
describe('ReactOnRails', () => {
10-
expect.assertions(14);
1110
it('render returns a virtual DOM element for component', () => {
12-
expect.assertions(1);
1311
const R1 = createReactClass({
1412
render() {
1513
return <div> WORLD </div>;
@@ -25,42 +23,36 @@ describe('ReactOnRails', () => {
2523
document.body.appendChild(root);
2624
ReactOnRails.render('R1', {}, 'root');
2725

28-
expect(document.getElementById('root').textContent).toEqual(' WORLD ');
26+
expect(document.getElementById('root').textContent).toBe(' WORLD ');
2927
});
3028

3129
it('accepts traceTurbolinks as an option true', () => {
3230
ReactOnRails.resetOptions();
33-
expect.assertions(1);
3431
ReactOnRails.setOptions({ traceTurbolinks: true });
3532
const actual = ReactOnRails.option('traceTurbolinks');
3633
expect(actual).toBe(true);
3734
});
3835

3936
it('accepts traceTurbolinks as an option false', () => {
4037
ReactOnRails.resetOptions();
41-
expect.assertions(1);
4238
ReactOnRails.setOptions({ traceTurbolinks: false });
4339
const actual = ReactOnRails.option('traceTurbolinks');
4440
expect(actual).toBe(false);
4541
});
4642

4743
it('not specified has traceTurbolinks as false', () => {
4844
ReactOnRails.resetOptions();
49-
expect.assertions(1);
5045
ReactOnRails.setOptions({});
5146
const actual = ReactOnRails.option('traceTurbolinks');
5247
expect(actual).toBe(false);
5348
});
5449

5550
it('setOptions method throws error for invalid options', () => {
5651
ReactOnRails.resetOptions();
57-
expect.assertions(1);
5852
expect(() => ReactOnRails.setOptions({ foobar: true })).toThrow(/Invalid option/);
5953
});
6054

6155
it('registerStore throws if passed a falsey object (null, undefined, etc)', () => {
62-
expect.assertions(3);
63-
6456
expect(() => ReactOnRails.registerStore(null)).toThrow(/null or undefined/);
6557

6658
expect(() => ReactOnRails.registerStore(undefined)).toThrow(/null or undefined/);
@@ -69,7 +61,6 @@ describe('ReactOnRails', () => {
6961
});
7062

7163
it('register store and getStoreGenerator allow registration', () => {
72-
expect.assertions(2);
7364
function reducer() {
7465
return {};
7566
}
@@ -87,7 +78,6 @@ describe('ReactOnRails', () => {
8778
});
8879

8980
it('setStore and getStore', () => {
90-
expect.assertions(2);
9181
function reducer() {
9282
return {};
9383
}
@@ -109,7 +99,6 @@ describe('ReactOnRails', () => {
10999
});
110100

111101
it('clearHydratedStores', () => {
112-
expect.assertions(2);
113102
function reducer() {
114103
return {};
115104
}

node_package/tests/StoreRegistry.test.js

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,12 @@ function storeGenerator2(props) {
1414
return createStore(reducer, props);
1515
}
1616

17-
describe('', () => {
18-
expect.assertions(11);
19-
it('StoreRegistry throws error for registering null or undefined store', () => {
20-
expect.assertions(2);
17+
describe('StoreRegistry', () => {
18+
beforeEach(() => {
2119
StoreRegistry.stores().clear();
20+
});
21+
22+
it('StoreRegistry throws error for registering null or undefined store', () => {
2223
expect(() => StoreRegistry.register({ storeGenerator: null })).toThrow(
2324
/Called ReactOnRails.registerStoreGenerators with a null or undefined as a value/,
2425
);
@@ -28,15 +29,12 @@ describe('', () => {
2829
});
2930

3031
it('StoreRegistry throws error for retrieving unregistered store', () => {
31-
expect.assertions(1);
32-
StoreRegistry.stores().clear();
3332
expect(() => StoreRegistry.getStore('foobar')).toThrow(
3433
/There are no stores hydrated and you are requesting the store/,
3534
);
3635
});
3736

3837
it('StoreRegistry registers and retrieves Render-Function stores', () => {
39-
expect.assertions(2);
4038
StoreRegistry.register({ storeGenerator, storeGenerator2 });
4139
const actual = StoreRegistry.getStoreGenerator('storeGenerator');
4240
const expected = storeGenerator;
@@ -46,23 +44,20 @@ describe('', () => {
4644
expect(actual2).toEqual(expected2);
4745
});
4846

49-
it('StoreRegistry throws error for retrieving unregistered store', () => {
50-
expect.assertions(1);
47+
it('StoreRegistry throws error for retrieving unregistered store generator', () => {
5148
expect(() => StoreRegistry.getStoreGenerator('foobar')).toThrow(
5249
/Could not find store generator registered with name foobar\. Registered store generator names include/,
5350
);
5451
});
5552

5653
it('StoreRegistry returns undefined for retrieving unregistered store, passing throwIfMissing = false', () => {
57-
expect.assertions(1);
5854
StoreRegistry.setStore('foobarX', {});
5955
const actual = StoreRegistry.getStore('foobar', false);
6056
const expected = undefined;
6157
expect(actual).toEqual(expected);
6258
});
6359

6460
it('StoreRegistry getStore, setStore', () => {
65-
expect.assertions(1);
6661
const store = storeGenerator({});
6762
StoreRegistry.setStore('storeGenerator', store);
6863
const actual = StoreRegistry.getStore('storeGenerator');
@@ -71,14 +66,12 @@ describe('', () => {
7166
});
7267

7368
it('StoreRegistry throws error for retrieving unregistered hydrated store', () => {
74-
expect.assertions(1);
7569
expect(() => StoreRegistry.getStore('foobar')).toThrow(
7670
/Could not find hydrated store registered with name foobar\. Registered hydrated store names include/,
7771
);
7872
});
7973

8074
it('StoreRegistry clearHydratedStores', () => {
81-
expect.assertions(2);
8275
StoreRegistry.clearHydratedStores();
8376

8477
const result = storeGenerator({});

node_package/tests/buildConsoleReplay.test.js

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,24 @@
11
import buildConsoleReplay, { consoleReplay } from '../src/buildConsoleReplay.ts';
22

33
describe('consoleReplay', () => {
4-
expect.assertions(8);
54
it('does not throw an exception if no console.history object', () => {
6-
expect.assertions(1);
75
expect(() => consoleReplay()).not.toThrow(/Error/);
86
});
97

108
it('returns empty string if no console.history object', () => {
11-
expect.assertions(1);
129
const actual = consoleReplay();
1310
const expected = '';
1411
expect(actual).toEqual(expected);
1512
});
1613

17-
it('does not throw an exception if console.history.length is zero', () => {
18-
expect.assertions(1);
19-
console.history = [];
20-
expect(() => consoleReplay()).not.toThrow(/Error/);
21-
});
22-
23-
it('returns empty string if no console.history object', () => {
24-
expect.assertions(1);
14+
it('returns empty string if console.history is empty', () => {
2515
console.history = [];
2616
const actual = consoleReplay();
2717
const expected = '';
2818
expect(actual).toEqual(expected);
2919
});
3020

3121
it('replays multiple history messages', () => {
32-
expect.assertions(1);
3322
console.history = [
3423
{ arguments: ['a', 'b'], level: 'log' },
3524
{ arguments: ['c', 'd'], level: 'warn' },
@@ -40,7 +29,6 @@ describe('consoleReplay', () => {
4029
});
4130

4231
it('replays converts console param objects to JSON', () => {
43-
expect.assertions(1);
4432
console.history = [
4533
{ arguments: ['some message', { a: 1, b: 2 }], level: 'log' },
4634
{ arguments: ['other message', { c: 3, d: 4 }], level: 'warn' },
@@ -52,8 +40,7 @@ console.warn.apply(console, ["other message","{\\"c\\":3,\\"d\\":4}"]);`;
5240
expect(actual).toEqual(expected);
5341
});
5442

55-
it('replays converts script tag inside of object string to be safe ', () => {
56-
expect.assertions(1);
43+
it('replays converts script tag inside of object string to be safe', () => {
5744
console.history = [
5845
{
5946
arguments: [
@@ -74,7 +61,6 @@ console.warn.apply(console, ["other message","{\\"c\\":3,\\"d\\":4}"]);`;
7461
});
7562

7663
it('buildConsoleReplay wraps console replay in a script tag', () => {
77-
expect.assertions(1);
7864
console.history = [
7965
{ arguments: ['some message', { a: 1, b: 2 }], level: 'log' },
8066
{ arguments: ['other message', { c: 3, d: 4 }], level: 'warn' },

0 commit comments

Comments
 (0)