Skip to content

Commit

Permalink
feat(validator): improve configuration validation
Browse files Browse the repository at this point in the history
- run validation only once, from main thread
- combine eslintrc.rules validation into same method
- rulesUnderTesting: from required to optional field
- array configs: only unique strings allowed
- numeric configs: only positive numbers allowed
- add tests for config, tested via package public API
  • Loading branch information
AriPerkkio committed Dec 27, 2020
1 parent 4a68211 commit 09c23ce
Show file tree
Hide file tree
Showing 17 changed files with 818 additions and 209 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
node_modules
coverage
log
libraries-io.json

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ module.exports = {
/** Optional max file size used to exclude bigger files. Defaults to 2 megabytes. */
maxFileSizeBytes: 2000000,

/** Rules used to filter out results. Use empty array when ESLint crashes are the only interest */
/** Optional array of rules used to filter out results. Use undefined or empty array when ESLint crashes are the only interest */
rulesUnderTesting: [],

/** Optional syntax for the result parser. Valid values are plaintext, markdown. Defaults to markdown on CLI, plaintext on CI */
Expand Down
2 changes: 1 addition & 1 deletion eslint-remote-tester.react.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ module.exports = {
'jquery-3\\.4\\.1\\.min\\.js',
].join('|')})`,

/** Rules used to filter out results */
/** Optional array of rules used to filter out results. Use undefined or empty array when ESLint crashes are the only interest */
rulesUnderTesting: ['react/no-unstable-nested-components'],

/** Optional syntax for the result parser. Valid values are plaintext, markdown. Defaults to markdown on CLI, plaintext on CI */
Expand Down
2 changes: 1 addition & 1 deletion lib/config/config-templates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export const CONFIGURATION_FILE_TEMPLATE =
/** Optional max file size (bytes) used to exclude bigger files. Defaults to 2 megabytes. */
maxFileSizeBytes: 2000000,
/** Rules used to filter out results */
/** Optional array of rules used to filter out results. Use undefined or empty array when ESLint crashes are the only interest */
rulesUnderTesting: ['react/no-direct-mutation-state'],
/** Optional syntax for the result parser. Valid values are plaintext, markdown. Defaults to markdown on CLI, plaintext on CI */
Expand Down
8 changes: 4 additions & 4 deletions lib/config/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@ import path from 'path';
import chalk from 'chalk';
import { workerData, isMainThread } from 'worker_threads';

import constructAndValidateConfiguration from './validator';
import { getConfigWithDefaults } from './validator';
import { CONFIGURATION_FILE_TEMPLATE } from './config-templates';
import { Config } from './types';
import { WorkerData } from '@engine/types';

const DEFAULT_CONFIGURATION_FILE = 'eslint-remote-tester.config.js';
Expand Down Expand Up @@ -57,6 +56,7 @@ if (!fs.existsSync(CONFIGURATION_FILE)) {
process.exit();
}

const config: Config = require(path.resolve(CONFIGURATION_FILE));
const configFileContents = require(path.resolve(CONFIGURATION_FILE));
const config = getConfigWithDefaults(configFileContents);

export default constructAndValidateConfiguration(config);
export default config;
2 changes: 1 addition & 1 deletion lib/config/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export { default, resolveConfigurationLocation } from './config';
export { validateEslintrcRules } from './validator';
export { default as validateConfig } from './validator';
25 changes: 20 additions & 5 deletions lib/config/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@ import { Linter } from 'eslint';

import { ResultTemplateOptions } from '@file-client/result-templates';

type AllKeysOptional<T extends { [K: string]: any }> = {
[K in keyof T]?: T[K];
};

export const ResultParsers: ['plaintext', 'markdown'];
export type ResultParser = typeof ResultParsers[number];

export const LogLevels: ['verbose', 'info', 'warn', 'error'];
export type LogLevel = typeof LogLevels[number];

/** Contents of the `eslint-remote-tester.config.js` */
/** Internal config typings after defaults have been set */
export interface Config {
repositories: string[];
extensions: string[];
Expand All @@ -25,9 +29,20 @@ export interface Config {
onComplete?: (results: ResultTemplateOptions[]) => Promise<void> | void;
}

type AllKeysOptional<T extends { [K: string]: any }> = {
[K in keyof T]?: T[K];
};
type RequiredFields = Pick<Config, 'repositories' | 'extensions' | 'eslintrc'>;
type OptionalFields = AllKeysOptional<
Pick<
Config,
Exclude<keyof Config, keyof RequiredFields | 'pathIgnorePattern'>
>
> &
// Internally a RegExp, publicly string
AllKeysOptional<{
pathIgnorePattern: string | Config['pathIgnorePattern'];
}>;

/** Config matching public API */
export type ConfigWithOptionals = RequiredFields & OptionalFields;

/** Config before validation */
export type ConfigToValidate = AllKeysOptional<Config>;
export type ConfigToValidate = AllKeysOptional<ConfigWithOptionals>;
Loading

0 comments on commit 09c23ce

Please sign in to comment.