Skip to content

Commit

Permalink
Minor cleanup. Provide ability to override rules when calling apply.
Browse files Browse the repository at this point in the history
  • Loading branch information
Ross McDonald committed Sep 28, 2018
1 parent 08be1df commit 18e2493
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 173 deletions.
11 changes: 0 additions & 11 deletions src/__tests__/builtins.test.ts

This file was deleted.

49 changes: 49 additions & 0 deletions src/__tests__/spectral.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { Spectral } from '@spectral/index';
import { IRuleConfig } from '@spectral/types';

const spec = require('./fixtures/todos.partial-deref.oas2.json');

describe('spectral', () => {
test('load and run the default rule set', () => {
const s = new Spectral();
const results = s.apply(spec, 'oas2');
expect(results.length).toBeGreaterThan(0);
});

test.only('be able to toggle rules on apply', () => {
const spec = {
something: 'something-else',
};

const initialConfig: IRuleConfig = {
rules: {
oas2: {
'lint:test': {
type: 'truthy',
path: '$',
enabled: false,
description: 'this should return a result if enabled',
truthy: 'something-not-present',
},
},
},
};

const overrideConfig: IRuleConfig = {
rules: {
oas2: {
'lint:test': true,
},
},
};

const s = new Spectral(initialConfig);
// run once with no override config
let results = s.apply(spec, 'oas2');
expect(results.length).toEqual(0);

// run again with an override config
results = s.apply(spec, 'oas2', overrideConfig);
expect(results.length).toEqual(1);
});
});
3 changes: 2 additions & 1 deletion src/__tests__/validation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ describe('validation', () => {
).toEqual(0);
});

test('return errors on invalid OASv2 spec', () => {
test.only('return errors on invalid OASv2 spec', () => {
const results = applyRuleToObject(
{
type: 'schema',
Expand All @@ -47,6 +47,7 @@ describe('validation', () => {
},
invalidV2
);
console.log(results);
expect(results.length).toEqual(1);
// expect(results[0].path).toEqual(['info', 'license', 'name']);
// expect(results[0].message).toEqual('should be string');
Expand Down
51 changes: 30 additions & 21 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ export class Spectral {
private paths: object = {};
// normalized object for holding rule definitions indexed by name
private rules: IRuleStore = {};

private ruleConfig: types.IRuleConfig;
// the initial rule config, set on initialization
private readonly ruleConfig: types.IRuleConfig;

constructor(rules?: types.IRuleConfig) {
if (rules) {
Expand All @@ -32,10 +32,14 @@ export class Spectral {
// no rules configuration provided, fall back to the default
this.ruleConfig = require('@spectral/rules/default.json');
}
this.parseRuleConfig(this.ruleConfig);
this.rules = this.parseRuleConfig(this.ruleConfig);
}

private parseRuleDefinition(name: string, rule: types.IRuleDefinitionBase, format: string) {
private parseRuleDefinition(
name: string,
rule: types.IRuleDefinitionBase,
format: string
): IRuleEntry {
try {
jp.parse(rule.path);
} catch (e) {
Expand All @@ -48,13 +52,6 @@ export class Spectral {
category = nameParts[0];
}

this.rules[name] = {
format,
rule,
category,
apply: generateRule(rule as types.LintRule),
};

// update paths object (ensure uniqueness)
if (!this.paths[rule.path]) {
this.paths[rule.path] = [];
Expand All @@ -69,31 +66,41 @@ export class Spectral {
if (!present) {
this.paths[rule.path].push(name);
}

return {
format,
rule,
category,
apply: generateRule(rule as types.LintRule),
};
}

private parseRuleConfig(ruleConfig: types.IRuleConfig) {
private parseRuleConfig(ruleConfig: types.IRuleConfig): IRuleStore {
const rules: IRuleStore = { ...this.rules };

const formats = ruleConfig.rules;
for (const format in formats) {
for (const ruleName in formats[format]) {
const r = formats[format][ruleName];
if (typeof r === 'boolean') {
// enabling/disabling rule
const ruleEntry = this.rules[ruleName];
if (!ruleEntry) {
if (!rules[ruleName]) {
console.warn(
`Unable to find rule matching name '${ruleName}' under format ${format} - this entry has no effect`
);
continue;
}
ruleEntry.rule.enabled = r;
rules[ruleName].rule.enabled = r;
} else if (typeof r === 'object' && !Array.isArray(r)) {
// rule definition
this.parseRuleDefinition(ruleName, r, format);
rules[ruleName] = this.parseRuleDefinition(ruleName, r, format);
} else {
throw new Error(`Unknown rule definition format: ${r}`);
}
}
}

return rules;
}

// public getRules(format?: string);
Expand All @@ -107,16 +114,18 @@ export class Spectral {
): types.IRuleResult[] {
const results: types.IRuleResult[] = [];

if (!rulesConfig) {
// no rules configuration was provided, use the rules provided at
// initialization time
// create copy of rule configuration for this run
let runRules: IRuleStore;
if (rulesConfig) {
runRules = this.parseRuleConfig(rulesConfig);
} else {
// rules configuration was provided
runRules = { ...this.rules };
}
console.log('rules', runRules);

for (const path in this.paths) {
for (const ruleName of this.paths[path]) {
const { rule, apply, category, format } = this.rules[ruleName];
const { rule, apply, category, format } = runRules[ruleName];

if (!rule.enabled || format.indexOf(dataFormat) === -1) {
continue;
Expand Down
Empty file.
56 changes: 0 additions & 56 deletions src/rules/validation/rules/oasParamCheck.ts

This file was deleted.

55 changes: 0 additions & 55 deletions src/rules/validation/rules/params/index.ts

This file was deleted.

30 changes: 1 addition & 29 deletions src/types/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { LintRule } from './lintRules';
import { ValidationRule } from './validationRules';
import { RuleCategory, RuleSeverity } from './rule';
import { RuleSeverity } from './rule';

import { ErrorObject } from 'ajv';
import { AssertionError } from 'assert';
Expand All @@ -10,34 +10,6 @@ export type Rule = ValidationRule | LintRule;

export type RawResult = ErrorObject | AssertionError;

export interface IRuleMetadata {
/**
* The kebab-case name of the rule.
*/
name: string;

/**
* A short, one line description of what the rule does.
*/
description: string;

/**
* The formats this rule applies to
*/
formats: TargetFormat[];

/**
* The type of rule
*/
type: RuleCategory;

/**
* The JSON path within the format object (oas, etc) on which this rule
* applies
*/
objPath: string;
}

export interface IRuleResult {
/**
* The category of the rule (ie, validation, lint)
Expand Down

0 comments on commit 18e2493

Please sign in to comment.