@sequencemedia/eslint-config-typescript 0.0.5 → 0.1.0

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.
package/README.md CHANGED
@@ -1,3 +1,62 @@
1
1
  # `@sequencemedia/eslint-config-typescript`
2
2
 
3
- [Love](https://github.com/mightyiam/eslint-config-love)
3
+ TypeScript style Flat Config for ESLint `v9`
4
+
5
+ Based on [Love](https://github.com/mightyiam/eslint-config-love)
6
+
7
+ ## Install
8
+
9
+ ```shell
10
+ npm i -D @sequencemedia/eslint-config-typescript
11
+ ```
12
+
13
+ ## Use
14
+
15
+ In your `eslint.config.*` either:
16
+
17
+ ```javascript
18
+ export { default } from '@sequencemedia/eslint-config-typescript'
19
+ ```
20
+
21
+ Or:
22
+
23
+ ```javascript
24
+ import { configs } from '@sequencemedia/eslint-config-typescript'
25
+
26
+ export default [
27
+ configs.recommended
28
+ ]
29
+ ```
30
+
31
+ You can merge _changes_ in the default configuration using the `merge` utility:
32
+
33
+ ```javascript
34
+ import merge from '@sequencemedia/eslint-config-typescript/merge'
35
+
36
+ export default merge({
37
+ files: [
38
+ '**/*.{mjs,cjs}'
39
+ ],
40
+ ignores: [
41
+ 'lib'
42
+ ]
43
+ })
44
+ ```
45
+
46
+ Which is _equivalent to_:
47
+
48
+ ```javascript
49
+ import { configs } from '@sequencemedia/eslint-config-typescript'
50
+
51
+ export default [
52
+ {
53
+ ...configs.recommended,
54
+ files: [
55
+ '**/*.{mts,cts}'
56
+ ],
57
+ ignores: [
58
+ 'lib'
59
+ ]
60
+ }
61
+ ]
62
+ ```
@@ -0,0 +1,12 @@
1
+ import recommended from './recommended.mjs'
2
+ import typescript from './typescript.mjs'
3
+
4
+ export {
5
+ recommended,
6
+ typescript
7
+ }
8
+
9
+ export default {
10
+ recommended,
11
+ typescript
12
+ }
@@ -0,0 +1,26 @@
1
+ import {
2
+ parser
3
+ } from 'typescript-eslint'
4
+ import typescript from './typescript.mjs'
5
+
6
+ export default {
7
+ name: '@sequencemedia/eslint-config-typescript/recommended',
8
+ languageOptions: {
9
+ parser,
10
+ parserOptions: {
11
+ projectService: true
12
+ }
13
+ },
14
+ linterOptions: {
15
+ reportUnusedDisableDirectives: 'error'
16
+ },
17
+ files: [
18
+ '**/*.{ts,mts,cts}'
19
+ ],
20
+ plugins: {
21
+ ...typescript.plugins
22
+ },
23
+ rules: {
24
+ ...typescript.rules
25
+ }
26
+ }
@@ -0,0 +1,468 @@
1
+ import {
2
+ plugin as t
3
+ } from 'typescript-eslint'
4
+ import c from 'eslint-plugin-eslint-comments'
5
+ import n from 'eslint-plugin-n'
6
+ import p from 'eslint-plugin-promise'
7
+ import i from 'eslint-plugin-import'
8
+
9
+ export default {
10
+ name: '@sequencemedia/eslint-config-typescript/typescript',
11
+ plugins: {
12
+ '@typescript-eslint': t,
13
+ 'eslint-comments': c,
14
+ n,
15
+ promise: p,
16
+ import: i
17
+
18
+ },
19
+ rules: {
20
+ /**
21
+ * `@typescript-eslint`
22
+ */
23
+ '@typescript-eslint/adjacent-overload-signatures': 'error',
24
+ '@typescript-eslint/array-type': [
25
+ 'error',
26
+ {
27
+ default: 'array-simple'
28
+ }
29
+ ],
30
+ '@typescript-eslint/await-thenable': 'error',
31
+ '@typescript-eslint/ban-ts-comment': [
32
+ 'error',
33
+ {
34
+ 'ts-expect-error': 'allow-with-description',
35
+ 'ts-ignore': true,
36
+ 'ts-nocheck': true,
37
+ 'ts-check': false,
38
+ minimumDescriptionLength: 3
39
+ }
40
+ ],
41
+ '@typescript-eslint/ban-tslint-comment': 'error',
42
+ '@typescript-eslint/class-literal-property-style': [
43
+ 'error',
44
+ 'fields'
45
+ ],
46
+ '@typescript-eslint/class-methods-use-this': [
47
+ 'error',
48
+ {
49
+ exceptMethods: [],
50
+ enforceForClassFields: true,
51
+ ignoreOverrideMethods: false,
52
+ ignoreClassesThatImplementAnInterface: false
53
+ }
54
+ ],
55
+ '@typescript-eslint/consistent-generic-constructors': [
56
+ 'error',
57
+ 'constructor'
58
+ ],
59
+ '@typescript-eslint/consistent-indexed-object-style': [
60
+ 'error',
61
+ 'record'
62
+ ],
63
+ '@typescript-eslint/consistent-type-assertions': [
64
+ 'error',
65
+ {
66
+ assertionStyle: 'as',
67
+ objectLiteralTypeAssertions: 'never'
68
+ }
69
+ ],
70
+ '@typescript-eslint/consistent-type-definitions': [
71
+ 'error',
72
+ 'interface'
73
+ ],
74
+ '@typescript-eslint/consistent-type-exports': [
75
+ 'error',
76
+ {
77
+ fixMixedExportsWithInlineTypeSpecifier: true
78
+ }
79
+ ],
80
+ '@typescript-eslint/consistent-type-imports': [
81
+ 'error',
82
+ {
83
+ prefer: 'type-imports',
84
+ disallowTypeAnnotations: true,
85
+ fixStyle: 'inline-type-imports'
86
+ }
87
+ ],
88
+ '@typescript-eslint/dot-notation': [
89
+ 'error',
90
+ {
91
+ allowIndexSignaturePropertyAccess: false,
92
+ allowKeywords: true,
93
+ allowPattern: '',
94
+ allowPrivateClassPropertyAccess: false,
95
+ allowProtectedClassPropertyAccess: false
96
+ }
97
+ ],
98
+ '@typescript-eslint/explicit-function-return-type': [
99
+ 'error',
100
+ {
101
+ allowExpressions: true,
102
+ allowHigherOrderFunctions: true,
103
+ allowTypedFunctionExpressions: true,
104
+ allowDirectConstAssertionInArrowFunctions: true
105
+ }
106
+ ],
107
+ '@typescript-eslint/init-declarations': [
108
+ 'error',
109
+ 'always'
110
+ ],
111
+ '@typescript-eslint/max-params': [
112
+ 'error',
113
+ {
114
+ max: 4
115
+ }
116
+ ],
117
+ '@typescript-eslint/method-signature-style': 'error',
118
+ '@typescript-eslint/naming-convention': [
119
+ 'error',
120
+ {
121
+ selector: 'variableLike',
122
+ leadingUnderscore: 'allow',
123
+ trailingUnderscore: 'allow',
124
+ format: [
125
+ 'camelCase',
126
+ 'PascalCase',
127
+ 'UPPER_CASE'
128
+ ]
129
+ }
130
+ ],
131
+ '@typescript-eslint/no-array-constructor': 'error',
132
+ '@typescript-eslint/no-array-delete': 'error',
133
+ '@typescript-eslint/no-base-to-string': 'error',
134
+ '@typescript-eslint/no-confusing-non-null-assertion': 'error',
135
+ '@typescript-eslint/no-confusing-void-expression': [
136
+ 'error',
137
+ {
138
+ ignoreArrowShorthand: false,
139
+ ignoreVoidOperator: false
140
+ }
141
+ ],
142
+ '@typescript-eslint/no-deprecated': [
143
+ 'warn'
144
+ ],
145
+ '@typescript-eslint/no-dupe-class-members': 'error',
146
+ '@typescript-eslint/no-duplicate-enum-values': 'error',
147
+ '@typescript-eslint/no-duplicate-type-constituents': [
148
+ 'error',
149
+ {
150
+ ignoreIntersections: false,
151
+ ignoreUnions: false
152
+ }
153
+ ],
154
+ '@typescript-eslint/no-dynamic-delete': 'error',
155
+ '@typescript-eslint/no-empty-function': [
156
+ 'error',
157
+ {
158
+ allow: []
159
+ }
160
+ ],
161
+ '@typescript-eslint/no-empty-object-type': [
162
+ 'error',
163
+ {
164
+ allowInterfaces: 'with-single-extends',
165
+ allowObjectTypes: 'never'
166
+ }
167
+ ],
168
+ '@typescript-eslint/no-explicit-any': [
169
+ 'error',
170
+ {
171
+ fixToUnknown: false,
172
+ ignoreRestArgs: false
173
+ }
174
+ ],
175
+ '@typescript-eslint/no-extra-non-null-assertion': 'error',
176
+ '@typescript-eslint/no-extraneous-class': [
177
+ 'error',
178
+ {
179
+ allowWithDecorator: true
180
+ }
181
+ ],
182
+ '@typescript-eslint/no-floating-promises': 'error',
183
+ '@typescript-eslint/no-for-in-array': 'error',
184
+ '@typescript-eslint/no-implied-eval': 'error',
185
+ '@typescript-eslint/no-import-type-side-effects': 'error',
186
+ '@typescript-eslint/no-inferrable-types': [
187
+ 'error',
188
+ {
189
+ ignoreParameters: false,
190
+ ignoreProperties: false
191
+ }
192
+ ],
193
+ '@typescript-eslint/no-invalid-void-type': 'error',
194
+ '@typescript-eslint/no-loop-func': 'error',
195
+ '@typescript-eslint/no-magic-numbers': [
196
+ 'error',
197
+ {
198
+ ignore: [],
199
+ ignoreArrayIndexes: false,
200
+ ignoreDefaultValues: false,
201
+ ignoreClassFieldInitialValues: false,
202
+ enforceConst: false,
203
+ detectObjects: true,
204
+ ignoreEnums: true,
205
+ ignoreNumericLiteralTypes: false,
206
+ ignoreReadonlyClassProperties: true,
207
+ ignoreTypeIndexes: false
208
+ }
209
+ ],
210
+ '@typescript-eslint/no-meaningless-void-operator': [
211
+ 'error',
212
+ {
213
+ checkNever: true
214
+ }
215
+ ],
216
+ '@typescript-eslint/no-misused-new': 'error',
217
+ '@typescript-eslint/no-misused-promises': 'error',
218
+ '@typescript-eslint/no-mixed-enums': 'error',
219
+ '@typescript-eslint/no-namespace': 'error',
220
+ '@typescript-eslint/no-non-null-asserted-nullish-coalescing': 'error',
221
+ '@typescript-eslint/no-non-null-asserted-optional-chain': 'error',
222
+ '@typescript-eslint/no-non-null-assertion': 'error',
223
+ '@typescript-eslint/no-redundant-type-constituents': 'error',
224
+ '@typescript-eslint/no-require-imports': [
225
+ 'error',
226
+ {
227
+ allow: [],
228
+ allowAsImport: false
229
+ }
230
+ ],
231
+ '@typescript-eslint/no-this-alias': [
232
+ 'error',
233
+ {
234
+ allowDestructuring: true
235
+ }
236
+ ],
237
+ '@typescript-eslint/no-unnecessary-boolean-literal-compare': 'error',
238
+ '@typescript-eslint/no-unnecessary-condition': [
239
+ 'error',
240
+ {
241
+ allowConstantLoopConditions: true
242
+ }
243
+ ],
244
+ '@typescript-eslint/no-unnecessary-parameter-property-assignment': 'error',
245
+ '@typescript-eslint/no-unnecessary-qualifier': 'error',
246
+ '@typescript-eslint/no-unnecessary-template-expression': 'error',
247
+ '@typescript-eslint/no-unnecessary-type-arguments': 'error',
248
+ '@typescript-eslint/no-unnecessary-type-assertion': 'error',
249
+ '@typescript-eslint/no-unnecessary-type-constraint': 'error',
250
+ '@typescript-eslint/no-unnecessary-type-parameters': 'error',
251
+ '@typescript-eslint/no-unsafe-argument': 'error',
252
+ '@typescript-eslint/no-unsafe-assignment': 'error',
253
+ '@typescript-eslint/no-unsafe-call': 'error',
254
+ '@typescript-eslint/no-unsafe-declaration-merging': 'error',
255
+ '@typescript-eslint/no-unsafe-enum-comparison': 'error',
256
+ '@typescript-eslint/no-unsafe-function-type': 'error',
257
+ '@typescript-eslint/no-unsafe-member-access': 'error',
258
+ '@typescript-eslint/no-unsafe-return': 'error',
259
+ '@typescript-eslint/no-unsafe-type-assertion': 'error',
260
+ '@typescript-eslint/no-unsafe-unary-minus': 'error',
261
+ '@typescript-eslint/no-unused-expressions': [
262
+ 'error',
263
+ {
264
+ allowShortCircuit: true,
265
+ allowTernary: true,
266
+ allowTaggedTemplates: true,
267
+ enforceForJSX: false
268
+ }
269
+ ],
270
+ '@typescript-eslint/no-unused-vars': [
271
+ 'error',
272
+ {
273
+ args: 'none',
274
+ caughtErrors: 'none',
275
+ ignoreRestSiblings: true,
276
+ vars: 'all'
277
+ }
278
+ ],
279
+ '@typescript-eslint/no-use-before-define': [
280
+ 'error',
281
+ {
282
+ functions: false,
283
+ classes: false,
284
+ enums: false,
285
+ variables: false,
286
+ typedefs: false
287
+ }
288
+ ],
289
+ '@typescript-eslint/no-useless-constructor': 'error',
290
+ '@typescript-eslint/no-useless-empty-export': 'error',
291
+ '@typescript-eslint/no-wrapper-object-types': 'error',
292
+ '@typescript-eslint/non-nullable-type-assertion-style': 'error',
293
+ '@typescript-eslint/only-throw-error': [
294
+ 'error',
295
+ {
296
+ allowThrowingAny: false,
297
+ allowThrowingUnknown: false
298
+ }
299
+ ],
300
+ '@typescript-eslint/prefer-as-const': 'error',
301
+ '@typescript-eslint/prefer-destructuring': [
302
+ 'error',
303
+ {
304
+ array: true,
305
+ object: true
306
+ },
307
+ {
308
+ enforceForRenamedProperties: true,
309
+ enforceForDeclarationWithTypeAnnotation: false
310
+ }
311
+ ],
312
+ '@typescript-eslint/prefer-find': 'error',
313
+ '@typescript-eslint/prefer-for-of': 'error',
314
+ '@typescript-eslint/prefer-function-type': 'error',
315
+ '@typescript-eslint/prefer-includes': 'error',
316
+ '@typescript-eslint/prefer-literal-enum-member': [
317
+ 'error',
318
+ {
319
+ allowBitwiseExpressions: true
320
+ }
321
+ ],
322
+ '@typescript-eslint/prefer-namespace-keyword': 'error',
323
+ '@typescript-eslint/prefer-nullish-coalescing': [
324
+ 'error',
325
+ {
326
+ ignoreConditionalTests: false,
327
+ ignoreMixedLogicalExpressions: false
328
+ }
329
+ ],
330
+ '@typescript-eslint/prefer-optional-chain': 'error',
331
+ '@typescript-eslint/prefer-promise-reject-errors': 'error',
332
+ '@typescript-eslint/prefer-readonly': 'error',
333
+ '@typescript-eslint/prefer-reduce-type-parameter': 'error',
334
+ '@typescript-eslint/prefer-regexp-exec': 'error',
335
+ '@typescript-eslint/prefer-return-this-type': 'error',
336
+ '@typescript-eslint/prefer-string-starts-ends-with': [
337
+ 'error',
338
+ {
339
+ allowSingleElementEquality: 'never'
340
+ }
341
+ ],
342
+ '@typescript-eslint/promise-function-async': 'error',
343
+ '@typescript-eslint/related-getter-setter-pairs': 'error',
344
+ '@typescript-eslint/require-array-sort-compare': [
345
+ 'error',
346
+ {
347
+ ignoreStringArrays: true
348
+ }
349
+ ],
350
+ '@typescript-eslint/require-await': 'error',
351
+ '@typescript-eslint/restrict-plus-operands': [
352
+ 'error',
353
+ {
354
+ skipCompoundAssignments: false
355
+ }
356
+ ],
357
+ '@typescript-eslint/restrict-template-expressions': [
358
+ 'error',
359
+ {
360
+ allowNumber: true
361
+ }
362
+ ],
363
+ '@typescript-eslint/return-await': [
364
+ 'error',
365
+ 'always'
366
+ ],
367
+ '@typescript-eslint/strict-boolean-expressions': [
368
+ 'error',
369
+ {
370
+ allowString: false,
371
+ allowNumber: false,
372
+ allowNullableObject: false,
373
+ allowNullableBoolean: false,
374
+ allowNullableString: false,
375
+ allowNullableNumber: false,
376
+ allowAny: false
377
+ }
378
+ ],
379
+ '@typescript-eslint/switch-exhaustiveness-check': [
380
+ 'error',
381
+ {
382
+ allowDefaultCaseForExhaustiveSwitch: false,
383
+ requireDefaultForNonUnion: false,
384
+ considerDefaultExhaustiveForUnions: true
385
+ }
386
+ ],
387
+ '@typescript-eslint/triple-slash-reference': [
388
+ 'error',
389
+ {
390
+ lib: 'never',
391
+ path: 'never',
392
+ types: 'never'
393
+ }
394
+ ],
395
+ '@typescript-eslint/unbound-method': [
396
+ 'error',
397
+ {
398
+ ignoreStatic: false
399
+ }
400
+ ],
401
+ '@typescript-eslint/unified-signatures': [
402
+ 'error',
403
+ {
404
+ ignoreDifferentlyNamedParameters: false
405
+ }
406
+ ],
407
+ '@typescript-eslint/use-unknown-in-catch-callback-variable': 'error',
408
+
409
+ /**
410
+ * `eslint-plugin-eslint-comments`
411
+ */
412
+ 'eslint-comments/disable-enable-pair': [
413
+ 'error',
414
+ {
415
+ allowWholeFile: true
416
+ }
417
+ ],
418
+ 'eslint-comments/no-aggregating-enable': 'error',
419
+ 'eslint-comments/no-duplicate-disable': 'error',
420
+ 'eslint-comments/no-unlimited-disable': 'error',
421
+ 'eslint-comments/no-unused-enable': 'error',
422
+ 'eslint-comments/require-description': [
423
+ 'error',
424
+ {
425
+ ignore: [
426
+ 'eslint-enable',
427
+ 'eslint-env'
428
+ ]
429
+ }
430
+ ],
431
+
432
+ /**
433
+ * `eslint-plugin-n`
434
+ */
435
+ 'n/handle-callback-err': [
436
+ 'error',
437
+ '^(err|error)$'
438
+ ],
439
+ 'n/no-callback-literal': 'error',
440
+ 'n/no-deprecated-api': 'error',
441
+ 'n/no-exports-assign': 'error',
442
+ 'n/no-new-require': 'error',
443
+ 'n/no-path-concat': 'error',
444
+ 'n/process-exit-as-throw': 'error',
445
+
446
+ /**
447
+ * `eslint-plugin-promise`
448
+ */
449
+ 'promise/param-names': 'error',
450
+
451
+ /**
452
+ * `eslint-plugin-import`
453
+ */
454
+ 'import/export': 'error',
455
+ 'import/first': 'error',
456
+ 'import/no-absolute-path': [
457
+ 'error',
458
+ {
459
+ esmodule: true,
460
+ commonjs: true,
461
+ amd: false
462
+ }
463
+ ],
464
+ 'import/no-duplicates': 'error',
465
+ 'import/no-named-default': 'error',
466
+ 'import/no-webpack-loader-syntax': 'error'
467
+ }
468
+ }
package/index.mjs CHANGED
@@ -1,11 +1,29 @@
1
- import typescript from '#eslint-config-typescript/config/typescript'
1
+ import {
2
+ parser
3
+ } from 'typescript-eslint'
4
+ import recommended from '#eslint-config-typescript/configs/recommended'
5
+ import typescript from '#eslint-config-typescript/configs/typescript'
6
+
7
+ export const configs = {
8
+ recommended,
9
+ typescript
10
+ }
2
11
 
3
12
  export default [
4
13
  {
5
14
  name: '@sequencemedia/eslint-config-typescript',
6
15
  languageOptions: {
7
- ecmaVersion: 'latest'
8
- }
16
+ parser,
17
+ parserOptions: {
18
+ projectService: true
19
+ }
20
+ },
21
+ linterOptions: {
22
+ reportUnusedDisableDirectives: 'error'
23
+ },
24
+ files: [
25
+ '**/*.{ts,mts,cts}'
26
+ ]
9
27
  },
10
28
  typescript
11
29
  ]
@@ -0,0 +1,12 @@
1
+ import merge from '@sequencemedia/eslint-merge'
2
+
3
+ import CONFIG from '#eslint-config-typescript/configs/recommended'
4
+
5
+ export default function mergeConfig (config) {
6
+ return (
7
+ merge(
8
+ CONFIG,
9
+ config
10
+ )
11
+ )
12
+ }
@@ -1,6 +1,6 @@
1
1
  import merge from '@sequencemedia/eslint-merge'
2
2
 
3
- import CONFIG from '#eslint-config-typescript/config/typescript'
3
+ import CONFIG from '#eslint-config-typescript/configs/typescript'
4
4
 
5
5
  export default function mergeConfig (config) {
6
6
  return (
package/merge.mjs CHANGED
@@ -2,9 +2,22 @@ import getMapMerge from '@sequencemedia/eslint-merge/get-map-merge'
2
2
 
3
3
  import eslintConfig from './index.mjs'
4
4
 
5
+ function include ({ name }) {
6
+ return name === '@sequencemedia/eslint-config-typescript'
7
+ }
8
+
9
+ function exclude ({ name }) {
10
+ return name !== '@sequencemedia/eslint-config-typescript'
11
+ }
12
+
5
13
  export default function mergeESLintConfigWith (config) {
6
14
  return (
7
15
  eslintConfig
8
- .map(getMapMerge(config))
16
+ .filter(include)
17
+ .concat(
18
+ eslintConfig
19
+ .filter(exclude)
20
+ .map(getMapMerge(config))
21
+ )
9
22
  )
10
23
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sequencemedia/eslint-config-typescript",
3
- "version": "0.0.5",
3
+ "version": "0.1.0",
4
4
  "description": "TypeScript configuration for ESLint 9",
5
5
  "keywords": [
6
6
  "JavaScript TypeScript Style",
@@ -60,7 +60,7 @@
60
60
  "typescript-eslint": "^8.17.0"
61
61
  },
62
62
  "devDependencies": {
63
- "@sequencemedia/eslint-config-standard": "^0.1.6",
63
+ "@sequencemedia/eslint-config-standard": "^0.2.0",
64
64
  "chai": "^5.1.2",
65
65
  "eslint": "^9.16.0",
66
66
  "husky": "^9.1.7",
@@ -72,14 +72,15 @@
72
72
  "imports": {
73
73
  "#eslint-config-typescript": "./index.mjs",
74
74
  "#eslint-config-typescript/common": "./common/index.mjs",
75
- "#eslint-config-typescript/config/*": "./config/*.mjs",
75
+ "#eslint-config-typescript/configs": "./configs/index.mjs",
76
+ "#eslint-config-typescript/configs/*": "./configs/*.mjs",
76
77
  "#eslint-config-typescript/merge": "./merge.mjs",
77
78
  "#eslint-config-typescript/merge/*": "./merge/*.mjs"
78
79
  },
79
80
  "exports": {
80
81
  ".": "./index.mjs",
81
- "./common": "./common/index.mjs",
82
- "./config/*": "./config/*.mjs",
82
+ "./configs": "./configs/index.mjs",
83
+ "./configs/*": "./configs/*.mjs",
83
84
  "./merge": "./merge.mjs",
84
85
  "./merge/*": "./merge/*.mjs"
85
86
  }
@@ -5,9 +5,9 @@ import {
5
5
  import {
6
6
  isString,
7
7
  isObject
8
- } from '@sequencemedia/eslint-config-typescript/common'
8
+ } from '#eslint-config-typescript/common'
9
9
 
10
- describe('@sequencemedia/eslint-config-typescript/common', () => {
10
+ describe('#eslint-config-typescript/common', () => {
11
11
  describe('`isString`', () => it('is a function', () => expect(isString).to.be.a('function')))
12
12
 
13
13
  describe('`isObject`', () => it('is a function', () => expect(isObject).to.be.a('function')))