Skip to content

Commit

Permalink
Use Stylelint v14 (#543)
Browse files Browse the repository at this point in the history
* Use jest-preset-stylelint

* Update tests

* Update to use custom syntax

* Use PostCSS 8 and latest postcss-scss

* Use Stylelint 14 from v14 branch

* Use default config for rules

* Skip HTML tests

* Use `testRule` for all tests

* Update GitHub actions

* Upgrade dependencies

* Revert two suspicious tests

* Add testing for nested declarations

Co-authored-by: Aleks Hudochenkov <aleks@hudochenkov.com>
  • Loading branch information
niksy and hudochenkov committed Oct 16, 2021
1 parent 9b1b978 commit c167e8c
Show file tree
Hide file tree
Showing 62 changed files with 6,465 additions and 5,809 deletions.
13 changes: 6 additions & 7 deletions .github/workflows/test.yml
Expand Up @@ -11,8 +11,7 @@ jobs:
strategy:
fail-fast: false
matrix:
# switch to `8` when https://github.com/actions/setup-node/issues/27 is fixed
node: [8.16.2, 10, 12, 14]
node: [12, 14]
os: [ubuntu-latest, windows-latest]

steps:
Expand All @@ -33,17 +32,17 @@ jobs:
- name: Build
run: npm run build

- name: Run jest tests
- name: Run Jest tests
run: npm run jest -- --runInBand
if: "!(startsWith(matrix.os, 'ubuntu') && matrix.node == 10)"
if: "!(startsWith(matrix.os, 'ubuntu') && matrix.node == 14)"

- name: Run jest tests with coverage
- name: Run Jest tests with coverage
run: npm run jest -- --runInBand --coverage
if: startsWith(matrix.os, 'ubuntu') && matrix.node == 10
if: startsWith(matrix.os, 'ubuntu') && matrix.node == 14

- name: Run Coveralls
uses: coverallsapp/github-action@master
if: startsWith(matrix.os, 'ubuntu') && matrix.node == 10
if: startsWith(matrix.os, 'ubuntu') && matrix.node == 14
with:
github-token: "${{ secrets.GITHUB_TOKEN }}"
path-to-lcov: "./.coverage/lcov.info"
22 changes: 12 additions & 10 deletions babel-jest.js
Expand Up @@ -82,34 +82,36 @@ const createTransformer = options => {

return {
canInstrument: true,
getCacheKey(fileData, filename, configString, _ref) {
const instrument = _ref.instrument;
getCacheKey(sourceText, sourcePath, transformOptions) {
const { configString, instrument } = transformOptions;

return crypto
.createHash("md5")
.update(THIS_FILE)
.update("\0", "utf8")
.update(fileData)
.update(sourceText)
.update("\0", "utf8")
.update(configString)
.update("\0", "utf8")
.update(getBabelRC(filename))
.update(getBabelRC(sourcePath))
.update("\0", "utf8")
.update(instrument ? "instrument" : "")
.digest("hex");
},
process(src, filename, config, transformOptions) {
process(sourceText, sourcePath, transformOptions) {
const { config, instrument } = transformOptions;

if (!babel) {
babel = require("@babel/core");
}

if (babel.util && !babel.util.canCompile(filename)) {
return src;
if (babel.util && !babel.util.canCompile(sourcePath)) {
return sourceText;
}

const theseOptions = Object.assign({ filename }, options);
const theseOptions = Object.assign({ filename: sourcePath }, options);

if (transformOptions && transformOptions.instrument) {
if (typeof instrument !== "undefined" && instrument) {
// theseOptions.auxiliaryCommentBefore = ' istanbul ignore next ';
// Copied from jest-runtime transform.js
theseOptions.plugins = theseOptions.plugins.concat([
Expand All @@ -124,7 +126,7 @@ const createTransformer = options => {
]);
}

return babel.transform(src, theseOptions).code;
return babel.transform(sourceText, theseOptions).code;
}
};
};
Expand Down
164 changes: 2 additions & 162 deletions jest-setup.js
@@ -1,163 +1,3 @@
"use strict"; // eslint-disable-line strict
const getTestRule = require("jest-preset-stylelint/getTestRule");

const _ = require("lodash");
const stylelint = require("stylelint");

global.testRule = (rule, schema) => {
expect.extend({
toHaveMessage(testCase) {
if (testCase.message === undefined) {
return {
message: () =>
'Expected "reject" test case to have a "message" property',
pass: false
};
}

return {
pass: true
};
}
});

// eslint-disable-next-line jest/valid-describe
describe(`${schema.ruleName}`, () => {
const stylelintConfig = {
plugins: ["./src"],
rules: {
[schema.ruleName]: schema.config
}
};

if (schema.accept && schema.accept.length) {
describe("accept", () => {
schema.accept.forEach(testCase => {
const spec = testCase.only ? it.only : it;

spec(testCase.description || "no description", () => {
const options = {
code: testCase.code,
config: stylelintConfig,
syntax: schema.syntax
};

return stylelint.lint(options).then(output => {
expect(output.results[0].warnings).toEqual([]);

if (!schema.fix) {
return;
}

// Check the fix
return stylelint
.lint(Object.assign({ fix: true }, options))
.then(output2 => {
const fixedCode = getOutputCss(output2);

expect(fixedCode).toBe(testCase.code);
});
});
});
});
});
}

if (schema.reject && schema.reject.length) {
describe("reject", () => {
schema.reject.forEach(testCase => {
const spec = testCase.only ? it.only : it;

spec(testCase.description || "no description", () => {
const options = {
code: testCase.code,
config: stylelintConfig,
syntax: schema.syntax
};

return stylelint.lint(options).then(output => {
const warnings = output.results[0].warnings;
const warning = warnings[0];

expect(warnings.length).toBeGreaterThanOrEqual(1);
// expect(testCase).toHaveMessage();

if (testCase.message !== undefined) {
expect(_.get(warning, "text")).toBe(testCase.message);
}

if (testCase.line !== undefined) {
expect(_.get(warning, "line")).toBe(testCase.line);
}

if (testCase.column !== undefined) {
expect(_.get(warning, "column")).toBe(testCase.column);
}

if (!schema.fix) {
return;
}

if (!testCase.fixed) {
throw new Error(
"If using { fix: true } in test schema, all reject cases must have { fixed: .. }"
);
}

// Check the fix
return stylelint
.lint(Object.assign({ fix: true }, options))
.then(output2 => {
const fixedCode = getOutputCss(output2);

expect(fixedCode).toBe(testCase.fixed);
});
});
});
});
});
}
});
};

function getOutputCss(output) {
const result = output.results[0]._postcssResult;
const css = result.root.toString(result.opts.syntax);

return css;
}

global.testConfig = input => {
let testFn;

if (input.only) {
testFn = test.only;
} else if (input.skip) {
testFn = test.skip;
} else {
testFn = test;
}

testFn(input.description, () => {
const config = {
plugins: ["./"],
rules: {
[input.ruleName]: input.config
}
};

return stylelint
.lint({
code: "",
config
})
.then(data => {
const invalidOptionWarnings = data.results[0].invalidOptionWarnings;

if (input.valid) {
expect(invalidOptionWarnings).toHaveLength(0);
} else {
expect(invalidOptionWarnings[0].text).toBe(input.message);
}
});
});
};
global.testRule = getTestRule({ plugins: ["./src"] });

0 comments on commit c167e8c

Please sign in to comment.