This commit is contained in:
William Durand 2018-11-19 20:30:57 +01:00 коммит произвёл GitHub
Родитель acdb2678f0
Коммит 5a055623d1
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
6 изменённых файлов: 172 добавлений и 1 удалений

Просмотреть файл

@ -98,6 +98,16 @@ If you want to run all tests and exit, type:
yarn test-once
```
### Eslint
As you run tests you will see a report of Eslint errors at the end of the test output:
yarn test
If you would like to run tests without Eslint checks, set an environment variable:
NO_ESLINT=1 yarn test
### Flow
There is limited support for using [Flow](https://flowtype.org/) to validate the intention of our program.

Просмотреть файл

@ -21,6 +21,7 @@ module.exports = {
'<rootDir>/tests/jest-reporters/fingers-crossed.js',
'<rootDir>/tests/jest-reporters/summary.js',
'<rootDir>/tests/jest-reporters/flow-check.js',
'<rootDir>/tests/jest-reporters/eslint-check.js',
],
setupTestFrameworkScriptFile: '<rootDir>/tests/setup.js',
testPathIgnorePatterns: [

Просмотреть файл

@ -176,7 +176,8 @@
"NODE_ICU_DATA": "./node_modules/full-icu",
"NODE_PATH": "./:./src",
"NODE_ENV": "test",
"NO_FLOW": "1"
"NO_FLOW": "1",
"NO_ESLINT": "1"
}
},
"webpack-dev-server": {

Просмотреть файл

@ -0,0 +1,58 @@
/* eslint-disable no-console */
const { CLIEngine } = require('eslint');
const { getChangedFiles } = require('./utils');
const NO_ESLINT_ENV_VAR = 'NO_ESLINT';
class EslintCheckReporter {
constructor() {
this.eslint = new CLIEngine();
this.eslintOutput = null;
}
isDisabled() {
return process.env[NO_ESLINT_ENV_VAR] === '1';
}
async onRunStart() {
if (this.isDisabled()) {
return;
}
const files = await getChangedFiles();
if (!files) {
throw new Error(`Failed to retrieve files in the eslint check reporter.`);
}
const report = this.eslint.executeOnFiles(files);
if (report.errorCount === 0 && report.warningCount === 0) {
// All good.
this.eslintOutput = null;
} else {
this.eslintOutput = CLIEngine.getFormatter()(report.results);
}
}
getLastError() {
if (this.isDisabled()) {
return undefined;
}
console.log('');
if (this.eslintOutput) {
console.log(this.eslintOutput);
console.log(
`Set ${NO_ESLINT_ENV_VAR}=1 in the environment to disable eslint checks`,
);
return new Error('eslint errors');
}
console.log('Eslint: no errors 💄 ✨');
return undefined;
}
}
module.exports = EslintCheckReporter;

Просмотреть файл

@ -0,0 +1,45 @@
const util = require('util');
const exec = util.promisify(require('child_process').exec);
const filterFileNamesFromGitStatusOutput = (output) => {
const files = output
.split('\n')
.map((line) => line.trim())
// Make sure we ignore deleted files.
.filter((line) => !line.startsWith('D'))
.map((line) => {
// Return the new name of a renamed file.
if (line.startsWith('RM')) {
return line.substring(line.indexOf('->'));
}
return line;
})
.map((line) => line.split(' '))
// .flatMap()
.reduce((chunks, chunk) => chunks.concat(chunk), [])
// We assume no filename can be smaller than 3 to filter the short format
// statuses: https://git-scm.com/docs/git-status#_short_format.
.filter((chunk) => chunk.length > 3)
// Allow directories OR JS/JSX files
.filter((filename) => /(\/|\.jsx?)$/.test(filename));
return files;
};
const getChangedFiles = async () => {
// We use the Porcelain Format Version 1,
// See: https://git-scm.com/docs/git-status#_porcelain_format_version_1
const { stdout, stderr } = await exec('git status --porcelain=1');
if (stderr) {
return null;
}
return filterFileNamesFromGitStatusOutput(stdout);
};
module.exports = {
filterFileNamesFromGitStatusOutput,
getChangedFiles,
};

Просмотреть файл

@ -0,0 +1,56 @@
import { filterFileNamesFromGitStatusOutput } from 'tests/jest-reporters/utils';
describe(__filename, () => {
describe('_filterFileNamesFromGitStatusOutput', () => {
const _filterFileNamesFromGitStatusOutput = (lines = []) => {
return filterFileNamesFromGitStatusOutput(lines.join('\n'));
};
it('does not return deleted files', () => {
const files = _filterFileNamesFromGitStatusOutput([
'D src/core/browserWindow.js',
' D src/core/browserWindow.js',
]);
expect(files).toHaveLength(0);
});
it('only returned the new filename of a renamed file', () => {
const files = _filterFileNamesFromGitStatusOutput([
'RM src/amo/sagas/categories.js -> src/core/sagas/categories.js',
]);
expect(files).toEqual(['src/core/sagas/categories.js']);
});
it('returns the filenames without the git statuses', () => {
const files = _filterFileNamesFromGitStatusOutput([
'M jest.config.js',
'A tests/jest-reporters/eslint-check.js',
'AM tests/jest-reporters/utils.js',
'?? tests/unit/jest-reporters/',
]);
expect(files).toEqual([
'jest.config.js',
'tests/jest-reporters/eslint-check.js',
'tests/jest-reporters/utils.js',
'tests/unit/jest-reporters/',
]);
});
it('only returns JavaScript files', () => {
const files = _filterFileNamesFromGitStatusOutput([
'M README.md',
'M package.json',
'M src/test.jsx',
' M tests/unit/jest-reporters/test_utils.js',
]);
expect(files).toEqual([
'src/test.jsx',
'tests/unit/jest-reporters/test_utils.js',
]);
});
});
});