Skip to content

Commit

Permalink
Prepare for Stylelint 16.0.0 (#87)
Browse files Browse the repository at this point in the history
- Change the `loadLint` option's default value.
- Update the `stylelint` dev dependency (`npm i stylelint@next --save-dev`).
- Migrate test files to ESM, although files executed by Jest are still CJS.
  (The current Jest's support for ESM is still experimental)
- Update TypeScript config for newer Node.js versions.
  • Loading branch information
ybiquitous committed Dec 8, 2023
1 parent 36ed2f8 commit 34929c4
Show file tree
Hide file tree
Showing 14 changed files with 557 additions and 857 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
@@ -1,8 +1,9 @@
# Changelog

## Head
## 7.0.0

- Removed: support for Node.js less than `18.12.0`.
- Changed: `loadLint` option's default value.

## 6.3.2

Expand Down
11 changes: 11 additions & 0 deletions README.md
Expand Up @@ -48,6 +48,17 @@ This is useful if you have many tests. There are two additional steps to do this
}
```

### Prevent segmentation fault

If you get a segmentation fault while running the preset on Node.js 18, you can use [jest-light-runner](https://www.npmjs.com/package/jest-light-runner):

```json
{
"preset": "jest-preset-stylelint",
"runner": "jest-light-runner"
}
```

## Usage

This preset exposes the following global functions as a helper.
Expand Down
File renamed without changes.
@@ -1,10 +1,13 @@
'use strict';
import stylelint from 'stylelint';

const stylelint = require('stylelint');
const {
createPlugin,
utils: { report, ruleMessages, validateOptions },
} = stylelint;

const ruleName = 'plugin/foo';

const messages = stylelint.utils.ruleMessages(ruleName, {
const messages = ruleMessages(ruleName, {
rejected: (selector) => `No "${selector}" selector`,
});

Expand All @@ -14,7 +17,7 @@ const isString = (value) => typeof value === 'string';
/** @type {import('stylelint').Rule} */
const ruleFunction = (primary) => {
return (root, result) => {
const validOptions = stylelint.utils.validateOptions(result, ruleName, {
const validOptions = validateOptions(result, ruleName, {
actual: primary,
possible: [isString],
});
Expand All @@ -27,7 +30,7 @@ const ruleFunction = (primary) => {
const { selector } = rule;

if (primary !== selector) {
stylelint.utils.report({
report({
result,
ruleName,
message: messages.rejected(selector),
Expand All @@ -41,4 +44,4 @@ const ruleFunction = (primary) => {
ruleFunction.ruleName = ruleName;
ruleFunction.messages = messages;

module.exports = stylelint.createPlugin(ruleName, ruleFunction);
export default createPlugin(ruleName, ruleFunction);
54 changes: 0 additions & 54 deletions __tests__/getTestRule.test.js

This file was deleted.

59 changes: 59 additions & 0 deletions __tests__/getTestRule.test.mjs
@@ -0,0 +1,59 @@
import { getTestRule } from '../index.js';

import plugin from './fixtures/plugin-foo.mjs';

const testRule = getTestRule();
const plugins = [plugin];
const {
// @ts-expect-error -- TS2339: Property 'ruleName' does not exist on type 'Plugin'.
ruleName,
// @ts-expect-error -- TS2339: Property 'ruleName' does not exist on type 'Plugin'.
rule: { messages },
} = plugin;

testRule({
plugins,
ruleName,
config: ['.a'],

accept: [
{
code: '.a {}',
},
{
code: '.a {}',
description: 'with description',
},
],

reject: [
{
code: '#a {}',
message: messages.rejected('#a'),
},
{
code: '#a {}',
message: messages.rejected('#a'),
description: 'with description',
},
],
});

testRule({
plugins,
ruleName,
config: ['.a'],
loadLint: () => import('stylelint').then((m) => m.default.lint),
accept: [{ code: '.a {}' }],
});

const testRuleWithLoadLint = getTestRule({
loadLint: () => import('stylelint').then((m) => m.default.lint),
});

testRuleWithLoadLint({
plugins,
ruleName,
config: ['.a'],
accept: [{ code: '.a {}' }],
});
@@ -1,10 +1,11 @@
'use strict';
import { getTestRuleConfigs } from '../index.js';

const { getTestRuleConfigs } = require('../index.js');
import plugin from './fixtures/plugin-foo.mjs';

const testRuleConfigs = getTestRuleConfigs();
const plugins = [require.resolve('./fixtures/plugin-foo.js')];
const ruleName = 'plugin/foo';
const plugins = [plugin];
// @ts-expect-error -- TS2339: Property 'ruleName' does not exist on type 'Plugin'.
const { ruleName } = plugin;

testRuleConfigs({
plugins,
Expand Down Expand Up @@ -34,12 +35,12 @@ testRuleConfigs({
testRuleConfigs({
plugins,
ruleName,
loadLint: () => Promise.resolve(require('stylelint').lint),
loadLint: () => import('stylelint').then((m) => m.default.lint),
accept: [{ config: 'a' }],
});

const testRuleConfigsWithLoadLint = getTestRuleConfigs({
loadLint: () => Promise.resolve(require('stylelint').lint),
loadLint: () => import('stylelint').then((m) => m.default.lint),
});

testRuleConfigsWithLoadLint({
Expand Down
4 changes: 1 addition & 3 deletions __tests__/index.test.js → __tests__/index.test.mjs
@@ -1,6 +1,4 @@
'use strict';

const preset = require('../jest-preset.js');
import preset from '../jest-preset.js';

it('should contain expected keys', () => {
expect(Object.keys(preset)).toMatchSnapshot();
Expand Down
12 changes: 7 additions & 5 deletions getTestRule.js
@@ -1,6 +1,6 @@
'use strict';

const util = require('util');
const { inspect } = require('node:util');

/**
* @typedef {import('.').TestCase} TestCase
Expand All @@ -11,9 +11,11 @@ const util = require('util');
module.exports = function getTestRule(options = {}) {
return function testRule(schema) {
const loadLint =
schema.loadLint || options.loadLint || (() => Promise.resolve(require('stylelint').lint)); // eslint-disable-line n/no-unpublished-require -- Avoid auto-install of `stylelint` peer dependency.
schema.loadLint ||
options.loadLint ||
(() => import('stylelint').then((m) => m.default.lint)); // eslint-disable-line n/no-unpublished-import -- Avoid auto-install of `stylelint` peer dependency.

/** @type {import('stylelint').lint} */
/** @type {import('stylelint').PublicApi['lint']} */
let lint;

beforeAll(async () => {
Expand Down Expand Up @@ -177,8 +179,8 @@ function setupTestCases({ name, cases, schema, comparisons }) {
if (testCase) {
const spec = testCase.only ? it.only : testCase.skip ? it.skip : it;

describe(`${util.inspect(schema.config)}`, () => {
describe(`${util.inspect(testCase.code)}`, () => {
describe(`${inspect(schema.config)}`, () => {
describe(`${inspect(testCase.code)}`, () => {
spec(testCase.description || 'no description', comparisons(testCase));
});
});
Expand Down
6 changes: 3 additions & 3 deletions getTestRuleConfigs.js
@@ -1,6 +1,6 @@
'use strict';

const { inspect } = require('util');
const { inspect } = require('node:util');

/** @type {import('.').getTestRuleConfigs} */
module.exports = function getTestRuleConfigs(options = {}) {
Expand All @@ -18,9 +18,9 @@ module.exports = function getTestRuleConfigs(options = {}) {
}

const loadLint =
schemaLoadLint || options.loadLint || (() => Promise.resolve(require('stylelint').lint)); // eslint-disable-line n/no-unpublished-require -- Avoid auto-install of `stylelint` peer dependency.
schemaLoadLint || options.loadLint || (() => import('stylelint').then((m) => m.default.lint)); // eslint-disable-line n/no-unpublished-import -- Avoid auto-install of `stylelint` peer dependency.

/** @type {import('stylelint').lint} */
/** @type {import('stylelint').PublicApi['lint']} */
let lint;

beforeAll(async () => {
Expand Down
2 changes: 1 addition & 1 deletion index.d.ts
Expand Up @@ -115,7 +115,7 @@ export type TestSchema = {
*
* @see https://stylelint.io/user-guide/configure#plugins
*/
plugins?: string | string[];
plugins?: import('stylelint').Config['plugins'];

/**
* Maps to Stylelint's `customSyntax` option.
Expand Down

0 comments on commit 34929c4

Please sign in to comment.