jest-preset-stylelint 6.1.0 → 6.2.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
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![NPM version](https://img.shields.io/npm/v/jest-preset-stylelint.svg)](https://www.npmjs.org/package/jest-preset-stylelint) [![Build Status](https://github.com/stylelint/jest-preset-stylelint/workflows/CI/badge.svg)](https://github.com/stylelint/jest-preset-stylelint/actions)
4
4
 
5
- [Jest](https://facebook.github.io/jest/) preset for [Stylelint](https://github.com/stylelint) plugins.
5
+ [Jest](https://jestjs.io/) preset for [Stylelint](https://stylelint.io/) plugins.
6
6
 
7
7
  ## Installation
8
8
 
@@ -22,14 +22,16 @@ Add the preset to your `jest.config.js` or `jest` field in `package.json`:
22
22
  }
23
23
  ```
24
24
 
25
- Optionally, you can avoid specifying `plugins` in every schema by defining your own setup file to configure the `testRule` function. This is useful if you have many tests. There are two additional steps to do this:
25
+ Optionally, you can avoid specifying `plugins` in every schema by defining your own setup file to configure the `testRule`/`testRuleConfigs` functions.
26
+ This is useful if you have many tests. There are two additional steps to do this:
26
27
 
27
- 1. Create `jest.setup.js` in the root of your project. Provide `plugins` option to `getTestRule()`:
28
+ 1. Create `jest.setup.js` in the root of your project. Provide `plugins` option to `getTestRule`/`getTestRuleConfigs`:
28
29
 
29
30
  ```js
30
31
  const { getTestRule } = require("jest-preset-stylelint");
31
32
 
32
33
  global.testRule = getTestRule({ plugins: ["./"] });
34
+ global.testRuleConfigs = getTestRuleConfigs({ plugins: ["./"] });
33
35
  ```
34
36
 
35
37
  2. Add `jest.setup.js` to your `jest.config.js` or `jest` field in `package.json`:
@@ -43,7 +45,13 @@ Optionally, you can avoid specifying `plugins` in every schema by defining your
43
45
 
44
46
  ## Usage
45
47
 
46
- The preset exposes a global `testRule` function that you can use to efficiently test your plugin using a schema.
48
+ This preset exposes the following global functions as a helper.
49
+
50
+ See also the [type definitions](index.d.ts) for more details.
51
+
52
+ ### `testRule`
53
+
54
+ The `testRule` function enables you to efficiently test your plugin using a schema.
47
55
 
48
56
  For example, we can test a plugin that enforces and autofixes kebab-case class selectors:
49
57
 
@@ -104,9 +112,34 @@ testRule({
104
112
  });
105
113
  ```
106
114
 
107
- ## Schema properties
115
+ ### `testRuleConfigs`
116
+
117
+ The `testRuleConfigs` function enables you to test invalid configs for a rule.
118
+
119
+ For example:
120
+
121
+ ```js
122
+ testInvalidRuleConfigs({
123
+ plugins: ["."],
124
+ ruleName,
125
+
126
+ accept: [
127
+ {
128
+ config: "valid"
129
+ }
130
+ ],
108
131
 
109
- See the [type definitions](index.d.ts).
132
+ reject: [
133
+ {
134
+ config: "invalid"
135
+ },
136
+ {
137
+ config: [/invalid/],
138
+ description: "regex is not allowed"
139
+ }
140
+ ]
141
+ });
142
+ ```
110
143
 
111
144
  ## [Changelog](CHANGELOG.md)
112
145
 
package/getTestRule.js CHANGED
@@ -2,9 +2,6 @@
2
2
 
3
3
  const util = require('util');
4
4
 
5
- // @ts-expect-error -- TS2614: Module '"stylelint"' has no exported member 'lint'. Did you mean to use 'import lint from "stylelint"' instead?
6
- const { lint } = require('stylelint'); // eslint-disable-line node/no-unpublished-require -- Avoid auto-install of `stylelint` peer dependency.
7
-
8
5
  /**
9
6
  * @typedef {import('.').TestCase} TestCase
10
7
  * @typedef {import('.').TestSchema} TestSchema
@@ -13,6 +10,14 @@ const { lint } = require('stylelint'); // eslint-disable-line node/no-unpublishe
13
10
  /** @type {import('.').getTestRule} */
14
11
  module.exports = function getTestRule(options = {}) {
15
12
  return function testRule(schema) {
13
+ /** @type {import('stylelint').lint} */
14
+ let lint;
15
+
16
+ beforeAll(() => {
17
+ // eslint-disable-next-line n/no-unpublished-require -- Avoid auto-install of `stylelint` peer dependency.
18
+ lint = require('stylelint').lint;
19
+ });
20
+
16
21
  describe(`${schema.ruleName}`, () => {
17
22
  const stylelintConfig = {
18
23
  plugins: options.plugins || schema.plugins,
@@ -0,0 +1,68 @@
1
+ 'use strict';
2
+
3
+ const { inspect } = require('util');
4
+
5
+ /** @type {import('.').getTestRuleConfigs} */
6
+ module.exports = function getTestRuleConfigs(options = {}) {
7
+ return function testRuleConfigs({
8
+ ruleName,
9
+ accept = [],
10
+ reject = [],
11
+ only = false,
12
+ skip = false,
13
+ plugins = options.plugins,
14
+ }) {
15
+ if (accept.length === 0 && reject.length === 0) {
16
+ throw new TypeError('The either "accept" or "reject" property must not be empty');
17
+ }
18
+
19
+ /** @type {import('stylelint').lint} */
20
+ let lint;
21
+
22
+ beforeAll(() => {
23
+ // eslint-disable-next-line n/no-unpublished-require
24
+ lint = require('stylelint').lint;
25
+ });
26
+
27
+ const testGroup = only ? describe.only : skip ? describe.skip : describe;
28
+
29
+ testGroup(`${ruleName} configs`, () => {
30
+ /**
31
+ * @param {import('.').ConfigCase} case
32
+ * @param {(warnings: unknown[]) => void} comparison
33
+ */
34
+ function testConfig({ config, description, only: onlyTest, skip: skipTest }, comparison) {
35
+ const testFn = onlyTest ? test.only : skipTest ? test.skip : test;
36
+
37
+ testFn(`${description || inspect(config)}`, async () => {
38
+ const lintConfig = {
39
+ plugins,
40
+ rules: { [ruleName]: config },
41
+ };
42
+ const { results } = await lint({ code: '', config: lintConfig });
43
+
44
+ expect(results).toHaveLength(1);
45
+ comparison(results[0].invalidOptionWarnings);
46
+ });
47
+ }
48
+
49
+ describe('accept', () => {
50
+ accept.forEach((c) => {
51
+ testConfig(c, (warnings) => {
52
+ // eslint-disable-next-line jest/no-standalone-expect
53
+ expect(warnings).toEqual([]);
54
+ });
55
+ });
56
+ });
57
+
58
+ describe('reject', () => {
59
+ reject.forEach((c) => {
60
+ testConfig(c, (warnings) => {
61
+ // eslint-disable-next-line jest/no-standalone-expect
62
+ expect(warnings).toEqual([{ text: expect.stringMatching(`"${ruleName}"`) }]);
63
+ });
64
+ });
65
+ });
66
+ });
67
+ };
68
+ };
package/index.d.ts CHANGED
@@ -156,6 +156,29 @@ export type TestRule = (schema: TestSchema) => void;
156
156
  */
157
157
  export function getTestRule(options?: { plugins?: TestSchema['plugins'] }): TestRule;
158
158
 
159
+ export type ConfigCase = {
160
+ config: unknown;
161
+ description?: string;
162
+ only?: boolean;
163
+ skip?: boolean;
164
+ };
165
+
166
+ /**
167
+ * Test configurations for a rule.
168
+ */
169
+ export type TestRuleConfigs = (
170
+ schema: Pick<TestSchema, 'ruleName' | 'plugins' | 'only' | 'skip'> & {
171
+ accept?: ConfigCase[];
172
+ reject?: ConfigCase[];
173
+ },
174
+ ) => void;
175
+
176
+ /**
177
+ * Create a `testRuleConfigs()` function with any specified plugins.
178
+ */
179
+ export function getTestRuleConfigs(options?: { plugins?: TestSchema['plugins'] }): TestRuleConfigs;
180
+
159
181
  declare global {
160
182
  var testRule: TestRule;
183
+ var testRuleConfigs: TestRuleConfigs;
161
184
  }
package/jest-preset.js CHANGED
@@ -2,5 +2,6 @@
2
2
 
3
3
  module.exports = {
4
4
  setupFiles: [require.resolve('./jest-setup.js')],
5
+ setupFilesAfterEnv: [require.resolve('./jest-setup-after-env.js')],
5
6
  testEnvironment: 'node',
6
7
  };
@@ -0,0 +1,18 @@
1
+ 'use strict';
2
+
3
+ const os = require('os');
4
+
5
+ const eolDescriptor = Object.getOwnPropertyDescriptor(os, 'EOL');
6
+
7
+ if (!eolDescriptor) {
8
+ throw new TypeError('`os` must have an `EOL` property');
9
+ }
10
+
11
+ beforeAll(() => {
12
+ // NOTE: `jest.replaceProperty()` is unavailable for a read-only property.
13
+ Object.defineProperty(os, 'EOL', { ...eolDescriptor, value: '\n' });
14
+ });
15
+
16
+ afterAll(() => {
17
+ Object.defineProperty(os, 'EOL', eolDescriptor);
18
+ });
package/jest-setup.js CHANGED
@@ -1,8 +1,7 @@
1
1
  'use strict';
2
2
 
3
- // Mock should be before stylelint required. Even if it's required inside other modules
4
- jest.mock('stylelint/lib/utils/getOsEol', () => () => '\n');
5
-
6
- const getTestRule = require('./getTestRule');
3
+ const getTestRule = require('./getTestRule.js');
4
+ const getTestRuleConfigs = require('./getTestRuleConfigs.js');
7
5
 
8
6
  global.testRule = getTestRule();
7
+ global.testRuleConfigs = getTestRuleConfigs();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jest-preset-stylelint",
3
- "version": "6.1.0",
3
+ "version": "6.2.0",
4
4
  "description": "Jest preset for Stylelint plugins.",
5
5
  "keywords": [
6
6
  "stylelint",
@@ -14,9 +14,11 @@
14
14
  "main": "index.js",
15
15
  "types": "index.d.ts",
16
16
  "files": [
17
+ "getTestRuleConfigs.js",
17
18
  "getTestRule.js",
18
19
  "jest-preset.js",
19
20
  "jest-setup.js",
21
+ "jest-setup-after-env.js",
20
22
  "index.d.ts"
21
23
  ],
22
24
  "scripts": {
@@ -26,7 +28,7 @@
26
28
  "lint:js": "eslint .",
27
29
  "lint:md": "remark . --quiet --frail",
28
30
  "lint:types": "tsc",
29
- "release": "np",
31
+ "release": "np --no-release-draft",
30
32
  "pretest": "npm run lint",
31
33
  "test": "jest",
32
34
  "watch": "jest --watch",
@@ -54,22 +56,26 @@
54
56
  "@stylelint/remark-preset"
55
57
  ]
56
58
  },
59
+ "jest": {
60
+ "preset": "./jest-preset.js",
61
+ "testRegex": ".*\\.test\\.js$"
62
+ },
57
63
  "devDependencies": {
58
- "@stylelint/prettier-config": "^2.0.0",
64
+ "@stylelint/prettier-config": "^3.0.0",
59
65
  "@stylelint/remark-preset": "^4.0.0",
60
- "@types/jest": "^29.4.0",
61
- "eslint": "^8.34.0",
62
- "eslint-config-stylelint": "^18.0.0",
63
- "eslint-plugin-jest": "^27.2.1",
66
+ "@types/jest": "^29.5.3",
67
+ "eslint": "^8.46.0",
68
+ "eslint-config-stylelint": "^19.1.0",
69
+ "eslint-plugin-jest": "^27.2.3",
64
70
  "husky": "^8.0.3",
65
- "jest": "^29.4.3",
66
- "lint-staged": "^13.1.2",
67
- "np": "^7.6.3",
71
+ "jest": "^29.6.2",
72
+ "lint-staged": "^13.2.3",
73
+ "np": "^8.0.4",
68
74
  "npm-run-all": "^4.1.5",
69
- "prettier": "^2.8.4",
75
+ "prettier": "^3.0.1",
70
76
  "remark-cli": "^11.0.0",
71
- "stylelint": "^15.1.0",
72
- "typescript": "^4.9.5"
77
+ "stylelint": "^15.10.2",
78
+ "typescript": "^5.1.6"
73
79
  },
74
80
  "peerDependencies": {
75
81
  "jest": "^29.0.2"