Skip to content

Commit

Permalink
Fix tightly-coupled dependency on Stylelint's internal module `lib/ut…
Browse files Browse the repository at this point in the history
…ils/getOsEol` (#66)

This change aims to make changes easier by removing the dependency on an internal module.

Summary:
- Change the `os.EOL` property by the before/all hooks instead of mocking.
- Add a file for `setupFilesAfterEnv`.
- Delay requiring `stylelint` in `getTestRule()`.

See also:
- https://github.com/stylelint/stylelint/blob/0dbed54626e87786c2ef2e4ccd4c27d04c8a6918/lib/utils/getOsEol.js
- https://jestjs.io/docs/configuration/#setupfilesafterenv-array
  • Loading branch information
ybiquitous committed Jul 26, 2023
1 parent a33df6f commit 61ab750
Show file tree
Hide file tree
Showing 7 changed files with 33 additions and 5 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
@@ -1,5 +1,9 @@
# Changelog

## Head

- Fixed: tightly-coupled dependency on Stylelint's internal module `lib/utils/getOsEol`.

## 6.1.0

- Added: support for custom unfixable error messages.
Expand Down
1 change: 1 addition & 0 deletions __tests__/__snapshots__/index.test.js.snap
Expand Up @@ -3,6 +3,7 @@
exports[`should contain expected keys 1`] = `
[
"setupFiles",
"setupFilesAfterEnv",
"testEnvironment",
]
`;
10 changes: 8 additions & 2 deletions getTestRule.js
Expand Up @@ -2,8 +2,6 @@

const util = require('util');

const { lint } = require('stylelint'); // eslint-disable-line n/no-unpublished-require -- Avoid auto-install of `stylelint` peer dependency.

/**
* @typedef {import('.').TestCase} TestCase
* @typedef {import('.').TestSchema} TestSchema
Expand All @@ -12,6 +10,14 @@ const { lint } = require('stylelint'); // eslint-disable-line n/no-unpublished-r
/** @type {import('.').getTestRule} */
module.exports = function getTestRule(options = {}) {
return function testRule(schema) {
/** @type {import('stylelint').lint} */
let lint;

beforeAll(() => {
// eslint-disable-next-line n/no-unpublished-require -- Avoid auto-install of `stylelint` peer dependency.
lint = require('stylelint').lint;
});

describe(`${schema.ruleName}`, () => {
const stylelintConfig = {
plugins: options.plugins || schema.plugins,
Expand Down
1 change: 1 addition & 0 deletions jest-preset.js
Expand Up @@ -2,5 +2,6 @@

module.exports = {
setupFiles: [require.resolve('./jest-setup.js')],
setupFilesAfterEnv: [require.resolve('./jest-setup-after-env.js')],
testEnvironment: 'node',
};
18 changes: 18 additions & 0 deletions jest-setup-after-env.js
@@ -0,0 +1,18 @@
'use strict';

const os = require('os');

const eolDescriptor = Object.getOwnPropertyDescriptor(os, 'EOL');

if (!eolDescriptor) {
throw new TypeError('`os` must have an `EOL` property');
}

beforeAll(() => {
// NOTE: `jest.replaceProperty()` is unavailable for a read-only property.
Object.defineProperty(os, 'EOL', { ...eolDescriptor, value: '\n' });
});

afterAll(() => {
Object.defineProperty(os, 'EOL', eolDescriptor);
});
3 changes: 0 additions & 3 deletions jest-setup.js
@@ -1,8 +1,5 @@
'use strict';

// Mock should be before stylelint required. Even if it's required inside other modules
jest.mock('stylelint/lib/utils/getOsEol', () => () => '\n');

const getTestRule = require('./getTestRule');

global.testRule = getTestRule();
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -17,6 +17,7 @@
"getTestRule.js",
"jest-preset.js",
"jest-setup.js",
"jest-setup-after-env.js",
"index.d.ts"
],
"scripts": {
Expand Down

0 comments on commit 61ab750

Please sign in to comment.