jest-preset-stylelint 4.1.1 → 5.0.1

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,11 +2,11 @@
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://facebook.github.io/jest/) preset for [Stylelint](https://github.com/stylelint) plugins.
6
6
 
7
7
  ## Installation
8
8
 
9
- Install the preset alongside jest and stylelint:
9
+ Install the preset alongside Jest and Stylelint:
10
10
 
11
11
  ```bash
12
12
  npm install jest-preset-stylelint jest stylelint --save-dev
@@ -24,10 +24,10 @@ Add the preset to your `jest.config.js` or `jest` field in `package.json`:
24
24
 
25
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:
26
26
 
27
- 1. Create `jest.setup.js` in the root of your project. Provide [`plugins`](#plugins-arraystring) option to `getTestRule()`:
27
+ 1. Create `jest.setup.js` in the root of your project. Provide `plugins` option to `getTestRule()`:
28
28
 
29
29
  ```js
30
- const getTestRule = require("jest-preset-stylelint/getTestRule");
30
+ const { getTestRule } = require("jest-preset-stylelint");
31
31
 
32
32
  global.testRule = getTestRule({ plugins: ["./"] });
33
33
  ```
@@ -75,7 +75,9 @@ testRule({
75
75
  description: "camel case class selector",
76
76
  message: messages.expected(),
77
77
  line: 1,
78
- column: 1
78
+ column: 1,
79
+ endLine: 1,
80
+ endColumn: 8
79
81
  },
80
82
  {
81
83
  code: ".MyClass,\n.MyOtherClass {}",
@@ -85,12 +87,16 @@ testRule({
85
87
  {
86
88
  message: messages.expected(),
87
89
  line: 1,
88
- column: 1
90
+ column: 1,
91
+ endLine: 1,
92
+ endColumn: 8
89
93
  },
90
94
  {
91
95
  message: messages.expected(),
92
96
  line: 2,
93
- column: 1
97
+ column: 1,
98
+ endLine: 2,
99
+ endColumn: 13
94
100
  }
95
101
  ]
96
102
  }
@@ -100,113 +106,7 @@ testRule({
100
106
 
101
107
  ## Schema properties
102
108
 
103
- ### `accept` \[array\<Object\>\]
104
-
105
- Accept test cases.
106
-
107
- ### `config` \[array\]
108
-
109
- Config to pass to the rule.
110
-
111
- ### `fix` \[boolean\]
112
-
113
- Default: `false` (Optional).
114
-
115
- Turn on autofix.
116
-
117
- ### `plugins` \[array\<string\>\]
118
-
119
- Maps to stylelint's [`plugins` configuration property](https://stylelint.io/user-guide/configure#plugins).
120
-
121
- Path to the file that exports the plugin object, relative to the root. Usually it's the same path as a `main` property in plugin's `package.json`.
122
-
123
- If you're testing a plugin pack, it's the path to the file that exports the array of plugin objects.
124
-
125
- Optional, if `plugins` option was passed to advanced configuration with `getTestRule()`.
126
-
127
- ### `reject` \[array\<Object\>\]
128
-
129
- Reject test cases.
130
-
131
- ### `ruleName` \[string\]
132
-
133
- Name of the rule being tested. Usually exported from the plugin.
134
-
135
- ### `skipBasicChecks` \[boolean\]
136
-
137
- Default: `false` (Optional).
138
-
139
- Skip [basic checks](https://github.com/stylelint/stylelint/blob/master/lib/testUtils/basicChecks.js), e.g. an empty source.
140
-
141
- ### `customSyntax` \<string\>
142
-
143
- Maps to stylelint's [`customSyntax` option](https://stylelint.io/user-guide/usage/options#customsyntax).
144
-
145
- ## Shared test case properties
146
-
147
- Used within both `accept` and `reject` test cases.
148
-
149
- ### `code` \[string\]
150
-
151
- The code of the test case.
152
-
153
- ### `description` \[string\]
154
-
155
- Optional.
156
-
157
- Description of the test case.
158
-
159
- ### `skip` \[boolean\]
160
-
161
- Default: `false` (Optional).
162
-
163
- Maps to Jest's [test.skip](https://jestjs.io/docs/en/api#testskipname-fn).
164
-
165
- ### `only` \[boolean\]
166
-
167
- Default: `false` (Optional).
168
-
169
- Maps to Jest's [test.only](https://jestjs.io/docs/en/api#testonlyname-fn-timeout).
170
-
171
- ## Reject test case properties
172
-
173
- Use the `warnings` property, rather than `message`, `line` and `column`, if the test case is expected to produce more than one warning.
174
-
175
- ### `column` \[number\]
176
-
177
- Optional.
178
-
179
- Expected column number of the warning.
180
-
181
- ### `fixed` \[string\]
182
-
183
- Optional if `fix` isn't `true`.
184
-
185
- Expected fixed code of the test case.
186
-
187
- ### `line` \[number\]
188
-
189
- Optional.
190
-
191
- Expected line number of the warning.
192
-
193
- ### `message` \[string\]
194
-
195
- Optional if `warnings` is used.
196
-
197
- Expected message from the test case. Usually exported from the plugin.
198
-
199
- ### `unfixable` \[boolean\]
200
-
201
- Default: `false` (Optional).
202
-
203
- Don't check the `fixed` code.
204
-
205
- ### `warnings` \[array\<Object\>\]
206
-
207
- Optional if `message` is used.
208
-
209
- Warning Objects containing expected `message`, `line` and `column`.
109
+ See the [type definitions](index.d.ts).
210
110
 
211
111
  ## [Changelog](CHANGELOG.md)
212
112
 
package/getTestRule.js CHANGED
@@ -2,34 +2,15 @@
2
2
 
3
3
  const util = require('util');
4
4
  // eslint-disable-next-line node/no-unpublished-require -- Avoid auto-install of `stylelint` peer dependency.
5
- const { basicChecks, lint } = require('stylelint');
5
+ const { lint } = require('stylelint');
6
6
 
7
7
  /**
8
- * @typedef {Object} TestCase
9
- * @property {string} code
10
- * @property {string} [description]
11
- * @property {boolean} [only]
12
- * @property {boolean} [skip]
8
+ * @typedef {import('.').TestCase} TestCase
9
+ * @typedef {import('.').TestSchema} TestSchema
13
10
  */
14
11
 
15
- /**
16
- * @typedef {Object} TestSchema
17
- * @property {string} ruleName
18
- * @property {any} config
19
- * @property {TestCase[]} accept
20
- * @property {TestCase[]} reject
21
- * @property {string | string[]} plugins
22
- * @property {boolean} [skipBasicChecks]
23
- * @property {boolean} [fix]
24
- * @property {Syntax} [customSyntax] - PostCSS Syntax (https://postcss.org/api/#syntax)
25
- * @property {boolean} [only]
26
- * @property {boolean} [skip]
27
- */
28
-
29
- function getTestRule(options = {}) {
30
- /**
31
- * @param {TestSchema} schema
32
- */
12
+ /** @type {import('.').getTestRule} */
13
+ module.exports = function getTestRule(options = {}) {
33
14
  return function testRule(schema) {
34
15
  describe(`${schema.ruleName}`, () => {
35
16
  const stylelintConfig = {
@@ -39,21 +20,16 @@ function getTestRule(options = {}) {
39
20
  },
40
21
  };
41
22
 
42
- let passingTestCases = schema.accept || [];
43
-
44
- if (!schema.skipBasicChecks) {
45
- passingTestCases = passingTestCases.concat(basicChecks);
46
- }
47
-
48
23
  setupTestCases({
49
24
  name: 'accept',
50
- cases: passingTestCases,
25
+ cases: schema.accept,
51
26
  schema,
52
27
  comparisons: (testCase) => async () => {
53
28
  const stylelintOptions = {
54
29
  code: testCase.code,
55
30
  config: stylelintConfig,
56
31
  customSyntax: schema.customSyntax,
32
+ codeFilename: schema.codeFilename,
57
33
  };
58
34
 
59
35
  const output = await lint(stylelintOptions);
@@ -80,6 +56,7 @@ function getTestRule(options = {}) {
80
56
  code: testCase.code,
81
57
  config: stylelintConfig,
82
58
  customSyntax: schema.customSyntax,
59
+ codeFilename: schema.codeFilename,
83
60
  };
84
61
 
85
62
  const outputAfterLint = await lint(stylelintOptions);
@@ -92,6 +69,7 @@ function getTestRule(options = {}) {
92
69
  (testCase.warnings || [testCase]).forEach((expected, i) => {
93
70
  const warning = actualWarnings[i];
94
71
 
72
+ // @ts-expect-error -- This is our custom matcher.
95
73
  expect(expected).toHaveMessage();
96
74
 
97
75
  expect(warning.text).toBe(expected.message);
@@ -103,6 +81,16 @@ function getTestRule(options = {}) {
103
81
  if (expected.column !== undefined) {
104
82
  expect(warning.column).toBe(expected.column);
105
83
  }
84
+
85
+ if (expected.endLine !== undefined) {
86
+ // @ts-expect-error -- TODO: `warning.endLine` is not implemented. See stylelint/stylelint#5725
87
+ expect(warning.endLine).toBe(expected.endLine);
88
+ }
89
+
90
+ if (expected.endColumn !== undefined) {
91
+ // @ts-expect-error -- TODO: `warning.endColumn` is not implemented. See stylelint/stylelint#5725
92
+ expect(warning.endColumn).toBe(expected.endColumn);
93
+ }
106
94
  });
107
95
 
108
96
  if (!schema.fix) return;
@@ -154,13 +142,24 @@ function getTestRule(options = {}) {
154
142
  }
155
143
 
156
144
  return {
145
+ message: () => '',
157
146
  pass: true,
158
147
  };
159
148
  },
160
149
  });
161
150
  };
162
- }
151
+ };
163
152
 
153
+ /**
154
+ * @template {TestCase} T
155
+ * @param {{
156
+ * name: string,
157
+ * cases: T[] | undefined,
158
+ * schema: TestSchema,
159
+ * comparisons: (testCase: T) => jest.ProvidesCallback,
160
+ * }} args
161
+ * @returns {void}
162
+ */
164
163
  function setupTestCases({ name, cases, schema, comparisons }) {
165
164
  if (cases && cases.length) {
166
165
  const testGroup = schema.only ? describe.only : schema.skip ? describe.skip : describe;
@@ -181,11 +180,16 @@ function setupTestCases({ name, cases, schema, comparisons }) {
181
180
  }
182
181
  }
183
182
 
183
+ /**
184
+ * @param {import('stylelint').LinterResult} output
185
+ * @returns {string}
186
+ */
184
187
  function getOutputCss(output) {
185
188
  const result = output.results[0]._postcssResult;
186
- const css = result.root.toString(result.opts.syntax);
187
189
 
188
- return css;
189
- }
190
+ if (result && result.root && result.opts) {
191
+ return result.root.toString(result.opts.syntax);
192
+ }
190
193
 
191
- module.exports = getTestRule;
194
+ throw new TypeError('Invalid result');
195
+ }
package/index.d.ts ADDED
@@ -0,0 +1,161 @@
1
+ export type TestCase = {
2
+ /**
3
+ * The code of the test case.
4
+ */
5
+ code: string;
6
+
7
+ /**
8
+ * Description of the test case.
9
+ */
10
+ description?: string;
11
+
12
+ /**
13
+ * Maps to Jest's `test.only`. Default: `false`.
14
+ *
15
+ * @see https://jestjs.io/docs/en/api#testonlyname-fn-timeout
16
+ */
17
+ only?: boolean;
18
+
19
+ /**
20
+ * Maps to Jest's `test.skip`. Default: `false`.
21
+ *
22
+ * @see https://jestjs.io/docs/api#testskipname-fn
23
+ */
24
+ skip?: boolean;
25
+ };
26
+
27
+ export type AcceptTestCase = TestCase;
28
+
29
+ export type Warning = {
30
+ /**
31
+ * Expected message from the test case. Usually exported from the plugin.
32
+ * Optional if `warnings` is used.
33
+ */
34
+ message?: string;
35
+
36
+ /**
37
+ * Expected line number of the warning.
38
+ */
39
+ line?: number;
40
+
41
+ /**
42
+ * Expected column number of the warning.
43
+ */
44
+ column?: number;
45
+
46
+ /**
47
+ * Expected end line number of the warning.
48
+ */
49
+ endLine?: number;
50
+
51
+ /**
52
+ * Expected end column number of the warning.
53
+ */
54
+ endColumn?: number;
55
+ };
56
+
57
+ /**
58
+ * Use the `warnings` property, rather than `message`, `line`, and `column`,
59
+ * if the test case is expected to produce more than one warning.
60
+ */
61
+ export type RejectTestCase = TestCase &
62
+ Warning & {
63
+ /**
64
+ * Expected fixed code of the test case. Optional if `fix` isn't `true`.
65
+ */
66
+ fixed?: string;
67
+
68
+ /**
69
+ * Don't check the `fixed` code. Default: `false`.
70
+ */
71
+ unfixable?: boolean;
72
+
73
+ /**
74
+ * Warning objects containing expected `message`, `line` and `column` etc.
75
+ * Optional if `message` is used.
76
+ */
77
+ warnings?: Warning[];
78
+ };
79
+
80
+ export type TestSchema = {
81
+ /**
82
+ * Name of the rule being tested. Usually exported from the plugin.
83
+ */
84
+ ruleName: string;
85
+
86
+ /**
87
+ * Config to pass to the rule.
88
+ */
89
+ config: unknown;
90
+
91
+ /**
92
+ * Accept test cases.
93
+ */
94
+ accept?: AcceptTestCase[];
95
+
96
+ /**
97
+ * Reject test cases.
98
+ */
99
+ reject?: RejectTestCase[];
100
+
101
+ /**
102
+ * Turn on autofix. Default: `false`.
103
+ */
104
+ fix?: boolean;
105
+
106
+ /**
107
+ * Maps to Stylelint's `plugins` configuration property.
108
+ *
109
+ * Path to the file that exports the plugin object, relative to the root.
110
+ * Usually it's the same path as a `main` property in plugin's `package.json`.
111
+ *
112
+ * If you're testing a plugin pack, it's the path to the file that exports the array of plugin objects.
113
+ *
114
+ * Optional, if `plugins` option was passed to advanced configuration with `getTestRule()`.
115
+ *
116
+ * @see https://stylelint.io/user-guide/configure#plugins
117
+ */
118
+ plugins?: string | string[];
119
+
120
+ /**
121
+ * Maps to Stylelint's `customSyntax` option.
122
+ *
123
+ * @see https://stylelint.io/user-guide/usage/options#customsyntax
124
+ */
125
+ customSyntax?: string;
126
+
127
+ /**
128
+ * Maps to Stylelint's `codeFilename` option.
129
+ *
130
+ * @see https://stylelint.io/user-guide/usage/options#codefilename
131
+ */
132
+ codeFilename?: string;
133
+
134
+ /**
135
+ * Maps to Jest's `test.only`. Default: `false`.
136
+ *
137
+ * @see https://jestjs.io/docs/en/api#testonlyname-fn-timeout
138
+ */
139
+ only?: boolean;
140
+
141
+ /**
142
+ * Maps to Jest's `test.skip`. Default: `false`.
143
+ *
144
+ * @see https://jestjs.io/docs/api#testskipname-fn
145
+ */
146
+ skip?: boolean;
147
+ };
148
+
149
+ /**
150
+ * Test a rule with the specified schema.
151
+ */
152
+ export declare function testRule(schema: TestSchema): void;
153
+
154
+ /**
155
+ * Create a `testRule()` function with any specified plugins.
156
+ */
157
+ export function getTestRule(options?: { plugins?: TestSchema['plugins'] }): typeof testRule;
158
+
159
+ declare global {
160
+ var testRule: typeof testRule;
161
+ }
package/index.js ADDED
@@ -0,0 +1,5 @@
1
+ 'use strict';
2
+
3
+ const getTestRule = require('./getTestRule');
4
+
5
+ module.exports = { getTestRule };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "jest-preset-stylelint",
3
- "version": "4.1.1",
4
- "description": "Jest preset for stylelint plugins.",
3
+ "version": "5.0.1",
4
+ "description": "Jest preset for Stylelint plugins.",
5
5
  "keywords": [
6
6
  "stylelint",
7
7
  "jest",
@@ -11,25 +11,25 @@
11
11
  "repository": "stylelint/jest-preset-stylelint",
12
12
  "license": "MIT",
13
13
  "author": "stylelint",
14
+ "main": "index.js",
15
+ "types": "index.d.ts",
14
16
  "files": [
15
17
  "getTestRule.js",
16
18
  "jest-preset.js",
17
- "jest-setup.js"
19
+ "jest-setup.js",
20
+ "index.d.ts"
18
21
  ],
19
22
  "scripts": {
20
23
  "format": "prettier . --write",
21
24
  "lint": "npm-run-all --parallel lint:*",
22
25
  "lint:formatting": "prettier . --check",
23
- "lint:js": "eslint . ",
24
- "lint:md": "remark . --quiet --frail ",
26
+ "lint:js": "eslint .",
27
+ "lint:md": "remark . --quiet --frail",
28
+ "lint:types": "tsc",
25
29
  "release": "np",
26
30
  "test": "jest",
27
- "watch": "jest --watch"
28
- },
29
- "husky": {
30
- "hooks": {
31
- "pre-commit": "lint-staged"
32
- }
31
+ "watch": "jest --watch",
32
+ "prepare": "husky install"
33
33
  },
34
34
  "lint-staged": {
35
35
  "*.js": "eslint --cache --fix",
@@ -39,7 +39,13 @@
39
39
  "eslintConfig": {
40
40
  "extends": [
41
41
  "stylelint"
42
- ]
42
+ ],
43
+ "globals": {
44
+ "module": true,
45
+ "require": true
46
+ },
47
+ "reportUnusedDisableDirectives": true,
48
+ "root": true
43
49
  },
44
50
  "remarkConfig": {
45
51
  "plugins": [
@@ -48,17 +54,19 @@
48
54
  },
49
55
  "devDependencies": {
50
56
  "@stylelint/prettier-config": "^2.0.0",
51
- "@stylelint/remark-preset": "^2.0.0",
52
- "eslint": "^7.27.0",
53
- "eslint-config-stylelint": "^13.1.1",
54
- "husky": "^6.0.0",
55
- "jest": "^27.0.1",
56
- "lint-staged": "^11.0.0",
57
- "np": "^7.5.0",
57
+ "@stylelint/remark-preset": "^3.0.0",
58
+ "@types/jest": "^27.4.0",
59
+ "eslint": "^8.9.0",
60
+ "eslint-config-stylelint": "^15.0.0",
61
+ "husky": "^7.0.4",
62
+ "jest": "^27.5.1",
63
+ "lint-staged": "^12.3.4",
64
+ "np": "^7.6.0",
58
65
  "npm-run-all": "^4.1.5",
59
- "prettier": "^2.3.0",
60
- "remark-cli": "^9.0.0",
61
- "stylelint": "^13.13.1"
66
+ "prettier": "^2.5.1",
67
+ "remark-cli": "^10.0.1",
68
+ "stylelint": "^14.5.1",
69
+ "typescript": "^4.5.5"
62
70
  },
63
71
  "peerDependencies": {
64
72
  "jest": "^25.3.0 || ^26.0.1 || ^27.0.1"