lint: fix things
This commit is contained in:
parent
6aa1cb5365
commit
2bb48b0b87
|
@ -1,5 +1,6 @@
|
||||||
import { Options, showCompletionScript, usage } from 'yargs';
|
import { Options, showCompletionScript, usage } from 'yargs';
|
||||||
|
|
||||||
|
import { RuleSelector } from '../rule';
|
||||||
import { VERSION_INFO } from '../version';
|
import { VERSION_INFO } from '../version';
|
||||||
|
|
||||||
export const CONFIG_ARGS_NAME = 'config-name';
|
export const CONFIG_ARGS_NAME = 'config-name';
|
||||||
|
@ -16,25 +17,40 @@ export interface Args {
|
||||||
mode: string;
|
mode: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ParsedArgs extends RuleSelector {
|
||||||
|
[CONFIG_ARGS_NAME]: string;
|
||||||
|
[CONFIG_ARGS_PATH]: string;
|
||||||
|
coerce: boolean;
|
||||||
|
count: boolean;
|
||||||
|
defaults: boolean;
|
||||||
|
dest: string;
|
||||||
|
mode: string;
|
||||||
|
rules: Array<string>;
|
||||||
|
source: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ParseResults {
|
||||||
|
args: ParsedArgs;
|
||||||
|
mode: string;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrap yargs to exit after completion.
|
* Wrap yargs to exit after completion.
|
||||||
*
|
*
|
||||||
* @TODO: fix it to use argv, not sure if yargs can do that
|
* @TODO: fix it to use argv, not sure if yargs can do that
|
||||||
*/
|
*/
|
||||||
export function parseArgs(argv: Array<string>) {
|
export function parseArgs(argv: Array<string>): ParseResults {
|
||||||
let mode = 'check';
|
let mode = 'check';
|
||||||
|
|
||||||
const args = usage(`Usage: salty-dog <mode> [options]`)
|
const parser = usage(`Usage: salty-dog <mode> [options]`)
|
||||||
.command({
|
.command({
|
||||||
command: ['check', '*'],
|
command: ['check', '*'],
|
||||||
describe: 'validate the source documents',
|
describe: 'validate the source documents',
|
||||||
handler: (argv: any) => {
|
handler: (argi: any) => {
|
||||||
mode = 'check';
|
mode = 'check';
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.command({
|
.command({
|
||||||
command: ['fix'],
|
|
||||||
describe: 'validate the source document and insert defaults',
|
|
||||||
builder: (yargs: any) => {
|
builder: (yargs: any) => {
|
||||||
return yargs
|
return yargs
|
||||||
.option('coerce', {
|
.option('coerce', {
|
||||||
|
@ -46,21 +62,23 @@ export function parseArgs(argv: Array<string>) {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
handler: (argv: any) => {
|
command: ['fix'],
|
||||||
|
describe: 'validate the source document and insert defaults',
|
||||||
|
handler: (argi: any) => {
|
||||||
mode = 'fix';
|
mode = 'fix';
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.command({
|
.command({
|
||||||
command: ['list'],
|
command: ['list'],
|
||||||
describe: 'list active rules',
|
describe: 'list active rules',
|
||||||
handler: (argv: any) => {
|
handler: (argi: any) => {
|
||||||
mode = 'list';
|
mode = 'list';
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.command({
|
.command({
|
||||||
command: ['complete'],
|
command: ['complete'],
|
||||||
describe: 'generate tab completion script for bash or zsh',
|
describe: 'generate tab completion script for bash or zsh',
|
||||||
handler: (argv: any) => {
|
handler: (argi: any) => {
|
||||||
mode = 'complete';
|
mode = 'complete';
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -112,8 +130,11 @@ export function parseArgs(argv: Array<string>) {
|
||||||
})
|
})
|
||||||
.help()
|
.help()
|
||||||
.version(VERSION_INFO.app.version)
|
.version(VERSION_INFO.app.version)
|
||||||
.alias('version', 'v')
|
.alias('version', 'v');
|
||||||
.argv;
|
|
||||||
|
// @TODO: this should not need a cast but argv's type only has the last option (include-tag)
|
||||||
|
// @tslint:disable-next-line:no-any
|
||||||
|
const args = parser.argv as any;
|
||||||
|
|
||||||
if (mode === 'complete') {
|
if (mode === 'complete') {
|
||||||
showCompletionScript();
|
showCompletionScript();
|
||||||
|
|
|
@ -1,14 +1,26 @@
|
||||||
|
import { Stream } from 'bunyan';
|
||||||
import { isNil, isString } from 'lodash';
|
import { isNil, isString } from 'lodash';
|
||||||
|
import { LogLevel } from 'noicejs';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
|
|
||||||
import { CONFIG_ENV, CONFIG_SCHEMA } from './schema';
|
|
||||||
import { includeSchema } from './type/Include';
|
|
||||||
import { NotFoundError } from '../error/NotFoundError';
|
import { NotFoundError } from '../error/NotFoundError';
|
||||||
import { YamlParser } from '../parser/YamlParser';
|
import { YamlParser } from '../parser/YamlParser';
|
||||||
import { readFileSync } from '../source';
|
import { readFileSync } from '../source';
|
||||||
|
import { CONFIG_ENV, CONFIG_SCHEMA } from './schema';
|
||||||
|
import { includeSchema } from './type/Include';
|
||||||
|
|
||||||
includeSchema.schema = CONFIG_SCHEMA;
|
includeSchema.schema = CONFIG_SCHEMA;
|
||||||
|
|
||||||
|
export interface ConfigData {
|
||||||
|
data: {
|
||||||
|
logger: {
|
||||||
|
level: LogLevel;
|
||||||
|
name: string;
|
||||||
|
streams: Array<Stream>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* With the given name, generate all potential config paths in their complete, absolute form.
|
* With the given name, generate all potential config paths in their complete, absolute form.
|
||||||
*
|
*
|
||||||
|
@ -39,7 +51,7 @@ export function completePaths(name: string, extras: Array<string>): Array<string
|
||||||
return paths;
|
return paths;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function loadConfig(name: string, ...extras: Array<string>): Promise<any> {
|
export async function loadConfig(name: string, ...extras: Array<string>): Promise<ConfigData> {
|
||||||
const paths = completePaths(name, extras);
|
const paths = completePaths(name, extras);
|
||||||
|
|
||||||
for (const p of paths) {
|
for (const p of paths) {
|
||||||
|
|
|
@ -20,4 +20,3 @@ export const streamType = new YamlType('!stream', {
|
||||||
return Reflect.get(process, name);
|
return Reflect.get(process, name);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ const MODES_LIST: Array<string> = [MODES.check, MODES.fix, MODES.list];
|
||||||
|
|
||||||
const STATUS_SUCCESS = 0;
|
const STATUS_SUCCESS = 0;
|
||||||
const STATUS_ERROR = 1;
|
const STATUS_ERROR = 1;
|
||||||
|
const STATUS_MAX = 255;
|
||||||
|
|
||||||
export async function main(argv: Array<string>): Promise<number> {
|
export async function main(argv: Array<string>): Promise<number> {
|
||||||
const { args, mode } = parseArgs(argv);
|
const { args, mode } = parseArgs(argv);
|
||||||
|
@ -43,7 +44,7 @@ export async function main(argv: Array<string>): Promise<number> {
|
||||||
});
|
});
|
||||||
|
|
||||||
const rules = await loadRules(args.rules, ctx);
|
const rules = await loadRules(args.rules, ctx);
|
||||||
const activeRules = await resolveRules(rules, args as any);
|
const activeRules = await resolveRules(rules, args);
|
||||||
|
|
||||||
if (mode === 'list') {
|
if (mode === 'list') {
|
||||||
logger.info({ rules: activeRules }, 'listing active rules');
|
logger.info({ rules: activeRules }, 'listing active rules');
|
||||||
|
@ -61,7 +62,7 @@ export async function main(argv: Array<string>): Promise<number> {
|
||||||
if (ctx.errors.length > 0) {
|
if (ctx.errors.length > 0) {
|
||||||
logger.error({ count: ctx.errors.length, errors: ctx.errors }, 'some rules failed');
|
logger.error({ count: ctx.errors.length, errors: ctx.errors }, 'some rules failed');
|
||||||
if (args.count) {
|
if (args.count) {
|
||||||
return Math.min(ctx.errors.length, 255);
|
return Math.min(ctx.errors.length, STATUS_MAX);
|
||||||
} else {
|
} else {
|
||||||
return STATUS_ERROR;
|
return STATUS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { CONFIG_SCHEMA } from '../config/schema';
|
||||||
import { Parser } from '../parser';
|
import { Parser } from '../parser';
|
||||||
|
|
||||||
export class YamlParser implements Parser {
|
export class YamlParser implements Parser {
|
||||||
dump(...data: Array<any>): string {
|
public dump(...data: Array<any>): string {
|
||||||
const docs: Array<any> = [];
|
const docs: Array<any> = [];
|
||||||
for (const doc of data) {
|
for (const doc of data) {
|
||||||
const part = safeDump(doc, {
|
const part = safeDump(doc, {
|
||||||
|
@ -15,7 +15,7 @@ export class YamlParser implements Parser {
|
||||||
return docs.join('\n---\n\n');
|
return docs.join('\n---\n\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
parse(body: string): Array<any> {
|
public parse(body: string): Array<any> {
|
||||||
const docs: Array<any> = [];
|
const docs: Array<any> = [];
|
||||||
safeLoadAll(body, (doc: any) => docs.push(doc), {
|
safeLoadAll(body, (doc: any) => docs.push(doc), {
|
||||||
schema: CONFIG_SCHEMA,
|
schema: CONFIG_SCHEMA,
|
||||||
|
|
157
src/rule.ts
157
src/rule.ts
|
@ -1,12 +1,12 @@
|
||||||
import { ValidateFunction } from 'ajv';
|
import { ValidateFunction } from 'ajv';
|
||||||
import { applyDiff, diff } from 'deep-diff';
|
import { applyDiff, diff } from 'deep-diff';
|
||||||
import { JSONPath } from 'jsonpath-plus';
|
import { JSONPath } from 'jsonpath-plus';
|
||||||
import { cloneDeep, Dictionary, intersection, isNil } from 'lodash';
|
import { cloneDeep, defaultTo, Dictionary, intersection, isNil } from 'lodash';
|
||||||
import { LogLevel } from 'noicejs';
|
import { LogLevel } from 'noicejs';
|
||||||
|
|
||||||
import { YamlParser } from './parser/YamlParser';
|
import { YamlParser } from './parser/YamlParser';
|
||||||
import { readFileSync } from './source';
|
import { readFileSync } from './source';
|
||||||
import { isNilOrEmpty } from './utils';
|
import { ensureArray, isNilOrEmpty } from './utils';
|
||||||
import { friendlyError } from './utils/ajv';
|
import { friendlyError } from './utils/ajv';
|
||||||
import { Visitor } from './visitor';
|
import { Visitor } from './visitor';
|
||||||
import { VisitorContext } from './visitor/VisitorContext';
|
import { VisitorContext } from './visitor/VisitorContext';
|
||||||
|
@ -40,11 +40,77 @@ export interface RuleSource {
|
||||||
rules: Array<RuleData>;
|
rules: Array<RuleData>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ensureArray<T>(val: Array<T> | undefined): Array<T> {
|
export interface RuleResult extends VisitorResult {
|
||||||
if (isNil(val)) {
|
rule: Rule;
|
||||||
return [];
|
}
|
||||||
} else {
|
|
||||||
return Array.from(val);
|
export class Rule implements RuleData, Visitor<RuleResult> {
|
||||||
|
public readonly check: ValidateFunction;
|
||||||
|
public readonly desc: string;
|
||||||
|
public readonly filter?: ValidateFunction;
|
||||||
|
public readonly level: LogLevel;
|
||||||
|
public readonly name: string;
|
||||||
|
public readonly select: string;
|
||||||
|
public readonly tags: Array<string>;
|
||||||
|
|
||||||
|
constructor(data: RuleData) {
|
||||||
|
this.desc = data.desc;
|
||||||
|
this.level = data.level;
|
||||||
|
this.name = data.name;
|
||||||
|
this.select = defaultTo(data.select, '$');
|
||||||
|
this.tags = Array.from(data.tags);
|
||||||
|
|
||||||
|
// copy schema objects
|
||||||
|
this.check = cloneDeep(data.check);
|
||||||
|
if (!isNil(data.filter)) {
|
||||||
|
this.filter = cloneDeep(data.filter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async pick(ctx: VisitorContext, root: any): Promise<Array<any>> {
|
||||||
|
const scopes = JSONPath({
|
||||||
|
json: root,
|
||||||
|
path: this.select,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (isNil(scopes) || scopes.length === 0) {
|
||||||
|
ctx.logger.debug('no data selected');
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return scopes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async visit(ctx: VisitorContext, node: any): Promise<RuleResult> {
|
||||||
|
ctx.logger.debug({ item: node, rule: this }, 'visiting node');
|
||||||
|
|
||||||
|
const check = ctx.compile(this.check);
|
||||||
|
const filter = this.compileFilter(ctx);
|
||||||
|
const errors: Array<VisitorError> = [];
|
||||||
|
const result: RuleResult = {
|
||||||
|
changes: [],
|
||||||
|
errors,
|
||||||
|
rule: this,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (filter(node)) {
|
||||||
|
ctx.logger.debug({ item: node }, 'checking item');
|
||||||
|
if (!check(node) && !isNil(check.errors) && check.errors.length > 0) {
|
||||||
|
ctx.error(...Array.from(check.errors).map(friendlyError));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ctx.logger.debug({ errors: filter.errors, item: node }, 'skipping item');
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected compileFilter(ctx: VisitorContext): ValidateFunction {
|
||||||
|
if (isNil(this.filter)) {
|
||||||
|
return () => true;
|
||||||
|
} else {
|
||||||
|
return ctx.compile(this.filter);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +141,7 @@ export async function loadRules(paths: Array<string>, ctx: VisitorContext): Prom
|
||||||
ctx.addSchema(data.name, data.definitions);
|
ctx.addSchema(data.name, data.definitions);
|
||||||
}
|
}
|
||||||
|
|
||||||
rules.push(...data.rules.map((data: RuleData) => new Rule(data)));
|
rules.push(...data.rules.map((it: RuleData) => new Rule(it)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,78 +215,3 @@ export async function visitRules(ctx: VisitorContext, rules: Array<Rule>, data:
|
||||||
|
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RuleResult extends VisitorResult {
|
|
||||||
rule: Rule;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Rule implements RuleData, Visitor<RuleResult> {
|
|
||||||
public readonly check: ValidateFunction;
|
|
||||||
public readonly desc: string;
|
|
||||||
public readonly filter?: ValidateFunction;
|
|
||||||
public readonly level: LogLevel;
|
|
||||||
public readonly name: string;
|
|
||||||
public readonly select: string;
|
|
||||||
public readonly tags: string[];
|
|
||||||
|
|
||||||
constructor(data: RuleData) {
|
|
||||||
this.desc = data.desc;
|
|
||||||
this.level = data.level;
|
|
||||||
this.name = data.name;
|
|
||||||
this.select = data.select || '$';
|
|
||||||
this.tags = Array.from(data.tags);
|
|
||||||
|
|
||||||
// copy schema objects
|
|
||||||
this.check = cloneDeep(data.check);
|
|
||||||
if (!isNil(data.filter)) {
|
|
||||||
this.filter = cloneDeep(data.filter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async pick(ctx: VisitorContext, root: any): Promise<Array<any>> {
|
|
||||||
const scopes = JSONPath({
|
|
||||||
json: root,
|
|
||||||
path: this.select,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (isNil(scopes) || scopes.length === 0) {
|
|
||||||
ctx.logger.debug('no data selected');
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
return scopes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async visit(ctx: VisitorContext, node: any): Promise<RuleResult> {
|
|
||||||
ctx.logger.debug({ item: node, rule: this }, 'visiting node');
|
|
||||||
|
|
||||||
const check = ctx.compile(this.check);
|
|
||||||
const filter = this.compileFilter(ctx);
|
|
||||||
const errors: Array<VisitorError> = [];
|
|
||||||
const result: RuleResult = {
|
|
||||||
changes: [],
|
|
||||||
errors,
|
|
||||||
rule: this,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (filter(node)) {
|
|
||||||
ctx.logger.debug({ item: node }, 'checking item');
|
|
||||||
if (!check(node) && check.errors && check.errors.length) {
|
|
||||||
const errors = Array.from(check.errors);
|
|
||||||
ctx.error(...errors.map(friendlyError));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ctx.logger.debug({ errors: filter.errors, item: node }, 'skipping item');
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected compileFilter(ctx: VisitorContext): ValidateFunction {
|
|
||||||
if (isNil(this.filter)) {
|
|
||||||
return () => true;
|
|
||||||
} else {
|
|
||||||
return ctx.compile(this.filter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { ErrorObject } from 'ajv';
|
import { ErrorObject } from 'ajv';
|
||||||
|
import { isNil } from 'lodash';
|
||||||
|
|
||||||
import { VisitorError } from '../../visitor/VisitorError';
|
import { VisitorError } from '../../visitor/VisitorError';
|
||||||
|
|
||||||
|
@ -13,9 +14,9 @@ export function friendlyError(err: ErrorObject): VisitorError {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function friendlyErrorMessage(err: ErrorObject): string {
|
export function friendlyErrorMessage(err: ErrorObject): string {
|
||||||
if (err.message) {
|
if (isNil(err.message)) {
|
||||||
return `${err.dataPath} ${err.message}`;
|
|
||||||
} else {
|
|
||||||
return `${err.dataPath} ${err.keyword}`;
|
return `${err.dataPath} ${err.keyword}`;
|
||||||
|
} else {
|
||||||
|
return `${err.dataPath} ${err.message}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,13 @@
|
||||||
|
import { isNil } from 'lodash';
|
||||||
|
|
||||||
export function isNilOrEmpty(val: Array<unknown> | null | undefined): val is Array<unknown> {
|
export function isNilOrEmpty(val: Array<unknown> | null | undefined): val is Array<unknown> {
|
||||||
return (Array.isArray(val) && val.length > 0);
|
return (Array.isArray(val) && val.length > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function ensureArray<T>(val: Array<T> | undefined): Array<T> {
|
||||||
|
if (isNil(val)) {
|
||||||
|
return [];
|
||||||
|
} else {
|
||||||
|
return Array.from(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -20,20 +20,20 @@ export class VisitorContext implements VisitorContextOptions, VisitorResult {
|
||||||
public readonly innerOptions: RuleOptions;
|
public readonly innerOptions: RuleOptions;
|
||||||
|
|
||||||
protected readonly ajv: Ajv.Ajv;
|
protected readonly ajv: Ajv.Ajv;
|
||||||
protected readonly _changes: Array<any>;
|
protected readonly changeBuffer: Array<any>;
|
||||||
protected readonly _errors: Array<VisitorError>;
|
protected readonly errorBuffer: Array<VisitorError>;
|
||||||
|
|
||||||
public get changes(): ReadonlyArray<any> {
|
public get changes(): ReadonlyArray<any> {
|
||||||
return this._changes;
|
return this.changeBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public get errors(): ReadonlyArray<VisitorError> {
|
public get errors(): ReadonlyArray<VisitorError> {
|
||||||
return this._errors;
|
return this.errorBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(options: VisitorContextOptions) {
|
constructor(options: VisitorContextOptions) {
|
||||||
this._changes = [];
|
this.changeBuffer = [];
|
||||||
this._errors = [];
|
this.errorBuffer = [];
|
||||||
|
|
||||||
this.ajv = new Ajv({
|
this.ajv = new Ajv({
|
||||||
coerceTypes: options.innerOptions.coerce,
|
coerceTypes: options.innerOptions.coerce,
|
||||||
|
@ -49,12 +49,12 @@ export class VisitorContext implements VisitorContextOptions, VisitorResult {
|
||||||
logWithLevel(this.logger, err.level, err.data, err.msg);
|
logWithLevel(this.logger, err.level, err.data, err.msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
this._errors.push(...errors);
|
this.errorBuffer.push(...errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
public mergeResult(other: VisitorResult): this {
|
public mergeResult(other: VisitorResult): this {
|
||||||
this._changes.push(...other.changes);
|
this.changeBuffer.push(...other.changes);
|
||||||
this._errors.push(...other.errors);
|
this.errorBuffer.push(...other.errors);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ export class VisitorContext implements VisitorContextOptions, VisitorResult {
|
||||||
});
|
});
|
||||||
|
|
||||||
this.ajv.addSchema({
|
this.ajv.addSchema({
|
||||||
'$id': name,
|
$id: name,
|
||||||
definitions: schema,
|
definitions: schema,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,26 +6,26 @@ import { makeSelector, resolveRules, Rule, visitRules } from '../src/rule';
|
||||||
import { VisitorContext } from '../src/visitor/VisitorContext';
|
import { VisitorContext } from '../src/visitor/VisitorContext';
|
||||||
|
|
||||||
const TEST_RULES = [new Rule({
|
const TEST_RULES = [new Rule({
|
||||||
name: 'foo',
|
check: {},
|
||||||
desc: '',
|
desc: '',
|
||||||
level: 'info',
|
level: 'info',
|
||||||
|
name: 'foo',
|
||||||
|
select: '$',
|
||||||
tags: ['all', 'foo'],
|
tags: ['all', 'foo'],
|
||||||
check: {},
|
|
||||||
select: '$',
|
|
||||||
}), new Rule({
|
}), new Rule({
|
||||||
|
check: {},
|
||||||
|
desc: '',
|
||||||
|
level: 'warn',
|
||||||
name: 'bar',
|
name: 'bar',
|
||||||
desc: '',
|
|
||||||
level: 'warn',
|
|
||||||
tags: ['all', 'test'],
|
|
||||||
check: {},
|
|
||||||
select: '$',
|
select: '$',
|
||||||
|
tags: ['all', 'test'],
|
||||||
}), new Rule({
|
}), new Rule({
|
||||||
name: 'bin',
|
check: {},
|
||||||
desc: '',
|
desc: '',
|
||||||
level: 'warn',
|
level: 'warn',
|
||||||
tags: ['all', 'test'],
|
name: 'bin',
|
||||||
check: {},
|
|
||||||
select: '$',
|
select: '$',
|
||||||
|
tags: ['all', 'test'],
|
||||||
})];
|
})];
|
||||||
|
|
||||||
describe('rule resolver', () => {
|
describe('rule resolver', () => {
|
||||||
|
@ -102,21 +102,21 @@ describe('rule resolver', () => {
|
||||||
describe('rule visitor', () => {
|
describe('rule visitor', () => {
|
||||||
it('should only call visit for selected items', async () => {
|
it('should only call visit for selected items', async () => {
|
||||||
const ctx = new VisitorContext({
|
const ctx = new VisitorContext({
|
||||||
logger: new ConsoleLogger(),
|
|
||||||
innerOptions: {
|
innerOptions: {
|
||||||
coerce: false,
|
coerce: false,
|
||||||
defaults: false,
|
defaults: false,
|
||||||
mutate: false,
|
mutate: false,
|
||||||
}
|
},
|
||||||
|
logger: new ConsoleLogger(),
|
||||||
});
|
});
|
||||||
const data = {};
|
const data = {};
|
||||||
const rule = new Rule({
|
const rule = new Rule({
|
||||||
name: 'foo',
|
check: {},
|
||||||
desc: '',
|
desc: '',
|
||||||
level: 'info',
|
level: 'info',
|
||||||
tags: [],
|
name: 'foo',
|
||||||
select: '$',
|
select: '$',
|
||||||
check: {},
|
tags: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
const mockRule = mock(rule);
|
const mockRule = mock(rule);
|
||||||
|
@ -143,12 +143,12 @@ describe('rule visitor', () => {
|
||||||
});
|
});
|
||||||
const data = {};
|
const data = {};
|
||||||
const rule = new Rule({
|
const rule = new Rule({
|
||||||
name: 'foo',
|
check: {},
|
||||||
desc: '',
|
desc: '',
|
||||||
level: 'info',
|
level: 'info',
|
||||||
tags: [],
|
name: 'foo',
|
||||||
select: '$',
|
select: '$',
|
||||||
check: {},
|
tags: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
const mockRule = mock(rule);
|
const mockRule = mock(rule);
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
import sourceMapSupport from 'source-map-support'
|
import sourceMapSupport from 'source-map-support';
|
||||||
|
|
||||||
sourceMapSupport.install()
|
sourceMapSupport.install();
|
||||||
|
|
|
@ -5,10 +5,10 @@ import { YamlParser } from '../../src/parser/YamlParser';
|
||||||
describe('yaml parser', () => {
|
describe('yaml parser', () => {
|
||||||
describe('dump documents', () => {
|
describe('dump documents', () => {
|
||||||
it('should dump multiple documents', () => {
|
it('should dump multiple documents', () => {
|
||||||
const parser = new YamlParser();
|
const parser = new YamlParser();
|
||||||
const data = parser.dump({}, {});
|
const data = parser.dump({}, {});
|
||||||
|
|
||||||
expect(data).to.contain('---');
|
expect(data).to.contain('---');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ foo: {}
|
||||||
---
|
---
|
||||||
bar: {}
|
bar: {}
|
||||||
`);
|
`);
|
||||||
|
|
||||||
expect(Array.isArray(data)).to.equal(true);
|
expect(Array.isArray(data)).to.equal(true);
|
||||||
expect(data.length).to.equal(2);
|
expect(data.length).to.equal(2);
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,10 +5,10 @@ import { friendlyError } from '../../../src/utils/ajv';
|
||||||
describe('friendly errors', () => {
|
describe('friendly errors', () => {
|
||||||
it('should have a message', () => {
|
it('should have a message', () => {
|
||||||
const err = friendlyError({
|
const err = friendlyError({
|
||||||
keyword: 'test',
|
|
||||||
dataPath: 'test-path',
|
dataPath: 'test-path',
|
||||||
schemaPath: 'test-path',
|
keyword: 'test',
|
||||||
params: { /* ? */ },
|
params: { /* ? */ },
|
||||||
|
schemaPath: 'test-path',
|
||||||
});
|
});
|
||||||
expect(err.msg).to.not.equal('');
|
expect(err.msg).to.not.equal('');
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue