diff --git a/docs/rules.md b/docs/rules.md index dab9da1..efe1076 100644 --- a/docs/rules.md +++ b/docs/rules.md @@ -244,7 +244,7 @@ An example rule module [is available here](https://github.com/ssube/salty-dog-oo ## From Path Rules may be loaded from a directory. Files with `.json` and `.yaml`/`.yml` extensions will be loaded, -with filenames lowercased before checking. +with file names converted to lowercase before being checked. To load a directory: `--rule-path rules/` diff --git a/src/rule/SchemaRule.ts b/src/rule/SchemaRule.ts index 7565596..1baf124 100644 --- a/src/rule/SchemaRule.ts +++ b/src/rule/SchemaRule.ts @@ -1,14 +1,11 @@ -import { ValidateFunction } from 'ajv'; +import { ErrorObject, ValidateFunction } from 'ajv'; import { cloneDeep, defaultTo, isNil } from 'lodash'; import { LogLevel } from 'noicejs'; import { Rule, RuleData } from '.'; import { hasItems } from '../utils'; -import { friendlyError } from '../utils/ajv'; -import { Visitor } from '../visitor'; +import { Visitor, VisitorError, VisitorResult } from '../visitor'; import { VisitorContext } from '../visitor/VisitorContext'; -import { VisitorError } from '../visitor/VisitorError'; -import { VisitorResult } from '../visitor/VisitorResult'; /* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/strict-boolean-expressions */ @@ -76,3 +73,22 @@ export class SchemaRule implements Rule, RuleData, Visitor { } } } + +export function friendlyError(ctx: VisitorContext, err: ErrorObject, rule: SchemaRule): VisitorError { + return { + data: { + err, + rule, + }, + level: 'error', + msg: friendlyErrorMessage(err, rule), + }; +} + +export function friendlyErrorMessage(err: ErrorObject, rule: SchemaRule): string { + if (isNil(err.message)) { + return `${err.dataPath} ${err.keyword} at ${rule.select} for ${rule.name}`; + } else { + return `${err.dataPath} ${err.message} at ${rule.select} for ${rule.name}`; + } +} diff --git a/src/rule/index.ts b/src/rule/index.ts index e06f392..c60fe3f 100644 --- a/src/rule/index.ts +++ b/src/rule/index.ts @@ -7,8 +7,8 @@ import { join } from 'path'; import { YamlParser } from '../parser/YamlParser'; import { readDir, readFile } from '../source'; import { ensureArray, hasItems } from '../utils'; +import { VisitorResult } from '../visitor'; import { VisitorContext } from '../visitor/VisitorContext'; -import { VisitorResult } from '../visitor/VisitorResult'; import { SchemaRule } from './SchemaRule'; /* eslint-disable @typescript-eslint/no-explicit-any */ diff --git a/src/utils/ajv/index.ts b/src/utils/ajv/index.ts deleted file mode 100644 index 80d6b58..0000000 --- a/src/utils/ajv/index.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { ErrorObject } from 'ajv'; -import { isNil } from 'lodash'; - -import { SchemaRule } from '../../rule/SchemaRule'; -import { VisitorContext } from '../../visitor/VisitorContext'; -import { VisitorError } from '../../visitor/VisitorError'; - -export function friendlyError(ctx: VisitorContext, err: ErrorObject, rule: SchemaRule): VisitorError { - return { - data: { - err, - rule, - }, - level: 'error', - msg: friendlyErrorMessage(err, rule), - }; -} - -export function friendlyErrorMessage(err: ErrorObject, rule: SchemaRule): string { - if (isNil(err.message)) { - return `${err.dataPath} ${err.keyword} at ${rule.select} for ${rule.name}`; - } else { - return `${err.dataPath} ${err.message} at ${rule.select} for ${rule.name}`; - } -} diff --git a/src/visitor/VisitorContext.ts b/src/visitor/VisitorContext.ts index b12e49f..4873b61 100644 --- a/src/visitor/VisitorContext.ts +++ b/src/visitor/VisitorContext.ts @@ -2,9 +2,8 @@ import Ajv from 'ajv'; import { JSONPath } from 'jsonpath-plus'; import { Logger } from 'noicejs'; +import { VisitorError, VisitorResult } from '.'; import { doesExist, hasItems } from '../utils'; -import { VisitorError } from './VisitorError'; -import { VisitorResult } from './VisitorResult'; /* eslint-disable @typescript-eslint/no-explicit-any */ diff --git a/src/visitor/VisitorError.ts b/src/visitor/VisitorError.ts deleted file mode 100644 index 5263083..0000000 --- a/src/visitor/VisitorError.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { LogLevel } from 'noicejs'; - -/** - * This is an runtime error, not an exception. - */ -export interface VisitorError { - data: any; - level: LogLevel; - msg: string; -} diff --git a/src/visitor/VisitorResult.ts b/src/visitor/VisitorResult.ts deleted file mode 100644 index d6a429f..0000000 --- a/src/visitor/VisitorResult.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface VisitorResult { - changes: ReadonlyArray; - errors: ReadonlyArray; -} diff --git a/src/visitor/index.ts b/src/visitor/index.ts index 34ffd30..ea27d8a 100644 --- a/src/visitor/index.ts +++ b/src/visitor/index.ts @@ -1,5 +1,20 @@ +import { LogLevel } from 'noicejs'; + import { VisitorContext } from './VisitorContext'; -import { VisitorResult } from './VisitorResult'; + +/** + * This is a runtime error, not an exception. + */ +export interface VisitorError { + data: any; + level: LogLevel; + msg: string; +} + +export interface VisitorResult { + changes: ReadonlyArray; + errors: ReadonlyArray; +} export interface Visitor { /** diff --git a/test/rule/TestSchemaRule.ts b/test/rule/TestSchemaRule.ts index 1c981fb..a321df3 100644 --- a/test/rule/TestSchemaRule.ts +++ b/test/rule/TestSchemaRule.ts @@ -2,7 +2,7 @@ import { expect } from 'chai'; import { NullLogger } from 'noicejs'; import { stub } from 'sinon'; -import { SchemaRule } from '../../src/rule/SchemaRule'; +import { friendlyError, SchemaRule } from '../../src/rule/SchemaRule'; import { VisitorContext } from '../../src/visitor/VisitorContext'; import { describeLeaks, itLeaks } from '../helpers/async'; @@ -157,3 +157,29 @@ describeLeaks('schema rule', async () => { expect(checkSpy, 'check spy should not have been called').to.have.callCount(0); }); }); + +describe('friendly errors', () => { + it('should have a message', () => { + const err = friendlyError(new VisitorContext({ + innerOptions: { + coerce: false, + defaults: false, + mutate: false, + }, + logger: NullLogger.global, + }), { + dataPath: 'test-path', + keyword: TEST_NAME, + params: { /* ? */ }, + schemaPath: 'test-path', + }, new SchemaRule({ + check: {}, + desc: TEST_NAME, + level: 'info', + name: TEST_NAME, + select: '', + tags: [TEST_NAME], + })); + expect(err.msg).to.not.equal(''); + }); +}); diff --git a/test/utils/ajv/TestFriendlyErrors.ts b/test/utils/ajv/TestFriendlyErrors.ts deleted file mode 100644 index 47ad058..0000000 --- a/test/utils/ajv/TestFriendlyErrors.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { expect } from 'chai'; -import { NullLogger } from 'noicejs'; - -import { SchemaRule } from '../../../src/rule/SchemaRule'; -import { friendlyError } from '../../../src/utils/ajv'; -import { VisitorContext } from '../../../src/visitor/VisitorContext'; - -const TEST_NAME = 'test'; - -describe('friendly errors', () => { - it('should have a message', () => { - const err = friendlyError(new VisitorContext({ - innerOptions: { - coerce: false, - defaults: false, - mutate: false, - }, - logger: NullLogger.global, - }), { - dataPath: 'test-path', - keyword: TEST_NAME, - params: { /* ? */ }, - schemaPath: 'test-path', - }, new SchemaRule({ - check: {}, - desc: TEST_NAME, - level: 'info', - name: TEST_NAME, - select: '', - tags: [TEST_NAME], - })); - expect(err.msg).to.not.equal(''); - }); -});